<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>TableMinPark's Tech Blog</title>
        <link>https://velog.io/</link>
        <description>💡 클린코드를 지향하는 Backend Developer</description>
        <lastBuildDate>Thu, 17 Aug 2023 12:51:06 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>TableMinPark's Tech Blog</title>
            <url>https://velog.velcdn.com/images/tablemin_park/profile/4ae2048f-8fdb-4587-a3a1-febff9e0cde3/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. TableMinPark's Tech Blog. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/tablemin_park" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[CS] CPU 스케줄링 알고리즘]]></title>
            <link>https://velog.io/@tablemin_park/CS-CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</link>
            <guid>https://velog.io/@tablemin_park/CS-CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</guid>
            <pubDate>Thu, 17 Aug 2023 12:51:06 GMT</pubDate>
            <description><![CDATA[<p>CPU 스케줄러는 CPU 스케줄링 알고리즘에 따라 프로세스에서 해야 하는 일을 스레드 단위로 CPU에 할당한다.</p>
<p>프로그램이 실행될 때는 CPU 스케줄링 알고리즘이 어떤 프로그램에 CPU 소유권을 줄 것인지 결정한다. 이 알고리즘은 CPU 이용률은 높게, 주어진 시간에 많은 일을 하게, 준비 큐에 있는 프로세스는 적게, 응답 시간은 짧게 설정하는 것을 목표로 한다.</p>
<h3 id="❗️비선점형-방식">❗️비선점형 방식</h3>
<p>비선점형 방식은 프로세스가 스스로 CPU 소유권을 포기하는 방식이며, 강제로 프로세스를 중지하지 않는다. 따라서 컨텍스트 스위칭으로 인한 부하가 적다.</p>
<ul>
<li><p>FCFS
FCFS(Fist Come, First Served)는 가장 먼저 온 것을 가장 먼저 처리하는 알고리즘이다. </p>
<p>길게 수행되는 프로세스 때문에 &#39;준비 큐에서 오래 기다리는 현상&#39;이 발생하는 단점이 있다.</p>
</li>
<li><p>SJF
SJF(Shortest Job First)는 실행 시간이 짧은 프로세스를 가장 먼저 실행하는 알고리즘이다.</p>
<p>긴 시간을 가진 프로세스가 실행되지 않는 현상이 일어나며 평균 대기 시간이 가장 짧다. 하지만 실제로는 실행 시간을 알 수 없기 때문에 과거에 실행했던 시간을 토대로 추측해서 사용한다.</p>
</li>
</ul>
<h3 id="❗️선점형-방식">❗️선점형 방식</h3>
<p>선점형 방식은 현대 운영체제가 쓰는 방식으로 지금 사용하고 있는 프로세스를 알고리즘에 의해 중단시켜 버리고 강제로 다른 프로세스에게 CPU 소유권을 할당하는 방식이다.</p>
<ul>
<li><p>라운드 로빈
각 프로세스는 동일한 할당 시간을 주고 그 시간안에 끝나지 않으면 다시 준비 큐의 뒤로 가는 알고리즘이다.</p>
<p>예를 들어 q만큼 할당 시간이 부여되었고 N개의 프로세스가 운영된다고 하면 (N - 1) * q 시간이 지나면 차례가 오게 된다. 할당 시간이 너무 크면 FCFS가 되고 짧으면 컨텍스트 스위칭이 잦아져서 오버헤드, 즉 비용이 커진다. 일반적으로 전체 작업 시간은 길어지지만 평균 응답 시간은 짧아진다는 특징이 있다.</p>
</li>
<li><p>SRF
SJF는 중간에 실행 시간이 더 짧은 작업이 들어와도 기존 작업을 모두 수행하고 그 다음 작업을 이어나가는데, SRF는 중간에 더 짧은 작업이 들어오면 수행하던 프로세스를 중지하고 해당 프로세스를 수행하는 알고리즘이다.</p>
</li>
<li><p>다단계 큐
우선순위에 따른 준비 큐를 여러개 사용하고, 큐마다 라운드 로빈이나 FCFS 등 다른 스케줄링 알고리즘을 적용한 것이다. 큐 간의 프로세스 이동이 안되므로 스케줄링 부담이 적지만 유연성이 떨어지는 특징이 있다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] 공유 자원과 임계영역]]></title>
            <link>https://velog.io/@tablemin_park/CS-%EA%B3%B5%EC%9C%A0-%EC%9E%90%EC%9B%90%EA%B3%BC-%EC%9E%84%EA%B3%84%EC%98%81%EC%97%AD</link>
            <guid>https://velog.io/@tablemin_park/CS-%EA%B3%B5%EC%9C%A0-%EC%9E%90%EC%9B%90%EA%B3%BC-%EC%9E%84%EA%B3%84%EC%98%81%EC%97%AD</guid>
            <pubDate>Thu, 17 Aug 2023 12:18:59 GMT</pubDate>
            <description><![CDATA[<h3 id="❗️공유-자원">❗️공유 자원</h3>
<p>공유 자원은 시스템 안에서 각 프로세스, 스레드가 함께 접근할 수 있는 모니터, 프린터, 메모리, 파일, 데이터 등의 자원이나 변수 등을 의미한다. </p>
<p>이 공유 자원을 두 개 이상의 프로세스가 동시에 읽거나 쓰는 상황을 경쟁 상태라고 한다. 동시에 접근을 시도할 때 접근의 타이밍이나 순서 등이 결과값에 영향을 줄 수 있다.</p>
<h3 id="❗️임계-영역">❗️임계 영역</h3>
<p>공유 자원에 접근할 때 순서 등의 이유로 결과가 달라지는 영역을 임계 영역이라고 한다.</p>
<p>임계 영역을 해결하기 위한 방법은 뮤텍스, 세마포어, 모니터 세 가지가 있으며, 이 방법 모두 상호 배제, 한정 대기, 융통성이란 조건을 만족한다.</p>
<p>이 방법에 토대가 되는 매커니즘은 잠금(lock)이다. 예를 들어 임계 구역을 화장실이라고 가정하면 화장실에 A라는 사람이 들어간 다음 문을 잠근다. 그리고 다음 사람이 이를 기다리다 A가 나오면 화장실을 쓸 수 있는 것이다.</p>
<blockquote>
<p>💡 상호배제
한 프로세스가 임계 영역에 들어갔을 때 다른 프로세스는 들어갈 수 없다.</p>
</blockquote>
<blockquote>
<p>💡 한정 대기
특정 프로세스가 영원히 임계 영역에 들어가지 못하면 안된다.</p>
</blockquote>
<blockquote>
<p>💡 융통성
한 프로세스가 다른 프로세스의 일을 방해해서는 안된다.</p>
</blockquote>
<ul>
<li><p>뮤텍스
<img src="https://velog.velcdn.com/images/tablemin_park/post/6e65ca6f-c716-4c1c-9b3a-f3b7dfe658d1/image.png" alt=""></p>
<p>뮤텍스는 공유 자원을 사용하기 전에 설정하고 사용한 후에는 해제하는 잠금이다. 잠금이 설정되면 다른 스레드는 잠긴 코드 영역에 접근할 수 없다. 또한 뮤텍스는 하나의 상태만 가진다. </p>
</li>
<li><p>세마포어
<img src="https://velog.velcdn.com/images/tablemin_park/post/e52c8c2b-2b57-4114-b3c9-c82d3e497cf6/image.png" alt=""></p>
<p>세마포어는 일반화된 뮤텍스이다. 간단한 정수 값과 두 가지 함수 wait, signal로 공유 자원에 대한 접근을 처리한다.</p>
<p>wait() 은 자신의 차례가 올 때까지 기다리는 함수고, signal()은 다음 프로세스로 순서를 넘겨주는 함수이다.</p>
<ul>
<li><p>바이너리 세마포어
0과 1의 두가지 값만 가질 수 있는 세마포어이다. 구현의 유사성으로 인해 뮤텍스는 바이너리 세마포어라고 할 수 있다. 하지만 뮤텍스는 리소스에 대한 접근을 동기화하는데 사용되는 잠금 매커니즘이고, 세마포어는 신호를 기반으로 상호 배제가 일어나는 신호 매커니즘이다.</p>
<p>예를 들어서 휴대폰에서 노래를 듣다가 친구로부터 전화가 오면 노래가 중지되고 통화 처리 작업에 관한 인터페이스가 등장하는 경우가 바이너리 세마포어에 해당한다.</p>
</li>
<li><p>카운팅 세마포어
여러 개의 값을 가질 수 있는 세마포어이며, 여러 자원에 대한 접근을 제어하는데 사용된다.</p>
</li>
</ul>
</li>
<li><p>모니터
둘 이상의 스레드나 프로세스가 공유 자원에 안전하게 접근할 수 있도록 공유 자원을 숨기고 해당 접근에 대해 인터페이스만 제공한다.</p>
<p>모니터큐를 통해 공유 자원에 대한 작업들을 순차적으로 처리한다. </p>
<p>모니터는 세마포어보다 구현하기 쉬우며 모니터에서의 상호 배제는 자동인 반면에, 세마포어에서는 상호 배제를 명시적으로 구현해야하는 차이점이 있다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] 스레드]]></title>
            <link>https://velog.io/@tablemin_park/CS-%EC%8A%A4%EB%A0%88%EB%93%9C</link>
            <guid>https://velog.io/@tablemin_park/CS-%EC%8A%A4%EB%A0%88%EB%93%9C</guid>
            <pubDate>Thu, 17 Aug 2023 11:26:57 GMT</pubDate>
            <description><![CDATA[<h3 id="❗️스레드란">❗️스레드란?</h3>
<p>프로세스의 실행 가능한 가장 작은 단위이다. 프로세스는 여러 스레드를 가질 수 있다.</p>
<p>코드, 데이터, 스택, 힙을 각각 생성하는 프로세스와는 달리 스레드는 코드, 데이터, 힙은 스레드끼리 공유한다. 그 외의 영역은 스레드마다 각각 생성된다.</p>
<h3 id="❗️멀티스레딩이란">❗️멀티스레딩이란?</h3>
<p>프로세스 내 작업을 여러 개의 스레드, 멀티스레드로 처리하는 기법이며 스레드끼리 서로 자원을 공유하기 때문에 효율성이 높다.</p>
<p>예를 들어 웹 요청을 처리할 때 새 프로세스를 생성하는 대신 스레드를 사용하는 웹 서버의 경우 훨씬 적은 리소스를 소비한다. 그리고 하나의 스레드가 작업을 할 때 다른 스레드가 별도의 작업을 할 수 있어 사용자와의 응답성도 좋아진다.</p>
<p>하지만 한 스레드에 문제가 생기면 다른 스레드에도 영향을 끼쳐 스레드로 이루어져 있는 프로세스에 영향을 줄 수 있는 단점이 있다.</p>
<blockquote>
<p>💡 동시성이란
서로 독립적인 작업들을 작은 단위로 나누고 동시에 실행되는 것처럼 보여주는 것</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] 멀티 프로세싱]]></title>
            <link>https://velog.io/@tablemin_park/CS-%EB%A9%80%ED%8B%B0-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8B%B1</link>
            <guid>https://velog.io/@tablemin_park/CS-%EB%A9%80%ED%8B%B0-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8B%B1</guid>
            <pubDate>Thu, 17 Aug 2023 10:34:59 GMT</pubDate>
            <description><![CDATA[<h3 id="❗️멀티-프로세싱이란">❗️멀티 프로세싱이란?</h3>
<p>멀티 프로세싱은 여러 개의 &#39;프로세스&#39;, 멀티 프로세스를 통해 동시에 두 가지 이상의 일을 수행할 수 있는 것이다.</p>
<p>이를 통해 하나 이상의 일을 병렬로 처리할 수 있으며 특정 프로세스의 메모리, 프로세스 중 일부에 문제가 발생하더라도 다른 프로세스를 이용해서 처리할 수 있으므로 신뢰성 높은 강점이 있다.</p>
<h3 id="❗️웹-브라우저">❗️웹 브라우저</h3>
<p>웹 브라우저는 멀티프로세스 구조를 가지고 있다.</p>
<ol>
<li>브라우저 프로세스
주소 표시줄, 북마크 막대, 뒤로가기 버튼, 앞으로 가기 버튼 등을 담당하며 네트워크 요청이나 파일 접근 권한을 담당한다.</li>
<li>렌더러 프로세스
웹 사이트가 &#39;보이는&#39; 부분의 모든 것을 제어한다.</li>
<li>플러그인 프로세스
웹 사이트에서 사용하는 플러그인을 제어한다.</li>
<li>GPU 프로세스
GPU를 이용해서 화면을 그리는 부분을 제어한다.</li>
</ol>
<h3 id="❗️ipc">❗️IPC</h3>
<p>멀티 프로세스는 IPC(Inter Process Communication)가 가능하며 IPC는 프로세스끼리 데이터를 주고받고 공유 데이터를 관리하는 매커니즘이다.</p>
<p>예를 들면, 클라이언트는 데이터를 요청하고 서버는 클라이언트 요청에 응답하는 것이 IPC이다.</p>
<ul>
<li><p>IPC 의 종류</p>
<ol>
<li><p>공유메모리
<img src="https://velog.velcdn.com/images/tablemin_park/post/da6debce-3712-48be-8a41-2a34719aad0b/image.png" alt=""></p>
<p>공유 메모리는 여러 프로세스에 동일한 메모리 블록에 대한 접근 권한이 부여되어 프로세스가 서로 통신할 수 있도록 공유 버퍼를 생성하는 것이다.</p>
<p>기본적으로는 각 프로세스의 메모리를 다른 프로세스가 접근할 수 없지만 공유 메모리를 통해 여러 프로세스가 하나의 메모리를 공유할 수 있다. IPC 방식 중 어떠한 매개체를 통해 데이터를 주고받는 것이 아닌 메모리 자체를 공유하기 때문에 불필요한 데이터 복사의 오버헤드가 발생하지 않아 가장 빠르며, 같은 메모리 영역을 여러 프로세스가 공유하기 때문에 동기화가 필요하다.</p>
</li>
<li><p>파일
파일은 디스크에 저장된 데이터 또는 파일 서버에서 제공한 데이터이다. 이를 기반으로 프로세스 간 통신을 한다.</p>
</li>
<li><p>소켓
동일한 컴퓨터의 다른 프로세스나 네트워크의 다른 텀퓨터로 네트워크 인터페이스를 통해 전송하는 데이터를 의미하며 TCP, UDP가 있다.</p>
</li>
<li><p>익명 파이프
<img src="https://velog.velcdn.com/images/tablemin_park/post/f588efbd-7302-4837-a016-36945f340b19/image.png" alt=""></p>
<p>익명파이프는 프로세스 간에 FIFO 방식으로 얽히는 임시 공간인 파이프를 기반으로 데이터를 주고받으며, 단방향 방식의 읽기 전용, 쓰기 전용 파이프를 만들어서 작동하는 방식이다.</p>
<p>이는 부모, 자식 프로세스 간에만 사용할 수 있으며, 다른 네트워크상에서는 사용이 불가능하다.</p>
</li>
<li><p>명명 파이프
 명명된 다이프는 파이프 서버와 하나 이상의 파이프 클라이언트 간의 통신을 위한 명명된 단방향 또는 이중 파이프이다. 클라이언트/서버 통신을 위한 별도의 파이프를 제공하며, 여러 파이프를 동시에 사용할 수 있다. 컴퓨터 프로세스끼리 또는 다른 네트워크상의 컴퓨터와도 통신을 할 수 있다.</p>
</li>
<li><p>메시지 큐
 <img src="https://velog.velcdn.com/images/tablemin_park/post/3a0963c3-cd41-4259-87f9-c4505ea53620/image.png" alt=""></p>
<p>메시지를 큐 데이터 구조 형태로 관리하는 것이다. 이는 커널의 전역변수 형태 등 커널에서 전역적으로 관리되며 다른 IPC 방식에 비해서 사용 방법이 매우 직관적이고 간단하며 다른 코드의 수정 없이 몇 줄의 코드를 추가시켜 간단하게 메시지 큐에 접근할 수 있는 장점이 있다.</p>
<p>공유 메모리를 통해 IPC 를 구현할 때 쓰기 및 읽기 빈도가 높으면 동기화 때문에 기능을 구현하는 것이 복잡해지는데, 이 때 대안으로 메시지 큐를 사용하기도 한다.</p>
</li>
</ol>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] 디자인 패턴]]></title>
            <link>https://velog.io/@tablemin_park/CS-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-n5t5gc60</link>
            <guid>https://velog.io/@tablemin_park/CS-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-n5t5gc60</guid>
            <pubDate>Thu, 17 Aug 2023 07:32:55 GMT</pubDate>
            <description><![CDATA[<h3 id="❗️팩토리-패턴">❗️팩토리 패턴</h3>
<blockquote>
<p>💡 객체의 생성을 캡슐화하는 패턴</p>
</blockquote>
<p>객체를 사용하는 코드에서 객체 생성 부분을 떼어네 추상화한 패턴이자 상속 관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결정하고, 하위 클래스에서 객체 생성에 대한 구체적인 내용을 결정하는 패턴이다.</p>
<p>상위 클래스와 하위 클래스가 분리되기 때문에 <strong>느슨한 결합</strong>을 가지며 상위 클래스에서는 인스턴스 생성 방식에 대해 전혀 알 필요가 없기 때문에 더 많은 <strong>유연성</strong>을 가지게 된다.</p>
<p>객체 생성 로직이 따로 떨어져 있기 때문에 코드를 리팩토링 하는 경우에도 한 곳만 고칠 수 있기 떄문에 유지 보수성이 증가한다.</p>
<p>팩토리 패턴은 객체 생성에 대한 로직은 상위 클래스에서 작성하고, 하위 클래스에서 객체 생성에 대한 구체적인 내용을 결정한다.</p>
<h3 id="❗️프록시-패턴">❗️프록시 패턴</h3>
<p>프록시는 대리인이라는 뜻으로, 무엇인가를 대신 처리하는 의미이다. 실제 객체 앞단에 위치하여 해당 객체의 행위(Method)를 대리하는 역할을 한다. 프록시 객체를 통해 대상 객체에 접근하기 때문에 실제 객체가 메모리에 존재하지 않아도 기본적인 정보를 참조하거나 설정할 수 있고, 또한 실제 객체의 기능이 반드시 필요한 시점까지 객체의 생성을 미룰 수 있다.</p>
<ul>
<li><p>💡 <strong>대표적인 프록시 3가지</strong></p>
<ol>
<li>가상 프록시
꼭 필요로 하는 시점까지 객체의 생성을 연기하고, 해당 객체가 생성된 것처럼 동작하도록 만들고 싶을 때 사용하는 패턴이다. 프록시 클래스에서 자잘한 작업들을 처리하고 리소스가 많이 요구되는 작업들이 필요할 때만 주체 클래스를 사용하도록 구현한다.</li>
<li>원격 프록시
원격 객체에 대한 접근을 제어 로컬 환경에 존재하며, 원격 객체에 대한 대변자 역할을 하는 객체, 서로 다른 주소 공간에 잇는 객체에 대해 마치 같은 주소 공간에 있는 것처럼 동작하게 만드는 패턴이다. 예시로 Google Docs가 있다.</li>
<li>보호 프록시
주체 클래스에 대한 접근을 제어하기 위한 경우에 객체에 대한 접근 권한을 제어하거나 객체마다 접근 권한을 달리하고 싶을 때 사용하는 패턴으로 프록시 클래스에서 클라이언트가 주체 클래스에 대한 접근을 허용할지 말지 결정하도록 할 수 있다.</li>
</ol>
</li>
<li><p>💡 <strong>프록시 패턴 장점</strong></p>
<ul>
<li>사이즈가 큰 객체가 로딩되기 전에도 프록시를 통해 참조할 수 있다.</li>
<li>실제 객체의 public, protected 메소드들을 숨기고 인터페이스를 통해 노출시킬 수 있다.</li>
<li>로컬에 있지 않고 떨어져 있는 객체를 사용할 수 있다.</li>
<li>원래 객체의 접근에 대해서 사전처리를 할 수 있다.</li>
</ul>
</li>
<li><p>💡 <strong>프록시 패턴 단점</strong></p>
<ul>
<li>객체를 생성할 때 한 단계를 더 거치게 되므로, 빈번한 객체 생성이 필요한 경우 성능이 저하될 수 있다.</li>
<li>프록시 내부에서 객체 생성을 위해 스레드가 생성, 동기화가 구현되야 하는 경우 성능이 저하될 수 있다.</li>
<li>로직이 난해해져 가독성이 떨어질 수 있다.</li>
</ul>
</li>
<li><p>💡 <strong>프록시 패턴 예제</strong></p>
<pre><code class="language-java">public interface Image {
    void displayImage();
}</code></pre>
<pre><code class="language-java">public class RealImage implements Image {
    private String fileName;

    public RealImage(String fileName) {
        this.fileName = fileName;
        loadFromDisk(fileName);
    }

    private void loadFromDisk(String fileName) {
        System.out.println(&quot;Loading &quot; + fileName);
    }

    @Override
    public void display() {
        System.out.println(&quot;Displaying &quot; + fileName);
    }
}</code></pre>
<pre><code class="language-java">public class ProxyImage implements Image {
    private RealImage realImage;
    private String fileName;

    public ProxyImage(String fileName) {
        this.fileName = fileName;
    }

    @Override
    public void displayImage() {
        if (realImage == null) {
            realImage = new RealImage(fileName);
        }
        realImage.displayImage();
    }
}</code></pre>
<pre><code class="language-java">public class ProxyMain {
    public static void main(String[] args) {
        Image image1 = new ProxyImage(&quot;test1.jpg&quot;);
        Image image2 = new ProxyImage(&quot;test2.jpg&quot;);

        image1.displayImage();
        image2.displayImage();
    }
}</code></pre>
<h3 id="❗️싱글톤-패턴">❗️싱글톤 패턴</h3>
<p>전역변수를 사용하지 않고 객체를 하나만 생성한다.
생성된 객체를 어디에서든지 참조할 수 있다.
생성자가 여러 차례 호출되어도 하나의 객체만 존재한다.
최초 생성 이후에 호출된 생성자는 최초 생성자가 생성한 객체를 리턴한다.
환경설정 관리 클래스나 커넥션 풀과 같이 pool 형태로 관리되는 공통 클래스에서 사용되는 것이 일반적이다.</p>
</li>
<li><p>💡 <strong>싱글톤 패턴의 특징</strong></p>
<ul>
<li><p>고정된 메모리 영역을 얻으면서 동시에 한번만 <code>new</code>를 사용하여 메모리 낭비를 방지할 수 있다.</p>
</li>
<li><p>싱글톤으로 만들어진 인스턴스는 전역으로 사용되며, 다른 클래스의 인스턴스들이 데이터를 공유하고 변경할 수 있다.</p>
</li>
<li><p>많은 일을 위임하거나 공유하는 경우 Coupling이 많아지고 결합도가 높아진다.</p>
</li>
<li><p>Java에서의 싱글톤 패턴</p>
<pre><code class="language-java">public class Singleton {
    private static class singleInstanceHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    public static synchronized Singleton getInstance() {
        return singleInstanceHolder.INSTANCE;
    }
}

public class HelloWorld { 
     public static void main(String[] args) { 
        Singleton a = Singleton.getInstance(); 
        Singleton b = Singleton.getInstance(); 
        System.out.println(a.hashCode());
        System.out.println(b.hashCode());  
        if (a == b) {
         System.out.println(true); 
        } 
     }
}</code></pre>
</li>
</ul>
</li>
<li><p>💡 <strong>싱글톤 패턴의 단점</strong></p>
<ul>
<li>TDD를 할 때 독립적인 인스턴스를 만들기가 어렵다.<blockquote>
<p>💡 TDD를 할 때 단위 테스트를 주로 하는데, 단위 테스트는 테스트가 서로 독립적이어야 하며 테스트를 어떤 순서로든 실행할 수 있어야 한다. 하지만 싱글톤 패턴은 미리 생성된 하나의 인스턴스를 기반으로 구현하는 패턴이므로 각 테스트마다 독립적인 인스턴스를 만들기가 어렵다.</p>
</blockquote>
</li>
<li>모듈 간의 결합도를 높힐 수 있다.<blockquote>
<p>💡 의존성 주입 (DI, Dendency Injection)을 통해 모듈 간 결합을 조금 더 느슨하게 만들어 해결할 수 있다.</p>
</blockquote>
</li>
</ul>
</li>
<li><p>💡 <strong>싱글톤 패턴에 주의할 점</strong>
상태를 가진 객체를 Singleton으로 만들면 안된다. 앱 내의 단 한개의 인스턴스가 존재하고, 이를 전역에서 접근할 수 있다면 각기 다른 스레드에서 객체의 상태를 마구잡이로 변경시킬 여지가 있다. 상태가 공유되는 것은 위험하기 때문에 무상태 객체 혹은 설계상 유일해야하는 시스템 컴포넌트를 Singleton으로 만들어야 한다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] HTTP]]></title>
            <link>https://velog.io/@tablemin_park/CS-HTTP</link>
            <guid>https://velog.io/@tablemin_park/CS-HTTP</guid>
            <pubDate>Thu, 03 Aug 2023 10:20:42 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>💡 전송 계층 위에 있는 애플리케이션 계층으로서 웹서비스 통신에 사용하는 프로토콜</p>
</blockquote>
<h3 id="❗️http10">❗️HTTP/1.0</h3>
<p><strong>HTTP 1.0 은 기본적으로 한 연결당 하나의 요청을 처리</strong>하도록 설계되었다. 이는 서버로부터 파일을 가져올 때마다 TCP 3-Way Hand Shake를 지속적으로 열어야 하기 때문에 <strong>RTT가 증가하는 단점</strong>이 있었다.</p>
<blockquote>
<p>💡 RTT란?
    패킷의 왕복 시간, 패킷이 목적지에 도달하고 나서 다시 출발지로 돌아오기까지 걸리는 시간</p>
</blockquote>
<p>RTT가 증가하는 단점을 보완하기 위해서는 두 가지의 방법이 있다.</p>
<ol>
<li><p>이미지 스틸리팅
 많은 이미지를 다운로드받게 되면 과부하가 걸리기 때문에 많은 이미지가 함쳐 있는 하나의 이미지를 다운로드받고, 이를 기반으로 background-image의 position을 이용하여 이미지를 표기하는 방법이다.</p>
<pre><code class="language-css"> #icons&gt;li&gt;a {
     background-image: url(&quot;icons.png&quot;);
     width: 25px;
     display: inline-block;
     height: 25px;
     repeat: no-repeat;
 }
 #icons&gt;li:nth-child(1)&gt;a {
     background-position: 2px -8px;
 }
 #icons&gt;li:nth-child(2)&gt;a {
     background-position: -29px -8px;
 }</code></pre>
<p> 여러 개의 이미지가 합쳐진 하나의 이미지를 다운받고 background-position을 이용해 이미지를 설정한다.</p>
</li>
<li><p>코드 압축
 개행 문자, 빈칸을 없애서 코드를 압축해 크기를 최소화하는 방법이다.</p>
<pre><code class="language-javascript"> // 압축 전 코드
 const express = require(&#39;express&#39;)
 const app = express()
 const port = 3000
 app.get(&#39;/&#39;, (req, res) =&gt; {
   res.send(&#39;Hello World!&#39;)
 })

 app.listen(port, () =&gt; {
   console.log(`Example app listening on port ${port}`)
 })</code></pre>
<pre><code class="language-javascript"> // 압축 후 코드
 const express=require(&quot;express&quot;),app=express(),port=3e3;app.get(&quot;/&quot;,(e,p)=&gt;{p.send(&quot;Hello World!&quot;)}),app.listen(3e3,()=&gt;{console.log(&quot;Example app listening on port 3000&quot;)});</code></pre>
</li>
<li><p>이미지 Base64 인코딩
 이미지 파일을 64진법으로 이루어진 문자열로 인코딩하는 방법이다. 단일 요청을 통해 여러 개의 이미지를 한번에 가져올 수 있는 장점이 있다. 하지만 Base64 문자열로 변환할 경우 37% 정도 크기가 커지는 단점이 있다.</p>
<blockquote>
<p>💡 인코딩이란?</p>
<pre><code> 정보의 형태나 형식을 표준화, 보안, 처리 속도 향상, 저장 공간 절약 등을 위해 다른 형태나 형식으로 변환하는 처리 방식</code></pre></blockquote>
</li>
</ol>
<h3 id="❗️http11">❗️HTTP/1.1</h3>
<p>HTTP/1.0에서 발전한 것이 HTTP1.1이다. <strong>매번 TCP를 연결하는 것이 아니라 한 번 TCP를 초기화 한 이후에 &quot;Keep-alive&quot;라는 옵션으로 여러 개의 파일을 송수신할 수 있게</strong> 바뀌었다. HTTP/1.0에도 &quot;keep-alive&quot;가 있었지만 HTTP/1.1에서 표준화 되었다.</p>
<p><img src="https://velog.velcdn.com/images/tablemin_park/post/ab69995d-6b14-49c3-94d8-b555394f7787/image.png" alt=""></p>
<p>TCP-3 Way Hand Shake 가 발생하면 HTTP/1.1에서는 닫지않고 지속적으로 데이터를 송수신하는 것을 볼 수 있다. 하지만 문서 안에 포함된 다수의 리소스 (이미지, css파일, script파일)를 처리하려면 <strong>요청할 리소스 개수에 비례해서 대기 시간이 길어지는 단점</strong>이 있다. 이 현상을 HOL Blocking 이라고 한다. 그리고 HTTP/1.1 <strong>헤더에서는 쿠키 등 많은 메타 데이터가 들어있고, 압축되지 않아 무거운 헤더 구조</strong>를 가지고 있다.</p>
<blockquote>
<p>💡 HOL Blocking (Head Of Line Blocking) 이란?
    네트워크에서 같은 큐에 있는 패킷이 그 첫 번째 패킷에 의해 지연될 때 발생하는 성능 저하 현상</p>
</blockquote>
<h3 id="❗️http20">❗️HTTP/2.0</h3>
<p>HTTP/2.0은 SPDY 프로토콜에서 파생된 <strong>HTTP/1.x보다 지연 시간을 줄이고 응답 시간을 더 빠르게</strong> 할 수 있으며 <strong>멀티플렉싱, 헤더압축, 서버 푸시, 요청의 우선순위 처리를 지원</strong>하는 프토콜이다.</p>
<ol>
<li><p>멀티 플렉싱
 멀티 플렉싱이란 여러 개의 스트림을 사용하여 송수신하는 것을 의미한다. 이를 통해 특정 스트림의 패킷이 손실되었다고 하더라도 해당 스트림에만 영향을 미치고 나머지 스트림은 멀쩡하게 동작할 수 있다. 즉 전송할 수 있는 경로를 병렬적으로 구성하고 여러 개의 경로로 동시에 전송한다.</p>
<blockquote>
<p>💡 스트림이란?</p>
<pre><code> 시간이 지남에 따라 사용할 수 있게 되는 일련의 데이터 요소를 가리키는 데이터 흐름</code></pre></blockquote>
<p> <img src="https://velog.velcdn.com/images/tablemin_park/post/775d4f29-eed6-476d-a8bf-83b7125346c9/image.png" alt=""></p>
<p>하나의 연결 내 여러 스트림을 병렬적으로 구성해 데이터를 서빙하고 있다. 또한 스트림 내의 데이터들도 분할하여 전달한다. 애플리케이션에서 받아온 데이터를 독립된 프레임으로 조각내어 서로 송수신한 이후 다시 조립하며 데이터를 주고받는다.</p>
<p>이를 통해 단일 연결을 통해 병렬로 여러 요청을 받을 수 있고 응답을 줄 수 있다. 이렇게 되면 HTTP/1.x에서 발생하는 문제인 HOL Blocking을 해결할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/tablemin_park/post/14415699-be9e-4ceb-81c6-ba22c6426752/image.png" alt=""></p>
</li>
</ol>
<ol start="2">
<li><p>헤더 압축
 HTTP/1.x에는 크기가 큰 헤더가 있는 문제가 있었다. 그래서 HTTP/2.0에서는 헤더 압축을 써서 해결하는데, 허프만 코딩 압축 알고리즘을 사용하는 HPACK 압축 형식을 가진다.</p>
<blockquote>
<p>💡 HPACK이란?</p>
<pre><code> 아직까지 나타나지 않은 값에 대해서 정적 허프만 코딩을 사용하고 또한 정적 테이블이나 동적 테이블에 이미 있는 값을 인덱스로 대체하여 각 요청의 크기를 줄일 수 있다. (indexing 한 것은 인코딩을 하지 않는다.)
 1. 헤더 인덱싱 : 중복되는 헤더는 헤더 테이블에 있는 index 값만 내려서 성능을 개선한다.
 2. 인코딩 : 중복되지 않는 헤더는 허프만 인코딩을 통해 전달한다.</code></pre></blockquote>
</li>
<li><p>서버 푸시
 HTTP/1.1에서는 클라이언트가 서버에 요청을 하여 파일을 다운로드 받을 수 있었지만, HTTP/2.0은 클라이언트 요청없이 서버가 바로 리소스를 푸시할 수 있다. html 파일에 필요한 자원(css, js)을 서버에서 푸시하여 클라이언트에게 미리 전달할 수 있다.</p>
<p> <img src="https://velog.velcdn.com/images/tablemin_park/post/4fbb19ca-825d-4e87-833c-a3c0dde00b72/image.png" alt=""></p>
</li>
</ol>
<h3 id="❗️https">❗️HTTPS</h3>
<p>HTTP/2.0은 HTTPS위에서 동작한다. HTTPS는 애플리케이션 계층과 전송 계층 사이에 신뢰 계층인 SSL/TLS 게층을 넣은 신뢰할 수 있는 HTTP 요청이다. 이를 통해 &quot;통신을 암호화&quot;한다.</p>
<ol>
<li><p>SSL/TLS
 SSL(Secure Socket Layer)은 SSL 1.0부터 2.0, 3.0, TLS(Transport Layer Security Protocol) 1.0, 1.3까지 버전이 올라가며 마지막으로 TLS로 명칭이 변경되었으나, 보통 이를 합쳐 SSL/TLS라고 부른다.
 SSL/TLS는 전송 계층에서 보안을 제공하는 프로토콜이다. 클라이언트와 서버가 통신할 때 SSL/TLS를 통해 제 3자가 메시지를 도청하거나 변조하지 못하도록 한다. SSL/TLS는 공격자가 서버인 척하며 사용자 정보를 가로채는 네트워크상의 &quot;인터셉터&quot;를 방지할 수 있다. SSL/TLS는 보안 세션을 기반으로 데이터를 암호화하여 보안 세션이 만들어질 때 인증 매커니즘, 키 교환 암호화 알고리즘, 해싱 알고리즘이 사용된다.</p>
</li>
<li><p>보안 세션
 보안 세션이란 보안이 시작되고 끝나는 동안 유지되는 세션을 말하고, SSL/TLS는 핸드쉐이크를 통해 보안 세션을 생성하고 이를 기반으로 상태 정보 등을 공유한다.</p>
<blockquote>
<p>💡 세션이란?</p>
<pre><code> 운영체제가 어떠한 사용자로부터 자신의 자산 이용을 허락하는 일정한 기간을 뜻한다. 즉, 사용자는 일정 기간동안 응용 프로그램, 자원 등을 사용할 수 있다.</code></pre><p> 클라이언트와 서버 간 키를 공유하고 이를 기반으로 인증, 인증 확인 등의 작업이 일어나는 단 한번의 1-RTT가 생긴 후 데이터를 송수신한다. </p>
</blockquote>
<ul>
<li><p>송수신 과정</p>
<ol>
<li>클라이언트에서 사이퍼슈트(cyber suites)를 서버에 전달하면 서버는 받은 사이퍼 슈트의 암호화 알고리즘 리스트를 제공할 수 있는지 확인</li>
<li>제공할 수 있다면 서버에서 클라이언트로 인증서를 보내는 인증 메커니즘 실행</li>
<li>해싱 알고리즘 등으로 암호화된 데이터의 송수신 진행</li>
</ol>
<blockquote>
<p>💡 사이퍼 슈트란?
  프로토콜, AEAD 사이퍼 모드, 해싱 알고리즘이 나열된 규약을 말하며, 다섯개가 있다. 사이퍼 슈트는 &quot;[TLS 프로토콜]_[AEAD 사이퍼모드]_[해싱 알고리즘]&quot; 형식으로 이루어져 있다.
  • TLS_AES_128_GCM_SHA256
  • TLS_AES_256_GCM_SHA384
  • TLS_CHACHA20_POLY1305_SHA256
  • TLS_AES_128_CCM_SHA256
  • TLS_AES_128_CCM_8_SHA256</p>
</blockquote>
<blockquote>
<p>💡 AEAD 사이퍼 모드란?
  AEAD(Authenticated Encryption with Associated Data)는 데이터 암호화 알고리즘이며 AES_128_GCM 등이 있다. 예를 들어 AES_128_GCM이라는 것은 128비트의 키를 사용하는 표준 블록 암호화 기술과 병렬 계산에 용이한 암호화 알고리즘 GCM이 결합된 알고리즘을 뜻한다.</p>
</blockquote>
</li>
</ul>
</li>
<li><p>인증 매커니즘
 인증 매커니즘은 CA(Certificate Authorities)에서 발급한 인증서를 기반으로 이루어진다. CA에서 발급한 인증서는 안전한 연결을 시작하는 데 있어 필요한 &quot;공개키&quot;를 클라이언트에 제공하고 사용자가 접속한 &quot;서버가 신뢰&quot;할 수 있는 서버임을 보장한다. 인증서는 서비스 정보, 공개키, 지문, 디지털 서명 등으로 이루어져 있다. CA는 아무 기업이나 할 수 있는 것이 아니라 신뢰성이 엄격하게 공인된 기업들만 참여할 수 있으며, 대표적으로 Comodo, GoDaddy, GlobalSign, 아마존 등이 있다.</p>
<ul>
<li><p>CA 발급 과정
  자신의 서비스가 CA 인증서를 발급받으려면 자신의 사이트 정보와 공개키를 CA에 제출해야한다. 이후 CA는 공개키를 해시한 값인 지문을 사용하는 CA의 비밀키 등을 기반으로 CA인증서를 발급한다.</p>
<blockquote>
<p>💡 개인키와 공개키</p>
<pre><code>  개인키 : 비밀키라고도 하며, 개인이 소유하고 있는 키이자 반드시 자신만이 소유해야 하는 키이다. (공개키로 암호화한 데이터를 복호화하기 위한 유일한 수단이다.)
  공개키 : 공개되어 있는 키로 암호화할 때 쓰인다.</code></pre></blockquote>
</li>
</ul>
</li>
<li><p>암호화 알고리즘
 키 교환 암호화 알고리즘으로는 대수곡선 기반의 ECDHE(Elliptic Curve Diffie-Hellman Ephermeral) 또는 모듈식 기반의 DHE(Diffie-Hellman Ephermeral)를 사용한다. 둘다 디피-헬만 방식을 근간으로 만들어졌다.</p>
<ul>
<li><p>디피-헬만 키 교환 암호화 알고리즘<br>  <img src="https://velog.velcdn.com/images/tablemin_park/post/d86c8b16-43f9-40fd-9325-6b27c67f2c78/image.png" alt=""></p>
<ol>
<li><p>공개 값을 공유하고 각자의 비밀 값과 혼합한 후 값을 공유한다.</p>
</li>
<li><p>각자의 비밀 값과 또 혼합한다. </p>
</li>
<li><p>공통의 암호키가 생성된다.</p>
<p>위 과정을 통해 서로에게 공개키를 보내고 공개키와 개인키를 결합하여 PSK(사전 합의된 비밀키)가 생성된다면, 악의적인 공격자가 개인키 또는 공개키를 가지고도 PSK가 없기 때문에 아무것도 할 수가 없다.</p>
</li>
</ol>
</li>
<li><p>SHA-256 알고리즘 (해싱 알고리즘)
  해싱 알고리즘은 데이터를 추정하기 힘든 더 작고, 섞여있는 조각으로 만드는 알고리즘이다. SSL/TLS는 해싱 알고리즘으로 SHA-256 또는 SHA-384를 사용하고, 보통 SHA-256를 많이 사용한다.</p>
<p>SHA-256 알고리즘은 해시 함수의 결과값이 256비트인 알고리즘이며 비트 코인을 비롯한 많은 블록체인 시스템에서도 사용한다. SHA-256 알고리즘은 해싱을 해야 할 메시지에 1을 추가하는 전처리를 하고 전처리 된 메시지를 기반으로 해시를 반환한다.</p>
<p><img src="https://velog.velcdn.com/images/tablemin_park/post/0db2b792-6c71-4f62-aedf-60352a2a36fe/image.png" alt=""></p>
<p>위 그림 처럼 메시지가 256 비트 크기의 알 수 없는 문자열로 변환되는 것을 볼 수 있다.</p>
<blockquote>
<p>💡 해시, 해싱, 해싱함수
  해시 : 다양한 길이를 가진 데이터를 고정된 길이를 가진 데이터로 매핑한 값
  해싱 : 임의의 데이터를 해시로 바꿔주는 일이며 해시 함수가 이를 담당
  해시 함수 : 임의의 데이터를 입력으로 받아 일정한 길이의 데이터로 바꿔주는 함수</p>
</blockquote>
</li>
</ul>
</li>
</ol>
<h3 id="❗️http30">❗️HTTP/3.0</h3>
<p>HTTP/3.0은 HTTP/1.1 및 HTTP/2.0와 함께 World Wide Web에서 정보를 교환하는데 사용되는 HTTP의 세 번째 버전이다. TCP 위에서 돌아가는 HTTP/2.0와는 달리 HTTP/3.0은 QUIC라는 것 위에서 돌아가며, TCP 기반이 아닌 UDP 기반으로 돌아간다.</p>
<p><img src="https://velog.velcdn.com/images/tablemin_park/post/b540a595-995d-431e-9509-25b8e2e9ccbc/image.png" alt=""></p>
<p>HTTP/2.0에서의 장점인 멀티 플렉싱을 가지고 있고, 초기 연결 설정 시 지연 시간 감소라는 장점이 있다.</p>
<p>QUIC는 TCP를 사용하지 않기 때문에 통신을 시작할 때 번거로운 3-Way Hand Shake 과정을 거치지 않아도 된다.</p>
<blockquote>
<p>💡 QUIC란?
    - UDP의 특성인 신뢰성이 없는 한계를 QUIC에서 보완하고 있으며, UDP 기반 응답 속도를 개선하고 TCP 기반 다중화와 신뢰성 있는 전송이 가능한 차세대 HTTP 프로토콜이다.
    - TLS1.3 암호화를 통해 단순성과 속도를 개선하였으며, 연결 설정 대기 시간 최소화를 위해 암호화 및 전송을 위한 1회 HandShake 를 수행한다.
    - UDP port 443을 통해 통신한다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tablemin_park/post/9feb4c4b-8d10-4261-b987-a5c411a08068/image.png" alt=""></p>
<p>QUIC은 첫 연결 설정에 1-RTT만 소요된다. 클라이언트가 서버에 어떤 신호를 한 번 주고, 서버도 거기에 응답하기만 하면 바로 본 통신을 진행할 수 있다. QUIC는 순방향 오류 수정 매커니즘(FEC, Forword Error Correction)이 적용되어서 전송한 패킷이 손실되었다면 수신 측에서 에러를 검출하고 수정하는 방식을 통해 열악한 네트워크 환경에서도 낮은 패킷 손실률을 유지할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] 객체지향과 절차지향]]></title>
            <link>https://velog.io/@tablemin_park/CS-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EA%B3%BC-%EC%A0%88%EC%B0%A8%EC%A7%80%ED%96%A5</link>
            <guid>https://velog.io/@tablemin_park/CS-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EA%B3%BC-%EC%A0%88%EC%B0%A8%EC%A7%80%ED%96%A5</guid>
            <pubDate>Fri, 30 Jun 2023 06:37:34 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>💡 절차적 프로그래밍과 객체지향 프로그래밍은 반대되는 단어가 아니다.</p>
</blockquote>
<blockquote>
<p>💡 프로시저에는 루틴, 서브루틴, 메소드, 함수 등이 있다.</p>
</blockquote>
<ul>
<li>루틴 : main문</li>
<li>서브루틴 : main문 밖에서 정의한 코드 블럭 중에 - 반환 값이 없는 것</li>
<li>함수 : main문 밖에서 정의한 코드 블럭 중에 반환 값이 있는 것</li>
</ul>
<h3 id="❗️절차지향">❗️절차지향</h3>
<ul>
<li>절차지향이란 프로시져로 프로그램을 구성하는 기법이다.</li>
<li>프로시져는 대체로 데이터를 중심으로 구현한다.</li>
<li>단점은 데이터 타입이나 의미를 변경해야 할 때, 함께 수정해야 하는 프로시져가 증가하는 것이다.</li>
</ul>
<h3 id="❗️절차적-프로그래밍">❗️절차적 프로그래밍</h3>
<ul>
<li>절차적 프로그래밍은 순차적인 처리를 중요시 여기며, 프로그램 전체가 유기적으로 연결되도록 만드는 프로그래밍 기법이다.</li>
<li>장점<ul>
<li>모듈 구성이 용이하며 구조적인 프로그래밍이 가능하다.</li>
<li>컴퓨터의 처리구조와 유사해 실행 속도가 빠르다.</li>
</ul>
</li>
<li>단점<ul>
<li>유지보수가 어렵다.</li>
<li>정해진 순서대로 입력을 해야하므로 순서를 바꾸면 결과값을 보장할 수 없다.</li>
<li>코드가 길어지면 가독성이 무척 떨어지며 이해하기가 힘들다.</li>
<li>대형 프로젝트에 부적합하다.</li>
</ul>
</li>
</ul>
<h3 id="❗️객체지향">❗️객체지향</h3>
<ul>
<li>객체는 자신만의 데이터와 프로시져를 갖는다.</li>
<li>객체는 자신만의 기능을 제공한다.</li>
<li>객체들은 서로 연결되어 다른 객체가 제공하는 기능을 사용할 수 있다.</li>
</ul>
<h3 id="❗️객체지향-프로그래밍">❗️객체지향 프로그래밍</h3>
<ul>
<li>객체지향 프로그래밍은 필요한 속성과 메서드를 가진 클래스를 정의하고, 정의된 클래스를 통해서 각각의 객체를 생성하여, 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 기법이다.</li>
<li>장점<ul>
<li>코드의 재사용성이 높아졌다.</li>
<li>유지보수가 쉬워졌다.</li>
<li>클래스를 한 번 이해하면 코드의 가독성이 높아진다.</li>
<li>대형 프로젝트에 적합해졌다.</li>
</ul>
</li>
<li>단점<ul>
<li>처리속도가 절차지향보다는 느리다.</li>
<li>객체가 많아지면 용량이 커질 수 있다.</li>
<li>설계시 많은 시간과 노력이 필요하다.</li>
</ul>
</li>
</ul>
<h3 id="❗️절차지향-vs-객체지향">❗️절차지향 VS 객체지향</h3>
<ul>
<li>설계방식<ul>
<li>절차적 프로그래밍은 프로그램의 순서와 흐름을 먼저 세우고 필요한 자료구조와 함수들을 설계하는 방식이다.</li>
<li>객체지향 프로그래밍은 반대로 자료 구조와 이를 중심으로 한 모듈 들을 먼저 설계한 후, 이들의 실행 순서와 흐름을 조합하는 방식이다.</li>
</ul>
</li>
<li>목적<ul>
<li>절차적 언어를 사용한다면, 말 그대로 실행 순서, 즉 절차가 더 중점이 된다.</li>
<li>객체지향 언어를 사용한다면, 필요한 객체들의 종류와 속성 등이 더 중점이 된다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] 영속성 컨텍스트]]></title>
            <link>https://velog.io/@tablemin_park/CS-%EC%98%81%EC%86%8D%EC%84%B1-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@tablemin_park/CS-%EC%98%81%EC%86%8D%EC%84%B1-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Thu, 15 Jun 2023 13:46:43 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/tablemin_park/post/9bb2290b-7f84-4d2b-beef-290883c62ccd/image.png" alt=""></p>
<h3 id="❗️영속성-컨텍스트란">❗️영속성 컨텍스트란?</h3>
<p>Server Side와 Database 사이에 엔티티를 저장하는 논리적인 영역이다. 엔티티 매니저로 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리한다.
영속성 컨텍스트는 엔티티 매니저를 생성할 때 하나 만들어진다. 그리고 엔티티 매니저를 통해서 영속성 컨텍스트에 접근할 수 있고, 관리할 수 있다.</p>
<blockquote>
<p>💡 엔티티의 생명주기
<img src="https://velog.velcdn.com/images/tablemin_park/post/650c7aba-3349-4c75-8ca7-d4f903bf625b/image.png" alt=""></p>
</blockquote>
<h4 id="✔️-비영속-상태">✔️ 비영속 상태</h4>
<p>객체를 생성만 하여 영속성 컨텍스트와 관계가 없는 상태</p>
<pre><code class="language-java">// 객체를 생성한 상태 (비영속)
Member member = new Member();
member.setId(&quot;member1&quot;);
member.setUsername(&quot;회원1&quot;);</code></pre>
<h4 id="✔️-영속-상태">✔️ 영속 상태</h4>
<p>객체를 생성 후 영속성 컨텍스트에 저장한 상태</p>
<pre><code class="language-java">// 객체를 생성한 상태 (비영속)
Member member = new Member();
member.setId(&quot;member1&quot;);
member.setUsername(&quot;회원1&quot;);
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// 객체를 저장한 상태 (영속)
em.persist(member);</code></pre>
<h4 id="✔️-준영속-상태">✔️ 준영속 상태</h4>
<p>영속성 컨텍스트에 저장되었다가 분리된 상태</p>
<pre><code class="language-java">// 회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태
em.detach(member);</code></pre>
<h4 id="✔️-삭제-상태">✔️ 삭제 상태</h4>
<p>삭제된 상태</p>
<pre><code class="language-java">// 객체를 삭제한 상태 (삭제)
em.remove(member);</code></pre>
<h3 id="❗️영속성-컨텍스트의-특징">❗️영속성 컨텍스트의 특징</h3>
<h4 id="1-영속성-컨텍스트와-식별자-값">1. 영속성 컨텍스트와 식별자 값</h4>
<blockquote>
<p>💡 @id 값으로 구분하기 때문에 @id 가 없는 엔티티는 JPA에서 사용할 수 없다.</p>
</blockquote>
<p>엔티티를 식별자 값(엔티티의 @id로 테이블의 기본키와 매핑한 값)으로 구분</p>
<h4 id="2-영속성-컨텍스트와-데이터베이스-저장">2. 영속성 컨텍스트와 데이터베이스 저장</h4>
<p>JPA는 보통 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 데이터베이스에 반영하게 되고 이 과정을 flush라고 한다.</p>
<h4 id="3-영속성-컨텍스트가-엔티티를-관리하는-것의-장점">3. 영속성 컨텍스트가 엔티티를 관리하는 것의 장점</h4>
<ul>
<li>동일성 보장
@id를 식별자로 사용하기 때문에 동일성을 보장한다.</li>
<li>트랜잭션을 지원하는 쓰기 지연<ol>
<li>회원 A 영속
<img src="https://velog.velcdn.com/images/tablemin_park/post/9e34e1f5-acb9-47f3-ac64-e18af77a880c/image.png" alt=""></li>
<li>회원 B 영속
<img src="https://velog.velcdn.com/images/tablemin_park/post/4bf3d521-99de-4eea-81c6-5e9d5bc7ea10/image.png" alt=""></li>
<li>트랜잭션이 끝나고 트랜잭션 커밋이 진행된다. 이후 쓰기 지연 된 SQL들을 한번에 Flush한다. 이후 데이터베이스 동기화가 진행되고, 실제 데이터베이스의 커밋을 진행한다.
<img src="https://velog.velcdn.com/images/tablemin_park/post/77848ee7-d82a-48a9-a2fb-6ce18756d8c4/image.png" alt=""></li>
</ol>
</li>
<li>변경 감지
영속성 컨텍스트를 사용하기 때문에 JPA는 엔티티를 수정할 때 단순히 엔티티를 조회하여 데이터만 변경하면 된다. 변경 감지 기능을 이용해서 데이터베이스에 자동 반영된다.</li>
<li>지연 로딩
실제 데이터가 필요한 순간에서야 데이터베이스를 조회하여 프록시 객체를 초기화한다. 만약 영속성 컨텍스트에 객체가 이미 존재한다면 프록시 객체가 아닌 실제 객체를 사용한다.</li>
<li>1차 캐시  </li>
</ul>
<h3 id="❗️1차-캐시--2차-캐시">❗️1차 캐시 &amp; 2차 캐시</h3>
<p><img src="https://velog.velcdn.com/images/tablemin_park/post/5c3ea18d-8dd5-4057-9cf8-f060b5b46098/image.png" alt=""></p>
<h4 id="1-1차-캐시">1. 1차 캐시</h4>
<p>영속성 내부에는 1차 캐시가 존재한다. 영속 상태의 엔티티를 이곳에서 저장하기 때문에 만약 엔티티를 조회했을 때 1차 캐시에 엔티티가 존재한다면 DB를 찾아보지 않는다. 캐시로써의 기능과 장점을 가지고 있다.</p>
<p>최초에 데이터에 접근할 때만 데이터베이스를 조회하여 데이터를 가져오고, 이후부터는 1차 캐시를 이용해 데이터를 반환한다. 그렇기 떄문에 반복 가능한 읽기 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공할 수 있다.</p>
<p>하지만 엔티티 매니저는 트랜잭션 단위로 만들고 해당 데이터베이스 트랜잭션이 끝날 때 같이 종료되기 때문에 1차 캐시 또한 소멸된다. 비즈니스 로직이 복잡할 경우에만 성능상 이득이 있다.</p>
<h4 id="2-2차-캐시">2. 2차 캐시</h4>
<p>애플리케이션 수준에서 공유하는 캐시이며 JPA에서는 공유 캐시라고도 한다. 2차 캐시는 애플리케이션을 종료할 때까지 유지된다. 2차 캐시를 적용 시, 엔티티 매니저를 통해 데이터를 조회할 때 우선 2차 캐시에서 찾고 없으면 데이터베이스를 조회한다. 이 때 2차 캐시는 동시성을 극대화하기 위해 캐시 한 객체를 직접 반환하지 않고 복사본을 만들어 반환한다. 캐시한 객체를 바로 반환하면 여러 곳에서 같은 객체를 동시에 수정하는 문제가 발생할 수 있기 때문에 복사하여 전달한다. 2차 캐시까지 사용하게 되면 애플리케이션 범위의 캐시이므로 데이터베이스 조회가 1차 캐시만 사용할 때 보다 획기적으로 줄어든다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] Filter와 Interceptor]]></title>
            <link>https://velog.io/@tablemin_park/CS-Filter%EC%99%80-Interceptor</link>
            <guid>https://velog.io/@tablemin_park/CS-Filter%EC%99%80-Interceptor</guid>
            <pubDate>Thu, 15 Jun 2023 12:46:45 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/tablemin_park/post/bd870ecc-c681-43a8-b22d-97da2cf9ed3e/image.png" alt=""></p>
<h3 id="❗️filter">❗️Filter</h3>
<ul>
<li>DispatcherServlet 이전에 실행된다.</li>
<li>모든 요청을 처리하는 DispatcherServlet 앞단에 실행되기 때문에 모든 일괄적인 요청에 대해 변경하거나 유효성 검사를 한곳에서 처리할 수 있다. (인코딩 변환, 로그인 여부확인, XSS방어)</li>
<li>스프링 빈이 아니므로 web.xml에 등록해야 한다.</li>
<li>Filter는 빈으로 등록되지 않아서 주입을 받을 수는 없지만 애플리케이션 컨텍스트의 생성된 빈들을 주입 받을 수는 있다. (Spring Security Filter)</li>
</ul>
<blockquote>
<p>💡 DispatcherServlet이란 HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아 적합한 컨트롤러에 위임해주는 프론트 컨트롤러이다. 
클라이언트로부터 어떠한 요청이 오면 Tomcat과 같은 서블릿 컨테이너가 요청을 받게 되고, 이 모든 요청을 프론트 컨트롤러인 디스패처 서블릿이 가장 먼저 받게 된다. 이후 디스패처 서블릿은 공통적인 작업을 먼저 처리한 후에 해당 요청을 처리해야하는 컨트롤러를 찾아서 작업을 위임한다.</p>
</blockquote>
<h3 id="❗️interceptor">❗️Interceptor</h3>
<ul>
<li>Interceptor는 DispatcherServlet 다음에 실행되는 스프링 내부 영역으로 Application Context 내에서 관리되므로 Bean으로 등록할 수 있다.</li>
<li>Interceptor는 특정 HandlerMapping에 종속되어 다양한 전략의 Interceptor를 생성할 수 있다.</li>
<li>Interceptor는 @ControllerAdvice, @ExceptionHandler를 이용해 예외처리가 가능하다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] JPA]]></title>
            <link>https://velog.io/@tablemin_park/CS-JPA</link>
            <guid>https://velog.io/@tablemin_park/CS-JPA</guid>
            <pubDate>Wed, 14 Jun 2023 09:26:54 GMT</pubDate>
            <description><![CDATA[<p>JPA(Java Persistence Api)는 자바 진영에서 ORM(Object-Relational Mapping) 기술 표준으로 사용되는 인터페이스 모음이다. 실제로 구현된 것이 아니라 구현된 클래스와 매핑을 해주기 위해 사용되는 프레임워크이다. JPA를 구현한 대표적인 오픈소스로는 Hibernate가 있다.</p>
<h3 id="❗️orm이란">❗️ORM이란?</h3>
<p>일반적으로 애플리케이션 Class와 RDB(Relational Database)의 테이블을 매핑(연결)한다는 것을 의미하며, 기술적으로는 애플리케이션 객체를 RDB 테이블에 자동으로 영속화 해주는 것이다.</p>
<blockquote>
<p>💡 <strong>영속화</strong>란 영속성 컨텍스트에 관리되는 상태로 만드는 것을 의미한다. 여기서 <strong>영속성 컨텍스트</strong>란 엔티티를 영구 저장하는 환경이라는 뜻을 가지고 있다. DB에 저장한다는 것이 아니라 영속성 컨텍스트를 통해서 엔티티를 영속화 한다는 뜻이다.</p>
</blockquote>
<h3 id="❗️orm-장단점">❗️ORM 장단점</h3>
<ul>
<li>장점<ol>
<li>SQL문이 아닌 Method를 통해 DB를 조작할 수 있어, 개발자는 객체 모델을 이용해서 비즈니즈 로직을 구성하는데 집중할 수 있다.</li>
<li>Query와 같이 필요한 질의문, 할당 등의 부수적인 코드가 줄어들어, 각종 객체에 대한 코드를 별도로 작성하여 코드 가독성을 높일 수 있다.</li>
<li>객체지형적인 코드 작성이 가능하다. 오직 객체지향적 접근만 고려하면 되기 때문에 생산성이 높아진다.</li>
<li>매핑하는 정보가 Class로 명시 되었기 때문에 ERD를 보는 의존도를 낮출 수 있고 유지보수 및 리팩토링에 유리하다.</li>
</ol>
</li>
<li>단점<ol>
<li>프로젝트 규모가 크고 복잡하여 설계가 잘못된 경우, 속도 저하 및 일관성을 무너뜨리는 문제점이 발생할 수 있다.</li>
<li>복잡하고 무거운 Query는 속도를 위해 별도의 튜닝이 필요하기 때문에 결국 SQL문을 써야할 수도 있다.</li>
</ol>
</li>
</ul>
<h3 id="❗️jpa란">❗️JPA란?</h3>
<p><img src="https://velog.velcdn.com/images/tablemin_park/post/3001dbcf-73d2-4190-a328-8941e437606b/image.png" alt="JPA 관계">
Java 진영에서 ORM 기술 표준으로 사용하는 인터페이스 모음으로, 자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스이다. Hibernate, OpenJPA 등이 JPA 인터페이스를 구현한 구현체이다.</p>
<p>JPA는 반복적인 CRUD SQL을 처리한다. 매핑된 관계를 이용해서 SQL을 생성하고 실행하는데, 개발자는 어떤 SQL이 실행될지 생각만하면 되고, 예측도 쉽게할 수 있다. 추가적으로 JPA는 네이티브 SQL이란 기능을 제공하는데 관계 매핑이 어렵거나 성능에 대한 이슈가 우려되는 경우 SQL을 직접 작성하여 사용할 수 있다.</p>
<h3 id="❗️jpa-장단점">❗️JPA 장단점</h3>
<ul>
<li><p>장점</p>
<ol>
<li>1차 캐시, 쓰기지연, 변경감지, 지연로딩 등을 제공하여 성능상 이점을 얻을 수 있다.</li>
<li>코드 레벨로 관리가 되므로 사용하기 용이하고 생산성이 높다.</li>
<li>컴파일 타임에 오류를 확인할 수 있다.</li>
<li>데이터베이스에 종속적이지 않으므로 특정 쿼리를 사용하지 않아 추상적으로 기술 구현이 가능하다.</li>
<li>엔티티로 관리되므로 스키마 변경시 엔티티만 수정하게 되면 엔티티를 사용하는 관련 쿼리는 자동으로 변경된 내역이 반영된다.</li>
<li>개발 초기에는 쿼리에 대한 이해가 부족해도 코드 레벨로 어느 정도 커버가 가능하다.</li>
<li>객체지향적으로 데이터를 관리할 수 있다.</li>
<li>부족한 부분은 다양한 쿼리 빌더와 호환하여 보완할 수 있다.</li>
</ol>
</li>
<li><p>단점</p>
<ol>
<li>JPA만 사용하여 복잡한 연산을 수행하기에는 무리가 있다. (로직이 복잡하거나 불필요한 쿼리가 발생할 수 있다.)</li>
<li>초기에는 생산성이 높을 수 있으나 점차 사용하다 보면 성능상 이슈가 발생할 수 있다. (N+1, FetchType, Proxy, 연관관계)</li>
<li>고도화 될수록 학습 곡선이 높아질 수 있다. (성능 이슈의 연장선으로 해결 방안에 따라 복잡한 내부 로직을 이해해야 할 필요가 있다.)</li>
</ol>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] Spring 이란?]]></title>
            <link>https://velog.io/@tablemin_park/CS-Spring-%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@tablemin_park/CS-Spring-%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Thu, 25 May 2023 12:00:30 GMT</pubDate>
            <description><![CDATA[<h3 id="❗-스프링-프레임워크란">❗ 스프링 프레임워크란?</h3>
<ul>
<li>IOC/DI, AOP, PSA를 제공해주는 프레임워크</li>
<li>IOC Container를 기반으로 객체지향 설계를 도와주는 프레임워크</li>
<li>Bean의 생명주기와 주입 등을 제공해주는 프레임워크</li>
<li>POJO를 도와주는 툴</li>
<li>객체지향적으로 설계한 POJO를 유지하며 애플리케이션을 쉽고 효과적으로 개발할 수 있도록 지원하는 프레임워크</li>
</ul>
<h3 id="❗-스프링-프레임워크-특징">❗ 스프링 프레임워크 특징</h3>
<p>엔터프라이즈 서비스 기술을 POJO 방식으로 개발된 애플리케이션 핵심 로직을 담은 코드에 제공하는 것이 스프링의 가장 강력한 특징과 목표이다.</p>
<ul>
<li><p>IOC / DI</p>
<ul>
<li><p>두개의 오브잭트를 분리해서 만들고, 인터페이스를 두어 느슨하게 연결한 뒤 실제 사용할 대상은 DI를 통해 외부에서 주입받는다.</p>
</li>
<li><p>활용방법</p>
<ul>
<li>의존 대상의 구현을 변경</li>
<li>핵심기능의 동적인 변경</li>
<li>부가기능 추가 </li>
<li>프록시 : 필요한 시점에서 실제 사용할 오브젝트를 초기화하고 리소스를 준비하게 해주는 지연 로딩을 적용하려고 할 때</li>
<li>템플릿 / 콜백 : 콜백을 얼마든지 만들어서 사용할 수 있다는 건 개발을 통한 유연한 확장성을 보여주는 것이며, 템플릿은 한 번 만들어두면 계속 재상요할 수 있다는 건 확장에도 변하지 않는다.</li>
<li>싱글톤과 오브젝트 : DI를 프레임워크로 이용한다는 건 DI 대상 오브젝트를 컨테이너가 관리한다는 의미이다. 스프링에서는 싱글톤 외에도 다양한 스코프를 갖는 오브젝트를 만들어 DI에 사용할 수도 있다. HTTP 요청 당 하나의 오브젝트가 만들어지거나, HTTP 세션 당 하나씩 오브젝트를 만들어지게 할 수 있다.</li>
</ul>
</li>
</ul>
</li>
<li><p>AOP</p>
<ul>
<li>공통 관심 사항을 구현한 코드를 비즈니스 로직에 영향 없이 삽입해 주는 기술이라고 할 수 있다.</li>
</ul>
</li>
<li><p>PSA</p>
<ul>
<li>PSA는 환경과 세부 기술의 변화에 관계없이 일관된 방식으로 기술에 접근할 수 있게 해준다.</li>
<li>서비스의 추상화의 좋은예는 JDBC<ul>
<li>JDBC라는 표준스펙이 존재하기 때문에 DBMS를 오라클을 사용하던, MYSQL을 사용하던 공통된 방식으로 코드를 작성할 수 있다. 데이터베이스 종류에 관계없이 같은 방식으로 제어할 수 있는 디자인 패턴(어댑터 패턴)을 적용해 다수의 기술을 공통 인터페이스로 제어할 수 있도록 한 것을 서비스 추상화라고 한다.</li>
</ul>
</li>
</ul>
</li>
<li><p>IOC Container
스프링 스테레오 타입의 객체들을 싱글톤으로 관리하고 다른 객체에 주입이 필요하다면 IoC Container가 직접 주입도 시켜준다. 여기서 제어의 역전(IOC)이 발생한다. 객체는 특정 객체가 아닌 타입에 의존하게 되면서 실제 구현체에 대해서는 모르는 상태를 유지하는 것이다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] REST API]]></title>
            <link>https://velog.io/@tablemin_park/CS-REST-API</link>
            <guid>https://velog.io/@tablemin_park/CS-REST-API</guid>
            <pubDate>Fri, 14 Apr 2023 12:28:45 GMT</pubDate>
            <description><![CDATA[<h3 id="❗-rest의-요소">❗ REST의 요소</h3>
<ul>
<li><p>Method</p>
<blockquote>
<p>💡 <a href="https://velog.io/@tablemin_park/CS-HTTP-Request-Methods">HTTP Request Methods</a> </p>
</blockquote>
<ul>
<li>POST : CREATE</li>
<li>GET : SELECT</li>
<li>PUT : UPDATE</li>
<li>DELETE : DELETE</li>
</ul>
</li>
<li><p>Resource</p>
<ul>
<li><a href="https://github.com/tableMinPark">https://github.com/tableMinPark</a> 과 같은 URI를 의미한다.</li>
<li>모든 것을 Resource (명사)로 표현하고, 세부 Resource에는 ID를 붙힌다.</li>
</ul>
</li>
</ul>
<h3 id="❗-rest-특징">❗ REST 특징</h3>
<ul>
<li>Uniform Interface<ul>
<li>HTTP 표준만 맞는다면, 어떤 기술도 가능한 Interface 스타일</li>
</ul>
</li>
<li>Statelessness<ul>
<li>HTTP Session과 같은 컨텍스트 저장소에 상태 정보를 저장하지 않는다.</li>
<li>Request만 Message로 처리하면 되고, 컨텍스트 정보를 신경쓰지 않아도 되므로, 구현이 단순해진다.</li>
<li>REST API 실행 중 실패가 발생한 경우, Transaction 복구를 위해 기존의 상태를 저장할 필요가 있다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] HTTP Request Methods]]></title>
            <link>https://velog.io/@tablemin_park/CS-HTTP-Request-Methods</link>
            <guid>https://velog.io/@tablemin_park/CS-HTTP-Request-Methods</guid>
            <pubDate>Fri, 14 Apr 2023 12:16:57 GMT</pubDate>
            <description><![CDATA[<h3 id="❗-get-method">❗ GET Method</h3>
<ul>
<li>리소스를 받기 위한 메서드</li>
<li>URL 형식으로 서버 측에 리소스를 요청한다.</li>
<li>파라미터를 query string을 통해 전달한다.</li>
</ul>
<h3 id="❗-head-method">❗ HEAD Method</h3>
<ul>
<li>메세지 헤더 정보를 받기 위한 메서드</li>
<li>GET 과 유사하지만, HEAD는 실제 문서 요청이 아닌 문서에 대한 정보 요청이다.</li>
<li>응답을 받았을 때, Body는 비어있고, Header 정보만 들어있다.</li>
</ul>
<h3 id="❗-post-method">❗ POST Method</h3>
<ul>
<li>내용 및 파일 전송을 하기 위한 메서드</li>
<li>클라이언트에서 서버로 어떤 정보를 제출하기 위해 사용한다.</li>
<li>Request 데이터를 HTTP Body에 담아 웹 서버로 전송한다.</li>
</ul>
<h3 id="❗-put-method">❗ PUT Method</h3>
<ul>
<li>리소스를 갱신하기 위한 메서드</li>
<li>POST 와 유사하지만, 기존 데이터를 갱신할 때 사용한다.</li>
</ul>
<h3 id="❗-delete-method">❗ DELETE Method</h3>
<ul>
<li>리소스를 삭제하기 위한 메서드</li>
<li>웹 서버 측에 요청한 리소스를 삭제할 때 사용한다.</li>
<li>실제로는 서버 자원을 삭제하도록 하지 않기 때문에 비활성화하는 요청에 사용된다.</li>
</ul>
<h3 id="❗-connect-method">❗ CONNECT Method</h3>
<ul>
<li>클라이언트와 서버 사이의 중간 경유를 위한 메서드</li>
<li>보통 Proxy를 통해 SSL 통신을 하고자할 떄 사용된다.</li>
</ul>
<h3 id="❗-options-method">❗ OPTIONS Method</h3>
<ul>
<li>서버 측 제공 메서드에 대한 질의를 하기 위한 메서드</li>
<li>웹 서버 측에서 지원하고 있는 메서드가 무엇인지 파악하기 위해 사용된다.</li>
</ul>
<h3 id="❗-trace-method">❗ TRACE Method</h3>
<ul>
<li>Request 리소스가 수신되는 경로르 보기 위한 메서드</li>
<li>웹 서버로부터 받은 내용을 확인하기 위해 loop-back 테스트를 할 떄 사용된다.</li>
</ul>
<h3 id="❗-patch-method">❗ PATCH Method</h3>
<ul>
<li>리소스의 일부분만 갱신하기 위한 메서드</li>
<li>PUT 과 유사하지만, 모든 데이터를 갱신하는 것이 아니라, 리소스의 일부분만 수정할 때 사용된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] 쿠기 & 세션]]></title>
            <link>https://velog.io/@tablemin_park/CS-%EC%BF%A0%EA%B8%B0-%EC%84%B8%EC%85%98</link>
            <guid>https://velog.io/@tablemin_park/CS-%EC%BF%A0%EA%B8%B0-%EC%84%B8%EC%85%98</guid>
            <pubDate>Fri, 14 Apr 2023 11:02:44 GMT</pubDate>
            <description><![CDATA[<h3 id="❗-쿠키란">❗ 쿠키란?</h3>
<ul>
<li>클라이언트 로컬에 저장되는 키와 값이 들어있는 작은 데이터 파일이다.</li>
<li>사용자 인증이 유효한 시간을 명시할 수 있으며, 유효 시간이 정해지면 브라우저가 종료되어도 인증이 유지된다는 특징이 있다.</li>
<li>클라이언트의 상태 정보를 로컬에 저장했다가 참조한다.</li>
<li>클라이언트에 <strong>300개까지 쿠키저장이 가능</strong>하며, 하나의 도메인당 <strong>20개의 값</strong>만 가질 수 있고 쿠키값은 <strong>4KB</strong>까지 저장할 수 있다.</li>
<li>쿠키는 사용자가 따로 요청하지 않아도 브라우저가 Request시에 Request Header를 넣어서 자동으로 서버에 전송한다.</li>
</ul>
<h3 id="❗-쿠키의-구성-요소">❗ 쿠키의 구성 요소</h3>
<ul>
<li>이름 : 각각의 쿠기를 구별하는데 사용하는 이름</li>
<li>값 : 쿠키의 이름과 관련된 값</li>
<li>유효시간 : 쿠키의 유지시간</li>
<li>도메인 : 쿠키를 전송할 도메인</li>
<li>경로 : 쿠키를 전송할 요청 경로</li>
</ul>
<h3 id="❗-쿠키의-동작-방식">❗ 쿠키의 동작 방식</h3>
<ol>
<li>클라이언트가 페이지를 요청한다.</li>
<li>서버에서 쿠키를 생성한다.</li>
<li>HTTP 헤더에 쿠키를 함께 보낸다.</li>
<li>브라우저가 종료되어도 쿠키 만료 기간이 있다면 클라이언트에서 보관하고 있다.</li>
<li>같은 요청 시 HTTP 헤더에 쿠키를 함께 보낸다.</li>
<li>서버에서 쿠키를 읽어 이전 상태 정보를 변경할 필요가 있을 때 쿠키를 업데이트 하여 변경된 쿠키를 HTTP 헤더에 포함시켜서 응답한다.</li>
</ol>
<h3 id="❗-세션이란">❗ 세션이란?</h3>
<ul>
<li>세션은 쿠키를 기반하고 있지만, 사용자 정보 파일을 브라우저에 저장하는 쿠키와 달리 세션은 서버측에서 관리한다.</li>
<li>서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여하며 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지한다.</li>
<li>사용자 정보를 서버에서 관리하기 때문에 보안에 좋지만, 사용자가 많아질수록 서버 메모리를 많이 차지하게 된다.</li>
<li>클라이언트가 Request를 보내면, 해당 서버 엔진이 클라이언트에게 유일한 세션 ID를 부여한다.</li>
</ul>
<h3 id="❗-세션의-동작-방식">❗ 세션의 동작 방식</h3>
<ol>
<li>클라이언트가 서버에 접속 시 세션 ID를 발급받는다.</li>
<li>클라이언트는 세션 ID를 쿠키로 저장해서 가지고 있다.</li>
<li>클라이언트는 서버에 요청할 때, 쿠키로 저장되어 있는 세션 ID를 같이 서버에 전달해서 요청한다.</li>
<li>서버는 세션 ID를 전달 받아서 별다른 작업없이 세션 ID로 세션에 있는 클라이언트 정보를 가져와서 사용한다.</li>
<li>클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답한다.</li>
</ol>
<h3 id="❗-쿠키와-세션을-사용하는-이유">❗ 쿠키와 세션을 사용하는 이유</h3>
<ul>
<li>HTTP의 특성이자 약점을 보완하기 위해서 쿠키 또는 세션을 사용한다.</li>
<li>기본적으로 HTTP 프로토콜 환경은 &#39;connectionless&#39;, &#39;stateless&#39; 한 특성을 가지기 때문에 서버는 클라이언트가 누구인지 매번 확인을 해야 하는데, 이 단점을 보완하기 위해서 사용한다.</li>
</ul>
<blockquote>
<p>💡 connectionless : 클라이언트가 요청을 한 후 응답을 받으면 그 연결을 끊어 버리는 특징</p>
</blockquote>
<blockquote>
<p>💡 stateless : 통신이 끝나면 상태를 유지하지 않는 특징</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] 브라우저 동작 방법]]></title>
            <link>https://velog.io/@tablemin_park/Web-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%8F%99%EC%9E%91-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@tablemin_park/Web-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%8F%99%EC%9E%91-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Thu, 13 Apr 2023 16:43:58 GMT</pubDate>
            <description><![CDATA[<h3 id="❗-브라우저-주요-기능">❗ 브라우저 주요 기능</h3>
<ul>
<li>사용자가 선택한 자원을 서버에 요청하고 응답을 브라우저에 표시한다.</li>
<li>자원은 html 문서, pdf, image 등 다양한 형태이다.</li>
<li>자원의 주소는 URI에 의해 정해진다.</li>
<li>html 과 css 명세에 따라 html 파일을 해석해서 표시한다.</li>
<li>브라우저가 가진 인터페이스는 보통 비슷한 요소들이 존재한다.</li>
</ul>
<h3 id="❗-브라우저-기본-구조">❗ 브라우저 기본 구조</h3>
<p><img src="https://velog.velcdn.com/images/tablemin_park/post/2b4ea926-4457-4221-a95a-4ae6c1b0754c/image.png" alt=""></p>
<ol>
<li><p>사용자 인터페이스 </p>
<ul>
<li>주소 표시줄, 이전/다음 버튼, 북마크 등 사용자가 활용하는 서비스들</li>
<li>요청한 페이지를 보여주는 창을 제외한 나머지 부분</li>
</ul>
</li>
<li><p>브라우저 엔진</p>
<ul>
<li>사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어한다.</li>
</ul>
</li>
<li><p>렌더링 엔진</p>
<ul>
<li>요청한 콘텐츠 표시</li>
</ul>
</li>
<li><p>통신</p>
<ul>
<li>html 요청과 같은 네트워크 호출에 사용한다.</li>
</ul>
</li>
<li><p>UI 백앤드</p>
<ul>
<li>플랫폼에서 명시하지 않은 일반적 인터페이스, 콤보 박스 창같은 기본적 장치를 </li>
</ul>
</li>
<li><p>자바 스크립트 해석기</p>
<ul>
<li>자바 스크립트 코드를 해석하고 실행</li>
</ul>
</li>
<li><p>자료 저장소</p>
<ul>
<li>쿠기, 등 모든 종류의 자원을 하드 디스크에 저장하는 계층</li>
</ul>
</li>
</ol>
<h3 id="❗-dom-document-object-model">❗ DOM (Document Object Model)</h3>
<ul>
<li>html이나 body 태그들을 자바 스크립트가 활용할 수 있는 객체로 만들면 문서 객체가 된다.</li>
<li>웹 브라우저가 html 페이지를 인식하는 방식을 말한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] C 컴파일 과정]]></title>
            <link>https://velog.io/@tablemin_park/CS-C-%EC%BB%B4%ED%8C%8C%EC%9D%BC-%EA%B3%BC%EC%A0%95</link>
            <guid>https://velog.io/@tablemin_park/CS-C-%EC%BB%B4%ED%8C%8C%EC%9D%BC-%EA%B3%BC%EC%A0%95</guid>
            <pubDate>Thu, 23 Mar 2023 10:55:27 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/tablemin_park/post/279192af-d14c-4c2d-8b9d-dd9ff82d74c0/image.png" alt=""></p>
<h3 id="📌-1-전처리-과정">📌 1. 전처리 과정</h3>
<ul>
<li>헤더파일 삽입 
#include 구문을 만나면 헤더 파일을 찾아 내용을 순차적으로 삽입한다.</li>
<li>매크로 치환 및 적용
#define, #ifdef 과 같은 전처리기 매크로 치환 및 처리한다.</li>
</ul>
<h3 id="📌-2-컴파일-과정-전단부---중단부---후단부">📌 2. 컴파일 과정 (전단부 - 중단부 - 후단부)</h3>
<ul>
<li><p>전단부
<img src="https://velog.velcdn.com/images/tablemin_park/post/947abbdf-8c02-4da3-9e3a-1d1f4e083822/image.png" alt=""></p>
<ol>
<li>어휘 분석 : C 소스코드를 의미가 있는 최소단위로 나눔</li>
<li>구문 분석 : 토큰으로 파스트리를 만들면서 문법적 오류를 검출</li>
<li>의미 분석 : 파스트리를 이용해 의미상 오류를 검출</li>
<li>중간 표현 생성 : 언어 독립적인 특성을 제공하기 위해 트리 형태의 중간표현을 생성</li>
</ol>
</li>
<li><p>중단부</p>
<blockquote>
<p>💡 최적화가 중요한 이유는 한번 컴파일 되고 나면 변경이 불가능하기 때문에 최적화를 수행함으로써 컴파일 시간이 길어지더라도 프로그램 수행속도를 향상시켜 전체 시스템 성능의 효율을 지속적으로 높여주기 위함이다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tablemin_park/post/8366d212-f5ac-41ac-a715-42b2fbb490e5/image.png" alt=""></p>
<ol>
<li><p>SSA(Static Single Assignment) 구조로 변환</p>
<blockquote>
<p>💡 비종속적인 최적화 : 서로 다른 CPU 아키텍쳐에 구애받지 않고 공통적으로 수행할 수 있는 최적화를 말한다.</p>
</blockquote>
<p>아키텍쳐 비종속적인 최적화를 수행한다.</p>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/tablemin_park/post/9cd88bc0-76d7-4836-b3ab-a869dcfefafd/image.png" alt=""></p>
<ol start="2">
<li>RTL(Register Transfer Language) 구조로 변환 <blockquote>
<p>💡 RTL : 고급 언어와 어셈블리 언어의 중간 형태</p>
</blockquote>
</li>
</ol>
</li>
</ul>
<ul>
<li><p>후단부
<img src="https://velog.velcdn.com/images/tablemin_park/post/576cd1be-369e-431b-9134-84f598fa45ed/image.png" alt=""></p>
<p>RTS로 아키텍처 최적화 수행 - 더 효율적인 명령어로 대체해서 성능 높이기 위함</p>
</li>
</ul>
<h3 id="📌-어셈블-과정">📌 어셈블 과정</h3>
<p>컴파일이 끝난 어셈블리 코드는 어셈블러에 의해 기계어로 어셈블된다.</p>
<p>어셈블러에 의해 생성되는 목적코드(source.o) 파일은 어셈블된 프로그램의 명령어와 데이터가 들어있는 ELF 바이너리 포멧 구조를 갖는다.</p>
<p>다음 단계인 링킹에서 링커가 여러개의 바이너리 파일을 하나의 실행 파일로 묶기 위해서 각 바이너리 정보를 효과적으로 파악하기 위해서 일정한 규칙을 갖게 형식화 해놓는다.</p>
<h3 id="📌-링킹-과정">📌 링킹 과정</h3>
<p>링커는 오브젝트 파일들과 프로그램에서 사용된 표준 C 라이브러리, 사용자 라이브러리들을 링크한다.</p>
<p>링킹 과정이 끝나면 실행 가능한 실행파일이 만들어지게 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] 자바 가상 머신]]></title>
            <link>https://velog.io/@tablemin_park/CS-%EC%9E%90%EB%B0%94-%EA%B0%80%EC%83%81-%EB%A8%B8%EC%8B%A0</link>
            <guid>https://velog.io/@tablemin_park/CS-%EC%9E%90%EB%B0%94-%EA%B0%80%EC%83%81-%EB%A8%B8%EC%8B%A0</guid>
            <pubDate>Thu, 16 Mar 2023 11:39:54 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>💡 시스템 메모리를 관리하면서, 자바 기반 애플리케이션을 위해 이식 가능한 실행 환경을 제공하는 것</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tablemin_park/post/a9e4aaca-f72f-437e-88ad-c40cd6c517fc/image.png" alt=""></p>
<h3 id="📌-jvm">📌 JVM?</h3>
<ul>
<li>자바 프로그램 실행 환경을 만들어주는 소프트웨어</li>
<li>Java는 플랫폼에 종속적이지 않지만 JVM은 플랫폼에 종속적이다.</li>
</ul>
<pre><code>Java는 어떠한 플랫폼(OS)에 영향을 받지 않는다.</code></pre><h3 id="📌-jvm-장점">📌 JVM 장점</h3>
<ul>
<li>하나의 바이트코드 (.class)로 모든 플랫폼에서 동작하도록 할 수 있다.</li>
</ul>
<h3 id="📌-jvm에서의-메모리-관리">📌 JVM에서의 메모리 관리</h3>
<ol>
<li>프로그램이 실행되면, JVM은 OS로부터 프로그램이 필요로하는 메모리를 할당받는다.</li>
<li>자바 컴파일러(Javac)가 자바 소스코드를 읽고, 자바 바이트코드(.class)로 변환 시킨다.</li>
<li>변경된 class 파일들을 클래스 로더를 통해 JVM 메모리 영역으로 로딩한다.</li>
<li>로딩된 class 파일들은 Execution engine을 통해 해석된다.</li>
<li>해석된 바이트 코드는 메모리 영역에 배치되어 실질적인 수행이 이루어진다.</li>
</ol>
<h3 id="📌-jvm의-구성요소">📌 JVM의 구성요소</h3>
<ol>
<li>자바 컴파일러
자바 소스코드를 바이트 코드로 변환시켜준다.</li>
<li>클래스 로더
JVM은 런타임 시 처음으로 클래스를 참조할 때 해당 클래스를 로드하고 메모리 영역에 배치시킨다.
이 동적 로드를 담당하는 부분이 클래스 로더이다.</li>
<li>Runtime Data Areas<ul>
<li>PC 레지스터
스레드가 어떤 명령어로 실행되어야 할지를 기록하는 영역이다. (JVM 명령의 주소를 가진다.)</li>
<li>Stack
지역변수, 매개변수, 메서드 정보, 임시 데이터 등을 저장하는 영역이다.</li>
<li>Native Stack
실제 실행할 수 있는 기계어로 작성된 프로그램을 실행시키는 영역이다.</li>
<li>Heap
런타임 영역에 동적으로 할당되는 데이터가 저장되는 영역이다. (객체, 배열 등)</li>
<li>Method
JVM이 시작될 때 생성되고, JVM이 읽은 각각의 클래스와 인터페이스에 대한 런타임 상수 풀, 필드 및 메서드 코드, 정적변수, 메서드의 바이트 코드 등을 보관하는 영역이다.</li>
</ul>
</li>
<li>가비지 컬렉션
자바 프로그램에서 사용되지 않는 메모리를 지속적으로 찾아내서 제거하는 역할을 한다.<blockquote>
<p>💡 실행순서</p>
<ol>
<li>참조되지 않은 객체들을 탐색 후 삭제</li>
<li>삭제된 객체의 메모리 반환</li>
<li>힙 메모리 재사용</li>
</ol>
</blockquote>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] Thread]]></title>
            <link>https://velog.io/@tablemin_park/CS-Thread</link>
            <guid>https://velog.io/@tablemin_park/CS-Thread</guid>
            <pubDate>Thu, 09 Mar 2023 12:02:21 GMT</pubDate>
            <description><![CDATA[<h3 id="📌-thread">📌 Thread?</h3>
<ul>
<li>메모리를 할당받아 실행 중인 프로그램을 프로세스라고 하는데 프로세스 내에서 실행되는 흐름의 단위를 의미한다.</li>
<li>실행중에 멈출 수 있으며 동시에 수행이 가능하다.</li>
</ul>
<h3 id="📌-thread-생성">📌 Thread 생성</h3>
<ol>
<li>Thread 클래스를 상속받아 생성<pre><code class="language-java">// 선언
class ThreadA extends Thread {
 public void run() {
     // Thread 내에서 실행할 코드
 }
}
</code></pre>
</li>
</ol>
<p>// 생성 및 사용
ThreadA TA = new ThreadA();
// Thread는 start 메서드를 통해 시작할 수 있다.
TA.start();</p>
<pre><code>2. Runnable 인터페이스를 구현하여 생성
```java
// 선언
public class RunnableTest implements Runnable{
    public void run() {
        try {
            // Thread 내에서 실행할 코드
        } catch(InterruptedException e){
            e.printStackTrace();
        }
    }
}

// 생성 및 사용
RunnableTest runnable = new RunnableTest();
Thread th = new Thread(runnable);
th.start();</code></pre><h3 id="📌-thread의-특징">📌 Thread의 특징</h3>
<ul>
<li>run() 메소드가 종료하면 Thread는 종료된다.</li>
<li>한번 종료한 Thread는 다시 시작시킬 수 없다.</li>
<li>한 Thread에서 다른 Thread를 강제 종료할 수 있다.</li>
</ul>
<h3 id="📌-thread의-상태">📌 Thread의 상태</h3>
<ol>
<li>NEW
Thread가 생성되었지만 Thread가 아직 실행할 준비가 되지 않은 상태</li>
<li>RUNNABLE
Thread가 실행되고 있거나 실행준비되어 스케줄링을 기다리고 있는 상태</li>
<li>WAITING
다른 Thread가 notify(), notifyAll()을 불러주기를 기다리고 있는 상태 (동기화)</li>
<li>TIMED_WAITING
Thread가 sleep(n) 호출로 인해 n 밀리초동안 잠을 자고 있는 상태</li>
<li>BLOCK
Thread가 I/O작업을 요청하면 자동으로 Thread를 BLOCK상태로 만든다.</li>
<li>TERMINATED
Thread가 종료된 상태</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] Casting]]></title>
            <link>https://velog.io/@tablemin_park/CS-Casting</link>
            <guid>https://velog.io/@tablemin_park/CS-Casting</guid>
            <pubDate>Wed, 08 Mar 2023 11:51:48 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>💡 캐스팅이란?
모든 연산을 진행할 때에는 같은 타입의 피연산자끼리만 수행이 가능한데, 이 때 다른 타입의 피연산자끼리 연산을 수행할 필요가 있을 경우 같은 타입으로 변경해주는 것이다.</p>
</blockquote>
<pre><code class="language-java">int a = 0.1;        // 에러 발생 X
int b = (int) true;    // 에러 발생 O, boolean은 int로 캐스트가 불가능하다.</code></pre>
<h3 id="📌-casting이-필요한-이유">📌 Casting이 필요한 이유</h3>
<ol>
<li>다형성
오버라이딩 된 함수를 분리해서 사용할 수 있다.</li>
<li>상속
캐스팅을 통해 범용적인 프로그래밍이 가능하다.</li>
</ol>
<h3 id="📌-형변환의-종류">📌 형변환의 종류</h3>
<ol>
<li>묵시적 형변환</li>
</ol>
<ul>
<li>캐스팅이 자동으로 발생한다. (업캐스팅)</li>
<li>자식 클래스에서 부모 클래스로 형변환하는 것이다.<pre><code class="language-java">// Parent를 상속받은 Child는 Parent의 속성을 포함하고 있기 떄문에 캐스팅을 명시할 필요가 없다.
Parent p = new Child();</code></pre>
</li>
</ul>
<ol start="2">
<li>명시적 형변환</li>
</ol>
<ul>
<li>캐스팅할 내용을 적어줘야 하는 경우 (다운캐스팅)</li>
<li>업캐스팅 한 것을 다시 원래의 형으로 복원 시켜주는 것이다.</li>
<li>업캐스팅과는 다르게 원래의 형을 꼭 명시해줘야 한다.<pre><code class="language-java">// 다운캐스팅은 업캐스팅이 발생한 이후에 작용한다.
Parent p = new Child();
child c = (Child) p;</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] 오브젝트 클래스]]></title>
            <link>https://velog.io/@tablemin_park/CS-%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-%ED%81%B4%EB%9E%98%EC%8A%A4</link>
            <guid>https://velog.io/@tablemin_park/CS-%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-%ED%81%B4%EB%9E%98%EC%8A%A4</guid>
            <pubDate>Wed, 08 Mar 2023 11:24:09 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>💡 Java의 최상위 클래스 = Object 클래스</p>
</blockquote>
<h3 id="📌-object-클래스의-메서드">📌 Object 클래스의 메서드</h3>
<ul>
<li>equals()<ul>
<li>두 객체가 동일한 객체라면 true를 리턴하고, 다르면 false를 리턴한다.</li>
</ul>
</li>
<li>toString()<ul>
<li>객체의 문자 정보를 리턴한다.</li>
<li>객체를 문자열로 표현한다.</li>
</ul>
</li>
<li>hashCode()<ul>
<li>객체의 메모리 주소를 이용해서 해시코드를 만들어 리턴한다.</li>
</ul>
</li>
<li>wait()<ul>
<li>갖고 있던 고유 락을 해제한다.</li>
<li>Thread를 잠들게 한다.</li>
</ul>
</li>
<li>notify()<ul>
<li>잠든 Thread 중 임의의 하나를 꺠운다.</li>
</ul>
</li>
<li>notifyAll()<ul>
<li>잠든 모든 Thread를 꺠운다.</li>
</ul>
</li>
</ul>
<blockquote>
<p>💡 wait, notify, notifyAll은 호출하는 쓰래드가 반드시 고유 락을 갖고 있어야 한다.</p>
<ul>
<li>Synchronized 블록 내에서 실행되어야 한다.</li>
<li>일반 블록 안에서 호출하는 경우 IllegalMonitorStateException이 발생한다.</li>
</ul>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>