<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>gyu_won.log</title>
        <link>https://velog.io/</link>
        <description>반가워요😎</description>
        <lastBuildDate>Wed, 18 Oct 2023 08:00:48 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>gyu_won.log</title>
            <url>https://velog.velcdn.com/images/gyu_won/profile/cdae38f4-10c7-4eda-9c82-dfd30ccbe7cb/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. gyu_won.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/gyu_won" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Data Link control Protocol]]></title>
            <link>https://velog.io/@gyu_won/Data-Link-control-Protocol-DLC-Protocols</link>
            <guid>https://velog.io/@gyu_won/Data-Link-control-Protocol-DLC-Protocols</guid>
            <pubDate>Wed, 18 Oct 2023 08:00:48 GMT</pubDate>
            <description><![CDATA[<p>앞서 설명하였듯이, data link control layer는 framing과 error control의 기능을 수행한다</p>
<p>이러한 기능들은 protocol이 정의하고 하는데 Data link protocol의 대표적인 protocol에 대해서 알아보자</p>
<blockquote>
</blockquote>
<ol>
<li>HDLC Protocol</li>
<li>Point-to-Point Protocol</li>
</ol>
<p>이 둘은 완전히 다른 개념이라기 보다는 HTTP도 있고 SMTP도 있듯이 Data Link Control protocol의 2가지 예로 활용방안에 따라 선택된다</p>
<hr>
<h3 id="high-level-data-link-control-hdlc">High-Level Data-Link Control (HDLC)</h3>
<blockquote>
<p>bit-oriented protocol로 point to point 통신이나 multipoint link 위에서 돌아가는 protocol이다</p>
</blockquote>
<p>bit-oriented이기 때문에 bit stuffing을 통해서 data를 구분한다</p>
<p>HDLC는 다양한 구성에서 사용할 수 있는 두 가지 전송 모드를 제공한다</p>
<blockquote>
<ol>
<li>일반 응답 모드(NRM)</li>
<li>비동기 균형 모드(ABM)</li>
</ol>
</blockquote>
<h4 id="normal-response-modenrm">Normal Response Mode(NRM)</h4>
<blockquote>
<p>NRM은 하나의 primary station과 secondary station으로 나누며 primary station은 명령을 보내기만 하고, secondary station은 명령에 응답만 한다
<img src="https://velog.velcdn.com/images/gyu_won/post/4c6ba6e0-24ce-4d29-aaad-a0d190f05e7e/image.png" alt=""></p>
</blockquote>
<p>NRM은 point-to-point와 multipoint links 모두에 사용된다</p>
<br/>

<h4 id="asynchronous-balanced-modeabm">Asynchronous balanced mode(ABM)</h4>
<blockquote>
</blockquote>
<p>link는 point-to-point이며 모두가 primary station이자, secondary station이 될 수 있다
<img src="https://velog.velcdn.com/images/gyu_won/post/64e9046a-2ce1-4447-a311-b2dbeda415cb/image.png" alt=""></p>
<br/>

<h4 id="frame">Frame</h4>
<p>NRM, ARM등 2가지 모드와 다양한 옵션을 위해서 HDLC는 세 가지 유형의 프레임을 정의한다</p>
<blockquote>
</blockquote>
<ol>
<li>Information frame (I-frame)</li>
<li>Supervisory frame (S-frame)</li>
<li>Unnumbered frame (U-frame)</li>
</ol>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/2ec50a2c-5b3a-4a25-9367-2e9e7523a88e/image.png" alt="">
<br/></p>
<p>frame은 5가지 종류의 필드로 구성된다</p>
<p><strong>Flag</strong></p>
<blockquote>
<p>01111110 으로 frame의 경계임을 알려준다</p>
</blockquote>
<p>multi frame 전송에서는 한 frame의 ending flag가 다른 frame의 시작 flag를 나타낸다</p>
<p>** Address **</p>
<blockquote>
<p>1 byte나 필요에 따라 몇 byte의 길이를 가지는 필드로 secondary station의 주소만 포함한다</p>
</blockquote>
<p>보통 HDLC는 WAN에서 주로 사용하는데 WAN의 경우에는 traffic이 어느정도 일정하기 때문에 경로가 정해져 있다.
즉, 받는이가 정해져 있을 때는 primary와 secondary 모두의 MAC 주소가 필요한 것은 아니기 때문에 secondary의 MAC 주소만 적어준다</p>
<p>primary station이 frame을 만들면 to를 주소에 포함하고
secondary station이 frame을 만들면 from을 주소에 포함한다</p>
<p>*<em>Information *</em></p>
<blockquote>
<p>말 그대로 network layer에서 보낸 데이터를 담은 부분이다</p>
</blockquote>
<p>** FCS **</p>
<blockquote>
<p>2byte 또는 4byte CRC 코드를 포함하는 error detection 전용 field이다</p>
</blockquote>
<p>** Control**</p>
<blockquote>
<p>error control 이나 flow control에 사용되는 1 또는 2 byte 필드로 frame의 종류와 기능을 결정한다</p>
</blockquote>
<p>즉, frame 종류에 따라서 control에 들어가는 정보들이 다르다</p>
<br/>

<h4 id="frame의-종류">Frame의 종류</h4>
<p>** I-frames**</p>
<blockquote>
<p>사용자 데이터 및 사용자 데이터와 관련된 제어 정보를 전송하는 데 사용된다
(가장 일반적으로 사용하는 frame)</p>
</blockquote>
<p> 추가로, flow control과 error control 정보를 포함할 수도 있는데 이렇게 데이터를 보냄과 동시에 아까 받은거에 대한 feedback도 제공해 주는 것을 piggybacking이라고 한다</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/0a3b4c52-16db-4249-a0bd-73b077df9353/image.png" alt=""></p>
<blockquote>
<p>모든 종류의 frame에 공통적으로 첫번째 bit는 frame의 종류를 결정한다</p>
</blockquote>
<ul>
<li>0: I-frame</li>
<li>10: S-frame</li>
<li>11: U-frame<blockquote>
</blockquote>
I-frame의 그 다음 3bit는 N(S)라고 불리며, frame의 순서를 정의한다 (0~7)<blockquote>
</blockquote>
I-frame의 마지막 3bit는 N(R)로 불리며, piggybacking을 사용할 때 ACK으로 사용한다<blockquote>
</blockquote>
P/F 1bit는 poll이냐 final이냐를 뜻하는데 둘다 1이므로 항상 1이다
(poll은 primary station에서 secondary station으로 보낸 것이고 final은 그 반대이다)</li>
</ul>
<br/>

<p>** S-frames **</p>
<blockquote>
<p>flow control이나 error control과 같은 제어 정보만 전송하는 데 사용된다</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/0a3b4c52-16db-4249-a0bd-73b077df9353/image.png" alt=""></p>
<p>제어 정보만 전송하기 때문에 ACK 뿐만 아니라 NAK도 전송할 수 있다</p>
<blockquote>
<p>S-frame은 information field가 없고 대신 Code라고 불리는 2bit field가 있는데 이 필드는 S-frame의 종류를 알려준다</p>
</blockquote>
<p>00: Receive ready (RR) / 받을 준비가 됐다는 뜻으로 N(R)은 ACK number이다
10: Receive not ready (RNR) / 방금까진 받았는데 이제 못받는다는 뜻으로 N(R)은 ACK number이다
01: Reject (REJ) / 못 받았으니 해당 번호 이후로 다시 달라는 뜻이다
11: Selective reject (SREJ): 특정한 번호만 못 받았으니 그것만 다시줘 라는 뜻이다</p>
<br/>

<p>** U-frame**</p>
<blockquote>
<p>연결된 장치 간의 세션 관리 및 제어 정보를 교환하기 위해 사용된다</p>
</blockquote>
<p>S-frame과 달리 information field가 있지만 이는 system management를 위한 정보를 담는 것이지 user data를 담지 않는다</p>
<p>U-frames에 의해 전송되는 정보는 링크 자체를 관리하기 위한 것이고 이 메시지들은 시스템에 예약되어 있다
<img src="https://velog.velcdn.com/images/gyu_won/post/0a3b4c52-16db-4249-a0bd-73b077df9353/image.png" alt=""></p>
<p>위 그림과 같이 Code 영역이 2bit 접두사 + 3bit 접미사로 5bit 이기 때문에 총 32개의 message를 정의할 수 있고 이에 따라 필요한 정보인 management information이 다르다 (근데 실제로는 32개 다 예약되어 있지는 않음)</p>
<hr>
<h3 id="point-to-point-protocol-ppp">Point-to-Point Protocol (PPP)</h3>
<blockquote>
<p>point-to-point 접근을 위해 사용하는 기본적인 protocol이다
<img src="https://velog.velcdn.com/images/gyu_won/post/9486502e-ae52-4bcf-ab7b-d9b54530c828/image.png" alt=""></p>
</blockquote>
<br/>

<h4 id="ppp의-구성-필드">PPP의 구성 필드</h4>
<p>PPP는 character-oriented frame으로 6개의 field로 구성된다
** Flag **</p>
<blockquote>
<p>1byte flag (01111110)을 가진다</p>
</blockquote>
<p><strong>Address</strong></p>
<blockquote>
<p>PPP는 어차피 point-to-point이기 때문에 주소가 필요 없어서 broadcast 주소인 11111111로 입력된다</p>
</blockquote>
<p><strong>Control</strong></p>
<blockquote>
<p>PPP는 flow control과 제한된 error detection만 제공하기 때문에 00000011 상수 값으로 입력된다</p>
</blockquote>
<p>** Protocol **</p>
<blockquote>
<p>data field에 있는 데이터가 어떤 데이터인지 정의한다 (어떤 프로토콜용 데이터인지 프로토콜을 bit로 표현하여 명시한다)</p>
</blockquote>
<p>2byte 길이지만 1byte만 사용하도록 약속하였다</p>
<p>** FCS **</p>
<blockquote>
<p>2byte 또는 4byte CRC 코드를 포함하는 error detection 전용 field이다</p>
</blockquote>
<p>detection만 하기 때문에 error가 발생하면 무조건 재전송 해야한다</p>
<p>*<em>Payload field *</em></p>
<blockquote>
<p>user data나 다른 information을 실제로 옮기는 부분</p>
</blockquote>
<p>1500byte로 크기가 고정되어 있고 이 안에는 byte stuffing로 인한 escape 문자열(0x7D: 01111101)도 포함된다
<img src="https://velog.velcdn.com/images/gyu_won/post/2d8d681c-cf6e-4b36-addd-f1f96fe3268c/image.png" alt=""></p>
<p>PPP의 경우에는 ESC는 01111101 이고 flag는 01111110
즉 01111101 다음에 나오는 01111110은 flag로 인식되지 않고 데이터로 인식된다</p>
<p>만약 1500 byte 보다 작으면 padding을 사용하여 빈 공간을 0으로 채운다</p>
<br/>

<h4 id="ppp의-transition-단계">PPP의 transition 단계</h4>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/8c9e5aad-84bb-4c99-b256-5c2adbec0161/image.png" alt=""></p>
<blockquote>
</blockquote>
<ol>
<li>transition이 시작되면 먼저 dead state로 출발한다</li>
<li>두개의 node가 통신을 시작하면 establish 단계로 이동한다</li>
<li>두개의 노드가 서로 인증하기 위해 authenticate 단계로 이동한다</li>
<li>여기서 인증이 되면 network 단계로 이동하고, 인증이 안되면 terminate 단계로 이동한다</li>
<li>data 전송은 open 단계에서 실행된다</li>
<li>두 node 중 하나가 연결을 종료시키길 원하면 terminate 단계로 이동한다</li>
</ol>
<br/>

<h4 id="multiplexing">Multiplexing</h4>
<blockquote>
<p>PPP는 link를 만들고 authentication을 하고 network-layer와 데이터를 주고받기 위해서 다른 protocol을 사용한다</p>
</blockquote>
<p>Link Control Protocol(LCP) 한 개, Authentication Protocol(AP) 2개, Network Control Protocol(NCP) 여러개가 PPP를 도와준다</p>
<p>종류는 3가지 이고 개수는 LCP는 1개, AP는 2개, NCP는 여러개이다!</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/864e6f0f-490b-4299-b8f8-78cd608d320a/image.png" alt=""></p>
<p>위 사진에서 보듯이, Protocol의 값에 따라서 해당 데이터가 어떤 protocol의 데이터인지 알 수 있다</p>
<p><strong>Link Control Protocol (LCP)</strong></p>
<blockquote>
<p>LCP는 establishing, maintaining, configuring, ternimating의 역할을 한다</p>
</blockquote>
<p>option을 설정하기 위한 negotiation mechanism을 제공하고, 두 endpoint가 모두 option들에 동의해야 link가 establish 된다</p>
<p>** Authentication Protocol (AP) **</p>
<blockquote>
<p>말그대로 user를 식별하기 위해 인증하는 것으로, PPP는 authentication을 위해 2개의 protocol을 만든다</p>
</blockquote>
<ul>
<li>PAP</li>
<li>CHAP</li>
</ul>
<p>PAP: Password Authentication Protocol</p>
<ol>
<li>system에 접근하기 원하는 사용자는 id와 password를 system에 보낸다</li>
<li>system은 id와 password의 유효성을 체크하고 연결을 accept 하거나 deny 한다</li>
</ol>
<p>CHAP: Challenge Handshake Authentication Protocol</p>
<ul>
<li>PAP 보다 더 안전한 3-way handshaking authentication protocol 이다</li>
</ul>
<ol>
<li>system은 user에게 challenge value를 포함한 challenge packet을 보낸다</li>
<li>user는 미리 정의해놓은 함수에 challenge value와 자신의 비밀번호를 입력하고 결과를 packet에 담아 system에 보낸다</li>
<li>system도 user의 password와 challenge value로 같은 함수를 적용하고 만일 결과가 같다면 accept 되고 다르면 deny 된다</li>
</ol>
<p>** Network Control Protocol (NCP) **</p>
<blockquote>
<p>NCP protocol를 사용하여 network layer로 부터의 data를 변환할 수 있다</p>
</blockquote>
<p>NCP는 그냥 다양하게 있다만 알아둬도 됨</p>
<br/>

<h4 id="multilink-ppp">Multilink PPP</h4>
<blockquote>
<p>PPP는 point-to-point protocol로 기존에 single-channel로 설계되었지만 single point-to-point link에서의 multiple channel 기술이 multilink PPP로 발달시켰다</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/53149ffd-f908-4f50-bd82-ba593ceff32f/image.png" alt=""></p>
<p>위 그림과 같이 하나의 큰 logical PPP frame은 여러개의 PPP frame으로 쪼개지고 이는 여러개의 채널로 보내진다</p>
<p>따라서 multilink PPP에서는 이렇게 쪼개진 애들임을 알려주기 위해 protocol field를 0x3d로 설정하고 sequence number도 PPP frame에 추가한다
(multi point가 아니라 multi link 이므로 address는 여전히 필요없음!)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Data Link Control - Error Control]]></title>
            <link>https://velog.io/@gyu_won/Data-Link-Control-Error-Control</link>
            <guid>https://velog.io/@gyu_won/Data-Link-Control-Error-Control</guid>
            <pubDate>Wed, 18 Oct 2023 05:12:13 GMT</pubDate>
            <description><![CDATA[<p>앞서 data link layer는 Data-link-control sublayer와 Media-access-control sublayer 2가지로 나눌 수 있다고 설명했다</p>
<p>그리고 이 중에서 Data-link-control sublayer의 대표적인 2가지 기능으로 아래의 2가지가 있다</p>
<ul>
<li>Framing</li>
<li>Error control</li>
</ul>
<hr>
<h3 id="error-control">Error Control</h3>
<blockquote>
<p>Error control은 error detection과 error correction을 포함한다</p>
</blockquote>
<p>간섭에 의하여 bit가 바뀌는 error가 발생할 수 있다</p>
<p>그렇다면 어떤 error들이 발생할 수 있을까?</p>
<h4 id="types-of-error">types of error</h4>
<blockquote>
</blockquote>
<ol>
<li>single-bit error</li>
<li>burst error</li>
</ol>
<p>** single-bit error **</p>
<blockquote>
<p>주어진 data unit(byte, character, packet)에서 1bit가 에러난 것</p>
</blockquote>
<p>** burst error **</p>
<blockquote>
<p>주어진 data unit에서 error가 자주 난 것</p>
</blockquote>
<p>정확이 2개 연속으로 나야 burst error가 아니라 그냥 슥 보고 bit error가 자주 있으면 다 묶어서 burst error 라고 함</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/01a921bf-1be3-47d4-913c-7a9d12900093/image.png" alt=""></p>
<h4 id="error-detection과-error-correction">error detection과 error correction</h4>
<blockquote>
<p>error detection과 error correction을 위하여 추가적인 bit들을 데이터에 추가하여 보낸다</p>
</blockquote>
<p>이렇게 추가하는 data를 redundancy라고 한다</p>
<p>당연히 detection 보다는 correction이 어렵고 redundancy가 길다</p>
<p>뭐가 더 좋냐는 상황에 따라 다르기 때문에 정할 수 없음</p>
<ul>
<li>error 숫자나 message 크기가 중요한 요소임</li>
</ul>
<blockquote>
<p>그러면 여기서 redundancy는 어떤 기준으로 만드는가?
redundancy는 다양한 코딩 기법으로 만들어낸다</p>
</blockquote>
<ol>
<li>Block Coding</li>
<li>Parity-Check Code</li>
<li>Cyclic Codes</li>
</ol>
<hr>
<h3 id="block-coding">Block Coding</h3>
<blockquote>
<p>k-bit block으로 n-bit block을 만들기 때문에 block coding이라고 한다</p>
</blockquote>
<p>순서</p>
<ol>
<li>message를 datawords라는 k-bit block들로 나눈다</li>
<li>각각의 block에 r bit의 redundancy를 추가한다</li>
</ol>
<p>여기서 n(k+r) bit의 block은 code words라고 불린다</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/c56cc19a-2d59-475b-be6e-419966620052/image.png" alt=""></p>
<p>Genertor에서는 r bit의 redundancy를 생성하고 Checker는 error 여부와 있었으면 어디에 있었는지를 체크함
(어떤 r bit를 생성하는지에 대한 원리는 나중에 나옴)</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/7445ea7e-6105-48f3-b11f-160d072b01a4/image.png" alt=""></p>
<p>위의 예시는 k = 2, r = 1, n = 3으로 설정한 table임
header나 trailer에 넣는 것이 아니라 data 자체를 match table에서 해당하는 codewords로 바꾸어 넣는거임</p>
<blockquote>
<p>이렇게 해서 011을 수신하면 이를 checker를 통해서 00이라는 datawords를 얻음
첫번째 bit에 error가 나서 111을 수신하면 이 데이터는 table에 없으니까 버림</p>
</blockquote>
<p>근데 여기서 만일 두번째, 세번째 bit가 error가 나서 000을 수신하면 이는 table에 있기 때문에 00으로 받아들이게 됨 (잘못된 데이터를 받아들이는 문제)</p>
<p>위의 경우에는 r = 1로 1 bit만 붙이기 때문에 detection의 성능이 떨어지게 됨</p>
<br/>

<h4 id="hamming-distance">Hamming Distance</h4>
<blockquote>
<p>error control의 중요한 컨셉중에 하나로, 길이가 같은 두 비트열의 값이 다른 비트 개수를 나타낸다</p>
</blockquote>
<p>즉, 두 bit들의 XOR 연산을 통해서 나온 결과값의 1의 개수를 의미함</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/c746443e-38f2-489a-a777-0cad12271df1/image.png" alt=""></p>
<h4 id="minimum-hamming-distance">Minimum Hamming Distance</h4>
<blockquote>
<p>codewords의 집합 속에서 가능한 codeword 쌍들의 가장 작은 hamming distance가 minimum hamming distance 이다</p>
</blockquote>
<p>s개의 error까지 탐지해야 한다면 codewords set의 minimum distance는 s+1 보다 커야한다
예를들어, minimum hamming distance가 3이면 2bit까지의 오류를 찾을 수 있다는 뜻</p>
<p>이는 codewords set의 성능을 측정하는 지표가 됨</p>
<h4 id="linear-block-codes">Linear Block Codes</h4>
<blockquote>
<p>두개의 유효한 codeworkds를 XOR 연산을 하면 다른 유효한 코드를 만들 수 있는 코드들이고 오늘날 사용되는 block code들은 거의 다 linear block code의 일부이다</p>
</blockquote>
<p>이런 linear block code에서 minimum hamming distance는 모든 bit가 0인 codeword를 제외한 codeword set에서 1의 개수가 가장 작은 codeword의 1의 개수이다
<img src="https://velog.velcdn.com/images/gyu_won/post/30324220-105b-4ca4-a3f0-dbbd9c28671e/image.png" alt=""></p>
<p>위의 table은 linear code block의 일부로 이루어져있고 그렇다면 hamming distance(dmin)는 1이 가장 작은 codeword의 1의 개수인 2이다 -&gt; 따라서 1bit의 오류를 탐지할 수 있다</p>
<hr>
<h3 id="parity-check-code">Parity-Check Code</h3>
<blockquote>
<p>가장 쉬운 error check 방법 중 하나로 k bit datawords에 1bit를 더하여 n(k+1)bit의 codeword를 만드는 것이다</p>
</blockquote>
<p>이때 추가되는 1bit를 parity bit라고 하고, 이 parity bit는 nbit의 codeword에서 1의 개수가 짝수가 되도록 만든다
<img src="https://velog.velcdn.com/images/gyu_won/post/3f98c47c-ec4e-4e7e-b876-334ea1ff3710/image.png" alt=""></p>
<p>위 그림에서, Generator는 4bit dataword를 input으로 받아 modulo 연산을 통해 parity bit r0를 생성하고, sender는 parity bit와 dataword를 합친 5bit codeword를 전송한다</p>
<p>receiver는 5 bit codeword를 Checker에 넣어서 똑같이 modulo 연산을 수행하고 Syndrome을 생성한다.
이때 syndrome이 1이라는 말은 codeword의 1이 짝수개가 아니라는 말이므로 데이터를 버리고 syndrome이 0이라면 data를 accept 한다</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/3a4f57a9-f806-4a9b-b981-54c7346185da/image.png" alt=""></p>
<p>이 방법은 error가 났다 안났다만 확인할 수 있지 어디서 났는지는 체크할 수 없기 때문에 dataword가 아닌 parity bit가 error가 나도 데이터를 discard 한다</p>
<p>또한 짝수개의 error가 발생하면 이를 알아차릴 수 없기 때문에, syndrome이 1인 홀수개의 error만 탐지할 수 있다</p>
<p>장점으로는 1bit를 추가함으로써 많은 error를 찾을 수 있다는 점!</p>
<hr>
<h3 id="cyclic-codes">Cyclic Codes</h3>
<blockquote>
<p>특정한 codeword를 왼쪽이나 오른쪽으로 shift 하여 다른 codeword를 얻는 것</p>
</blockquote>
<p>만일 1011000을 cyclically left-shift를 수행하면 0110001이 된다</p>
<p>cyclic code의 대표적인 예로 cyclic redundancy check(CRC)를 살펴보자</p>
<h4 id="cyclic-redundancy-check-crc">Cyclic redundancy check (CRC)</h4>
<blockquote>
<p>주로 LAN이나 WAN에서 사용하는 방식으로 나눗셈을 통하여 codeword를 생성한다</p>
</blockquote>
<p>나눗셈은 순환적 bit shift와 XOR 연산의 결합이므로 이는 Cyclic code의 특성에 만족한다</p>
<br/>

<p><strong>CRC에서 codeword를 전송하는 과정</strong>
<img src="https://velog.velcdn.com/images/gyu_won/post/414e3a18-5a74-4586-8057-9320ad003024/image.png" alt=""></p>
<p>위의 예시 설명</p>
<p>Encoder:</p>
<blockquote>
</blockquote>
<p>dataword 가 4 bit 이고 codeword가 7bit라면 n - k = 7 - 4 = 3이므로 3bit의 data를 가장 오른쪽에 더하여 codeword를 생성하면 된다</p>
<blockquote>
</blockquote>
<p>따라서 000이라는 데이터를 추가하여 총 7bit의 data가 generator로 입력된다</p>
<blockquote>
</blockquote>
<p>generator는 n-k+1 = 7-4+1 = 4bit의 divisor를 사용하여 나눗셈 연산을 수행하고 나머지인 r2r1r0를 data word에 붙인다 (몫은 버림)
<img src="https://velog.velcdn.com/images/gyu_won/post/09e32876-622f-426b-959f-3aef124d6c25/image.png" alt=""></p>
<p>Decoder:</p>
<blockquote>
</blockquote>
<p>codeword를 받으면 n = 7bit 모두를 checker에 넘겨준다</p>
<blockquote>
</blockquote>
<p>checker는 똑같이 divisor를 사용하여 나눗셈 연산을 수행하고 그 결과가 0이라면 앞의 k bit를 accept 하고 아니라면 버린다
<img src="https://velog.velcdn.com/images/gyu_won/post/57ce9ce3-1dc4-4ae3-819b-043e89fb3734/image.png" alt=""></p>
<p>sender와 reciever가 공유하는 divisor로 나눈다</p>
<p>Encoder와 Decoder는 이렇게 계산을 일일이 할 수도 있고 이미 모든 dataword에 대해 계산을 한 값을 match table로 정리하여 찾아서 할 수도 있다</p>
<p>** Divisor **
여기서 그러면 divisor는 어떻게 정할 것인가?</p>
<blockquote>
<p>아래 표와 같이 표준 나눗셈 연산자가 있다
<img src="https://velog.velcdn.com/images/gyu_won/post/8ba008ca-fc30-46e8-8506-d3ae7770f946/image.png" alt=""></p>
</blockquote>
<p>나눗셈 연산자의 Name의 숫자는 나눗셈 연산자를 나타내는 다항식의 가장 높은 차수를 나타내기 때문에 bit의 수는 name 옆에 적힌 수보다  항상 1만큼 많다</p>
<blockquote>
<p>즉 CRC-8은 9bit를 가지고 CRC-32는 33bit를 가진다
그리고 CRC-8은 나누는 divisor가 9bit이기 때문에 8bit가 remainder 가 된다</p>
</blockquote>
<p>뿐만 아니라 divisor는 최소한 2bit를 가져야 하고 가장 오른쪽과 왼쪽의 bit는 모두 1이어야 하는 요구사항을 가지기도 한다</p>
<br/>

<p>** Performance of CRC **</p>
<blockquote>
<ol>
<li>single error는 모두 찾을 수 있다</li>
<li>odd number of error는 다는 찾을 수 없고 특정 조건 하에서만 찾을 수 있다
(even 이슈는 언급하지 않음)</li>
<li>burst error 탐지는 burst error의 길이가 L이고, 추가로 붙인 remainder의 길이가 r일때 아래와 같은 식을 만족한다<ul>
<li>L &lt;= r 이면 탐지할 수 있다</li>
<li>L = r +1 이면 1-(0.5의 r-1승)의 확률로 찾을 수 있다</li>
<li>L &gt; r + 1 이면 1-(0.5의 r승)의 확률로 찾을 수 있다</li>
</ul>
</li>
</ol>
</blockquote>
<p><strong>사이클릭 코드의 장점</strong>
사이클릭 코드는 하드웨어와 소프트웨어에서 쉽게 구현될 수 있고, 특히 하드웨어에서 구현될 때 빠르게 동작한다</p>
<br/>

<p><strong>+) Checksum</strong></p>
<blockquote>
<p>체크섬은 어떤 길이의 메시지에도 적용될 수 있는 오류 검출 기술로 network layer와 transport layer에서 주로 사용한다</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Data Link Control - Framing]]></title>
            <link>https://velog.io/@gyu_won/Data-Link-Control-Framing</link>
            <guid>https://velog.io/@gyu_won/Data-Link-Control-Framing</guid>
            <pubDate>Wed, 18 Oct 2023 02:35:56 GMT</pubDate>
            <description><![CDATA[<h3 id="data-link-layer">Data-link layer</h3>
<p>TCP/IP layer의 두번째 Data-link layer</p>
<blockquote>
<p>Data-link layer에서는 당장 어디로 보낼지를 생각하는 node-to-node communication이 수행된다</p>
</blockquote>
<p>여기서 node는 end host나 router들을 뜻하고 그들 사이의 network를 link 라고 한다</p>
<p>data는 cable이나 air를 통해서 전달되고 1대 1 방식의 point-to-point link나 1대 다 방식의 broadcast link 방식을 사용한다</p>
<h3 id="two-sublayers">Two sublayers</h3>
<blockquote>
<p>data-link layer의 역할을 잘 이해하기 위해서 data-link layer를 아래와 같이 2개의 sub layer로 나누어서 표현하기도 한다
<img src="https://velog.velcdn.com/images/gyu_won/post/46463205-e8c0-4c79-acd6-b351f9feb6a4/image.png" alt=""></p>
</blockquote>
<p> Broadcast link 에서는 1대 다 방식이기 떄문에 누가 보냈는지를 control 해야하는 media-access-conrol sublayer가 필요하다</p>
<p> 반면에 point-to-point layer에서는 1대 1방식이기 때문에 이게 필요없다</p>
<hr>
<h3 id="data-link-control-dlc">Data-Link Control (DLC)</h3>
<p>아래의 2가지 기능을 가짐</p>
<ul>
<li>framing</li>
<li>error control</li>
</ul>
<h3 id="framing">Framing</h3>
<blockquote>
<p>message를 분리해서 frame에 담는 것</p>
</blockquote>
<p>frame이 클수록 flow control이나 error control이 어려워진다</p>
<ul>
<li>한개의 bit만 error가 나도 전체 frame을 다 보내야하니 문제가 됨</li>
</ul>
<h4 id="frame-size">Frame size</h4>
<p>그렇다면 frame 크기는 어떻게 지정할 것이냐</p>
<blockquote>
<p>frame의 크기는 기준이 없기 떄문에 고정크기로 해도 되고 가변크기로 해도 된다</p>
</blockquote>
<p>이때 고정크기를 하면 boundary를 명시할 필요가 없지만 가변 크기로 하면 boundary를 명시해 줘야함</p>
<h4 id="character-oriented-framing">Character-oriented Framing</h4>
<blockquote>
<p>이 프레이밍 유형에서 전송되는 데이터는 8-bit 문자로 구성된다</p>
</blockquote>
<p>Header에는 출발지와 목적지 주소, 그리고 다른 제어 정보를 포함하며, 8-bit의 배수로 구성된다</p>
<blockquote>
</blockquote>
<p>Trailer는 오류 감지를 위한 중복 비트를 포함하며, 8-bit의 배수로 구성된다</p>
<blockquote>
</blockquote>
<p>또한 추가로 하나의 프레임을 다음 프레임과 구분하기 위해, 프레임의 시작과 끝에 8-bit flag가 추가된다 (이런 flag는 data-link layer에만 존재함)</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/2b96ceaa-9fd1-4ef3-b1c9-eac813e61398/image.png" alt=""></p>
<p>그런데 flag가 data에도 똑같이 있으면 수신기는 이게 frame의 끝이라고 판단 할 수도 있음</p>
<p>이를 해결하기 위해 byte-stuffing 전략을 사용한다</p>
<p>** Byte Stuffing **</p>
<blockquote>
<p>프레임의 시작과 끝을 표시하기 위한 특별한 바이트(flag)가 데이터 내용 자체에도 나타날 경우 그것을 특정한 data를 삽입하여 구별하는 방법</p>
</blockquote>
<p> 이렇게 추가되는 data를 escape character(ESC) 라고 한다
<img src="https://velog.velcdn.com/images/gyu_won/post/d9ab98e2-f10f-42f8-9633-f00731b40797/image.png" alt=""></p>
<p>위와 같이 수신자가 ESC를 만나면 ESC를 제거하고 다음 section의 data를 data로 인식한다</p>
<p>즉, flag가 그냥 나오면 data의 경계로 인식하지만 esc 다음에 flag가 나오면 이는 data의 일부로 판단한다</p>
<br/>

<h4 id="bit-oriented-framing">Bit-oriented Framing</h4>
<blockquote>
<p>이 framing 유형에서 전송되는 data는 bit 열이다</p>
</blockquote>
<p>bit framing에서는 flag로 8-bit flag를 사용한다 
(01111110을 주로 사용함, data pattern으로 자주 사용되지 않아서 HDLC나 PPP에 사용)</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/9d0d7edf-87b5-415b-b0ef-d0ea6ef3f016/image.png" alt=""></p>
<p>bit-oriented framing에서는 실제 data의 패턴이 flag로 해석되는 것을 막기 위해서 bit stuffing을 사용한다</p>
<p>** Bit stuffing **</p>
<blockquote>
</blockquote>
<p>5개의 1이 연속으로 나오면 다음으로 0 한개를 추가하는 방식이다</p>
<p>이 방식을 사용하면 receiver는 data로써 01111110을 받을 수 없다
수신측에서는 반대로 1 5개 이후의 0은 무조건 제거하면 된다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Transmission Media]]></title>
            <link>https://velog.io/@gyu_won/Transmission-Media</link>
            <guid>https://velog.io/@gyu_won/Transmission-Media</guid>
            <pubDate>Tue, 17 Oct 2023 15:50:46 GMT</pubDate>
            <description><![CDATA[<h3 id="transmission-media">Transmission Media</h3>
<blockquote>
<p>Physical layer 아래에 존재하고 있으며 physical layer의 통제를 받는다
<img src="https://velog.velcdn.com/images/gyu_won/post/cb367a8e-bbc6-40c3-a609-82b267eccf8e/image.png" alt=""></p>
</blockquote>
<p>hidden layer로 유선, 무선 이런 선의 느낌임</p>
<hr>
<h3 id="guided-media-유선">Guided Media: 유선</h3>
<ol>
<li>twisted-pair cable</li>
<li>coaxial cable</li>
<li>fiber-optic cable</li>
</ol>
<h4 id="twisted-pair-cable">twisted-pair cable</h4>
<blockquote>
<p>두개의 도체(주로 구리)가 한개의 플라스틱 절연체로 꼬여서 감싸져 있는 것
(유선 중에서는 느린편)</p>
</blockquote>
<p>metal shield로 씌워져 있냐 없냐에 따라서 unshielded twisted pair(UTP)와 shielded twisted pair(STP)로 나뉜다
<img src="https://velog.velcdn.com/images/gyu_won/post/e06ff2dd-f09a-416f-83c7-1e599f35d481/image.png" alt=""></p>
<p>위 그래프에서 gauge가 클수록 얇은 거고 작을수록 굵은 거다
세로축의 attenuation은 감쇄량으로 km당 얼마나 감쇄되었는가를 나타낸다
속도가 빠를 수록 감쇄량의 차이도 커진다는 것을 알 수 있다</p>
<h4 id="coaxial-cable">coaxial cable</h4>
<blockquote>
<p>동축케이블로 중간에 core가 있고 이를 절연피복이 덮고 있다
(twisted-pair cable 보다 성능 우수)
<img src="https://velog.velcdn.com/images/gyu_won/post/8fc8cada-51a1-4d4c-b797-efbde7dda1f6/image.png" alt=""></p>
</blockquote>
<p>coaxial cable도 굵기가 굵어질수록 감쇄량이 약한것을 알 수 있다</p>
<h4 id="fiber-optic-cable">fiber-optic cable</h4>
<blockquote>
<p>유리나 플라스틱으로 만들어진 광케이블로 빛의 형태로 신호를 전달한다
<img src="https://velog.velcdn.com/images/gyu_won/post/dd5ceb09-7808-436b-b2cc-29d56da19b73/image.png" alt=""></p>
</blockquote>
<p>반사각을 이용해서 빛이 반사되면서 신호가 이동한다</p>
<hr>
<h3 id="unguided-media-무선">Unguided Media: 무선</h3>
<blockquote>
<p>physical conductor(전기전도체) 없이 전송되는 것</p>
</blockquote>
<p>신호는 주로 broadcast 되기 때문에 그 신호를 받을 수 있는 장치만 있으면 누구나 신호를 받을 수 있다</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/fe1ebd60-3244-49b8-9a02-b141db5bd9c2/image.png" alt=""></p>
<p>위 그림은 무선 통신에 사용되는 전자기 스펙트럼을 3kHz에서 900 THz까지 보여준 예시이다</p>
<h4 id="radio-waves">Radio waves</h4>
<blockquote>
<p>3KHz 부터 1GHz 까지의 주파수를 가지는 전자기파를 radiowaves 라고 한다</p>
</blockquote>
<p>radio waves는 대부분 전방향으로 통신한다</p>
<ul>
<li>보내는 방향을 따로 안정해도 되기 때문에 장점이면서도 간섭에 취약하다는 단점도 있다</li>
</ul>
<h4 id="micro-waves">Micro waves</h4>
<blockquote>
<p>1GHz 부터 300GHz 까지의 주파수를 가지는 전자기파를 microwaves 라고 한다</p>
</blockquote>
<p>micro waves는 단방향으로 통신한다</p>
<ul>
<li>따라서 수신자를 할당해야 하지만 수신자를 할당하기 때문에 간섭이 적다</li>
</ul>
<h4 id="infrared-waves">Infrared waves</h4>
<blockquote>
<p>300GHz 부터 400THz 까지의 wave를 의미한다</p>
</blockquote>
<p>고주파수이기 때문에 짧은 거리의 통신에 이용된다</p>
<p>고주파수이기 때문에 벽을 통과 못한다</p>
<ul>
<li>장점: 다른 시스템과의 간섭을 방지한다</li>
<li>단점: 잘 안터진다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Multiplexing]]></title>
            <link>https://velog.io/@gyu_won/Multiplexing</link>
            <guid>https://velog.io/@gyu_won/Multiplexing</guid>
            <pubDate>Tue, 17 Oct 2023 15:27:49 GMT</pubDate>
            <description><![CDATA[<h3 id="multiplexing">Multiplexing</h3>
<blockquote>
<p>동시에 여러 신호를 전송할 수 있게끔 해준다</p>
</blockquote>
<p>다중화 시스템에서는 n개의 input line이 하나의 link 대역폭을 공유한다</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/6d744a22-90d5-49ba-9dad-cf2b313ee766/image.png" alt=""></p>
<p>위그림에서 왼쪽의 multiplexer는 여러 전송 스트림들을 하나의 스트림으로 결합하고, 오른쪽의 demultiplexer에서는 그 구성요소를 다시 분리하고 해당 라인으로 보내준다</p>
<p>Multiplexing의 방법으로 FDM과 TDM이 있다</p>
<h4 id="frequency-division-multiplexingfdm">Frequency-Division Multiplexing(FDM)</h4>
<blockquote>
<p>여러 개의 신호를 하나의 링크에 동시에 전송하기 위해 각 신호를 다른 주파수 대역에 할당하는 것
<img src="https://velog.velcdn.com/images/gyu_won/post/cdc73a08-49d7-4a94-8844-3044d4b0fc4b/image.png" alt=""></p>
</blockquote>
<p>위 예시에서는 주파수 대역을 3개의 channel로 나누었음</p>
<p>링크의 대역폭이 함께 전송되어야 하는 신호들의 총합 대역폭보다 클 때 적용할 수 있는 아날로그 기술이다</p>
<p>신호들이 서로 중첩되는 것을 방지하기 위에 채널들은 사용되지 않는 대역폭의 띠인 가드 밴드에 의해 분리될 수 있다</p>
<br/>

<h4 id="time-division-multiplexingtdm">Time-Division Multiplexing(TDM)</h4>
<blockquote>
<p>여러 연결이 하나의 링크의 높은 대역폭을 공유할 수 있게 하며, 각 연결은 순차적으로 일정한 시간 동안 데이터를 전송하도록 하는 방법
<img src="https://velog.velcdn.com/images/gyu_won/post/1b531ee7-dcd4-4bee-96b9-5a99361ac810/image.png" alt=""></p>
</blockquote>
<p>대역폭을 나누니까 속도가 줄기 때문에 시간을 나누어서 전송한다</p>
<p>여기도 역시 guard time이 존재함</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Analog Transmission]]></title>
            <link>https://velog.io/@gyu_won/Analog-Transmission</link>
            <guid>https://velog.io/@gyu_won/Analog-Transmission</guid>
            <pubDate>Tue, 17 Oct 2023 15:13:39 GMT</pubDate>
            <description><![CDATA[<p>bandpass channel에서 analog 신호를 보내는데 이때 analog Transmission이 필요하다</p>
<blockquote>
</blockquote>
<ol>
<li>digital-to-analog
digital 신호를 bandpass analog 신호로 변환하기 위함<blockquote>
</blockquote>
</li>
<li>analog-to-analog
낮은 대역의 analog 신호를 bandpass analog 신호로 변환하기 위함</li>
</ol>
<h3 id="digital-to-analog-conversion">Digital-to-Analog Conversion</h3>
<h4 id="amplitude-shift-keyingask">Amplitude Shift Keying(ASK)</h4>
<blockquote>
<p>디지털 데이터를 표현하기 위해 analog 신호의 진폭을 변조하는 기술</p>
</blockquote>
<p>기본적으로, 디지털 비트의 값에 따라 신호의 진폭을 변경하여 데이터를 인코딩한다
<img src="https://velog.velcdn.com/images/gyu_won/post/a37eeba2-893a-4307-a217-23dbd757352d/image.png" alt=""></p>
<p>위의 예시에서는 데이터가 1이면 sin wave가 3번, 0이면 없는걸로 정의함</p>
<blockquote>
</blockquote>
<p>S: signal rate(baud): 초당 몇 symbol을 보냈는가
(주파수가 정해지면 baud rate을 정의할 수 있음)
B: bandwidth (대역폭)
r: 1 symbol에 몇 bit인지
d: modulation이나 filtering 하는데 사용되는 낭비되는 구간 (0~1)</p>
<p>ASK는 진폭으로 신호를 구분하기 때문에 r이 커지면 sin 파의 높낮이가 달라진다</p>
<p>즉, 주파수를 여러개 사용하지 않는다
그래서 위의 그림에서도 주파수의 기준은 fc 한개만 사용하는 것을 알 수 있다</p>
<p>하지만 noise에 따라 신호가 약해지면 다른 신호가 되어버리기 때문에 장거리, 고속 전송에 불가능하다</p>
<br/>

<h4 id="frequency-shift-keyingfsk">Frequency Shift Keying(FSK)</h4>
<blockquote>
<p>진폭은 그대로 두고 Frequency만 변환하는 기법
<img src="https://velog.velcdn.com/images/gyu_won/post/c40eb242-b3ec-4a49-a7a5-93a9ec95769c/image.png" alt=""></p>
</blockquote>
<p>두 신호의 주파수가 다르기 때문에 f1, f2 2개의 주파수가 필요한다</p>
<p>즉, r이 커지면 더 많은 주파수를 필요로 함</p>
<br/>

<h4 id="phase-shift-keyingpsk">Phase Shift Keying(PSK)</h4>
<blockquote>
<p>phase를 달리하는 기법
<img src="https://velog.velcdn.com/images/gyu_won/post/25bb0581-6d67-4bdb-9e5c-343258ca3399/image.png" alt=""></p>
</blockquote>
<p>신호의 phase가 다른 것으로 위의 사진과 같이 binary일 경우에는 0, 180으로 나눔</p>
<p>진폭이 같기 때문에 베터리 소모도 동일하고 주파수도 하나만 써서 제일 많이 쓰는 기술</p>
<hr>
<h3 id="analog-to-analog-conversion">Analog-to-Analog Conversion</h3>
<h4 id="amplitude-modulationam">Amplitude Modulation(AM)</h4>
<blockquote>
<p>modulating signal의 amplitude를 보고 carrier frequency를 곱해서 amplitude를 변환하는 기법
<img src="https://velog.velcdn.com/images/gyu_won/post/e03bd978-1b2c-47fd-b191-7a145352512f/image.png" alt=""></p>
</blockquote>
<p>Oscillator: 반복적인 변화 신호를 생섬함</p>
<h4 id="frequency-modulationfm">Frequency Modulation(FM)</h4>
<blockquote>
<p>modulating signal의 amplitude를 보고 carrier frequency를 곱해서 frequency를 변환하는 기법
<img src="https://velog.velcdn.com/images/gyu_won/post/13e0c7b2-e5c1-4c57-b386-71403715fef1/image.png" alt=""></p>
</blockquote>
<h4 id="phase-modulationpm">Phase Modulation(PM)</h4>
<blockquote>
<p>modulatin signal의 amplitude의 변화율을 보고 carrier frequency를 곱해서 frequency를 변환하는 기법
<img src="https://velog.velcdn.com/images/gyu_won/post/db2503af-2bd4-4201-bfed-ff84051e4628/image.png" alt=""></p>
</blockquote>
<p>FM이랑 비슷해 보이지만 차이점은 FM은 modulatin signal의 amplitude 값을 보고 곱하였지만 PM은 amplitude의 변화율을 보고 곱한다</p>
<p>위에서 보면 알겠지만 analog-to-analog는 digital-to-analog와 다르게 주파수가 바뀌더라도 주파수를 2개를 쓰는게 아니라 연속적으로 이어져있다 
(한마디로 주파수가 특정하게 정해져 있는게 아니라 연속적인 값을 띈다는 뜻)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Digital Transmission]]></title>
            <link>https://velog.io/@gyu_won/Digital-Transmission</link>
            <guid>https://velog.io/@gyu_won/Digital-Transmission</guid>
            <pubDate>Tue, 17 Oct 2023 14:25:46 GMT</pubDate>
            <description><![CDATA[<p>정보 전달을 위해서 신호는 digital 신호로 변환되기도 한다.</p>
<blockquote>
<p>Digital Transmission에는 아래와 같이 2가지 변환이 있을 수 있다</p>
</blockquote>
<ul>
<li>digital-to-digital conversion</li>
<li>analog-to-digital conversion</li>
</ul>
<h3 id="digital-to-digital-conversion">Digital-to-Digital Conversion</h3>
<blockquote>
<p>digital 신호를 digital 신호로 변환</p>
</blockquote>
<p>대표적인 변환 기술</p>
<ol>
<li>line coding</li>
<li>block coding</li>
<li>scrambling</li>
</ol>
<p>line coding은 항상 필요하고 block coding과 scrambling은 필요 할 수도 있고 안할 수도 있다</p>
<h4 id="line-coding">Line Coding</h4>
<blockquote>
<p>digital bit sequence를 전기신호로 변환하는 것을 생각하면 된다</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/a79bea82-a866-4f5f-829c-b64f0bc475ac/image.png" alt=""></p>
<p>사진과 같이 0이면 위로, 1이면 아래로</p>
<br/>

<h4 id="block-coding">Block Coding</h4>
<blockquote>
<p>데이터 블록을 다른 형식의 데이터 블록으로 변환하는 방법</p>
</blockquote>
<p>synchronization, error control을 위하여 redundancy가 필요한데 이런 경우에 block coding을 사용하여 m bit block을 n bit block으로 바꿀 수 있다
(mB/nB encoding이라고도 부름)</p>
<blockquote>
</blockquote>
<p>block coding의 순서</p>
<blockquote>
</blockquote>
<ol>
<li>division: 연속적인 bit들은 m bit 블록으로 나누어진다</li>
<li>substitution: m bit 블록을 n bit 블록으로 바꾼다</li>
<li>combination: n bit 블록들은 합쳐서 보낸다</li>
</ol>
<hr>
<h3 id="analog-to-digital-conversion">Analog-to-Digital Conversion</h3>
<blockquote>
<p>Analog 신호를 Digital 신호로 변환</p>
</blockquote>
<p>대표적인 2가지 기술</p>
<blockquote>
</blockquote>
<ul>
<li>pulse code modulation</li>
<li>delta modulation</li>
</ul>
<br/>

<h4 id="pulse-code-modulation-pcm">Pulse-Code modulation (PCM)</h4>
<blockquote>
<p>sampling, quantizing, encoding 과정을 통해 analog 신호를 digital 신호로 바꿈</p>
</blockquote>
<ol>
<li><p>sampling</p>
<blockquote>
<p>연속된 analog 신호가 T개의 sample들로 나눔</p>
</blockquote>
</li>
<li><p>quantizing (양자화)</p>
<blockquote>
<p>연속된 값을 나타내는 sample들을 level로 나누어 digital 숫자로 바꿈</p>
</blockquote>
</li>
<li><p>encoding</p>
<blockquote>
<p>양자화된 디지털 숫자 값을 전송 가능한 이진 코드로 변환함</p>
</blockquote>
</li>
</ol>
<p>그러면 몇개를 샘플링 해야할까?</p>
<p>Nyquist-Shannon Sampling Theorem</p>
<blockquote>
<p>모든 신호는 그 신호에 포함되 가장 높은 주파수의 2배에 해당하는 빈도로 일정한 간격으로 샘플링 하면 원래 신호를 완벽하게 기록할 수 있다.</p>
</blockquote>
<blockquote>
<p>문제
<img src="https://velog.velcdn.com/images/gyu_won/post/7f9def59-df5f-49b6-b046-5c58113f7131/image.png" alt=""></p>
</blockquote>
<p>Nyquist-Shannon sampling theorem에 따라서 최대 4000Hz 까지 주파수를 가지는 인간의 목소리는 이의 2배인 8000개/second 로 샘플링하면 완벽하게 기록할 수 있다</p>
<blockquote>
</blockquote>
<p>그리고 한 샘플 당 8bit라고 했으니 총 bit rate는 64Kbps 가 요구된다</p>
<br/>

<h4 id="delta-modulation-dm">Delta Modulation (DM)</h4>
<blockquote>
<p>delta(변화량)을 통해서 값을 변환하는 기술</p>
</blockquote>
<p>PCM이 signal의 크기를 직접 고려했기 때문에 복잡하다는 단점이 있었다</p>
<p>그래서 DM은 이를 극복하기 위해 실제 값이 아닌 변화추이를 본다
<img src="https://velog.velcdn.com/images/gyu_won/post/92f920d8-84f8-4096-9e92-cc25d7d0f3e9/image.png" alt=""></p>
<p>위와 같은 신호가 있으면 sample 단위로 level의 변화 추위를 보고 digital 신호로 변환함</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Signal Impairment]]></title>
            <link>https://velog.io/@gyu_won/Signal-Impairment</link>
            <guid>https://velog.io/@gyu_won/Signal-Impairment</guid>
            <pubDate>Tue, 17 Oct 2023 13:48:42 GMT</pubDate>
            <description><![CDATA[<h3 id="signal-impairment-신호-손상">Signal Impairment: 신호 손상</h3>
<blockquote>
<p>자연현상, line의 문제, hardware의 제약 등으로 signal은 손상 될 수 있다</p>
</blockquote>
<p>signal 손상의 3가지 종류에는 3가지가 있다</p>
<ul>
<li>attenuation: 감쇄</li>
<li>distortion: 왜곡</li>
<li>noise: 잡음</li>
</ul>
<hr>
<h3 id="attenuation">Attenuation</h3>
<blockquote>
<p>거리가 멀거나 저항을 극복하면서 신호가 약해지는 것</p>
</blockquote>
<p>이를 해결하기 위해 중간중간에 증폭기를 달아서 신호를 증폭시켜서 해결한다</p>
<br/>

<p><strong>attenuation(힘의 손실) 계산</strong></p>
<blockquote>
<p>10 x log10 (P2/P1)
신호를 P1의 크기로 쐈는데 P2로 받았다고 할 때</p>
</blockquote>
<p>만일 P2 = 0.5 P1이면
10 log10 (P2/P1) = 10 log10 (0.5) = 10 x -0.3 = -3dB (약 2배)</p>
<p>신호나 소리는 무조건 크다고 좋은것이 아니다
-&gt; 다른 신호에 noise가 될 수 있고 전력도 많이 소모하기 때문</p>
<p>따라서 신호나 소리는 절대적인 크기보다는 상대적인게 중요하기 때문에 dB 단위를 사용하여 상대적인 값을 표현한다</p>
<h3 id="distortion">Distortion</h3>
<blockquote>
<p>왜곡은 신호의 모양이나 형태가 바뀌는 것으로 현실적으로는 복구가 어렵기 때문에 일단 신호를 수신하고 bit 단에서 문제를 해결한다</p>
</blockquote>
<h3 id="noise">Noise</h3>
<blockquote>
<p>일반적으로 백색 잡음을 뜻하며 Noise는 다른 손상의 원인이 되기도 한다</p>
</blockquote>
<h4 id="snr-signal-to-noise-ratio">SNR (Signal-to-Noise Ratio)</h4>
<blockquote>
<p>잡음 대비 신호의 크기를 뜻한다 (average signal power) / (average noise power)</p>
</blockquote>
<p>SNR은 단순히 비율이고 상대적인 값인 SNRdB를 구하기 위해서는 아래 수식을 이용한다
<img src="https://velog.velcdn.com/images/gyu_won/post/9157bd58-f004-49f8-ba93-38fdf4a9360f/image.png" alt=""></p>
<p>여기서 SNR이 DB로 주어졌는지 그냥 SNR 값으로 주어졌는지를 잘 확인해야 한다</p>
<hr>
<h3 id="data-rate-limits-전송-속도-제한">Data Rate Limits: 전송 속도 제한</h3>
<p>전송 속도에는 최대 제한이 있는데 이를 결정하는 요인에는 아래의 3가지가 있다</p>
<blockquote>
<ol>
<li>사용가능한 대역폭</li>
<li>사용하는 신호의 level 수</li>
<li>channel의 품질 (noise의 양, SNR)</li>
</ol>
</blockquote>
<p>그리고 위의 요인들을 활용해서 최대 전송 속도를 구하는 2가지 이론이 있다</p>
<blockquote>
</blockquote>
<ol>
<li>Nyquist 이론</li>
<li>Shannon 이론</li>
</ol>
<h4 id="nyquist-bit-rate">Nyquist bit rate</h4>
<blockquote>
<p>noise가 없는 channel(현존하지 않음)에서 max bit rate을 다음과 같이 정의한다
<img src="https://velog.velcdn.com/images/gyu_won/post/9d938de4-7b35-49f6-a9e3-816ad42b8541/image.png" alt=""></p>
</blockquote>
<p>B: bandwidth / L: level 개수</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/d1d6c6b2-7a32-406f-bba3-4b1d134db5eb/image.png" alt=""></p>
<p>위의 결과로 98.7개의 level이 필요하다고 했는데 level은 2의 제곱수만 가능하므로 가까운 64 level을 택해서 최대 속도를 낮추던가 128 level을 택해서 최대 속도를 늘려야한다</p>
<br/>

<h4 id="shannon-capacity">Shannon Capacity</h4>
<blockquote>
<p>noise가 있는 channel 에서는 Capacity라고 부르고 아래와 같이 정의한다
<img src="https://velog.velcdn.com/images/gyu_won/post/8d32527f-ef15-4b18-9052-718ddfe757f5/image.png" alt=""></p>
</blockquote>
<p>위 식에서는 bandwidth와 SNR을 사용하기 때문에 요인 3가지 (대역폭, level수, noise)를 모두 고려하였다</p>
<p>SNR은 noise 대비 신호의 세기인데 세기가 크면 level을 더 많이 나눌 수 있으니 level을 고려한 것으로 봄</p>
<p>여기서 SNR은 dB 단위가 아니기 때문에 dB 단위로 주어지면 변환 후 사용해야 한다</p>
<p>noise가 너무 많은 채널일 경우에는 SNR이 거의 0에 가까운 값이 된다
<img src="https://velog.velcdn.com/images/gyu_won/post/33d8a134-8e58-43d6-91bf-81ca85e6f2a2/image.png" alt=""></p>
<p>이때는 capacity도 0에 근접하게 된다. 즉 bandwidth가 넓다고 속도가 빨라지는 것은 아니다 (noise 도 고려해야함)
<img src="https://velog.velcdn.com/images/gyu_won/post/9a95584b-d218-489d-b669-e639e2687092/image.png" alt=""></p>
<h4 id="data-rate-limits">Data Rate Limits</h4>
<blockquote>
<p>현실에서는 noise가 있기 때문에 주로 Shannon을 사용하지만 역으로 특정한 최대 속도를 가지기 위해서 어떤 값을 설정해야하는지 정할 때느 Nyquist를 사용하기도 한다</p>
</blockquote>
<hr>
<h3 id="performance">Performance</h3>
<p>그렇다면 실제로 성능은 어떻게 측정하는가?</p>
<blockquote>
</blockquote>
<ol>
<li>Bandwidth</li>
<li>Throughput</li>
<li>Latency(delay)</li>
</ol>
<h4 id="throughput-처리량">Throughput: 처리량</h4>
<blockquote>
<p>실제로 전송되는 데이터의 속도로 네트워크 혼잡도, 패킷 손실, 지연시간, 프로토콜 오버헤드 등을 반영한다</p>
</blockquote>
<p>throughput은 결국 layer의 관점에 따라 다르다</p>
<p>이에 반에 capacity는 물을 흘려보내는 파이프 통으로 실제로 보낼 수 있는 양을 의미함</p>
<h4 id="latencydelay-지연">Latency(Delay): 지연</h4>
<blockquote>
<p>첫번쨰 bit가 출발해서 destination에 도착할 때까지의 시간</p>
</blockquote>
<p>보통 저렇게 정의하지만 일반적으로 latency는 연구자가 다르게 정의하기는 함</p>
<p>그러면 latency를 어떻게 계산하는가</p>
<blockquote>
</blockquote>
<p>Latency = transmission delay + propagation delay + queuing delay + processing delay</p>
<ol>
<li><p>transmission delay</p>
<blockquote>
<p>패킷이 물리적 링크를 통과하는데 걸리는 시간 (패킷의 크기와 bps에 영향을 받는다)</p>
</blockquote>
<p>편지를 쓰는 시간으로 생각하면 됨 (편지 크기랑 편지 쓰는 속도에 영향을 받음)</p>
</li>
<li><p>propagation delay</p>
<blockquote>
<p>실제로 전파되는데 걸리는 시간 (거리와 전파 속도에 영향을 받음)</p>
</blockquote>
<p>편지가 배달되는 시간이라 생각하면 됨 (목적지까지 거리랑 배달속도에 영향 받음)</p>
</li>
<li><p>queuing delay</p>
<blockquote>
<p>특정 장치에 들어갈 때 queue에 머무는 시간</p>
</blockquote>
<p>편지가 배달될 때 옥천 Hub에서 들어가는데 기다리는 시간 (가장 큰 영향을 미침)</p>
</li>
<li><p>processing delay</p>
<blockquote>
<p>포괄적인 개념으로 어디로 보낼지 등을 판단하는데 걸리는 시간</p>
</blockquote>
<p>편지 배달부가 편지를 주소를 보고 판단하는데 걸리는 시간</p>
</li>
</ol>
<p>이렇게 bandwidth랑 delay는 성능을 결정하는데 중요한 요소이고 bandwidth x delay로 연결통로(pipe)의 Volumne이라고 말한다</p>
<h4 id="jitter">Jitter</h4>
<blockquote>
<p>첫번째 data와  두번째 data 사이의 시간과 두번째 data와 세번째 data 사이의 시간</p>
</blockquote>
<p>즉, jitter가 0이면 신호가 일정하게 들어온다는 것이다 (안정적)</p>
<p>실시간을 중요시하는 통신에서는 Jitter가 매우 중요하다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Signal]]></title>
            <link>https://velog.io/@gyu_won/Signal</link>
            <guid>https://velog.io/@gyu_won/Signal</guid>
            <pubDate>Tue, 17 Oct 2023 12:42:57 GMT</pubDate>
            <description><![CDATA[<p>physical layer에서는 signal을 다룬다</p>
<h3 id="signals란">Signals란?</h3>
<blockquote>
<p>signal은 아래 그림과 같이 analog signal과 digital signal로 나눌 수 있다</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/1dec9704-5583-4fe4-a6d6-391128b1cc5d/image.png" alt=""></p>
<hr>
<h3 id="analog-signal">Analog signal</h3>
<blockquote>
<p>Analog signal은 또다시 주기적 신호와 비주기적 신호로 나눌 수 있다</p>
</blockquote>
<p>현실에서 신호는 대부분 비주기적 신호이겠지만 여기서는 주기적 신호를 다룬다
(주기적 신호는 더이상 다른 signal로 분해될 수 없는 sin 파로 나타낸다)</p>
<h4 id="아날로그-신호를-다루는-용어">아날로그 신호를 다루는 용어</h4>
<p>** Period: 주기 **</p>
<blockquote>
<p>signal이 한 cycle 도는데 걸리는 시간 (sec 단위)</p>
</blockquote>
<p>** Amplitude: 진폭**</p>
<blockquote>
<p>wave의 중간 지점과 가장 높은 지점 사이의 차이 (V 단위)
(min 부터 max가 아니라 0부터 max인것에 주의)</p>
</blockquote>
<p>** Phase: 위상 **</p>
<blockquote>
<p>시간이 0일때를 기준으로 얼만큼 이동했는가 (도 단위)</p>
</blockquote>
<p>이렇게 T(Phase), A(Aplitude), P(Period)를 신호의 3요소라고 하고 이 3가지만 알면 wave를 그릴 수 있다
<img src="https://velog.velcdn.com/images/gyu_won/post/9648b1e9-00b7-4104-84fd-1993ce985776/image.png" alt=""></p>
<p>** Frequency: 주파수 **</p>
<blockquote>
<p>단위 시간당 몇번 진동했는가를 의미 (Hz 단위, period의 역수)</p>
</blockquote>
<p>** Wavelength: 파장(람다) **</p>
<blockquote>
<p>한 주기동안 간 거리</p>
</blockquote>
<p>람다를 파장, c를 전파속도, f를 주파수, T를 period라고 할 때 아래의 식이 성립함
<img src="https://velog.velcdn.com/images/gyu_won/post/d230c133-647d-42bb-aac3-be1772ec5e3c/image.png" alt=""></p>
<p>즉, 주파수와 파장은 반비례</p>
<blockquote>
<p>문제: 주파수가 30GHz인 신호의 파장은?</p>
</blockquote>
<p>30GHz = 30 x 10의 9승 Hz
빛의 속도 c = 3 x 10의 8승 m/s
따라서 c = 람다 x f, 람다 = (3 x 10의 8승) / (30 x 10의 9승) = 1/100 m = 10 mm</p>
<p>** Bandwidth: 대역폭 **</p>
<blockquote>
<p>frequence의 범위</p>
</blockquote>
<p>sin wave를 여러개 합치면 composite signal을 만들 수 있는데 이 composite signal의 frequence range를 bandwidth라고 한다</p>
<p>composite signal에서 bandwidth는 lowest frequency와 highest frequency를 구해서 그 차이를 뜻함</p>
<blockquote>
<p>Band(대역)를 중심주파수라고 하고 이 주위로 폭이 있는데 그 폭이 bandwidth</p>
</blockquote>
<p>신호의 대역폭에 맞는 전송방식이 있어야 data를 보낼 수 있음</p>
<br/>

<h4 id="time-and-frequency-domain">Time and Frequency Domain</h4>
<blockquote>
<p>가로축이 time 이나 frequency나를 나타내고 아래와 같이 표현할 수 있다</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/ef524b66-3422-490f-94e0-52788e4ec3ec/image.png" alt=""></p>
<hr>
<h3 id="digital-signal">Digital Signal</h3>
<blockquote>
<p>0과 1로만 구성된 신호</p>
</blockquote>
<p>digital 신호는 두개 이상의 level을 가지고 있고  level은 2의 제곱수 개를 가질 수 있다</p>
<p>아래 예시는 level 2개와 4개인 digital 신호를 예시로 든 것으로 1초에 8번 상태 변화가 있더라도 level이 더 많으니 더 많은 신호를 보낼 수 있다</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/54c9c8bc-986f-4b9a-9bda-dce3b391ed3e/image.png" alt=""></p>
<blockquote>
<p>그러면 level이 많으면 무조건 좋은가?
세기가 동일하다는 가정하에 level이 많으면 그만큼 level 사이의 간격이 줄어들기 때문에 오류가 날 가능성이 높아진다</p>
</blockquote>
<h4 id="digital-신호를-다루는-용어">Digital 신호를 다루는 용어</h4>
<p>** Bit rate: 전송 속도 **</p>
<blockquote>
<p>1초에 몇 bit를 보냈냐를 의미 (bit per second: BPS)</p>
</blockquote>
<p>periodic한 analog 신호는 frequency나 period를 통해서 전송속도를 나타낼 수 있지만, digital 신호는 이런 주기가 없기 때문에 bit rate을 속도로 사용한다</p>
<blockquote>
<p>속도의 단위에서 K, M, G</p>
</blockquote>
<ul>
<li>속도의 단위(bps) 에서는 각각이 10의 3승만큼 차이가 남</li>
<li>크기의 단위(byte) 에서는 각각이 2의 10승만큼 차이가 남</li>
</ul>
<blockquote>
<p>문제
<img src="https://velog.velcdn.com/images/gyu_won/post/8512956d-71c5-44d9-94d9-40d11e77af8d/image.png" alt=""></p>
</blockquote>
<p>결국 100 x 24 x 80 x 8 bit를 분당 다운 받은 거임
즉, 100 x 24 x 80 x 8bit = 1,536,000 bit / minute 
= 1,536,000/60 bps = 25,600 bps = 25.6 Kbps</p>
<p>** Bit Length **</p>
<blockquote>
<p>한 bit 보내는데에 몇초가 걸리냐 (bit rate의 역수)</p>
</blockquote>
<blockquote>
<p>앞선 문제에 적용시키면 25.6 Kbps = 1/25,600 sec 
= 0.0000390625 sec = 39.0625 Kbps </p>
</blockquote>
<p>속도에서 단위는 역시 반대로</p>
<ul>
<li>10의 -3승: 밀리</li>
<li>10의 -6승: 마이크로</li>
<li>10의 -9승: 나노</li>
</ul>
<p>로 표현한다</p>
<br/>

<h4 id="digital-신호의-전송">digital 신호의 전송</h4>
<ol>
<li>Baseband transmission</li>
<li>Bandpass transmission</li>
</ol>
<h4 id="baseband-transmission">Baseband transmission</h4>
<blockquote>
<p>앱 내에서 데이터를 주고 받는 경우와 같이 낮은 주파수로 digital 신호를 변환 없이 직접 보냄</p>
</blockquote>
<h4 id="bandpass-transmission">Bandpass transmission</h4>
<blockquote>
<p>외부로 나갈 때와 같이 높은 주파수 대역으로 digital 신호를 analog 신호로 변환하여 보냄</p>
</blockquote>
<p>근데 이거 왜 bandpass는 멀리 가려면 낮은 주파수 대역이 필요한데 왜 높은 주파수 대역으로 보내지?</p>
<blockquote>
<p>규제 및 사용가능한 대역이 정해져 있고 고주파수 대역이 일반적으로 더 넓은 대역폭을 제공할 수 있기 때문에 더 높은 데이터 전송률을 지원하기 때문이다</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Layered Architecture]]></title>
            <link>https://velog.io/@gyu_won/Layered-Architecture</link>
            <guid>https://velog.io/@gyu_won/Layered-Architecture</guid>
            <pubDate>Tue, 17 Oct 2023 11:43:26 GMT</pubDate>
            <description><![CDATA[<p>TCP/IP protocol은 아래와 같다
<img src="https://velog.velcdn.com/images/gyu_won/post/94b3cb37-48b1-4ae1-bb6b-0cdb0ac9fc23/image.png" alt=""></p>
<p>각각의 layer는 세부적으로 깊게 배우겠지만 대략적인 역할들을 짚고 넘어가자</p>
<hr>
<h3 id="physical-layer">Physical Layer</h3>
<blockquote>
<p>한개의 hop에서 다음 hop으로 넘어가는데 각각의 bit들의 움직임에 책임진다 
(주소 개념이 없음)</p>
</blockquote>
<p>이 계층은 전기적인 신호의 전송 기술도 포함한다
<img src="https://velog.velcdn.com/images/gyu_won/post/b12def37-6206-4bed-adac-c315e0633b3c/image.png" alt=""></p>
<p>받는이 입장에서 갑자기 data를 보내면 받을 수 없으니 보내기 전에 다른걸 먼저 보내서 받는이가 준비를 할 수 있도록 하다가 110이라는 bit를 보면 이제부터 data구나 를 인지하도록 한다</p>
<hr>
<h3 id="data-link-layer">Data Link Layer</h3>
<blockquote>
<p>한개의 hop에서 다음 hop으로 넘어가는데 각각의 frame들의 움직임을 책임진다</p>
</blockquote>
<p>Data-link layer의 data를 Frame이라고 부른다</p>
<blockquote>
</blockquote>
<p>Framing, hop-to-hop delivery, Error control과 같은 역할을 한다</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/a16882b8-a159-4655-a91c-513cdf4f3838/image.png" alt=""></p>
<p>위 그림과 같이 header와 trailer를 붙이거나 떼고 header에는 Mac Address 정보나 control 정보 같은게 포함된다
Mac address를 data-link layer에서 붙이고, 떼기 때문에 data-link 계층의 입장에서 data에는 Mac Address는 포함되지 않는다</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/0359dbf1-54dd-496a-9aaf-63c667d03407/image.png" alt=""></p>
<p>physical layer와 같이 flag 정보도 포함한다</p>
<p>그리고 Data-link 계층의 Mac 주소는 각각이 4bit * 12 자리로 48bit 주소이다
(IPv4는 32bit, IPv6는 128bit)</p>
<hr>
<h3 id="network-layer">Network Layer</h3>
<blockquote>
<p>packet들을 source에서 destination으로 보내는데 책임이 있다</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/0dee4255-3641-4a3f-8787-25b3c582dbc3/image.png" alt=""></p>
<p>data에 header를 붙이는데 이 header에는 IP 주소가 포함되어 있어 host-to-host service를 제공한다
IP Address를 network layer에서 붙이고, 떼기 때문에 network 계층의 입장에서 data에는 IP Address는 포함되지 않는다</p>
<blockquote>
<p>즉, network layer의 두가지 기능은 아래와 같다</p>
</blockquote>
<ol>
<li>host addressing</li>
<li>packet routing
<img src="https://velog.velcdn.com/images/gyu_won/post/c96e934b-8393-48d6-bb48-c9e5153f1e69/image.png" alt=""></li>
</ol>
<ul>
<li>위 그림에서 IP address는 바뀌지 않고 Mac Address는 계속 바뀐다는 것을 알 수 있음</li>
</ul>
<p>network layer에서는 data를 packet이라고 부르고 IP에 의해 사용되는 것을 datagram이라고 부른다</p>
<p>datagram은 header와 payload(실제 data)로 나뉘고 header는 아래와 같이 가변적인 길이를 가진다 (20 byte ~ 60 byte)</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/73ed97ff-ca5f-4ee9-996f-a7d9a6a4087a/image.png" alt=""></p>
<hr>
<h3 id="transport-layer">Transport Layer</h3>
<blockquote>
<p>message를 process에서 process로 전달하는 역할을 한다 (end-to-end)</p>
</blockquote>
<p>Error, flow, congestion control과 process-to-process delievery를 수행한다</p>
<p>application 에서 받은 data를 segments로 나누고 header를 붙이는데 이 header에는 port number가 포함되어 있다</p>
<p>port number를 Transport layer에서 붙이고, 떼기 때문에 Transport 계층의 입장에서 data에는 Port number는 포함되지 않는다</p>
<p>가장 대표적인 UDP와 TCP에 대해서 간략히 알아보자</p>
<blockquote>
<p>UDP: TCP에 비해서 상당히 간단하며 잘보냈는지 확인같은거는 하지 않는 connectionless 방식이다</p>
</blockquote>
<p>TCP: 데이터가 잘 보냈는지 확인도 하는 connection-oriented 방식이다</p>
<p>TCP의 이런 추가 기능들 때문에 TCP header가 훨씬 복잡함</p>
<hr>
<h3 id="application-layer">Application Layer</h3>
<blockquote>
<p>user에게 service를 제공하는것에 책임을 지는 것으로 주로 개인이 정의해서 쓴다</p>
</blockquote>
<p>대표적으로 HTTP, FTP, SMTP, DHCP 등이 있다</p>
<p>url 주소와 같은 names 주소가 포함된다</p>
<hr>
<p>Layered Architecture를 Protocol의 관점에서 보면 아래와 같다</p>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/af35ac49-d0bf-441d-aa97-fb347b6152e2/image.png" alt=""></p>
<hr>
<p>결국 Addressing을 통해서 데이터를 전송하고 TCP/IP 5계층 에서는 4쌍의 주소체계게 필요하다</p>
<ul>
<li>physical layer는 필요없음</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[OSI Model과 한계]]></title>
            <link>https://velog.io/@gyu_won/OSI-Model%EA%B3%BC-%ED%95%9C%EA%B3%84</link>
            <guid>https://velog.io/@gyu_won/OSI-Model%EA%B3%BC-%ED%95%9C%EA%B3%84</guid>
            <pubDate>Mon, 16 Oct 2023 14:19:25 GMT</pubDate>
            <description><![CDATA[<p>TCP/IP protocol suite 외에도 다른 model도 존재한다</p>
<p>그런데 왜 TCP/IP만 쓰지?</p>
<h3 id="osi-model">OSI Model</h3>
<blockquote>
<p>ISO에 의해서 표준화된 모델</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/600ec2b0-fca1-4705-86a0-d79f0a036911/image.png" alt=""></p>
<p>위 사진에서 보는 것과 같이 Presentation layer와 Session Layer가 추가되었다</p>
<hr>
<h3 id="osi-model은-왜-실패했는가">OSI Model은 왜 실패했는가?</h3>
<p>OSI Model은 TCP/IP protocol suite가 발표되고 난 이후 나왔기 때문에 많은 전문가들이 TCP/IP protocol은 OSI model로 대체될 것이라고 예상했다</p>
<p>하지만 왜 실패 하였는가?</p>
<blockquote>
</blockquote>
<ol>
<li>OSI가 완성되었을때는 이미 TCP/IP가 많이 보급된 상태였다</li>
<li>Presentation layer와 Session layer는 다 정의되지 않았다</li>
<li>OSI가 성능이 더 떨어졌다</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Protocol]]></title>
            <link>https://velog.io/@gyu_won/Protocol</link>
            <guid>https://velog.io/@gyu_won/Protocol</guid>
            <pubDate>Mon, 16 Oct 2023 14:04:11 GMT</pubDate>
            <description><![CDATA[<h3 id="protocol">Protocol</h3>
<blockquote>
<p>sender, receiver 와 모든 중간의 장치들이 따라야 하는 통신규약</p>
</blockquote>
<p>protocol은 계층화 되어 있는데 2가지 원칙이 존재한다</p>
<blockquote>
<ol>
<li>각각의 층에서 sender냐 receiver냐에 따라서 2개의 역할을 수행한다</li>
<li>각각의 층에 있는 data들은 동일하다</li>
</ol>
</blockquote>
<br/>

<h3 id="프로토콜-스위트protocol-suite">프로토콜 스위트(protocol suite)</h3>
<blockquote>
<p>통신이나 네트워킹 작업을 수행하기 위해 함께 작동하는 여러 프로토콜들의 집합을 말한다</p>
</blockquote>
<p>이러한 프로토콜들은 각기 다른 네트워킹 기능과 책임을 담당하며, 종종 계층적인 구조를 가진다는 특징이 있다</p>
<p>가장 잘 알려진 프로토콜 스위트 중 하나는 인터넷 프로토콜 스위트(IP suite) 혹은 TCP/IP 스위트라고 부른다</p>
<br/>

<h3 id="tcpip-protocol-suite">TCP/IP protocol suite</h3>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/59123361-27d9-4435-8791-284a855a0ead/image.png" alt=""></p>
<h4 id="layered-architecture">Layered Architecture</h4>
<blockquote>
<p>아래 그림과 같이 작은 인터넷 구조가 있다고 가정
<img src="https://velog.velcdn.com/images/gyu_won/post/0af3b6eb-09ce-4e4a-bf21-d2022343a0ab/image.png" alt=""></p>
</blockquote>
<p>여기서 switch에서는 MAC주소를 따라가는데 단말기 장치로 데이터를 전송하는게 목표이기 때문에 hop by hop으로 MAC 주소가 바뀜
(위의 예에서는 Link1의 Mac 주소, Router의 Mac 주소, Link2 의 Mac 주소, B의 Mac 주소로 바뀜)</p>
<blockquote>
</blockquote>
<p>하지만 router는 목적지 주소(IP 주소)를 보고 routing table을 체크하여 데이터를 전송하기 때문에 IP 주소는 계속 고정임</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/a88d7fe1-68fb-4c87-96f0-ff9d41aa6a81/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>위 사진을 통해 이전에 말한 &quot;각각의 층에 있는 data들은 동일하다&quot; 라는 원칙이 성립함을 알 수 있다</p>
<blockquote>
</blockquote>
<p>추가로 data를 부르는 이름도 message, segment/datagram, datagram, frame, bit로 다른것을 알 수 있다</p>
<br/>

<h4 id="physical-layer">Physical Layer</h4>
<blockquote>
<p>frame 안의 bit를 link를 통해 어떻게 보낼지 책임지는 layer</p>
</blockquote>
<p> 물리 계층에서의 통신은 실제로 물리적인 전송만을 의미하지 않는다</p>
<p> 물리 계층 아래에 전송매체 라는 숨겨진 계층이 있고, 이는 실제로 데이터가 전송되는 물리적인 매체(예: 동축 케이블, 광섬유, 무선 주파수)를 의미한다</p>
<blockquote>
<p>즉, 물리 계층의 통신은 단순히 신호의 전송만을 의미하지 않고 실제로 신호가 어떻게 전송되는지(전송 매체를 통한 방법)와 관련된 논리적인 측면이 포함되어 있다</p>
</blockquote>
<br/>

<h4 id="data-link-layer">Data Link Layer</h4>
<blockquote>
<p>두 장치 간의 직접적인 연결을 통한 데이터 프레임의 전송에 책임이 있는 layer</p>
</blockquote>
<p>이 계층은 데이터 프레임의 에러 검출 및 제어, 프레임의 순서 보장, MAC 주소 처리 등의 역할을 한다</p>
<br/>

<h4 id="network-layer">Network Layer</h4>
<blockquote>
<p>source와 destination 사이에 연결을 만드는 데에 책임이 있는 layer</p>
</blockquote>
<p>network layer에서의 통신은 host-to-host이다</p>
<p>하지만 host로 가기에 여러가지 길이 있을 수 있는데 source에서 router로 가는동안 각각의 packet이 어느 길로 가야 가장 좋은 길일지를 책임져주는게 Network Layer</p>
<br/>

<h4 id="transport-layer">Transport Layer</h4>
<blockquote>
<p>application layer에 service를 제공한다</p>
</blockquote>
<p>transport layer에서의 통신은 end-to-end이다</p>
<p>즉, 아래와 같은 2가지 책임이 있다</p>
<blockquote>
<ol>
<li>application layer로 부터 온 message를 encapsulation을 통해 packet으로 만든다</li>
<li>packet을 다시 message로 변환하여 목적지 host에서 일치하는 application program에 전송한다.</li>
</ol>
</blockquote>
<br/>

<h4 id="application-layer">Application Layer</h4>
<blockquote>
<p>end system 들에게 여러가지 서비스를 제공거나 받는 부분을 책임진다</p>
</blockquote>
<p>Application layer에서의 통신은 process-to-process 이다</p>
<p>즉, 이메일, 웹서핑 등과 같은 서비스를 제공하고 제공받기 위해서 어떤 형식으로 메시지를 주고 받아야 하는지와 같은 프로세스 간의 통신을 담당한다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Network Types]]></title>
            <link>https://velog.io/@gyu_won/Network-Types</link>
            <guid>https://velog.io/@gyu_won/Network-Types</guid>
            <pubDate>Mon, 16 Oct 2023 13:06:32 GMT</pubDate>
            <description><![CDATA[<h3 id="network-types-이란">Network types 이란?</h3>
<blockquote>
</blockquote>
<p>network는 LANs나 WANs 으로 두가지 종류로 나뉜다</p>
<br/>

<h3 id="lan-local-area-network">LAN (Local Area Network)</h3>
<blockquote>
</blockquote>
<p>주로 개인적으로 소유하거나 하나의 빌딩이나 사무실, 대학 안에서 host들을 연결한다</p>
<p>아래 사진은 과거에 많이 사용하던 Bus구조로 link를 공유하기 때문에 간섭이 발생할 수 있다
<img src="https://velog.velcdn.com/images/gyu_won/post/98743832-ec9e-4db9-b07b-5df050877374/image.png" alt=""></p>
<p>그래서 오늘날에는 아래와 같은 구조를 사용하여 간섭이 잘 발생하지 않도록 한다
<img src="https://velog.velcdn.com/images/gyu_won/post/1921a4a2-e961-4048-a8d6-c7ec0e7b6af9/image.png" alt=""></p>
<br/>

<h3 id="wan-wide-area-network">WAN (Wide Area Network)</h3>
<blockquote>
</blockquote>
<p>제한된 크기에서 사용하는 LAN과 달리 넓은 지리적 공간(마을, 주, 나라, 세계)에서 사용한다</p>
<blockquote>
</blockquote>
<p>즉 LAN은 host들을 서로 연결하고 WAN은 router, switch, modem과 같은 connecting device들을 연결한다</p>
<br/>

<h4 id="point-to-point-wan">Point-to-Point WAN</h4>
<blockquote>
<p>두개의 통신하는 장치들을 transmission media를 통해서 연결하는 것
<img src="https://velog.velcdn.com/images/gyu_won/post/8d467e37-2550-4c2c-9c45-cd3dddcd3c32/image.png" alt=""></p>
</blockquote>
<br/>

<h4 id="switched-wan">Switched WAN</h4>
<blockquote>
<p>두개보다 더 많은 end들을 가진 네트워크
<img src="https://velog.velcdn.com/images/gyu_won/post/a2f3e077-cc23-46de-ad59-7a72dac080b9/image.png" alt=""></p>
</blockquote>
<p>오늘날 세계적인 통신에서의 골격으로 사용됨</p>
<br/>

<p>오늘날에는, LAN이나 WAN이 독립적으로 있는것은 드물고 두개 이상의 연결된 network들이 internetwork를 형성한다 (Internet)
<img src="https://velog.velcdn.com/images/gyu_won/post/7d7dde0e-8c79-4b88-8fb5-8e69164fcb04/image.png" alt="">
여기서 Router는 3계층이고 switch들은 2계층에서 데이터를 송수신하는 작업을 수행함</p>
<br/>

<h3 id="internet">Internet</h3>
<blockquote>
<p>두개 이상의 network들이 모여있는 것
<img src="https://velog.velcdn.com/images/gyu_won/post/610b83c6-d236-4f07-a956-679a63d56db5/image.png" alt="">
Customer Network (집 단위):
개인, 기업, 또는 다른 조직이 사용하는 로컬 네트워크를 의미합니다</p>
</blockquote>
<p>Provider Network (회사 단위):
개인 또는 조직에 인터넷 접속을 제공하는 업체의 네트워크를 의미한다
주로 &quot;Internet Service Provider (ISP) network&quot;라고도 부른다</p>
<blockquote>
</blockquote>
<p>Peering Point:
두 ISP나 여러 ISP들이 서로의 네트워크에 직접적으로 접근하기 위해 만든 교환 지점
&quot;Internet Exchange Point (IXP)&quot;라고도 불린다</p>
<blockquote>
</blockquote>
<p>Backbones (core network):
인터넷의 &quot;주요 도로&quot;와 같이, 전세계의 큰 데이터 트래픽을 운반하는 고속의 통신망을 의미한다
백본은 주로 광섬유 또는 고속의 전송 라인으로 구성되며, 국가 간 또는 대륙 간의 데이터 전송을 위해 사용되고 큰 ISP들, 통신업체들, 정부기관에 의해 운영된다</p>
<br/>

<h3 id="internet에-접속하기">Internet에 접속하기</h3>
<blockquote>
<p>user가 물리적으로 한개의 ISP에 연결되어 있다면 어느 누구나 인터넷에 접속할 수 있다</p>
</blockquote>
<p>그리고 이렇게 한개의 ISP에 연결은 주로 point-to-point WAN 방식으로 연결된다</p>
<p>사용자가 Internet에 접속할 수 있는 방법은 다음과 같다</p>
<h4 id="1-telephone-network-사용">1. Telephone network 사용</h4>
<blockquote>
<p>전화 통신을 위해 설계된 network를 이용</p>
</blockquote>
<p>거주지에서 통신사 센터로 point-to-point로 연결됨</p>
<p>아래와 같이 2가지 다른 방법으로 인터넷 연결을 제공함</p>
<blockquote>
<ol>
<li>Dial-up service
기존의 전화 회선을 사용하여 인터넷에 연결하는 방식으로 속도가 느리고 인터넷과 전화 통화 중 하나만 할 수 있다</li>
</ol>
</blockquote>
<blockquote>
</blockquote>
<ol start="2">
<li>DSL service
DSL도 기존의 전화 회선을 사용하지만, 다이얼업과는 달리 특별한 기술을 사용하여 높은 속도의 인터넷 연결을 제공한다
DSL은 전화 통화에 사용되는 주파수 대역과는 다른 대역을 사용하여 데이터를 전송하므로, 동시에 인터넷과 전화 통화를 할 수 있다</li>
</ol>
<br/>

<h4 id="2-cable-network-사용">2. Cable network 사용</h4>
<blockquote>
<p>Cable TV가 보급되면서 텔레비전 방송 서비스를 제공하기 위해 설계된 광대역 통신 네트워크인 cable network를 사용</p>
</blockquote>
<p>이 네트워크는 도시와 마을 전체에 걸쳐 설치된 동축 케이블 또는 광섬유 케이블을 사용하여 정보를 전송한다</p>
<br/>

<h4 id="3-무선-network-사용">3. 무선 network 사용</h4>
<h4 id="4-direct-connection">4. Direct Connection</h4>
<blockquote>
<p>큰 회사나 조직은 자기 자신이 local ISP가 되어서 Internet backbone network에 연결될 수 있다</p>
</blockquote>
<p>빠른 WAN을 임대해서 자신의 지역 ISP를 직접 연결하는 방식</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Networks]]></title>
            <link>https://velog.io/@gyu_won/2-Networks</link>
            <guid>https://velog.io/@gyu_won/2-Networks</guid>
            <pubDate>Mon, 16 Oct 2023 12:15:56 GMT</pubDate>
            <description><![CDATA[<h3 id="network-란">Network 란?</h3>
<blockquote>
</blockquote>
<p>network란 통신 가능한 여러 장치들의 집합간의 연결</p>
<p>이 정의에 따르면 device를 둘로 나눈다</p>
<h4 id="1-host">1. host</h4>
<blockquote>
<p>사용자의 요청을 처리하고 데이터를 생성하는 역할
즉, 특정 애플리케이션을 실행하거나 사용자의 명령을 처리할 수 있는 장치</p>
</blockquote>
<p>ex) large computer, desktop, laptop, workstation, cellular phone, security system</p>
<blockquote>
</blockquote>
<p>security system은 뭐지?
CCTV와 같은 보안 시스템도 데이터를 처리하고 실행할 수 있는 장치로 간주 될 수 있음</p>
<br/>

<h4 id="2-connecting-device연결장치">2. connecting device(연결장치)</h4>
<blockquote>
<p>데이터의 전송을 위한 경로를 제공하거나 데이터를 적절한 형식으로 반환하는 역할</p>
</blockquote>
<ul>
<li><strong>router</strong>: 여러개의 네트워크를 연결하고, 데이터를 목적지까지 가장 효율적인 경로로 전송하는 장치</li>
<li><strong>switch</strong>: 로컬 영역 네트워크(LAN)내의 장치들을 연결하며, 데이터를 특정 장치에게만 전송하도록 하는 장치</li>
<li><strong>Modem</strong>: 아날로그 신호와 디지털 신호 간의 변환을 수행하는 장치로, 전화 회선과 같은 아날로그 매체를 통해 디지털 데이터를 전송하는데 사용된다</li>
</ul>
<br/>

<h3 id="network-criteria">Network Criteria</h3>
<blockquote>
</blockquote>
<p>network는 performance, reliability, security라는 기준을 충족해야 한다</p>
<h4 id="1-performance">1. Performance</h4>
<blockquote>
<p>network의 성능은 transit time이나 response time과 같이 다양한 방식으로 측정될 수 있다</p>
</blockquote>
<pre><code>- transit time: message가 디바이스에서 다른 디바이스로 가는동안 걸린 시간
- response time: 요청과 그에 대한 응답을 반환할 때 까지의 시간</code></pre><h4 id="2-reliability">2. Reliability</h4>
<blockquote>
<p>network의 신뢰성은 실패의 빈도나 실패로부터 복구하는데 걸리는 시간, 비상 상황에서의 네트워크 견고성에 의해 측정된다</p>
</blockquote>
<h4 id="3-security">3. Security</h4>
<blockquote>
<p>데이터를 보호하고, 정책을 실행하며 보안 위반(breaches)이나 데이터 손실(data losses) 후 복구하는 과정을 의미한다</p>
</blockquote>
<br/>

<h3 id="physical-structures">Physical Structures</h3>
<h4 id="link-란">link 란?</h4>
<blockquote>
</blockquote>
<p>장치들 간 통신하는 길</p>
<p>이러한 link의 연결방식으로는 2가지가 있음</p>
<h4 id="1-point-to-point">1. point-to-point</h4>
<blockquote>
<p>단말기 2대가 일대일로 연결되어 있는 것</p>
</blockquote>
<h4 id="2-multipoint">2. multipoint</h4>
<blockquote>
<p>여러개의 단말기가 일대다로 연결되어 있는 것</p>
</blockquote>
<p> 둘 이상의 장치들이 둘 중 하나의 연결방식으로 한 개의 link에 연결되고, 둘 이상의 link들이 topology를 구성한다</p>
<br/>

<h3 id="physical-topology">physical topology</h3>
<blockquote>
<p>물리적으로 network가 어떻게 구성되어 있는지 표현한 것</p>
</blockquote>
<p>즉, topology는 모든 link들과 link에 연결된 device들(node라고 부름)간의 관계를 표현한 거라고 보면 됨</p>
<p>그래서 4가지 기본 topology가 있음</p>
<ol>
<li>mesh</li>
<li>star</li>
<li>bus</li>
<li>ring</li>
</ol>
<br/>

<h4 id="mesh-topology">Mesh topology</h4>
<blockquote>
<p>참여하고 있는 node들이 모두 서로 연결되어 있는것
<img src="https://velog.velcdn.com/images/gyu_won/post/a912b222-2c80-4685-ba50-8d2542b3ecc1/image.png" alt=""></p>
</blockquote>
<ul>
<li>mesh topology에서 node가 5개면 총 link의 개수는 4+3+2+1 해서 10개이다</li>
</ul>
<br/>

<h4 id="star-topology">Star topology</h4>
<blockquote>
</blockquote>
<p>Access Pointer와 같이 1대 다로 연결된 것
<img src="https://velog.velcdn.com/images/gyu_won/post/cb59246c-f7b0-44ef-9473-aaf500639b18/image.png" alt=""></p>
<br/>

<h4 id="bus-topology">Bus topology</h4>
<blockquote>
</blockquote>
<p>Bus 구조로 공유 (동시에 여러명이 보내면 충돌함)
<img src="https://velog.velcdn.com/images/gyu_won/post/8438a649-a9d7-423e-bbf0-cd4592a08466/image.png" alt=""></p>
<br/>

<h4 id="ring-topology">Ring topology</h4>
<blockquote>
</blockquote>
<p>ring 모양으로 구성돼서 data를 옆으로 전달함
<img src="https://velog.velcdn.com/images/gyu_won/post/e1666eaa-03f9-4c76-8414-b07c75e712a6/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Data Communication 이란?]]></title>
            <link>https://velog.io/@gyu_won/Datacommunication1</link>
            <guid>https://velog.io/@gyu_won/Datacommunication1</guid>
            <pubDate>Mon, 16 Oct 2023 12:01:45 GMT</pubDate>
            <description><![CDATA[<h3 id="datacommunication-이란">Datacommunication 이란?</h3>
<blockquote>
</blockquote>
<p>transmission media(연결통로: 유선, 무선)를 통해서 두개의 장비간에 데이터를 교환하는 것</p>
<p>communication과 network는 다른거임</p>
<ul>
<li>communication: 둘 사이에 교환한다는 의미</li>
<li>network: 이건 교환망이라는 의미</li>
</ul>
<br/>

<p>이런 Data communication에는 4가지 특성이 있음</p>
<h4 id="data-commication의-특성">Data commication의 특성</h4>
<blockquote>
</blockquote>
<ol>
<li>Delivery: 전달</li>
<li>Accuracy: 정확성</li>
<li>Timeliness: 시간 축 개념</li>
<li>Jitter: 첫번째 data와 두번째 data 사이의 시간과 두번째 data와 세번째 data 사이의 시간 차이</li>
</ol>
<ul>
<li>jitter = 0 → data가 일정하게 들어왔다는 뜻 (안정적)</li>
</ul>
<br/>

<h3 id="data-communication-system의-5가지-components">Data communication system의 5가지 Components</h3>
<ol>
<li>Message (packet): 실제 교환되어지는 정보</li>
<li>Sender</li>
<li>Receiver</li>
<li>Transmission Media: 연결 매체 (유선 or 무선)</li>
<li>Protocol: 데이터 통신간의 규약</li>
</ol>
<h4 id="message">Message</h4>
<p>message는 text, 숫자, 이미지, 오디오, 비디오 등 다양한 형태를 띈다</p>
<blockquote>
</blockquote>
<ul>
<li>Text: Unicode를 사용하는 bit pattern으로 표현됨</li>
<li>숫자: 이진수로 표현됨</li>
<li>Images: RGB나 YCM을 사용한 bit 패턴으로 표현됨 (YCM: yellow, cyan, magenta)</li>
<li>Audio: analog나 digital 신호로 표현됨</li>
<li>Videos: 연속되거나 결합된 이미지들을 의미함</li>
</ul>
<br/>

<h3 id="data-flow">Data Flow</h3>
<blockquote>
</blockquote>
<p>Data의 흐름은 simplex, half-duplex, duplex로 나눌 수 있다</p>
<h4 id="1-simplex-단방향-통신">1. simplex: 단방향 통신</h4>
<blockquote>
</blockquote>
<p>두 기기들 중 하나는 받고 하나는 보내는 역할만 가능</p>
<blockquote>
</blockquote>
<p>ex) 컴퓨터 mainframe 과 monitor의 관계
mainframe은 보내기만 가능하고 monitor는 받기만 함</p>
<h4 id="2-half-duplex-양방향-이긴-한데-동시에는-불가능한-것">2. half-duplex: 양방향 이긴 한데 동시에는 불가능한 것</h4>
<blockquote>
</blockquote>
<p>각각은 보내거나 받을 수 있지만 동시에 보내거나 받는것은 불가능</p>
<blockquote>
</blockquote>
<p>ex) A와 B가 half-duplex 연결을 맺고 있다면, A가 데이터를 전송할 때는 B는 받기만 할 수 있고, B가 데이터를 전송할 때는 A는 받기만 할 수 있다는 뜻</p>
<blockquote>
</blockquote>
<p>무전기가 대표적인 half-duplex 통신 장치 사용자가 말할 때 &#39;송신&#39; 버튼을 누르고, 말하는 동안 다른 사용자는 듣기만 할 수 있음</p>
<h4 id="3-full-duplex-양방향-통신">3. (full) duplex: 양방향 통신</h4>
<blockquote>
</blockquote>
<p>각각은 동시에 보내거나 받을 수 있음</p>
<blockquote>
</blockquote>
<p>A와 B가 full-duplex 연결을 맺고 있다면, A가 B에게 데이터를 전송하는 동안 B도 A에게 동시에 데이터를 전송할 수 있음</p>
<blockquote>
</blockquote>
<p>한 사람이 말하는 동안, 다른 사람도 동시에 말할 수 있는 전화 통화가 대표적인 예</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[LG Soft India 인턴쉽 및 Christ university 방문]]></title>
            <link>https://velog.io/@gyu_won/LG-Soft-India</link>
            <guid>https://velog.io/@gyu_won/LG-Soft-India</guid>
            <pubDate>Mon, 16 Oct 2023 08:19:52 GMT</pubDate>
            <description><![CDATA[<h3 id="지원-동기">지원 동기:</h3>
<p>2023년 1월에 Lasvegas에서 열린 CES 전시회에 참관하고, Nvidia, Intel, Google과 같은 글로벌 IT 기업에 방문하였다.<br/>
갔다 온 이후 외국의 IT 기업과 한국의 IT 기업이 어떻게 다른지 궁금해서 Kakao 판교 사옥에 방문하여 기업 내부를 둘러보고 멘토님과 기술 및 회사에 대해서 이야기를 나누었다<br/>
그러던 중 LG Soft India에서 인턴쉽 프로그램을 발견하고 합격하여 한달간 인턴활동을 위해 인도의 Bengaluru로 가게되었다.</p>
<hr>
<h3 id="인턴쉽">인턴쉽</h3>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/52294bd8-ceb4-4350-a998-9723822f8430/image.png" alt=""></p>
<p>인턴쉽에서 가장 먼저 한 것은 LG의 <strong>WebOS</strong>를 배우는 것이었다.</p>
<p>LG 전자는 자신들만의 플랫폼을 구축하고, 제품에 맞춤화 하기 위하여 WebOS 운영체제를 사용한다</p>
<p>그래서 우리는 WebOS 운영체제가 어떤식으로 동작하는지를 먼저 학습하였다</p>
<blockquote>
<p>이후 LG webOS 운영체제를 라즈베리파이에 설치하여 각종 센서를 연결하며 수질 오염에 대한 개별 알림을 주는 서비스를 개발하였다<br/>
<a href="https://github.com/Gyu-won/LGSI">https://github.com/Gyu-won/LGSI</a></p>
</blockquote>
<p>팀 프로젝트에서 라즈베리파이를 다루는 역할을 맡아 과제를 수행하였다.</p>
<blockquote>
<p>webOS를 통해 서버에서 서비스를 제공하는 과정에서 많은 오류를 마주쳤고 이를 해결하는 과정에서 운영체제를 더 깊게 공부해야겠다는 필요성을 느꼈다</p>
</blockquote>
<p>이후 &quot;실습과 그림으로 배우는 리눅스 구조: 개발자가 알아야 하는 OS와 하드웨어 기초&quot; 교재를 구매하여 현재 서버부분에 대한 공부를 진행중이다</p>
<br/>

<p>또한, 인도의 개발 분위기에 대해서 알 수 있었다</p>
<p>요즘 한국 IT 기업들도 편안한 분위기 속에서 함께 고민하고 토론하는 분위기를 만들기 위해 노력하는데 인도에서도 역시 비슷한 개발 문화를 공유한다는 것을 알 수 있었다</p>
<blockquote>
<p>인도에서 멘토분들에게 webOS의 service 관해 질문하였을 때, 인도 개발자분들은 서로 토론을 통해서 내용을 고민하였다.<br/>
서로가 편하게 도움을 요청하고 함께 고민하는 모습을 보고 인도에는 함께하는 개발 문화가 발전해 있다는 사실을 깨달았다</p>
</blockquote>
<hr>
<h3 id="문화활동">문화활동</h3>
<p>인턴쉽을 위해 Bengaluru에 있는 Christ university에서 한달간 머물면서 대학교 학생들과 문화도 교류하는 시간을 보냈다</p>
<p>CES에 방문하였을 때는 한국 학생들끼리 주로 다니고 외국인들과 대화할 일이 거의 없다보니 미국의 문화를 느끼거나 미국 사람들에 대해 알지 못해서 아쉬웠다</p>
<blockquote>
<p>그래서 이번에 인도를 가게되면 인도 사람들에게 먼저 말을 걸면서 소통하겠다는 목표를 세우고 인도로 향했다</p>
</blockquote>
<p>기숙사 엘리베이터를 타거나 길을 지나가면 먼저 말을 걸어주는 인도 학생들이 많아서 더 편하게 말하며 친해질 수 있었고 친해지니 친구들과 공원과 동물원에 놀러가기도 하였다</p>
<p>인도친구들이 한국인들을 좋아해주고 먼저 다가와주니 저도 더 적극적으로 대화를 하면서 영어 실력도 늘고 인도 친구들과도 친해졌다. </p>
<p>또한 한국-인도 문화의 날 행사에서 BTS의 Dynamite로 K-pop 공연을 하였다
<img src="https://velog.velcdn.com/images/gyu_won/post/809dafe5-ff55-49eb-9617-4ab00e42a420/image.png" alt=""></p>
<p>평소 춤을 좋아하기 때문에 많은 관객들 앞에서 공연을 하는 경험은 익숙하였지만 외국에서 공연을 하는 것은 처음이었기 때문에 긴장이 많이 되었다.</p>
<p>하지만 인도 학생들이 많은 응원을 해주고, 팀원들과 함께 열심히 연습한 덕분에 성공적으로 공연을 마칠 수 있었다.</p>
<p><a href="https://drive.google.com/file/d/1VzukqvY4kG8w-ZvtygoYnUTb-u1qWMM_/view?usp=sharing">https://drive.google.com/file/d/1VzukqvY4kG8w-ZvtygoYnUTb-u1qWMM_/view?usp=sharing</a></p>
<p>외국에서 K-pop의 인기를 한번 더 실감할 수 있었고, 공연을 통해 나도 한국을 알렸다는 사실에 뿌듯하였다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[time 패키지]]></title>
            <link>https://velog.io/@gyu_won/java18</link>
            <guid>https://velog.io/@gyu_won/java18</guid>
            <pubDate>Mon, 16 Oct 2023 07:27:18 GMT</pubDate>
            <description><![CDATA[<h3 id="javatime-패키지">java.time 패키지</h3>
<h4 id="날짜를-표시하는-방법">날짜를 표시하는 방법</h4>
<p>JDK 1.0에서는 Date 클래스를 사용하여 날짜에 관한 처리를 수행했지만 Date 클래스는 직관적이지 않고 기능이 부족하여 현재는 사용하지 않는다 </p>
<p>JDK 1.1부터 새롭게 제공된 Calendar 클래스는 날짜와 시간에 대한 정보를 손쉽게 얻을 수 있지만 아래와 같은 문제점이 있다</p>
<blockquote>
<ol>
<li>Calendar 인스턴스는 불변 객체(immutable object)가 아니라서 값이 수정될 수 있다 <br/></li>
<li>윤초(leap second)와 같은 특별한 상황을 고려하지 않는다<br/></li>
<li>Calendar 클래스에서는 월을 나타낼 때 1월부터 12월을 0부터 11까지로 표현한다<br/></li>
</ol>
</blockquote>
<p>이 때문에 많은 자바 개발자들은 Calendar 클래스뿐만 아니라 더 나은 성능의 Joda-Time이라는 라이브러리를 함께 사용해 왔다</p>
<br/>

<h4 id="javatime-패키지-1">java.time 패키지</h4>
<blockquote>
</blockquote>
<p>Java SE 8부터 제공되는 java.time 패키지에는 자바에서 날짜와 시간을 다루는 데 사용되는 필수 클래스들이 포함되어 있음</p>
<p>위와 같은 문제점을 모두 해결하며, 다양한 기능을 지원하는 다수의 하위 패키지를 포함하고 있음</p>
<blockquote>
<p>하위 패키지 종류<br/></p>
</blockquote>
<ol>
<li>java.time.chrono : ISO-8601에 정의된 표준 달력 이외의 달력 시스템을 사용할 때 필요한 클래스들<br/></li>
<li>java.time.format : 날짜와 시간에 대한 데이터를 구문분석하고 형식화하는 데 사용되는 클래스들<br/></li>
<li>java.time.temporal : 날짜와 시간에 대한 데이터를 연산하는 데 사용되는 보조 클래스들&lt;br?</li>
<li>java.time.zone : 타임 존(time-zone)과 관련된 클래스들</li>
</ol>
<p>java.time 패키지에 속하는 모든 클래스의 인스턴스는 불변 객체로 생성되기 때문에 위의 메소드들은 모두 새로운 객체를 생성하여 반환한다</p>
<br/>

<h4 id="javatime-패키지의-구성-클래스">java.time 패키지의 구성 클래스</h4>
<blockquote>
<ul>
<li>LocalDate 클래스는 날짜를 표현할 때 사용한다</li>
</ul>
</blockquote>
<ul>
<li>LocalTime 클래스는 시간을 표현할 때 사용한다</li>
<li>LocalDateTime 클래스는 날짜와 시간을 한 번에 표현하고 싶을 때 사용한다</li>
<li>ZonedDateTime 클래스는 특정 타임 존(time-zone)에 해당하는 날짜와 시간을 다루는 데 사용한다</li>
<li>Instant 클래스는 특정 시점의 날짜와 시간을 나노초(nanosecond) 단위로 표현하는 타임스탬프(time-stamp)를 다루는 데 사용된다</li>
<li>Period 클래스는 두 날짜 사이의 차이를 표현하는 데 사용된다</li>
<li>Duration 클래스는 두 시각 사이의 차이를 표현하는 데 사용된다</li>
</ul>
<hr>
<h3 id="localdate와-localtime">LocalDate와 LocalTime</h3>
<h4 id="localdate-클래스와-localtime-클래스">LocalDate 클래스와 LocalTime 클래스</h4>
<blockquote>
<p>LocalDate 클래스는 날짜를 표현하는 데 사용되며, LocalTime 클래스는 시간을 표현하는 데 사용된다</p>
</blockquote>
<p>java.time 패키지에 포함된 대부분의 클래스들은 이 두 클래스를 확장한 것이 많음</p>
<br/>

<h4 id="날짜와-시간-객체의-생성">날짜와 시간 객체의 생성</h4>
<p>LocalDate와 LocalTime 클래스는 객체를 생성하기 위해서 now()와 of() 메소드가 클래스 메소드를 제공된다</p>
<blockquote>
<p>now(): 현재의 날짜와 시간을 이용하여 새로운 객체를 생성하여 반환<br/>
of(): 전달된 인수를 가지고 특정 날짜와 시간을 표현하는 새로운 객체를 생성하여 반환</p>
</blockquote>
<pre><code class="language-java">LocalDate today = LocalDate.now();
LocalTime present = LocalTime.now();

System.out.println(today + &quot; &quot; + present);

// static LocalDate of(int year, int month, int dayOfMonth)
LocalDate birthDay = LocalDate.of(1982, 02, 19);

// static LocalTime of(int hour, int minute, int second, int nanoOfSecond)
LocalTime birthTime = LocalTime.of(02, 02, 00, 100000000);

System.out.println(birthDay + &quot; &quot; + birthTime);</code></pre>
<pre><code class="language-json">2017-02-16 09:21:50.634
1982-02-19 02:02:00.100</code></pre>
<br/>


<h4 id="날짜와-시간-객체에-접근하기">날짜와 시간 객체에 접근하기</h4>
<blockquote>
<p>LocalDate와 LocalTime 클래스는 특정 필드의 값을 가져오기 위해서 다양한 getter 메소드를 제공한다</p>
</blockquote>
<h4 id="localdate가-제공하는-getter-메소드">LocalDate가 제공하는 getter 메소드</h4>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/e2f686fb-f389-4c4b-a4d2-ddcb3cabd59d/image.png" alt=""></p>
<p>java.time 패키지에서는 1월을 1로 표현하여 월의 범위가 1~12가 되었으며, 요일은 월요일부터 1로 표현하도록 변경되었다</p>
<pre><code class="language-java">LocalDate today = LocalDate.now();

System.out.println(&quot;올해는 &quot; + today.getYear() + &quot;년입니다.&quot;);
System.out.println(&quot;이번달은 &quot; + today.getMonthValue() + &quot;월입니다.&quot;);
System.out.println(&quot;오늘은 &quot; + today.getDayOfWeek() + &quot;입니다.&quot;);

System.out.println(&quot;오늘은 1년 중 &quot; + 
                today.get(ChronoField.DAY_OF_YEAR) + &quot;일째 날입니다.&quot;);</code></pre>
<pre><code class="language-java">올해는 2017년입니다.
이번달은 2월입니다.
오늘은 THURSDAY입니다.
오늘은 1년 중 47일째 날입니다.</code></pre>
 <br/>

<h4 id="localtime이-제공하는-getter-메소드">LocalTime이 제공하는 getter 메소드</h4>
<p><img src="https://velog.velcdn.com/images/gyu_won/post/0ca2e08f-3f46-47a1-b946-4b1a93a0af2d/image.png" alt=""></p>
<pre><code class="language-java">LocalTime present = LocalTime.now();

System.out.println(&quot;현재 시각은 &quot; + present.getHour() + 
                    &quot;시 &quot; + present.getMinute() + &quot;분입니다.&quot;);</code></pre>
<pre><code class="language-json">현재 시간은 9시 22분입니다.</code></pre>
<br/>

<h4 id="temporalfield-인터페이스">TemporalField 인터페이스</h4>
<blockquote>
<p>월과 시와 같이 날짜와 시간과 관련된 필드를 정의해 놓은 인터페이스</p>
</blockquote>
<p>이 인터페이스를 구현하여 날짜와 시간을 나타낼 때 사용하는 열거체가 바로 ChronoField</p>
<p>java.time 패키지를 구성하는 클래스의 메소드에서는 이 열거체를 이용하여 날짜와 시간을 처리하고 있다</p>
<p>ChronoField 열거체에 정의된 대표적인 열거체 상수는 아래와 같다</p>
<blockquote>
</blockquote>
<p>ERA:    시대
YEAR:    연도
MONTH_OF_YEAR:    월
DAY_OF_MONTH:    일
DAY_OF_WEEK:    요일 (월요일:1, 화요일:2, ..., 일요일:7)
AMPM_OF_DAY:    오전/오후 (오전:0, 오후 1)
HOUR_OF_DAY:    시(0<del>23)
CLOCK_HOUR_OF_DAY:    시(1</del>24)
HOUR_OF_AMPM:    시(0<del>11)
CLOCK_HOUR_OF_AMPM:    시(1</del>12)
MINUTE_OF_HOUR:    분
SECOND_OF_MINUTE:    초
DAY_OF_YEAR:     해당 연도의 몇 번째 날 (1~365, 윤년이면 366)
EPOCH_DAY:    EPOCH(1970년 1월 1일)을 기준으로 몇 번째 날</p>
<pre><code class="language-java">LocalTime present = LocalTime.now();

String ampm; 

if(present.get(ChronoField.AMPM_OF_DAY) == 0) {
    ampm = &quot;오전&quot;;
} else {
    ampm = &quot;오후&quot;;
}

System.out.println(&quot;지금은 &quot; + ampm + &quot; &quot; + present.get(ChronoField.HOUR_OF_AMPM) + &quot;시입니다.&quot;);</code></pre>
<pre><code class="language-java">지금은 오전 9시입니다.</code></pre>
<br/>


<h4 id="날짜와-시간-객체의-필드값-변경">날짜와 시간 객체의 필드값 변경</h4>
<blockquote>
<p>LocalDate와 LocalTime 클래스는 날짜와 시간 객체에 접근하여 특정 필드의 값을 변경하기 위해서 with() 메소드를 사용한다</p>
</blockquote>
<h4 id="localdate-클래스에서-제공하는-with-메소드-종류">LocalDate 클래스에서 제공하는 with 메소드 종류</h4>
<blockquote>
</blockquote>
<p>LocalDate with(TemporalField field, long newValue)
해당 날짜 객체에서 특정 필드를 전달된 새로운 값으로 설정한 새로운 날짜 객체를 반환함 <br/>
LocalDate withYear(int year)<br>해당 날짜 객체에서 연도(YEAR) 필드를 전달된 새로운 값으로 설정한 새로운 날짜 객체를 반환함<br/>
LocalDate withMonth(int month)<br>해당 날짜 객체에서 월(MONTH_OF_YEAR) 필드를 전달된 새로운 값으로 설정한 새로운 날짜 객체를 반환함<br/>
LocalDate withDayOfMonth(int dayOfMonth)<br>해당 날짜 객체에서 일(DAY_OF_MONTH) 필드를 전달된 새로운 값으로 설정한 새로운 날짜 객체를 반환함<br/>
LocalDate withDayOfYear(int dayOfYear)<br>해당 날짜 객체에서 DAY_OF_YEAR 필드를 전달된 새로운 값으로 설정한 새로운 날짜 객체를 반환함.</p>
<p> withYear 사용 예시</p>
<pre><code class="language-java">LocalDate today = LocalDate.now();
System.out.println(&quot;올해는 &quot; + today.getYear() + &quot;년입니다.&quot;); 

LocalDate otherDay = today.withYear(1982);
System.out.println(&quot;올해는 &quot; + otherDay.getYear() + &quot;년입니다.&quot;);</code></pre>
<pre><code class="language-json">올해는 2017년입니다.
올해는 1982년입니다.</code></pre>
<p>withDayOfYear 사용 예시</p>
<pre><code class="language-java">LocalDate date = LocalDate.of(2023, 10, 16);
System.out.println(&quot;Original date: &quot; + date);

LocalDate modifiedDate = date.withDayOfYear(100); // 연도의 100번째 날로 변경
System.out.println(&quot;Modified date: &quot; + modifiedDate);</code></pre>
<pre><code class="language-json">Original date: 2023-10-16
Modified date: 2023-04-10</code></pre>
<p>with 사용 예시</p>
<pre><code class="language-java">LocalDate date = LocalDate.of(2023, 10, 16);
System.out.println(&quot;Original date: &quot; + date);

LocalDate modifiedMonth = date.with(ChronoField.MONTH_OF_YEAR, 2); // 2월로 변경
System.out.println(&quot;Month modified: &quot; + modifiedMonth);

LocalDate modifiedDay = date.with(ChronoField.DAY_OF_MONTH, 25); // 25일로 변경
System.out.println(&quot;Day modified: &quot; + modifiedDay);</code></pre>
<pre><code class="language-json">Original date: 2023-10-16
Month modified: 2023-02-16
Day modified: 2023-10-25</code></pre>
 <br/>

<h4 id="localtime-클래스에서-제공하는-with-메소드-종류">LocalTime 클래스에서 제공하는 with() 메소드 종류</h4>
<blockquote>
</blockquote>
<p>LocalTime with(TemporalField field, long newValue)<br>해당 시간 객체에서 특정 필드를 전달된 새로운 값으로 설정한 새로운 시간 객체를 반환함<br/>
LocalTime withHour(int hour)<br>해당 시간 객체에서 시(HOUR_OF_DAY) 필드를 전달된 새로운 값으로 설정한 새로운 시간 객체를 반환함<br/>
LocalTime withMinute(int minute)<br>해당 시간 객체에서 분(MINUTE_OF_HOUR) 필드를 전달된 새로운 값으로 설정한 새로운 시간 객체를 반환함<br/>
LocalTime withSecond(int second)<br>해당 시간 객체에서 초(SECOND_OF_MINUTE) 필드를 전달된 새로운 값으로 설정한 새로운 시간 객체를 반환함<br/>
LocalTime withNano(int nanoOfSecond)<br>해당 시간 객체에서 나노초(NANO_OF_SECOND) 필드를 전달된 새로운 값으로 설정한 새로운 시간 객체를 반환함</p>
<pre><code class="language-java">LocalTime present = LocalTime.now();
System.out.println(&quot;현재 시각은 &quot; + present.getHour() + &quot;시입니다.&quot;);

LocalTime otherTime = present.withHour(8);
System.out.println(&quot;현재 시각은 &quot; + otherTime.getHour() + &quot;시입니다.&quot;);</code></pre>
<pre><code class="language-json">현재 시간은 9시입니다.
현재 시간은 8시입니다.</code></pre>
<p>with() 메소드 이외에도 특정 필드의 값을 더하거나 뺄 수 있는 다양한 plus()와 minus() 메소드도 제공한다</p>
<pre><code class="language-java">LocalTime present = LocalTime.now();
System.out.println(&quot;현재 시각은 &quot; + present.get(ChronoField.HOUR_OF_DAY) + &quot;시입니다.&quot;);

LocalTime otherTime = present.plus(2, ChronoUnit.HOURS);
System.out.println(&quot;바뀐 시간은 &quot; + otherTime.getHour() + &quot;시입니다.&quot;);

LocalTime anotherTime = present.minus(6, ChronoUnit.HOURS);
System.out.println(&quot;바뀐 시간은 &quot; + anotherTime.getHour() + &quot;시입니다.&quot;);

```java
현재 시간은 9시입니다.
바뀐 시간은 11시입니다.
바뀐 시간은 3시입니다.</code></pre>
<p>ChronoUnit은 날짜와 시간의 기간을 나타내기 위한 다양한 시간 단위를 제공한다
ChronoField는 날짜와 시간의 구체적인 필드를 나타낸다</p>
<br/>

<h4 id="날짜와-시간-객체의-비교">날짜와 시간 객체의 비교</h4>
<p>LocalDate와 LocalTime 클래스에도 객체를 비교할 수 있는 compareTo() 메소드가 오버라이딩되어 있다</p>
<p>하지만 더욱 편리하게 날짜와 시간 객체를 서로 비교할 수 있도록 다음과 같은 메소드를 제공한다</p>
<blockquote>
</blockquote>
<ol>
<li>isEqual() 메소드 : equals() 메소드와는 달리 오직 날짜만을 비교함. 
(LocalDate 클래스에서만 제공)<br/></li>
<li>isBefore() 메소드 : 두 개의 날짜와 시간 객체를 비교하여 현재 객체가 명시된 객체보다 앞선 시간인지를 비교함.<br/></li>
<li>isAfter() 메소드 : 두 개의 날짜와 시간 객체를 비교하여 현재 객체가 명시된 객체보다 늦은 시간인지를 비교함.</li>
</ol>
<pre><code class="language-java">LocalDate today = LocalDate.now();
LocalDate otherDay = LocalDate.of(1982, 02, 19);

System.out.println(today.compareTo(otherDay));
System.out.println(today.isBefore(otherDay));
System.out.println(today.isEqual(otherDay));</code></pre>
<pre><code class="language-json">35
false
false</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[스트림 API]]></title>
            <link>https://velog.io/@gyu_won/java17</link>
            <guid>https://velog.io/@gyu_won/java17</guid>
            <pubDate>Sat, 14 Oct 2023 15:14:42 GMT</pubDate>
            <description><![CDATA[<h3 id="스트림-api">스트림 API</h3>
<p>자바에서는 많은 양의 데이터를 저장하기 위해서 배열이나 컬렉션을 사용하는데 그러면 여기 접근하기 위해서는 반복문과 iterator를 사용해야한다</p>
<p>코드는 길이가 너무 길고 가독성도 떨어지며, 코드의 재사용이 거의 불가능 하며 정형화된 처리 패턴이 없어서 불편함 </p>
<p>이러한 문제점을 극복하기 위해서 Java SE 8부터 스트림(stream) API를 도입!</p>
<h4 id="스트림-api-1">스트림 API</h4>
<blockquote>
<p>스트림 API는 데이터를 추상화하여 다루므로, 다양한 방식으로 저장된 데이터를 읽고 쓰기 위한 공통된 방법을 제공</p>
</blockquote>
<p>따라서 배열이나 컬렉션, 파일에 저장된 데이터를 모두 같은 방법으로 다룰 수 있음</p>
<blockquote>
</blockquote>
<p>스트림 API의 특징: <br/></p>
<ol>
<li>스트림은 외부 반복을 통해 작업하는 컬렉션과는 달리 내부 반복(internal iteration)을 통해 작업을 수행한다<br/></li>
<li>스트림은 재사용이 가능한 컬렉션과는 달리 단 한 번만 사용할 수 있다.<br/></li>
<li>스트림은 원본 데이터를 변경하지 않는다<br/></li>
<li>스트림의 연산은 필터-맵(filter-map) 기반의 API를 사용하여 지연(lazy) 연산을 통해 성능을 최적화한다 <br/></li>
<li>스트림은 parallelStream() 메소드를 통한 손쉬운 병렬 처리를 지원한다</li>
</ol>
<p>+) 4번 특징 부연 설명
스트림의 연산은 대부분 filter-map 연산인데 아래 코드와 같이 중간연사(filter, map)에서 실제 연산을 하는게 아니라 연산의 결과가 필요한 마지막에(.collect) 연산을 수행한다</p>
<pre><code class="language-java">List&lt;String&gt; names = Arrays.asList(&quot;John&quot;, &quot;Anna&quot;, &quot;Mike&quot;, &quot;Kate&quot;);
List&lt;String&gt; filteredNames = names.stream()
    .filter(name -&gt; name.length() &lt;= 4)
    .map(name -&gt; name.toUpperCase())
    .collect(Collectors.toList());</code></pre>
<p>+) 5번 특징 부연 설명</p>
<pre><code>List&lt;String&gt; names = Arrays.asList(&quot;John&quot;, &quot;Anna&quot;, &quot;Mike&quot;, &quot;Kate&quot;);
List&lt;String&gt; filteredNames = names.parallelStream()
    .filter(name -&gt; name.length() &lt;= 4)
    .map(name -&gt; name.toUpperCase())
    .collect(Collectors.toList());</code></pre><p>위와 같이 멀티 코어 프로세서의 특징을 살려서 filter와 map 연산을 동시에 수행할 수도 있다</p>
<br/>

<p>** 스트림 API의 동작 흐름 **</p>
<ol>
<li><p>스트림의 생성</p>
</li>
<li><p>스트림의 중개 연산 (스트림의 변환)</p>
</li>
<li><p>스트림의 최종 연산 (스트림의 사용)</p>
</li>
</ol>
<hr>
<h3 id="스트림의-생성">스트림의 생성</h3>
<p>스트림 API는 아래와 같은 다양한 데이터 소스에서 사용할 수 있다</p>
<blockquote>
</blockquote>
<ol>
<li>컬렉션</li>
<li>배열</li>
<li>가변 매개변수</li>
<li>지정된 범위의 연속된 정수</li>
<li>특정 타입의 난수들</li>
<li>람다 표현식</li>
<li>파일</li>
<li>빈 스트림</li>
</ol>
<h4 id="컬렉션">컬렉션</h4>
<blockquote>
<p>자바에서 제공하는 모든 컬렉션의 최고 상위 조상인 Collection 인터페이스에는 stream() 메소드가 정의되어 있기 때문에 Collection 인터페이스를 구현한 모든 List와 Set 컬렉션 클래스에서도 stream() 메소드로 스트림을 생성할 수 있다</p>
</blockquote>
<pre><code class="language-java">ArrayList&lt;Integer&gt; list = new ArrayList&lt;Integer&gt;(); 

list.add(4);
list.add(2);
list.add(3);
list.add(1);

Stream&lt;Integer&gt; stream = list.stream();

stream.forEach(System.out::println);</code></pre>
<pre><code class="language-json">4
2
3
1</code></pre>
<p>같은 스트림으로는 forEach() 메소드를 한 번밖에 호출할 수 없다
따라서 또 다른 스트림을 생성하여 forEach() 메소드를 호출해야 한다</p>
<p>Stream 클래스의 forEach() 메소드는 해당 스트림의 요소를 하나씩 소모해가며 순차적으로 요소에 접근하는 메소드이다</p>
<br/>

<h4 id="배열">배열</h4>
<blockquote>
<p>배열에 관한 스트림을 생성하기 위해 Arrays 클래스에는 다양한 형태의 stream() 메소드가 클래스 메소드로 정의되어 있다<br/>
또한, 기본 타입인 int, long, double 형을 저장할 수 있는 배열에 관한 스트림이 별도로 정의되어 있다<br/>
이러한 스트림은 java.util.stream 패키지의 IntStream, LongStream, DoubleStream 인터페이스로 각각 제공된다</p>
</blockquote>
<pre><code class="language-java">String[] arr = new String[]{&quot;넷&quot;, &quot;둘&quot;, &quot;셋&quot;, &quot;하나&quot;};

Stream&lt;String&gt; stream1 = Arrays.stream(arr);

stream1.forEach(e -&gt; System.out.print(e + &quot; &quot;));
System.out.println();

// 배열의 특정 부분만을 이용한 스트림 생성
Stream&lt;String&gt; stream2 = Arrays.stream(arr, 1, 3);
stream2.forEach(e -&gt; System.out.print(e + &quot; &quot;));</code></pre>
<pre><code class="language-json">넷 둘 셋 하나 
둘 셋 </code></pre>
<br/>

<h4 id="가변-매개변수">가변 매개변수</h4>
<p>Stream 클래스의 of() 메소드를 사용하면 가변 매개변수(임의의 값)를 전달받아 스트림을 생성할 수 있다</p>
<p>그러면 무조건 이것만 쓰면 되는거 아닌가?
맞긴 하지만 다른 방식이 더 효율적이기 때문에 타입에 따라 나누는 게 좋다</p>
<pre><code class="language-java">import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class VarArgsAndStreamExample {

    public static void main(String[] args) {
        List&lt;String&gt; result = filterStrings(&quot;A&quot;, &quot;BB&quot;, &quot;CCC&quot;, &quot;DDDD&quot;);
        System.out.println(result); // [CCC, DDDD]
    }

    public static List&lt;String&gt; filterStrings(String... strings) {
        return Stream.of(strings)
                     .filter(s -&gt; s.length() &gt;= 3)
                     .collect(Collectors.toList());
    }
}</code></pre>
<pre><code class="language-json">4.2
2.5
3.1
1.9</code></pre>
<br/>

<h4 id="지정된-범위의-연속된-정수">지정된 범위의 연속된 정수</h4>
<p>지정된 범위의 연속된 정수를 스트림으로 생성하기 위해 IntStream나 LongStream 인터페이스에는 range()와 rangeClosed() 메소드가 정의되어 있다</p>
<blockquote>
</blockquote>
<p>range() 메소드는 명시된 시작 정수를 포함하지만, 명시된 마지막 정수는 포함하지 않는다
rangeClosed() 메소드는 명시된 시작 정수뿐만 아니라 명시된 마지막 정수까지도 포함하는 스트림을 생성한다</p>
<pre><code class="language-java">// 지정된 범위의 연속된 정수에서 스트림 생성
IntStream stream1 = IntStream.range(1, 4);

stream1.forEach(e -&gt; System.out.print(e + &quot; &quot;));

System.out.println(); 

IntStream stream2 = IntStream.rangeClosed(1, 4);

stream2.forEach(e -&gt; System.out.print(e + &quot; &quot;));</code></pre>
<pre><code class="language-json">1 2 3 
1 2 3 4</code></pre>
<br/>

<h4 id="특정-타입의-난수들">특정 타입의 난수들</h4>
<p>특정 타입의 난수로 이루어진 스트림을 생성하기 위해 Random 클래스에는 ints(), longs(), doubles()와 같은 메소드가 정의되어 있다</p>
<p>이 메소드들은 매개변수로 스트림의 크기를 long 타입으로 전달받을 수 있다</p>
<p>이 메소드들은 만약 매개변수를 전달받지 않으면 크기가 정해지지 않은 무한 스트림(infinite stream)을 반환한다</p>
<p>이때에는 limit() 메소드를 사용하여 따로 스트림의 크기를 제한해야 한다</p>
<pre><code class="language-java">// 특정 타입의 난수로 이루어진 스트림 생성
IntStream stream = new Random().ints(4);

stream.forEach(System.out::println);</code></pre>
<pre><code class="language-json">1072176871
-649065206
133298431
-616174137</code></pre>
<br/>

<h4 id="람다-표현식">람다 표현식</h4>
<p>람다 표현식을 매개변수로 전달받아 해당 람다 표현식에 의해 반환되는 값을 요소로 하는 무한 스트림을 생성하기 위해 Stream 클래스에는 iterate()와 generate() 메소드가 정의되어 있다</p>
<p>iterate() 메소드는 시드(seed)로 명시된 값을 람다 표현식에 사용하여 반환된 값을 다시 시드로 사용하는 방식으로 무한 스트림을 생성한다</p>
<pre><code class="language-java">IntStream stream = Stream.iterate(2, n -&gt; n + 2); 
// 2, 4, 6, 8, 10, ...</code></pre>
<p>반면에 generate() 메소드는 매개변수가 없는 람다 표현식을 사용하여 반환된 값으로 무한 스트림을 생성한다</p>
<pre><code class="language-java">Stream&lt;Double&gt; generateStream = Stream.generate(Math::random); 
// 랜덤한 숫자들을 무한히 생성</code></pre>
<br/>

<h4 id="파일">파일</h4>
<p>파일의 한 줄(line)을 요소로 하는 스트림을 생성하기 위해 java.nio.file.Files 클래스에는 lines() 메소드가 정의되어 있다</p>
<pre><code class="language-java">String&lt;String&gt; stream = Files.lines(Path path);</code></pre>
<br/>

<h4 id="빈-스트림">빈 스트림</h4>
<p>아무 요소도 가지지 않는 빈 스트림은 Stream 클래스의 empty() 메소드를 사용하여 생성할 수 있다</p>
<pre><code class="language-java">Stream&lt;Object&gt; stream = Stream.empty();

System.out.println(stream.count()); // 스트림의 요소의 총 개수를 출력함.</code></pre>
<pre><code class="language-json">0</code></pre>
<hr>
<h3 id="스트림의-중개-연산">스트림의 중개 연산</h3>
<p>스트림 API에 의해 생성된 초기 스트림은 중개 연산을 통해 또 다른 스트림으로 변환된다</p>
<p>결국 중개 연산은 스트림을 전달받아 스트림을 반환하는 것 이기 때문에, 중개 연산은 연속으로 연결해서 사용할 수 있다</p>
<p>또한, 스트림의 중개 연산은 필터-맵(filter-map) 기반의 API를 사용함으로 지연(lazy) 연산을 통해 성능을 최적화할 수 있습니다.</p>
<blockquote>
<p>대표적인 stream 중개 연산들 <br/></p>
</blockquote>
<ol>
<li>스트림 필터링 : filter(), distinct()</li>
<li>스트림 변환 : map(), flatMap()</li>
<li>스트림 제한 : limit(), skip()</li>
<li>스트림 정렬 : sorted()</li>
<li>스트림 연산 결과 확인 : peek()</li>
</ol>
<br/>

<h4 id="스트림-필터링">스트림 필터링</h4>
<blockquote>
<p>filter()
해당 스트림에서 주어진 조건에 맞는 요소만으로 구성된 새로운 스트림을 반환한다<br/>
distinct()
메소드는 해당 스트림에서 중복된 요소가 제거된 새로운 스트림을 반환한다</p>
</blockquote>
<p>distinct() 메소드는 내부적으로 Object 클래스의 equals() 메소드를 사용하여 요소의 중복을 비교합니다.</p>
<pre><code class="language-java">IntStream stream1 = IntStream.of(7, 5, 5, 2, 1, 2, 3, 5, 4, 6);
IntStream stream2 = IntStream.of(7, 5, 5, 2, 1, 2, 3, 5, 4, 6);

stream1.distinct().forEach(e -&gt; System.out.print(e + &quot; &quot;));
System.out.println();

stream2.filter(n -&gt; n % 2 != 0).forEach(e -&gt; System.out.print(e + &quot; &quot;));</code></pre>
<pre><code class="language-json">7 5 2 1 3 4 6 
7 5 5 1 3 5 </code></pre>
<br/>

<h4 id="스트림-변환">스트림 변환</h4>
<blockquote>
<p>map()
해당 스트림의 요소들을 주어진 함수에 인수로 전달하여, 그 반환값들로 이루어진 새로운 스트림을 반환<br/>
flatMap()
만약 해당 스트림의 요소가 배열일때 각 배열의 각 요소의 반환값을 하나로 합친 새로운 스트림을 얻을 수 있다</p>
</blockquote>
<p>map 예시</p>
<pre><code class="language-java">Stream&lt;String&gt; stream = Stream.of(&quot;HTML&quot;, &quot;CSS&quot;, &quot;JAVA&quot;, &quot;JAVASCRIPT&quot;);

stream.map(s -&gt; s.length()).forEach(System.out::println);</code></pre>
<pre><code class="language-json">4
3
4
10</code></pre>
<br/>

<p>flatMap 예시</p>
<pre><code class="language-java">String[] arr = {&quot;I study hard&quot;, &quot;You study JAVA&quot;, &quot;I am hungry&quot;};

Stream&lt;String&gt; stream = Arrays.stream(arr);

stream.flatMap(s -&gt; Stream.of(s.split(&quot; +&quot;))).forEach(System.out::println);</code></pre>
<pre><code class="language-json">I
study
hard
You
study
JAVA
I
am
hungry</code></pre>
<p>위 예시와 같이 flatMap은 스트림의 요소가 stream일 때 이를 하나의 stream으로 합쳐주는 역할을 하는 것이다</p>
<p>각 요소가 stream이어야 하기 때문에 s.split()이 리턴하는 문자열 배열을 Stream.of()를 통해서 stream으로 바꾸어 준다
(Stream.of 가 아니라 Arrays.stream()이어도 상관없음)</p>
<br/>

<h4 id="스트림-제한">스트림 제한</h4>
<blockquote>
<p>limit():
해당 스트림의 첫 번째 요소부터 전달된 개수만큼의 요소만으로 이루어진 새로운 스트림을 반환한다<br/>
skip():
해당 스트림의 첫 번째 요소부터 전달된 개수만큼의 요소를 제외한 나머지 요소만으로 이루어진 새로운 스트림을 반환한다</p>
</blockquote>
<pre><code class="language-java">IntStream stream1 = IntStream.range(0, 10);
IntStream stream2 = IntStream.range(0, 10);
IntStream stream3 = IntStream.range(0, 10);

stream2.limit(5).forEach(n -&gt; System.out.print(n + &quot; &quot;));
System.out.println();

stream1.skip(4).forEach(n -&gt; System.out.print(n + &quot; &quot;));
System.out.println();

stream3.skip(3).limit(5).forEach(n -&gt; System.out.print(n + &quot; &quot;));</code></pre>
<pre><code class="language-json">4 5 6 7 8 9 
0 1 2 3 4 
3 4 5 6 7 </code></pre>
<br/>

<h4 id="스트림-정렬">스트림 정렬</h4>
<blockquote>
<p>sorted() 메소드는 해당 스트림을 주어진 비교자를 이용하여 정렬한다</p>
</blockquote>
<p>이때 비교자를 전달하지 않으면 기본적으로 사전 편찬 순으로 정렬한다</p>
<pre><code class="language-java">Stream&lt;String&gt; stream1 = Stream.of(&quot;JAVA&quot;, &quot;HTML&quot;, &quot;JAVASCRIPT&quot;, &quot;CSS&quot;);
Stream&lt;String&gt; stream2 = Stream.of(&quot;JAVA&quot;, &quot;HTML&quot;, &quot;JAVASCRIPT&quot;, &quot;CSS&quot;);

stream1.sorted().forEach(s -&gt; System.out.print(s + &quot; &quot;));

System.out.println();

stream2.sorted(Comparator.reverseOrder()).forEach(s -&gt; System.out.print(s + &quot; &quot;));</code></pre>
<pre><code class="language-json">CSS HTML JAVA JAVASCRIPT 
JAVASCRIPT JAVA HTML CSS </code></pre>
<br/>

<p>근데 앞서 배운 내용에서 Comparator은 인터페이스인데 구현체가 없이 저렇게 줘도 되나?</p>
<blockquote>
<p>자바 8부터 인터페이스에도 구현이 포함될 수 있게 변경되었다<br/>
그러면 추상클래스와 차이는 뭐야?</p>
</blockquote>
<ul>
<li>추상 클래스는 상태 (멤버 변수)를 가질 수 있지만, 인터페이스는 상수만 가질 수 있다</li>
<li>추상 클래스는 단일 상속만 가능하지만, 인터페이스는 다중 상속이 가능하다.</li>
<li>추상 클래스는 일반 메서드, 생성자, 필드도 포함할 수 있지만, 인터페이스는 디폴트 메서드와 정적 메서드 (및 private 메서드)만 구현을 가질 수 있다.</li>
</ul>
<p>아하 그러면 위에서 Comparator는 인터페이스이고 reverseOrder()는 정적 메소드이구나</p>
<br/>

<h4 id="스트림-연산-결과-확인">스트림 연산 결과 확인</h4>
<blockquote>
<p>peek() 메소드는 결과 스트림으로부터 요소를 소모하여 추가로 명시된 동작을 수행한다</p>
</blockquote>
<p>이 메소드는 원본 스트림에서 요소를 소모하지 않으므로, 주로 연산과 연산 사이에 결과를 확인하고 싶은 디버깅 용도로 많이 활용한다</p>
<pre><code class="language-java">IntStream stream = IntStream.of(7, 5, 5, 2, 1, 2, 3, 5, 4, 6);

stream.peek(s -&gt; System.out.println(&quot;원본 스트림 : &quot; + s))
    .skip(2)
    .peek(s -&gt; System.out.println(&quot;skip(2) 실행 후 : &quot; + s))
    .limit(5)
    .peek(s -&gt; System.out.println(&quot;limit(5) 실행 후 : &quot; + s))
    .sorted()
    .peek(s -&gt; System.out.println(&quot;sorted() 실행 후 : &quot; + s))
    .forEach(n -&gt; System.out.println(n));</code></pre>
<pre><code class="language-json">원본 스트림 : 7
원본 스트림 : 5
원본 스트림 : 5
skip(2) 실행 후 : 5
limit(5) 실행 후 : 5
원본 스트림 : 2
skip(2) 실행 후 : 2
limit(5) 실행 후 : 2
원본 스트림 : 1
skip(2) 실행 후 : 1
limit(5) 실행 후 : 1
원본 스트림 : 2
skip(2) 실행 후 : 2
limit(5) 실행 후 : 2
원본 스트림 : 3
skip(2) 실행 후 : 3
limit(5) 실행 후 : 3
sorted() 실행 후 : 1
1
sorted() 실행 후 : 2
2
sorted() 실행 후 : 2
2
sorted() 실행 후 : 3
3
sorted() 실행 후 : 5
5</code></pre>
<p>위에서 7, 5, 5, 2, 1, 2, 3, 5, 4, 6 이 순서대로 각각의 중간 연산을 거치기 때문에 하나씩 출력된 결과가 위와 같이 나온다</p>
<p>이렇게 peek() 메소드는 스트림의 각 요소가 해당 중개 연산 후에 어떻게 변화하는지를 보여준다</p>
<p>peek()가 없으면 그냥 아래와 같이 최종 결과만 나올 것이다</p>
<pre><code class="language-json">1
2
2
3
5</code></pre>
<hr>
<h3 id="스트림의-최종-연산">스트림의 최종 연산</h3>
<h4 id="스트림의-최종-연산-1">스트림의 최종 연산</h4>
<p>스트림 API에서 중개 연산을 통해 변환된 스트림은 마지막으로 최종 연산을 통해 각 요소를 소모하여 결과를 표시한다</p>
<p>즉, 지연(lazy)되었던 모든 중개 연산들이 최종 연산 시에 모두 수행되는 것임</p>
<p>이렇게 최종 연산 시에 모든 요소를 소모한 해당 스트림은 더는 사용할 수 없게 된다</p>
<blockquote>
<p>Stream의 대표적인 최종 연산들의 메소드들</p>
</blockquote>
<ol>
<li>요소의 출력 : forEach()</li>
<li>요소의 소모 : reduce()</li>
<li>요소의 검색 : findFirst(), findAny()</li>
<li>요소의 검사 : anyMatch(), allMatch(), noneMatch()</li>
<li>요소의 통계 : count(), min(), max()</li>
<li>요소의 연산 : sum(), average()</li>
<li>요소의 수집 : collect()</li>
</ol>
<br/>

<h4 id="요소의-출력">요소의 출력</h4>
<blockquote>
<p>스트림의 각 요소를 소모하여 명시된 동작을 수행한다</p>
</blockquote>
<p>반환 타입이 void이므로 보통 스트림의 모든 요소를 출력하는 용도로 많이 사용함</p>
<pre><code class="language-java">Stream&lt;String&gt; stream = Stream.of(&quot;넷&quot;, &quot;둘&quot;, &quot;셋&quot;, &quot;하나&quot;);

stream.forEach(System.out::println);</code></pre>
<pre><code class="language-json">넷
둘
셋
하나</code></pre>
<br/>

<h4 id="요소의-소모">요소의 소모</h4>
<blockquote>
<p>reduce() 메소드는 첫 번째와 두 번째 요소를 가지고 연산을 수행한 뒤, 그 결과와 세 번째 요소를 가지고 또다시 연산을 수행하는 식으로 해당 스트림의 모든 요소를 소모하여 연산을 수행하고, 그 결과를 반환한다</p>
</blockquote>
<p>또한, 인수로 초깃값을 전달하면 초깃값과 해당 스트림의 첫 번째 요소와 연산을 시작하며, 그 결과와 두 번째 요소를 가지고 계속해서 연산을 수행한다</p>
<pre><code class="language-java">Stream&lt;String&gt; stream1 = Stream.of(&quot;넷&quot;, &quot;둘&quot;, &quot;셋&quot;, &quot;하나&quot;);
Stream&lt;String&gt; stream2 = Stream.of(&quot;넷&quot;, &quot;둘&quot;, &quot;셋&quot;, &quot;하나&quot;);

Optional&lt;String&gt; result1 = stream1.reduce((s1, s2) -&gt; s1 + &quot;++&quot; + s2);

result1.ifPresent(System.out::println);

String result2 = stream2.reduce(&quot;시작&quot;, (s1, s2) -&gt; s1 + &quot;++&quot; + s2);

System.out.println(result2);</code></pre>
<pre><code class="language-json">넷++둘++셋++하나
시작++넷++둘++셋++하나</code></pre>
<p>초기값을 전달하지 않는 reduce() 메소드는 반환타입이 Optional T 이지만,
초깃값을 전달하는 reduce() 메소드의 반환 타입은 T 타입입니다.</p>
<br/>

<h4 id="요소의-검색">요소의 검색</h4>
<blockquote>
<p>findFirst()와 findAny() 메소드는 해당 스트림에서 첫 번째 요소를 참조하는 Optional 객체를 반환한다</p>
</blockquote>
<p>두 메소드 모두 비어 있는 스트림에서는 비어있는 Optional T 객체를 반환합니다.</p>
<pre><code class="language-java">IntStream stream1 = IntStream.of(4, 2, 7, 3, 5, 1, 6);
IntStream stream2 = IntStream.of(4, 2, 7, 3, 5, 1, 6);

OptionalInt result1 = stream1.sorted().findFirst();
System.out.println(result1.getAsInt());

OptionalInt result2 = stream2.sorted().findAny();
System.out.println(result2.getAsInt());</code></pre>
<pre><code class="language-json">1
1</code></pre>
<p>그러면 둘의 차이는 뭐냐?
병렬 스트림인 경우에는 findAny() 메소드를 사용해야만 정확한 연산 결과를 반환할 수 있다</p>
<blockquote>
<p>왜?
findFirst()는 병렬 스트림에서도 항상 스트림의 첫 번째 요소를 반환하려고 하기 때문에 첫번째 요소에 도달하기 위해 추가적인 조정과 동기화가 필요하다. 즉 성능저하가 발생할 수 있음<br/>
이에 반해 findAny()는 병렬 스트림에서 스트림의 어느 요소든지 빠르게 찾아 반환하는 것을 목적으로 하기 때문에 첫 번째 요소가 아닌 다른 요소를 반환할 수도 있다. </p>
</blockquote>
<br/>

<h4 id="요소의-검사">요소의 검사</h4>
<blockquote>
<p>해당 스트림의 요소 중에서 특정 조건을 만족하는 요소가 있는지, 아니면 모두 만족하거나 모두 만족하지 않는지를 확인한다<br/></p>
</blockquote>
<ol>
<li>anyMatch() : 해당 스트림의 일부 요소가 특정 조건을 만족할 경우에 true를 반환<br/></li>
<li>allMatch() : 해당 스트림의 모든 요소가 특정 조건을 만족할 경우에 true를 반환<br/></li>
<li>noneMatch() : 해당 스트림의 모든 요소가 특정 조건을 만족하지 않을 경우에 true를 반환</li>
</ol>
<p>세 메소드 모두 인수로 Predicate 객체를 전달받으며, 요소의 검사 결과는 boolean 값으로 반환한다</p>
<pre><code class="language-java">IntStream stream1 = IntStream.of(30, 90, 70, 10);
IntStream stream2 = IntStream.of(30, 90, 70, 10);

System.out.println(stream1.anyMatch(n -&gt; n &gt; 80));
System.out.println(stream2.allMatch(n -&gt; n &gt; 80));</code></pre>
<pre><code class="language-json">true
false</code></pre>
<blockquote>
<p>+) Predicate
Predicate는 자바에서 제공하는 함수형 인터페이스 중 하나로 Java 8부터 java.util.function 패키지에 소개되었으며, 주로 람다 표현식과 스트림 API에서 사용된다 <br/>
Predicate 인터페이스는 한 개의 입력 파라미터를 받아 조건에 따라 boolean 값을 반환하는 test라는 메서드를 정의한다 <br/>
Predicate 인터페이스는 and(), or(), negate()와 같은 다양한 디폴트 메서드들도 제공하고 이를 통해 여러 개의 조건을 조합할 수 있다</p>
</blockquote>
<br/>

<h4 id="요소의-통계--count-min-max">요소의 통계 : count(), min(), max()</h4>
<blockquote>
</blockquote>
<ul>
<li>count() 메소드는 해당 스트림의 요소의 총 개수를 long 타입의 값으로 반환한다</li>
<li>max()와 min() 메소드를 사용하면 해당 스트림의 요소 중에서 가장 큰 값과 가장 작은 값을 가지는 요소를 참조하는 Optional T 객체를 얻을 수 있다</li>
</ul>
<pre><code class="language-java">IntStream stream1 = IntStream.of(30, 90, 70, 10);
IntStream stream2 = IntStream.of(30, 90, 70, 10);

System.out.println(stream1.count());
System.out.println(stream2.max().getAsInt());</code></pre>
<pre><code class="language-json">4
90</code></pre>
<blockquote>
<p>+) OptionalInt
여기서 stream2는 IntStream이고 이로 인해 stream2.max()는 OptionalInt를 반환하기 때문에 값을 얻기 위해서는 get()이 아니라 getAsInt()를 사용해야만 한다
(Optional이면 getAsInt() 가 안되고, OptionalInt면 get()이 안됨)</p>
</blockquote>
<br/>

<h4 id="요소의-연산--sum-average">요소의 연산 : sum(), average()</h4>
<blockquote>
<p>IntStream이나 DoubleStream과 같은 기본 타입 스트림에 포함된 해당 스트림의 모든 요소에 대해 합과 평균을 구할 수 있는 메소드</p>
</blockquote>
<p>이때 sum() 메소드는 해당하는 T 타입을, average() 메소드는 각 기본 타입으로 래핑 된 OptionalDouble객체를 반환한다</p>
<pre><code class="language-java">IntStream stream1 = IntStream.of(30, 90, 70, 10);
DoubleStream stream2 = DoubleStream.of(30.3, 90.9, 70.7, 10.1);

System.out.println(stream1.sum());
System.out.println(stream2.average().getAsDouble());</code></pre>
<pre><code class="language-json">200
50.5</code></pre>
<br/>

<h4 id="요소의-수집">요소의 수집</h4>
<blockquote>
<p>collect() 메소드는 인수로 전달되는 Collectors 객체에 구현된 방법대로 스트림의 요소를 수집한다</p>
</blockquote>
<p>Collectors 클래스에는 미리 정의된 다양한 방법이 클래스 메소드로 정의되어 있으며  사용자가 직접 Collector 인터페이스를 구현하여 자신만의 수집 방법을 정의할 수도 있다</p>
<blockquote>
<p>Collectors 클래스의 메소드<br/></p>
</blockquote>
<ol>
<li>스트림을 배열이나 컬렉션으로 변환 : toArray(), toCollection(), toList(), toSet(), toMap() <br/></li>
<li>요소의 통계와 연산 메소드와 같은 동작을 수행 : counting(), maxBy(), minBy(), summingInt(), averagingInt() 등<br/></li>
<li>요소의 소모와 같은 동작을 수행 : reducing(), joining()<br/></li>
<li>요소의 그룹화와 분할 : groupingBy(), partitioningBy()</li>
</ol>
<p>toList() 예제</p>
<pre><code class="language-java">Stream&lt;String&gt; stream = Stream.of(&quot;넷&quot;, &quot;둘&quot;, &quot;하나&quot;, &quot;셋&quot;);

List&lt;String&gt; list = stream.collect(Collectors.toList());

Iterator&lt;String&gt; iter = list.iterator();

while(iter.hasNext()) {
    System.out.print(iter.next() + &quot; &quot;);
}</code></pre>
<pre><code class="language-json">넷 둘 하나 셋 </code></pre>
<br/>

<p>groupingBy() 예제</p>
<pre><code class="language-java">import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class Student {
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public int getScore() {
        return score;
    }

    @Override
    public String toString() {
        return name + &quot;: &quot; + score;
    }
}

public class GroupingExample {
    public static void main(String[] args) {
        List&lt;Student&gt; students = List.of(
            new Student(&quot;John&quot;, 90),
            new Student(&quot;Jane&quot;, 85),
            new Student(&quot;Tom&quot;, 85),
            new Student(&quot;Alice&quot;, 92)
        );

        // 학생들을 점수에 따라 그룹화
        Map&lt;Integer, List&lt;Student&gt;&gt; groupedByScore = students.stream()
            .collect(Collectors.groupingBy(Student::getScore));

        System.out.println(groupedByScore);
    }
}</code></pre>
<pre><code class="language-json">{85=[Jane: 85, Tom: 85], 90=[John: 90], 92=[Alice: 92]}
</code></pre>
<br/>

<p>partitioningBy() 예제</p>
<pre><code class="language-java">Stream&lt;String&gt; stream = Stream.of(&quot;HTML&quot;, &quot;CSS&quot;, &quot;JAVA&quot;, &quot;PHP&quot;);

Map&lt;Boolean, List&lt;String&gt;&gt; patition = stream.collect(Collectors.partitioningBy(s -&gt; (s.length() % 2) == 0));

List&lt;String&gt; oddLengthList = patition.get(false);
System.out.println(oddLengthList);

List&lt;String&gt; evenLengthList = patition.get(true);
System.out.println(evenLengthList);</code></pre>
<pre><code class="language-json">[CSS, PHP]
[HTML, JAVA]</code></pre>
<hr>
<h3 id="optional-클래스">Optional 클래스</h3>
<blockquote>
<p>Optional T 클래스는 Integer나 Double 클래스처럼 &#39;T&#39;타입의 객체를 포장해 주는 래퍼 클래스이기 때문에 모든 타입의 참조변수를 저장할 수 있다</p>
</blockquote>
<p>왜 쓰는가?
Optional 클래스를 통해서 복잡한 구문 없이도 null값으로 인해 발생하는 NullPointerException을 처리할 수 있다</p>
<br/>

<h4 id="optional-생성">Optional 생성</h4>
<blockquote>
</blockquote>
<p> of() 메소드로 생성: null이 아닌 명시된 값을 가짐
(null이 저장되면 NullPointerException이 발생함)<br/>
ofNullable() 메소드로 생성: null이 아니면 명시된 값을 가지는 Optional 객체를 반환하고 null이면 비어있는 Optional 객체를 반환한다</p>
<pre><code class="language-ㅓㅁㅍㅁ">Optional&lt;String&gt; opt = Optional.ofNullable(&quot;자바 Optional 객체&quot;);

System.out.println(opt.get());</code></pre>
<pre><code class="language-json">자바 Optional 객체</code></pre>
<br/>

<h4 id="optional-객체에-접근">Optional 객체에 접근</h4>
<blockquote>
<p>get() 메소드를 사용하여 Optional 객체에 저장된 값에 접근
(Optional 객체에 저장된 값이 null이면, NoSuchElementException 예외가 발생)</p>
</blockquote>
<p>따라서 get() 메소드를 호출하기 전에 isPresent() 메소드를 사용하여 Optional 객체에 저장된 값이 null인지 아닌지를 먼저 확인한 후 호출하는 것이 좋다</p>
<pre><code class="language-java">Optional&lt;String&gt; opt = Optional.ofNullable(&quot;자바 Optional 객체&quot;);

if(opt.isPresent()) {
    System.out.println(opt.get());
}</code></pre>
<pre><code class="language-json">자바 Optional 객체</code></pre>
<p>또한, 다음과 같은 메소드를 사용하여 null 대신에 대체할 값을 지정할 수도 있다</p>
<blockquote>
</blockquote>
<ol>
<li>orElse() 메소드 : 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 값을 반환함 <br/></li>
<li>orElseGet() 메소드 : 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 람다 표현식의 결괏값을 반환함<br/></li>
<li>orElseThrow() 메소드 : 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 예외를 발생시킴.</li>
</ol>
<pre><code class="language-java">Optional&lt;String&gt; opt = Optional.empty(); // Optional를 null로 초기화함.

System.out.println(opt.orElse(&quot;빈 Optional 객체&quot;));
System.out.println(opt.orElseGet(String::new));
System.out.println(opt.orElseThrow(IllegalArgumentException::new));</code></pre>
<pre><code class="language-json">빈 Optional 객체</code></pre>
<br/>

<h4 id="기본-타입의-optional-클래스">기본 타입의 Optional 클래스</h4>
<p>자바에서는 IntStream 클래스와 같이 기본 타입 스트림을 위한 별도의 Optional 클래스를 제공한다 </p>
<blockquote>
</blockquote>
<ol>
<li>OptionalInt 클래스</li>
<li>OptionalLong 클래스</li>
<li>OptionalDouble 클래스</li>
</ol>
<p>이러한 클래스는 반환 타입이 Optional T 타입이 아니라 해당 기본 타입이라는 사실만 제외하면 거의 모든 면에서 비슷함</p>
<p>그리고 각각은 다른 get() 메소드를 통해서 값에 접근할 수 있다</p>
<blockquote>
</blockquote>
<p>Optional T :    T get()
OptionalInt :    int getAsInt()
OptionalLong :    long getAsLong()
OptionalDouble :    double getAsDouble()</p>
<pre><code class="language-java">IntStream stream = IntStream.of(4, 2, 1, 3);

OptionalInt result = stream.findFirst();

System.out.println(result.getAsInt());</code></pre>
<pre><code class="language-json">4</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[람다 표현식]]></title>
            <link>https://velog.io/@gyu_won/java16</link>
            <guid>https://velog.io/@gyu_won/java16</guid>
            <pubDate>Sat, 14 Oct 2023 12:24:35 GMT</pubDate>
            <description><![CDATA[<h3 id="람다표현식">람다표현식</h3>
<blockquote>
<p>메소드를 하나의 식으로 표현한 것입니다.</p>
</blockquote>
<p>메소드</p>
<pre><code class="language-java">int min(int x, int y) {
    return x &lt; y ? x : y;
}</code></pre>
<p>람다표현식</p>
<pre><code class="language-java">(x, y) -&gt; x &lt; y ? x : y;</code></pre>
<p>그러면 이걸 왜 쓰는가?</p>
<blockquote>
</blockquote>
<ul>
<li>클래스를 작성하고 객체를 생성하지 않아도 메소드를 사용할 수 있다</li>
<li>불필요한 코드를 줄이고 가독성을 높일 수 있다</li>
</ul>
<br/>

<p><strong>람다 표현식 작성</strong>
자바에서는 <code>(매개변수목록) -&gt; { 함수몸체 }</code>와 같이 람다 표현식을 작성한다</p>
<blockquote>
<p>자바에서 람다 표현식을 작성할 때 유의해야 할 사항은 다음과 같다</p>
</blockquote>
<ol>
<li>매개변수의 타입을 추론할 수 있는 경우에는 타입을 생략할 수 있다.</li>
</ol>
<pre><code class="language-java">// 타입을 명시한 경우
(String s) -&gt; System.out.println(s)
// 타입을 생략한 경우
s -&gt; System.out.println(s)</code></pre>
<ol start="2">
<li>매개변수가 하나인 경우에는 괄호(())를 생략할 수 있다.<pre><code class="language-java">// 괄호를 사용한 경우
(s) -&gt; System.out.println(s)
</code></pre>
</li>
</ol>
<p>// 괄호를 생략한 경우
s -&gt; System.out.println(s)</p>
<pre><code>3. 함수의 몸체가 하나의 명령문만으로 이루어진 경우에는 중괄호({})를 생략할 수 있다. (이때 세미콜론(;)은 붙이지 않음)
```java
// 중괄호를 사용한 경우
s -&gt; { System.out.println(s); }

// 중괄호를 생략한 경우
s -&gt; System.out.println(s)</code></pre><ol start="4">
<li>함수의 몸체가 하나의 return 문으로만 이루어진 경우에는 중괄호({})를 생략할 수 없다<pre><code class="language-java">// 잘못된 예
x -&gt; return x * x;  
</code></pre>
</li>
</ol>
<p>// 올바른 예
x -&gt; x * x</p>
<pre><code>5. return 문 대신 표현식을 사용할 수 있으며, 이때 반환값은 표현식의 결괏값이 된다 
(이때 세미콜론(;)은 붙이지 않음)
```java
// return 문을 사용한 경우
x -&gt; { return x * x; }

// 표현식을 사용한 경우 (return 및 세미콜론 생략)
x -&gt; x * x</code></pre><br/>

<p>** 함수형 인터페이스(functional interface) **</p>
<blockquote>
</blockquote>
<p>Java 8부터 도입된 개념으로, 오직 하나의 추상 메서드만을 포함하는 인터페이스를 의미</p>
<p>왜 쓰는가?</p>
<p>람다표현식을 통해서 해당 함수를 작성하는 것으로 코드의 부족한 부분을 사용자가 지정해서 줄 수 있음</p>
<pre><code class="language-java">@FunctionalInterface // 위와 같은 어노테이션을 사용하여 함수형 인터페이스임을 명시
public interface MyFunctionalInterface {
    void execute();
}

public class Lambda02 {
  public static void main(String[] args) {
      runTask(() -&gt; System.out.println(&quot;Task 1&quot;));
      runTask(() -&gt; System.out.println(&quot;Task 2&quot;));
  }

  public static void runTask(MyFunctionalInterface task) {
      task.execute();
}

}</code></pre>
<pre><code class="language-json">Task 1
Task 2</code></pre>
<br/>

<p>stream에서 map 이나 filter를 사용했던 것도 그 뒷단은 함수형 인터페이스 임</p>
<pre><code class="language-java">List&lt;String&gt; list = Arrays.asList(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;);
list.stream().filter(s -&gt; s.startsWith(&quot;A&quot;)).forEach(System.out::println); // &quot;A&quot;</code></pre>
<pre><code class="language-java">List&lt;String&gt; list = Arrays.asList(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;);
list.stream().map(s -&gt; s.toLowerCase()).forEach(System.out::println); // &quot;a&quot; &quot;b&quot; &quot;c&quot;</code></pre>
<p> 이렇게 함수형 인터페이스를 통해 람다식으로 함수를 정의하고 exectue()를 실행한거라고 보면 됨</p>
<hr>
<h3 id="메소드-참조">메소드 참조</h3>
<blockquote>
<p>람다 표현식이 단 하나의 메소드만을 호출하는 경우에 해당 람다 표현식에서 불필요한 매개변수를 제거하고 사용할 수 있도록 해준다</p>
</blockquote>
<blockquote>
<p>문법:
클리스이름::메소드이름
참조변수이름::메소드이름</p>
</blockquote>
<p>람다표현식</p>
<pre><code class="language-java">(base, exponent) -&gt; Math.pow(base, exponent);</code></pre>
<p>위의 예제는 단순히 Math 클래스의 pow() 메소드로 인수를 전달하는 역할만 하므로, 메소드 참조를 사용하여 아래와 같이 표현할 수 있다</p>
<pre><code class="language-java">Math::pow;</code></pre>
<p>특정 인스턴스의 메소드를 참조할 때에도 참조 변수의 이름을 통해 메소드 참조를 사용할 수 있다</p>
<pre><code class="language-java">MyClass obj = new MyClass;

Function&lt;String, Boolean&gt; func = (a) -&gt; obj.equals(a); // 람다 표현식
Function&lt;String, Boolean&gt; func = obj::equals(a);       // 메소드 참조</code></pre>
<pre><code class="language-java">DoubleUnaryOperator oper;

oper = (n) -&gt; Math.abs(n); // 람다 표현식
System.out.println(oper.applyAsDouble(-5));

oper = Math::abs; // 메소드 참조
System.out.println(oper.applyAsDouble(-5));</code></pre>
<pre><code class="language-json">5.0
5.0</code></pre>
<p>DoubleUnaryOperator 인터페이스는 한 개의 double 형 매개변수를 전달받아 한 개의 double 형 값을 반환하는 java.util.function 패키지에서 제공하는 함수형 인터페이스이다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스레드]]></title>
            <link>https://velog.io/@gyu_won/java15</link>
            <guid>https://velog.io/@gyu_won/java15</guid>
            <pubDate>Sat, 14 Oct 2023 09:18:51 GMT</pubDate>
            <description><![CDATA[<h3 id="스레드">스레드</h3>
<h4 id="프로세스">프로세스</h4>
<blockquote>
<p>운영체제에 의해 메모리 공간을 할당받아 실행 중인 프로그램</p>
</blockquote>
<p>프로세스는 프로그램에 사용되는 데이터와 메모리 등의 자원 그리고 스레드로 구성됨
<br/></p>
<h4 id="스레드-1">스레드</h4>
<blockquote>
<p>프로세스 내에서 실제로 작업을 수행하는 주체를 의미합니다.</p>
</blockquote>
<p>즉, 모든 프로세스에는 한 개 이상의 스레드가 존재하여 작업을 수행한다</p>
<br/>

<h4 id="스레드의-생성과-실행">스레드의 생성과 실행</h4>
<blockquote>
<p>스레드 생성하는 방법:</p>
</blockquote>
<ol>
<li>Runnable 인터페이스를 구현하는 방법</li>
<li>Thread 클래스를 상속받는 방법</li>
</ol>
<p>두 방법 모두 스레드를 통해 작업하고 싶은 내용을 run() 메소드에 작성하면 된다</p>
<pre><code class="language-java">class ThreadWithClass extends Thread {
    public void run() {
        for (int i = 0; i &lt; 5; i++) {
            System.out.println(getName()); // 현재 실행 중인 스레드의 이름을 반환함.
            try {
                Thread.sleep(10);          // 0.01초간 스레드를 멈춤.
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class ThreadWithRunnable implements Runnable {
    public void run() {
        for (int i = 0; i &lt; 5; i++) {
            System.out.println(Thread.currentThread().getName()); // 현재 실행 중인 스레드의 이름을 반환함
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


public class Thread01 {
    public static void main(String[] args){
        ThreadWithClass thread1 = new ThreadWithClass();       // Thread 클래스를 상속받는 방법
        Thread thread2 = new Thread(new ThreadWithRunnable()); // Runnable 인터페이스를 구현하는 방법

        thread1.start(); // 스레드의 실행
        thread2.start(); // 스레드의 실행
    }
}</code></pre>
<pre><code class="language-json">Thread-0
Thread-1
Thread-0
Thread-1
Thread-0
Thread-1
Thread-0
Thread-1
Thread-0
Thread-1</code></pre>
<br/>

<p>그러면 어떤 방법을 써야할까?</p>
<blockquote>
<p>자바는 단일 상속만 되기 때문에 Thread 클래스를 상속받으면 다른 클래스를 상속받을 수 없으므로, 일반적으로 Runnable 인터페이스를 구현하는 방법으로 스레드를 생성한다</p>
</blockquote>
<br/>

<p>** 스레드의 우선순위 **</p>
<blockquote>
<p>우선순위에 따라 특정 스레드가 더 많은 시간동안 작업할 수 있도록 설정하기 위해서 모든 스레드는 우선순위에 관한 필드를 가지고 있다</p>
</blockquote>
<p>우선순위와 관련된 필드
<code>static int MAX_PRIORITY</code> :    스레드가 가질 수 있는 최대 우선순위를 명시함
<code>static int MIN_PRIORITY</code> :    스레드가 가질 수 있는 최소 우선순위를 명시함
<code>static int NORM_PRIORITY</code> :    스레드가 생성될 때 가지는 기본 우선순위를 명시함</p>
<p>int형인것을 보니까 우선순위는 정수네!</p>
<p>=&gt; 스레드의 우선순위가 가질 수 있는 범위는 1부터 10까지이며, 숫자가 높을수록 우선순위 또한 높아진다</p>
<p>getPriority()와 setPriority() 메소드를 통해 스레드의 우선순위를 반환하거나 변경할 수 있음</p>
<p>우선순위는 절대값이 아닌 상대값 이기 때문에 10인 스레드가 우선순위가 1인 스레드보다 10배 더 빨리 수행되는 것이 아니라 단순히 좀 더 많이 실행 큐에 포함되어 더 많은 작업 시간을 할당 받는 거임</p>
<p>추가로, 스레드의 우선순위는 해당 스레드를 생성한 스레드의 우선순위를 상속받게 된다</p>
<pre><code class="language-java">class ThreadWithRunnable implements Runnable {
    public void run() {
        for (int i = 0; i &lt; 5; i++) {
            System.out.println(Thread.currentThread().getName()); // 현재 실행 중인 스레드의 이름을 반환함.
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


public class Thread02 {
    public static void main(String[] args){
        Thread thread1 = new Thread(new ThreadWithRunnable());
        Thread thread2 = new Thread(new ThreadWithRunnable());

       thread2.setPriority(10); // Thread-1의 우선순위를 10으로 변경함.

       thread1.start(); // Thread-0 실행
       thread2.start(); // Thread-1 실행

        System.out.println(thread1.getPriority());
        System.out.println(thread2.getPriority());
    }
}</code></pre>
<pre><code class="language-json">5
10
Thread-1
Thread-0
Thread-1
Thread-0
Thread-1
Thread-0
Thread-1
Thread-0
Thread-1
Thread-0</code></pre>
<p>main() 메소드를 실행하는 스레드의 우선순위는 언제나 5이므로, main() 메소드 내에서 생성된 스레드 Thread-0의 우선순위는 5로 설정됨</p>
<p>Thread-0을 먼저 실행하였지만, Thread-1의 우선순위가 더 높기 때문에 Thread-1이 먼저 실행된 것을 볼 수 있음</p>
<hr>
<h3 id="멀티스레드">멀티스레드</h3>
<p>앞서 스레드를 설명할때 다음과 같이 설명했다</p>
<blockquote>
<p>모든 프로세스에는 한 개 이상의 스레드가 존재하여 작업을 수행한다</p>
</blockquote>
<p>한개 이상이라고 했으니 여러개도 가능하다는 소리네
<br/></p>
<p>** 멀티 스레드 **</p>
<blockquote>
<p>하나의 프로세스 내에 두 개 이상의 스레드가 동시에 작업을 수행하는 것</p>
</blockquote>
<p>하나의 스레드가 작업을 할 때 다른 스레드가 별도의 작업을 할 수 있으니까 사용자와의 응답성이 좋아진다</p>
<p>또 여러게 프로세스를 쓰는 것보다 하나를 쓰는게 자원을 공유하기 때문에 낭비가 적다</p>
<br/>

<p>** 멀티 프로세스 **</p>
<blockquote>
<p>여러 개의 CPU를 사용하여 여러 프로세스를 동시에 수행하는 것</p>
</blockquote>
<p>멀티 스레드와 멀티 프로세스 모두 여러 흐름을 동시에 수행하다는 공통점을 가지고 있다</p>
<blockquote>
<p>둘의 차이점은?</p>
</blockquote>
<ol>
<li>멀티 프로세스는 각 프로세스가 독립적인 메모리를 가지고 별도로 실행되지만, 멀티 스레드는 각 스레드가 자신이 속한 프로세스의 메모리를 공유한다<br/></li>
<li>멀티 스레드는 각 스레드가 자신이 속한 프로세스의 메모리를 공유하므로, 시스템 자원의 낭비가 적다</li>
</ol>
<br/>

<p><strong>문맥 교환(context switching)</strong>
컴퓨터에서 동시에 처리할 수 있는 최대 작업 수는 CPU의 코어 수와 같은데 CPU 코어 수보다 더 많은 스레드가 실행되면, 각 코어가 정해진 시간 동안 여러 작업을 번갈아가며 수행한다 </p>
<p>그러면 스레드가 교체될텐데 현재까지의 작업상태를 저장하고, 다음 작업에 필요한 각종 데이터를 읽는 작업이 필요하다</p>
<blockquote>
<p>문맥 교환:
문맥 교환이란 현재까지의 작업 상태나 다음 작업에 필요한 각종 데이터를 저장하고 읽어오는 작업을 가리킨다</p>
</blockquote>
<p>이러한 문맥 교환에 걸리는 시간이 커지면 커질수록, 멀티 스레딩의 효율은 저하될 것이다</p>
<p>그래서 문맥교환이 너무 길면 오히려 싱글 스레드가 더 효율적일 수도 있음
(많은 수의 스레드를 실행하는 것이 언제나 좋은 성능을 보이는 것은 아님)</p>
<br/>

<p>** 스레드 그룹 **</p>
<blockquote>
<p>서로 관련이 있는 스레드를 하나의 그룹으로 묶어 다루기 위한 장치</p>
</blockquote>
<p>자바에서는 스레드 그룹을 다루기 위해 ThreadGroup이라는 클래스를 제공한다</p>
<p>이러한 스레드 그룹은 다른 스레드 그룹을 포함할 수도 있으며, 이렇게 포함된 스레드 그룹은 트리 형태로 연결된다</p>
<p>이때 스레드는 자신이 포함된 스레드 그룹이나 그 하위 그룹에는 접근할 수 있지만, 다른 그룹에는 접근할 수 없다</p>
<p>이렇게 범위를 제한하면 보안상으로도 좋겠네</p>
<pre><code class="language-java">class ThreadWithRunnable implements Runnable {
    public void run() {
        try {
            Thread.sleep(10); // 0.01초간 스레드를 멈춤.
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


public class Thread03 {
    public static void main(String[] args){
        Thread thread0 = new Thread(new ThreadWithRunnable());
        thread0.start(); // Thread-0 실행

        System.out.println(thread0.getThreadGroup());

        ThreadGroup group = new ThreadGroup(&quot;myThread&quot;); // myThread라는 스레드 그룹 생성함.
        group.setMaxPriority(7); // 해당 스레드 그룹의 최대 우선순위를 7로 설정함.

        // 스레드를 생성할 때 포함될 스레드 그룹을 전달할 수 있음.
        Thread thread1 = new Thread(group, new ThreadWithRunnable());

        thread1.start(); // Thread-1 실행

        System.out.println(thread1.getThreadGroup());
    }
}</code></pre>
<pre><code class="language-java">java.lang.ThreadGroup[name=main,maxpri=10]
java.lang.ThreadGroup[name=myThread,maxpri=7]</code></pre>
<p>위의 예제처럼 main() 메소드에서 생성된 스레드의 기본 스레드 그룹의 이름은 &quot;main&quot;이 되며, 최대 우선순위는 10으로 자동 설정됨</p>
<br/>

<p>** 데몬 스레드 **</p>
<blockquote>
<p>다른 일반 스레드의 작업을 돕는 보조적인 역할을 하는 스레드</p>
</blockquote>
<p>따라서 데몬 스레드는 일반 스레드가 모두 종료되면 더는 할 일이 없으므로, 데몬 스레드 역시 자동으로 종료된다</p>
<p>일반 스레드와 생성 및 실행 방법은 같고 실행 전에 setDaemon()메소드를 호출하여 데몬 스레드로 설정하기만 하면 된다 
<code>myThread.setDaemon(true);</code></p>
<p>주로 일정 시간마다 자동으로 수행되는 저장 및 화면 갱신 등 백그라운드 작업에 이용함</p>
<br/>

<h3 id="가비지-컬렉터">가비지 컬렉터</h3>
<p><strong>가비지 컬렉터</strong></p>
<blockquote>
<p>프로그래머가 동적으로 할당한 메모리(힙 영역) 중 더 이상 사용하지 않는 영역을 자동으로 찾아내어 해제해 주는 데몬 스레드</p>
</blockquote>
<p>자바에서는 프로그래머가 메모리에 직접 접근하지 못하게 하는 대신에 가비지 컬렉터가 자동으로 메모리를 관리해 준다</p>
<p>이러한 가비지 컬렉터를 이용하면 프로그래밍을 하기가 훨씬 쉬워지며, 메모리에 관련된 버그가 발생할 확률도 낮아진다
<br/></p>
<p>거면 가비지 컬렉터는 장점만 있는가?</p>
<blockquote>
<p>자동으로 처리해준다 해도 메모리가 언제 해제되는지 정확하게 알 수 없어 제어하기 힘들며 가비지 컬렉션(GC)이 동작하는 동안에는 다른 동작을 멈추기 때문에 오버헤드가 발생되는 문제점이 있다</p>
</blockquote>
<p>이를 전문적인 용어로 Stop-The-World 라고 함</p>
<p>그러면 실시간 성이 매우 강조되는 포로그램일 경우 가비지컬렉터에게 메모리 관리를 맡기는게 안좋겠네
=&gt; GC 최적화 작업(GC 튜닝)을 통해서 개발자가 성능을 높여야 한다</p>
<br/>

<p>가비지 컬렉터에 관한 내용과 원리가 궁금해서 이는 검색을 해본 후 따로 정리해서 올릴 예정!</p>
]]></description>
        </item>
    </channel>
</rss>