<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev_ws.journey</title>
        <link>https://velog.io/</link>
        <description>반갑습니다람지</description>
        <lastBuildDate>Fri, 14 Jun 2024 01:08:19 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dev_ws.journey</title>
            <url>https://velog.velcdn.com/images/calis_ws/profile/d53d7d70-0d97-4985-80d1-6ea5a6db52e8/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dev_ws.journey. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/calis_ws" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Java] JDK, JRE, JVM 이란?]]></title>
            <link>https://velog.io/@calis_ws/Java-JDK-JRE-JVM-%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@calis_ws/Java-JDK-JRE-JVM-%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Fri, 14 Jun 2024 01:08:19 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/calis_ws/post/390be24b-d5ec-450c-8bcb-7144fb6fd310/image.png" alt=""></p>
<h3 id="jvm">JVM</h3>
<blockquote>
<p>Java Virtual Machine 의 약자로 “자바 가상머신” 이라는 뜻</p>
</blockquote>
<p>가상 머신이란 가상의 기기를 만들어주는 것을 의미한다.</p>
<p>다시 말해서, 여러가지의 기기위에 Java 프로그램을 실행시킬 수 있는 가상의기기를 만들어주는 것을 의미한다.</p>
<p>놀이터 그림으로 표현하자면 흐름은 아래와 같다.</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/a99b0723-1243-4341-afa1-7a0b86376d0d/image.png" alt=""></p>
<h4 id="compiletime---runtime">CompileTime - RunTime</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/0fde86cc-1da1-432a-845a-dc20ffcad076/image.png" alt=""></p>
<h4 id="java-의-놀이터-구성하기-개발환경-구성">Java 의 놀이터 구성하기 (개발환경 구성)</h4>
<p>Java 의 놀이터인 JVM 을 설치하는 방법은 JRE를 설치하는 것이다.</p>
<h3 id="jre">JRE</h3>
<blockquote>
<p>JRE 는 Java Runtime Environment 즉, 자바 실행 환경 이라는 뜻</p>
</blockquote>
<p>하지만, JRE(JVM) 만 있다면 Java 프로그램을 실행만 시킬 수 있다.</p>
<p>JRE 는 <code>.class</code> 파일만 실행 가능하다. </p>
<p>JDK 가 javac 명령을 통해 <code>.java</code> 파일을 실행가능한 <code>.class</code> 파일로 변환해준다.</p>
<p>Java 의 놀이터기능과 함께 Java 프로그램을 개발할 수 있는 JDK 라는것이 있다.</p>
<h3 id="jdk">JDK</h3>
<blockquote>
<p> JDK 는 Java Development Kit 즉, 자바 개발 키트 라는 뜻</p>
</blockquote>
<p>우리는 Java 프로그램을 개발할 것 이기 때문에 JDK 를 설치해야한다.</p>
<p>JDK 는 위의 그림처럼 JRE(JVM)의 기능을 포함하고 있다. </p>
<p>JDK는 <code>.java</code> 파일들을 <code>.class</code> 파일들로변환해주는 Java Compiler<code>(javac)</code> 기능이 있다.</p>
<p>JDK는 코드를 디버깅하는 jdb 등의 기능이 있다.</p>
<ul>
<li><p>JDK 디버깅 기능</p>
<p>JDK 의 Jdb 기능을 통해서 실행중인 프로그램의 코드 실행을 따라다니며 볼 수 있다.</p>
<ul>
<li>Java 프로그램을 실행한다는 것은 곧 Java 코드를 한줄씩 실행하면서 명령을 수행하는것을 의미한다.</li>
</ul>
<ul>
<li><p>우리가 개발한 코드들을 한줄씩 객체와 메소드를 수행하면서 변수들도 변하는 과정을 우리가 볼 수있도록 JDK(자바 개발 키트)는 코드를 따라가면서 변수를 볼 수 있는 “디버깅” 기능을 제공한다.</p>
</li>
<li><p>내가 작성한 코드 라인에 “중단점” 을 설정하고 “디버그” 모드로 프로그램을 실행하면, 프로그램이 중단점의 코드라인을 수행할때 프로그램 흐름이 일시정지되며 변수들을 볼 수 있게 도와준다.</p>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[서버] 컨테이너, 도커, 쿠버네티스란]]></title>
            <link>https://velog.io/@calis_ws/%EC%84%9C%EB%B2%84-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EB%8F%84%EC%BB%A4-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4%EB%9E%80</link>
            <guid>https://velog.io/@calis_ws/%EC%84%9C%EB%B2%84-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EB%8F%84%EC%BB%A4-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4%EB%9E%80</guid>
            <pubDate>Sun, 05 May 2024 07:14:56 GMT</pubDate>
            <description><![CDATA[<p>소프트웨어가 실행되는 하드웨어를 서버라고 한다. 운영되는 서버는 회사의 서버실에 있을 수도 있고 클라우드처럼 온라인 서버를 사용할 수도 있다.</p>
<p>PC에서 개발한 소프트웨어는 보통 메모리가 2<del>4GB 만 있어도 충분히 실행할 수 있는데 서버실에 있는 서버는 32</del>64GB 메모리를 가지고 있기 때문에 대량의 소프트웨어를 실행해야 한다.</p>
<p>하지만 IT 서비스로 제공되는 소프트웨어가 다운된다면 서비스의 장애로 이어지기 때문에 1 서버 1 소프트웨어 실행이 안전하다. 그런데 64GB 서버에서 4GB 소프트웨어 하나만 실행하면 낭비가 아닐까?</p>
<h3 id="가상화">가상화</h3>
<p>이로 인해 &quot;가상화&quot;라는 기술을 사용하여 1 서버 n 소프트웨어 실행을 가능하게 한다.</p>
<p>예전부터 사용하던 가상화 방식은 VM(Virtual Machine) 가상머신 이라는 방식을 사용했는데 프로그램을 실행하고 업그레이드 하는데에 시간이 오래 걸렸다. </p>
<p>이에 반해 컨테이너 가상화 방식은 기존의 가상화 기술보다 가볍고 빠르다는 장점이 있어서 안전하고 효율적인 소프트웨어의 운영이 가능하다.</p>
<h3 id="docker">Docker</h3>
<p>이러한 컨테이너를 관리하기 위한 일종의 프로그램이 도커이다.</p>
<h3 id="k8s">k8s</h3>
<p>그런데 도커마저 여러 대를 운영하면 관리하기 힘들어지는데 이를 관리해주는 오케스트레이션 도구가 쿠버네티스이다. 개발자가 원하는 상태를 문서로 정리한다면 k8s는 알아서 도커 컨테이너를 관리해준다.</p>
<hr>
<h3 id="정리">정리</h3>
<ul>
<li><p>컨테이너 : 한 대의 서버에서 여러 개의 소프트웨어를 안전하고 효율적으로 운영할 수 있는 가상화 방식</p>
</li>
<li><p>도커 : 컨테이너를 관리하기 위한 도구로 일종의 프로그램</p>
</li>
<li><p>쿠버네티스 : 서버가 여러 대 있는 환경에서 각각의 서버의 도커에게 대신 지시해주는 오케스트레이션 도구</p>
</li>
</ul>
<h4 id="출처">출처</h4>
<p>개발자를 위한 쉬운 도커 (2024 NEW) | 컨테이너, 도커, 쿠버네티스의 개념을 엄청 쉽게 알려드려요.
<a href="https://www.youtube.com/watch?v=eRfHp16qJq8&amp;t=331">https://www.youtube.com/watch?v=eRfHp16qJq8&amp;t=331</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS 탄력 IP (public ip) 삭제]]></title>
            <link>https://velog.io/@calis_ws/AWS-%ED%83%84%EB%A0%A5-IP-public-ip-%EC%82%AD%EC%A0%9C</link>
            <guid>https://velog.io/@calis_ws/AWS-%ED%83%84%EB%A0%A5-IP-public-ip-%EC%82%AD%EC%A0%9C</guid>
            <pubDate>Wed, 03 Apr 2024 04:06:13 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/calis_ws/post/2b2e5643-9b8d-429d-a00b-e493ec4378d5/image.png" alt=""></p>
<p>아침에 AWS 6300원이 결제되었다는 알림이 왔다
2/23 에 분명 인스턴스 다 껐는데 .. 뭐지?</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/96a63943-f8a4-4d0b-bee4-e7abc177385b/image.png" alt=""></p>
<p>VPC 에서 요금이 발생했었다</p>
<p>원인은 탄력적 IP 주소가 활성화 되어있기 때문</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/41eedeca-bf59-4bd5-b35f-c3a3e88b2728/image.png" alt=""></p>
<p>탄력적 IP 들어가서 삭제하자 (릴리스)</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/59ecc870-bdc0-4e86-a0b8-3dfa0d950179/image.png" alt=""></p>
<p>바로 완치. (내돈 ㅠ)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[네트워크] 쿠키와 세션]]></title>
            <link>https://velog.io/@calis_ws/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%BF%A0%ED%82%A4%EC%99%80-%EC%84%B8%EC%85%98</link>
            <guid>https://velog.io/@calis_ws/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%BF%A0%ED%82%A4%EC%99%80-%EC%84%B8%EC%85%98</guid>
            <pubDate>Thu, 21 Mar 2024 10:40:20 GMT</pubDate>
            <description><![CDATA[<h4 id="쿠키와-세션을-사용하는-이유">쿠키와 세션을 사용하는 이유</h4>
<blockquote>
<p>쿠키와 세션은 HTTP 프로토콜의 특징이자 약점을 보완하기 위해 사용한다.</p>
</blockquote>
<p>HTTP 프로토콜은 비연결지향과 상태정보 유지 안함이라는 특징을 가지고 있다.
따라서 서버와 클라이언트가 통신을 할 때 통신이 연속적으로 이어지지 않고 한 번 통신이 되면 끊어진다.
또한 통신이 끊어지면 상태정보가 유지되지 않기 때문에 매번 페이지를 이동할 때마다 로그인은 다시 하거나, 상품 선택 후 구매 페이지에서 선택한 상품의 정보가 없거나 하는 등의 문제가 발생할 수 있다.</p>
<p>이러한 문제를 해결하는 방법이 바로 쿠키와 세션이다.</p>
<h3 id="쿠키cookie">쿠키(Cookie)</h3>
<blockquote>
<p>HTTP 의 일종으로 사용자가 어떤 웹 사이트를 방문할 경우, 해당 사이트가 사용하고 있는 서버에서 사용자의 컴퓨터에 저장하는 작은 기록 정보 파일이다.</p>
</blockquote>
<p>HTTP 에서 클라이언트의 상태정보를 쿠키 형태로 클라이언트 PC에 저장하였다가 필요 시 정보를 참조하거나 재사용할 수 있다.</p>
<h4 id="특징">특징</h4>
<ul>
<li><p><code>Key-Value</code> 쌍으로 구성되어 있는 데이터 파일이다.</p>
</li>
<li><p>쿠키이름, 쿠키값, 만료시간, 전송할 도메인명, 전송할 경로, 보안연결여부, HttpOnly 여부로 구성되어 있다.</p>
</li>
<li><p>도메인 당 20개의 쿠키를 가질 수 있다.</p>
</li>
<li><p>하나의 쿠키는 4KB(= 4096 byte)까지 저장이 가능하다.</p>
</li>
</ul>
<h4 id="작동-방식">작동 방식</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/d7363ee2-4d4d-4c43-b7df-5780b6c3865e/image.png" alt=""></p>
<ol>
<li><p>클라이언트가 서버에 로그인 요청</p>
</li>
<li><p>서버는 클라이언트의 로그인 요청의 유효성을 확인하고(아이디와 비밀번호 검사) 응답헤더에 <code>set-cookie:</code> 를 통해 쿠키를 추가하여 응답</p>
</li>
<li><p>클라이언트는 이후 서버에 요청할 때 전달받은 쿠키를 자동으로 요청헤더에 추가하여 요청한다. 헤더에 쿠키값을 자동으로 추가하여 주는데 이는 브라우저에서 처리해주는 작업이다.</p>
</li>
</ol>
<p>쿠키의 기한이 정해져 있지 않고 명시적으로 지우지 않는다면 반 영구적으로 쿠키가 남아있다.</p>
<h4 id="사용-목적">사용 목적</h4>
<p>쿠키는 주로 3가지 목적을 위해 사용한다.</p>
<ol>
<li><p>세션 관리(Session Management)</p>
<p> 로그인, 사용자 닉네임, 접속 시간, 장바구니 등의 서버가 알아야할 정보들을 저장</p>
</li>
<li><p>개인화(Personalization)</p>
<p> 사용자마다 다르게 그 사람에 적절한 페이지를 보여줄 수 있다.</p>
</li>
<li><p>트래킹(Tracking)</p>
<p> 사용자의 행동과 패턴을 분석하고 기록</p>
</li>
</ol>
<h4 id="쿠키값-확인-및-단점">쿠키값 확인 및 단점</h4>
<p>브라우저 개발자도구의 네트워크에서 쿠키값을 확인할 수 있지만, 가독성이 떨어지고 수정이 불가능하다.
하지만 &#39;브라우저의 쿠키 관리 탭&#39; 또는 &#39;쿠키 관리 플러그인&#39;을 설치하면 쿠키를 쉽게 수정할 수 있다.</p>
<p>이러한 쿠키는 클라이언트에서 수정할 수 있기 때문에 위변조의 위험이 항상 존재한다. 따라서 쿠키값(value)를 암호화해야 하며, 민감하거나 중요한 정보를 담지 않도록 해야한다.</p>
<h3 id="세션session">세션(Session)</h3>
<blockquote>
<p>일정 시간 동안 같은 사용자(브라우저)로부터 들어오는 일련의 요구를 하나의 상태로 보고, 그 상태를 유지시키는 기술이다.</p>
</blockquote>
<p>여기서 일정 시간은 방문자가 웹 브라우저를 통해 웹 서버에 접속한 시점부터 웹 브라우저를 종료하여 연결을 끝내는 시점을 말한다.</p>
<p>즉, 브라우저가 종료되기 전까지 클라이언트의 요청을 유지하게 해주는 기술을 세션이라고 한다.</p>
<h4 id="특징-1">특징</h4>
<ul>
<li><p>웹 서버에 웹 컨테이너의 상태를 유지하기 위한 정보를 저장한다.</p>
</li>
<li><p>웹 서버에 저장되는 쿠키(세션 쿠키 / session cookie)이다.</p>
</li>
<li><p>브라우저를 닫거나, 서버에서 세션을 삭제했을 때만 삭제가 되기 때문에 쿠키보다 비교적 보안적으로 우수하다.</p>
</li>
<li><p>저장 데이터에 제한이 없다. (서버 용량 허용 범위 내에서)</p>
</li>
<li><p>각 클라이언트에 고유 세션 ID(Session ID)를 부여한다. 세션 ID를 통해 클라이언트를 구분하여 각 요구에 맞는 서비스를 제공한다.</p>
</li>
</ul>
<h4 id="작동-방식-1">작동 방식</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/90ff953e-c736-476f-a6a6-6e55c523c371/image.png" alt=""></p>
<ol>
<li><p>클라이언트가 서버에 로그인 요청</p>
</li>
<li><p>서버는 클라이언트의 로그인 요청의 유효성을 확인하고(아이디와 비밀번호 검사) unique한 id를 session ID로 생성하여 저장한다.</p>
</li>
<li><p>서버가 응답할 때 응답헤더에 세션 ID를 쿠키에 추가하여 응답합니다.</p>
</li>
<li><p>클라이언트는 이후 서버에 요청할 때 전달받은 세션 ID를 쿠키에 자동으로 요청 헤더에 추가하여 요청한다.</p>
</li>
<li><p>서버에서는 요청 헤더의 세션 ID 값을 저장된 세션 저장소에서 찾아보고 유효한지 확인 후 요청을 처리하고 응답한다.</p>
</li>
</ol>
<h4 id="사용-목적-1">사용 목적</h4>
<p>사용자나 다른 누군가에게 노출되면 안되는 보안적으로 중요한 정보들을 서버 안에서 다루기 위해 사용한다.</p>
<h4 id="단점">단점</h4>
<p>세션의 내용은 서버에 저장되기 때문에 계속하여 늘어날 경우 서버에 부하가 발생할 수 있다.
또한 세션에 대한 정보가 서버에 있어 쿠키에 비해 비교적 속도가 느리다.</p>
<h3 id="차이점">차이점</h3>
<h4 id="1-저장-위치">1. 저장 위치</h4>
<p>쿠키 : 클라이언트의 웹 브라우저가 지정하는 메모리 또는 하드디스크</p>
<p>세션 : 서버의 메모리에 저장</p>
<h4 id="2-만료-시점">2. 만료 시점</h4>
<p>쿠키 : 클라이언트에 설정된 만료 날짜까지 유지, 만료 날짜를 설정하지 않으면 브라우저를 닫을 때까지 유지</p>
<p>세션 : 클라이언트가 웹 애플리케이션에 접속하는 동안 유지되며, 클라이언트가 웹 브라우저를 종료하거나 세션을 만료시키는 경우에만 제거</p>
<h4 id="3-리소스">3. 리소스</h4>
<p>쿠키 : 클라이언트에 저장되고, 클라이언트의 메모리를 사용하기 때문에 서버 자원을 사용하지 않음</p>
<p>세션 : 서버에 저장되고, 서버의 메모리로 로딩되기 때문에 세션이 생길 때마다 리소스를 차지함</p>
<h4 id="4-용량-제한">4. 용량 제한</h4>
<p>쿠키 : 클라이언트도 모르게 접속되는 사이트에 의해 설정될 수 있기 때문에 쿠키로 인한 문제가 발생하는 것을 막기 위해 한 도메인 당 20개, 한개의 쿠키 당 4KB로 제한</p>
<p>세션 : 클라이언트가 접속하면 서버에 의해 생성되므로 개수나 용량 제한 없음</p>
<hr>
<h3 id="정리">정리</h3>
<h4 id="세션와-쿠키를-모두-사용하는-이유">세션와 쿠키를 모두 사용하는 이유</h4>
<p> 세션이 쿠키에 비해 보안이 높은 편이나 쿠키를 사용하는 이유는 세션은 서버에 저장되고, 서버의 자원을 사용하기 때문에 서버 자원에 한계가 있고, 속도가 느려질 수 있다. 
따라서 자원관리 차원에서 쿠키와 세션을 적절한 요소 및 기능에 병행 사용하여 서버 자원의 낭비를 방지하며 웹사이트의 속도를 높일 수 있다.</p>
<h4 id="출처">출처</h4>
<p><a href="https://velog.io/@octo__/%EC%BF%A0%ED%82%A4Cookie-%EC%84%B8%EC%85%98Session#%EC%BF%A0%ED%82%A4cookie%EC%99%80-%EC%84%B8%EC%85%98session%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0">https://velog.io/@octo__/쿠키Cookie-세션Session#쿠키cookie와-세션session을-사용하는-이유</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[네트워크] RESTful한 API]]></title>
            <link>https://velog.io/@calis_ws/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-RESTful%ED%95%9C-API</link>
            <guid>https://velog.io/@calis_ws/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-RESTful%ED%95%9C-API</guid>
            <pubDate>Mon, 18 Mar 2024 21:16:04 GMT</pubDate>
            <description><![CDATA[<h2 id="rest-api">REST API</h2>
<blockquote>
<p>REST(Representational State Transfer)는 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식</p>
</blockquote>
<ol>
<li><p>REST는 기본적으로 웹의 기존 기술과 HTTP 프로토콜을 그대로 활용하기 때문에 웹의 장점을 최대한 활용할 수 있는 아키텍처 스타일이다.</p>
</li>
<li><p>REST는 네트워크 상에서 Client와 Server 사이의 통신 방식 중 하나이다.</p>
</li>
</ol>
<p>자원을 이름(자원의 표현)으로 구분하여 해당 자원의 상태(정보)를 주고 받는 모든 것을 의미한다.
즉, 자원의 표현에 의한 상태 전달</p>
<ol>
<li>자원(resource)의 표현(representation)</li>
</ol>
<ul>
<li><p>자원 : 해당 소프트웨어가 관리하는 모든 것
ex) 문서, 그림, 데이터, 해당 소프트웨어 자체 등</p>
</li>
<li><p>자원의 표현 : 그 자원을 표현하기 위한 이름
ex) DB의 학생 정보가 자원일 때, ‘students’를 자원의 표현으로 정한다.</p>
</li>
</ul>
<ol start="2">
<li>상태(정보) 전달</li>
</ol>
<ul>
<li>데이터가 요청되어지는 시점에서 자원의 상태(정보)를 전달한다.</li>
<li>JSON 혹은 XML를 통해 데이터를 주고 받는 것이 일반적이다.</li>
</ul>
<p>개념을 간단히 표현하자면, HTTP URI를 통해서 자원을 명시하고 HTTP Method(<code>POST, GET, PUT, DELETE</code>)를 통해서 명시된 자원의 CRUD(<code>Create, Read, Update, Delete</code>)를 요청하는 API를 작성하는 것이라 할 수 있다.</p>
<h3 id="restful-api의-조건">RESTful API의 조건</h3>
<p>REST 아키텍처는 다음과 같은 특성을 지켜야 한다.</p>
<h4 id="uniform-interface-인터페이스-일관성">Uniform Interface (인터페이스 일관성)</h4>
<p>인터페이스가 일관되어야 한다. URI로 지정한 리소스에 대한 조작을 통일되고 한정적인 인터페이스로 수행할 수 있어야 한다는 것이다. RESTful API라면 HTTP 표준 프로토콜을 따르는 모든 플랫폼에서 사용이 가능하다.</p>
<h4 id="stateless-무상태성">Stateless (무상태성)</h4>
<p>API 호출한 클라이언트 상태에 대한 정보를 따로 서버에 저장하고 관리하지 않는다. 이에 따라 API 서버는 들어오는 요청에 대한 처리만 할 수 있어 서비스의 자유도가 높아지고 구현이 단순해지는 특징을 가지고 있다.</p>
<h4 id="cacheable-캐시-처리-가능">Cacheable (캐시 처리 가능)</h4>
<p>HTTP라는 기존의 웹 표준을 활용하기 때문에, 캐시 기능을 사용할 수 있다. 잘 관리되는 캐싱은 클라이언트-서버 간의 상호작용을 부분적으로 또는 완전히 제거하여 성능을 향상시킬 수 있다고 한다.</p>
<h4 id="self-descriptiveness-자체-표현-구조">Self-descriptiveness (자체 표현 구조)</h4>
<p>REST API 메세지만 보고도 쉽게 이해할 수 있는 구조로 표현되어야 한다. HTTP Method 명칭이 자체 표현 구조를 따르는 예시라고 할 수 있다.</p>
<h4 id="client-server-구조">Client-Server 구조</h4>
<p>Client와 Server의 역할이 확실히 구분되어야 하며, 서로간 의존성을 낮출 수 있어야 한다. 서버는 API를 제공하고 비즈니스 로직 처리 및 데이터 저장에 책임이 있으며, 클라이언트는 사용자 인증이나 상태정보를 직접 관리하는 것에 책임이 있다.</p>
<h4 id="layered-system-계층형-구조">Layered System (계층형 구조)</h4>
<p>REST API 서버는 다중 계층으로 구성되어 있어야 한다. RESTful API 서버는 순수 비즈니스 로직을 수행하는 API 서버와 그 앞단에 사용자 인증, 암호화, 로드 밸런싱을 하는 계층을 추가해서 구조상의 유연성을 둘 수 있다.</p>
<h3 id="rest-api-uri-설계-가이드">REST API URI 설계 가이드</h3>
<h4 id="1-소문자를-사용하고-단어는-언더바가-아닌-하이픈으로-구분">1. 소문자를 사용하고 단어는 언더바가 아닌 하이픈으로 구분</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/0d99c1b1-8e6c-47c4-9008-85c9dbacc4b7/image.png" alt=""></p>
<p>여러 단어를 나열해야 하는 경우 카멜 표기법이 아닌 하이픈을 활용한 소문자로 URI를 만들어야 한다.</p>
<h4 id="2-슬래시-구분자로-계층-관계를-표현하고-마지막에는-포함시키지-않는다">2. 슬래시 구분자로 계층 관계를 표현하고 마지막에는 포함시키지 않는다</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/3c0daafe-5bf0-4fef-a839-41b116d49188/image.png" alt=""></p>
<p>정확한 계층 관계를 표현할 수 있어야 하기 때문에, 마지막에 포함시키지 않도록 하여 혼란을 주지 않아야 한다.</p>
<h4 id="3-uri에서는-리소스에-대한-행위를-포함시키지-않는다">3. URI에서는 리소스에 대한 행위를 포함시키지 않는다</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/26095439-b887-4904-aa2d-04cc6233d4b6/image.png" alt=""></p>
<p>리소스에 대한 행위는 HTTP Method를 통해서 충분히 전달이 가능하다. 명료한 URI 작성을 위해서 리소스에 대한 행위를 포함시키지 않도록 하라.</p>
<h4 id="4-파일-확장자를-uri에-포함시키지-않는다">4. 파일 확장자를 URI에 포함시키지 않는다</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/ec7b5e39-0313-40a5-aa96-4e59f3fc5c09/image.png" alt=""></p>
<p>리소스 자료의 포맷을 URI 안에 포함시키지 않아야 한다. Request의 헤더에 Accept 속성을 통해서 파일의 형식을 지정해 줄 수 있다.</p>
<hr>
<h3 id="정리">정리</h3>
<p>REST 하게 만든 API 를 RESTful API 라고 한다.
REST에서 말하는 모든 REST 아키텍처 스타일을 지켜야만 진정한 의미의 RESTful API 라고 말할 수 있다.</p>
<pre><code>- Uniform Interface (인터페이스 일관성)
- Stateless (무상태성)
- Cacheable (캐시 처리 가능)
- Self-descriptiveness (자체 표현 구조)
- Client-Server 구조
- Layered System (계층형 구조)</code></pre><p>REST API 설계 규칙</p>
<pre><code>소문자 사용과 하이픈(-) 사용
슬래시(/) 로 계층 관계 표현, 마지막은 불포함
리소스에 대한 행위 불포함
파일 확장자 불포함</code></pre><p>그러나 모든 API가 모든 요소를 엄격하게 준수할 필요는 없으며, 상황에 따라 유연하게 적용될 수 있다.</p>
<h4 id="출처">출처</h4>
<p><a href="https://tedjunny.tistory.com/entry/RESTful%ED%95%9C-API-%EC%84%A4%EA%B3%84%ED%95%98%EA%B8%B0">https://tedjunny.tistory.com/entry/RESTful한-API-설계하기</a>
<a href="https://hahahoho5915.tistory.com/54">https://hahahoho5915.tistory.com/54</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[네트워크] HTTP Keep-Alive 란?]]></title>
            <link>https://velog.io/@calis_ws/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-HTTP-Keep-Alive-%EB%9E%80</link>
            <guid>https://velog.io/@calis_ws/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-HTTP-Keep-Alive-%EB%9E%80</guid>
            <pubDate>Tue, 12 Mar 2024 16:30:13 GMT</pubDate>
            <description><![CDATA[<p>HTTP 는 Connectionless 방식으로 연결을 매번 끊고 새로 생성하는 구조이다. 이는 Network 비용 측면에서 최초 연결을 하기 위해 많은 비용을 소비한다.</p>
<p>HTTP 프로토콜의 Keep-Alive 기능은 클라이언트와 서버 간 요청 및 응답 과정을 효율적으로 유지하기 위해 사용된다. Keep-alive 를 활성화하면 하나의 TCP 연결을 여러 번 재사용하며 응답과 요청을 수행할 수 있다.</p>
<h3 id="keep-alive">Keep-Alive</h3>
<p>HTTP 프로토콜에서 클라이언트와 서버 간 여러 요청을 단일 TCP 연결을 재사용하는 방식으로 처리하는 기능을 말한다. HTTP/1.1 프로토콜부터 도입됐다. 이 기능을 활성화하면 여러 HTTP 요청 및 응답 과정에서 발생하는 네트워크 오버헤드를 줄일 수 있다.</p>
<p>keep-alive를 사용하는 경우 HTTP 요청 헤더에 Connection: Keep-Alive 라는 값을 포함시킨다.</p>
<pre><code>HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Thu, 11 Aug 2016 15:23:13 GMT
Keep-Alive: timeout=5, max=1000
Last-Modified: Mon, 25 Jul 2016 04:32:39 GMT
Server: Apache

(body)</code></pre><h4 id="사용-이점">사용 이점</h4>
<p>keep-alive가 없으면 클라이언트와 서버는 각 요청과 응답에 대해 매번 새로운 TCP 연결을 생성하고 닫아야 한다. 이 방식은 네트워크 리소스가 비효율적으로 사용된다. 반면 keep-alive를 사용하면 단일 TCP 연결에서 여러 요청과 응답이 이루어지기 때문에 네트워크 지연 시간이 줄어들고 웹 사이트 성능이 좋아진다.</p>
<p>초기 HTTP/1.0 프로토콜에서는 각 HTTP 요청에 대해 매번 TCP 연결을 새로 생성해야 했기 때문에 위에서 언급한 문제들이 존재했다. 이를 해결하기 위해 HTTP/1.1 프로토콜에 해당 기능이 도입됐다.
<img src="https://velog.velcdn.com/images/calis_ws/post/9734bb1a-c5f2-492b-ab31-e82f21dcd10d/image.png" alt=""></p>
<p>위 이미지는 4개의 트랜잭션에 대해 연속적으로 4개의 커넥션을 생성하여 처리하는 방식과 하나의 지속 커넥션으로만 처리하는 방식을 비교한 이미지이다.</p>
<p>후자에서는 커넥션을 맺고 끊는 데 작업이 없어졌기 때문에 시간이 단축되었다.</p>
<pre><code>keep-alive 의 상황을 비유하자면, 전화 통화하는 상황을 떠올릴 수 있다. 
한 고객이 고객센터에 전화를 걸어 제품에 대해 궁금한 정보를 하나씩 묻는다고 해보자. 
이때 하나의 질문을 할 때마다 대답을 듣고 전화가 끊어진다고 생각해 보자. 
전화를 걸고 다시 물어보는 과정이 반복된다면 매우 피곤할 것이다. 
한번 연결된 전화를 통해 모든 궁금증을 해결할 수 있는 편이 훨씬 효율적이다.</code></pre><h4 id="예시">예시</h4>
<ol>
<li><p>Image를 4개를 보여주어야 한다.</p>
</li>
<li><p>Client는 동시에 2개의 Image만 받아올 수 있다.</p>
</li>
<li><p>Image는 받아오는데 2초가 걸린다.</p>
</li>
<li><p>Port를 여는데 1초가 걸린다.</p>
</li>
</ol>
<p>keep-alive 비활성화</p>
<pre><code>처음 Server에 2개의 Port를 열고 Image를 받고 Client Socket의 닫는다. ( 3초 ) 
다시 Server에 2개의 Port를 열고 Image를 받고 Client Socket의 닫는다. ( 3초 ) 
총 6초가 걸린다.</code></pre><p>keep-alive 활성화</p>
<pre><code>처음 Server에 2개의 Port를 열고 Image를 받는다. ( 3초 ) 
재요청 시 기존에 열어 둔 Port로 Image를 받아온다. ( 2초 )
총 5초가 걸린다.</code></pre><hr>
<h3 id="정리">정리</h3>
<p>HTTP 프로토콜은 클라이언트가 서버에 요청을 보내고 서버가 응답을 보내는 동안에만 연결을 유지한다. 이후에는 연결이 종료되고 다시 연결을 맺어야 한다. </p>
<p>하지만 Keep Alive 를 사용하면 클라이언트와 서버 간의 연결을 유지할 수 있다. 이는 웹 페이지를 로드하는 데 필요한 추가 연결 설정 시간을 줄여 성능을 향상시킬 수 있다.</p>
<h4 id="출처">출처</h4>
<p><a href="https://change-words.tistory.com/entry/HTTP-Keep-Alive">https://change-words.tistory.com/entry/HTTP-Keep-Alive</a>
<a href="https://goodgid.github.io/HTTP-Keep-Alive/">https://goodgid.github.io/HTTP-Keep-Alive/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[네트워크] TCP 혼잡 제어]]></title>
            <link>https://velog.io/@calis_ws/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-TCP-%ED%98%BC%EC%9E%A1-%EC%A0%9C%EC%96%B4</link>
            <guid>https://velog.io/@calis_ws/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-TCP-%ED%98%BC%EC%9E%A1-%EC%A0%9C%EC%96%B4</guid>
            <pubDate>Sun, 10 Mar 2024 16:47:26 GMT</pubDate>
            <description><![CDATA[<h3 id="혼잡-제어congestion-control">혼잡 제어(Congestion Control)</h3>
<blockquote>
<p>송신측의 데이터 전달과 네트워크의 데이터 처리 속도 차이를 해결하기 위한 기법</p>
</blockquote>
<p>한 라우터에 데이터가 몰리는 경우 등의 네트워크 혼잡을 피하기 위해 송신측에서 보내는 데이터의 전송속도를 강제로 줄이는 작업이다.</p>
<p>네트워크 내에 패킷의 수가 과도하게 증가하는 현상을 방지하는 현상도 혼잡제어라고 한다.</p>
<p>송신측과 수신측의 전송속도를 다루는 흐름제어와 달리, 혼잡 제어는 호스트와 라우터를 포함한 넓은 관점에서의 전송 문제를 다룬다.</p>
<h4 id="congestion-의-발견">Congestion 의 발견</h4>
<p>TCP 는 송신한 패킷에 대해서 ACK 를 수신한다.
만약 정해진 시간이 지날 때까지 ACK 가 도착하지 않으면 congestion 이 발생한 것으로 판단한다. (timeout)</p>
<h4 id="ackacknowledgment">ACK(acknowledgment)</h4>
<p>데이터 통신에서 수신자가 송신자에게 데이터를 정상적으로 받았음을 알리는 신호</p>
<h4 id="window-size">Window Size</h4>
<p>TCP 통신에서 데이터를 전송하는 속도를 조절하는 중요한 매개변수이다. 
TCP는 데이터를 전송할 때 수신 측이 데이터를 수신할 수 있는 만큼의 윈도우 크기를 설정하게 된다. 이 윈도우 크기는 데이터를 얼마나 많이 한 번에 전송할 수 있는지를 결정하며, 네트워크 성능과 효율에 영향을 미친다.</p>
<h3 id="혼잡제어-해결방법">혼잡제어 해결방법</h3>
<h4 id="1-aimd-additive-increase--multicative-decrease-합-증가--곱-감소">1. AIMD (Additive Increase / Multicative Decrease) 합 증가 / 곱 감소</h4>
<p>패킷을 하나씩 보내고 문제없이 도착하면 윈도우 크기(단위 시간 내에 보내는 패킷의 수)를 1씩 증가시켜가며 전송하는 방법</p>
<p>만약 패킷 전송을 실패하거나, 일정시간을 넘으면 패킷을 보내는 속도를 절반으로 줄이게 된다.</p>
<p>매우 공평한 방식으로, 여러 호스트가 한 네트워크를 공유하고 있으면 나중에 진입하는 쪽이 불리하지만, 시간이 지날수록 평행상태로 수렴하는 특징이 있다.</p>
<h4 id="2-slow-start-느린-시작">2. Slow Start (느린 시작)</h4>
<p>합 증가 / 곱 감소 방식과 마찬가지로, 패킷을 하나씩 보내는 것부터 시작하고, 패킷이 문제 없이 도착하면 각각의 ACK 패킷마다 윈도우 크기를 1씩 늘려준다.</p>
<p>위와 같은 방법으로 한 주기가 지나면 윈도우 크기는 2배가 되며, 이러한 전송속도는 지수 함수의 꼴로 증가한다.</p>
<p>만약 혼잡제어 현상이 발생하면, 윈도우 크기를 1로 떨어뜨린다.</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/bea432c9-7f74-49db-b0b9-4bb1125b9da7/image.png" alt=""></p>
<h4 id="cwndcongestion-window">Cwnd(congestion window)</h4>
<p>송신자가 현재 네트워크 상황에 맞춰 전송할 수 있는 데이터의 양을 나타낸다. </p>
<p>TCP 통신에서는 데이터를 전송할 때마다 이 Cwnd 크기에 따라 전송량이 조절된다.</p>
<h4 id="혼잡-회피congestion-avoidance">혼잡 회피(Congestion Avoidance)</h4>
<p>Congestion 이 발생한 것으로 판단되면(timeout), 전송되는 패킷의 양을 초기 상태로 줄여서 다시 시작한다.</p>
<h4 id="tcp-tahoe-방식">TCP Tahoe 방식</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/a5ac743d-d650-4eb7-97a2-aaa3238f5b6b/image.png" alt=""></p>
<p>이외에도 TCP Reno, TCP-SACK, TCP-New Reno, TCP-Vegas, TCP Cubic, Multipath TCP ...</p>
<hr>
<h3 id="정리">정리</h3>
<p>TCP Congestion Control 은 네트워크에서 발생할 수 있는 혼잡 현상을 관리하고 해결하기 위한 기능의 집합이다. 이러한 기능들은 네트워크에서의 데이터 전송 과정에서 발생할 수 있는 혼잡을 감지하고 조절하여 네트워크 성능을 최적화하고 데이터의 손실을 최소화한다.</p>
<h4 id="출처">출처</h4>
<p>TCP : 체증 제어/혼잡 제어 (congestion control)
<a href="https://www.youtube.com/watch?v=4TvP_-3KBH4&amp;t=1493">https://www.youtube.com/watch?v=4TvP_-3KBH4&amp;t=1493</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] 낙관적 락 vs 비관적 락]]></title>
            <link>https://velog.io/@calis_ws/DB-%EB%82%99%EA%B4%80%EC%A0%81-%EB%9D%BD-vs-%EB%B9%84%EA%B4%80%EC%A0%81-%EB%9D%BD</link>
            <guid>https://velog.io/@calis_ws/DB-%EB%82%99%EA%B4%80%EC%A0%81-%EB%9D%BD-vs-%EB%B9%84%EA%B4%80%EC%A0%81-%EB%9D%BD</guid>
            <pubDate>Sun, 03 Mar 2024 11:28:09 GMT</pubDate>
            <description><![CDATA[<h3 id="lock">Lock</h3>
<blockquote>
<p>락은 대표적인 동시성 제어 기법 중 하나로, 데이터베이스의 일관성과 무결성을 유지하기 위해 트랜잭션의 순차적 진행을 보장할 수 있는 직렬화 장치이다.</p>
</blockquote>
<p>일반적으로 락은 둘 혹은 그 이상의 사용자가 동시에 같은 데이터를 접근하는 것을 방지하기 위해 사용한다.</p>
<p>트랜잭션만으로는 해결할 수 없는 요청이 유실되는 경우가 발생하는 갱신 손실 문제나 동시에 발생하는 따닥 요청등을 해결할 때 사용한다.</p>
<h3 id="낙관적-락optimistic-lock">낙관적 락(Optimistic Lock)</h3>
<blockquote>
<p>자원에 락을 걸어서 선점하지말고, 동시성 문제가 발생하면 그때 가서 처리 하자는 방법론이다.</p>
</blockquote>
<ul>
<li><p>트랜잭션의 충돌이 발생하지 않을 것이라고 기대한다.</p>
</li>
<li><p>일단 충돌이 나는 것을 막지 않고, 충돌이 난 것을 감지하면 그때 처리한다.</p>
</li>
<li><p>일반적으로 version 의 상태를 보고 충돌을 확인하며, 충돌이 확인된 경우 롤백을 진행시킨다. (hashcode나 timestamp를 이용해서 충돌을 확인할 수도 있다.)</p>
</li>
<li><p>DB 단에서 동시성을 처리하는것이 아닌, 어플리케이션 단에서 처리한다.</p>
</li>
</ul>
<h4 id="유저가-동시에-tilte-데이터를-수정하는-상황">유저가 동시에 TILTE 데이터를 수정하는 상황</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/0fcee960-4d1d-466e-9779-ce643fe1be33/image.png" alt=""></p>
<h4 id="장점">장점</h4>
<ul>
<li>충돌이 안난다는 가정하에, 동시 요청에 대해서 처리 성능이 좋다.<h4 id="단점">단점</h4>
</li>
<li>잦은 충돌이 일어나는 경우 롤백 처리에 대한 비용이 많이 들어 오히려 성능에서 손해를 볼 수 있다.</li>
<li>롤백 처리를 구현하는게 복잡할 수 있다.</li>
</ul>
<h3 id="비관적-락pessimistic-lock">비관적 락(Pessimistic Lock)</h3>
<blockquote>
<p>자원 요청에 따른 동시성 문제가 발생할 것이라고 예상하고 락을 걸어버리는 방법론이다.</p>
</blockquote>
<ul>
<li><p>트랜잭션의 충돌이 발생한다고 가정한다.</p>
</li>
<li><p>하나의 트랜잭션이 자원에 접근시 락을 걸고, 다른 트랜잭션이 접근하지 못하게 한다.</p>
</li>
<li><p>데이터베이스에서 Shared Lock(공유, 읽기 잠금) 이나 Exclusive Lock(배타, 쓰기 잠금) 을 건다.</p>
</li>
<li><p>Shared Lock 의 경우, 다른 트랜잭션에서 읽기만 가능하다. 또한 Exclusive lock 적용이 불가능하다. (읽는 동안 변경하는 것을 막기 위해)</p>
</li>
<li><p>Exclusive lock 의 경우, 다른 트랜잭션에서 읽기, 쓰기가 둘다 불가능하다. 또한 Shared, Exclusive Lock 적용이 추가적으로 불가능하다. (쓰는동안 읽거나, 다른 쓰기가 오는것을 막기위해)</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/50b85736-22bb-4475-8668-c8c57681f8b0/image.png" alt=""></p>
<h4 id="장점-1">장점</h4>
<ul>
<li>충돌이 자주 발생하는 환경에 대해서는 롤백의 횟수를 줄일 수 있으므로 성능에서 유리하다.</li>
<li>데이터 무결성을 보장하는 수준이 매우 높다.<h4 id="단점-1">단점</h4>
</li>
<li>데이터 자체에 락을 걸어버리므로 동시성이 저하되는 성능 손해를 많이 보게 된다. 특히 읽기가 많이 이루어지는 데이터베이스의 경우에는 손해가 더 두드러진다.</li>
<li>서로 자원이 필요한 경우에, 락이 걸려있으므로 <a href="https://namu.wiki/w/%EB%8D%B0%EB%93%9C%EB%9D%BD#s-3.1">데드락(Deadlock)</a>이 일어날 가능성이 있으며, 이에 대한 처리가 필요하다.</li>
</ul>
<h4 id="데드락이란">데드락이란?</h4>
<p>두 개 이상의 프로세스나 스레드가 서로가 가진 자원을 대기하며 무한히 기다리는 상황</p>
<hr>
<h3 id="정리">정리</h3>
<h4 id="낙관적락">낙관적락</h4>
<p>데이터에 대한 동시 액세스를 허용하되, 충돌을 검출하여 데이터의 일관성을 유지한다.
실제로 데이터 충돌이 자주 일어나지 않을 것이라고 예상되는 시나리오에서 좋다.</p>
<h4 id="비관적락">비관적락</h4>
<p>데이터에 대한 액세스를 다른 프로세스로부터 차단하여 데이터의 일관성을 유지한다.
데이터의 무결성이 중요하고, 충돌이 많이 발생하여 잦은 롤백으로 인한 효율성 문제가 발생하는 것이 예상되는 시나리오에서 좋다.</p>
<h4 id="출처">출처</h4>
<p>낙관적 락 VS 비관적 락 - 김영수 | 백엔드 데브코스 3기 | 20230203
<a href="https://www.youtube.com/watch?v=SoQ4ExWnetg&amp;t=336s">https://www.youtube.com/watch?v=SoQ4ExWnetg&amp;t=336s</a>
<a href="https://unluckyjung.github.io/db/2022/03/07/Optimistic-vs-Pessimistic-Lock/">https://unluckyjung.github.io/db/2022/03/07/Optimistic-vs-Pessimistic-Lock/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] 릴레이션의 분석 지침, 함수적 종속성]]></title>
            <link>https://velog.io/@calis_ws/DB-%EB%A6%B4%EB%A0%88%EC%9D%B4%EC%85%98%EC%9D%98-%EB%B6%84%EC%84%9D-%EC%B9%98%EC%B9%A8-%ED%95%A8%EC%88%98%EC%A0%81-%EC%A2%85%EC%86%8D%EC%84%B1</link>
            <guid>https://velog.io/@calis_ws/DB-%EB%A6%B4%EB%A0%88%EC%9D%B4%EC%85%98%EC%9D%98-%EB%B6%84%EC%84%9D-%EC%B9%98%EC%B9%A8-%ED%95%A8%EC%88%98%EC%A0%81-%EC%A2%85%EC%86%8D%EC%84%B1</guid>
            <pubDate>Tue, 27 Feb 2024 15:56:07 GMT</pubDate>
            <description><![CDATA[<p>데이터베이스 릴레이션 분석은 데이터를 적절하게 구조화하여 중복을 최소화하고 데이터의 무결성을 보장하는 과정이다. 이를 위해 정규화와 함수적 종속성을 이해하고 적용해야 한다.</p>
<h4 id="릴레이션이란">릴레이션이란?</h4>
<blockquote>
<p>릴레이션(relation)은 데이터베이스에서 정보를 구분하여 저장하는 기본 단위이며, 엔티티에 관한 데이터를 데이터베이스에서 릴레이션에 담아서 관리한다.</p>
</blockquote>
<p>릴레이션은 일종의 표 형태로, 행과 열의 집합으로 구성된다. 각 행은 레코드나 튜플이라고 불리며, 각 열은 속성(attribute)이라고 불린다.</p>
<p>RDBMS에선 릴레이션을 테이블 이라 하며, NoSQL에선 컬렉션 이라 부른다.</p>
<h3 id="함수적-종속성functional-dependency">함수적 종속성(Functional Dependency)</h3>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/f86dd9a4-8ac7-419d-8434-5049dcf94d9f/image.png" alt=""></p>
<h4 id="완전-함수적-종속full-functional-dependency">완전 함수적 종속(Full Functional Dependency)</h4>
<p>완전 함수적 종속이란, 종속자가 기본키에만 종속되며, 기본키가 여러 속성으로 구성되어 있을경우 기본키를 구성하는 모든 속성이 포함된 기본키의 부분집합에 종속된 경우이다.</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/018f11cd-b8f6-4e02-afe3-a7727bd5ea03/image.png" alt=""></p>
<p>해당 릴레에션의 기본키는 &#39;고객ID&#39;와 &#39;상품코드&#39; 속성으로 구성되어 있다. 여기서 &#39;수량&#39; 속성은 기본키를 구성하는 &#39;고객ID&#39;, &#39;상품코드&#39; 속성을 모두 알아야 식별할 수 있다. 따라서 &#39;수량&#39;은 완전 함수 종속된 관계이다.</p>
<h4 id="부분-함수적-종속partial-functional-dependency">부분 함수적 종속(Partial Functional Dependency)</h4>
<p>부분 함수적 종속이란, 릴레이션에서 종속자가이 기본키가 아닌 다른 속성에 종속되거나, 기본키가 여러 속성으로 구성되어 있을경우 기본키를 구성하는 속성 중 일부만 종속되는 경우이다.</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/14ce4cc9-6adf-44b1-a569-f18d6cd79e1d/image.png" alt=""></p>
<p>기본키가 &#39;고객ID&#39; 와 &#39;제품코드&#39; 속성으로 구성된 위의 릴레이션에서 &#39;주문상품&#39;은 기본키 중 &#39;제품코드&#39;만 알아도 식별할 수 있다. 이 경우에는 &#39;주문상품&#39; 속성은 기본키에 부분 함수 종속된 관계이다.</p>
<h4 id="제1-정규형1nf">제1 정규형(1NF)</h4>
<p>릴레이션을 구성하는 모든 도메인이 원자값으로 된 정규형</p>
<h4 id="제2-정규형2nf">제2 정규형(2NF)</h4>
<p>제1 정규형을 만족하면서 릴레이션에 존재하는 부분 함수적 종속을 제거하여, 모든 속성이 기본키에 완전 함수 종속이 되도록 만들어진 정규형</p>
<h4 id="이행적-함수-종속transitive-functional-dependecy">이행적 함수 종속(Transitive Functional Dependecy)</h4>
<p>릴레이션에서 X, Y, Z라는 3 개의 속성이 있을 때 X→Y, Y→Z 이란 종속 관계가 있을 경우, X→Z가 성립될 때 이행적 함수 종속이라고 한다. 즉, X를 알면 Y를 알고 그를 통해 Z를 알 수 있는 경우를 말한다.</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/ce3964c7-853b-4a8e-8a8e-bac477df39be/image.png" alt=""></p>
<p>이 릴레이션에서 &#39;상품번호&#39;를 알면 &#39;소분류&#39;를 알 수 있고, &#39;소분류&#39;을 알면 &#39;대분류&#39;도 알 수 있다. 따라서 &#39;상품번호&#39;를 알면 &#39;대분류&#39;를 알 수 있으므로 이행적 함수 종속 관계이다. 이 때, 대분류는 소분류에 의해 관계되는 항목이지만, 상품번호를 통해 귀속되어있다. 따라서 이런 관계를 이행적 함수 종속이라고 한다.</p>
<h4 id="제3-정규형3nf">제3 정규형(3NF)</h4>
<p>제2 정규형을 만족하면서 릴레이션을 구성하는 속성들 간의 이행적 종속관계를 분해하여 속성들이 비이행적 함수 종속관계를 만족하도록 만들어진 정규형</p>
<h3 id="릴레이션의-분석-지침">릴레이션의 분석 지침</h3>
<blockquote>
<p>릴레이션이 잘 설계되었는지, 문제는 없는지 간단히 확인하는 기본 지침</p>
</blockquote>
<p>기본 지침을 체크해보면, 잘 설계되었는지 대략적으로 확인할 수 있다.</p>
<h4 id="1-스키마에서-속성의-의미가-명확한지-확인한다">1. 스키마에서 속성의 의미가 명확한지 확인한다.</h4>
<p>속성의 이름을 의미적으로 모호하지 않게 작명해야 한다.</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/71b1ba8b-bc3c-4cbd-918e-b563eeeda22a/image.png" alt=""></p>
<p>-&gt; 회원 테이블의 경우, 날짜 시간 이라고 작명하기 보다는, 더 명확하게 가입 날짜 시간 이라고 작명해준다.</p>
<p>-&gt; 게시글 데이터를 저장하기 위해 만든 게시글 릴레이션에는 게시글과 관련된 속성만 존재하게 한다. </p>
<p>위 예시처럼, 게시글 번호 를 기본키로 하는 게시글 릴레이션에 회원번호 작성자 이름 작성자 생년월일 등과 같은 게시글과 관계가 먼 속성들이 존재하여 데이터가 중복되는 부분들이 많이 생기면 메모리 문제, 중복 문제 뿐만 아니라 다른 문제도 야기할 수 있다.</p>
<h4 id="2-튜플들에서-중복되는-값들이-있는지-확인한다">2. 튜플들에서 중복되는 값들이 있는지 확인한다.</h4>
<h4 id="삽입-이상">삽입 이상</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/b548f64e-9537-4fab-a323-28a0daaf6208/image.png" alt=""></p>
<p>실수로 작성자의 이름을 김수민으로 잘 못 입력될 수 있다. 나중에, 릴레이션의 튜플들을 확인했을 때, 회원 번호 1번이 김민수 인지 김수민 인지 확실하게 알 수 없어 릴레이션의 신뢰성을 잃게된다.</p>
<h4 id="수정-이상">수정 이상</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/edcc37f5-1ce4-4a99-b6be-eb4b38750fe2/image.png" alt=""></p>
<p>회원 번호 1번인 회원의 이름을 특정한 이유로 일부만 변경되었을 때(실수로) , 삽입 이상 때와 같은 이유로 릴레이션의 신뢰성을 잃게된다.</p>
<h4 id="삭제-이상">삭제 이상</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/d87bd198-ffe8-42c3-88da-cb737eeaa978/image.png" alt=""></p>
<p>3번 게시글 튜플을 삭제 시, 게시글과 관련된 제목 , 내용 과 같은 데이터는 이유가 있어 삭제했다고 해도, 회원과 관련된 데이터도 모두 사라지게 된다. 이는, 데이터 누락을 야기하게 된다.</p>
<h4 id="3-튜플들에-저장된-null-값을-확인한다">3. 튜플들에 저장된 NULL 값을 확인한다.</h4>
<p>속성에 NULL 값이 빈번하게 저장되면, 불필요한 저장 공간을 사용하게 된다.
-&gt; 속성에 빈번하게 NULL 값이 저장된다는 의미가, 불필요한 정보라는 의미로 받아들일 수 있다. 따라서, 메모리 관점에서 이러한 속성이 해당 릴레이션에서 필수적인 속성인지 검토해볼 필요가 있다.</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/69f805bb-68e1-44ba-aeb5-3b29feedba23/image.png" alt=""></p>
<p>NULL 값이 존재하면, 튜플의 의미가 모호해지거나 통계적 관점에서도 쓸모없는 데이터가 되어버리기 때문에, 별도의 릴레이션으로 분리하는 것을 고려하는 것이 좋다.</p>
<h4 id="4-가짜-튜플이-생성되는지-확인한다">4. 가짜 튜플이 생성되는지 확인한다.</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/3e4702b3-1d0c-4c6b-98f0-37326e9078f7/image.png" alt=""></p>
<p>위와 같은 경우가 릴레이션을 잘못 분리한 예시이다.</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/6dfd0eea-fbf7-4726-b2d8-74d459266251/image.png" alt=""></p>
<p>릴레이션을 분리했다가 다시 합쳤을 뿐인데, (0003,데이터베이스,A0003) 과 같은 이전에는 존재하지 않았던 튜플이 생성되었고, 이를 가짜 튜플 이라고 한다.</p>
<p>이처럼, 릴레이션을 적절하게 분리하지 않거나, 잘못된 설계를 하면, 두 릴레이션을 JOIN 할 시 가짜 튜플 을 만들어 낸다.</p>
<hr>
<h3 id="정리">정리</h3>
<h4 id="정규화">정규화</h4>
<ul>
<li><p>제2 정규형 : 릴레이션에 존재하는 부분 함수적 종속을 제거하여, 모든 속성이 기본키에 완전 함수 종속이 되도록 만들어짐</p>
</li>
<li><p>제3 정규형 : 릴레이션을 구성하는 속성들 간의 이행적 종속관계를 분해하여 속성들이 비이행적 함수 종속관계를 만족하도록 만들어짐</p>
</li>
</ul>
<h4 id="릴레이션의-분석-지침-4가지">릴레이션의 분석 지침 4가지</h4>
<ul>
<li><p>릴레이션의 속성이 명확하게 작명되었는지 확인</p>
</li>
<li><p>릴레이션의 데이터가 중복되는 부분이 많은지 확인</p>
</li>
<li><p>속성 데이터가 NULL 값이 빈번하게 존재한다면, 필요한 속성인지 검토</p>
</li>
<li><p>릴레이션 분리 시, 적절하게 분리되어 가짜 튜플을 생성하지 않는지 확인</p>
</li>
</ul>
<h4 id="출처">출처</h4>
<p><a href="https://dodo000.tistory.com/20">https://dodo000.tistory.com/20</a>
<a href="https://swingswing.tistory.com/15">https://swingswing.tistory.com/15</a>
<a href="https://inkyu-yoon.github.io/docs/Learned/DataBase/RelationRule#1-%EC%8A%A4%ED%82%A4%EB%A7%88%EC%97%90%EC%84%9C-%EC%86%8D%EC%84%B1%EC%9D%98-%EC%9D%98%EB%AF%B8%EA%B0%80-%EB%AA%85%ED%99%95%ED%95%9C%EC%A7%80-%ED%99%95%EC%9D%B8%ED%95%9C%EB%8B%A4">https://inkyu-yoon.github.io/docs/Learned/DataBase/RelationRule#1-스키마에서-속성의-의미가-명확한지-확인한다</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] 패턴 매칭(pattern matching)]]></title>
            <link>https://velog.io/@calis_ws/DB-%ED%8C%A8%ED%84%B4-%EB%A7%A4%EC%B9%ADpattern-matching</link>
            <guid>https://velog.io/@calis_ws/DB-%ED%8C%A8%ED%84%B4-%EB%A7%A4%EC%B9%ADpattern-matching</guid>
            <pubDate>Sun, 25 Feb 2024 12:38:37 GMT</pubDate>
            <description><![CDATA[<p><code>=</code> 연산자로 검색하는 경우 데이터의 값이 완전히 동일한지를 비교하게 된다.</p>
<p>하지만 특정 문자나 문자열이 포함되어 있는지를 검색하고 싶은 경우도 많을 것이다.</p>
<p>이런 경우 LIKE 를 사용하여 패턴 매칭으로 검색할 수 있다.</p>
<h3 id="like-로-패턴-매칭">LIKE 로 패턴 매칭</h3>
<p>LIKE 를 사용하면 열 값이 부분적으로 일치하는 경우에도 참이 된다.</p>
<pre><code class="language-sql">// LIKE 조건식
열명 LIKE &#39;패턴&#39;</code></pre>
<p>LIKE 는 이항 연산자처럼 왼쪽에 매칭 대상을 지정하고 오른쪽에는 패턴을 문자열로 지정한다. 단, 수치형 상수는 지정할 수 없다.</p>
<p>패턴을 정의할 때는 <code>%</code> 그리고 <code>_</code>와 같은 메타문자를 사용할 수 있다.</p>
<p>와일드 카드라고 불리는 메타문자는 패턴 매칭 시 임의의 문자 또는 문자열에 매치하는 부분을 지정하기 위해 쓰이는 특수 문자이다.</p>
<p>퍼센트<code>%</code>는 임의의 문자열을 의미하고 언더스코어<code>_</code>는 임의의 문자 하나를 의미한다.</p>
<p>메타문자가 없어도 조회는 가능하지만 이럴 경우 완전 일치로 검색되므로 LIKE 를 사용하는 의미가 없어진다.</p>
<pre><code class="language-sql">SELECT * FROM sample25;</code></pre>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/24315f97-50e3-4455-adca-884587f309d4/image.png" alt=""></p>
<p>예제 테이블의 text 열에서 &#39;SQL&#39; 문자열을 포함하는 행을 패턴 매칭으로 검색해보자</p>
<pre><code class="language-sql">SELECT * FROM sample25 WHERE (text LIKE &#39;SQL%&#39;);</code></pre>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/092c85f9-6378-498e-8bc0-96313b1c29e2/image.png" alt=""></p>
<p>분명 no 열이 3인 행도 SQL 문자열을 포함하는데 조회 결과에 포함되지 않은 이유가 무엇일까?</p>
<p>그 이유는 text 열의 데이터가 SQL 문자열로 시작하지 않았기 때문이다.
다시 말해 SQL 문자열 앞에도 문자열이 존재하므로 % 메타문자를 패턴 앞에도 붙여줘야 한다.</p>
<pre><code class="language-sql">SELECT * FROM sample25 WHERE (text LIKE &#39;%SQL%&#39;);</code></pre>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/f4a5771f-0a78-490f-a6e9-dba26b42125c/image.png" alt=""></p>
<h3 id="like로-를-검색하기">LIKE로 %를 검색하기</h3>
<p>예제 테이블에서 no열이 2인 행의 text열 값을 보면 메타문자인 %와 _가 포함되어 있다.</p>
<p>만약 메타문자와 동일한 문자로 LIKE로 검색할 경우 어떻게 패턴을 정의해야 할까?</p>
<p>프로그래밍 언어에서는 이런 경우 대체로 이스케이프라는 방법으로 처리한다.</p>
<p>이스케이프 문자<code>\</code>를 메타문자 앞에 붙이면 메타문자도 패턴에 사용할 수 있다.</p>
<pre><code class="language-sql">SELECT * FROM sample25 WHERE (text LIKE &#39;%\%%&#39;);</code></pre>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/b867424c-b90c-427d-9908-3c549d2276f5/image.png" alt=""></p>
<h3 id="문자열-상수--의-이스케이프">문자열 상수 &#39; 의 이스케이프</h3>
<p>메타문자는 이스케이프로 처리할 수 있음을 확인하였다.</p>
<p>그렇다면 패턴과 같이 문자열 상수 안에 <code>&#39;</code>를 포함하고 싶다면 어떻게 해야 할까?</p>
<p>이때는 이스케이프 문자가 아니라 동일한 문자인 <code>&#39;</code>를 앞에 한 번 더 붙여주면 된다.</p>
<pre><code class="language-sql">WHERE (text LIKE &#39;It&#39;&#39;s&#39;)</code></pre>
<p>위의 예시를 보면 실제로 It&#39;s라는 문자열을 검색하는 명령임을 알 수 있다.</p>
<hr>
<h3 id="정리">정리</h3>
<p><code>=</code> 연산자로는 동일한 값만 비교 가능한 아쉬움을 패턴 매칭으로 해결할 수 있음을 알게 되었다.</p>
<p>하지만 보다 복잡한 패턴을 비교해야 하는 경우는 패턴 매칭보다는 정규 표현식(Regular Expression)을 사용하는 편이 더 나을 수 있다.</p>
<p>대부분의 데이터베이스가 정규 표현식을 지원하고 정규 표현식이 더 많은 메타문자를 지원하기 때문에 간단한 패턴에 대해서 이러한 패턴 매칭을 사용하면 훨씬 유연하게 조회를 할 수 있을 것이다.</p>
<h4 id="출처">출처</h4>
<p><a href="https://lxxjn0-dev.netlify.app/first-step-sql-lec-08">https://lxxjn0-dev.netlify.app/first-step-sql-lec-08</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] 데이터베이스에 대하여]]></title>
            <link>https://velog.io/@calis_ws/DB-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC</link>
            <guid>https://velog.io/@calis_ws/DB-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC</guid>
            <pubDate>Thu, 22 Feb 2024 21:36:05 GMT</pubDate>
            <description><![CDATA[<h3 id="데이터베이스란">데이터베이스란</h3>
<blockquote>
<p>특정 조직의 여러 사용자가 &#39;공유&#39;하여 사용할 수 있도록 &#39;통합&#39;해서 &#39;저장&#39;한 &#39;운영&#39; 데이터의 집합이다</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/35aa2059-d159-46fa-b384-8d0f18d4bc6e/image.png" alt=""></p>
<ul>
<li><p>공유 데이터 : 특정 조직의 여러 사용자가 함께 소유하고 이용할 수 있는 공유 데이터</p>
</li>
<li><p>통합 데이터 : 최소의 중복과 통제 가능한 중복만 허용하는 데이터</p>
</li>
<li><p>저장 데이터 : 컴퓨터가 접근할 수 있는 매체에 저장된 데이터</p>
</li>
<li><p>운영 데이터 : 조직의 주요 기능을 수행하기 위해 지속적으로 꼭 필요한 데이터</p>
</li>
</ul>
<h3 id="특징">특징</h3>
<ul>
<li><p>데이터의 구조화 : 데이터를 구조화하여 저장한다. 이는 데이터가 쉽게 검색, 추가, 삭제, 수정될 수 있도록 도와준다.</p>
</li>
<li><p>데이터의 독립성 : 데이터와 응용프로그램을 독립시킨다. 이는 데이터의 논리적 구조와 물리적 구조를 분리함으로써 데이터베이스 시스템의 유연성을 높여준다.</p>
</li>
<li><p>동시성 제어 : 여러 사용자가 동시에 접근할 수 있도록 해준다. 이 때, 데이터베이스 시스템은 데이터의 일관성을 유지하기 위해 동시성 제어를 수행한다.</p>
</li>
<li><p>데이터의 보안성 : 데이터의 무결성과 안전성을 보장하기 위한 다양한 보안 메커니즘을 제공한다.</p>
</li>
<li><p>데이터의 지속성 : 시스템 장애나 비정상적인 종료 상황에서도 데이터를 지속적으로 보존한다.</p>
</li>
</ul>
<h3 id="장단점">장단점</h3>
<h4 id="장점">장점</h4>
<ul>
<li><p>데이터 중복 최소화 : 중복을 피함으로써 데이터 일관성을 유지하고 저장 공간을 절약할 수 있다.</p>
</li>
<li><p>데이터의 일관성 : 데이터의 일관성을 유지하기 위한 동시성 제어와 트랜잭션 처리를 제공하여 데이터의 정확성을 보장한다.</p>
</li>
<li><p>데이터의 공유성 : 여러 사용자가 동시에 데이터에 접근할 수 있도록 허용하여 데이터의 공유성을 제공한다.</p>
</li>
<li><p>데이터의 보안성 강화 : 데이터베이스 시스템은 다양한 보안 메커니즘을 제공하여 민감한 데이터를 보호한다.</p>
</li>
<li><p>데이터의 표준화 : 데이터의 구조화와 표준화를 통해 데이터의 일관성을 유지하고 관리하기 쉽게 해준다.</p>
</li>
</ul>
<h4 id="단점">단점</h4>
<ul>
<li><p>비용 : 데이터베이스 시스템을 구축하고 유지보수하는 데에는 비용이 많이 들 수 있다.</p>
</li>
<li><p>복잡성 : 데이터베이스는 복잡한 구조를 가질 수 있으며, 이를 이해하고 관리하기 위해서는 전문적인 지식이 필요하다.</p>
</li>
<li><p>시스템의 종속성 : 데이터베이스 시스템을 선택하면 해당 시스템에 종속되는 경우가 있을 수 있다.</p>
</li>
<li><p>보안 문제 : 데이터베이스에 저장된 정보는 해킹, 무단 접근 등의 보안 위협에 노출될 수 있다. 이에 대한 보안 대책이 필요하다.</p>
</li>
<li><p>성능 문제 : 대용량의 데이터베이스를 다룰 때 성능 저하가 발생할 수 있으며, 이를 최적화하기 위해 추가적인 노력이 필요할 수 있다.</p>
</li>
</ul>
<hr>
<h3 id="정리">정리</h3>
<p>데이터베이스는 데이터를 구조화하여 효율적으로 관리하고 사용할 수 있도록 하는 매우 중요한 도구이다. 하지만 구축 및 유지보수 비용, 복잡성, 보안 문제 등의 단점도 고려해야 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL(MariaDB) dump 도전하기]]></title>
            <link>https://velog.io/@calis_ws/MySQLMariaDB-dump-%EB%8F%84%EC%A0%84%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@calis_ws/MySQLMariaDB-dump-%EB%8F%84%EC%A0%84%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 21 Feb 2024 11:42:29 GMT</pubDate>
            <description><![CDATA[<p>우리 프로젝트의 DB 서버를 팀장님이 내려버렸다</p>
<p>그래서 dump 를 하기 위해 AWS 계정을 받아옴</p>
<p>우선 팀장님 EC2 부터 다시 켜놓고 작업 시작</p>
<h3 id="dump-과정">dump 과정</h3>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/9f65ba64-42d6-41f0-88a1-4c442e4e7454/image.png" alt=""></p>
<p>내 계정에 DB용 EC2 인스턴스 하나 생성해준다</p>
<p>그 다음 ubuntu 접속 후 mariadb 설치</p>
<pre><code class="language-bash">$ sudo su
$ apt-get update
$ apt-get install mariadb-server mariadb-client</code></pre>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/93a55de2-3778-44fc-9dd3-83b9fdac03b2/image.png" alt=""></p>
<p>설치가 되면 <code>mysql -u root -p</code> 로 접속하는데 비번 설정이 안되어있음</p>
<p>아래 명령어로 비번 설정하기</p>
<pre><code class="language-bash">$ sudo mysql
$ use mysql;
$ set password for &#39;root&#39;@&#39;localhost&#39; = password(&#39;비밀번호&#39;); // 비밀번호를 설정
$ FLUSH PRIVILEGES; // 변경사항 적용</code></pre>
<p>설정해준 비번치고 재접속 후 새로 스키마 생성하기
<img src="https://velog.velcdn.com/images/calis_ws/post/6772660a-ce76-4944-90d5-ff2fc77117cf/image.png" alt=""></p>
<p>ubuntu 서버에 fcc 폴더 생성
<img src="https://velog.velcdn.com/images/calis_ws/post/8eaaafe6-7b38-4a3c-8dbc-c2579454929b/image.png" alt=""></p>
<p>아래 명령어를 입력하여 dump 진행</p>
<pre><code class="language-bash">$ mysqldump -h 원격지IP -u fcc(원격지계정) -p fcc(원격지대상DB) &gt; fcc/dump.sql;
$ use fcc;
$ source dump.sql</code></pre>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/fce94dbc-7679-49c8-a359-b8fb3a3967ea/image.png" alt=""></p>
<p>성공적으로 dump 가 완료되었다 !</p>
<h3 id="mariadb-외부-접속-허용하기">MariaDB 외부 접속 허용하기</h3>
<pre><code class="language-bash">$ sudo su -
$ vi /etc/mysql/mariadb.conf.d/50-server.cnf

// port 주석 해제 (없으면 기입)
// bind-address 127.0.0.1 -&gt; 0.0.0.0 으로 변경 (필수)

$ systemctl restart mariadb // 재시작</code></pre>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/1a3e77f4-7c40-4f3b-a4c9-8bbc3863a593/image.png" alt=""></p>
<pre><code class="language-bash">// MariaDB 접속
$ sudo su -
$ mysql -u root -p

// 권한 확인
mysql&gt; use mysql;
mysql&gt; select host, user, paswor from user;</code></pre>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/be3d8df2-4d2a-4316-8527-9c8a18ec99f6/image.png" alt=""></p>
<p>host 에 % 가 아닌 localhost 밖에 없어서 신규 유저 생성</p>
<pre><code class="language-bash">// 유저 생성
mysql&gt; create user &#39;YOUR_USER&#39;@&#39;%&#39; identified by &#39;YOUR_PASSWORD&#39;;
// 유저 변경
mysql&gt; update user set host=&#39;%&#39; where host=&#39;YOUR_HOST&#39; and user=&#39;YOUR_USER&#39;;

// 유저 권한 변경
mysql&gt; grant privileges on YOUR_DATABSE.* to &#39;YOUR_USER&#39;@&#39;%&#39; with grant option;</code></pre>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/b53208f9-46ec-4ecf-8daa-d6d483b8e85d/image.png" alt=""></p>
<p>포트 3306 인바운드 규칙 추가</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/0c28ad2c-1384-46e9-b973-432c9878f34e/image.png" alt=""></p>
<p>DB 접속 완료 !! 
도와주신 하영님 감사합니다 :)</p>
<p>출처 : <a href="https://8ugust-dev.tistory.com/19">https://8ugust-dev.tistory.com/19</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] 정규화, 역정규화]]></title>
            <link>https://velog.io/@calis_ws/DB-%EC%A0%95%EA%B7%9C%ED%99%94-%EC%97%AD%EC%A0%95%EA%B7%9C%ED%99%94</link>
            <guid>https://velog.io/@calis_ws/DB-%EC%A0%95%EA%B7%9C%ED%99%94-%EC%97%AD%EC%A0%95%EA%B7%9C%ED%99%94</guid>
            <pubDate>Sun, 18 Feb 2024 11:13:34 GMT</pubDate>
            <description><![CDATA[<h3 id="정규화normalization">정규화(normalization)</h3>
<blockquote>
<p>관계형 DB 설계에서 중복을 최소화하고 데이터 일관성을 유지하기 위해 데이터의 구조를 조직화하는 프로세스이다. </p>
</blockquote>
<p>주로 테이블을 작은 단위로 분리하여 중복을 제거하고, 이상 현상(anomalies)을 방지하는 데 사용된다.</p>
<h4 id="normal-forms">Normal forms</h4>
<p>정규화 되기 위해 준수해야 하는 몇 가지 rule 들이 있는데, 이 각각의 rule 을 normal form(NF) 이라고 한다.</p>
<h4 id="db-정규화-과정">DB 정규화 과정</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/382d78d3-871d-4154-a77b-fd562691f38a/image.png" alt=""></p>
<h3 id="제1-정규형">제1 정규형</h3>
<p>원자값(Atomic Value, 하나의 값)을 갖도록 테이블을 분해하는 작업
<img src="https://velog.velcdn.com/images/calis_ws/post/2e08e4c2-71a7-47eb-935f-f8931182aadd/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/3ca25134-d3fb-4ae9-be32-fcf6958f925f/image.png" alt=""></p>
<p>장점 : 데이터의 중복을 최소화하고 데이터 일관성을 유지할 수 있음
단점 : 중첩된 데이터를 허용하지 않기 때문에 데이터 구조를 더 복잡하게 만들 수 있음</p>
<h3 id="제2-정규형">제2 정규형</h3>
<p>현재 테이블의 주제와 관련없는 컬럼을 다른 테이블로 빼는 작업
<img src="https://velog.velcdn.com/images/calis_ws/post/38f28392-809f-4072-a036-1c5cc7e4eade/image.png" alt=""></p>
<pre><code>Partial Dependency : 부분적 종속
Composite Primary Key : 복합키</code></pre><p><img src="https://velog.velcdn.com/images/calis_ws/post/deb87d17-6dd7-4079-a46c-7d8ea99dcb16/image.png" alt=""></p>
<p>장점 : 데이터의 수정 작업이 편리해짐
단점 : 테이블의 분리로 인해 일부 쿼리가 복잡해질 수 있음</p>
<h3 id="제3-정규형">제3 정규형</h3>
<p>일반 컬럼에만 종속된 컬럼은 다른 테이블로 빼는 작업</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/b41b25e0-c904-4d8e-9298-281432740db5/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/a843a4dd-7904-48b9-8dcb-df4746f4c912/image.png" alt=""></p>
<p>장점 : 데이터 수정 시 발생할 수 있는 이상 현상을 방지함
단점 : 정규화된 데이터베이스는 조인을 많이 필요로 하므로 읽기 작업이 많은 시스템에서 성능 문제가 발생할 수 있음</p>
<p>관계형 DB 들은 정규화를 해두는게 일반적이지만 비관계형 DB 들은 정규화를 안하는 경우가 많다.</p>
<h3 id="역정규화-denormalization">역정규화 (Denormalization)</h3>
<blockquote>
<p>역정규화는 성능을 향상시키기 위해 정규화된 DB 를 다시 중복을 포함하는 형태로 변경하는 프로세스이다.</p>
</blockquote>
<p>테이블을 너무 많이 잘게 쪼개면 여러 테이블들이 모두 동시에 조인을 하게 되기 때문에 성능이 느려지는 이슈가 발생할 수 있고, 관리하기 어려워질 수 있다. </p>
<ul>
<li><p>일반적으로 쿼리의 성능을 향상시키기 위해 사용되며, 특히 읽기 작업이 많은 시스템에서 유용하다. </p>
</li>
<li><p>데이터의 일부를 중복 저장하거나 중복 인덱스를 생성함으로써 데이터에 대한 읽기 액세스를 최적화한다. </p>
</li>
<li><p>하지만 데이터 일관성을 유지하기 위해 조심스럽게 사용되어야 한다.</p>
</li>
</ul>
<hr>
<h3 id="정리">정리</h3>
<p>정규화는 데이터 일관성과 구조를 유지하고 중복을 최소화하기 위해 데이터를 정리하는 반면, 역정규화는 읽기 성능을 향상시키기 위해 중복을 허용하는 방향으로 데이터를 재구성하는 것이다.</p>
<p>DB 를 설계할 때 과도한 조인과 중복 데이터 최소화 사이에서 적정 수준을 선택할 필요가 있다.</p>
<h4 id="출처">출처</h4>
<p>데이터 정규화가 뭔지 설명해보세요 (개발면접타임)
<a href="https://youtu.be/Y1FbowQRcmI?si=qohrNhajyETA2evF">https://youtu.be/Y1FbowQRcmI?si=qohrNhajyETA2evF</a></p>
<p>(1부) DB 정규화(normalization)는 DB를 설계하는 공식적인 방법이죠~ 1부에서는 정규화 개념과 정규화 과정의 앞 부분인 1NF, 2NF를 설명합니다 :)
<a href="https://youtu.be/EdkjkifH-m8?si=aEX_ni05tFE1jQPj">https://youtu.be/EdkjkifH-m8?si=aEX_ni05tFE1jQPj</a></p>
<p>(2부) DB 정규화(normalization) 2부입니다!! 3NF, BCNF와 2NF 참고 사항, 역정규화(denormalization)까지 설명합니다!!
<a href="https://youtu.be/5QhkZkrqFL4?si=aUKZ81mNL7mLalSJ">https://youtu.be/5QhkZkrqFL4?si=aUKZ81mNL7mLalSJ</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] index 의 적용 기준]]></title>
            <link>https://velog.io/@calis_ws/DB-index-%EC%9D%98-%EC%A0%81%EC%9A%A9-%EA%B8%B0%EC%A4%80</link>
            <guid>https://velog.io/@calis_ws/DB-index-%EC%9D%98-%EC%A0%81%EC%9A%A9-%EA%B8%B0%EC%A4%80</guid>
            <pubDate>Fri, 16 Feb 2024 14:58:33 GMT</pubDate>
            <description><![CDATA[<p>인덱스는 테이블의 동작 속도를 높여주는 자료 구조이다.
데이터의 위치를 빠르게 찾아주는 역할을 한다.</p>
<p>쉬운 예시로, 책 뒷 편에 ‘색인’이 바로 이 인덱스의 역할이라고 보면 된다.
색인을 통해 원하는 키워드에 대한 페이지로 바로 이동할 수 있다.</p>
<p>책의 색인이 여러 페이지에 기재되어 있는 것처럼
DB의 인덱스가 잘 설정되었을 경우, 데이터베이스 메모리에 일정 공간을 사용해 저장이 되고, 데이터를 조회할 때 소모되는 메모리를 효율적으로 사용하게 한다.</p>
<h3 id="인덱스의-특징">인덱스의 특징</h3>
<h4 id="인덱스는-where-절에서-효과가-있다">인덱스는 WHERE 절에서 효과가 있다</h4>
<p>인덱스는 SELECT - FROM - WHERE 절 중 WHERE 절에 사용할 컬럼에 대한 효율화라고 볼 수 있다.</p>
<p>WHERE 절을 사용하지 않고 인덱스가 걸린 컬럼을 조회하는 것은 성능에 아무런 영향이 없다.</p>
<p>예를 들어, ‘학생’ 테이블에 ‘학번’, ‘이름’, ‘전화번호’가 있다고 가정해보자.
인덱스는 ‘학번’, ‘전화번호’에 걸려 있다.</p>
<p>다음 중 인덱스가 영향을 주는 쿼리는 어떤 것일까?</p>
<pre><code class="language-sql">1번) SELECT &#39;학번&#39; FROM &#39;학생&#39;;
2번) SELECT &#39;전화번호&#39; FROM &#39;학생&#39; WHERE &#39;이름&#39; = &quot;김철수&quot;;
3번) SELECT * FROM &#39;학생&#39; WHERE &#39;학번&#39; = 1;</code></pre>
<p>정답은 3번)
WHERE 절에 사용할 때 성능을 향상시킨다.</p>
<h4 id="무조건-많이-설정하면-좋은걸까">무조건 많이 설정하면 좋은걸까?</h4>
<p>인덱스는 하나 혹은 여러 개의 컬럼에 대해 설정할 수 있다.
단일 인덱스를 여러 개 생성할 수도, 여러 컬럼을 묶어 복합 인덱스를 설정할 수도 있다.</p>
<p>그러나 무조건 많이 설정하는게 검색 속도 향상을 높여주지는 않는다.
인덱스는 데이터베이스 메모리를 사용하여 테이블 형태로 저장되므로 개수와 저장 공간은 비례한다.</p>
<p>따라서, 조회시 자주 사용하고 고유한 값 위주로 인덱스를 설정하는게 좋다.</p>
<h4 id="dmldata-manipulation-language-각각에는-어떤-영향을-미칠까">DML(Data Manipulation Language) 각각에는 어떤 영향을 미칠까?</h4>
<p>SELECT 쿼리에서 성능이 잘 나오지만, INSERT, UPDATE, DELETE 쿼리에서는 때에 따라 다르다.</p>
<p>UPDATE, DELETE 는 WHERE 절에 잘 설정된 인덱스로 조건을 붙여주면 조회할 때 성능은 크게 저하되지 않으나
(업데이트 할 데이터를 찾을 때의 속도가 빨라지는 것이지, 업데이트 자체가 빨라지는 것은 아님!)</p>
<p>INSERT 의 경우, 새로운 데이터가 추가되면서 → 기존에 인덱스 페이지에 저장되어 있던 탐색 위치가 수정되어야 하므로 효율이 좋지 않다.</p>
<p>즉, 인덱스는 원하는 데이터를 빠르게 찾을 때 빛을 발한다.</p>
<h4 id="그럼-어떤-컬럼에-인덱스를-설정하는게-좋을까">그럼 어떤 컬럼에 인덱스를 설정하는게 좋을까?</h4>
<p>인덱스는 한 테이블당 보통 3~5개 정도가 적당하다.
물론 테이블의 목적 등에 따라 개수는 달라질 수 있다.</p>
<p>인덱스는 컬럼을 정해서 설정하는 것이므로 후보 컬럼의 특징을 잘 파악해야 한다.
아래 4가지 기준을 사용하면 효율적으로 인덱스를 설정할 수 있다.</p>
<h4 id="카디널리티-cardinality">카디널리티 (Cardinality)</h4>
<p>✔️ 카디널리티가 높을 수록 인덱스 설정에 좋은 컬럼이다.
= 한 컬럼이 갖고 있는 값의 중복 정도가 낮을 수록 좋다.</p>
<p>컬럼에 사용되는 값의 다양성 정도, 즉 중복 수치를 나타내는 지표이다.
후보 컬럼에 따라 상대적으로 중복 정도가 낮다, 혹은 높다로 표현된다.</p>
<p>예를 들어, 10개 rows를 가지는 ‘학생’ 테이블에 ‘학번’과 ‘이름’ 컬럼이 있다고 해보자.</p>
<ul>
<li>‘학번’은 학생마다 부여 받으므로 10개 값 모두 고유하다.<ul>
<li>중복 정도가 낮으므로 카디널리티가 높다.</li>
</ul>
</li>
<li>‘이름’은 동명이인이 있을 수 있으니 1~10개 사이의 값을 가진다.<ul>
<li>중복 정도가 ‘학번’에 비해 높으므로 카디널리티가 낮다고 표현할 수 있다.</li>
</ul>
</li>
</ul>
<h4 id="선택도-selectivity">선택도 (Selectivity)</h4>
<p>✔️ 선택도가 낮을 수록 인덱스 설정에 좋은 컬럼이다.
5~10% 정도가 적당하다.</p>
<p>데이터에서 특정 값을 얼마나 잘 선택할 수 있는지에 대한 지표이다.
선택도는 아래와 같이 계산한다.</p>
<pre><code>= 컬럼의 특정 값의 row 수 / 테이블의 총 row 수 * 100
= 컬럼의 값들의 평균 row 수 / 테이블의 총 row 수 * 100</code></pre><p>예를 들어, 10개 rows를 가지는 ‘학생’ 테이블에 ‘학번’, ‘이름’, ‘성별’ 컬럼이 있다고 해보자.
학번은 고유하고, 이름은 2명씩 같고, 성별은 남녀 5:5 비율이다.</p>
<ul>
<li>‘학번’의 선택도 = 1/10 * 100 = 10%<ul>
<li>SELECT COUNT(1) FROM &#39;학생&#39; WHERE &#39;학번&#39; = 1; (모두 고유하므로 특정 값 : 1)</li>
</ul>
</li>
<li>‘이름’의 선택도 = 2/10 * 100 = 20%<ul>
<li>SELECT COUNT(1) FROM &#39;학생&#39; WHERE &#39;이름&#39; = &quot;김철수&quot;; (2명씩 같으므로 특정 값 : 2)</li>
</ul>
</li>
<li>‘성별’의 선택도 = 5/10 * 100 = 50%<ul>
<li>SELECT COUNT(1) FROM &#39;학생&#39; WHERE &#39;성별&#39; = F; (5명씩 같으므로 특정 값 : 5)</li>
</ul>
</li>
</ul>
<p>즉, 선택도는 특정 필드값을 지정했을 때 선택되는 레코드 수를 테이블 전체 레코드 수로 나눈 것이다.</p>
<h4 id="활용도">활용도</h4>
<p>✔️ 활용도가 높을 수록 인덱스 설정에 좋은 컬럼이다.</p>
<p>해당 컬럼이 실제 작업에서 얼마나 활용되는지에 대한 값이다.
수동 쿼리 조회, 로직과 서비스에서 쿼리를 날릴 때 WHERE 절에 자주 활용되는지를 판단하면 된다.</p>
<h4 id="중복도">중복도</h4>
<p>✔️ 중복도가 낮을 수록 인덱스 설정에 좋은 컬럼이다.</p>
<p>중복도는 인덱스로 선택된 값이 얼마나 고유한지를 나타낸다.</p>
<p>중복도가 낮을수록 인덱스의 효과가 높아진다. 
즉, 인덱스로 선택된 값이 서로 다른 레코드에서 자주 발생하는 경우에는 인덱스가 더 유용합니다.</p>
<p>예를 들어, 성별 열은 중복도가 높지만 주민등록번호와 같은 고유한 값은 중복도가 매우 낮다.</p>
<hr>
<h3 id="정리">정리</h3>
<p>인덱스는 WHERE 절에서 사용할 때 성능을 향상시킨다.</p>
<p>조회 시 자주 사용하고 고유한 값 위주로 인덱스를 설정하는게 좋다.</p>
<ul>
<li>카디널리티 : 높을 수록 적합</li>
<li>선택도 : 낮을 수록 적합 (5~10% 적정)</li>
<li>활용도 : 높을 수록 적합</li>
<li>중복도 : 낮을 수록 적합</li>
</ul>
<p>이러한 요소들을 고려하여 인덱스를 설계하면 데이터베이스의 성능을 최적화할 수 있다.</p>
<h4 id="출처">출처</h4>
<p><a href="https://yurimkoo.github.io/db/2020/03/14/db-index.html">https://yurimkoo.github.io/db/2020/03/14/db-index.html</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] Hash index 와 B-Tree index]]></title>
            <link>https://velog.io/@calis_ws/DB-Hash-index-%EC%99%80-B-Tree-index</link>
            <guid>https://velog.io/@calis_ws/DB-Hash-index-%EC%99%80-B-Tree-index</guid>
            <pubDate>Tue, 13 Feb 2024 21:17:32 GMT</pubDate>
            <description><![CDATA[<h3 id="hash-index">Hash index</h3>
<blockquote>
<p>해시 테이블은 데이터 요소의 주소/인덱스 값이 해시 함수에서 생성되는 데이터 구조 유형이다. 인덱스 값이 데이터 값에 대한 키로 동작하므로 매우 빠른 데이터 액세스가 가능하다.</p>
</blockquote>
<p>해시 테이블은 키-값 쌍을 저장하지만 키는 해싱 함수를 통해 생성된다. 따라서 키 값 자체가 데이터를 저장하는 배열의 인덱스가 되기 때문에 데이터 요소의 검색 및 삽입 기능이 훨씬 빨라진다. 조회하는 동안 키가 해시되고 결과 해시는 해당 값이 저장된 위치를 나타낸다.</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/2e6c0c73-4bf2-4e5f-8139-13d47df374b5/image.png" alt=""></p>
<p>해싱의 개념은 버킷 배열에 항목(키/값 쌍)을 배포하는 것이다. 키가 주어지면 알고리즘은 항목을 찾을 수 있는 위치를 제안하는 인덱스를 계산한다.</p>
<h3 id="b-tree-index">B-tree index</h3>
<blockquote>
<p>최대 2개의 자식 노드만을 가지는 이진탐색트리(BST)를 일반화하여 2개 이상의 자식 노드를 가질 수 있도록 확장한 균형 트리이다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/c3411c4f-7425-4237-9777-4f605d1d9e36/image.png" alt=""></p>
<p>자녀 노드의 최대 개수를 원하는대로 결정해서 사용할 수 있다.</p>
<p>최대 m 개의 자녀를 가질 수 있는 B-tree를 m 차 B-tree 라고 한다.</p>
<pre><code class="language-java">m : 각 노드의 최대 자녀 노드 수
m - 1 : 각 노드의 최대 key 수
m / 2 (올림) : 각 노드의 최소 자녀 노드 수
m / 2 (올림) - 1 : 각 노드의 최소 key 수</code></pre>
<h4 id="속성">속성</h4>
<ul>
<li><p>모든 리프 노드는 동일한 수준에 있어야 한다.</p>
</li>
<li><p>루트를 제외한 모든 노드에는 최소 [m/2]-1개의 키와 최대 m-1개의 키가 있어야 한다.</p>
</li>
<li><p>루트를 제외한 모든 비 리프 노드(즉, 모든 내부 노드)에는 최소 m/2개의 자식이 있어야 한다.</p>
</li>
<li><p>루트 노드가 리프 노드가 아닌 경우 최소 2개의 자식이 있어야 한다.</p>
</li>
<li><p>n-1 개의 키가 있는 비 리프 노드에는 n개의 자식이 있어야 한다.</p>
</li>
<li><p>노드의 모든 키 값은 오름차순 이어야 한다.</p>
</li>
</ul>
<h3 id="차이점">차이점</h3>
<h4 id="1-검색-방법">1. 검색 방법</h4>
<ul>
<li><p>Hash 인덱스 : 해시 함수를 사용하여 키를 해싱하고, 해시 테이블에 저장한다. 해시 테이블은 해시 값과 해당하는 데이터 레코드의 포인터를 저장한다. 따라서 검색 시 해시 값을 계산하여 해당하는 위치로 바로 이동하여 데이터를 찾는다. 이는 일반적으로 O(1)의 시간 복잡도를 가진다.</p>
</li>
<li><p>B-Tree 인덱스 : B-Tree 는 이진 트리의 확장된 형태로, 노드당 여러 키를 가질 수 있다. 이진 탐색 트리와는 달리 균형을 유지하며, 각 노드의 자식은 키 값에 대한 범위를 가진다. 따라서 검색 시 루트부터 시작하여 트리를 탐색하며 원하는 키를 찾는다. 이는 일반적으로 O(log n)의 시간 복잡도를 가진다.</p>
</li>
</ul>
<h4 id="2-범위-검색">2. 범위 검색</h4>
<ul>
<li><p>Hash 인덱스 : 해시 함수를 사용하기 때문에 키의 범위 검색이 어렵다. 범위 검색을 하려면 모든 해시 값에 대해 순차적으로 탐색해야 한다.</p>
</li>
<li><p>B-Tree 인덱스 : B-Tree는 범위 검색에 효과적이다. 각 노드가 키 값에 대한 범위를 가지기 때문에 범위 검색 시에도 효율적으로 데이터를 찾을 수 있다.</p>
</li>
</ul>
<h4 id="3-데이터-정렬">3. 데이터 정렬</h4>
<ul>
<li><p>Hash 인덱스 : 해시 함수를 사용하기 때문에 데이터가 해시 값에 따라 무작위로 배치된다.</p>
</li>
<li><p>B-Tree 인덱스 : B-Tree는 키 값에 따라 정렬된 상태로 데이터가 저장된다.</p>
</li>
</ul>
<h4 id="4-인덱스-크기">4. 인덱스 크기</h4>
<ul>
<li><p>Hash 인덱스 : 일반적으로 B-Tree 인덱스보다 작은 크기를 가진다. 하지만 해시 충돌이 발생할 경우 공간 효율성이 저하될 수 있다.</p>
</li>
<li><p>B-Tree 인덱스 : Hash 인덱스보다 큰 크기를 가질 수 있다.</p>
</li>
</ul>
<h4 id="5-적용-가능성">5. 적용 가능성</h4>
<ul>
<li><p>Hash 인덱스 : 등 값이 정확히 일치해야 하는 경우에 유용하다. 예를 들어 고유한 식별자를 가진 테이블에 매우 적합하다.</p>
</li>
<li><p>B-Tree 인덱스 : 범위 검색이나 정렬된 데이터에 대한 검색이 필요한 경우에 유용하다. 대다수의 상황에서 일반적으로 사용된다.</p>
</li>
</ul>
<hr>
<h3 id="정리">정리</h3>
<p>Hash table 은 O(1)으로 탐색시간이 빠르지만 이는 단 하나의 데이터를 탐색하기 때문이다. 또한 저장되는 값들은 정렬되어 있지 않기 때문에 특정 값보다 크거나 작은 값을 찾을 수 없다. 그리고 해시 충돌이 발생할 경우, 성능 저하의 문제와 탐색에 걸리는 시간이 증가 할 수 있다.</p>
<p>반면에 B-Tree를 사용할 경우 평균적으로 O(logN)이라는 빠른 성능으로 탐색, 삽입, 수정, 삭제할 수 있으며, 정렬이 되어 있기 때문에 &gt;,&lt; 과 같은 범위탐색에 효율적으로 접근할 수 있다. 또한 노드마다 배열로 구현되어 있기 때문에 참조포인터를 RB-Tree 에 비해 조금 사용하여 방대한 데이터 접근에 더 적합하다.</p>
<p>따라서 DataBase 의 여러 고려사항을 따졌을 때 B-Tree 가 가장 적합한 자료구조로 채택이 된다.</p>
<h4 id="출처">출처</h4>
<p><a href="https://applepick.tistory.com/155">https://applepick.tistory.com/155</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Stack 대신 Deque]]></title>
            <link>https://velog.io/@calis_ws/Java-Stack-%EB%8C%80%EC%8B%A0-Deque</link>
            <guid>https://velog.io/@calis_ws/Java-Stack-%EB%8C%80%EC%8B%A0-Deque</guid>
            <pubDate>Tue, 06 Feb 2024 14:16:28 GMT</pubDate>
            <description><![CDATA[<h2 id="deque">Deque</h2>
<blockquote>
<p>자바에서 Deque(Double Ended Queue) 는 Queue 인터페이스를 상속받은 인터페이스이며, Queue 와 Stack 의 메서드를 모두 제공한다.</p>
</blockquote>
<p>자료의 입출력을 양 끝에서 할 수 있다. 인덱스로 요소에 액세스, 삽입, 제거를 허용하지 않는다.</p>
<h4 id="삽입">삽입</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/fbda1ab8-ba3b-4da2-82da-513c9af1b8d1/image.png" alt=""></p>
<h4 id="삭제">삭제</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/1b18926b-1c61-4b47-8f04-95c0ce24a526/image.png" alt=""></p>
<h4 id="조회">조회</h4>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/baccf651-078f-492e-a528-549eff63dc24/image.png" alt=""></p>
<pre><code class="language-java">public class Application {
    public static void main(String[] args) {
        Deque&lt;String&gt; deque = new ArrayDeque&lt;&gt;();
        deque.addFirst(&quot;첫 번째 요소&quot;); // &quot;첫 번째 요소&quot;
        deque.add(&quot;두 번째 요소&quot;); // &quot;첫 번째 요소&quot;, &quot;두 번째 요소&quot;
        deque.push(&quot;세 번째 요소&quot;); // &quot;세 번째 요소&quot;, &quot;첫 번째 요소&quot;, &quot;두 번째 요소&quot;
        System.out.println(deque.pop());
        System.out.println(deque.pop());
    }
}
// [출력 결과]
// 세 번째 요소
// 첫 번째 요소</code></pre>
<h3 id="종류">종류</h3>
<pre><code class="language-java">Deque&lt;Integer&gt; queue = new ArrayDeque&lt;&gt;();
Deque&lt;Integer&gt; queue2 = new LinkedList&lt;&gt;();</code></pre>
<p>일반적으로 Deque의 구현체는 ArrayDeque 와 LinkedList 가 있다.</p>
<h4 id="arraydeque">ArrayDeque</h4>
<ul>
<li><p>Deque 인터페이스의 구현체이며 크기를 재설정 할 수 있다.</p>
</li>
<li><p>null 요소 추가 불가</p>
</li>
<li><p>양쪽 끝에서 추가, 제거하는 것이 효율적이다</p>
</li>
<li><p>메모리 소모량이 적을 때는 iterate 효율이 좋은 ArrayDeque 를 사용하는 것이 좋다</p>
</li>
</ul>
<h4 id="linkedlist">LinkedList</h4>
<ul>
<li><p>List 의 구현체다.</p>
</li>
<li><p>null 요소를 추가할 수 있다</p>
</li>
<li><p>반복중에 현재 요소를 제거하는 것이 효율적이다</p>
</li>
<li><p>ArrayDeque 보다 많은 메모리를 소모한다</p>
</li>
<li><p>스택의 사이즈가 커지거나 심한 변동이 예상될 때는 즉각적인 메모리 공간 확보를 위해 LinkedList 를 사용한다.</p>
</li>
</ul>
<p>대부분의 상황에서는 Deque 를 사용할 때 ArrayDeque 를 사용한다.</p>
<h3 id="그럼-deque-만-써도-되는거-아님">그럼 Deque 만 써도 되는거 아님?</h3>
<h4 id="1-문제-상황에-따른-선택">1. 문제 상황에 따른 선택</h4>
<p>스택과 큐가 각자 잘 맞는 상황이 있습니다. 예를 들어, 괄호 짝 맞추기 문제는 스택을, 프린터 큐 문제는 큐를 사용하는 것이 더 자연스럽습니다. 덱을 사용하면 구현이 복잡해질 수 있습니다.</p>
<h4 id="2-가독성과-유지-보수">2. 가독성과 유지 보수</h4>
<p>스택과 큐는 각각의 역할이 명확하므로, 코드의 가독성을 높이고 유지 보수를 용이하게 합니다. 덱을 사용하면 코드가 복잡해지고 오류 발생 가능성이 높아질 수 있습니다.</p>
<h4 id="3-효율성">3. 효율성</h4>
<p>스택과 큐는 각각의 목적에 맞게 최적화된 연산을 제공합니다. 반면에 덱은 양쪽 끝에서의 연산을 모두 지원하므로, 특정 상황에서는 스택이나 큐보다 덜 효율적일 수 있습니다.</p>
<p><em>출처 : GPT-4 답변</em></p>
<hr>
<h3 id="정리">정리</h3>
<p>Deque(덱 또는 데크) 란 쉽게 말해 양방향 큐이다.
Stack 과 Queue 대신 Deque 를 사용할 수 있다.</p>
<p>LinkedList 나 ArrayDeque 로 사용될 수 있으며, ArrayDeque 로 사용 시 Stack 으로 사용하면 Stack 보다 빠르고, Queue 로 사용하면 LinkedList 보다 빠를 수 있다.</p>
<h4 id="출처">출처</h4>
<p><a href="https://soft.plusblog.co.kr/24">https://soft.plusblog.co.kr/24</a>
<a href="https://ttl-blog.tistory.com/170">https://ttl-blog.tistory.com/170</a>
<a href="https://velog.io/@may_yun/JAVA-Stack-%EB%8C%80%EC%B2%B4-Collection-Deque">https://velog.io/@may_yun/JAVA-Stack-대체-Collection-Deque</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] 문자열 리터럴과 객체]]></title>
            <link>https://velog.io/@calis_ws/Java-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A6%AC%ED%84%B0%EB%9F%B4%EA%B3%BC-%EA%B0%9D%EC%B2%B4</link>
            <guid>https://velog.io/@calis_ws/Java-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A6%AC%ED%84%B0%EB%9F%B4%EA%B3%BC-%EA%B0%9D%EC%B2%B4</guid>
            <pubDate>Sat, 03 Feb 2024 13:50:34 GMT</pubDate>
            <description><![CDATA[<h4 id="literal">literal</h4>
<p>변수에 저장되기 전의 값을 리터럴이라고 한다.</p>
<pre><code class="language-java">int score = 100;        // 변수 : score
final int MAX = 100;    // 상수 : MAX</code></pre>
<h3 id="선언-방법">선언 방법</h3>
<p>자바에는 String 을 선언하는 방법이 리터럴과 객체로 선언할 수 있다.</p>
<pre><code class="language-java">//리터럴
String a = &quot;hello&quot;;
String b = &quot;hello&quot;;

//객체
String c = new String(&quot;hello&quot;);
String d = new String(&quot;hello&quot;);

System.out.println(a.equals(b));     // true
System.out.println(a == b);          // true

System.out.println(c.equals(d));     // true
System.out.println(c == d);         // false

System.out.println(a.equals(c));     // true
System.out.println(a == c);            // false
</code></pre>
<p>리터럴 선언 방식은 Heap 영역 안에 있는 String Constant Pool(상수풀) 에 위치한다.
String Constant Pool 에 이미 존재하는 문자열이라면 같은 주소값을 공유한다.</p>
<p>따라서 변수 a, b 는 비교하였을 때, 문자열과 주소값이 모두 같은 것을 확인할 수 있다.</p>
<pre><code>String Constant Pool 이란

자바 메모리 중 Heap 영역 안에 위치하여 String 을 별도로 관리하는 장소다.
Heap 안에 있기 때문에 모든 스레드가 공유할 수 있고 가비지 콜렉터의 대상이 된다.</code></pre><p>객체 선언 방식은 Heap 영역에 할당된다.
새로운 인스턴스를 생성할 때마다 Heap 영역에 객체가 새로 생긴다.</p>
<p>따라서 변수 c, d 를 비교하였을 때 문자열은 같지만 Heap 영역에서 서로 다른 객체로 생성되었기 때문에 주소값은 다르다.</p>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/90c71c50-1deb-4b76-bf35-95632d468d67/image.png" alt=""></p>
<p>문자열 리터럴은 String Constant Pool 영역에, 객체는 Heap 영역안에 위치하므로
변수 a, c 는 서로 다른 주소값을 참조한다.</p>
<pre><code class="language-java">System.out.println(a == c.intern());     //true</code></pre>
<p><code>intern()</code> 메서드는 String Constant pool 에서 리터럴 문자열이 있으면 반환하고, 없다면 새로 문자열을 넣어주고 그 주소값을 반환한다.</p>
<p>new 연산자로 생성한 변수 c 에 <code>intern()</code> 메서드를 적용하면 리터럴 변수인 a 와 참조하는 주소값이 같아진다.</p>
<ol>
<li><code>intern()</code> 메소드 실행</li>
<li>String Constant Pool 에 문자열 존재하는지 확인</li>
<li>동일한 주소값 리턴</li>
</ol>
<hr>
<h3 id="정리">정리</h3>
<h4 id="리터럴">리터럴</h4>
<ul>
<li><p>상수풀이라는 특별한 메모리 영역에 저장된다. </p>
</li>
<li><p>서로 같은 문자열 리터럴을 사용하는 경우, 동일한 객체로 인식된다.</p>
</li>
<li><p><code>==</code> 연산자를 사용하여 동등성을 비교할 수 있다.</p>
</li>
<li><p>자바는 상수풀에서 중복된 문자열을 관리하므로 같은 문자열 리터럴을 사용하면 같은 객체를 참조하게 된다.</p>
</li>
</ul>
<h4 id="객체">객체</h4>
<ul>
<li><p>new 연산자로 문자열을 생성하면 새로운 객체가 heap 메모리에 할당된다.</p>
</li>
<li><p>동일한 문자열이라도 별도의 객체로 취급된다. </p>
</li>
<li><p>불필요한 메모리 사용이 발생할 수 있다.</p>
</li>
<li><p><code>==</code> 로 동등성을 비교하면 객체의 참조값을 비교하게 되므로 <code>equals()</code> 를 사용하여 내용을 비교해야 한다.</p>
</li>
</ul>
<p>일반적으로 문자열을 다룰 때는 리터럴 방식을 사용하는 것이 권장되며, 이는 코드의 가독성을 높이고 불필요한 메모리 사용을 최소화할 수 있다.</p>
<h4 id="출처">출처</h4>
<p><a href="https://velog.io/@kiiiyeon/%EC%9E%90%EB%B0%94-%EC%8A%A4%ED%8A%B8%EB%A7%81-%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1-%EB%B0%A9%EB%B2%95">https://velog.io/@kiiiyeon/자바-스트링-객체-생성-방법</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] hashCode 란?]]></title>
            <link>https://velog.io/@calis_ws/Java-hashCode-%EB%9E%80</link>
            <guid>https://velog.io/@calis_ws/Java-hashCode-%EB%9E%80</guid>
            <pubDate>Thu, 01 Feb 2024 14:50:11 GMT</pubDate>
            <description><![CDATA[<h2 id="hashcode"><code>hashCode()</code></h2>
<blockquote>
<p>객체 hashcode 란 객체를 식별하는 하나의 고유 정수값을 말한다.</p>
</blockquote>
<p>쉽게 말해서 객체의 지문이다.</p>
<ul>
<li><p>객체의 해시코드(hash code)를 반환하는 메소드</p>
</li>
<li><p>Object 클래스의 메소드로써, 모든 클래스는 Object 클래스를 상속하기 때문에 사실상 모든 객체에서 가지고 있는 메소드</p>
</li>
<li><p><code>hashCode()</code> 는 객체의 주소를 int 로 변환해서 반환한다.</p>
</li>
</ul>
<pre><code class="language-java">import java.util.Objects;

public class Main {
    public static void main(String[] args) {
        Person person1 = new Person(&quot;kimsana&quot;);
        Person person2 = new Person(new String(&quot;kimsana&quot;));
        Person person3 = person2;
        Person person4 = new Person(&quot;kimsana&quot;);

        System.out.println(person1.hashCode()); // 798154996
        System.out.println(person2.hashCode()); // 681842940
        System.out.println(person3.hashCode()); // 681842940
        System.out.println(person4.hashCode()); // 1392838282
        System.out.println(person1.equals(person4)); // false

        // 재정의 하면 전부 106222
        // equals 도 재정의 해줘야함
    }
}

// @EqualsAndHashCode 이거 쓰면 원콤
class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(name); // name 에서 해시 코드 생성
    }
}</code></pre>
<ul>
<li><code>equals()</code> 를 오버라이딩하면, <code>hashCode()</code> 도 오버라이딩해야 한다.
<code>equals()</code> 의 결과가 true 인 두 객체의 해시코드는 같다.</li>
</ul>
<pre><code class="language-java">String str1 = new String(&quot;abc&quot;);
String str2 = new String(&quot;abc&quot;);
System.out.println(str1.equals(str2));    // true
System.out.println(str1.hashCode());    // 96354
System.out.println(str2.hashCode());    // 96354</code></pre>
<ul>
<li>String class 는 <code>equals()</code> 메소드를 재정의해서 주소값 비교가 아닌 문자열 &#39;값&#39;만을 비교한다.
(참고로 반대로 &#39;주소값&#39;을 비교하는 건 &#39;==&#39; 연산자를 많이 쓴다.)</li>
</ul>
<h3 id="equals와-hashcode를-함께-재정의해야-하는-이유"><code>equals()</code>와 <code>hashCode()</code>를 함께 재정의해야 하는 이유</h3>
<p><img src="https://velog.velcdn.com/images/calis_ws/post/a5c0ed9e-8f50-4bf8-8bc3-81e2c922675e/image.png" alt=""></p>
<ol>
<li><p><code>equals()</code> 메서드가 두 객체를 동등하다고 판단한다면, 두 객체의 <code>hashCode()</code> 값은 반드시 같아야 한다. 따라서 <code>equals()</code> 가 true를 반환하는 두 객체는 항상 같은 해시 코드를 가져야 한다.</p>
</li>
<li><p><code>hashCode()</code> 값이 같다고 해서 두 객체가 반드시 동등하다고 판단하는 것은 아니다. 하지만 해시 코드가 다른 두 객체는 반드시 서로 다르다고 판단해야 한다. 이는 해시 기반 컬렉션(HashMap, HashSet)에서 객체를 효율적으로 검색하기 위해 필요한 규칙이다.</p>
</li>
<li><p><code>hashCode()</code> 메서드를 재정의하여 객체의 내용을 기반으로 한 해시 코드를 생성하면, 동일한 내용의 객체는 동일한 해시 코드를 갖게 된다. 이로 인해 해시 기반 컬렉션에서 효율적인 검색 및 삽입이 가능해진다.</p>
</li>
</ol>
<hr>
<h3 id="정리">정리</h3>
<ul>
<li><p><code>equals()</code> 로 같은 객체는 같은 <code>hashCode()</code> 결과가 나와야 한다.</p>
</li>
<li><p><code>hashCode()</code> 로 같은 객체가 항상 <code>equals()</code> 메서드로 같은 객체는 아니다.</p>
</li>
<li><p>이 두 메서드를 함께 재정의하지 않으면 해시 기반 컬렉션을 올바르게 사용할 수 없고, 예상치 못한 동작이 발생할 수 있다. (해시 충돌, 동등성 비교 오류 등)</p>
</li>
</ul>
<h4 id="출처">출처</h4>
<p><a href="https://velog.io/@mooh2jj/equals%EC%99%80-hashCode%EB%8A%94-%EC%96%B8%EC%A0%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%EA%B0%80">https://velog.io/@mooh2jj/equals와-hashCode는-언제-사용하는가</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Interface 의 사용 시점]]></title>
            <link>https://velog.io/@calis_ws/Java-Interface-%EC%9D%98-%EC%82%AC%EC%9A%A9-%EC%8B%9C%EC%A0%90</link>
            <guid>https://velog.io/@calis_ws/Java-Interface-%EC%9D%98-%EC%82%AC%EC%9A%A9-%EC%8B%9C%EC%A0%90</guid>
            <pubDate>Tue, 30 Jan 2024 14:28:29 GMT</pubDate>
            <description><![CDATA[<h2 id="interface">Interface</h2>
<blockquote>
<p>인터페이스(interface)는 자바에서 다중 상속을 지원하지 않는 문제를 해결하고, 코드의 유연성을 높이기 위해 사용된다. </p>
</blockquote>
<p>여러 클래스가 공통된 메서드를 구현하도록 강제함으로써 코드의 일관성을 유지하고, 다형성을 통해 다양한 객체를 통일적으로 다룰 수 있도록 한다.</p>
<p>두 객체간의 &#39;연결, 대화, 소통&#39;을 돕는 &#39;중간 역할&#39;을 한다.
선언(설계)과 구현을 분리시킬 수 있게 한다.</p>
<h3 id="사용-시점">사용 시점</h3>
<h4 id="1-다형성-구현">1. 다형성 구현</h4>
<p>인터페이스는 하나의 객체가 아니라 여러 객체들과 사용이 가능하므로 어떤 객체를 사용하느냐에 따라서 실행 내용과 리턴 값이 다를 수 있다.</p>
<p><a href="https://bbs.ruliweb.com/family/211/board/300075/read/30580378">다형성이란</a></p>
<ul>
<li><p>자바의 상속 구조는 단일 상속의 원칙을 갖기 때문에 하나의 클래스가 여러 부모 클래스를 상속할 수 없다.</p>
</li>
<li><p>서로 다른 부모 클래스를 가지는 클래스간에도 같은 인터페이스를 구현할 수 있다.</p>
</li>
<li><p>같은 인터페이스를 구현하고 있는 클래스간에는 그 인터페이스로 하여금 대표성을 갖게 할 수 있다.</p>
</li>
</ul>
<pre><code class="language-java">public class InterfaceAssist {
    public static void main(String[] args) {
        play(new Soccer());
        play(new BassGuitar());
    }

    public static void play(IBehavior ib) {
        ib.play();
    }
}

public interface IBehavior {
    void play(); // public abstract 생략
}

public class Soccer extends Sport implements IBehavior {
    @Override
    public void play() {
        System.out.println(&quot;Playing Soccer&quot;);
    }
}

public class BassGuitar extends Guitar implements IBehavior {
    @Override
    public void play() {
        System.out.println(&quot;Playing BassGuitar&quot;);
    }
}</code></pre>
<h4 id="2-약한-결합">2. 약한 결합</h4>
<p>약한 결합은 소프트웨어의 요소 간의 의존성을 최소화하고 유연성을 높이는 개념이다. 여러 클래스가 서로 독립적으로 존재하면서도 상호 작용할 수 있는 구조를 지원한다.</p>
<ul>
<li><p>하나의 프로그램의 다수의 클래스들이 서로 관계를 형성하게 되고 각 클래스들은 역할에 따라 구분한다.</p>
</li>
<li><p>클래스들간에 관계를 밀접하게 구성하게 되면 특정 클래스에서 변경이 일어날 경우 많은 클래스들이 영향을 받는다. (Tight Coupling)</p>
</li>
<li><p>따라서, 클래스 간에 관계를 구성할 때 그 관계를 느슨하게 관리하는 것이 중요하다. (Loose Coupling)</p>
</li>
<li><p>클래스와 클래스 사이에 인터페이스를 구성하면 직접적인 접근이 없는 느슨한 관계를 구성할 수 있다.</p>
</li>
</ul>
<pre><code class="language-java">public class Person {
    private Chicken chicken;

    public Person() {
        this.chicken = new Chicken();
    }

    public void startEat() {
        chicken.eat();
    }
}

public class Chicken {
    public void eat() {
        System.out.println(&quot;치킨을 먹습니다.&quot;);
    }
}</code></pre>
<p>강한 결합은 어떠한 객체가 다른 객체에 강한 의존성을 가지고 있음을 뜻한다.</p>
<pre><code class="language-java">public interface Food {
    void eat();
}

public class Chicken implements Food {
    @Override
    public void eat() {
        System.out.println(&quot;치킨을 먹습니다.&quot;);
    }
}

public class Pizza implements Food {
    @Override
    public void eat() {
        System.out.println(&quot;피자를 먹습니다.&quot;);
    }
}

public class Person {
    private Food food;

    public Person(Food food) {
        this.food = food;
    }

    public void startEat() {
        food.eat();
    }
}</code></pre>
<h4 id="3-다중-상속이-필요할-때">3. 다중 상속이 필요할 때</h4>
<p>다중 상속은 한 클래스가 여러 개의 클래스로부터 상속받는 것을 말한다. 자바에서는 클래스에서의 다중 상속이 허용되지 않지만, 인터페이스를 통한 다중 상속은 가능하다.</p>
<ul>
<li><p>여러 인터페이스를 구현함으로써 한 클래스가 다양한 기능을 동시에 제공할 수 있다.</p>
</li>
<li><p>각 인터페이스는 독립적으로 분리된 역할을 수행한다. 이는 코드를 더욱 모듈화하고 유지보수하기 쉽게 만들어준다.</p>
</li>
<li><p>여러 인터페이스의 기능을 재사용하여 새로운 클래스를 작성할 수 있다. 이는 코드의 중복을 피하고 유지보수성을 향상시킨다.</p>
<pre><code class="language-java">interface Swimmable {
  void swim();
}
</code></pre>
</li>
</ul>
<p>interface Flyable {
    void fly();
}</p>
<p>class FlyingFish implements Swimmable, Flyable {
    public void swim() {
        // 구현 내용
    }</p>
<pre><code>public void fly() {
    // 구현 내용
}</code></pre><p>}</p>
<p>```</p>
<h4 id="인터페이스의-장점">인터페이스의 장점</h4>
<ul>
<li><p>두 대상 사이의 &#39;중간&#39; 역할을 해준다. -&gt; 직접 거치지 않고 중간 단계를 거친다. (중개인)</p>
</li>
<li><p>선언과 구현을 분리시킬 수 있다.  -&gt; 변경사항이 있어도 수정 범위가 적다.</p>
</li>
<li><p>개발 시간을 단축할 수 있다. -&gt; 개발시 협업 시스템에서 미완성, 추상메서드(내용없는) 를 통해 = 완성되었다고 가정하고 동시에 개발 가능</p>
</li>
<li><p>변경에 유리한 유연한 설계가 가능하다. -&gt; (선물 상자에 내용물이 바뀌어도 상관없는 것처럼)</p>
</li>
<li><p>클래스들의 관계를 맺어줄 수 있다. (다형성/추상화)</p>
</li>
</ul>
<hr>
<h3 id="출처">출처</h3>
<p><a href="https://velog.io/@damiano1027/Java-%EA%B0%95%ED%95%9C-%EA%B2%B0%ED%95%A9%EA%B3%BC-%EC%95%BD%ED%95%9C-%EA%B2%B0%ED%95%A9">https://velog.io/@damiano1027/Java-강한-결합과-약한-결합</a></p>
<p>자바 기초 강의 - 3-14강 인터페이스의 활용
<a href="https://youtu.be/enD9V74_kRs?si=Mh-L7nUE2IHpQVQo">https://youtu.be/enD9V74_kRs?si=Mh-L7nUE2IHpQVQo</a></p>
<p>[자바의 정석 - 기초편] ch7-38인터페이스와 다형성
<a href="https://youtu.be/EnBLkMYt1XQ?si=y4VWBb5yTW4KMsjn">https://youtu.be/EnBLkMYt1XQ?si=y4VWBb5yTW4KMsjn</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바에서 final 이란?]]></title>
            <link>https://velog.io/@calis_ws/%EC%9E%90%EB%B0%94%EC%97%90%EC%84%9C-final-%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@calis_ws/%EC%9E%90%EB%B0%94%EC%97%90%EC%84%9C-final-%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Mon, 29 Jan 2024 16:45:36 GMT</pubDate>
            <description><![CDATA[<h2 id="final">Final</h2>
<blockquote>
<p>자바 언어에서 final은 오직 한 번만 할당할 수 있는 entity 를 정의할 때 사용된다. </p>
</blockquote>
<p>final 로 선언된 변수가 할당되면 항상 같은 값을 가진다. 만약 final 변수가 객체를 참조하고 있다면, 그 객체의 상태가 바뀌어도 final 변수는 매번 동일한 내용을 참조한다.</p>
<p>final 키워드는 클래스, 필드, 메소드, 지역변수, 파라미터에 적용할 수 있다.</p>
<ul>
<li><p>클래스에 final 은 상속을 허용하지 않는다.</p>
</li>
<li><p>메소드의 final 은 오버라이딩을 허용하지 않는다.</p>
</li>
<li><p>필드, 지역변수, 파라미터에 final을 적용하면 한번 초기화 한 이후에는 다른 값으로 변경할 수 없다.</p>
</li>
</ul>
<h4 id="final-변수">Final 변수</h4>
<p>final 필드의 초기화 방식은 필드 선언 시점의 초기화, 초기화 블록, 생성자를 통한 초기화 방법 3가지가 있다.</p>
<pre><code class="language-java">public class FinalExam {
    private final String message = &quot;Final Message&quot;; // (1)

    private final String message;
    {
        message = &quot;Final Message&quot;; // (2)
    }

    public FinalExam(String message) {
        this.message = message; // (3)
    }

    public final void showMessage() {
        System.out.println(message);
    }

    // final 로 선언된 인자값
    public void showMessage(final String message) {
        // message = &quot;New Message!&quot;;
        // Cannot assign a value to final variable &#39;message&#39;
        System.out.println(message);
    }
}</code></pre>
<h4 id="final-메소드">final 메소드</h4>
<p>메소드를 final 로 선언하면 상속받은 클래스에서 오버라이딩이 불가능하다. Dog 객체는 Pet 의 <code>makeSound()</code> 메소드를 재정의할 수 없다.</p>
<pre><code class="language-java">public class Pet {
    public final void makeSound() {
        System.out.println(&quot;ahaha&quot;);
    }
}

public class Dog extends Pet {
    // final로 된 메소드는 override 할 수 없음
     public void makeSound() { 

     }
}</code></pre>
<h4 id="final-클래스">final 클래스</h4>
<p>클래스에 final 을 선언하면 상속 자체가 불가능하다. 그냥 클래스 그대로 사용해야 한다.</p>
<pre><code class="language-java">public final class FinalClass {
    ...
}

// final 클래스로 선언되어 상속할 수 없음
public class OtherClass extends FinalClass {
    ...
}</code></pre>
<pre><code>자바에서 기본적으로 제공하는 라이브러리 클래스는 final 을 사용함
java.lang.System, java.lang.String ...</code></pre><hr>
<h3 id="정리">정리</h3>
<p>final 은 최종이라는 의미. 
변수, 메소드, 클래스 각각 어디에 붙냐에 따라 다르지만 개념은 같다.</p>
<p>불변성, 상수값 유지, 상속과 오버라이딩의 방지 등 이러한 특성들은 소프트웨어 개발에서 버그를 줄이고 코드를 유지보수하기 쉽게 만들어준다. </p>
<p>따라서 final 키워드는 코드의 안정성과 예측 가능성을 높이기 위한 강력한 도구로 사용된다.</p>
]]></description>
        </item>
    </channel>
</rss>