<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>blanky_munn.log</title>
        <link>https://velog.io/</link>
        <description>iOS 개발자 꿈나무</description>
        <lastBuildDate>Sun, 10 Apr 2022 10:33:51 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. blanky_munn.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/blanky_munn" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[네트워크]]></title>
            <link>https://velog.io/@blanky_munn/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC</link>
            <guid>https://velog.io/@blanky_munn/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC</guid>
            <pubDate>Sun, 10 Apr 2022 10:33:51 GMT</pubDate>
            <description><![CDATA[<h1 id="network">Network</h1>
<h2 id="http의-get과-post-비교"><strong>HTTP의 GET과 POST 비교</strong></h2>
<p>둘 다 HTTP 프로토콜을 이용해서 서버에 무엇인가를 요청할 때 사용하는 방식이다. 하지만 둘의 특징을 제대로 이해하여 기술의 목적에 맞게 알맞은 용도에 사용해야한다.</p>
<h3 id="get"><strong>GET</strong></h3>
<p>우선 GET 방식은 요청하는 데이터가 <code>HTTP Request Message</code>의 Header 부분에 url 이 담겨서 전송된다. 때문에 url 상에 <code>?</code> 뒤에 데이터가 붙어 request 를 보내게 되는 것이다. 이러한 방식은 url 이라는 공간에 담겨가기 때문에 전송할 수 있는 데이터의 크기가 제한적이다. 또 보안이 필요한 데이터에 대해서는 데이터가 그대로 url 에 노출되므로 <code>GET</code>방식은 적절하지 않다. (ex. password)</p>
<h3 id="post"><strong>POST</strong></h3>
<p>POST 방식의 request 는 <code>HTTP Request Message</code>의 Body 부분에 데이터가 담겨서 전송된다. 때문에 바이너리 데이터를 요청하는 경우 POST 방식으로 보내야 하는 것처럼 데이터 크기가 GET 방식보다 크고 보안면에서 낫다.(하지만 보안적인 측면에서는 암호화를 하지 않는 이상 고만고만하다.)</p>
<p><em>그렇다면 이러한 특성을 이해한 뒤에는 어디에 적용되는지를 알아봐야 그 차이를 극명하게 이해할 수 있다.</em> 우선 GET 은 가져오는 것이다. 서버에서 어떤 데이터를 가져와서 보여준다거나 하는 용도이지 서버의 값이나 상태 등을 변경하지 않는다. <strong>SELECT 적인 성향을 갖고 있다고 볼 수 있는 것이다. 반면에 POST 는 서버의 값이나 상태를 변경하기 위해서 또는 추가하기 위해서 사용된다.</strong></p>
<p>부수적인 차이점을 좀 더 살펴보자면 GET 방식의 요청은 브라우저에서 Caching 할 수 있다. 때문에 POST 방식으로 요청해야 할 것을 보내는 데이터의 크기가 작고 보안적인 문제가 없다는 이유로 GET 방식으로 요청한다면 기존에 caching 되었던 데이터가 응답될 가능성이 존재한다. 때문에 목적에 맞는 기술을 사용해야 하는 것이다.</p>
<h2 id="tcp와-udp의-비교"><strong>TCP와 UDP의 비교</strong></h2>
<h3 id="udp"><strong>UDP</strong></h3>
<p><code>UDP(User Datagram Protocol, 사용자 데이터그램 프로토콜)</code>는 <strong>비연결형 프로토콜</strong> 이다. IP 데이터그램을 캡슐화하여 보내는 방법과 연결 설정을 하지 않고 보내는 방법을 제공한다. <code>UDP</code>는 흐름제어, 오류제어 또는 손상된 세그먼트의 수신에 대한 재전송을 <strong>하지 않는다.</strong> 이 모두가 사용자 프로세스의 몫이다. <code>UDP</code>가 행하는 것은 포트들을 사용하여 IP 프로토콜에 인터페이스를 제공하는 것이다.</p>
<p>종종 클라이언트는 서버로 짧은 요청을 보내고, 짧은 응답을 기대한다. 만약 요청 또는 응답이 손실된다면, 클라이언트는 time out 되고 다시 시도할 수 있으면 된다. 코드가 간단할 뿐만 아니라 TCP 처럼 초기설정(initial setup)에서 요구되는 프로토콜보다 적은 메시지가 요구된다.</p>
<p><code>UDP</code>를 사용한 것들에는 <code>DNS</code>가 있다. 어떤 호스트 네임의 IP 주소를 찾을 필요가 있는 프로그램은, DNS 서버로 호스트 네임을 포함한 UDP 패킷을 보낸다. 이 서버는 호스트의 IP 주소를 포함한 UDP 패킷으로 응답한다. 사전에 설정이 필요하지 않으며 그 후에 해제가 필요하지 않다.</p>
<h3 id="tcp"><strong>TCP</strong></h3>
<p>대부분의 인터넷 응용 분야들은 <strong>신뢰성</strong> 과 <strong>순차적인 전달</strong> 을 필요로 한다. UDP 로는 이를 만족시킬 수 없으므로 다른 프로토콜이 필요하여 탄생한 것이 <code>TCP</code>이다. <code>TCP(Transmission Control Protocol, 전송제어 프로토콜)</code>는 <strong>신뢰성이 없는 인터넷을 통해 종단간에 신뢰성 있는 바이트 스트림을 전송 하도록 특별히 설계되었다.</strong> TCP 서비스는 송신자와 수신자 모두가 소켓이라고 부르는 종단점을 생성함으로써 이루어진다. TCP 에서 연결 설정(connection establishment)는 <code>3-way handshake</code>를 통해 행해진다.</p>
<p>모든 TCP 연결은 전이중(full-duplex), 점대점(point to point)방식이다. 전이중이란 전송이 양방향으로 동시에 일어날 수 있음을 의미하며 점대점이란 각 연결이 정확히 2 개의 종단점을 가지고 있음을 의미한다. TCP 는 멀티캐스팅이나 브로드캐스팅을 지원하지 않는다.</p>
<h2 id="http와-https"><strong>HTTP와 HTTPS</strong></h2>
<h3 id="http-의-문제점"><strong>HTTP 의 문제점</strong></h3>
<ul>
<li>HTTP 는 평문 통신이기 때문에 도청이 가능하다.</li>
<li>통신 상대를 확인하지 않기 때문에 위장이 가능하다.</li>
<li>완전성을 증명할 수 없기 때문에 변조가 가능하다.</li>
</ul>
<p><em>위 세 가지는 다른 암호화하지 않은 프로토콜에도 공통되는 문제점들이다.</em></p>
<h3 id="tcpip-는-도청-가능한-네트워크이다"><strong>TCP/IP 는 도청 가능한 네트워크이다.</strong></h3>
<p>TCP/IP 구조의 통신은 전부 통신 경로 상에서 엿볼 수 있다. 패킷을 수집하는 것만으로 도청할 수 있다. 평문으로 통신을 할 경우 메시지의 의미를 파악할 수 있기 때문에 암호화하여 통신해야 한다.</p>
<h3 id="보완-방법"><strong>보완 방법</strong></h3>
<ol>
<li>통신 자체를 암호화 <code>SSL(Secure Socket Layer)</code> or <code>TLS(Transport Layer Security)</code>라는 다른 프로토콜을 조합함으로써 HTTP 의 통신 내용을 암호화할 수 있다. SSL 을 조합한 HTTP 를 <code>HTTPS(HTTP Secure)</code> or <code>HTTP over SSL</code>이라고 부른다.</li>
<li>콘텐츠를 암호화 말 그대로 HTTP 를 사용해서 운반하는 내용인, HTTP 메시지에 포함되는 콘텐츠만 암호화하는 것이다. 암호화해서 전송하면 받은 측에서는 그 암호를 해독하여 출력하는 처리가 필요하다.</li>
</ol>
<h3 id="통신-상대를-확인하지-않기-때문에-위장이-가능하다"><strong>통신 상대를 확인하지 않기 때문에 위장이 가능하다.</strong></h3>
<p>HTTP 에 의한 통신에는 상대가 누구인지 확인하는 처리는 없기 때문에 누구든지 리퀘스트를 보낼 수 있다. IP 주소나 포트 등에서 그 웹 서버에 액세스 제한이 없는 경우 리퀘스트가 오면 상대가 누구든지 무언가의 리스폰스를 반환한다. 이러한 특징은 여러 문제점을 유발한다.</p>
<ol>
<li>리퀘스트를 보낸 곳의 웹 서버가 원래 의도한 리스폰스를 보내야 하는 웹 서버인지를 확인할 수 없다.</li>
<li>리스폰스를 반환한 곳의 클라이언트가 원래 의도한 리퀘스트를 보낸 클라이언트인지를 확인할 수 없다.</li>
<li>통신하고 있는 상대가 접근이 허가된 상대인지를 확인할 수 없다.</li>
<li>어디에서 누가 리퀘스트 했는지 확인할 수 없다.</li>
<li>의미없는 리퀘스트도 수신한다. —&gt; DoS 공격을 방지할 수 없다.</li>
</ol>
<h3 id="보완-방법-1"><strong>보완 방법</strong></h3>
<p>위 암호화 방법으로 언급된 <code>SSL</code>로 상대를 확인할 수 있다. SSL 은 상대를 확인하는 수단으로 <strong>증명서</strong> 를 제공하고 있다. 증명서는 신뢰할 수 있는 <strong>제 3 자 기관에 의해</strong> 발행되는 것이기 때문에 서버나 클라이언트가 실재하는 사실을 증명한다. 이 증명서를 이용함으로써 통신 상대가 내가 통신하고자 하는 서버임을 나타내고 이용자는 개인 정보 누설 등의 위험성이 줄어들게 된다. 한 가지 이점을 더 꼽자면 클라이언트는 이 증명서로 본인 확인을 하고 웹 사이트 인증에서도 이용할 수 있다.</p>
<h3 id="완전성을-증명할-수-없기-때문에-변조가-가능하다"><strong>완전성을 증명할 수 없기 때문에 변조가 가능하다</strong></h3>
<p>여기서 완전성이란 <strong>정보의 정확성</strong> 을 의미한다. 서버 또는 클라이언트에서 수신한 내용이 송신측에서 보낸 내용과 일치한다라는 것을 보장할 수 없는 것이다. 리퀘스트나 리스폰스가 발신된 후에 상대가 수신하는 사이에 누군가에 의해 변조되더라도 이 사실을 알 수 없다. 이와 같이 공격자가 도중에 리퀘스트나 리스폰스를 빼앗아 변조하는 공격을 중간자 공격(Man-in-the-Middle)이라고 부른다.</p>
<h3 id="보완-방법-2"><strong>보완 방법</strong></h3>
<p><code>MD5</code>, <code>SHA-1</code> 등의 해시 값을 확인하는 방법과 파일의 디지털 서명을 확인하는 방법이 존재하지만 확실히 확인할 수 있는 것은 아니다. 확실히 방지하기에는 <code>HTTPS</code>를 사용해야 한다. SSL 에는 인증이나 암호화, 그리고 다이제스트 기능을 제공하고 있다.</p>
<h3 id="https"><strong>HTTPS</strong></h3>
<blockquote>
<p>HTTP 에 암호화와 인증, 그리고 완전성 보호를 더한 HTTPS</p>
</blockquote>
<p><code>HTTPS</code>는 SSL 의 껍질을 덮어쓴 HTTP 라고 할 수 있다. 즉, HTTPS 는 새로운 애플리케이션 계층의 프로토콜이 아니라는 것이다. HTTP 통신하는 소켓 부분을 <code>SSL(Secure Socket Layer)</code> or <code>TLS(Transport Layer Security)</code>라는 프로토콜로 대체하는 것 뿐이다. HTTP 는 원래 TCP 와 직접 통신했지만, HTTPS 에서 HTTP 는 SSL 과 통신하고 <strong>SSL 이 TCP 와 통신</strong> 하게 된다. SSL 을 사용한 HTTPS 는 암호화와 증명서, 안전성 보호를 이용할 수 있게 된다.</p>
<p>HTTPS 의 SSL 에서는 공통키 암호화 방식과 공개키 암호화 방식을 혼합한 하이브리드 암호 시스템을 사용한다. 공통키를 공개키 암호화 방식으로 교환한 다음에 다음부터의 통신은 공통키 암호를 사용하는 방식이다.</p>
<h3 id="모든-웹-페이지에서-https를-사용해도-될까"><strong>모든 웹 페이지에서 HTTPS를 사용해도 될까?</strong></h3>
<p>평문 통신에 비해서 암호화 통신은 CPU나 메모리 등 리소스를 더 많이 요구한다. 통신할 때마다 암호화를 하면 추가적인 리소스를 소비하기 때문에 서버 한 대당 처리할 수 있는 리퀘스트의 수가 상대적으로 줄어들게 된다.</p>
<p>하지만 최근에는 하드웨어의 발달로 인해 HTTPS를 사용하더라도 속도 저하가 거의 일어나지 않으며, 새로운 표준인 HTTP 2.0을 함께 이용한다면 오히려 HTTPS가 HTTP보다 더 빠르게 동작한다. 따라서 웹은 과거의 민감한 정보를 다룰 때만 HTTP에 의한 암호화 통신을 사용하는 방식에서 현재 모든 웹 페이지에서 HTTPS를 적용하는 방향으로 바뀌어가고 있다.</p>
<h2 id="웹-통신의-큰-흐름"><strong>웹 통신의 큰 흐름</strong></h2>
<p><em>우리가 Chrome 을 실행시켜 주소창에 특정 URL 값을 입력시키면 어떤 일이 일어나는가?</em></p>
<h3 id="in-브라우저"><strong>in 브라우저</strong></h3>
<ol>
<li>url 에 입력된 값을 브라우저 내부에서 결정된 규칙에 따라 그 의미를 조사한다.</li>
<li>조사된 의미에 따라 HTTP Request 메시지를 만든다.</li>
<li>만들어진 메시지를 웹 서버로 전송한다.</li>
</ol>
<p>이 때 만들어진 메시지 전송은 브라우저가 직접하는 것이 아니다. 브라우저는 메시지를 네트워크에 송출하는 기능이 없으므로 OS에 의뢰하여 메시지를 전달한다. 우리가 택배를 보낼 때 직접 보내는게 아니라, 이미 서비스가 이루어지고 있는 택배 시스템(택배 회사)을 이용하여 보내는 것과 같은 이치이다. 단, OS에 송신을 의뢰할 때는 도메인명이 아니라 ip주소로 메시지를 받을 상대를 지정해야 하는데, 이 과정에서 DNS서버를 조회해야 한다.</p>
<h3 id="in-프로토콜-스택-lan-어댑터"><strong>in 프로토콜 스택, LAN 어댑터</strong></h3>
<ol>
<li>프로토콜 스택(운영체제에 내장된 네트워크 제어용 소프트웨어)이 브라우저로부터 메시지를 받는다.</li>
<li>브라우저로부터 받은 메시지를 패킷 속에 저장한다.</li>
<li>그리고 수신처 주소 등의 제어정보를 덧붙인다.</li>
<li>그런 다음, 패킷을 LAN 어댑터에 넘긴다.</li>
<li>LAN 어댑터는 다음 Hop의 MAC주소를 붙인 프레임을 전기신호로 변환시킨다.</li>
<li>신호를 LAN 케이블에 송출시킨다.</li>
</ol>
<p>프로토콜 스택은 통신 중 오류가 발생했을 때, 이 제어 정보를 사용하여 고쳐 보내거나, 각종 상황을 조절하는 등 다양한 역할을 하게 된다. 네트워크 세계에서는 비서가 있어서 우리가 비서에게 물건만 건네주면, 받는 사람의 주소와 각종 유의사항을 써준다! 여기서는 프로토콜 스택이 비서의 역할을 한다고 볼 수 있다.</p>
<h3 id="in-허브-스위치-라우터"><strong>in 허브, 스위치, 라우터</strong></h3>
<ol>
<li>LAN 어댑터가 송신한 프레임은 스위칭 허브를 경유하여 인터넷 접속용 라우터에 도착한다.</li>
<li>라우터는 패킷을 프로바이더(통신사)에게 전달한다.</li>
<li>인터넷으로 들어가게 된다.</li>
</ol>
<h3 id="in-액세스-회선-프로바이더"><strong>in 액세스 회선, 프로바이더</strong></h3>
<ol>
<li>패킷은 인터넷의 입구에 있는 액세스 회선(통신 회선)에 의해 POP(Point Of Presence, 통신사용 라우터)까지 운반된다.</li>
<li>POP 를 거쳐 인터넷의 핵심부로 들어가게 된다.</li>
<li>수 많은 고속 라우터들 사이로 패킷이 목적지를 향해 흘러가게 된다.</li>
</ol>
<h3 id="in-방화벽-캐시서버"><strong>in 방화벽, 캐시서버</strong></h3>
<ol>
<li>패킷은 인터넷 핵심부를 통과하여 웹 서버측의 LAN 에 도착한다.</li>
<li>기다리고 있던 방화벽이 도착한 패킷을 검사한다.</li>
<li>패킷이 웹 서버까지 가야하는지 가지 않아도 되는지를 판단하는 캐시서버가 존재한다.</li>
</ol>
<p>굳이 서버까지 가지 않아도 되는 경우를 골라낸다. 액세스한 페이지의 데이터가 캐시서버에 있으면 웹 서버에 의뢰하지 않고 바로 그 값을 읽을 수 있다. 페이지의 데이터 중에 다시 이용할 수 있는 것이 있으면 캐시 서버에 저장된다.</p>
<h3 id="in-웹-서버"><strong>in 웹 서버</strong></h3>
<ol>
<li>패킷이 물리적인 웹 서버에 도착하면 웹 서버의 프로토콜 스택은 패킷을 추출하여 메시지를 복원하고 웹 서버 애플리케이션에 넘긴다.</li>
<li>메시지를 받은 웹 서버 애플리케이션은 요청 메시지에 따른 데이터를 응답 메시지에 넣어 클라이언트로 회송한다.</li>
<li>왔던 방식대로 응답 메시지가 클라이언트에게 전달된다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로세스]]></title>
            <link>https://velog.io/@blanky_munn/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4</link>
            <guid>https://velog.io/@blanky_munn/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4</guid>
            <pubDate>Sun, 10 Apr 2022 10:33:18 GMT</pubDate>
            <description><![CDATA[<h2 id="프로세스와-스레드의-차이">프로세스와 스레드의 차이</h2>
<p><strong>프로세스</strong></p>
<p>프로세스는 실행 중인 프로그램으로 디스크로부터 메모리에 적재되어 CPU의 할당을 받을 수 있는 것을 말한다.</p>
<p><strong>프로세스 제어블록</strong></p>
<p>PCB는 특정 프로세스에 대한 중요성을 저장 하고 있는 운영 체제의 자료구조이다. 운영체제는 프로세스를 관리하기 위해 프로세스의 생성과 동시에 고유한 PCB를 생성한다. </p>
<p><em>PCB 에 저장되는 정보</em></p>
<ul>
<li>프로세스 식별자(Process ID, PID) : 프로세스 식별번호</li>
<li>프로세스 상태 : new, ready, running, waiting, terminated 등의 상태를 저장</li>
<li>프로그램 카운터 : 프로세스가 다음에 실행할 명령어의 주소</li>
<li>CPU 레지스터</li>
<li>CPU 스케쥴링 정보 : 프로세스의 우선순위, 스케줄 큐에 대한 포인터 등</li>
<li>메모리 관리 정보 : 페이지 테이블 또는 세그먼트 테이블 등과 같은 정보를 포함</li>
<li>입출력 상태 정보 : 프로세스에 할당된 입출력 장치들과 열린 파일 목록</li>
<li>어카운팅 정보 : 사용된 CPU 시간, 시간제한, 계정번호 등</li>
</ul>
<h3 id="스레드thread"><strong>스레드(Thread)</strong></h3>
<p>스레드는 프로세스의 실행 단위라고 할 수 있다. 한 프로세스 내에서 동작되는 여러 실행 흐름으로 프로세스 내의 주소 공간이나 자원을 공유할 수 있다. 스레드는 스레드 ID, 프로그램 카운터, 레지스터 집합, 그리고 스택으로 구성된다. 같은 프로세스에 속한 다른 스레드와 코드, 데이터 섹션, 그리고 열린 파일이나 신호와 같은 운영체제 자원들을 공유한다. 하나의 프로세스를 다수의 실행 단위로 구분하여 자원을 공유하고 자원의 생성과 관리의 중복성을 최소화하여 수행 능력을 향상시키는 것을 멀티스레딩이라고 한다. 이 경우 각각의 스레드는 독립적인 작업을 수행해야 하기 때문에 각자의 스택과 PC 레지스터 값을 갖고 있다</p>
<p><strong>멀티스레드 vs 멀티 프로세스</strong></p>
<p>멀티스레드는 멀티프로세스 보다 적은 메모리 공간을 차지하고 문맥전환이 빠르다는 장점이 있지만 오류로 인해 하나의 스레드가 종료되면 전체 스레드가 종료될수도 있지만, 멀티 프로세스는 다른 프로세스에 영향을 끼치지않는다. 하지만 많은 메모리와 CPU시간을 차지한다.그래서 적합한 방식을 선택해야한다.</p>
<h2 id="스케줄러"><strong>스케줄러</strong></h2>
<p><em>프로세스를 스케줄링하기 위한 Queue 에는 세 가지 종류가 존재한다.</em></p>
<ul>
<li>Job Queue : 현재 시스템 내에 있는 모든 프로세스의 집합</li>
<li>Ready Queue : 현재 메모리 내에 있으면서 CPU 를 잡아서 실행되기를 기다리는 프로세스의 집합</li>
<li>Device Queue : Device I/O 작업을 대기하고 있는 프로세스의 집합</li>
</ul>
<p>각각의 Queue 에 프로세스들을 넣고 빼주는 스케줄러에도 크게 <strong>세 가지 종류가</strong> 존재한다.</p>
<h3 id="장기스케줄러long-term-scheduler-or-job-scheduler"><strong>장기스케줄러(Long-term scheduler or job scheduler)</strong></h3>
<p>메모리는 한정되어 있는데 많은 프로세스들이 한꺼번에 메모리에 올라올 경우, 대용량 메모리(일반적으로 디스크)에 임시로 저장된다. 이 pool 에 저장되어 있는 프로세스 중 어떤 프로세스에 메모리를 할당하여 ready queue 로 보낼지 결정하는 역할을 한다.</p>
<ul>
<li>메모리와 디스크 사이의 스케줄링을 담당.</li>
<li>프로세스에 memory(및 각종 리소스)를 할당(admit)</li>
<li>degree of Multiprogramming 제어(실행중인 프로세스의 수 제어)</li>
<li>프로세스의 상태new -&gt; ready(in memory)</li>
</ul>
<p><em>cf) 메모리에 프로그램이 너무 많이 올라가도, 너무 적게 올라가도 성능이 좋지 않은 것이다. 참고로 time sharing system 에서는 장기 스케줄러가 없다. 그냥 곧바로 메모리에 올라가 ready 상태가 된다.</em></p>
<h3 id="단기스케줄러short-term-scheduler-or-cpu-scheduler"><strong>단기스케줄러(Short-term scheduler or CPU scheduler)</strong></h3>
<ul>
<li>CPU 와 메모리 사이의 스케줄링을 담당.</li>
<li>Ready Queue 에 존재하는 프로세스 중 어떤 프로세스를 running 시킬지 결정.</li>
<li>프로세스에 CPU 를 할당(scheduler dispatch)</li>
<li>프로세스의 상태ready -&gt; running -&gt; waiting -&gt; ready</li>
</ul>
<h3 id="중기스케줄러medium-term-scheduler-or-swapper"><strong>중기스케줄러(Medium-term scheduler or Swapper)</strong></h3>
<ul>
<li>여유 공간 마련을 위해 프로세스를 통째로 메모리에서 디스크로 쫓아냄 (swapping)</li>
<li>프로세스에게서 memory 를 deallocate</li>
<li>degree of Multiprogramming 제어</li>
<li>현 시스템에서 메모리에 너무 많은 프로그램이 동시에 올라가는 것을 조절하는 스케줄러.</li>
<li>프로세스의 상태ready -&gt; suspended</li>
</ul>
<h3 id="process-state---suspended"><strong>Process state - suspended</strong></h3>
<p>Suspended(stopped) : 외부적인 이유로 프로세스의 수행이 정지된 상태로 메모리에서 내려간 상태를 의미한다. 프로세스 전부 디스크로 swap out 된다. blocked 상태는 다른 I/O 작업을 기다리는 상태이기 때문에 스스로 ready state 로 돌아갈 수 있지만 이 상태는 외부적인 이유로 suspending 되었기 때문에 스스로 돌아갈 수 없다.</p>
<p><a href="https://github.com/JaeYeopHan/for_beginner">뒤로</a>/<a href="https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/master/OS#part-1-4-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C">위로</a></p>
<hr>
<h2 id="cpu-스케줄러"><strong>CPU 스케줄러</strong></h2>
<p><em>스케줄링 대상은 Ready Queue 에 있는 프로세스들이다.</em></p>
<h3 id="fcfsfirst-come-first-served"><strong>FCFS(First Come First Served)</strong></h3>
<h3 id="특징"><strong>특징</strong></h3>
<ul>
<li>먼저 온 고객을 먼저 서비스해주는 방식, 즉 먼저 온 순서대로 처리.</li>
<li>비선점형(Non-Preemptive) 스케줄링일단 CPU 를 잡으면 CPU burst 가 완료될 때까지 CPU 를 반환하지 않는다. 할당되었던 CPU 가 반환될 때만 스케줄링이 이루어진다.</li>
</ul>
<h3 id="문제점"><strong>문제점</strong></h3>
<ul>
<li>convoy effect소요시간이 긴 프로세스가 먼저 도달하여 효율성을 낮추는 현상이 발생한다.</li>
</ul>
<h3 id="sjfshortest---job---first"><strong>SJF(Shortest - Job - First)</strong></h3>
<h3 id="특징-1"><strong>특징</strong></h3>
<ul>
<li>다른 프로세스가 먼저 도착했어도 CPU burst time 이 짧은 프로세스에게 선 할당</li>
<li>비선점형(Non-Preemptive) 스케줄링</li>
</ul>
<h3 id="문제점-1"><strong>문제점</strong></h3>
<ul>
<li>starvation효율성을 추구하는게 가장 중요하지만 특정 프로세스가 지나치게 차별받으면 안되는 것이다. 이 스케줄링은 극단적으로 CPU 사용이 짧은 job 을 선호한다. 그래서 사용 시간이 긴 프로세스는 거의 영원히 CPU 를 할당받을 수 없다.</li>
</ul>
<h3 id="srtfshortest-remaining-time-first"><strong>SRTF(Shortest Remaining Time First)</strong></h3>
<h3 id="특징-2"><strong>특징</strong></h3>
<ul>
<li>새로운 프로세스가 도착할 때마다 새로운 스케줄링이 이루어진다.</li>
<li>선점형 (Preemptive) 스케줄링현재 수행중인 프로세스의 남은 burst time 보다 더 짧은 CPU burst time 을 가지는 새로운 프로세스가 도착하면 CPU 를 뺏긴다.</li>
</ul>
<h3 id="문제점-2"><strong>문제점</strong></h3>
<ul>
<li>starvation</li>
<li>새로운 프로세스가 도달할 때마다 스케줄링을 다시하기 때문에 CPU burst time(CPU 사용시간)을 측정할 수가 없다.</li>
</ul>
<h3 id="priority-scheduling"><strong>Priority Scheduling</strong></h3>
<h3 id="특징-3"><strong>특징</strong></h3>
<ul>
<li>우선순위가 가장 높은 프로세스에게 CPU 를 할당하는 스케줄링이다. 우선순위란 정수로 표현하게 되고 작은 숫자가 우선순위가 높다.</li>
<li>선점형 스케줄링(Preemptive) 방식더 높은 우선순위의 프로세스가 도착하면 실행중인 프로세스를 멈추고 CPU 를 선점한다.</li>
<li>비선점형 스케줄링(Non-Preemptive) 방식더 높은 우선순위의 프로세스가 도착하면 Ready Queue 의 Head 에 넣는다.</li>
</ul>
<h3 id="문제점-3"><strong>문제점</strong></h3>
<ul>
<li>starvation</li>
<li>무기한 봉쇄(Indefinite blocking)실행 준비는 되어있으나 CPU 를 사용못하는 프로세스를 CPU 가 무기한 대기하는 상태</li>
</ul>
<h3 id="해결책"><strong>해결책</strong></h3>
<ul>
<li>aging아무리 우선순위가 낮은 프로세스라도 오래 기다리면 우선순위를 높여주자.</li>
</ul>
<h3 id="round-robin"><strong>Round Robin</strong></h3>
<h3 id="특징-4"><strong>특징</strong></h3>
<ul>
<li>현대적인 CPU 스케줄링</li>
<li>각 프로세스는 동일한 크기의 할당 시간(time quantum)을 갖게 된다.</li>
<li>할당 시간이 지나면 프로세스는 선점당하고 ready queue 의 제일 뒤에 가서 다시 줄을 선다.</li>
<li><code>RR</code>은 CPU 사용시간이 랜덤한 프로세스들이 섞여있을 경우에 효율적</li>
<li><code>RR</code>이 가능한 이유는 프로세스의 context 를 save 할 수 있기 때문이다.</li>
</ul>
<h3 id="장점"><strong>장점</strong></h3>
<ul>
<li><code>Response time</code>이 빨라진다.n 개의 프로세스가 ready queue 에 있고 할당시간이 q(time quantum)인 경우 각 프로세스는 q 단위로 CPU 시간의 1/n 을 얻는다. 즉, 어떤 프로세스도 (n-1)q time unit 이상 기다리지 않는다.</li>
<li>프로세스가 기다리는 시간이 CPU 를 사용할 만큼 증가한다.공정한 스케줄링이라고 할 수 있다.</li>
</ul>
<h3 id="주의할-점"><strong>주의할 점</strong></h3>
<p>설정한 <code>time quantum</code>이 너무 커지면 <code>FCFS</code>와 같아진다. 또 너무 작아지면 스케줄링 알고리즘의 목적에는 이상적이지만 잦은 context switch 로 overhead 가 발생한다. 그렇기 때문에 적당한 <code>time quantuy</code></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[기본 지식]]></title>
            <link>https://velog.io/@blanky_munn/%EA%B8%B0%EB%B3%B8-%EC%A7%80%EC%8B%9D</link>
            <guid>https://velog.io/@blanky_munn/%EA%B8%B0%EB%B3%B8-%EC%A7%80%EC%8B%9D</guid>
            <pubDate>Sun, 10 Apr 2022 10:32:09 GMT</pubDate>
            <description><![CDATA[<h2 id="객체-지향-프로그래밍">객체 지향 프로그래밍</h2>
<p>객체 지향 프로그래밍 패러다임을 살펴보면, 중심은 컴퓨터에 있었다. 컴퓨터가 사고하는데 프로그래밈을 하는것이다. 하지만 객체 지향 프로그래밍이란 인간 중심적 프로그래밍 패러다임이라고 볼수 있다. 즉, 현실 세계에 존재하는 것을 프로그래밍으로 옮겨와 프로그래밍을 하는것을 말한다.</p>
<p>현실 세계의 사물들을 객체라고 보고 그 객체로 부터 개발하고자 하는 애플리케이션에 필요한 특징들을 뽑아와 프로그래밍 하는 것이다. 이것을 추상화 라고 한다.</p>
<p>객체 지향 프로그래밍으로 코드를 작성하면 코드에 대한 재사용성이높다. 자주 사용되는 로직을 라이브러리로 만들어두면 계속해서 사용할 수 있으며, 또한 예외 상황에 맞게 라이브러리를 만들어 두면 개발자가 실수를 하더라도 컴파일중 에러를 잡아낼수 있어서 버그의 발생률도 줄어든다.</p>
<p>또한 내부적으로 어떻게 동작하는지 몰라도 개발자는 라이브러리가 제공하는 기능들을 사용할 수 있기 때문에 생산성이 높아지게 된다. 객체 단위로 코드가 나눠져 작성되기 때문에 디버깅이 쉽고 유지보수에 용이하다. 또한 데이터 모델링을 할 때 객체와 매핑하는 것이 수월하기 때문에 요구사항을 보다 명확하게 파악하여 프로그래밍 할 수 있다.</p>
<p>객체 간의 정보 교환이 모두 메시지 교환을 통해 일어나므로 실행 시스템에 많은 overhead 가 발생하게 된다. 하지만 이것은 하드웨어의 발전으로 많은 부분 보완되었다. 객체 지향 프로그래밍의 치명적인 단점은 함수형 프로그래밍 패러다임의 등장 배경을 통해서 알 수 있다. 바로 객체가 상태를 갖는다는 것이다. 변수가 존재하고 이 변수를 통해 객체가 예측할 수 없는 상태를 갖게 되어 애플리케이션 내부에서 버그를 발생시킨다는 것이다. 이러한 이유로 함수형 패러다임이 주목받고 있다.</p>
<h3 id="객체-지향적-설계-원칙"><strong>객체 지향적 설계 원칙</strong></h3>
<ol>
<li>SRP(Single Responsibility Principle) : 단일 책임 원칙클래스는 단 하나의 책임을 가져야 하며 클래스를 변경하는 이유는 단 하나의 이유이어야 한다.</li>
<li>OCP(Open-Closed Principle) : 개방-폐쇄 원칙확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다.</li>
<li>LSP(Liskov Substitution Principle) : 리스코프 치환 원칙상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.</li>
<li>ISP(Interface Segregation Principle) : 인터페이스 분리 원칙인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다.</li>
<li>DIP(Dependency Inversion Principle) : 의존 역전 원칙고수준 모듈은 저수준 모듈의 구현에 의존해서는 안된다.</li>
</ol>
<h3 id="restful-api"><strong><strong>RESTful API</strong></strong></h3>
<p><code>REST</code>란, REpresentational State Transfer 의 약자이다. 여기에 ~ful 이라는 형용사형 어미를 붙여 ~한 API 라는 표현으로 사용된다. 즉, REST 의 기본 원칙을 성실히 지킨 서비스 디자인은 &#39;RESTful&#39;하다라고 표현할 수 있다.</p>
<p><code>REST</code>가 디자인 패턴이다, 아키텍처다 많은 이야기가 존재하는데, 하나의 아키텍처로 볼 수 있다. 좀 더 정확한 표현으로 말하자면, REST 는 <code>Resource Oriented Architecture</code> 이다. API 설계의 중심에 자원(Resource)이 있고 HTTP Method 를 통해 자원을 처리하도록 설계하는 것이다.</p>
<h3 id="rest-6-가지-원칙"><strong>REST 6 가지 원칙</strong></h3>
<ul>
<li>Uniform Interface</li>
<li>Stateless</li>
<li>Caching</li>
<li>Client-Server</li>
<li>Hierarchical system</li>
<li>Code on demand<em>cf) 보다 자세한 내용에 대해서는 Reference 를 참고해주세요.</em></li>
</ul>
<h3 id="restful-하게-api-를-디자인-한다는-것은-무엇을-의미하는가요약"><strong>RESTful 하게 API 를 디자인 한다는 것은 무엇을 의미하는가.(요약)</strong></h3>
<ol>
<li><strong>리소스</strong> 와 <strong>행위</strong> 를 명시적이고 직관적으로 분리한다.</li>
</ol>
<ul>
<li>리소스는 <code>URl</code>로 표현되는데 리소스가 가리키는 것은 <code>명사</code>로 표현되어야 한다.</li>
<li>행위는 <code>HTTP Method</code>로 표현하고, <code>GET(조회)</code>, <code>POST(생성)</code>, <code>PUT(기존 entity 전체 수정)</code>, <code>PATCH(기존 entity 일부 수정)</code>, <code>DELETE(삭제)</code>을 분명한 목적으로 사용한다.</li>
</ul>
<ol>
<li>Message 는 Header 와 Body 를 명확하게 분리해서 사용한다.</li>
</ol>
<ul>
<li>Entity 에 대한 내용은 body 에 담는다.</li>
<li>애플리케이션 서버가 행동할 판단의 근거가 되는 컨트롤 정보인 API 버전 정보, 응답받고자 하는 MIME 타입 등은 header 에 담는다.</li>
<li>header 와 body 는 http header 와 http body 로 나눌 수도 있고, http body 에 들어가는 json 구조로 분리할 수도 있다.</li>
</ul>
<ol>
<li>API 버전을 관리한다.</li>
</ol>
<ul>
<li>환경은 항상 변하기 때문에 API 의 signature 가 변경될 수도 있음에 유의하자.</li>
<li>특정 API 를 변경할 때는 반드시 하위호환성을 보장해야 한다.</li>
</ul>
<ol>
<li>서버와 클라이언트가 같은 방식을 사용해서 요청하도록 한다.</li>
</ol>
<ul>
<li>브라우저는 form-data 형식의 submit 으로 보내고 서버에서는 json 형태로 보내는 식의 분리보다는 json 으로 보내든, 둘 다 form-data 형식으로 보내든 하나로 통일한다.</li>
<li>다른 말로 표현하자면 URI 가 플랫폼 중립적이어야 한다.</li>
</ul>
<h3 id="장점">장점</h3>
<ol>
<li>Open API 를 제공하기 쉽다</li>
<li>멀티플랫폼 지원 및 연동이 용이하다.</li>
<li>원하는 타입으로 데이터를 주고 받을 수 있다.</li>
<li>기존 웹 인프라(HTTP)를 그대로 사용할 수 있다.</li>
</ol>
<h3 id="단점">단점</h3>
<ol>
<li>사용할 수 있는 메소드가 4 가지 밖에 없다.</li>
<li>분산환경에는 부적합하다.</li>
<li>HTTP 통신 모델에 대해서만 지원한다.</li>
</ol>
<p>출처 : <a href="https://github.com/JaeYeopHan/Interview_Question_for_Beginner">https://github.com/JaeYeopHan/Interview_Question_for_Beginner</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ARSession]]></title>
            <link>https://velog.io/@blanky_munn/ARSession</link>
            <guid>https://velog.io/@blanky_munn/ARSession</guid>
            <pubDate>Sun, 10 Apr 2022 10:30:05 GMT</pubDate>
            <description><![CDATA[<p>ARSession은 애플 공식 문서를 찾아보았다. 하지만 정확한 개념을 이해하지 못한거 같아 인터넷에 검색하며 찾으니 좀 이해가 되는 기분이다.</p>
<h3 id="arsession">ARSession</h3>
<ul>
<li>AR경험을 제어하는데 사용하는 메인 Object</li>
<li>ARKit이 수행하는 프로세스를 조정하여 증강 현실 경험을 생성
(데이터 읽기, 내장 카메라 제어, 카메라 이미지 분석 등등)</li>
</ul>
<p>이러한 여러가지 데이터를 합성하여 휴대폰이 있는 실제 공간과 AR Object를 모델링하는 가상 공간 간의 대응 관계 설정을 한다.</p>
<p>-&gt; 모든 AR 기능을 사용하려면 ARSession이 필요하다. 
AR을 이용하면 대부분 카메라에 표시되는 물체를 분석하는데, 이러한 분석을 ARSession에서 처리하기 때문에 필요하다고 이해하였다.</p>
<h3 id="arsession-lifecycle">ARSession LifeCycle</h3>
<p>ARSession 생명 주기도 공식문서에 있어 궁금해서 공부했다.</p>
<p>World-Tracking AR Session은 시각적 관성 주행 거리 측정 이라는 기술을 사용하는데, 이 기술은 모션 센서 데이터를 카메라 이미지 분석과 결합하여 실제 공간에서 장치의 위치와 방향을 추적한다. 라고 적혀있다.</p>
<p>결론은 모션 센서와 카메라 이미지 분석을 이용해 사용자 기기의 위치와 방향을 추적한다는 말이다.</p>
<h4 id="lifecycle은-크게-3가지로-분류된다">LifeCycle은 크게 3가지로 분류된다.</h4>
<ul>
<li>Not available (이용 불가)</li>
<li>Limited(Initializing) - 초기화중</li>
<li>Normal (이용 가능)</li>
</ul>
<p>새로운 세션을 생성하면 Not available 상태 인데, 이 상태는 장치의 포즈(위치와 방향)을 추적하기에 정보가 부족한 상태.</p>
<p>몇 프레임 후 Limited 상태가 되는데, 위치와 방향을 추적하지만 정확성은 조금 떨어지는 단계이다. 이 상태의 경우 ARKit을 사용하는 기능을 사용할 수 없다.</p>
<p>Limited 상태 이후는 Normal 상태로 ARKit의 모든 기능을 사용할 수 있게된다.</p>
<p>ARKit은 ARSession없이 장치의 포즈를 추적할 수 없다. 만약 세션이 중단되면 relocalization을 통해 복구를 할 수 있다. relocalization이 성공려면 장치를 중단 되었을때 있던 위치로 돌아가야한다. 돌아가지않으면 세션은 무기한 중단 상태가 된다.</p>
<p>말이 조금 어렵지만 세션이 도중에 중단되면 relocalization을 통해 복구를 할 수 있는데, 이 과정에서 중단된 위치로 다시 돌아가야한다는 것으로 이해했다.그러면 이 세션이 중단될 때 그 중단된 위치를 저장해야하는데, 이 기능은 iOS 12.0 이상 부터 지원한다. 
그렇지만 이 모든 정보를 저장하는게 아니라, ARSession에 저장할만한 가치가 있는것들만 저장을한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ARFaceAnchor]]></title>
            <link>https://velog.io/@blanky_munn/ARFaceAnchor</link>
            <guid>https://velog.io/@blanky_munn/ARFaceAnchor</guid>
            <pubDate>Sun, 10 Apr 2022 09:07:14 GMT</pubDate>
            <description><![CDATA[<p>FaceTraking 활성화
<img src="https://velog.velcdn.com/images/blanky_munn/post/9165ac32-d62c-4c5b-a968-4ad244e277b1/image.png" alt="">configuration 생성후 sceneView에 add</p>
<p>FaceTraking이 활성화 되면 ARKit은 자동으로 ARFaceAnchor을 ARsession에 add한다.</p>
<blockquote>
<p>ARFaceAnchor은 ARAnchor의 서브클래스로, 사용자의 얼굴위치에 관련된 정보를 포함하고, SceneKit를 기반으한 AR에서는 3D Content를 FaceAnchor에 추가할 수 있다 !</p>
</blockquote>
<p>다른 글 들을 찾아보니 3D Content를 SceneKit node에 Add하고, SceneKit node를 Anchor에 붙인다고 설명되어있다.</p>
<p>여기서 ! <strong>ARAnchor</strong>도 뭔지 잘 몰라서 공식 문서를 찾아보았다.(AR분야는 처음 공부해본다..ㅎㅎ)</p>
<blockquote>
<p>ARAnchor : 카메라를 기준으로 실제 또는 가상 개체의 정적 위치와 방향을 추적하는 앵커를 만들고 add메서드를 통해 ARSession에 추가한다.</p>
</blockquote>
<p>무슨 말 인지 한 번에 이해가 되지않아 Apple 공식 문서를 읽어보았는데, 얼굴을 감지하면 ARFaceAnchor 객체를 앵커 목록에 자동으로 추가하고, 추가된 객체를 ARFaceTrakingConfiguration으로 얼굴을 추적하는것이다.
추적하는 좌표계는 오른손 잡이 기준이며, <strong>x축은 오른쪽, y축은 위쪽, z쭉은 전방을 향한다</strong>. (Unity에서 사용하는 SCNVector3와 비슷?한것같다)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Swift ARKit]]></title>
            <link>https://velog.io/@blanky_munn/Swift-ARKit</link>
            <guid>https://velog.io/@blanky_munn/Swift-ARKit</guid>
            <pubDate>Sun, 10 Apr 2022 08:09:16 GMT</pubDate>
            <description><![CDATA[<h1 id="arkit">ARKit</h1>
<blockquote>
<p>AR : Argumented Reality = <strong>증강현실</strong></p>
</blockquote>
<p>우선 ARKit을 사용하려면 iOS 11.0 이상과 A9 이상의 프로세서가 탑재된 iOS 기기가 필요하다.</p>
<p>ARKit과 FaceTraking(얼굴 추적)을 지원하는지 확인하는 방법</p>
<pre><code>ARKit : .isSupportedARConfiguration
FaceTraking :ARFaceTrackingConfiguration.isSupported
</code></pre><p>그리고 ARKit을 사용하려면 카메라 사용권한이 필요하기 때문에 Info.plist에 NSCameraUsageDescription 키가 포함되어야한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Implicitly Unwrapped Optional ]]></title>
            <link>https://velog.io/@blanky_munn/Implicitly-Unwrapped-Optional</link>
            <guid>https://velog.io/@blanky_munn/Implicitly-Unwrapped-Optional</guid>
            <pubDate>Sat, 09 Apr 2022 09:25:24 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>IUO : Implicitly Unwrapped Optional (묵시적 추출)</p>
</blockquote>
<pre><code>let name : String!</code></pre><p>묵시적 추출은 위에 코드 처러 사용된다.
변수나 상수를 선언할 때 Type뒤에 ? 대신 !를 붙인다.
이렇게 선언한 변수도 Optional Type 이며, Optional을 선언하는 또 다른 방식 중 하나이다. 변수선언을 IUO로 하게 되면 Non Optional Type으로 처리되어야할 때 값을 자동으로 추출 하게 된다. </p>
<pre><code>var num : Int! = 4
var num2 : Int = num</code></pre><p>기존에 사용하던 옵셔널 선언대로 하면 오류가 발생하지만 IUO를 이용하면 
<strong>Optional Type을 Non Optional Type에 대입할 때 별도의 추출 과정 없이 대입이 가능한 것이다.</strong></p>
<p>IUO또한 ? 대신 !를 사용한 Optional Type 이기 때문에, 강제 추출이다.</p>
<p>아직 까진 제대로 사용해보진 못했지만, 이렇게 선언하는 이유는 프로퍼티 지연 초기화 떄문에 사용한다고 한다. </p>
<p>Main.StoryBoard에서 아이템을 끌어오면 IBOutlet뒤에 !를 붙은것을 자주 보았다. 이게 IUO를 사용한 것? 이라고 하지만, 더 공부를 해보아야 알 수 있을것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Forced Unwrapping]]></title>
            <link>https://velog.io/@blanky_munn/Forced-Unwrapping</link>
            <guid>https://velog.io/@blanky_munn/Forced-Unwrapping</guid>
            <pubDate>Thu, 07 Apr 2022 16:27:21 GMT</pubDate>
            <description><![CDATA[<p>첫 글로 Optinal에 대해 찾아보며 공부한 것을 올렷는데 
이렇게 선언한 Optinal로 선언된 값은 일반 자료형이 아닌 Optinal 자료형이다.</p>
<pre><code>let name:String? = nil
print(type(of:name))</code></pre><p>이렇게 선언된 변수의 Type을 확인해보면 </p>
<pre><code>Optional&lt;String&gt;</code></pre><p>그냥 String 값이 아니라 Optinal이 앞에 붙은걸 알 수 있다.
이 자료형은 일반 자료형이 아니기 때문에 사용하려면 Optinal을 벗겨내야한다. </p>
<blockquote>
<p>Optinal을 벗겨내는 작업을 <strong>Optinal Unwrapping</strong> 이라고 하며,이 작업을 하면 NonOptinalType으로 변경 가능하다.</p>
</blockquote>
<p>Optinal UnWrapping을 하기 위해선 절대 그 값이 nil값이면 안된다</p>
<h3 id="강제-추출-forced-unwrapping">강제 추출 (Forced Unwrapping)</h3>
<p>단어 그대로 강제로 추출하는 것이다.</p>
<p>위에서 Optinal UnWrapping을 하기 위해선 nil값이 아니면 안 된다고 했는데, 강제 추출은 nil이든 아니든 그냥 강제로 Optinal을 벗겨낸다.</p>
<pre><code>let name:String? = &quot;Blanky&quot;
print(name!)
</code></pre><p>이렇게 강제로 Optinal을 벗겨낼 수 있다.</p>
<p>그렇지만 어느 곳에서든 강제로 하는 방법은 좋지않다. 개발자가 이 값은 무조건 nil이 아니다 ! 라고 할 경우에 사용할 수 있겟지만 만약 이 값이 nil값일경우에는 Crash가 일어나서 앱이 종료되는 경우가 발생하게된다.</p>
<p>그리므로 우리는 이 값이 nil인지 아닌지 확인하고 사용하는 방법인 Optinal Binding을 사용할 수 있다.</p>
<h3 id="optinal-binding">Optinal Binding</h3>
<p>Udemy 강의를 들을때도 많이 보게되었던 문법이다.
이 방법도 Optinal을 벗겨내는 방법 중 하나이다.</p>
<pre><code>let num : Int? = 4
if let optional = num {
    print(optinal)
} else {
    print(num)
}</code></pre><p>if 문을 사용해서 값이 nil인지 아닌지 확인해서 안전하게 Optional을 벗겨낼수 있게 된다.</p>
<p>정말 Swift언어는 다른 언어와 다르게 매력이 있어 더 찾아보고 공부 하게 되는것 같다. 언어와 대화하는 기분이 드는...??</p>
<pre><code>let optionalNum : Int? = nil
guard let nonOptional = optionalNum else {
    return
}</code></pre><p>Udemy 강의 에서 if let 과 guard let 의 차이를 듣게 되었는데,
if문은 else 구문까지 실행되는 것을 고려해서 코드를 작성하게 되는데, guard let 구문은 <strong>else구문이 최대한 실행되지않게</strong> 코드를 작성한다.</p>
<p>저기 위의 코드에서 optinalNum이 존재하는지 안하는지 확인할때 자주 사용되는 것을 다른 코드에서 많이 보았다.</p>
<p>이렇게 두 가지 Optional Unwrapping 방법을 알게되었는데, if let 구문과 guard let 구문의 차이점은 위에서 설명했듯이 else구문의 실행을 고려하느냐, 아니냐의 차이인것같다 !</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Swift Optional]]></title>
            <link>https://velog.io/@blanky_munn/Swift-Optinal</link>
            <guid>https://velog.io/@blanky_munn/Swift-Optinal</guid>
            <pubDate>Thu, 07 Apr 2022 15:55:06 GMT</pubDate>
            <description><![CDATA[<p>Swift를 배우다 보면 변수를 선언하거나 타입 뒤에 ?가 붙어있는걸 볼 수 있다. </p>
<pre><code>let name:String?</code></pre><p>Optinal의 정의 : &#39;nil&#39;이라는 값을 가질 수 있으면 Optinal Type이고, 이 Optinal Type을 선언할 땐 타입 옆에 ?을 붙인다.</p>
<p>여기서 nil은 값이 없다는 것을 의미한다.
예를 들어 값에 접근할때 존재하지 않는 값에 접근을 하면 앱을 Crash 하는것이 아닌 nil을 return 한다.
결국 Swift는 안정성에 중점을 둔 언어라는것을 알게되었다!</p>
<p>nil값을 저장할 수 있는건 Optinal Type뿐이며, 이것을 구분짓기 위해서는 
Non Optinal Type과 Optinal Type을 알아야한다.</p>
<p>우리가 일반적으로 변수를 선언할때는 이렇게 선언한다.</p>
<pre><code>var name : String
name = &quot;Blanky&quot;</code></pre><p>이렇게 선언된 변수는 Non Optinal Typed이고, nil으로 값을 지정할 수는 없다.</p>
<p>하지만 이렇게 선언하면?</p>
<pre><code>var name : String?
name = nil</code></pre><p>String Type에 ?를 붙이면 Optinal Type이 되어 nil으로 값을 지정할 수 있게 된다.</p>
<p>이 방법을 통해 선언과 동시에 초기화 시킬수도 있다.</p>
<pre><code>let a : Int? = nil
let b = a</code></pre><p>nil의 자료형이 어떤것인지 궁금해 찾아보게되었는데, 말 그대로 값이 존재하지 않는것이고, 자료형을 유추할 수 없다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오픈 주소법]]></title>
            <link>https://velog.io/@blanky_munn/%EC%98%A4%ED%94%88-%EC%A3%BC%EC%86%8C%EB%B2%95</link>
            <guid>https://velog.io/@blanky_munn/%EC%98%A4%ED%94%88-%EC%A3%BC%EC%86%8C%EB%B2%95</guid>
            <pubDate>Fri, 20 Nov 2020 15:19:38 GMT</pubDate>
            <description><![CDATA[<p>해시 충돌이 발생했을 때 해결하는 또다른 방법으로는 오픈 주소법이 있다.
충돌이 발생했을 때 재해시를 수행하여 빈 버킷을 찾을때 까지 수행하는 방법 이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[해시법]]></title>
            <link>https://velog.io/@blanky_munn/%ED%95%B4%EC%8B%9C%EB%B2%95</link>
            <guid>https://velog.io/@blanky_munn/%ED%95%B4%EC%8B%9C%EB%B2%95</guid>
            <pubDate>Fri, 20 Nov 2020 14:21:51 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해시법 : 데이터를 저장할 위치 = 인덱스를 간단한 연산으로 구하는것</p>
</blockquote>
<p><strong>해시법</strong>은 원소의 검색뿐 아니라 추가,삭제도 효율적으로 수행할 수 있다.</p>
<p><strong>해시값</strong> : 키값을 원소의 갯수로 나눈 값</p>
<p><strong>해시 충돌</strong> : 18(키 값)을 원소갯수가 13인 배열에 저장하려고 할 때,여기서 해시값은  5이다.
그럼 이 키 값을 x[5]에 저장해야하는데, 배열x[5]에 이미 값이 있을때 해시 충돌이 일어나는 것이다.</p>
<p>이렇게 해시법에서 <strong>충돌</strong>이 발생하는경우에 2가지 방법으로 대처할 수 있다.</p>
<blockquote>
<p>체인법 : 해시값이 같은 원소를  연결리스트로 관리
오픈 주소법 : 빈 버킷을 찾을 때까지 해시를 반복</p>
</blockquote>
<h3 id="체인법">체인법</h3>
<p>체인법에서는 해시값이 같은 데이터를 연결리스트에 의해 체인 모양으로 연결한다. 배열의 각 버킷에 저장하는 것은 인덱스를 해시값으로하는 연결 리스트의 앞쪽 노드를 참조하는 것이다.</p>
<p>x[5] - 10 - 11 - 12</p>
<pre><code>#체인법으로 해시 함수 구현하기
from typing import Any, Type
import hashlib

class Node:
    def __init__(self, key:Any, value : Any, next : None) -&gt; None:
        #&quot;&quot;초기화&quot;&quot;
        self.key = key
        self.value = value
        self.next = next
class Chainhash:
    #&quot;&quot;체인법으로 해시 클래스 구현&quot;&quot;

    def __init__(self, capacity : int):
        #&quot;&quot;초기화&quot;&quot;
        self.capacity = capacity
        self.table = [None] * self.capacity

    def hash_value(self, key : Any):
        #&quot;&quot;해시값 구하기&quot;&quot;
        if instance(key, int):
            return key % self.capacity
        return(int(hashlib.sha256(str(key).encode()).hexdigest(), 16) % self.capacity)</code></pre><blockquote>
<p>capacity : 해시 테이블의 크기(table의 원소 수)
table : 해시테이블을 저장하는 list형 배열</p>
</blockquote>
<p>해시 테이블의 각 버킷은 맨 앞부터 table[0],table[1],table[2] ... table[capacity -1] 순으로 접근 가능하다.</p>
<h3 id="key가-int형인-경우">key가 int형인 경우</h3>
<p>key를 capacity로 나눈값을 해시로 하여 바로 사용가능하다.</p>
<h3 id="key가-int형이-아닌-경우">key가 int형이 아닌 경우</h3>
<p>key가 정수가 아닌겨우 그 값으로는 바로 나눌 수 없기 때문에 형 변환을 해야 해시값을 구할 수있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[self]]></title>
            <link>https://velog.io/@blanky_munn/self</link>
            <guid>https://velog.io/@blanky_munn/self</guid>
            <pubDate>Fri, 20 Nov 2020 13:55:03 GMT</pubDate>
            <description><![CDATA[<p>책으로 <strong>리스트</strong>를 공부하다가, 함수나 클래스를 정의하다가 의문이 들었다. 변수 입력자리에 self가 들어가는 이유가 뭔지 궁금해서 인터넷에 처보니 <strong>객체의 인스턴스 그 자체, 객체 자기 자신을 참조하는 매개변수</strong>라고 하는데 이해가 안되서 예시도 한번 보았다.</p>
<pre><code>class Foo:
    def a1():
        print(&quot;func1&quot;)
        #파이썬 메서드의 첫번째 인자로 항상 인스턴스가 전달되기 때문이다.
    def a2(self):
        print(&quot;func2&quot;)

f = Foo()
#하나의 인스턴스


print(Foo.a1())
#클래스형으로 호출했기때문에 별도의 인스턴스가 없어도 오류가 발생하지않는다.

print(Foo.a2(f))</code></pre><p>여기 위에서 볼수 있듯이 클래스를 하나의 인스턴스(f)로 만들어서 하면(a2) 처럼 바로 출력 가능하다. 하지만 a1은 인스턴스로 만들어서 출력하면 <strong>Traceback 오류</strong>가 발생하며 인스턴스 하나를 입력하라고 한다. 
두 가지 경우의 결과를 도출하니 a1에는 인스턴스 메서드가 존재하지않아, 출력하는데 오류가 생기지만, a2는 인스턴스 메서드가 존재하여 출력하는데에는 문제가 없다.</p>
<p>하지만 클래스를 하나의 인스턴스로 만들지 않고 클래스형으로 출력을 하면 a1은 출력이된다. a2의 경우에는 클래스형으로 출력하면 self 인스턴스 메서드를 필요로 하기때문에 오류가 발생한다. self 자리에 다른 인자를 넣어 출력하면 오류가 발생하지않는다.</p>
]]></description>
        </item>
    </channel>
</rss>