<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>co_mong.log</title>
        <link>https://velog.io/</link>
        <description>.</description>
        <lastBuildDate>Mon, 15 Nov 2021 12:50:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>co_mong.log</title>
            <url>https://images.velog.io/images/co_mong/profile/d6b303e2-3349-432f-9679-5c3852f06b32/메타몽2.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. co_mong.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/co_mong" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[면접] 컴퓨터구조]]></title>
            <link>https://velog.io/@co_mong/%EB%A9%B4%EC%A0%91-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@co_mong/%EB%A9%B4%EC%A0%91-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Mon, 15 Nov 2021 12:50:00 GMT</pubDate>
            <description><![CDATA[<h1 id="1-시스템-소프트웨어와-응용소프트웨어의-차이">1. 시스템 소프트웨어와 응용소프트웨어의 차이</h1>
<p><strong>시스템 소프트웨어</strong>란 <strong>운영체제</strong>,<strong>컴파일러</strong>와 같이 사용자들이 컴퓨터를 효율적으로 사용할수 있도록 도와주는 소프트웨어입니다.<br><strong>응용소프트웨어</strong>는 특정 목적을 달성하기 위해 만들어진 프로그램으로서 보통 일반 사용자들이 사용하는 프로그램을 의미합니다. 
<br/><br><br/><br><br/>  </p>
<h1 id="2-시스템-버스">2. 시스템 버스</h1>
<p><strong>시스템 버스</strong>란 하드웨어의 각각의 구성요소 간 데이터 통신을 위해 필요한 통로입니다.<br>용도에 따라 <strong>데이터 버스</strong>, <strong>주소버스</strong>, <strong>제어 버스</strong>로 나누어집니다.  </p>
<h4 id="📝데이터버스"><strong>📝데이터버스?</strong></h4>
<blockquote>
<p>데이터 버스란 말그대로 중앙처리장치와 기타 장치 사이에서 <strong>데이터를 전송하기 위한 버스</strong>이고 <strong>양방향</strong>입니다.  </p>
</blockquote>
<h4 id="📝주소버스"><strong>📝주소버스?</strong></h4>
<blockquote>
<p>주소버스는 데이터를 전송하기 위해 <strong>주소를 전달</strong>하는 버스이고 중앙처리장치에서 주기억장치,입출력장치로 향하는 단방향버스 입니다.  </p>
</blockquote>
<h4 id="📝데이터버스-1"><strong>📝데이터버스?</strong></h4>
<blockquote>
<p>제어버스는 중앙처리장치가 기억,입출력 장치에 <strong>제어신호를 전달</strong>하기 위해 필요한 버스입니다.<br>제어신호의 종류는 인터럽트 요청,기억장치 (읽기,쓰기), 버스사용 요청등이 있고 <strong>양방향</strong>버스입니다.<br><br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="3-명령어-처리-과정">3. 명령어 처리 과정</h1>
<p><strong>명령어 처리 과정</strong>은 <strong>fetch cycle(인출사이클)</strong> 과 <strong>execute cycle(실행사이클)</strong> 두개로 나누어집니다. </p>
<h4 id="📝인출-사이클"><strong>📝인출 사이클</strong></h4>
<blockquote>
<p><strong>인출사이클</strong>은 우선 <strong>PC</strong>에 저장된 주소를 <strong>MAR</strong>로 전달하고 해당 주소에서 명령어를 인출합니다.<br>그리고 해당 명령어를 <strong>명령어 버퍼 레지스터(MBR)</strong> 에 저장하고 PC값을 1증가시킵니다.<br>마지막으로 명령어를 <strong>명령어 레지스터(IR)</strong> 에 전달하면 인출 사이클이 완료됩니다.<br><img src="https://user-images.githubusercontent.com/49298852/141679596-38b5aac0-ac20-4651-b26a-db3d9daa136a.png" alt="image">  </p>
</blockquote>
<h4 id="📝실행-사이클"><strong>📝실행 사이클</strong></h4>
<blockquote>
<p><strong>실행 사이클</strong>의 경우 <strong>데이터를 인출</strong>하고 <strong>데이터 처리</strong> 그리고 처리된 <strong>데이터를 저장</strong>하는 과정을 거쳐서 완료됩니다. 
<br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="4-고정소수점-부동소수점">4. 고정소수점, 부동소수점</h1>
<blockquote>
<p><strong>고정소수점</strong>은 10진수를 2진수로 변경해서 그대로 사용하는 방식입니다. <strong>부호부</strong>,<strong>정수부</strong>,<strong>소수부</strong>로 나누어서 표현합니다.<br><img src="https://user-images.githubusercontent.com/49298852/141679802-8158834f-9034-429b-ba40-ffec7d6f9827.png" alt="image"></p>
</blockquote>
<blockquote>
<p>반면에 <strong>부동소수점</strong>은 2진수로 변경한 값을 그대로 사용하는 것이 아니라 <strong>정규화</strong>의 과정을 거친 다음 IEEE 부동소수점 표현방식인 <strong>부호부</strong>,<strong>지수부</strong>,<strong>가수부</strong>로 나누어서 표현합니다.<br><br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="5-risccisc">5. Risc,cisc</h1>
<p><strong>Risc</strong>는 단순한 명령어의 조합으로 이루어져 있어서 <strong>설계가 간단</strong>하고 <strong>비용이 줄어듭니다</strong>.  
따라서 복잡한 명령어를 <strong>소프트웨어적으로 구현</strong>해야 하므로 <strong>sw부담이 상대적으로 더 큽니다</strong>. 보통 안드로이드에서 사용됩니다.  </p>
<p><strong>Cisc</strong>는 복잡한 명령어들로 구성되어있습니다.<br>따라서 명령어 <strong>해석에 시간</strong>이 필요하고 <strong>회로도 상대적으로 복잡</strong>합니다. 주로 윈도우 환경에서 사용됩니다.<br><br/><br><br/><br><br/>  </p>
<h1 id="6-파이프라이닝">6. 파이프라이닝</h1>
<p>명령어를 처리할때 한번에 하나씩 순차적으로 처리하는 것이 아니라 명령어가 처리되는 도중에 다른 명령어의 처리를 시작하는 방식으로 <strong>동시에 여러개의 명령어를 처리</strong>해 <strong>처리량</strong>을 올리는 것입니다.<br>명령어의 처리시간을 단축시키는 것이지 동작속도를 증가시키는 것은 아닙니다.<br>이때 <strong>처리시간</strong>과 <strong>처리단계</strong>가 균등하지 않아서 <strong>‘해저드’</strong> 라는 오류가 발생할수 있습니다. </p>
<h4 id="📝해저드"><strong>📝해저드</strong></h4>
<blockquote>
<p><strong>해저드</strong>란 파이프라이닝에서 나타나는 문제점을 뜻합니다. 명령어의 처리시간과 처리단계가 균등하지 않아서 발생합니다.<br>해저드의 종류는 <strong>구조적 해저드</strong>, <strong>데이터 해저드</strong>, <strong>제어 해저드</strong>로 나뉩니다.  </p>
</blockquote>
<ul>
<li>구조적 해저드  <blockquote>
<p><strong>구조적 해저드</strong>는 하나의 자원을 여러개의 명령어에서 동시에 사용하려 할 때 발생합니다.<br>구조적 해저드를 해결하기 위해서는 데이터 처리와 명령어 처리를 동시에 할 수 있게 <strong>자원을 추가</strong>하거나 <strong>명령어 처리를 지연</strong>시켜서 해결합니다. </p>
</blockquote>
</li>
<li>데이터 해저드  <blockquote>
<p><strong>데이터 해저드</strong>는 <strong>이전 명령어의 결과값</strong>이 다음 명령어의 <strong>입력으로 사용</strong>될 경우 발생합니다.<br>이를 해결하기 위해 <strong>결과를 저장하기 전에 다음 명령어를 입력</strong>으로 넣어줘서 해결하거나 이전 명령어의 값이 저장되기 전까지 기다렸다가 진행하는 방식을 사용합니다. </p>
</blockquote>
</li>
<li>제어 해저드<blockquote>
<p><strong>제어 해저드</strong>는 분기처리시 다음 명령어가 어떤 것인지 <strong>특정하지 못하기</strong> 때문에 발생합니다.<br>이를 해결하기 위해 <strong>분기 처리에 영향을 받지 않는 명령어를 우선 수행</strong>하거나 <strong>명령어 분기를 예측</strong>하여 명령어를 수행하거나 <strong>지연</strong>시키는 방법으로 해결합니다.<br>👉분기를 예측하는 방법은 항상 하나의 결과를 예측하는(True or False) <strong>정적 예측</strong>이나 이전의 분기를 기록해두고 이를 바탕으로 예측하는 <strong>동적예측</strong> 2가지가 있습니다. </p>
<br/>  
<br/>  
<br/>  
</blockquote>
</li>
</ul>
<h1 id="7-캐시메모리">7. 캐시메모리</h1>
<p><strong>캐시메모리</strong>는 속도가 빠른 장치와 느린 장치 사이의 병목현상을 줄이기 위한 메모리입니다.<br>메인메모리와 cpu사이에서 자주 사용되는 데이터를 캐시에 저장해서 사용해서 <strong>속도를 향상</strong>시킵니다. 대신 <strong>용량이 작고</strong> <strong>비싸다</strong>는 단점이 있습니다.<br>그리고 <strong>캐시 적중률(hit)</strong> 을 높이기 위해 지역성의 원리를 사용합니다.  </p>
<h4 id="📝캐시-지역성"><strong>📝캐시 지역성</strong></h4>
<blockquote>
<p>캐시메모리 적중률을 상승시키기 위해 <strong>지역성 원리</strong>를 사용합니다. <strong>공간지역성</strong>,<strong>시간지역성</strong>이 있습니다.<br><strong>시간 지역성</strong>이란 한번 캐싱된 데이터는 다시 참조될 가능성이 높은 것을 의미하고 <strong>공간지역성</strong>은 참조된 데이터 주변의 데이터가 참조될 가능성이 높은것을 의미합니다. </p>
</blockquote>
<h4 id="📝캐시-미스"><strong>📝캐시 미스</strong></h4>
<blockquote>
<p><strong>캐시 미스</strong>란 가져오려는 데이터가 캐시메모리에 없는 경우를 의미합니다.<br>캐시 미스의 종류는 <strong>Cold miss</strong>, <strong>Conflict miss</strong>, <strong>Capacity miss</strong>가 있습니다. 
<strong>Cold miss</strong>는 해당 데이터를 처음 호출해서 없는 경우를 의미합니다.<br><strong>Conflict miss</strong>는 여러개의 명령어 주소가 같은 캐시메모리 주소에 저장되어있는 경우 발생합니다.<br><strong>Capacity miss</strong>는 캐시메모리의 공간이 부족해서 발생합니다.  </p>
</blockquote>
<h4 id="📝캐시-매핑"><strong>📝캐시 매핑</strong></h4>
<blockquote>
<p>캐시에 <strong>데이터 주소를 저장하는 방식</strong>을 의미합니다. 그리고 <strong>직접(direct)</strong>,<strong>연관(associate)</strong>,<strong>집합 연관(set associate)</strong> 맵핑이있습니다.  </p>
</blockquote>
<ul>
<li><p>직접사상  </p>
<blockquote>
<p><strong>직접 사상</strong>은 캐시와 메모리를 같은 크기로 나누어서 순서대로 매핑하는 것을 말합니다, 블럭단위로 저장하기 때문에 <strong>캐시의 공간활용을 제대로 할수 없다</strong>는 단점이있습니다.  </p>
</blockquote>
</li>
<li><p>연관사상  </p>
<blockquote>
<p><strong>연관 사상</strong>은 <strong>비어있는 캐시 메모리 공간이 있으면 저장</strong>하는 방식입니다. <strong>적중률이 높다</strong>는 장점이 있고 저장할때는 <strong>간단</strong>하다는 장점이 있습니다. 하지만 데이터를 규칙이 없어서 <strong>검색할때 시간이 오래</strong>걸립니다.  </p>
</blockquote>
</li>
<li><p>세트연관사상  </p>
<blockquote>
<p><strong>세트 연관 사상</strong>은 직접사상과 연관사상의 장점을 합친 사상방법입니다.<br>캐시메모리는 <strong>세트로 구분</strong>되고 <strong>세트내에 2개 이상의 슬롯</strong>을 가집니다.<br>만약 세트가 n개있고 세트당 슬롯이 1개라면 직접 연관사상입니다.  그리고 세트가 1개있고 세트당 슬롯이 n개라면 연관사상입니다.<br>따라서 세트번호로 먼저 탐색해서 탐색 수를 줄이고 무작위로 배치해서 직접사상의 단점을 보완하였습니다.  </p>
</blockquote>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접] 데이터베이스]]></title>
            <link>https://velog.io/@co_mong/%EB%A9%B4%EC%A0%91-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4</link>
            <guid>https://velog.io/@co_mong/%EB%A9%B4%EC%A0%91-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4</guid>
            <pubDate>Mon, 15 Nov 2021 12:49:27 GMT</pubDate>
            <description><![CDATA[<h1 id="1인덱스">1.인덱스</h1>
<p><strong>데이터 값</strong>과 <strong>데이터의 주소</strong>가 같이 저장된 것을 의미합니다.<br>데이터의 탐색에는 효율적이지만 데이터 삽입,삭제,수정에는 시간이 더 많이 걸리게 됩니다.<br>인덱스 알고리즘은 b+tree, hash 인덱스 알고리즘이 있습니다.<br>hash인덱스는 시간복잡도가O(1)이지만 데이터의 일부분으로 검색할수 없어서 범위탐색시에는 오히려 b+tree보다 오래걸린다는 특징이 있습니다.  </p>
<h4 id="📝인덱스-단점-발생하는-이유"><strong>📝인덱스 단점 발생하는 이유</strong></h4>
<blockquote>
<p>인덱스는 데이터&amp;주소가 맵핑되어있고 정렬되어있습니다. 따라서 원하는 데이터가 어떤 주소에 저장되어있는지 알기 때문에 검색속도는 올라가게 됩니다.<br>하지만 삽입,삭제,갱신에는 <strong>정렬된 상태를 유지</strong>해서 데이터를 관리하고 인덱스 테이블도 관리해야 하기 때문에 <strong>속도가 느려질수 있습니다</strong>.  </p>
</blockquote>
<h4 id="📝인덱스-알고리즘-종류"><strong>📝인덱스 알고리즘 종류</strong></h4>
<blockquote>
<p>인덱스 알고리즘은 <strong>B-tree</strong>,<strong>B+tree</strong> 알고리즘과 <strong>Hash</strong> 알고리즘이 있습니다.  </p>
</blockquote>
<ul>
<li>B-tree  <blockquote>
<p><strong>B-tree</strong>는 <strong>balanced tree</strong>로 정렬된 상태로 유지되고 <strong>노드 전체에 데이터가 저장</strong>되어 있습니다.  </p>
</blockquote>
</li>
<li>B+tree  <blockquote>
<p>B+tree 인덱스는 말그대로 트리형태로 인덱스를 구분해서 나누어 놓은것입니다.<br>B+tree의 경우 삽입,삭제 시 자동으로 구조를 유지하기 때문에 <strong>테이블의 구조를 재구성할 필요가 없기</strong> 때문에 사용합니다.<br>또한 <strong>범위 탐색시 유리</strong>하다는 장점이 있습니다. 이러한 장점 때문에 대부분의 관계형 DB에서 B+tree를 지원하고 있습니다.  </p>
</blockquote>
</li>
<li>Hash  <blockquote>
<p>해시는 컬럼 값의 해시값을 계산해서 저장하므로 <strong>검색속도가 빠릅니다</strong>.  
하지만 해시값으로 탐색하므로 <strong>값의 일부분만으로 검색할수 없습니다</strong>.  </p>
</blockquote>
</li>
</ul>
<p>👉<strong>B+tree 삽입</strong><br><img src="https://user-images.githubusercontent.com/49298852/140603501-fff2f0f2-85ed-4a86-84f8-2229e345c404.png" alt="image">
위의 트리에 Adams를 삽입하라.  </p>
<p>👉<strong>B+tree 삭제</strong><br><img src="https://user-images.githubusercontent.com/49298852/140603501-fff2f0f2-85ed-4a86-84f8-2229e345c404.png" alt="image"><br>위의 트리에서 Srinivasan를 삭제하라.  </p>
<p>❗<a href="https://ju-hy.tistory.com/106">정답</a>  </p>
<h4 id="📝인덱스-종류"><strong>📝인덱스 종류</strong></h4>
<ul>
<li>primary index(기본인덱스)  <blockquote>
<p><strong>기본 인덱스</strong>는 테이블의 <strong>기본키</strong>를 포함하는 인덱스로서 키의 순서가 레코드의 순서를 결정 짓습니다.  </p>
</blockquote>
</li>
<li>secondary index(보조인덱스)  <blockquote>
<p><strong>보조 인덱스</strong>는 기본키 이외의 인덱스이고 키의 순서가 레코드의 순서를 의미하지 않습니다.  </p>
</blockquote>
</li>
<li>컴포지트 인덱스(Composite)  <blockquote>
<p><strong>컴포지트 인덱스</strong>는 인덱스를 생성할때 두개 이상의 컬럼을 합쳐서 생성한 인덱스입니다.<br>두개 이상의 컴럼을 사용하기 때문에 <strong>and 연산</strong>으로 탐색할때 유리합니다.</p>
</blockquote>
</li>
<li>클러스터드(Clustered) 인덱스  <blockquote>
<p><strong>클러스터드 인덱스</strong>는 물리적으로 정렬되어 있는 상태로 데이터가 저장되는 인덱스이고 1개만 생성이 가능합니다.<br>기본키 설정 시 <strong>기본키를 기준</strong>으로 클러스터드 인덱스가 생성됩니다.<br>인덱스 자체의 <strong>리프 페이지가 데이터</strong>입니다. 이 말은 테이블 자체가 인덱스라는 의미이고 <strong>별도의 인덱스 테이블이 생성되지 않습니다</strong>.  </p>
</blockquote>
</li>
<li>넌클러스터드(Non-Clustered) 인덱스  <blockquote>
<p><strong>넌클러스터드 인덱스</strong>는 레코드 <strong>원본은 정렬되어 있지 않고</strong> <strong>인덱스 테이블만 정렬</strong>되어있는 인덱스입니다.  </p>
</blockquote>
</li>
<li><em>클러스터드 인덱스*</em>보다 <strong>검색 속도는 느리지만</strong> <strong>삽입,삭제,변경의 속도는 더 빠릅니다</strong>.  
별도의 인덱스 테이블을 생성하므로 <strong>용량을 추가로 차지</strong>합니다.  <br/>  
<br/>  
<br/>  

</li>
</ul>
<h1 id="2키">2.키</h1>
<p><strong>키</strong>는 데이터베이스에서 조건을 만족하는 <strong>튜플을 구분할수 있는 속성의 조합</strong>을 의미합니다.<br>키는 <strong>기본키</strong>,<strong>후보키</strong>,<strong>슈퍼키</strong>,<strong>대체키</strong>,<strong>외래키</strong>등이 있습니다.  </p>
<p><strong>후보키</strong>는 릴레이션에서 튜플을 유일하게 식별할수 있는 키들을 의미합니다. <strong>유일성</strong>과 <strong>최소성</strong>을 만족합니다.<br><strong>기본키</strong>는 후보키들중 선택한 하나의 키를 의미하고 <strong>널값을 가질수 없습니다</strong>.
<strong>대체키</strong>는 후보키에서 <strong>기본키를 제외한 키</strong>를 의미합니다.<br><strong>슈퍼키</strong>는 릴레이션에서 튜플을 유일하게 식별할수있는 유일성을 만족하지만 <strong>최소성을 만족하지 못하는 키</strong>를 의미합니다.<br><strong>외래키</strong>는 참조하고 있는 릴레이션의 속성이 현재 릴레이션에서는 <strong>기본키</strong>인 속성을 의미합니다.  </p>
<h4 id="📝유일성"><strong>📝유일성</strong></h4>
<blockquote>
<p><strong>유일성</strong>이란 하나의 키값으로 튜플을 유일하게 식별할수 있는 특성을 의미합니다.  </p>
</blockquote>
<h4 id="📝최소성"><strong>📝최소성</strong></h4>
<blockquote>
<p><strong>최소성</strong>이란 튜플을 유일하게 식별하는 키 값에서 키 값의 모든 속성이 포함되어야 튜플을 식별할수 있는 특성을 의미합니다.
<br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="3정규화">3.정규화</h1>
<p>데이터의 <strong>중복으로 발생하는 이상현상</strong>을 없애기 위해서 데이터의 <strong>중복을 최소화</strong> 하는 작업을 의미합니다. 
정규화는 1정규화부터 5정규화까지 존재하고 주로 BCNF정규화까지만 합니다.<br>정규화를 할수록 이상현상이 없어진다. 하지만 <strong>join연산이 많이 일어나게</strong> 되어서 <strong>연산속도가 느려진다</strong>는 단점이 있습니다. </p>
<p><strong>1정규화</strong>는 도메인에 여러 값이 들어가는 것이 아니라 <strong>원자값</strong>으로 되어있어야합니다. 예를 들어 한사람에 핸드폰번호가 여러개 있으면 원자값이 아닌것이고 핸드폰번호가 한개면 원자값입니다.<br><strong>2정규화</strong>는 1정규화에 속하고 모든속성이 기본키에 <strong>완전 함수 종속</strong>이 되어야합니다.<br><strong>3정규화</strong>는 2정규화에 속하고 <strong>이행적함수 종속을 제거</strong>해야합니다.<br><strong>BCNF정규화</strong>는 3정규화에 속하고 <strong>모든 결정자</strong>가 <strong>후보키</strong>에 속해야 합니다. <strong>결정자</strong>란 A-&gt;B 관계에서 A가 B의 결정자입니다.  </p>
<h4 id="📝완전-함수-종속-이행적-함수-종속"><strong>📝완전 함수 종속, 이행적 함수 종속</strong></h4>
<blockquote>
<p><strong>완전함수 종속</strong>은 기본키로 모든 튜플을 식별할수 있는 것을 의미합니다.<br>기본키가 1개의 속성으로 구성되어있으면 기본키로 식별이 가능하고 2개의 속성이라면 2개 속성을 모두 알아야 튜플을 식별할수 있어야합니다.<br><strong>이행적 함수 종속</strong>은 A가 B를 식별할수 있고 B가 C를 식별하는 경우를 의미합니다.  </p>
</blockquote>
<h4 id="📝이상현상"><strong>📝이상현상</strong></h4>
<blockquote>
<p><strong>삽입이상</strong>: 데이터를 추가할때 원하는 데이터만 추가하는 것이 아니라 다른 데이터도 같이 추가해줘야해서 발생하는 이상입니다.<br><strong>삭제이상</strong>: 삭제하려는 데이터만 지워지는 것이 아니라 그 이외의 데이터가 같이 삭제되서 발생합니다.<br><strong>갱신이상</strong>: 다른 릴레이션에 존재하는 같은 데이터와 값이 달라져서 <strong>일관성이 위배</strong>되어서 발생입니다.   </p>
</blockquote>
<h4 id="📝반정규화"><strong>📝반정규화</strong></h4>
<blockquote>
<p>데이터베이스의 성능 향상을 위해 <strong>의도적으로 정규화 원칙</strong>을 위배하는 방법입니다.<br>반정규화를 하면 성능이 향상되지만 데이터의 <strong>일관성</strong>과 <strong>정합성</strong>이 저하될수 있고 과도한 정규화는 오히려 <strong>성능이 저하</strong>됩니다.<br>반정규화 방법에는 테이블 통합, 테이블 분할, 중복 테이블 추가, 중복 속성 추가등이 있습니다.  </p>
</blockquote>
<ul>
<li>테이블 통합  <blockquote>
<p><strong>테이블 통합</strong>은 조인이 많이 발생하는 두개의 테이블을 합치는 것을 의미힙니다.  </p>
</blockquote>
</li>
<li>테이블 분할  <blockquote>
<p><strong>테이블 분할</strong>은 <strong>수직분할</strong>과 <strong>수평분할</strong>로 나뉘게 됩니다.<br>우선 <strong>수평분할</strong>은 레코드 별로 사용빈도 차이가 큰 경우 수평으로 테이블을 분할하는 것이고 <strong>수직분할</strong>은 속성이 너무 많을 경우 수직으로 분할하는 방법입니다.  </p>
</blockquote>
</li>
<li>중복 테이블 추가  <blockquote>
<p><strong>중복 테이블 추가</strong>는 여러 테이블에서 데이터를 가져와서 사용할때 중복되는 테이블을 추가해서 사용하는 것입니다.  </p>
</blockquote>
</li>
<li>중복 속성 추가  <blockquote>
<p>마지막으로 <strong>중복속성 추가</strong>는 조인이 자주 발생하거나 접근 경로가 복잡한 경우 속성을 추가하는 방식입니다.  </p>
<br/>  
<br/>  
<br/>  
</blockquote>
</li>
</ul>
<h1 id="4-트랜잭션">4. 트랜잭션</h1>
<p>트랜잭션이란 작업의 논리적 기본단위이고 <strong>작업의 완전성을 보장</strong>해주는 것입니다. 하나의 작업을 완전히 처리하지 않으면 기존의 상태로 복구시키는 특징이 있습니다.<br>트랜잭션은 <strong>원자성, **일관성</strong>, <strong>독립성</strong>, <strong>지속성</strong> (ACID)을 만족해야합니다.<br><strong>원자성</strong>은 연산의 결과가 모든 데이터베이스에 반영이 되거나 전혀 반영되지 말아야 하는 속성을 말합니다.<br><strong>일관성</strong>은 트랜잭션이 처리 결과가 항상 일관성이 있어야합니다.<br><strong>독립성</strong>은 하나의 트랜잭션이 수행중일때 다른 트랜잭션이 간섭할수 없는 것을 의미합니다.<br><strong>지속성</strong>은 트랜잭션이 성공적으로 완료된 경우 결과가 <strong>영구적으로 반영</strong>되어야 하는 것을 의미합니다.  </p>
<p>ex) A은행에서 B은행으로 송금을 해야하는 경우
    만약 송금 도중에 A은행의 계좌에서는 돈이 빠져나가고 B은행의 계좌에는 돈이 입금되지 않는 문제가 발생했습니다.
    이러한 경우 송금이 완전히 이루어지거나 아예 없던 거래로 처리하기 위해 트랜잭션이 존재하는 것입니다.  </p>
<h4 id="📝트랜잭션-연산"><strong>📝트랜잭션 연산</strong></h4>
<blockquote>
<p><strong>트랜잭션의 연산</strong>은 <strong>Commit</strong>,<strong>Savepoint</strong>,<strong>Rollback</strong>으로 구성되어있습니다.<br>우선 <strong>Commit</strong>의 경우 변경된 내용을 디스크에 저장하는 연산입니다.<br><strong>Savepoint</strong>는 rollback할 지점을 정하는 연산입니다.<br><strong>Rollback</strong>은 변경된 내용을 취소하고 이전 지점이나 저장된 지점으로 복귀시키는 연산입니다.  </p>
</blockquote>
<h4 id="📝트랜잭션-격리수준"><strong>📝트랜잭션 격리수준</strong></h4>
<blockquote>
<p>특정 트랜잭션이 다른 트랜잭션이 변경한 데이터를 볼 수 있도록 허용할지 말지 결정하는 것입니다.<br>트랜잭션 격리 수준은 <strong>READ UNCOMMITED</strong>, <strong>READ COMMITED</strong>, <strong>REPEATABLE READ</strong>, <strong>SERIALIZABLE</strong>로 나누어집니다.  </p>
</blockquote>
<ul>
<li>READ UNCOMMITED  <blockquote>
<p><strong>READ UNCOMMITED</strong>는 커밋되지 않은 데이터에도 접근이 가능한 것으로 공유데이터에 접근해도 보호되지 않습니다. 이때 <strong>Dirty read</strong>문제가 발생할수 있습니다.  </p>
</blockquote>
</li>
<li><em>Dirty read*</em>란 변경되었지만 커밋하지 않은 공유데이터를 다른 트랜잭션이 사용했는데 트랜잭션이 롤백되었을 경우 롤백 이전의 값을 그대로 사용하는 것을 의미합니다.  </li>
<li>READ COMMITED    <blockquote>
<p><strong>READ COMMITED</strong>는 실제 변경된 데이터를 가져오는 것이 아니라 <strong>커밋된 데이터를 조회</strong>하는 것입니다. 커밋된 데이터만 조회하므로 <strong>DIRTY READ가 발생하지 않습니다</strong>.  
하지만 하나의 트랜잭션이 같은 일을 할때 다른 값을 조회하는 <strong>non-repeatable read</strong> 문제가 발생할수 있습니다.  </p>
</blockquote>
</li>
<li><em>non-repeatable read*</em>는 하나의 트랜잭션내에서 항상 같은 결과를 반환해야하는 원칙을 위반하는 문제입니다.<br>만약 B트랜잭션이 1이라는 데이터를 조회하면 1이 반환됩니다. 그리고 A트랜잭션이 1을 2로 변경합니다. B트랜잭션이 다시 1을 조회하면 2가 반환됩니다.  </li>
<li>REPEATABLE READ  <blockquote>
<p><strong>REPEATABLE READ</strong>는 트랜잭션이 시작되고 종료될때까지 한번 조회한 값은 계속 같은 값이 조회되도록 하는 것입니다. 트랜잭션이 시작되기 전 커밋 상태만 조회하는 것입니다.<br>이때 업데이트 한 값에는 정합성을 보장하지만 <strong>삭제와 삽입은 보장하지 않습니다</strong>.   </p>
</blockquote>
</li>
<li>SERIALIZABLE  <blockquote>
<p><strong>SERIALIZABLE</strong>은 트랜잭션이 특정 테이블을 조회하면 <strong>다른 트랜잭션은 해당 테이블을 삽입,삭제,변경할수 없는 것</strong>을 의미합니다. 다른 말로 <strong>로킹제어</strong>라고 합니다.<br>가장 강력한 격리수준이지만 <strong>동시에 처리하는 능력은 가장 떨어진다</strong>는 단점이 있습니다.  </p>
</blockquote>
</li>
</ul>
<h4 id="📝트랜잭션-로킹"><strong>📝트랜잭션 로킹</strong></h4>
<blockquote>
<p>트랜잭션 로킹이란 트랜잭션이 데이터에 접근할때 다른 트랜잭션이 접근하지 못하도록 하는 기법입니다.<br>로킹제어를 사용하면 <strong>데드락</strong>이 발생할수 있다는 문제점도 존재합니다.<br>이때 로킹 단위가 크면 <strong>관리는 쉽지만 병행성이 떨어집니다</strong>. 하지만 로킹 단위가 작으면 <strong>관리가 어렵고 오버헤드가 증가</strong>하지만 <strong>병행성은 증가</strong>하는 장점이 있습니다.<br><br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="5-시스템-카탈로그">5. 시스템 카탈로그</h1>
<p>시스템 자체에 관련이 있는 데이터들을 저장하는 <strong>시스템 데이터 베이스</strong>입니다.<br>시스템 카탈로그에 저장되있는 데이터를 <strong>메타데이터</strong>라고 하고 메타데이터는 일반 사용자가 <strong>조회는 가능</strong>하지만 <strong>삽입,삭제,갱신과 같은 작업은 허용되지 않습니다</strong>.  
<br/><br><br/><br><br/>  </p>
<h1 id="6-무결성정합성">6. 무결성,정합성?</h1>
<p><strong>무결성</strong>이란 데이터값이 정확하고 완전해야하는 속성입니다. 무결성이 유지되어야 데이터와 실제값이 일치하는지 신뢰할수 있습니다.<br>무결성의 종류는 <strong>개체 무결성</strong>, <strong>참조 무결성</strong>, <strong>도메인 무결성</strong>, <strong>키 무결성</strong> 등이 있습니다.  </p>
<ul>
<li>개체 무결성  <blockquote>
<p><strong>개체 무결성</strong>은 기본키는 널값을 허용하지 않는 것입니다.  </p>
</blockquote>
</li>
<li>참조 무결성  <blockquote>
<p><strong>참조 무결성</strong>은 참조 관계에 있는 테이블의 <strong>데이터는 항상 같은 값을 유지하거나 Null</strong>이여야 합니다.  </p>
</blockquote>
</li>
<li>도메인 무결성  <blockquote>
<p><strong>도메인 무결성</strong>은 특정 속성의 값이 <strong>도메인에 속한 값</strong>이여야 하는 것을 의미합니다. (ex. 성별 속성에는 남,여가 올수 있지만 중성은 올수 없다)  </p>
</blockquote>
</li>
<li>키 무결성  <blockquote>
<p><strong>키 무결성</strong>은 하나의 릴레이션에는 <strong>반드시 하나의 키가 존재</strong>해야 하는 것을 의미합니다.  </p>
</blockquote>
</li>
</ul>
<p><strong>정합성</strong>이란 데이터들의 값이 서로 일치해야하는 속성입니다. 중복 데이터를 많이 사용하면 정합성을 맞추기 어렵습니다.<br>비정규형을 사용할때 이상현상이 발생하고 이때 정합성이 위배될수 있습니다.<br><br/><br><br/><br><br/>  </p>
<h1 id="7-nosql">7. NoSQL</h1>
<p><strong>NoSQL</strong>이란 관계형 데이터 베이스의 한계를 극복하기 위한 새로운 데이터 저장소의 형태입니다.<br>key-value 형식을 지원하고 관계를 정의하지 않습니다. 그리고 읽기,쓰기의 성능이 RDBMS에 비해 빠릅니다.<br><strong>고정된 스키마가 없고 수평확장에 유리</strong>합니다. 또한 빅데이터,분산환경에서 대용량의 데이터를 처리하기 유리합니다.  </p>
<h4 id="📝nosql-데이터-모델"><strong>📝NoSQL 데이터 모델</strong></h4>
<ul>
<li>key/value 데이터베이스   <blockquote>
<p>key와 value로 구성된 데이터 모델입니다. 단순한 저장구조를 가지고 빠르게 읽고 쓸수 있습니다.  </p>
</blockquote>
</li>
<li>Big Table 데이터베이스  <blockquote>
<p>key/value와 데이터 저장방식을 같습니다.<br>보통의 NoSQL은 정렬기능을 제공하지 않지만 Big Table 데이터베이스은 key를 기준으로 정렬합니다.  </p>
</blockquote>
</li>
<li>Document 데이터베이스  <blockquote>
<p>key/value에서 확장된 형태입니다. value에 document타입을 받습니다.(XML,JSON)<br>복잡한 데이터 구조를 표현할수 있고 document id 또는 속성값으로 인덱스를 생성하므로 sorting,join이 가능합니다.  </p>
</blockquote>
</li>
<li>Graph 데이터베이스  <blockquote>
<p>노드들과 관계로 구성된 데이터베이스입니다.  </p>
</blockquote>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접] 네트워크]]></title>
            <link>https://velog.io/@co_mong/%EB%A9%B4%EC%A0%91-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC</link>
            <guid>https://velog.io/@co_mong/%EB%A9%B4%EC%A0%91-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC</guid>
            <pubDate>Fri, 12 Nov 2021 12:47:15 GMT</pubDate>
            <description><![CDATA[<h1 id="1-osi-7계층이란">1. OSI 7계층이란?</h1>
<p>국제 표준화 기구에서 개발한 모델로서 네트워크 프로토콜 디자인과 통신을 계층으로 나누어서 설명한것입니다.<br>네트워크 통신이 일어나는과정을 7단계로 나누어 놓은것입니다.  </p>
<p>OSI 7계층은 물리,데이터링크,네트워크,전송,세션,표현,응용 계층으로 나누어 집니다.</p>
<h4 id="📝osi-7계층을-나누는-이유는"><strong>📝OSI 7계층을 나누는 이유는?</strong></h4>
<blockquote>
<p>계층을 나눈 이유는 통신이 일어나는 과정을 단계별로 파악할수 있기 때문입니다.<br> 이를 통해 복잡한 통신의 흐름을 사람이 알아보기 쉽고 문제가 발생했을 경우 문제가 발생한 계층만 보수하여 문제를 해결할 수 있습니다.<br> 이는 유지보수 측면에서 큰 강점이기 때문에 계층을 나누어 사용합니다.  </p>
</blockquote>
<h4 id="📝osi-7계층의-각-계층에-대한-설명"><strong>📝OSI 7계층의 각 계층에 대한 설명</strong></h4>
<ul>
<li><strong>물리 계층(1계층)</strong>  </li>
</ul>
<blockquote>
<p>데이터를 전기적 신호로 변환해서 주고받는 기능을 수행합니다.<br>전송하는(받는) <strong>데이터가 무엇인지</strong>, <strong>에러가 존재하는지 알수 없고</strong> 주고 받는 기능만 수행합니다.<br>전송단위는 비트이며 케이블, 리피터, 허브등의 장비를 사용합니다.  </p>
</blockquote>
<ul>
<li><strong>데이터 링크(2계층)</strong> </li>
</ul>
<blockquote>
<p>물리 계층으로 송수신 되는 <strong>정보의 오류와 재전송, 그리고 흐름을 관리</strong>하는 역할을 수행합니다. 
MAC 주소를 사용하여 통신하는데 MAC 주소는 랜카드마다 할당되어있습니다.<br>전송단위는 프레임이며 브리지, 스위치등의 장비를 사용합니다. </p>
</blockquote>
<ul>
<li><strong>네트워크(3계층)</strong> </li>
</ul>
<blockquote>
<p>논리적인 <strong>주소(IP)체계</strong>와 <strong>라우팅 기능</strong>을 지원합니다.<br>그 외에도 <strong>흐름제어, 오류 제어</strong>의 기능을 수행합니다.<br>전송단위는 패킷이며 라우터를 사용합니다.<br>👉 라우팅 기능이란 데이터를 목적지까지 안전하고 빠르게 전달하는 경로를 찾아서 전송하는 기능입니다.  </p>
</blockquote>
<ul>
<li><strong>전송(4계층)</strong> </li>
</ul>
<blockquote>
<p>통신을 활성화하기 위한 계층입니다. 포트를 열어서 응용프로그램들이 전송을 가능하도록 합니다. 
단대단 오류, 흐름제어를 담당합니다.<br>TCP,UDP 프로토콜을 사용합니다. </p>
</blockquote>
<ul>
<li><strong>세션(5계층)</strong> </li>
</ul>
<blockquote>
<p>통신을 위한 논리적 연결을 담당합니다.<br>어플리케이션 간 세션을 구축하고 관리하는 역할을 합니다.<br>이는 전송모드(전이중, 반이중 ...)을 결정하고 데이터 송수신의 동기를 관리합니다.  </p>
</blockquote>
<ul>
<li><strong>표현(6계층)</strong> </li>
</ul>
<blockquote>
<p>각각의 어플리케이션이 정보를 잘 통신할수 있도록 필터링하고 변환하는 계층입니다.<br>데이터의 확장자 결정과 같은 암호화와 데이터 압축을 수행합니다.<br>JPG,MPEG등의 프로토콜이 있습니다. </p>
</blockquote>
<ul>
<li><strong>응용(7계층)</strong> </li>
</ul>
<blockquote>
<p>소프트웨어,UI를 담당하는 계층입니다. 
즉 응용 프로세스와 직접 연계하여 서비스를 제공합니다. 
DNS,FTP,HTTP등의 프로토콜이 존재합니다. 
<br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="2-tcp란">2. TCP란?</h1>
<p>OSI 7계층중 4계층(전송)의 프로토콜로서 <code>신뢰성</code>을 보장하는 <code>연결지향 통신</code> 프로토콜입니다. 
또한 <code>3 way handshake</code>의 과정을 거쳐서 연결되고 <code>4 way handshake</code>과정을 거처서 연결을 종료합니다.  </p>
<h4 id="📝프로토콜이란"><strong>📝프로토콜이란?</strong></h4>
<blockquote>
<p>프로토콜이란 국가 간의 약속을 의미하고 통신에서는 통신규약을 의미합니다.  </p>
</blockquote>
<h4 id="📝tcp가-연결되고-해제하는-과정을-설명하시오"><strong>📝TCP가 연결되고 해제하는 과정을 설명하시오.</strong></h4>
<blockquote>
<p><strong>3way handshake</strong>는 TCP 통신에서 정확한 전송을 보장하기 위한 네트워크 연결 방법입니다. 
클라이언트가 SYN패킷(x) 전송==&gt;서버가 SYN(y)+ACK(x+1)패킷을 전송==&gt;클라이언트가 ACK(y+1)을 전송  </p>
</blockquote>
<blockquote>
<p><strong>4way handshake</strong>는 통신이 끝났을때 네트워크 연결 해제 방법입니다.<br>클라이언트가 FIN 패킷 전송==&gt;서버가ACK전송==&gt;서버가 ACK를 모두 전송하면 FIN 패킷을 전송한다 ==&gt;<br>클라이언트는 FIN 패킷을 받고 ACK패킷을 전송한다 ==&gt;서버는 ACK패킷을 받고 소켓을 닫는다 ==&gt; 클라이언트도 <code>TIME WAIT</code> 동안 기다리다가 소켓을 닫는다.<br>👉 클라이언트가 바로 연결을 종료하지 않고 <code>TIME WAIT</code>동안 기다리는 이유는 서버가 FIN패킷 전송전에 전송한 패킷이 늦게 도착하는 경우 데이터 유실을 방지하기 위함 때문입니다.<br><br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="3-udp란">3. UDP란?</h1>
<p>OSI 7계층중 4계층(전송)의 프로토콜로서 TCP와는 다르게 신뢰성을 보장하지 않고 비연결지향 통신 프로토콜입니다.<br>패킷이 제대로 전송되었는지 확인하는 과정이 없기 때문에(비신뢰성) 때문에 TCP에 비해 속도가 빠르다는 장점이 있습니다.<br><br/><br><br/><br><br/>  </p>
<h1 id="4-흐름제어란-무엇인가">4. 흐름제어란 무엇인가?</h1>
<p>송신과 수신측의 데이터 처리 속도 차이를 해결하기 위한 기법입니다.<br>송신측의 전송속도가 수신측의 처리속도보다 빠를경우 문제가 생깁니다. 따라서 송신측의 데이터 전송량을 수신측에 따라 조절해 줍니다.<br>이러한 흐름제어의 방식에는 <strong>Stop-wait</strong> 방식과 <strong>Sliding window</strong> 방식이 있습니다.  </p>
<h4 id="📝stop-wait-방식이란"><strong>📝Stop-wait 방식이란?</strong></h4>
<blockquote>
<p>송수신간 처리속도 차이로 인해 발생하는 문제를 해결하는 기법인 흐름제어 중 하나입니다.<br>전송한 패킷에 대해 확인 응답을 받고 다음 패킷을 전송하는 방식입니다.<br>하나를 전송하기 기다려야하기 때문에 비효율적이고 속도가 느리다는 단점이 있습니다.  </p>
</blockquote>
<h4 id="📝sliding-window-방식이란"><strong>📝Sliding window 방식이란?</strong></h4>
<blockquote>
<p>송수신간 처리속도 차이로 인해 발생하는 문제를 해결하는 기법인 흐름제어 중 하나입니다.<br>기존의 방식인 Stop-wait방식을 개선한 방법으로 수신 측에서 설정한 윈도우 크기만큼 전송하는 방식입니다.<br>전송한 패킷에 대한 응답 패킷을 받으면 해당 패킷만큼 윈도우를 옮겨서 전송하는 방식입니다.<br><br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="5-혼잡제어란-무엇인가">5. 혼잡제어란 무엇인가?</h1>
<p>송신측과 네트워크의 데이터 처리속도 차이로 인해 발생하는 문제를 해결하기 위한 기법입니다.<br>하나의 라우터에 다수의 데이터가 몰리게 된 경우 모든 데이터를 처리할수 없게 되는 경우 송신측의 데이터 전송속도를 제어해서 해결하는 방법입니다.<br>혼잡제어의 종류에는 <strong>AIMD</strong>, <strong>Slow start</strong>, <strong>빠른 재전송</strong>, <strong>빠른 회복</strong>이 있습니다.  </p>
<h4 id="📝aimdadditive-increase-multicative-decrease"><strong>📝AIMD(Additive Increase Multicative Decrease)</strong></h4>
<blockquote>
<p>초기 송신시 패킷을 하나씩 보내다가 문제가 없으면 윈도우의 크기를 증가시켜가며 전송하는 방식입니다.<br>만약 패킷 전송을 실패하거나 응답 시간이 오래 걸리면 패킷 전송 속도를 반으로 줄여가면서 조절하는 방식입니다.<br>공평하게 네트워크를 사용한다는 장점이 있지만 전송속도를 확보하는데 시간이 오래걸리고 혼잡을 미리 예측하지 못한다는 단점이 있습니다.  </p>
</blockquote>
<h4 id="📝slow-start"><strong>📝Slow start</strong></h4>
<blockquote>
<p>AIMD처럼 선형으로 윈도우의 크기를 증가시키는 것이 아니라 지수형태로 증가시키는 방법입니다.<br>하지만 전송속도가 임계점을 넘어가면 선형으로 증가시키는 방법을 사용합니다. 그러다 혼잡이 발생하면 윈도우의 크기를 1로 떨어뜨려서 혼잡 제어를 합니다.  </p>
</blockquote>
<h4 id="📝fast-retransmit빠른-재전송"><strong>📝Fast retransmit(빠른 재전송)</strong></h4>
<blockquote>
<p>패킷이 제대로 전송되면 마지막으로 제대로 수신한 ACK패킷을 응답합니다.<br>이때 패킷이 중간에 손실된 경우 특정 ACK패킷이 중복으로 수신되게 되므로 혼잡을 감지하고 윈도우의 크기를 줄이는 방식입니다.   </p>
</blockquote>
<h4 id="📝fast-recovery빠른-회복"><strong>📝Fast recovery(빠른 회복)</strong></h4>
<blockquote>
<p>혼잡 상태가 되었을때 윈도우의 크기를 1로 줄이는 것이 아니라 절반으로 줄이고 선형으로 증가시키는 방법입니다.  </p>
</blockquote>
<br/>  
<br/>  
<br/>  

<h1 id="6-http-와-https란">6. HTTP 와 HTTPS란?</h1>
<p><code>HTTP</code>는 클라이언트와 서버가 데이터를 주고 받을 때 사용하는 <strong>응용계층</strong>의 프로토콜입니다.<br>데이터를 주고 받는 형태는 메시지 형태이고 <strong>무상태</strong>, <strong>비연결성</strong>의 특징을 가집니다.<br>이러한 특성 때문에 불특정 다수에게 서비스를 제공하는데 유리합니다.  </p>
<p><code>HTTPS</code>는 HTTP의 메세지가 노출될수 있다는 보안의 약점을 보완하기 위해 <strong>HTTP</strong> 와 <strong>SSL</strong> 프로토콜을 같이 사용하는 것을 의미합니다.<br>쉽게 말하면 HTTP의 메세지를 SSL을 사용하여 공개키 암호화 방식을 사용해 <strong>암호화</strong>해서 전송하는 것을 의미합니다.  </p>
<h4 id="📝비연결성과-무상태성란"><strong>📝비연결성과 무상태성란?</strong></h4>
<blockquote>
<p>클라이언트에서 요청하고 서버가 응답하면 바로 연결을 해제하는 것을 의미합니다.<br>바로 연결을 해제하기 때문에 클라이언트의 이전 상태를 기억하지 못하므로 무상태성의 특징을 가집니다.  </p>
</blockquote>
<h4 id="📝http의-단점을-보완할-방법은-무엇이-있는지"><strong>📝HTTP의 단점을 보완할 방법은 무엇이 있는지?</strong></h4>
<blockquote>
<p>HTTP의 단점인 무상태성을 보완하기 위해 <strong>쿠키</strong>, <strong>세션</strong>, <strong>토큰</strong>을 사용합니다.<br>최근에는 무상태 특징을 보완하기 위해 쿠키,세션을 사용하여 이전상태를 반영구적으로 기억할수 있기도 합니다.  </p>
</blockquote>
<h4 id="📝ssl-handshake"><strong>📝SSL Handshake</strong></h4>
<blockquote>
<p>HTTPS는 TCP기반의 프로토콜이기 때문에 우선 TCP 3way Handshake를 실시합니다.<br>그 뒤에 SSL클라이언트가 서버에 연결을 시도하는 패킷(client hello)을 전송합니다. 그리고 SSL서버는 <strong>암호화 방식</strong>과 클라이언트 요청시 <strong>SSL인증서</strong>를 클라이언트에게 전송합니다.<br>이때 인증서 내부에는 서버에서 발행한 <strong>공개키</strong>가 있는데 이를 사용해 <strong>인증서를 복호</strong>화합니다. 만약 복호화가 된다면 <strong>적합한 서버임을 확인</strong>할수 있습니다.<br>그리고 클라이언트는 <strong>대칭키를 생성</strong>하고 SSL인증서 내부에 있던 공개키를 사용해 암호화해서 서버에 전송합니다.<br>서버에서는 기존에 가지고 있던 <strong>비밀키</strong>를 사용해 클라이언트가 전송한 <strong>대칭키</strong>를 얻을수 있습니다.<br>이제 클라이언트와 서버 모두 키를 가졌으므로 <strong>Finished</strong>패킷을 전송해 <strong>SSL Handshake</strong>를 종료합니다.<br><br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="7-쿠키세션토큰">7. 쿠키,세션,토큰</h1>
<h4 id="📝쿠키"><strong>📝쿠키</strong></h4>
<blockquote>
<p>쿠키란 <strong>HTTP 비상태성의 한계를 극복</strong>하기 위해 사용하는 기법입니다.<br>쿠키는 서버가 클라이언트의 브라우저에 저장하고 key,value형태로 저장됩니다.<br>브라우저가 종료되도 쿠키는 남아있고 아이디,비밀번호,팝업창을 저장해서 <strong>UX를 향상</strong>시켜줍니다.<br>클라이언트에 저장되기 때문에 <strong>빠르다</strong>는 장점과 <strong>보안에 취약</strong>하다는 단점이 있습니다.  </p>
</blockquote>
<h4 id="📝세션"><strong>📝세션</strong></h4>
<blockquote>
<p>쿠키를 매개로 하지만, 사용자의 정보 파일인 <strong>세션ID</strong>를 관리하는 방법입니다.<br>로그인을 유지하고 <strong>클라이언트를 구분</strong>하기 위해 사용합니다.<br>브라우저를 종료하면 세션이 만료된다는 특징이 있고 서버에 저장되기 때문에 <strong>서버에 부하</strong>가 생길수 있습니다.<br>서버에 저장되기 때문에 <strong>보안성이 좋지만</strong> 쿠키보다는 처리가 <strong>느리다</strong>는 단점이 있습니다.</p>
</blockquote>
<h4 id="📝토큰"><strong>📝토큰</strong></h4>
<blockquote>
<p>토큰은 <strong>인증에 필요한 정보를 암호화</strong>시킨 것을 의미합니다.<br>만약 유저가 로그인을 하면 서버는 이를 확인하고 인증에 필요한 토큰을 발급합니다. 이제 클라이언트는 해당 토큰을 가지고 인증을 하면 됩니다.<br>쿠키/세션과 달리 토큰만 가지고 인증하기 때문에 <strong>별도의 저장소가 필요하지 않습니다</strong>. 또한 유효기간이 만료되기 전까지 사용가능하고 후에 재발급해서 사용하면 된다.<br>하지만 유효기간 때문에 토큰이 악의적으로 사용되도 유효기간전까지 삭제할수 없다는 단점이 있습니다. 이러한 문제는 <strong>Access Token</strong>의 수명은 짧게 하고, <strong>Refresh Token</strong>을 새로 발급하면 됩니다.</p>
</blockquote>
<br/>  
<br/>  
<br/>  

<h1 id="8-ip주소">8. IP주소</h1>
<p><code>IP주소</code>는 네트워크에서 장치들이 서로를 인식하고 통신하기 위한 논리적 주소입니다.<br>또한 IP주소는 <strong>IPV4</strong>와 <strong>IPV6</strong>로 나누어지고 계층적 구조라는 특징을 가지고 있습니다.<br>IP 주소를 구분하는 방법은 Class를 통해 구분합니다. 실제 네트워크에서 사용되는 클래스는 A,B,C입니다.<br><strong>A Class</strong>의 경우 왼쪽 8비트가 네트워크 id이고 나머지 비트는 호스트 id입니다. <strong>B Class</strong>는 앞의 16비트가 네트워크 id, <strong>C Class</strong>는 앞의 24비트가 네트워크 id입니다.<br>그리고 <strong>D Class</strong>는 멀티캐스트, <strong>E Class</strong>는 예비용으로 남겨져 있습니다.<br>따라서 A가 가장 많은 host를 보유하고 할수 있습니다.</p>
<h4 id="📝ipv4"><strong>📝IPV4</strong></h4>
<blockquote>
<p>일반적인 IP주소 체계입니다.  총 32비트로 이루어져있고 43억개정도의 주소를 표현할수 있습니다.<br>하지만 현재는 부족해서 IPV6를 사용하고 있습니다.  </p>
</blockquote>
<h4 id="📝ipv6"><strong>📝IPV6</strong></h4>
<blockquote>
<p>IPV4주소의 개수가 부족해서 새롭게 만든 주소 체계입니다.<br>총 주소의 길이는 128비트이고 16진수로 표현됩니다.  </p>
</blockquote>
<h4 id="📝ip주소-할당-방식"><strong>📝IP주소 할당 방식</strong></h4>
<blockquote>
<p>IP주소 할당 방식은 <strong>고정IP</strong> 방식과 <strong>유동IP</strong> 방식 2가지가 있습니다.<br><strong>고정IP</strong>의 경우 한번 할당 받은 주소를 반납하기 전까지는 계속 해당 주소를 사용하는 방식입니다.<br><strong>유동IP</strong>는 고정IP와 다르게 인터넷에 접속할때만 IP를 할당받고 접속이 끝나면 IP를 반환하는 방식입니다. 또한 주기적으로 주소가 변경되기 때문에 보안측면에서 더 좋습니다.<br>그리고 유동IP는 <strong>DHCP서버</strong>에서 가지고 있는 IP주소를 할당받아 사용하고 반납합니다.<br><br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="9-주소검색과정">9. 주소검색과정</h1>
<p>우선 <strong>목적지의 IP주소</strong>를 확인해야 합니다.<br><strong>브라우저 캐시</strong>나 <strong>로컬 host</strong>에 해당되는 IP주소가 있다면 사용하고 없다면 <strong>DNS서버</strong>에 요청을 보내 목적지 IP주소를 응답받습니다.<br>그리고 <strong>자신의 IP주소</strong>와 <strong>가장 가까운 라우터의 IP주소</strong>를 알아내기 위해 <strong>DHCP서버</strong>에 요청해 응답받습니다.<br>다음으로 라우터 IP주소를 <strong>ARP프로토콜</strong>을 사용해 MAC주소를 알아냅니다.<br>위의 과정을 통해 다음 라우터로 데이터를 전송하면 다음 라우터에서 목적지까지 도착할때까지 <strong>최적의 라우터를 탐색하는 과정을 반복</strong>합니다.<br>목적지에 도착하면 전송 계층에서 port정보를 꺼내 어떤 프로세스에 접근해야 하는지 판단합니다.<br>그리고 응용계층을 지나 HTTP프로토콜에 따라 필요한 데이터를 탐색합니다. 검색된 데이터를 다시 위의 <strong>역순으로 전송</strong>해주면 웹페이지를 받게 됩니다.  </p>
<h4 id="📝mac주소-알아내는-방법"><strong>📝MAC주소 알아내는 방법</strong></h4>
<blockquote>
<p>브로드캐스트로 IP주소를 포함한 패킷을 전송하면 동일한 주소를 가지고 있는 라우터에서 자신의 MAC주소를 응답해줍니다.<br><br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="10-로드밸런싱이란">10. 로드밸런싱이란?</h1>
<p>서버에 트래픽이 몰릴 경우 이를 분산시켜서 트래픽 문제를 해결하는 방법을 말합니다.<br>서버를 여러 개 두고 로드밸런서가 클라이언트의 접속을 분산시켜주는 역할을 합니다.<br>라운드 로빈 방식을 사용하여 스케줄링을 진행하고 같은 IP에서의 접근하면 항상 같은 서버로 연결되는것을 보장해줍니다.  </p>
<h4 id="📝스케일업과-스케일-아웃"><strong>📝스케일업과 스케일 아웃</strong></h4>
<blockquote>
<p><code>스케일업</code>은 서버 자체의 <strong>스펙을 증가</strong>시켜서 서버 부하 문제를 해결하는 것을 의미합니다.<br>더 좋은 스펙의 서버로 변경하는 것이므로 확장성이 떨어진다는 단점이 있습니다.<br><strong>정합성 유지</strong>(데이터가 일관성이 있는것) 조건이 어려운 경우 사용합니다.  </p>
</blockquote>
<blockquote>
<p><code>스케일 아웃</code>은 <strong>서버의 개수를 증가</strong>시켜서 서버 부하 문제를 해결하는 것을 의미합니다.<br>스케일 아웃이 비교적 <strong>확장성</strong>,<strong>서버비용</strong>,<strong>장애에 강인</strong>하지만 운영비용이나 관리가 힘들다는 단점이 존재합니다.<br><strong>정합성 유지</strong>(데이터가 일관성이 있는것) 조건이 어렵지 않은 경우 사용합니다.  </p>
</blockquote>
<h4 id="📝서버에-트래픽이-몰릴경우-대처방법"><strong>📝서버에 트래픽이 몰릴경우 대처방법</strong></h4>
<blockquote>
<p><strong>스케일업</strong>과 <strong>스케일 아웃</strong>이 있다.<br>그 외에도 <strong>웹 캐시</strong>를 사용하여 웹서버에서 컨텐츠를 매번 요청하여 받아오는 것이 아니라 웹캐시 서버에서 불러와서 사이트의 <strong>응답시간</strong>과 <strong>트래픽</strong>을 감소시키는 효과를 얻을수 있습니다.<br>추가로 <strong>MSA(MicroService Architecture)</strong> 를 사용하는 방법도 존재합니다. MSA는 API를 사용해서 서비스의 end-point에 접근하고 세부사항은 추상화합니다.<br>따라서 각각의 서비스는 따로 <strong>모듈화</strong>가 되어 있으므로 모듈마다 <strong>기술스택을 다르게 사용</strong>할수도 있고 <strong>서비스별로 scale-out</strong>이 가능하다는 장점이 있습니다.<br>하지만 <strong>트랜잭션 유지</strong>, <strong>통합테스트의 어려움</strong>, <strong>복잡함</strong>이라는 단점이 존재합니다.  </p>
</blockquote>
<br/>  
<br/>  
<br/> 

<h1 id="11-blockingnon-blocking--synchronousasynchronous">11. Blocking/Non-blocking &amp; Synchronous/Asynchronous</h1>
<p><strong>블럭</strong>,<strong>논블럭</strong>은 <strong>제어권</strong>을 누가 가지고 있느냐의 차이입니다.<br>우선 <strong>블럭</strong>의 경우 호출된 함수에게 제어권을 넘겨주고 <strong>논블럭</strong>의 경우 호출된 함수를 실행하고 바로 제어권을 가져옵니다. 따라서 논블럭은 호출된 함수를 기다리면서 다른 일을 수행할수 있습니다.  </p>
<p><strong>동기</strong>,<strong>비동기</strong>는 <strong>동시성</strong>에 중점을 두고 봐야합니다.<br><strong>동기</strong>는 호출된 함수의 상태를 본래 함수에서 계속해서 확인하는 것이고 <strong>비동기</strong>는 호출된 함수에서 스스로 상태를 보고 call back을 전달하여 완료여부를 본래 함수에게 알립니다.  </p>
<br/>  
<br/>  
<br/> 

<h1 id="12-네트워크-오류">12. 네트워크 오류</h1>
<p>네트워크에서 데이터를 전송시 <strong>감쇠</strong>,<strong>지연</strong>,<strong>잡음</strong>,<strong>외곡</strong>의 이유로 오류가 발생할수 있습니다.<br>그리고 이러한 오류를 제어하는 방식은 스스로 오류를 검출해 수정하는 <strong>FEC</strong>, 수신측에서 재전송을 요구하는 <strong>BEC</strong>방식이 있습니다.<br>BEC의 경우 패리티,CRC,체크섬,해밍코드등을 사용해 오류를 검출하게 됩니다.  </p>
<h4 id="📝패리티-검사"><strong>📝패리티 검사</strong></h4>
<blockquote>
<p><strong>1차원 패리티</strong>는 1의 개수를 짝수 또는 홀수로 보낼지 약속하고 전송하게 됩니다. 그리고 수신측에서 1의 개수를 검사했을때 다르면 오류를 검출하는 방식입니다.<br>이 경우 1개의 오류만 검출할수 있고 어디서 오류가 발생했는지 알수 없습니다. 또한 변경된 비트의 개수가 짝수이면 오류를 검출하지 못합니다.  </p>
</blockquote>
<blockquote>
<p>이러한 문제를 해결하기 위해 <strong>2차원 패리티</strong>가 등장했습니다.<br>2차원 패리티는 말 그대로 패리티비트를 2차원으로 보냅니다. 이 경우 1차원 패리티에서 짝수개의 오류를 검출하지 못하던 점을 해결했지만 여전히 행열 모두 짝수개씩 변경됐다면 검출하지 못합니다.  </p>
</blockquote>
<h4 id="📝crc"><strong>📝CRC</strong></h4>
<blockquote>
<p>전송할 데이터에 (CRC코드 최고차수)비트를 붙이고 CRC코드로 XOR 한 값을 구합니다.<br> 그리고 전송할 데이터 뒤에 위에서 구한 값을 붙이고 전송합니다.<br> 데이터를 수신하면 CRC코드로 나누고 결과가 0이면 오류가 없는 것이고 다른 값이 나오면 오류가 발생한 것입니다.<br> 주로 <strong>데이터 링크 계층</strong>에서 사용됩니다.  </p>
</blockquote>
<h4 id="📝체크섬"><strong>📝체크섬</strong></h4>
<blockquote>
<p>송신할 데이터를 전부 더한 다음 앞의 4비트를 버립니다. 그리고 그 값의 2의 보수를 구해 체크섬을 생성합니다.
데이터를 수신받으면 모든 데이터와 체크섬을 더합니다. 그리고 앞의 4비트를 버렸을때 0이 나오면 오류가 없고 0이 아닌 값이 나오면 오류가 발생했다고 판단합니다.  </p>
</blockquote>
<h4 id="📝해밍코드"><strong>📝해밍코드</strong></h4>
<blockquote>
<p>오류를 <strong>검출</strong>하고 <strong>수정</strong>할수 있는 오류검출 방법입니다.  </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접] OS]]></title>
            <link>https://velog.io/@co_mong/%EB%A9%B4%EC%A0%91-OS</link>
            <guid>https://velog.io/@co_mong/%EB%A9%B4%EC%A0%91-OS</guid>
            <pubDate>Fri, 12 Nov 2021 12:31:49 GMT</pubDate>
            <description><![CDATA[<h1 id="1-운영체제">1. 운영체제</h1>
<p><strong>운영체제</strong>란 시스템의 자원을 효율적으로 관리하고 유저가 사용하기 편하도록 환경을 제공해주는 시스템 소프트웨어를 의미합니다.<br>운영체제의 기능으로는 <strong>시분할 시스템</strong>이 있는데 다수의 작업을 계속해서 번갈아가면서 실행해서 <strong>동시에 처리되는것처럼</strong> 보이게 해주고 <strong>응답시간을 짧게</strong> 합니다.<br>그리고 운영체제는 중요한 자원에 대한 접근 권한을 나누기 위해 <strong>유저모드</strong>와 <strong>커널모드</strong>로 나누어서 사용합니다.<br>운영체제의 종류는 <strong>Window</strong>,<strong>Linux</strong>,<strong>Unix</strong>등이 있고 Window는 주로 개인용으로 사용되고 Linux와 Unix는 서버용으로 사용됩니다.  </p>
<h4 id="📝시스템콜"><strong>📝시스템콜</strong></h4>
<blockquote>
<p><strong>시스템콜</strong>이란 <strong>커널 영역</strong>의 기능을 <strong>유저모드</strong>에서 사용가능 하도록 해주는 기능입니다.<br>다시말해 프로세스가 하드웨어에 직접 접근하여 필요한 기능을 사용할수 있게 해주는 것을 의미합니다.  </p>
</blockquote>
<h4 id="📝시스템콜-명령어"><strong>📝시스템콜 명령어</strong></h4>
<blockquote>
<p>Fork(): 자식프로세스를 생성하는 시스템콜<br>Wait(): Child가끝날때까지기다리는 시스템콜<br>Exec(): Fork해온 기존 프로세스와 다른 기능을 하도록 하게 해주는 시스템콜</p>
</blockquote>
<br/>  
<br/>  
<br/>  

<h1 id="2-프로세스와-스레드">2. 프로세스와 스레드</h1>
<p><strong>프로세스</strong>는 메모리에 적재되어 실행중인 프로그램을 의미하고 운영체제로부터 자원을 할당받는 <strong>작업의 단위</strong>입니다.<br>각각의 프로세스는 독립적으로 동작하며 다른 프로세스의 자원에 접근할수없습니다. 프로세스간 데이터를 교환하기 위해서는 <strong>IPC(Inter Process Comunication)</strong> 을 사용해야 합니다.<br>프로세스는 공유하는 메모리가 없기 때문에 기존의 캐시와 상관없는 데이터를 탐색해야 하기 때문에 <strong>Context Switch</strong>에 많은 비용이 발생합니다.  </p>
<p><strong>스레드</strong>란 프로세스의 <strong>실행 단위</strong>입니다.<br>하나의 프로세스에서 여러개의 스레드가 동작하고 각각의 스레드는 <strong>힙</strong>,<strong>데이터</strong>,<strong>코드 영역</strong>을 공유하고 별도의 <strong>스택</strong>을 가집니다.<br>스레드간 공유메모리를 가지기 때문에 <strong>데이터 전송</strong>과 <strong>Context Switch</strong>에 많은 비용이 발생하지 않습니다.<br>또한 스택을 제외한 메모리를 공유하므로 하나의 스레드에서 공유 메모리 영역에 손상시키면 전체의 스레드가 동작하지 않는 단점이 있습니다.  </p>
<h4 id="📝프로세스의-메모리-영역"><strong>📝프로세스의 메모리 영역</strong></h4>
<blockquote>
<p><strong>Code</strong>: 코드자체가 저장됩니다.<br><strong>Data</strong>: 전역변수,정적변수,배열과같은 데이터가 저장됩니다.<br><strong>Heap</strong>: 동적 데이터가 저장됩니다.<br><strong>Stack</strong>:지역변수,매개변수, 함수가 저장됩니다.</p>
</blockquote>
<h4 id="📝context-switching"><strong>📝Context switching</strong></h4>
<blockquote>
<p>cpu는 한번에 하나의 프로세스만 실행 가능합니다. 이때 최대한 동시에 프로세스들이 실행되는 것처럼 보이도록 다른 프로세스와 교체할때 <strong>context switching</strong>을 사용합니다.<br><strong>Context swithcing</strong>의 실행과정은 우선 실행중인 프로세스의 상태를 <strong>PCB</strong>에 저장합니다.<br>그리고 실행하려는 프로세스의 상태를 복원해 레지스터에 저장해 실행하면 됩니다.  </p>
</blockquote>
<h4 id="📝pcbprocess-control-block"><strong>📝PCB(Process Control Block)</strong></h4>
<blockquote>
<p><strong>PCB</strong>는 프로세스의 메타데이터를 저장하고 다음 실행 명령어의 주소를 저장하고 있습니다.<br>프로세스의 <strong>Context switching</strong>을 할때 현재 프로세스의 상태를 기억하는 용도로 사용합니다.<br><br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="3-인터럽트">3. 인터럽트</h1>
<p>프로그램 실행 도중에 <strong>우선적으로 처리해야할 작업</strong>이 생길 경우 먼저 처리하고 기존의 작업으로 복귀하는 것을 <strong>인터럽트</strong>라고 합니다.<br>인터럽트의 종류는 <strong>외부인터럽트</strong>,<strong>내부인터럽트</strong>,<strong>소프트웨어인터럽트</strong>가 있습니다.<br><strong>외부인터럽트</strong>는 입출력 장치등에서 오는 외부적요인으로 발생합니다.<br><strong>내부인터럽트</strong>는 잘못된 명령이나 데이터를 사용했을때 (0으로나누기 ,버퍼오버플로우...) 발생합니다.<br>마지막으로 <strong>소프트웨어 인터럽트</strong>는 사용자가 다른 프로세스를 실행시키거나 감시 프로그램을 호출할때 발생한다.  </p>
<h4 id="📝인터럽트-동작-과정"><strong>📝인터럽트 동작 과정</strong></h4>
<blockquote>
<p>인터럽트 요청이 발생하면 우선 현재 실행중인 명령을 완료합니다.<br>그리고 PCB에 현재 프로세스의 상태를 저장하고 인터럽트가 발생한 요청을 찾아 해당 요청을 처리합니다.<br>마지막으로 PCB에서 기존 프로그램 상태를 복원하고 프로세스 실행을 재개합니다.<br><br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="4-ipc란">4. IPC란?</h1>
<p>프로세스는 독립된 메모리 공간을 가지기 때문에 통신을 위한 기법이 필요합니다. 이때 프로세스간 통신을 가능하도록 해주는 것이 <strong>IPC(interprocesscommunication)</strong> 입니다.  </p>
<h4 id="📝ipc종류"><strong>📝IPC종류</strong></h4>
<ul>
<li><p><strong>익명파이프</strong>  </p>
<blockquote>
<p>통신할 프로세스를 명확히 알고 있는 경우 사용합니다.(=&gt; 같은 부모 프로세스를 가진 경우)<br>한쪽방향으로만 통신이 가능한 <strong>반이중통신</strong>입니다.<br>간단하게 사용할수 있다는 장점이 있지만 전이중통신을 위해 2개의 파이프를 만들어야 한다는 단점이 있습니다.</p>
</blockquote>
</li>
<li><p><strong>네임드파이프</strong>  </p>
<blockquote>
<p>전혀 모르는 프로세스간 통신에 사용돠고 다른 기능들은 익명파이프와 동일합니다.  </p>
</blockquote>
</li>
<li><p><strong>메시지큐</strong></p>
<blockquote>
<p>파이프처럼 데이터의 흐름이 아니라 메모리에 번호를 붙인 데이터를 적재해서 통신하는 방법입니다. 또한 파이프와 같이 단방향 통신을 지원합니다.  </p>
</blockquote>
</li>
<li><p><strong>공유메모리</strong></p>
<blockquote>
<p>프로세스간 메모리를 공유해서 사용하는 방법입니다.<br>공유메모리는 처음 사용할때만 시스템콜을 사용하고 중개자 없이 바로 메모리에 접근이 가능하므로 <strong>IPC</strong>중 가장 빠릅니다. 하지만 데이터의 일관성을 유지해야 하기 때문에 <strong>동기화</strong>가 중요합니다.  </p>
</blockquote>
</li>
<li><p><strong>메모리맵</strong></p>
<blockquote>
<p><strong>메모리맵</strong> 또한 공유메모리처럼 메모리를 공유합니다.<br>다른점은 파일을 열고 메모리에 맵핑 시켜서 공유하는 방식입니다. 대용량의 데이터를 공유할 때 사용하는 방식입니다.  </p>
</blockquote>
</li>
<li><p><strong>소켓</strong>  </p>
<blockquote>
<p>소켓은 일반적으로 네트워크에서 데이터 통신에 사용되는 방식입니다.<br>하지만 같은 운영체제 상에서 실행되는 두 프로세스도 <strong>소켓</strong>을 통해 통신이 가능합니다.<br>소켓은 파이프처럼 연결을 진행하고 1대1로 데이터를 통신하는 방법입니다.  </p>
<br/>  
<br/>  
<br/>  
</blockquote>
</li>
</ul>
<h1 id="5-스케줄링">5. 스케줄링</h1>
<p>Cpu나 자원을 <strong>효율적으로 사용</strong>하기 위해 프로세스를 cpu에 할당하는 순서를 정해주는 것을 의미합니다.<br>스케줄러의 목표는 <strong>많은처리량</strong>,<strong>빠른응답시간</strong>,<strong>deadline 맞추는것</strong>입니다.<br>크게는 <strong>장기,중기,단기 스케줄러</strong>로 구분하고 cpu 점유 탈취 가능 여부로 <strong>선점형 스케줄러</strong>와 <strong>비선점형 스케줄러</strong>로 구분됩니다.</p>
<h4 id="📝장기중기단기-스케줄러"><strong>📝장기,중기,단기 스케줄러</strong></h4>
<blockquote>
<p><strong>장기 스케줄러</strong>는 스케줄러 큐에 적재할 task를 선정하는 것이 목표입니다.<br><strong>단기 스케줄러</strong>는 장기스케줄러로 선택한 task들의 우선순위를 결정해줍니다. 선점형,비선점형 스케줄러가 이에 속합니다.<br>마지막으로 <strong>중기 스케줄러</strong>는 우선순위가 낮은 task를 스케줄링 큐에서 내리는 역할을 합니다.  </p>
</blockquote>
<h4 id="📝비선점형-스케줄러"><strong>📝비선점형 스케줄러</strong></h4>
<blockquote>
<p><strong>비선점형 스케줄러</strong>는 프로세스가 종료되지 않는 이상 자원을 반납하지 않습니다. 정해진 순서대로 프로세스가 처리되기 때문에 <strong>오버헤드</strong>가 적고 <strong>기아상태</strong>에 빠질 일도 없습니다.<br>비선점형 스케줄링은 일괄처리 되는 <strong>배치시스템</strong>에 사용됩니다.  </p>
</blockquote>
<h4 id="📝비선점형-스케줄러-종류"><strong>📝비선점형 스케줄러 종류</strong></h4>
<blockquote>
<p><strong>FCFS</strong>: 먼저 큐에 들어간 순서대로 처리합니다.<br><strong>SJF</strong>: 가장 짧은 수행시간을 가지는 작업을 먼저 처리합니다.<br><strong>HRN</strong>: SJF에 에이징기법을 추가한 방식입니다.<br><strong>Priority스케줄링</strong>: 대기중인 프로세스에 우선순위를 부여하여 할당합니다.    </p>
</blockquote>
<h4 id="📝선점형-스케줄러"><strong>📝선점형 스케줄러</strong></h4>
<blockquote>
<p><strong>선점형 스케줄러</strong>는 실행중인 프로세스를 중지하고 다른 프로세스가 CPU를 점유할수 있게 해주는 스케줄러입니다.<br> 우선순위가 존재함으로 특정task가 자원을 할당받지 못하는 <strong>기아현상(starvation)</strong> 이 발생할 수 있습니다. 또한 <strong>Context Switching</strong>이 자주 발생할 수 있어서 <strong>오버헤드</strong>가 발생할수 있습니다.<br> 선점형 스케줄링은 대화형 시스템에 많이 사용됩니다.   </p>
</blockquote>
<h4 id="📝선점형-스케줄러의-종류"><strong>📝선점형 스케줄러의 종류</strong></h4>
<blockquote>
<p> <strong>SRT(Shortest Remaining Time)</strong> : <strong>SJF</strong> 알고리즘에 선점형 스케줄링 기법을 추가한것입니다. 남은 시간이 가장 작은 task가 우선순위가 높습니다.<br> <strong>라운드로빈</strong> : 각각의 프로세스마다 <strong>timequantum</strong>을 할당해서 timequantum만큼 실행하고 다음 프로세스를 실행하는 방식입니다. 문맥교환이 자주 발생해서 <strong>오버헤드</strong>가 발생합니다.<br> <strong>Multilevel-queue</strong> : 라운드로빈에 큐를 여러개 사용하는 방식입니다. 라운드로빈처럼 timequantum이 주어지고 timequantum만큼 실행하지만 다 실행되지 않았으면 우선순위가 낮은 다음 큐로 내려가게 됩니다. <strong>짧은 작업을 처리</strong>할때 유리하고, <strong>turnarround</strong> 평균시간을 줄여줍니다.<br> <strong>멀티레벨피드백큐</strong> : 멀티레벨큐에서 기아상태에 빠지는 것을 방지하기 위해 <strong>에이징기법</strong>을 추가한 스케줄링 기법입니다.  </p>
</blockquote>
<h4 id="📝에이징-기법"><strong>📝에이징 기법</strong></h4>
<blockquote>
<p>특정 프로세스의 우선순위가 낮아서 무한정 기다리는 경우(<strong>기아상태</strong>)를 방지하기 위해서 기다린 시간에 비례해서 우선순위를 높여주는 방법입니다.
<br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="6-데드락교착상태"><strong>6. 데드락(교착상태)</strong></h1>
<p>프로세스들이 서로의 자원을 반환하기 기다리고 있는 상태를 의미합니다.<br><strong>상호배제</strong>,<strong>점유대기</strong>,<strong>비선점</strong>,<strong>순환대기</strong> 모두 충족할때 발생합니다.</p>
<p><strong>상호배제</strong>: 하나의 자원에 동시에 하나의 프로세스만 접근할수 있는 속성입니다.<br><strong>점유대기</strong>: 자원을 가지고 있는 상태에서 다른 프로세스가 사용하는 자원의 반납을 기다리는 것을 의미합니다.<br><strong>비선점</strong>: 다른 프로세스가 점유중인 자원을 가져올수 없는 것을 의미합니다.<br><strong>환형대기</strong>: 각각의 프로세스가 다음 프로세스가 원하는 자원을 가지고 있는 상태를 의미합니다.</p>
<h4 id="📝교착상태-해결방법"><strong>📝교착상태 해결방법</strong></h4>
<blockquote>
<p><strong>예방&amp;회피</strong>,<strong>탐지&amp;회복</strong>,<strong>무시</strong>가 있습니다.<br>예방은 교착상태 발생 조건중 하나를 제거해서 해결하지만 자원의 낭비가 큽니다.<br>회피는 교착상태가 발생하지 않도록 회피하는 방법입니다. <strong>은행원</strong>알고리즘이 있습니다.<br>탐지&amp;회복은 교착상태가 되도록 허용하고 탐지를 하고 회복하는 방법입니다. <strong>자원 할당 그래프</strong>를 통해 교착상태를 탐지하고 프로세스를 모두 제거하거나 하나씩 제거하는 방법을 사용해 회복합니다.<br>마지막으로 무시는 대부분의 시스템은 교착상태가 잘 발생하지 않으므로 무시하는 방법입니다.  </p>
</blockquote>
<h4 id="📝은행원-알고리즘"><strong>📝은행원 알고리즘</strong></h4>
<blockquote>
<p>안전상태를 유지할수 있는 요구만 수락하고 불안전 상태를 유발할수 있는 요구는 거절하는 방법입니다.<br><strong>안전상태</strong>란 시스템이 교착상태를 일으키지 않고 각 프로세스가 요구하는 자원을 할당할수 있는 상태를 의미합니다.<br>반대로 <strong>불안전상태</strong>란 시스템이 교착상태를 일으킬 가능성이 있는 상태입니다. 또한 각 프로세스가 요구한 양만큼 자원을 할당할수 없는 경우입니다.  </p>
</blockquote>
<blockquote>
<p><strong>은행원 알고리즘</strong>이 수행되기 위해서는 각각의 프로세스가 <strong>필요로하는 최대 자원의 양</strong>, 그리고 각 프로세스가 <strong>사용하고 있는 자원의 양</strong>, 마지막으로 <strong>사용가능한 자원의 양</strong>을 알아야 합니다.<br>예를 들면 12개의 자원을 보유하고 있고 프로세스 3개가 각각 10,9,9개의 자원을 요구하는 상황입니다.<br>그리고 a,b,c 프로세스에 자원을 1,2,6개씩 할당합니다.
여기서 a나b 프로세스에 추가적으로 자원을 할당하는 경우는 불안전 상태를 유발할수 있으므로 거절하고 c에서 요청하는 자원을 할당하는 것은 안전상태이므로 허가해주게됩니다.<br><br/><br><br/><br><br/>  </p>
</blockquote>
<h1 id="7-경쟁상태race-condition">7. 경쟁상태(Race Condition)</h1>
<p><strong>공유자원</strong>에 여러 프로세스가 접근해서 데이터의 <strong>일관성</strong>을 해칠수 있는 상태를 의미합니다.<br>경쟁상태는 커널에서 작업을 수행할때 <strong>인터럽트가 발생</strong>하면 경쟁상태가 발생할 수 있습니다. 이때 커널에서 작업중일때 인터럽트가 발생하지 않도록 disable해놓으면 해결됩니다.<br>프로세스가 커널에서 작업중일때 <strong>문맥교환이 발생</strong>하면 경쟁상태가 발생합니다. 이떄도 커널모드에서 작업중이면 문맥교환이 발생하지 않도록 하면 해결됩니다.<br>공유메모리 내의 커널데이터에 <strong>여러개의 프로세스가 접근</strong>하면 발생합니다. 한 프로세스가 공유데이터에 접근할때 lock을 걸어서 다른 프로세스가 접근하지 못하도록 하면 해결됩니다.  </p>
<h4 id="📝경쟁상태-해결방법"><strong>📝경쟁상태 해결방법</strong></h4>
<blockquote>
<p>첫번째 방법으로 <strong>스핀락</strong>이 있습니다. 스핀락은 임계영역에 접근할수 없을때 무한 루프를 돌면서 대기하면서 기다리는 방법입니다.<br>무한 루프를 돌기 때문에 <strong>문맥교환이 발생하지 않고</strong> <strong>busy waiting</strong>이 발생하게 됩니다.  </p>
</blockquote>
<blockquote>
<p>두번째는 <strong>뮤텍스</strong>입니다. 동시에 임계영역에 접근할수 있는 프로세스가 1개이고 접근할때 lock을 걸고 사용 후에 unlock을 해서 접근을 제어합니다.<br>뮤텍스는 wait과 signal을 사용하는데 락킹 매커니즘은 스핀락과 같은데 busy waiting을 하는 것이 아니라 <strong>sleep상태에서 wakeup</strong>상태로 변환될 때 권한을 획득합니다.<br>뮤텍스 알고리즘은 <strong>데커</strong>,<strong>피터슨</strong>,<strong>제과점</strong> 알고리즘으로 나뉩니다.<br>데커 알고리즘은 flag로 임계영역점근 여부를 정하고 turn으로 누가 접근할 차례인지 판단합니다.<br>피터슨 알고리즘은 데커와 유사하지만 임계영역 접근 순서를 양보하는 것이 차이입니다.<br>마지막으로 제과점 알고리즘은 가장 적은 수의 표를 가지고 있는 프로세스가 임계영역에 접근하는 방법입니다.  </p>
</blockquote>
<blockquote>
<p>마지막 방법으로 <strong>세모포어</strong>가 있습니다. 프로세스가 공유자원(임계영역)에 접근하면 세마포어를 감소하고 사용하지 않으면 세마포어를 증가시킵니다. 따라서 세마포어가 0이 되면 가용할수 있는 자원이 없기 때문에 더이상 접근할수 없습니다.<br>이때 가용할수 있는 자원의 수가 2개 이상이면 <strong>카운팅 세마포어</strong> 1개라면 <strong>이진 세마포어(뮤텍스)</strong> 라고 부릅니다.<br><br/><br><br/><br><br/>      </p>
</blockquote>
<h1 id="8-메모리-관리-기법">8. 메모리 관리 기법</h1>
<p>부족한 메모리를 효율적으로 사용하기 위한 기법입니다. 메모리에 연속적으로 할당하는지 여부에 따라 <strong>연속 메모리 할당</strong>,<strong>불연속 메모리 할당</strong>으로 나누어집니다.  </p>
<h4 id="📝연속-메모리-관리-기법"><strong>📝연속 메모리 관리 기법</strong></h4>
<blockquote>
<p><strong>연속 메모리 관리 기법</strong>은 프로그램 전체가 하나의 커다란 메모리에 <strong>연속적으로 할당</strong>되는 것입니다.<br>연속 메모리 관리 기법은 <strong>고정분할</strong>,<strong>동적분할</strong> 기법으로 나뉩니다.<br>고정분할 기법은 말그대로 고정된 크기로 분할하는 것인데 <strong>내부 단편화</strong>가 발생합니다.<br>동적분할 기법은 파티션이 분할되는 크기가 동적입니다. <strong>외부 단편화</strong>가 발생합니다.  </p>
</blockquote>
<h4 id="📝불연속-메모리-관리-기법"><strong>📝불연속 메모리 관리 기법</strong></h4>
<blockquote>
<p><strong>불연속 메모리 관리 기법</strong>은 프로그램의 일부가 서로 <strong>다른 주소에 할당</strong>되는 것입니다.<br>불연속 메모리 관리 기법은 <strong>페이징(고정)</strong>,<strong>세그멘테이션(동적)</strong> 으로 나뉩니다.<br><strong>단순 페이징</strong>은 고정된 크기로 할당하여 <strong>내부 단편화</strong>는 있지만 외부 단편화는 발생하지 않습니다.<br><strong>단순 세그멘테이션</strong>은 메모리를 동적분할해서 프로세스를 할당하므로 <strong>메모리 사용효율이 증가</strong>하고 <strong>오버헤드가 감소</strong>합니다. 하지만 여전히 <strong>외부 단편화</strong>는 존재합니다.<br><strong>가상 메모리 페이징</strong>은 프로세스를 전부 메모리에 올려서 사용하느 것이 아니라 <strong>필요한 페이지가 생기면 로드</strong>하는 방식입니다. 필요할때마다 로드해야 하므로 <strong>오버헤드</strong>가 발생합니다.<br><strong>가상 메모리 세그멘테이션</strong> 또한 <strong>필요할때 마다 메모리로 로드</strong>하므로 오버헤드가 발생합니다.  </p>
</blockquote>
<h4 id="📝단편화"><strong>📝단편화</strong></h4>
<blockquote>
<p><strong>내부 단편화</strong>는 고정 크기 파티션을 할당했을때 해당 크기를 다 사용하지 못해서 발생하는 단편화입니다.<br><strong>외부 단편화</strong>는 동적 크기 파티션을 할당했을때 메모리 전체에서 남는 메모리가 생기는 것을 의미합니다.<br><br/><br><br/><br><br/>    </p>
</blockquote>
<h1 id="9-가상메모리란">9. 가상메모리란?</h1>
<p>실제로 존재하는 메모리가 아니라 메모리 역할을 하는 <strong>가상의 메모리</strong>입니다.<br>실행되어야 하는 부분만 메모리상에 있으면 되기 때문에 실제 프로그램을 수행할때 프로그램 전체가 메모리에 있을 필요가 없습니다.<br>이를 위해 필요한 것이 가상메모리입니다.<br>가상메모리는 <strong>논리적 연속성</strong>을 제공해주고 실제 메모리 크기보다 더 큰 공간을 사용할수 있다는 장점이 있습니다.<br><br/><br><br/><br><br/>    </p>
<h1 id="10-엔디안이란">10. 엔디안이란?</h1>
<p>컴퓨터 메모리에 연속된 바이트를 할당하는 방법입니다.<br>엔디안은 <strong>빅엔디안</strong>과 <strong>리틀엔디안</strong>으로 나뉩니다.  </p>
<h4 id="📝리틀엔디안"><strong>📝리틀엔디안</strong></h4>
<blockquote>
<p><strong>리틀엔디안</strong>은 빅엔디안과 읽는 순서가 반대입니다.<br>최상위 비트가 가장 뒤에오고 최하위 비트가 가장 앞에오게됩니다. 이러한 점 덕분에 수가 커지더라도 <strong>오버헤드가 발생하지 않습니다</strong>.  </p>
</blockquote>
<h4 id="📝빅엔디안"><strong>📝빅엔디안</strong></h4>
<blockquote>
<p><strong>빅엔디안</strong>은 사람들이 평소에 읽는 방식과 유사합니다.<br>최상위 비트가 앞에오므로 낮은 주소에 앞의 값이 오게됩니다. 이러한 특성 때문에 <strong>디버깅에 유리</strong>하다는 장점이 있습니다.  </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접] 공통 질문]]></title>
            <link>https://velog.io/@co_mong/%EB%A9%B4%EC%A0%91-%EA%B3%B5%ED%86%B5-%EC%A7%88%EB%AC%B8</link>
            <guid>https://velog.io/@co_mong/%EB%A9%B4%EC%A0%91-%EA%B3%B5%ED%86%B5-%EC%A7%88%EB%AC%B8</guid>
            <pubDate>Tue, 02 Nov 2021 12:39:06 GMT</pubDate>
            <description><![CDATA[<h3 id="1-좋은-코드란-무엇인가">1. 좋은 코드란 무엇인가?</h3>
<hr>
<p>사람들마다 좋은 코드의 기준이 다르겠지만 제가 생각하는 좋은 코드란 <strong>&quot;읽기 쉬운 코드&quot;</strong>, 그리고 <strong>&quot;중복이 없는 코드&quot;</strong>라고 생각합니다.</p>
<p> 👉<strong>읽기 쉬운 코드란?</strong>
읽기 쉬운 코드는 개개인 또는 집단마다 기준이 다르다고 생각합니다. 개인이라면 자신이 작성한 코드를 다시 봐도 이해하기 쉬운 코드일 것이고 집단이라면 집단 내에서 정한 코딩 규칙을 준수한 코드일 것입니다. </p>
<p>물론 주석을 제대로 작성하면 코드를 읽기 쉬운 코드일 수도 있지만 코드 갱신과 주석 갱신이 같이 이루어 지지 않는다면 불확실한 정보를 전달할수도 있습니다.</p>
<p> 👉<strong>중복이 없는 코드란?</strong>
같은 기능을 하는 코드가 여러곳에 존재한다면 우선 코드의 길이가 길어지기 때문에 코드를 읽는데 걸리는 시간이 늘어나는 <strong>&quot;코드량 증가&quot;</strong>, 그리고 기능을 수정할때 모든 코드의 동일성을 유지하기 힘든 <strong>&quot;중복 코드 동일성&quot;</strong>문제가 발생할수 있습니다.</p>
<h3 id="2-oopobject-oriented-programming">2. OOP(Object Oriented Programming)</h3>
<hr>
<p>객체 지향 프로그래밍은 현실의 객체를 프로그램으로 옮겨와 상태와 행위를 가진 객체를 생성해 프로그래밍하는 기법입니다. </p>
<h4 id="객체지향-장단점">객체지향 장단점</h4>
<blockquote>
<p>장점: 재사용성이 뛰어나고 유지보수하기 쉽다.
단점: 개발속도, 실행속도가 느리다.</p>
</blockquote>
<h4 id="객체지향언어-종류">객체지향언어 종류</h4>
<blockquote>
<p>자바, 오브젝트-C, C++, C#, 파이썬</p>
</blockquote>
<h4 id="oop-4가지-특징">OOP 4가지 특징</h4>
<blockquote>
<p><strong>👉캡슐화</strong>
코드를 외부로 노출시키지 않는다.
데이터를 외부에서 직접 접근하지 않고 getter,setter를 통해서만 접근할수 있다.
<strong>👉추상화</strong>
불필요한 정보는 숨기고 중요한 정보만 표현하는 것입니다. 공통의 속성이나 기능을 묶어놓은 추상메소드나 인터페이스가 있습니다.
<strong>👉다형성</strong>
변수나 메소드가 상황에 따라 다른 결과를 나타내는것을 의미합니다.
오버로딩(Overloading), 오버라이딩(Overriding)을 사용합니다.
오버로딩이란 메소드의 이름은 같지만 파라미터를 다르게 받는것을 의미합니다.
오버라이딩은 부모 클래스에서 상속받은 메소드를 자식 클래스에서 재정의 해서 사용하는 것을 의미합니다.
<strong>👉상속성</strong>
부모 클래스를 자식 클래스에서 이어 받아 사용할수 있게 하고 부분적인 기능을 수정해서 사용할수 있게 하는 것입니다.</p>
</blockquote>
<h4 id="oop-5원칙solid">OOP 5원칙(SOLID)</h4>
<blockquote>
<p><strong>👉S (SRP : Single Responsibility Principle)</strong>
한 클래스는 하나의 책임만 가져야 한다.
<strong>👉O (OCP : Open/Closed Principle)</strong>
기존 클래스의 확장에는 열려있으나, 기존 클래스 변경에는 닫혀있어야 한다.
<strong>👉L (LSP : Liskov’s Substitution Principle)</strong>
프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다. 
쉽게 말하면 자식 클래스를 부모 클래스 자리에 넣어도 제대로 동작해야하는 것을 의미한다.
<strong>👉I (ISP : Interface Segregation Principle)</strong>
특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다. 
이것은 큰 인터페이스들을 작은 단위로 분리해서 꼭 필요한 메소드만 이용할수 있게하는 것이 핵심이다.
<strong>👉D (DIP : Dependency Inversion Principle)</strong>
추상화에 의존한다. 
구체화에 의존하면 안된다.
상위 클래스는 하위 클래스에 종속되면 안되는 원칙입니다.</p>
</blockquote>
<h3 id="3-함수형-프로그래밍">3. 함수형 프로그래밍</h3>
<hr>
<p>함수형 프로그래밍은 문제를 순수 함수로 해결하는 프로그래밍 기법입니다.
작은 문제를 해결하기 위해 함수를 작성하여 <strong>재사용성</strong>과 <strong>가독성</strong>을 높이고 <strong>유지보수를 용이</strong>하게 해줍니다.</p>
<p>함수형 프로그래밍은 아래와 같은 원칙이 있습니다.</p>
<blockquote>
<ul>
<li>프로그래밍은 입출력이 순수해야한다. (<strong>순수함수</strong>)</li>
<li>부작용이 없어야한다.<ul>
<li>함수와 데이터를 중심으로 생각한다.</li>
</ul>
</li>
</ul>
</blockquote>
<p> <strong>순수함수</strong>란 한개 이상의 파라미터를 받아서 파라미터만으로 결화물을 반환해주는 함수를 의미합니다.
부작용이 없다는 것은 원본 데이터는 불변(immutable)해야하는 특성입니다. 만약 변경되어야 한다면 새로운 객체를 생성해 변경된 값을 대입해서 변경해야 합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 자동완성]]></title>
            <link>https://velog.io/@co_mong/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%90%EB%8F%99%EC%99%84%EC%84%B1</link>
            <guid>https://velog.io/@co_mong/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%90%EB%8F%99%EC%99%84%EC%84%B1</guid>
            <pubDate>Fri, 29 Oct 2021 05:28:45 GMT</pubDate>
            <description><![CDATA[<h3 id="1-문제-설명">1. 문제 설명</h3>
<hr>
<p><img src="https://images.velog.io/images/co_mong/post/92cfb9f0-e07c-438d-9519-9e65b5992665/image.png" alt=""></p>
<ul>
<li>trie 구조를 사용하여 해결한다.</li>
<li>각각의 노드마다 하위 단어가 몇개인지 저장해준다.</li>
<li>하위 trie개수를 보고 더 탐색을 할지 말지 결정한다.<h3 id="2-풀이">2. 풀이</h3>
</li>
</ul>
<hr>
<ul>
<li>root를 [하위노드 개수,{자식노드}]의 구조로 생성해준다.
👉모든 노드는 아래의 구조로 생성한다.<pre><code class="language-python">root=[0,dict()]</code></pre>
</li>
<li>단어와 root를 파라미터로 받아서 trie를 생성해주는 make_trie 함수를 생성한다.<pre><code class="language-python">def make_trie(root,word):
  cur_node=root
  #단어를 순서대로 탐색
  for c in word:
      #만약 노드에 현재 알파벳이 존재하지 않으면 생성
      if c not in cur_node[1]:
          cur_node[1][c]=[0,dict()]
      #하위 노드개수+1
      cur_node[0]+=1
      #다음노드를 탐색하기 위해 현재노드를 다음노드로 변경해준다.
      cur_node=cur_node[1][c]
  #노드개수+1
  cur_node[0]+=1</code></pre>
</li>
<li>make_trie 함수를 사용해서 trie를 생성해준다.<pre><code class="language-python">for word in words:
  make_trie(root,word)</code></pre>
</li>
</ul>
<ul>
<li><p>생성된 trie를 탐색하는 search_target 함수를 생성해준다.</p>
<pre><code class="language-python">def search_target(root,word):
  ret=0
  cur_node=root
  #단어를 순서대로 탐색
  for c in word:
      #하위 노드가 없는 경우 탐색 횟수 반환
      if cur_node[0]==1:
          return ret
      #탐색횟수+1
      ret+=1
      #현재노드를 다음노드로 변경
      cur_node=cur_node[1][c]

  #단어 끝가지 탐색해야하는 경우
  return ret</code></pre>
</li>
<li><p>단어마다 탐색하면서 answer에 더해준다.</p>
<pre><code class="language-python">for word in words:
  answer += search_target(root,word)</code></pre>
</li>
</ul>
<h3 id="3-코드">3. 코드</h3>
<pre><code class="language-python">import sys
from collections import defaultdict
sys.setrecursionlimit(10**6)
def make_trie(root,word):
    cur_node=root
    for c in word:
        if c not in cur_node[1]:
            cur_node[1][c]=[0,dict()]

        cur_node[0]+=1
        cur_node=cur_node[1][c]
    cur_node[0]+=1
def search_target(root,word):
    ret=0
    cur_node=root

    for c in word:
        if cur_node[0]==1:
            return ret
        ret+=1
        cur_node=cur_node[1][c]

    return ret
def solution(words):
    answer = 0
    root=[0,dict()]

    for word in words:
        make_trie(root,word)
    for word in words:
        answer += search_target(root,word)

    return answer</code></pre>
<ul>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/17685">https://programmers.co.kr/learn/courses/30/lessons/17685</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 프렌즈4블록]]></title>
            <link>https://velog.io/@co_mong/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%94%84%EB%A0%8C%EC%A6%884%EB%B8%94%EB%A1%9D</link>
            <guid>https://velog.io/@co_mong/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%94%84%EB%A0%8C%EC%A6%884%EB%B8%94%EB%A1%9D</guid>
            <pubDate>Sun, 17 Oct 2021 09:18:24 GMT</pubDate>
            <description><![CDATA[<h3 id="1-문제-설명">1. 문제 설명</h3>
<hr>
<p><img src="https://images.velog.io/images/co_mong/post/2be2c985-8a1a-45a3-b1d3-a67ec19efff1/image.png" alt=""></p>
<ul>
<li>블록이 내려오는 부분을 위해 행과열을 바꿔줘야한다.</li>
<li>zip을 사용하여 rotate를 구현해야한다.</li>
<li>문자열을 사용해서 빈공간 만큼 블록을 내려주고 위에 빈공간을 만들어줘야한다.</li>
<li>set에 리스트를 넣기 위해서는 튜플로 변경해서 넣어준다.<h3 id="2-풀이">2. 풀이</h3>
</li>
</ul>
<hr>
<ul>
<li><p>행과 열을 바꿔주는 rotate메소드를 만들어주고 회전시킨다.
👉zip(*iterable)은 zip을 풀어주는 기능을 한다.</p>
<pre><code class="language-python">def rotate(grid):
  return list(map(list,zip(*grid)))</code></pre>
</li>
<li><p>더이상 지울수 없을 때까지 반복문을 돌면서 블록을 지워준다.</p>
<pre><code class="language-python">while True:
  result=remove_block()
  if not result:
      break</code></pre>
</li>
<li><p>블록을 지워주는 remove_block() 메소드를 만들어준다.</p>
</li>
<li><p>행,열을 탐색하면서 4칸이 같은 블록이면 remove_set에 행,열을 넣어준다.
👉행과열을 set에 저장하기 위해 튜플형식으로 값을 넣어준다.</p>
<pre><code class="language-python">for row in range(n-1):
  for col in range(m-1):
      if board[row][col] != &quot;&quot; and board[row][col]==board[row+1][col]==board[row][col+1]==board[row+1][col+1]:
          remove_set.add((row,col))
          remove_set.add((row+1,col))
          remove_set.add((row,col+1))
          remove_set.add((row+1,col+1))</code></pre>
</li>
<li><p>remove_set을 돌면서 해당 블록을 빈 블록으로 만들어준다.</p>
<pre><code class="language-python">for row,col in remove_set:
  board[row][col]=&quot;&quot;</code></pre>
</li>
<li><p>블록을 비웠으므로 블록을 내려주고 빈공간을 빈블록으로 채워주고 board와 지운블록의 개수를 반환한다.</p>
<pre><code class="language-python">for idx,row in enumerate(board):
  row=&quot;&quot;.join(row)
  board[idx]=[&quot;&quot;]*(m-len(row))+list(row)
return board,len(remove_set)</code></pre>
</li>
<li><p>반환받은 블록의 개수가 0개일 경우 반복문을 탈출하는 코드를 완성해준다.</p>
<pre><code class="language-python">while True:
  board,cnt=remove_block(board,n,m)

  if cnt&gt;0:
      answer+=cnt
  else:
      break</code></pre>
<h3 id="3-코드">3. 코드</h3>
<pre><code class="language-python">def rotate(grid):
  return list(map(list,zip(*grid)))
def remove_block(board,n,m):
  remove_set=set()

  for row in range(n-1):
      for col in range(m-1):
          if board[row][col] != &quot;&quot; and board[row][col]==board[row+1][col]==board[row][col+1]==board[row+1][col+1]:
              remove_set.add((row,col))
              remove_set.add((row+1,col))
              remove_set.add((row,col+1))
              remove_set.add((row+1,col+1))

  for row,col in remove_set:
      board[row][col]=&quot;&quot;
  for idx,row in enumerate(board):
      row=&quot;&quot;.join(row)
      board[idx]=[&quot;&quot;]*(m-len(row))+list(row)

  return board,len(remove_set)
def solution(m, n, board):
  answer = 0
  board=rotate(board)

  while True:
      board,cnt=remove_block(board,n,m)

      if cnt&gt;0:
          answer+=cnt
      else:
          break
  return answer</code></pre>
</li>
<li><p><a href="https://programmers.co.kr/learn/courses/30/lessons/17679">https://programmers.co.kr/learn/courses/30/lessons/17679</a></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] N-Queen]]></title>
            <link>https://velog.io/@co_mong/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-N-Queen</link>
            <guid>https://velog.io/@co_mong/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-N-Queen</guid>
            <pubDate>Sun, 17 Oct 2021 03:44:18 GMT</pubDate>
            <description><![CDATA[<h3 id="1-문제-설명">1. 문제 설명</h3>
<hr>
<p><img src="https://images.velog.io/images/co_mong/post/4099fa63-cfbc-4a91-9f15-a7a37c275e69/image.png" alt=""></p>
<h3 id="2-풀이">2. 풀이</h3>
<hr>
<ul>
<li><p>가장 먼저 각 행에 몇번째 열에 퀸을 놓았는지 판단하기 위한 리스트를 생성해 dfs()메소드에 넣어줍니다.</p>
<pre><code class="language-python">#dfs(리스트,현재 행,n)
dfs([0]*n,0,n)</code></pre>
</li>
<li><p>이 리스트와 DFS알고리즘을 사용하여 Queen을 놓을 위치를 탐색합니다.  </p>
</li>
<li><p>만약 마지막 행까지 탐색했다면 탐색을 종료주는 예외처리를 합니다. (마지막행까지 탐색했을때 1개의 경우의 수가 생기므로 1을 반환합니다.)  </p>
<pre><code class="language-python">if row == n:
  return 1</code></pre>
</li>
<li><p>마지막 행이 아닌경우 현재 행 몇번째 열에 Queen을 배치할지 for문을 사용해 탐색합니다.  </p>
<pre><code class="language-python">for col in range(n):
  queen[row] = col

  #배치가능한지 확인
  if is_valid(queen,row):    
      cnt+=dfs(queen,row+1,n)</code></pre>
</li>
<li><p>이제 현재 배치한 행,열이 적합한 위치인지 판별해 줍니다.</p>
<pre><code class="language-python">for r in range(row):
  #같은 열에 위치한 퀸이 있는지 판단
  #같은 대각선 상에 퀸이 있는지 판단
  if queen[row] == queen[r] or abs(queen[row]-queen[r]) == row-r:
      return False
  return True</code></pre>
</li>
<li><p>반환 결과가 True면 다음 행으로 진행하고 아니면 다른 열을 계속해서 탐색합니다.</p>
</li>
</ul>
<h3 id="3-코드">3. 코드</h3>
<hr>
<pre><code class="language-python">def is_valid(queen,row):
    for r in range(row):
        if queen[row] == queen[r] or abs(queen[row]-queen[r]) == row-r:
            return False
    return True
def dfs(queen,row,n):
    cnt = 0
    if row == n:
        return 1

    for col in range(n):
        queen[row] = col

        if is_valid(queen,row):    
            cnt+=dfs(queen,row+1,n)
    return cnt
def solution(n):
    return dfs([0]*n,0,n)</code></pre>
<ul>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/12952">https://programmers.co.kr/learn/courses/30/lessons/12952</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 외벽점검]]></title>
            <link>https://velog.io/@co_mong/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%99%B8%EB%B2%BD%EC%A0%90%EA%B2%80</link>
            <guid>https://velog.io/@co_mong/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%99%B8%EB%B2%BD%EC%A0%90%EA%B2%80</guid>
            <pubDate>Tue, 12 Oct 2021 06:50:40 GMT</pubDate>
            <description><![CDATA[<h3 id="문제-설명">문제 설명</h3>
<hr>
<p><img src="https://images.velog.io/images/co_mong/post/e7c410e5-00c2-4a46-a415-5350a249fe88/image.png" alt=""></p>
<h3 id="풀이">풀이</h3>
<hr>
<ul>
<li>반시계 방향으로 탐색하는 경우를 위해 weak리스트를 2배로 늘려준다.</li>
<li>순열을 사용해서 완점탐색을 구현한다.<pre><code class="language-python">from itertools import permutations
</code></pre>
</li>
</ul>
<p>def solution(n, weak, dist):
    answer = len(dist)+1
    len_weak=len(weak)
    #1.dist의 가능한 모든 순열 저장
    dist_comb=list(map(list,permutations(dist,len(dist))))</p>
<pre><code>#2.weak리스트 2배로 늘려주기
for i in range(len(weak)):
    weak.append(weak[i]+n)
#3.weak리스트에서 시작점을 정하기 위한 반복문
for start in range(len_weak):
    #4.start기준으로 weak길이만큼 리스트 생성
    weak_points = weak[start:start+len_weak]
    #5.친구 순열(dist_comb)를 탐색하면서 수리 가능한 경우 찾기
    for d in dist_comb:
        #6.사용한 친구수,현재 위치
        cnt=1
        cur_position=friends[0]+d[0]
        for weak_point in weak_points[1:]:
            #7.현재 위치보다 결함지점이 뒤에 있는 경우
            if weak_point&gt;cur_position:
                #8-1.정해진 친구 범위 벗어난 경우 탈출
                if cnt+1&gt;len(d):
                    cnt+=1
                    break
                #8-2.현재 위치 갱신
                cur_position=friend+d[cnt]
                cnt+=1
        #9.가장 작은 값으로 answer 갱신
        answer = min(answer,cnt)
if answer&gt;len(dist):
    answer=-1

return answer</code></pre><p>```
[1] 완전탐색을 위해 친구들의 배치를 permutation을 사용해 순열을 구해준다.
[2] 반시계 방향 탐색을 고려하기 위해 weak리스트를 2배로 늘려준다.
[3] weak리스트 시작점을 기준으로 반복 탐색
[4] 시작점을 기준으로 weak길이만큼 새로운 weak_points리스트 생성
[5] 4에서 구한 새로운 weak_points에 가능한 모든 친구 순열을 사용해 탐색
[6] 사용한 친구수와 현재 위치를 기억하기 위한 변수를 생성
[7] 만약 weak_point가 현재 위치보다 뒤에 있으면 새로운 친구를 추가해줘야 한다
[8-1] 정해진 친구들로만 모든 weak_point를 탐색 못하는 경우 반복문 탈출
[8-2] 탐색 가능하면 현재위치를 갱신하고 사용한 친구의 수+1
[9] answer을 가장 작은 값으로 갱신한다. </p>
<ul>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/60062">https://programmers.co.kr/learn/courses/30/lessons/60062</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] SQL연습-2]]></title>
            <link>https://velog.io/@co_mong/SQL-SQL%EC%97%B0%EC%8A%B5-2</link>
            <guid>https://velog.io/@co_mong/SQL-SQL%EC%97%B0%EC%8A%B5-2</guid>
            <pubDate>Thu, 02 Sep 2021 13:35:22 GMT</pubDate>
            <description><![CDATA[<h3 id="1중성화-여부-파악하기">1.중성화 여부 파악하기</h3>
<pre><code class="language-sql">SELECT ANIMAL_ID,NAME,CASE WHEN SEX_UPON_INTAKE LIKE &quot;Neutered%&quot; OR SEX_UPON_INTAKE LIKE &quot;Spayed%&quot;
                      THEN &#39;O&#39; ELSE &#39;X&#39; END AS &#39;중성화&#39;
FROM ANIMAL_INS;</code></pre>
<ul>
<li><code>CASE</code>를 사용하여 해결</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/59409">https://programmers.co.kr/learn/courses/30/lessons/59409</a></li>
</ul>
<hr>
<h3 id="2헤비-유저가-소유한-장소">2.헤비 유저가 소유한 장소</h3>
<pre><code class="language-sql">SELECT ID,NAME,HOST_ID
FROM PLACES
WHERE HOST_ID IN (
    SELECT HOST_ID
    FROM PLACES
    GROUP BY HOST_ID
    HAVING COUNT(*)&gt;=2
)
ORDER BY ID;</code></pre>
<ul>
<li><code>서브쿼리</code>,<code>ORDER BY</code>를 사용하여 해결</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/77487">https://programmers.co.kr/learn/courses/30/lessons/77487</a></li>
</ul>
<hr>
<h3 id="3datetime에서-date로-형-변환">3.DATETIME에서 DATE로 형 변환</h3>
<pre><code class="language-sql">SELECT ANIMAL_ID,NAME,DATE_FORMAT(DATETIME,&#39;%Y-%m-%d&#39;) as 날짜
FROM ANIMAL_INS
ORDER BY ANIMAL_ID;</code></pre>
<ul>
<li><code>DATE_FORMAT</code>,<code>ORDER BY</code>를 사용하여 해결</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/59414">https://programmers.co.kr/learn/courses/30/lessons/59414</a></li>
<li>날짜 관련 함수</li>
</ul>
<table>
<thead>
<tr>
<th align="center">함수</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">SYSDATE()</td>
<td align="center">현재 날짜와 시간</td>
</tr>
<tr>
<td align="center">CURRENT_DATE</td>
<td align="center">현재 날짜</td>
</tr>
<tr>
<td align="center">NOW()</td>
<td align="center">현재 날짜와 시간</td>
</tr>
<tr>
<td align="center">DATE_FORMAT(데이터,FORMAT)</td>
<td align="center">데이터를 FORMAT형태로 변환</td>
</tr>
</tbody></table>
<ul>
<li>FORMAT 형식</li>
</ul>
<table>
<thead>
<tr>
<th align="center">함수</th>
<th align="center">설명</th>
<th align="center">예시</th>
</tr>
</thead>
<tbody><tr>
<td align="center">%Y</td>
<td align="center">4자리 년도</td>
<td align="center">1995</td>
</tr>
<tr>
<td align="center">%y</td>
<td align="center">2자리 년도</td>
<td align="center">95</td>
</tr>
<tr>
<td align="center">%m</td>
<td align="center">2자리 월</td>
<td align="center">01</td>
</tr>
<tr>
<td align="center">%c</td>
<td align="center">1자리 월</td>
<td align="center">1</td>
</tr>
<tr>
<td align="center">%M</td>
<td align="center">영문 월</td>
<td align="center">January</td>
</tr>
<tr>
<td align="center">%b</td>
<td align="center">영문 월(줄임)</td>
<td align="center">Jan</td>
</tr>
<tr>
<td align="center">%d</td>
<td align="center">2자리 일</td>
<td align="center">08</td>
</tr>
<tr>
<td align="center">%e</td>
<td align="center">1자리 일</td>
<td align="center">8</td>
</tr>
<tr>
<td align="center">%D</td>
<td align="center">숫자+영문 일</td>
<td align="center">8th</td>
</tr>
</tbody></table>
<hr>
<h3 id="4오랜-기간-보호한-동물2">4.오랜 기간 보호한 동물(2)</h3>
<pre><code class="language-sql">SELECT I.ANIMAL_ID,I.NAME
FROM ANIMAL_INS as I,ANIMAL_OUTS as O
WHERE I.ANIMAL_ID = O.ANIMAL_ID
ORDER BY O.DATETIME-I.DATETIME DESC
LIMIT 2;</code></pre>
<ul>
<li><code>ORDER BY</code>,<code>LIMIT</code>를 사용하여 해결</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/59411">https://programmers.co.kr/learn/courses/30/lessons/59411</a></li>
</ul>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] SQL 연습]]></title>
            <link>https://velog.io/@co_mong/SQL-SQL-%EC%97%B0%EC%8A%B5</link>
            <guid>https://velog.io/@co_mong/SQL-SQL-%EC%97%B0%EC%8A%B5</guid>
            <pubDate>Sun, 22 Aug 2021 03:33:20 GMT</pubDate>
            <description><![CDATA[<h3 id="1없어진-기록-찾기">1.없어진 기록 찾기</h3>
<pre><code class="language-sql">SELECT ANIMAL_ID,NAME
FROM ANIMAL_OUTS
WHERE ANIMAL_ID NOT IN (
    SELECT ANIMAL_ID
    FROM ANIMAL_INS
)
ORDER BY ANIMAL_ID ASC;</code></pre>
<ul>
<li><code>서브쿼리</code>, <code>NOT IN</code>, <code>ORDER BY</code>를 사용하여 해결</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/59042">https://programmers.co.kr/learn/courses/30/lessons/59042</a></li>
</ul>
<hr>
<h3 id="2우유와-요거트가-담긴-장바구니">2.우유와 요거트가 담긴 장바구니</h3>
<pre><code class="language-sql">SELECT A.CART_ID
FROM (SELECT CART_ID FROM CART_PRODUCTS WHERE NAME = &#39;Yogurt&#39;) AS A,
     (SELECT CART_ID FROM CART_PRODUCTS WHERE NAME = &#39;Milk&#39;) AS B
WHERE A.CART_ID = B.CART_ID</code></pre>
<ul>
<li>FROM 절에 <code>서브쿼리</code> 사용하여 해결</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/62284">https://programmers.co.kr/learn/courses/30/lessons/62284</a></li>
</ul>
<hr>
<h3 id="3있었는데요-없었습니다">3.있었는데요 없었습니다</h3>
<pre><code class="language-sql">SELECT ANIMAL_INS.ANIMAL_ID,ANIMAL_INS.NAME
FROM ANIMAL_INS,ANIMAL_OUTS
WHERE ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID AND ANIMAL_INS.DATETIME &gt; ANIMAL_OUTS.DATETIME
ORDER BY ANIMAL_INS.DATETIME ASC;</code></pre>
<ul>
<li><code>다중조건</code>, <code>ORDER BY</code> 사용하여 해결</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/59043">https://programmers.co.kr/learn/courses/30/lessons/59043</a></li>
</ul>
<hr>
<h3 id="4입양-시각-구하기1">4.입양 시각 구하기(1)</h3>
<pre><code class="language-sql">SELECT HOUR(DATETIME) AS &#39;HOUR&#39;, COUNT(*) AS &#39;COUNT&#39;
FROM ANIMAL_OUTS
WHERE HOUR(DATETIME) BETWEEN 9 AND 20
GROUP BY HOUR
ORDER BY HOUR;</code></pre>
<ul>
<li><code>BETWEEN</code>, <code>HOUR</code>, <code>GROUP BY</code> 사용하여 해결</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/59412">https://programmers.co.kr/learn/courses/30/lessons/59412</a></li>
</ul>
<hr>
<h3 id="span-stylecolor-red5입양-시각-구하기2span"><span style="color: red">5.입양 시각 구하기(2)</span></h3>
<pre><code class="language-sql">SET @hour = -1;
SELECT (@hour := @hour+1) AS HOUR, 
       (SELECT COUNT(*) FROM ANIMAL_OUTS WHERE HOUR(DATETIME) = @hour) AS COUNT
FROM ANIMAL_OUTS
WHERE @hour &lt; 23
ORDER BY HOUR;</code></pre>
<ul>
<li><code>서브쿼리</code>, <code>SQL 변수(@VAR)</code>, <code>:= 대입연산자</code> 사용하여 해결</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/59413">https://programmers.co.kr/learn/courses/30/lessons/59413</a></li>
</ul>
<hr>
<h3 id="6이름에-el이-들어가는-동물-찾기">6.이름에 el이 들어가는 동물 찾기</h3>
<pre><code class="language-sql">SELECT ANIMAL_ID,NAME
FROM ANIMAL_INS
WHERE ANIMAL_TYPE = &#39;Dog&#39; AND NAME LIKE &#39;%EL%&#39;
ORDER BY NAME ASC;</code></pre>
<ul>
<li><code>Like</code>, <code>%</code>, <code>-</code> 사용하여 해결</li>
<li><code>%</code> = 여러개의 문자 매칭</li>
<li><code>-</code> = 한개의 문자 매칭</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/59047">https://programmers.co.kr/learn/courses/30/lessons/59047</a></li>
</ul>
<hr>
<h3 id="7보호소에서-중성화한-동물">7.보호소에서 중성화한 동물</h3>
<pre><code class="language-sql">SELECT A.ANIMAL_ID,A.ANIMAL_TYPE,A.NAME
FROM ANIMAL_INS AS A,ANIMAL_OUTS AS B
WHERE A.SEX_UPON_INTAKE LIKE &#39;Intact%&#39;
      AND A.ANIMAL_ID = B.ANIMAL_ID
      AND (B.SEX_UPON_OUTCOME LIKE &#39;Neutered%&#39; OR B.SEX_UPON_OUTCOME LIKE &#39;Spayed%&#39;)
ORDER BY A.ANIMAL_ID;</code></pre>
<ul>
<li><code>join</code>, <code>%</code>, <code>-</code> 사용하여 해결</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/59045">https://programmers.co.kr/learn/courses/30/lessons/59045</a></li>
</ul>
<hr>
<h3 id="8동물-수-구하기">8.동물 수 구하기</h3>
<pre><code class="language-sql">SELECT COUNT(*) AS &#39;COUNT&#39;
FROM ANIMAL_INS;</code></pre>
<ul>
<li><code>COUNT</code> 사용하여 해결</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/59406">https://programmers.co.kr/learn/courses/30/lessons/59406</a></li>
</ul>
<hr>
<h3 id="9null-처리하기">9.NULL 처리하기</h3>
<pre><code class="language-sql">SELECT ANIMAL_TYPE,
       CASE WHEN NAME IS NULL THEN &#39;No name&#39; ELSE NAME END AS &#39;NAME&#39;,
       SEX_UPON_INTAKE
FROM ANIMAL_INS;</code></pre>
<ul>
<li><code>CASE</code> 사용하여 해결</li>
<li><code>NULL</code>은 <code>=</code>로 구분 못하고 <code>IS</code>를 사용해야한다.</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/59406">https://programmers.co.kr/learn/courses/30/lessons/59406</a></li>
</ul>
<hr>
<h3 id="10오랜-기간-보호한-동물1">10.오랜 기간 보호한 동물(1)</h3>
<pre><code class="language-sql">SELECT NAME,DATETIME
FROM ANIMAL_INS
WHERE ANIMAL_ID NOT IN (
    SELECT ANIMAL_ID
    FROM ANIMAL_OUTS
)
ORDER BY DATETIME
LIMIT 3</code></pre>
<ul>
<li><code>서브쿼리</code>,<code>ORDER BY</code>, <code>LIMIT</code> 사용하여 해결</li>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/59044">https://programmers.co.kr/learn/courses/30/lessons/59044</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] Promise]]></title>
            <link>https://velog.io/@co_mong/JS-Promise</link>
            <guid>https://velog.io/@co_mong/JS-Promise</guid>
            <pubDate>Sun, 15 Aug 2021 07:23:24 GMT</pubDate>
            <description><![CDATA[<h1 id="javascript-promise">Javascript Promise</h1>
<p>Promise는 비동기 연산이 종료된 이후 <strong><code>결과값</code></strong> 또는 <strong><code>실패 이유</code></strong>를 반환합니다. 비동기 연산을 동기 연산처럼 사용 가능합니다. 비동기 연산이기 때문에 바로 값을 반환하지 않고, 미리 프로미스를 반환해서 연산이 완료된 시점에 결과를 반환합니다.</p>
<h2 id="1-promise-상태">1. Promise 상태</h2>
<p>Promise에는 3가지 상태가 있습니다.</p>
<ul>
<li>대기(pending) : 아직 연산 수행 전 대기 상태</li>
<li>이행(fullfilled) : 연산이 성공하여 완료된 상태</li>
<li>거부(rejected) : 연산이 실패한 상태</li>
</ul>
<p><img src="https://images.velog.io/images/co_mong/post/085e1a2b-ed27-4c17-afb2-f7f72a04394b/image.png" alt=""></p>
<h2 id="2-promise-메소드">2. Promise 메소드</h2>
<ul>
<li><strong>Promise.all(iterable)</strong>
iterable 내의 모든 프로미스가 이행한 뒤 이행하고, 어떤 프로미스가 거부하면 즉시 거부하는 프로미스를 반환합니다. 이 메서드는 여러 프로미스의 결과를 한번에 반환하지만 순서를 보장하지 않습니다.</li>
<li><strong>Promise.race(iterable)</strong>
iterable 내의 어떤 프로미스가 이행하거나 거부하는 즉시 스스로 이행하거나 거부하는 프로미스를 반환합니다. 이행 값이나 거부 이유는 원 프로미스의 값이나 이유를 그대로 사용합니다.</li>
<li><strong>Promise.reject()</strong>
주어진 이유로 거부하는 Promise 객체를 반환합니다.</li>
<li><strong>Promise.resolve()</strong>
주어진 값으로 이행하는 Promise 객체를 반환합니다. 값이 then 가능한 (즉, then 메서드가 있는) 경우, 반환된 프로미스는 then 메서드를 따라가고 마지막 상태를 취합니다. 그렇지 않은 경우 반환된 프로미스는 주어진 값으로 이행합니다. 어떤 값이 프로미스인지 아닌지 알 수 없는 경우, Promise.resolve(value) 후 반환값을 프로미스로 처리할 수 있습니다.</li>
</ul>
<h2 id="3-promise-예제">3. Promise 예제</h2>
<h3 id="31-기본-예제">3.1 기본 예제</h3>
<pre><code class="language-javascript">var myPromise = new Promise((resolve,reject)=&gt;{
    setTimeout(()=&gt;{
        resolve(&quot;success!&quot;);
    },1000);
});

myPromise
.then((message)=&gt;{
    console.log(&quot;First Promise &quot;+message);
});
var arr = [1,2,3,4,5,6,7,8,9,10];
for(var i of arr){
    console.log(i);
}
//1,2,3,4,5,6,7,8,9,10,First Promise success!</code></pre>
<p>위의 예제에서는 1초 뒤에 success! 메세지를 반환하기 때문에 반복문이 먼저 실행되고 .then이 실행되는 것을 볼수 있습니다.</p>
<h3 id="32-asyncawait">3.2 async/await</h3>
<p>이때 for문을 먼저 실행시키려면 ES7부터 추가된 async/await 문법을 사용하면 됩니다.
async/await 문법을 사용하면 비동기 코드를 동기코드 처럼 사용할수 있습니다.</p>
<pre><code class="language-javascript">var myPromise = new Promise((resolve,reject)=&gt;{
    setTimeout(()=&gt;{
        resolve(&quot;success!&quot;);
    },1000);
});
const printMessage = async() =&gt; {
    const message = await myPromise;
    console.log(&quot;First Promise &quot;+message);

    myPromise
    .then((m)=&gt;{
        console.log(&quot;second Promise &quot;+m)    
    })

    var arr = [1,2,3,4,5,6,7,8,9,10];
    for(var i of arr){
        console.log(i);
    }
}
printMessage();
//First Promise success!,1,2,3,4,5,6,7,8,9,10,second Promise success!</code></pre>
<p>이와 같이 async 함수에 await을 붙이면 await 뒤의 Promise가 반환되기 전까지 다음 코드로 진행되지 않는 것을 확인할수 있습니다.
.then 과 async/await 실행 시간을 랜덤으로 주고 실행해보면 더욱 확실하게 비교해 볼수 있습니다.</p>
<pre><code class="language-javascript">var arr = [1,2,3,4,5,6,7,8,9,10];
var myPromise = (num) =&gt; new Promise((resolve,reject)=&gt;{
    const time = Math.random();
    setTimeout(()=&gt;{
        resolve(num);
    },Number(time*100));
});

const syncMessage = async() =&gt; {
    for(var num of arr){
        const message = await myPromise(num);
        console.log(message);
    }
}
const asyncMessage = () =&gt; {
    for(var num of arr){
        myPromise(num)
        .then((message)=&gt;{
            console.log(&quot;async&quot;,message);
        });
    }
}
syncMessage();
asyncMessage();</code></pre>
<hr>
<p><strong>참고자료</strong></p>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise</a></li>
<li><a href="https://developer.mozilla.org/ko/docs/Learn/JavaScript/Asynchronous/Async_await">https://developer.mozilla.org/ko/docs/Learn/JavaScript/Asynchronous/Async_await</a></li>
<li><a href="https://developers.google.com/web/fundamentals/primers/async-functions?hl=ko">https://developers.google.com/web/fundamentals/primers/async-functions?hl=ko</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 백틱(``)]]></title>
            <link>https://velog.io/@co_mong/JS-%EB%B0%B1%ED%8B%B1</link>
            <guid>https://velog.io/@co_mong/JS-%EB%B0%B1%ED%8B%B1</guid>
            <pubDate>Tue, 27 Jul 2021 14:46:54 GMT</pubDate>
            <description><![CDATA[<h2 id="1-템플릿-리터럴">1. 템플릿 리터럴</h2>
<p>템플릿 리터럴이란 <code>백틱(``)</code>을 의미합니다.</p>
<p>기존에는 템플릿 스트링이라고 불리던 것이 ES6이후 템플릿 리터럴이라고 불리게 되었습니다.</p>
<p>템플릿 리터럴은 문자열과 변수를 함께 사용하기 위해 필요합니다.
템플릿 리터럴이 없을때는 아래와 같이 문자열과 변수를 사용하였습니다.</p>
<pre><code class="language-javascript">var age = 99;
console.log(&quot;age : &quot;+age);
//age : 99</code></pre>
<p>하지만 템플릿 리터럴을 사용하면 아래와 같이 사용할수 있고 문자열 줄바꿈도 가능합니다.</p>
<pre><code class="language-javascript">var age = 99;
console.log(`age :
             ${age}`);
//age : 
//             99</code></pre>
<h2 id="2-템플릿-태그">2. 템플릿 태그</h2>
<p>탬플릿 태그란 함수에 인자를 넘겨줄때 <code>()</code>로 넘겨주는 것이 아니라 <code>백틱``</code>으로 감싸서 넘겨주는 방식을 의미합니다.</p>
<pre><code class="language-javascript">function func(str,...rest){
    console.log(str);
    if(rest[0] === rest[1]){
        console.log(`${rest[0]} == ${rest[1]}`);
    }else{
        console.log(`${rest[0]} != ${rest[1]}`);
    }
    console.log(rest[2]);
}

func`co_mong${99}${99}age${true}`;
//[&quot;co_mong&quot;,&quot;&quot;,&quot;age&quot;,&quot;&quot;]
//99 == 99
//true</code></pre>
<p>위의 경우와 같이 템플릿 태그를 사용하면 함수에 인자를 좀더 유연하게 넘겨주는 것이 가능합니다.</p>
<p>인자에서 문자열의 경우 str에 저장되는데 문자열간 <code>${}</code>가 있는 경우 빈 문자열로 치환되어 저장됩니다.
그리고 <code>${}</code>로 감싸진 나머지 인자의 경우 rest에 저장됩니다.</p>
<p><del>아직 다 이해 못함 공부가 더 필요할 듯😡</del></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 불변성(Immutability)]]></title>
            <link>https://velog.io/@co_mong/JS-%EB%B6%88%EB%B3%80%EC%84%B1Immutability</link>
            <guid>https://velog.io/@co_mong/JS-%EB%B6%88%EB%B3%80%EC%84%B1Immutability</guid>
            <pubDate>Mon, 26 Jul 2021 01:48:53 GMT</pubDate>
            <description><![CDATA[<h1 id="javascript-불변성">Javascript 불변성</h1>
<p>자바스크립트에서 불변성이란 객체가 생성된 이후 그 상태를 변경할 수 없는 것을 의미합니다.
여기서 상태를 변경할 수 있는 것과 값을 재할당하는 것은 다르다는 것을 알아야합니다.</p>
<pre><code class="language-javascript">let a = 10;
let b = a;
a = 20;
console.log(a,b); //20 10</code></pre>
<p>위의 코드는 a에 10을 할당하고 b를 a가 가리키는 주소를 가리킵니다.
이때 a의 값을 20으로 변경시켜줍니다.</p>
<p>만약 값을 직접 변경하는 것이라면 a와 b가 둘다 20을 출력해야합니다.</p>
<p>하지만 자바스크립트에서 <code>Number</code>값은 불변성을 유지하기 때문에 새롭게 20이라는 값을 가지는 주소를 a에 할당하게 되기 때문에 위와 같은 결과가 나오게 됩니다.
<img src="https://images.velog.io/images/co_mong/post/f2912982-427e-4b48-b365-5d4c31188ed0/%EC%A0%9C%EB%AA%A9%20%EC%97%86%EC%9D%8C.png" alt=""></p>
<h2 id="1-immutable-vs-mutable">1. immutable vs mutable</h2>
<p>자바스크립트에서는 불변성을 유지하는 값들과 그렇지 않은 값들이 나누어져 있다.</p>
<p><code>Boolean</code>, <code>Number</code>, <code>String</code>, <code>null</code>, <code>undefined</code>, <code>Symbol</code>과 같은 타입들은 불변성을 유지하는 타입들이고 <code>Object</code>타입들은 변경가능한 값들입니다.</p>
<p>이 말은 객체는 객체 내부의 값을 변경하면 객체를 참조하고 있는 다른 값들도 다 같이 변경된다는 의미입니다.</p>
<pre><code class="language-javascript">var coke = {
    name: &#39;coca&#39;,
    price: 2980,
}
var new_coke = coke;
coke.name = &#39;pepsi&#39;;
console.log(coke.name,new_coke.name);//&#39;pepsi&#39; &#39;pepsi&#39;</code></pre>
<p>위와 같이 coke의 name값을 변경했는데 new_coke의 name까지 한번에 변경된 것을 볼 수 있습니다.</p>
<h2 id="2-객체의-불변성-지키기">2. 객체의 불변성 지키기</h2>
<h3 id="21-스프레드-문법-사용">2.1 스프레드 문법 사용</h3>
<pre><code class="language-javascript">var coke = {
    name: &#39;coca&#39;,
    price: 2980,
}
var new_coke = {...coke};
coke.name = &#39;pepsi&#39;;
console.log(coke.name,new_coke.name);//&#39;pepsi&#39; &#39;coca&#39;</code></pre>
<p>스프레드 문법을 사용하여 객체를 복사해야지 객체가 불변성을 유지할 수 있습니다. 
하지만 스프레드 문법은 1레벨 깊이에서만 유효하게 동작하기 때문에 객체 내부의 객체의 불변성까지는 유지할수 없습니다.</p>
<pre><code class="language-javascript">var coke = {
    name: &#39;coca&#39;,
    fake: {
        name: &#39;pepsi&#39;,
    }
}
var new_coke = {...coke};
coke.fake.name = &#39;coca zero&#39;;
console.log(coke.fake.name,new_coke.fake.name);
//&#39;coca zero&#39; &#39;coca zero&#39;</code></pre>
<p>만약 레벨2 객체까지 불변성을 유지해주려면 아래와 같이 별도의 변수에 값을 재할당하고 넣어주는 번거러운 과정을 거쳐야 합니다.</p>
<pre><code class="language-javascript">const coke = {
    name: &#39;coca&#39;,
    fake: {
        name: &#39;pepsi&#39;,
    }
}
const new_fake = {...coke.fake};
const new_coke = {...coke};
new_coke.fake = new_fake;
coke.fake.name = &#39;coca zero&#39;;
console.log(coke.fake.name,new_coke.fake.name);
//&#39;coca zero&#39; &#39;pepsi&#39;</code></pre>
<h3 id="22-immer">2.2 immer</h3>
<p>불변성을 유지하기 위해 복잡한 과정없이 <code>immer</code>라이브러리를 사용하면 간단하게 불변성을 유지할 수 있습니다.</p>
<ul>
<li>설치
<code>npm i immer</code></li>
<li>import
<code>import produce from &#39;immer&#39;</code></li>
<li>사용방법<pre><code class="language-javascript">import produce from &#39;immer&#39;;
const coke = {
  name: &#39;coca&#39;,
  fake: {
      name: &#39;pepsi&#39;,
  }
}
</code></pre>
</li>
</ul>
<p>const new_coke = produce(coke, (draft) =&gt; {
    draft.name = &#39;pepsi&#39;;
    draft.fake.name = &#39;coca&#39;;
});
console.log(coke.name,coke.fake.name);
console.log(new_coke.name,new_coke.fake.name);</p>
<p>//&quot;coca&quot; &quot;pepsi&quot;
//&quot;pepsi&quot; &quot;coca&quot;</p>
<p>```</p>
<p><strong>결론 : immer 쓰자</strong></p>
<hr>
<p><strong>참고자료</strong></p>
<p><a href="https://poiemaweb.com/js-immutability">https://poiemaweb.com/js-immutability</a>
<a href="https://junwoo45.github.io/2019-11-04-memory_model/">https://junwoo45.github.io/2019-11-04-memory_model/</a>
<a href="https://github.com/immerjs/immer">https://github.com/immerjs/immer</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 구조 분해 할당]]></title>
            <link>https://velog.io/@co_mong/JS-%EA%B5%AC%EC%A1%B0-%EB%B6%84%ED%95%B4-%ED%95%A0%EB%8B%B9</link>
            <guid>https://velog.io/@co_mong/JS-%EA%B5%AC%EC%A1%B0-%EB%B6%84%ED%95%B4-%ED%95%A0%EB%8B%B9</guid>
            <pubDate>Sun, 25 Jul 2021 03:26:58 GMT</pubDate>
            <description><![CDATA[<h1 id="구조-분해-할당">구조 분해 할당</h1>
<p>자바스크립트에서 구조 분해 할당이란 <code>객체,배열,모듈</code>등을 변수로 분해해서 할당하는 것을 의미합니다.
이 방법은 <code>객체,배열,모듈</code>의 크기가 크고 특정 값만을 사용하기 원할 때 유용하게 사용할수 있습니다.</p>
<h2 id="1-배열-분해">1. 배열 분해</h2>
<h3 id="11-일반적인-배열-분해-방법">1.1 일반적인 배열 분해 방법</h3>
<p>구조 분해를 사용해서 배열의 값을 할당하면 아래와 같이 나오게 됩니다.</p>
<pre><code class="language-javascript">const name = [&quot;co&quot;,&quot;mong&quot;];
const [first_name,second_name] = name;
console.log(first_name,second_name);//co mong</code></pre>
<p>배열 값의 개수보다 많은 변수에 할당하면 값이 할당되지 않은 변수는 <code>undefined</code>가 됩니다.</p>
<p>만약 배열에서 중간 값을 제외하고 값을 분해 할당하고 싶다면 <code>쉼표(,)</code>로 중간값을 비워준 다음에 값을 할당하면 됩니다.</p>
<pre><code class="language-javascript">const name = [&quot;co&quot;,&quot;mong&quot;,&quot;hola&quot;];
const [first_name,,hello] = name;
console.log(first_name,hello);//co hola</code></pre>
<h3 id="12-rest-문법을-사용한-구조-분해">1.2 rest(...) 문법을 사용한 구조 분해</h3>
<p><code>rest</code> 문법은 말 그대로 나머지 요소들을 가지고 올때 사용합니다.</p>
<p>만약 배열의 크기가 클 경우 특정 값들만 변수에 할당하고 나머지 값들은 하나의 변수에 같이 저장하고 싶은 경우 <code>...문법</code>을 사용해서 구조분해 하면 됩니다.</p>
<pre><code class="language-javascript">const name = [&quot;co&quot;,&quot;mong&quot;,&quot;hola&quot;,&quot;cola&quot;,&quot;coca cola&quot;];
const [first_name,second_name,...coke] = name;
console.log(first_name,second_name);//co hola
console.log(coke); //[&quot;hola&quot;, &quot;cola&quot;, &quot;coca cola&quot;]</code></pre>
<p>이때 <code>rest</code>는 가장 뒤쪽에 위치시켜야 합니다.</p>
<h2 id="2-객체-분해">2. 객체 분해</h2>
<p>배열 뿐만 아니라 객체 또한 구조 분해 할당으로 분해 가능합니다.</p>
<h3 id="21-일반적인-객체-분해-방법">2.1 일반적인 객체 분해 방법</h3>
<p>객체는 배열과 다르게 프로퍼티 키(key)값을 사용해서 구조 분해가 가능합니다. 이 방법은 키 값들의 순서를 바꿔도 해당되는 키 값들이 할당됩니다.</p>
<pre><code class="language-javascript">const name = {
  first_name:&quot;co&quot;,
  second_name:&quot;mong&quot;,
};
const {second_name,first_name} = name;
console.log(first_name,second_name);//co mong</code></pre>
<p>만약 프로퍼티의 키 값과 다른 이름의 변수에 저장하고 싶다면 아래와 같은 방법을 사용하여 저장할수 있습니다.</p>
<pre><code class="language-javascript">const name = {
  first_name:&quot;co&quot;,
  second_name:&quot;mong&quot;,
};
const {second_name:s,first_name:f} = name;
console.log(f,s);//co mong</code></pre>
<h3 id="22-rest-문법을-사용한-구조-분해">2.2 rest(...) 문법을 사용한 구조 분해</h3>
<p>객체 또한 배열과 마찬가지로 <code>rest</code>문법을 사용해서 구조 분해가 가능합니다.</p>
<pre><code class="language-javascript">const name = {
  first_name:&quot;co&quot;,
  second_name:&quot;mong&quot;,
  coke:&#39;coca&#39;,
  non_coke:&#39;pepsi&#39;,
};
const {first_name,second_name,...coke} = name;
console.log(first_name,second_name);//co mong
console.log(coke);//{coke: &quot;coca&quot;, non_coke: &quot;pepsi&quot;}</code></pre>
<p>위처럼 나머지 프로퍼티들은 객체의 형태로 변수에 저장되게 됩니다.</p>
<h2 id="3-스프레드spread-문법">3. 스프레드(Spread) 문법</h2>
<p><code>스프레드(rest)</code>문법 또한 <code>rest</code>와 마찬가지로 ES6에서 추가된 문법이고 형태가 (...)로 같습니다.
<code>스프레드</code>는 단어 의미 그대로 펼치는 기능을 합니다. </p>
<p>예를 들어 특정 객체나 배열의 값을 기존의 객체에 추가하고 싶을 때 이 기능을 사용합니다.</p>
<pre><code class="language-javascript">const name = {
  first_name:&quot;co&quot;,
  second_name:&quot;mong&quot;,
};
const coke = {
  ...name,
  coke:&#39;coca&#39;,
  non_coke:&#39;pepsi&#39;,
}
coke.second_name = &#39;ca&#39;;
console.log(name);
//{first_name: &quot;co&quot;, second_name: &quot;mong&quot;}
console.log(coke);
//{first_name: &quot;co&quot;, second_name: &quot;mong&quot;, coke: &quot;coca&quot;, non_coke: &quot;pepsi&quot;}</code></pre>
<p>위 처럼 기존의 객체에는 영향을 주지 않으면서 값들을 가져올수 있습니다.</p>
<pre><code class="language-javascript">const arr1 = [1,2];
const arr2 = [...arr1,3,4];
arr1[0] = 0;
console.log(arr1); //[0, 2]
console.log(arr2); //[1, 2, 3, 4]</code></pre>
<p>객체와 마찬가지로 배열 또한 스프레드 기능을 사용할 수 있습니다.</p>
<hr>
<p><strong>참고자료</strong></p>
<p><a href="https://ko.javascript.info/destructuring-assignment">https://ko.javascript.info/destructuring-assignment</a>
<a href="https://learnjs.vlpt.us/useful/07-spread-and-rest.html">https://learnjs.vlpt.us/useful/07-spread-and-rest.html</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 객체]]></title>
            <link>https://velog.io/@co_mong/JS-%EA%B0%9D%EC%B2%B4</link>
            <guid>https://velog.io/@co_mong/JS-%EA%B0%9D%EC%B2%B4</guid>
            <pubDate>Sat, 24 Jul 2021 02:52:19 GMT</pubDate>
            <description><![CDATA[<h1 id="javascript-객체">Javascript 객체</h1>
<p>자바스크립트는 객체 기반의 스크립트 언어이고 자바스크립트에서 함수, 배열들은 모두 객체입니다.
자바스크립트의 객체는 키(Key)/값(Value)로 구성되어있는 프로퍼티(Property)들의 집합입니다.</p>
<p>프로퍼티란 객체내의 속성들을 의미하고 프로퍼티 값으로 일반 변수나 함수들이 올 수 있습니다.
그리고 프로퍼티 값이 함수이면 메소드라고 부르게 됩니다.</p>
<p>또한 자바스크립트는 객체지향 상속 구현을 위해 <code>프로토타입(Prototype)</code>이라고 불리는 객체의 프로퍼티와 메소드를 상속받습니다.</p>
<pre><code class="language-javascript">var dog = {
    name: &#39;Dazzi&#39;,          //=&gt;프로퍼티
    sayDa: function(){      //=&gt;메소드
        console.log(&quot;zzi&quot;); 
    }
};</code></pre>
<h2 id="1객체-생성-방법">1.객체 생성 방법</h2>
<h3 id="11-객체-리터럴">1.1 객체 리터럴</h3>
<p>객체 리터럴 방식은 중괄호({})를 사용해서 객체를 생성하는 방식으로 주로 사용되는 방식입니다.
중괄호 내에 한개 이상의 프로퍼티를 작성한채로 생성하면 프로퍼티가 추가된 채로 객체가 생성됩니다. 만약 프로퍼티를 작성하지 않으면 빈 객체가 생성됩니다.</p>
<pre><code class="language-javascript">var dog = {
    name: &#39;Dazzi&#39;,          //=&gt;프로퍼티
    sayDa: function(){      //=&gt;메소드
        console.log(&quot;zzi&quot;); 
    }
};
var cat = {};

console.log(dog);
console.log(cat);</code></pre>
<p><img src="https://images.velog.io/images/co_mong/post/a5d12082-9489-4a3c-abe9-b91fbdb00a33/image.png" alt=""></p>
<h3 id="12-object-생성자-함수">1.2 Object 생성자 함수</h3>
<p><code>Object</code> 생성자 함수는 <code>new</code> 연산자와 <code>Object</code> 생성자 함술을 사용하여 빈 객체를 생성하고 프로퍼티와 메소드를 추가하는 방식으로 객체를 완성하는 방식입니다.</p>
<pre><code class="language-javascript">var dog = new Object();
dog.name = &#39;Dazzi&#39;;
dog.sayDa = function(){
    console.log(&quot;zzi&quot;); 
};
var cat = new Object();

console.log(dog);
console.log(cat);</code></pre>
<p><img src="https://images.velog.io/images/co_mong/post/a5d12082-9489-4a3c-abe9-b91fbdb00a33/image.png" alt=""></p>
<h3 id="13-생성자-함수">1.3 생성자 함수</h3>
<p>1.2의 방식으로 비슷한 객체를 계속 생성하려면 불편하기 때문에 우리는 생성자 함수를 만들어서 사용합니다.
생성자 함수 방식은 클래스를 생성해서 객체를 만드는 방식처럼 유사하게 사용할수 있습니다.</p>
<pre><code class="language-javascript">function Animal(name,gender){
    this.name = name;
    this.gender = gender;
    var host = &#39;co_mong&#39;;
};

var dog = new Animal(&#39;Dazzi&#39;,&#39;male&#39;);
var cat = new Animal(&#39;Betodi&#39;,&#39;female&#39;);

console.log(dog);
console.log(cat);</code></pre>
<p>여기서 <code>this</code>란 생성자 함수가 생성할 인스턴스를 가리킵니다.
그리고 <code>this</code>로 만들어진 프로퍼티와 메소드는 public이 되서 외부에서 참조가 가능하지만 var등으로 선언된 프로퍼티는 <code>private</code>으로 외부에서 참조가 불가능합니다.
만약 <code>private</code> 프로퍼티를 외부에서 참조하면 <code>undefined</code>가 출력됩니다.</p>
<h2 id="2프로퍼티-값-접근">2.프로퍼티 값 접근</h2>
<p>객체의 값에 접근할때 보통 <code>.</code>이나 <code>[]</code>를 사용해서 접근합니다.</p>
<p><code>.</code>을 사용하여 객체에 접근할 때는 프로퍼티를 &quot;&quot;로 감싸지 않고 접근합니다.
하지만 <code>[]</code>를 사용하여 객체의 프로퍼티에 접근하려면 반드시 프로퍼티 이름을 &quot;&quot;로 감싸 주어야 합니다.</p>
<p>대괄호 표기법에서 따옴표로 감싸주어야 하는 이유는 객체의 프로퍼티는 기본적으로 문자열로 저장되기 때문입니다.</p>
<pre><code class="language-javascript">var dog = {
    name: &#39;Dazzi&#39;,
    sayDa: function(){
        console.log(&quot;zzi&quot;); 
    }
};
console.log(dog.name);
console.log(dog[&#39;name&#39;]);</code></pre>
<h3 id="21-프로퍼티-동적할당">2.1 프로퍼티 동적할당</h3>
<p>객체 선언시 정의되지 않은 프로퍼티에 객체 외부에서 값을 넣어주게 되면 객체 내에 새로운 프로퍼티가 생성됩니다.</p>
<pre><code class="language-javascript">var dog = {
    name: &#39;Dazzi&#39;,
    sayDa: function(){
        console.log(&quot;zzi&quot;); 
    }
};
dog.host = &#39;co_mong&#39;;
console.log(dog);</code></pre>
<h3 id="22-프로퍼티-삭제">2.2 프로퍼티 삭제</h3>
<p>객체내의 프로퍼티를 삭제하려면 <code>delete</code>연산자를 사용하면 됩니다.</p>
<pre><code class="language-javascript">var dog = {name: &#39;Dazzi&#39;};
delete dog.name;
console.log(dog);</code></pre>
<h3 id="23-for문을-사용한-프로퍼티-접근">2.3 for문을 사용한 프로퍼티 접근</h3>
<p>자바스크립트에서 사용되는 <code>for in</code> 반복문을 사용하여 객체의 프로퍼티에 접근할수 있습니다.</p>
<pre><code class="language-javascript">var dog = {name: &#39;Dazzi&#39;,gender: &#39;male&#39;};
for(var property in dog){
    console.log(property,dog[property]);
}</code></pre>
<p>위의 방법으로 객체의 프로퍼티에 접근하면 프로퍼티 이름에 접근 가능합니다. 만약 프로퍼티 값에 접근하려면 <code>대괄호 표기법</code>을 사용하여 값에 접근해야 합니다.</p>
<hr>
<p><strong>참고자료</strong></p>
<p> <a href="https://poiemaweb.com/js-object">https://poiemaweb.com/js-object</a>
<a href="https://www.zerocho.com/category/JavaScript/post/572c6f759a5f1c4db2481ee3">https://www.zerocho.com/category/JavaScript/post/572c6f759a5f1c4db2481ee3</a>
<a href="https://bigtop.tistory.com/12">https://bigtop.tistory.com/12</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 타입 변환]]></title>
            <link>https://velog.io/@co_mong/JS-%ED%83%80%EC%9E%85-%EB%B3%80%ED%99%98</link>
            <guid>https://velog.io/@co_mong/JS-%ED%83%80%EC%9E%85-%EB%B3%80%ED%99%98</guid>
            <pubDate>Fri, 23 Jul 2021 02:40:29 GMT</pubDate>
            <description><![CDATA[<h1 id="javascript-타입-변환">Javascript 타입 변환</h1>
<p>타입 변환이란 값의 타입을 다른 타입으로 변환시키는 것을 의미합니다.
자바스크립트에는 개발자가 직접 타입을 변화시켜주는 <code>명시적 타입 변환(타입 캐스팅)</code>과 자바스크립트 엔진이 타입을 변경해주는 <code>암묵적 타입 변환(타입 강제 변환)</code> 두 가지 타입 변환이 있습니다.</p>
<h2 id="1-명시적-타입-변환">1. 명시적 타입 변환</h2>
<p>변수나 함수등을 개발자가 직접 형변환을 시켜주는 명시적 타입 변환입니다.
기본적으로 Number,String,Boolean등이 있고 그외에도 parseInt,parseFloat와 같은 형변환 함수들이 존재합니다.</p>
<h3 id="11-숫자-타입으로-변환">1.1 숫자 타입으로 변환</h3>
<ul>
<li><p><strong>Number()</strong></p>
<pre><code class="language-javascript">Number(&quot;12&quot;)       //12
Number(true)       //1
Number(false)      //0
Number(&quot;12Num&quot;)    //NaN
Number(null)       //0
Number(undefined)  //NaN</code></pre>
</li>
<li><p><strong>parseInt()</strong></p>
<pre><code class="language-javascript">parseInt(&quot;12&quot;,10)  //12
parseInt(&quot;12&quot;,8)   //10
parseInt(&quot;11&quot;,2)   //3</code></pre>
<blockquote>
<p><code>parseInt</code> 의 경우 문자열과 N진수가 파라미터로 들어오게되고 해당 문자열을 N진수 형태로 인식해 10진수로 변환시켜줍니다.
N진수의 기본값은 10진수 입니다.</p>
</blockquote>
</li>
<li><p><strong>parseFloat()</strong></p>
<pre><code class="language-javascript">parseInt(&quot;12.34&quot;)  //12.34</code></pre>
<h3 id="12-문자열-타입으로-변환">1.2 문자열 타입으로 변환</h3>
</li>
<li><p><strong>String()</strong></p>
<pre><code class="language-javascript">String(12)         //&quot;12&quot;
String(true)       //&quot;true&quot;
String(false)      //&quot;false&quot;
String(12.3)       //&quot;12.3&quot;
String(null)       //&quot;null&quot;
String(undefined)  //&quot;undefined&quot;</code></pre>
<h3 id="13-불리언-타입으로-변환">1.3 불리언 타입으로 변환</h3>
</li>
<li><p><strong>Boolean()</strong></p>
<pre><code class="language-javascript">Boolean(&quot;12&quot;)      //true
Boolean(0)         //true
Boolean([])        //true
Boolean(NaN)       //false
Boolean(null)      //false
Boolean(undefined) //false</code></pre>
</li>
</ul>
<h2 id="2-암묵적-타입-변환">2. 암묵적 타입 변환</h2>
<p>암묵적 타입 변환이란 개발자가 직접 데이터 타입을 변환시키는 것이 아니라 자바스크립트 엔진이 자율적으로 변환시키는 것을 의미합니다.</p>
<h3 id="21-숫자-타입으로-변환">2.1 숫자 타입으로 변환</h3>
<p>기본적으로 <code>+</code>를 제외한 산술연산자(<code>-,*,/,%</code>)등을 사용하면 산술연산이 이루어집니다.</p>
<pre><code class="language-javascript">&quot;10&quot;*3 //30
&quot;10&quot;-3 //7
&quot;10&quot;/3 //3.3333
&quot;10&quot;%3 //1</code></pre>
<h3 id="22-문자열-타입으로-변환">2.2 문자열 타입으로 변환</h3>
<p>하지만 <code>+</code>의 경우 문자열과 숫자가 만나게 되면 숫자를 문자열로 형변환하게 됩니다.
그 결과 <code>+</code>는 문자열을 이어 붙이는 기능을 수행합니다.</p>
<pre><code class="language-javascript">&quot;10&quot;+3   //&quot;103&quot;
3+&quot;10&quot;   //&quot;301&quot;
3+&quot;10&quot;+3 //&quot;3103&quot;</code></pre>
<h3 id="23-불리언-타입으로-변환">2.3 불리언 타입으로 변환</h3>
<p>자바스크립트의 모든 값들은 <code>true</code>와 <code>false</code>값으로 변경될수 있습니다.
<code>true</code>로 형변환 되는 것을 <code>truthy</code>라고 하고 <code>false</code>로 형변환 되는 것을 <code>falsy</code>라고 합니다.</p>
<p>우선 <code>falsy</code>로 취급되는 값들은 다음과 같습니다.</p>
<pre><code>[false, 0, -0, null, undefined, &quot;&quot;, NaN]</code></pre><p>이 값들을 제외한 모든 값들은 <code>truthy</code>로 취급됩니다.
이러한 특징을 사용해 다음과 같은 코드를 작성할수 있습니다.</p>
<pre><code class="language-javascript">const a = 0;
if(a){
  console.log(a);
}else{
  console.log(&quot;falsy&quot;);
}</code></pre>
<p>위의 코드를 실행하면 0은 <code>falsy</code>이므로 &quot;falsy&quot;가 출력됩니다.</p>
<h2 id="3단축-평가">3.단축 평가</h2>
<p>단축 평가란 논리연산을 수행할때 해당 연산의 결과를 미리 반환하는 것을 의미합니다.</p>
<h3 id="31-and-연산자">3.1 And 연산자</h3>
<pre><code class="language-javascript">&quot;A&quot; &amp;&amp; &quot;B&quot; //&quot;B&quot;</code></pre>
<p>위의 경우 and 연산이 참인지 판별하려면 &quot;B&quot;까지 확인해야하므로 결과가 &quot;B&quot;가 나오게 됩니다.</p>
<pre><code class="language-javascript">0 &amp;&amp; &quot;B&quot; //&quot;B&quot;</code></pre>
<p>하지만 이 경우에는 0에서 이미 false값으로 판별이 났으므로 0을 반환합니다.</p>
<pre><code class="language-javascript">if(0 &amp;&amp; &quot;b&quot;){
    console.log(1);
}else{
    console.log(0);
}
//0</code></pre>
<h3 id="32-or-연산자">3.2 Or 연산자</h3>
<pre><code class="language-javascript">&quot;A&quot; || &quot;B&quot; //&quot;A&quot;</code></pre>
<p>위의 경우 or 연산이 &quot;A&quot;에서 이미 참임을 확인했으므로 &quot;A&quot;를 반환합니다.</p>
<pre><code class="language-javascript">0 || &quot;B&quot; //&quot;B&quot;</code></pre>
<p>하지만 이 경우에는 0까지만 봐서는 확인이 안되고 &quot;B&quot;까지 봐야 하므로 &quot;B&quot;가 결과값이 됩니다.</p>
<pre><code class="language-javascript">if(&quot;A&quot; || &quot;B&quot;){
    console.log(1);
}else{
    console.log(0);
}
//1</code></pre>
<hr>
<p><strong>참고자료</strong></p>
<p> <a href="https://poiemaweb.com/js-type-coercion">https://poiemaweb.com/js-type-coercion</a>
 <a href="https://velog.io/@design0728/%EC%95%94%EB%AC%B5%EC%A0%81-%ED%83%80%EC%9E%85-%EB%B3%80%ED%99%98implicit-coercion-0gqe2tex">https://velog.io/@design0728/%EC%95%94%EB%AC%B5%EC%A0%81-%ED%83%80%EC%9E%85-%EB%B3%80%ED%99%98implicit-coercion-0gqe2tex</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 변수]]></title>
            <link>https://velog.io/@co_mong/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@co_mong/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Thu, 22 Jul 2021 02:23:54 GMT</pubDate>
            <description><![CDATA[<h1 id="javascript-변수">Javascript 변수</h1>
<p>기존의 Javascript는 <code>var</code>를 사용해서 변수를 선언했습니다.
하지만 <code>ES6</code>부터 <code>const</code>와 <code>let</code>이 추가되었고 이들의 차이점을 정리하겠습니다.</p>
<h3 id="1-변수-재할당">1. 변수 재할당</h3>
<p><code>var</code>와 <code>let</code>의 경우 값을 초기화하고 나중에 값의 재할당이 가능합니다.</p>
<pre><code class="language-javascript">var x = 1;
x = 100;
console.log(x);
//x = 100</code></pre>
<pre><code class="language-javascript">let x = 1;
x = 100;
console.log(x);
//x = 100</code></pre>
<p>하지만 <code>const</code>의 경우 한번 초기화 이후 값의 재할당이 불가능합니다.</p>
<pre><code class="language-javascript">const x = 1;
x = 100;
console.log(x);</code></pre>
<p><img src="https://images.velog.io/images/co_mong/post/0f46b5b2-3187-49c9-b67b-e2fd276f419a/image.png" alt=""></p>
<h3 id="2-변수의-중복선언">2. 변수의 중복선언</h3>
<p><code>var</code>의 경우 변수를 중복해서 선언해도 문제되지 않습니다.</p>
<pre><code class="language-javascript">var x = 1;
var x = 2;</code></pre>
<p>하지만 <code>const</code>와 <code>let</code>의 경우 변수 중복선언이 불가능하고 중복선언 할 경우 아래와 같은 에러 메세지가 출력됩니다.</p>
<pre><code class="language-javascript">let x = 1;
let x = 2;</code></pre>
<pre><code class="language-javascript">const x = 1;
const x = 2;</code></pre>
<p><img src="https://images.velog.io/images/co_mong/post/f0874d40-5492-45a1-b17f-cb410fbd35f9/image.png" alt="">
변수의 중복선언이 가능한 문제는 코드가 짧을 경우 문제가 되지 않습니다.</p>
<p>하지만 코드가 길어졌을때 변수를 중복선언하게 되면 어디에서 문제가 발생했는지 찾기 어렵기 때문에 <code>var</code> 대신 <code>let</code>이나 <code>const</code>를 사용하는것이 좋습니다.</p>
<h3 id="3-변수의-스코프">3. 변수의 스코프</h3>
<p>우선 스코프란 변수를 사용할수 있는 유효범위를 말합니다.
그리고 <code>var</code>,<code>const</code>,<code>let</code>은 변수의 스코프에 차이가 존재합니다.</p>
<p><code>var</code>의 경우 함수 레벨 스코프입니다.
함수 레벨 스코프란 말그대로 함수 내부에서 선언된 변수는 함수 내부에서만 사용이 가능하고 그 외에는 전역변수로 취급하는 것을 의미합니다.</p>
<pre><code class="language-javascript">function func(){
    var x = &#39;hola&#39;;
    console.log(x);
}
func();//hola
console.log(x);//x is not defined</code></pre>
<p>위의 경우 print 함수 내부에서 선언된 x는 print 함수 내부에서만 유효합니다.
따라서 <code>print</code>의 경우 <code>hola</code>가 정상적으로 출력되고
<code>console.log(x)</code>의 경우 <code>ReferenceError</code>가 발생하게 됩니다.</p>
<p>이에 반해 <code>const</code>와 <code>let</code>의 경우는 스코프가 좀더 작은 범위까지 나눠지는 블록 레벨 스코프입니다.</p>
<pre><code class="language-javascript">function func(){
    if(true){
        let x = &#39;hola&#39;;
    }
    console.log(x);
}
func();//x is not defined
console.log(x);//x is not defined</code></pre>
<p>위의 경우 <code>var</code>과는 다르게 <code>print</code>와 <code>console.log(x)</code> 둘다 <code>ReferenceError</code>가 발생하게 됩니다. 👉 const의 경우도 동일합니다.</p>
<h3 id="4-호이스팅">4. 호이스팅</h3>
<p>호이스팅이란 변수나 함수의 선언을 스코프를 상단으로 끌어올려 실행하는 것을 의미합니다.
그리고 자바스크립트에서는 <code>var</code>, <code>const</code>, <code>let</code>, <code>function</code>등을 모두 호이스팅해줍니다.</p>
<p>하지만 초기화과정에서 <code>var</code>와 <code>const</code>,<code>let</code>의 차이가 생깁니다.
<code>var</code>의 경우 선언과 초기화의 단계가 같이 실행됩니다.</p>
<pre><code class="language-javascript">console.log(hola); //undefined

var hola;
console.log(hola); //undefined

hola = &#39;hola&#39;;
console.log(hola); //hola</code></pre>
<p>그 결과 hola에 값을 넣어주지 않아도 초기화가 되어있어 undefined가 출력되는것을 볼수 있습니다.</p>
<p><code>const</code>, <code>let</code>의 경우는 선언과 초기화가 분리되어 실행됩니다.</p>
<pre><code class="language-javascript">console.log(hola); //ReferenceError

let hola;
console.log(hola); //undefined

hola = &#39;hola&#39;;
console.log(hola); //hola</code></pre>
<p>위의 코드에서 hola를 선언했을때 초기화가 되지 않아서 처음에는 <code>ReferenceError</code>가 발생합니다.
그리고 초기화가 이루어지고 난 뒤에는 <code>undefined</code>가 출력되고
값을 할당한 뒤에는 hola가 정상적으로 출력되는 것을 볼 수 있습니다.</p>
<hr>
<p><strong>참고자료</strong></p>
<p> <a href="https://poiemaweb.com/es6-block-scope">https://poiemaweb.com/es6-block-scope</a>
 <a href="https://curryyou.tistory.com/192">https://curryyou.tistory.com/192</a></p>
]]></description>
        </item>
    </channel>
</rss>