<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>b-joon.log</title>
        <link>https://velog.io/</link>
        <description>성장을 즐기는 백엔드 자바 개발자</description>
        <lastBuildDate>Thu, 22 Feb 2024 07:37:19 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>b-joon.log</title>
            <url>https://velog.velcdn.com/images/b-joon/profile/3a756cdd-e8ff-4f98-a50c-6a25c9f84d9c/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. b-joon.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/b-joon" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[JDK & JRE]]></title>
            <link>https://velog.io/@b-joon/JDK-JRE</link>
            <guid>https://velog.io/@b-joon/JDK-JRE</guid>
            <pubDate>Thu, 22 Feb 2024 07:37:19 GMT</pubDate>
            <description><![CDATA[<p>지금까지 자바를 사용해 개발을 하면서 &#39;나는 자바 개발자가 맞는가? 자바 개발자가 맞다면 자바에 대해서 어느정도 알고 있는가?&#39;하는 생각이 들었다. 생각해보니 많은 부분을 모르고 있었다. 그래서 기본부터 다시 공부하면서 정리해보려고 한다.</p>
<h1 id="jdk-java-development-kit">JDK (Java Development Kit)</h1>
<p>JDK는 자바 개발자들이 Java로 개발할 때 사용되는 키트이다. JDK 안에는 자바를 개발 시 필요한 라이브러리들과 javac, javadoc 등의 개발 도구들이 포함되고 JRE도 같이 포함되어 있다.</p>
<blockquote>
<p>종류</p>
</blockquote>
<ul>
<li>Oracle JDK : Oracle에서 제공하는 JDK로 상업적으로 사용하려면 구독을 통해 유료 라이센스를 구매해야한다.</li>
<li>Open JDK : 무료 JDK이지만 직접 사용하는것 보다는 Open JDK 기반으로 빌드된 JDK 사용을 추천한다.</li>
<li>Azul Zulu : Mac 등에서 사용할 수 있는 바이너리를 제공하는 JDK이다.</li>
<li>Amazon Corretto : AWS에서 제공하는 JDK이다</li>
</ul>
<h3 id="jdk-파일-구조">JDK 파일 구조</h3>
<p>Java 디렉토리에는 다양한 파일들로 구성되어 있다.</p>
<h5 id="디렉토리-구성요소">디렉토리 구성요소</h5>
<p><img src="https://velog.velcdn.com/images/b-joon/post/0e489296-208b-4759-a2c5-a5b436aeec4d/image.png" alt=""></p>
<ul>
<li>bin : 프로그램 작동에 필요한 파일, 프로그램 개발에 필요한 모든 툴과 유틸리티가 포함되어 있다.</li>
<li>conf : 사용자 구성 옵션을 포함하고 있고, JDK 접근 권한 설정, 보안 알고리즘 변경, 자바 암호화 확장 정책 등을 설정할 수 있다.</li>
<li>include : 자바 가상머신 디버거인터페이스, 네이티브인터페이스의 네이티브 코드 작성하는데 사용되는 C헤더 파일이 있다.</li>
<li>jmods : jlink를 사용하여 사용자 지정 런타임을 만드는데 사용되는 모듈이 있다.</li>
<li>legal : 각 모듈에 대한 라이선스와 저작권에 대한 내용이 있다.</li>
<li>lib : JDK에 필요한 추가 클래스 라이브러리와 지원 파일이 있다.</li>
</ul>
<h5 id="개발-프로그램">개발 프로그램</h5>
<p><img src="https://velog.velcdn.com/images/b-joon/post/8c2b4a71-dc1b-4b9b-957c-709849b63d28/image.png" alt=""></p>
<ul>
<li>jar : 자바 클래스 파일을 압축한 자바 아카이브 파일을 생성(.jar), 관리한다.</li>
<li>java : 컴파일러가 생성한 바이트 코드를 실행한다. (인터프리터)</li>
<li>javac : 자바 컴파일러로 자바 소스를 바이트 코드로 변환한다.</li>
<li>javadoc : 자바 소스 주석으로부터 HTML 형식의 API 도큐먼트를 생성한다.</li>
<li>javap : 컴파일된 코드를 원래 코드로 되돌린다. (역어셈블러)</li>
<li>jlink : 응용 프로그램에 맞춘 맞춤형 JRE를 생성한다</li>
<li>jmod : 자바의 모듈 파일(.jmd)를 만들거나 모듈 파일의 내용을 출력한다.</li>
</ul>
<h3 id="jdk-버전">JDK 버전</h3>
<p>자바는 처음에 JDK 1.0a를 시작으로 다양한 기능들이 추가되면서 JDK 1.2버전에서는 약칭이 J2SE(Java2 Standard Edition)로 표기되기 시작했고 J2SE 6버전에서는 Java SE(Java Standard Edition)로 명칭이 바뀌었다.</p>
<p>Oracle 사이트에 접속해보면 다운 받을 수 있는 버전은 JDK1.4.2 ~ Java SE 21 버전까지 다운 받을 수 있다.</p>
<blockquote>
</blockquote>
<p>표기법 <br>
<strong>Java SE 21.0.2(LTS)</strong></p>
<ul>
<li>21 : 주요 버전</li>
<li>0 : 개선 버전</li>
<li>2 : 업데이트 버전</li>
<li>LTS : Long Term Support 장기 지원 하는 버전</li>
</ul>
<h5 id="java-edition">Java Edition</h5>
<ul>
<li>Java SE (Java Standard Edition) : 추상 Java 플랫폼을 기술하는 스펙으로 가장 기본이 되는 표준 에디션의 자바 플랫폼으로 자바 언어의 핵심 기능을 제공한다.<ul>
<li>가장 기본적인 클래스 패키지로 구성된다.</li>
<li>PC용 애플리케이션, 애플릿개발, 응용프로그램 개발, 웹 개발, 안드로이드 개발이 가능하다.</li>
<li>PC에 설치하여 사용할 수 있는 모든 프로그램 개발에 관련된 것들이 있다.</li>
</ul>
</li>
<li>Java EE (Java Enterprise Edition) : 대규모 기업용 에디션으로 Java SE 스펙을 기반으로 한다.<ul>
<li>Java SE를 줄여 라이트하게 만든 것으로 SE개발을 할 줄 알면 ME기반의 개발도 가능하다.</li>
<li>각각의 OS를 가지고 있는 스마트폰이 대중화된 지금은 잘 사용하지 않는다.</li>
</ul>
</li>
<li>Java ME (Java Micro Edition) : 작은 임베디드 기기들 같은 작은 기기들을 다루는데 이용하는 에디션이다.<ul>
<li>Java SE를 줄여 라이트 하게 만든 것으로 SE를 활용할 줄 알면 ME개발도 가능하다.</li>
<li>지금은 각각의 OS를 가지고 있어서 사용하지 않는다.</li>
</ul>
</li>
<li>Java FX : UI 애플리케이션을 개발할 수 있도록 가볍고 풍부한 UI를 제공하는 에디션이다.<ul>
<li>고성능의 하드웨어 그래픽 가속과 미디어 엔진 API를 제공해주어 프로그램의 성능에 신경을 써야 하는 분야에서 사용한다.</li>
</ul>
</li>
</ul>
<h1 id="jre-java-runtime-environment">JRE (Java Runtime Environment)</h1>
<p>JVM과 자바 프로그램을 실행시킬 때 필요한 라이브러리 API를 함께 묶어서 배포되는 패키지 이다. 컴퓨터 운영체제 소프트웨어 상에서 실행되고 클래스 라이브러리 및 특정 Java 프로그램이 실행해야 하는 기타 리소스를 제공하는 소프트웨어 계층이다.</p>
<p>개별적으로 설치가 가능했지만 JDK 11 버전부터는 따로 제공되지 않는다.</p>
<blockquote>
<p>런타임 아키텍처</p>
</blockquote>
<ul>
<li>클래스로더 : Java 프로그램의 실행에 필요한 모든 클래스를 동적으로 로드한다.</li>
<li>바이트코드 검증기 : 인터프리터에 전달되기 전에 Java 코드의 형식과 정확성을 보장</li>
<li>인터프리터 : Java 프로그램이 기본 시스템에서 기본적으로 실행될 수 있도록 해주는 JVM의 인스턴스를 작성한다.</li>
</ul>
<hr>
출처

<p><a href="https://namu.wiki/w/Java">나무위키 - Java/버전</a>
<a href="https://ko.wikipedia.org/wiki/%EC%9E%90%EB%B0%94_%EA%B0%9C%EB%B0%9C_%ED%82%A4%ED%8A%B8">위키백과 - 자바 개발 키트</a>
<a href="https://www.ibm.com/kr-ko/topics/jre">IBM - JRE</a>
<a href="https://inpa.tistory.com/entry/JAVA-%E2%98%95-JDK-JRE-JVM-%EA%B0%9C%EB%85%90-%EA%B5%AC%EC%84%B1-%EC%9B%90%EB%A6%AC-%F0%9F%92%AF-%EC%99%84%EB%B2%BD-%EC%B4%9D%EC%A0%95%EB%A6%AC#">https://inpa.tistory.com/entry/JAVA-%E2%98%95-JDK-JRE-JVM-%EA%B0%9C%EB%85%90-%EA%B5%AC%EC%84%B1-%EC%9B%90%EB%A6%AC-%F0%9F%92%AF-%EC%99%84%EB%B2%BD-%EC%B4%9D%EC%A0%95%EB%A6%AC#</a>
<a href="https://coding-factory.tistory.com/826">https://coding-factory.tistory.com/826</a>
<a href="https://hajoung56.tistory.com/35">https://hajoung56.tistory.com/35</a>
<a href="https://themach.tistory.com/88">https://themach.tistory.com/88</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[IntelliJ 에서 Spring MVC 프로젝트 생성]]></title>
            <link>https://velog.io/@b-joon/IntelliJ-%EC%97%90%EC%84%9C-Spring-MVC-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%83%9D%EC%84%B1</link>
            <guid>https://velog.io/@b-joon/IntelliJ-%EC%97%90%EC%84%9C-Spring-MVC-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%83%9D%EC%84%B1</guid>
            <pubDate>Tue, 20 Feb 2024 09:26:43 GMT</pubDate>
            <description><![CDATA[<p>Spring Framework를 공부하다보니 Spring MVC 프로젝트를 만들게 됐다.
이론만 공부하지 않고 프로젝트 세팅부터 간단한 게시글까지 만들어 보기 위해 프로젝트를 생성해 보았는데 조금 복잡한 부분이 있어서 생성 방법을 잊더라도 빠르게 확인 할 수 있게 남겨보려고 한다.</p>
<h3 id="intellij-version">IntelliJ Version</h3>
<p><Strong>IntelliJ IDEA 2021.3.3 (Ultimate Edition)</Strong></p>
<h4 id="1-maven-project-created">1 Maven Project Created</h4>
<ol>
<li>file -&gt; new -&gt; project</li>
<li>Maven 선택</li>
<li>Create from archetype 선택하지 않고 Next
(Java 21 버전을 생성하려 했으나 pom.xml이 공백으로 생성되어 17버전으로 선택)</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/9d0baf12-dcd5-4bac-be80-5cce11799c2d/image.png" alt=""></p>
<h4 id="2-project-name">2 Project name</h4>
<ol>
<li>Name 작성</li>
<li>GroupId 작성 권장<ul>
<li>GroupId : 최상위 패키지명 (ex. com.aaa)</li>
</ul>
</li>
<li>ArtifactId -&gt; 1.name 과 동일 프로젝트 명</li>
<li>Version<ul>
<li>개발 버전 : SNAPSHOT</li>
<li>배포 버전 : RELEASE</li>
</ul>
</li>
<li>Finish</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/2e0fd16d-3bd6-480a-b16f-ddc9f7ea2d06/image.png" alt=""></p>
<h4 id="3-add-framework">3 Add Framework</h4>
<ol>
<li>Project 우클릭</li>
<li>Add Framework Support 클릭</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/d36bbf52-4123-4311-a1ef-67916436bc9c/image.png" alt=""></p>
<h4 id="4-spring-framework-download">4 Spring Framework download</h4>
<ol>
<li>Spring mvc 선택</li>
<li>따로 library가 없으므로 Download</li>
<li>OK 클릭</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/0532280e-6280-4e2c-b25a-21ec6e6ed1db/image.png" alt=""></p>
<h4 id="5-사용하지-않는-lib-파일-삭제">5 사용하지 않는 lib 파일 삭제</h4>
<ol>
<li>IntelliJ의 lib를 사용하지 않고 pom.xml에 의존성을 추가하여 사용할 것이기 때문에 lib삭제</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/0e5d8fa0-ad00-4401-93a3-1c77bfd1717c/image.png" alt=""></p>
<h4 id="6-pomxml-dependency-추가">6 pom.xml dependency 추가</h4>
<ol>
<li>pom.xml에 <code>&lt;dependencies&gt;&lt;/dependencies&gt;</code>를 추가</li>
<li><code>&lt;dependencies&gt;&lt;/dependencies&gt;</code> 안에서 우클릭 후 Generate 클릭</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/2789f3b2-96cb-41ff-8399-1f4bbcd1423b/image.png" alt=""></p>
<ol start="3">
<li>Dependency 클릭</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/46e2c457-ffc8-4ceb-996f-1d6fdfca5553/image.png" alt=""></p>
<ol start="4">
<li>search for artifact의 검색창에 &quot;org.spring&quot; 검색</li>
<li>spring-webmvc 확장</li>
<li>Add Framework Support했을 때 Spring MVC 버전과 맞는 버전 선택 후 Add 클릭<ul>
<li>저는 5.2.3.RELEASE 버전으로 Support 받아서 해당 버전으로 선택</li>
</ul>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/da990669-3e37-47da-abec-01bb5073240a/image.png" alt=""></p>
<ol start="7">
<li>2~4까지 동일 검색창에 &quot;javax.servlet&quot; 검색</li>
<li>javax.servlet-api 선택 후 Add 클릭</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/06d16f4d-f8cd-48bb-9e0e-f1ae6086fc73/image.png" alt=""></p>
<ol start="9">
<li>위 그림에서 우측 상단 Maven 버튼 클릭</li>
</ol>
<h4 id="7-project-구조-변경">7 Project 구조 변경</h4>
<ol>
<li>web 폴더를 src/main 으로 이동</li>
<li>web을 webapp 으로 변경</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/a1bce59b-7bb5-4b9c-bd32-5b02d0df014a/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/b-joon/post/e6cfa525-27a3-4217-9d99-fdd3cb30233f/image.png" alt=""></p>
<p>3.Project 우클릭 Open Module Settings 클릭</p>
<p><img src="https://velog.velcdn.com/images/b-joon/post/c137c195-4a7e-4eac-8875-b30d9bccacb8/image.png" alt=""></p>
<ol start="4">
<li>Modules클릭 -&gt; Web클릭</li>
<li>Web Resource Directories 경로 변경<ul>
<li>project/web -&gt; 위 2번 webapp 경로로</li>
</ul>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/f88d4783-d7ee-4fe3-8a42-2c15f864ca87/image.png" alt=""></p>
<ol start="6">
<li>Artifacts에서 오른쪽 Available Elements에 springmvc 폴더에 있는 내용 전부를 선택 후 우클릭 해서 Put info /WEB-INF/lib 클릭</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/e22b6130-8c0b-49a4-bbcd-9bafdf595f35/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/b-joon/post/5703fbe4-a01e-4f90-b6e4-63375f3626a8/image.png" alt=""></p>
<h4 id="8-tomcat-연동">8 Tomcat 연동</h4>
<ol>
<li>우측 상단 Add Configuration 클릭</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/c4bb2ad2-52c4-4efd-b228-899e64e3a07d/image.png" alt=""></p>
<ol start="2">
<li>좌측 상단 + 클릭하여 톰캣 추가</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/e3c9625a-09d3-4b30-a9b8-77bddf735055/image.png" alt=""></p>
<ol start="3">
<li>우측 Configure 클릭</li>
<li>Tomcat Home 경로 지정 후 OK클릭<ul>
<li>본인이 설치한 톰켓 지정</li>
</ul>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/06c605ba-cb4c-44f0-88e6-bc8a0fb431a8/image.png" alt=""></p>
<ol start="5">
<li>Deployment클릭 후 + 클릭</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/1b0e1feb-6e57-4aea-97bd-f33efd5091b0/image.png" alt=""></p>
<ol start="6">
<li>Artifact 추가</li>
<li>Application context : /springmvc_war_exploded -&gt; / 변경 후 OK 클릭</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/e6c2cdc8-47c0-4b93-9f95-b4958889e5c8/image.png" alt=""></p>
<ol start="8">
<li>Tomcat을 실행하면 정상 동작하는 것을 볼 수 있다.</li>
</ol>
<p><img src="https://velog.velcdn.com/images/b-joon/post/9cbb616c-5879-45d3-9380-4b2bb55d3c68/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/b-joon/post/9885ac90-280c-4ebd-abb5-d4631c20f11b/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring은 어떻게 동작 하는가?]]></title>
            <link>https://velog.io/@b-joon/Spring%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8F%99%EC%9E%91-%ED%95%98%EB%8A%94%EA%B0%80</link>
            <guid>https://velog.io/@b-joon/Spring%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8F%99%EC%9E%91-%ED%95%98%EB%8A%94%EA%B0%80</guid>
            <pubDate>Tue, 20 Feb 2024 07:37:33 GMT</pubDate>
            <description><![CDATA[<p>지금까지 개발을 하면서 스프링에 대하여 잘 모르고 개발을 했었다. 그래서 스프링이 어떻게 동작하는지 이해하기 쉽게 정리하며 공부해보려고 한다. 그럼 Spring MVC 의 동작 구조, 실행 순서는 어떻게 되는지 알아보자</p>
<h1 id="spring-web-mvc">Spring Web MVC</h1>
<p>Spring Web MVC는 Servlet API를 기반으로 구축된 독창적인 웹 프레임워크이며 처음부터 Spring Framework에 포함되었다. 정식 이름인 Spring Web MVC는 소스 모듈 Spring-webmvc 에서 유래되었지만 일반적으로 Spring MVC로 알려져 있다. </p>
<p>Model, View, Controller 구성요소를 사용하여 사용자의 다양한 HTTP Request를 처리하고 단순한 텍스트 형식의 응답부터 REST 형식의 응담은 물론 View를 표시하는 HTML을 return하는 응답까지 다양한 요청, 응답을 할 수 있는 웹 프레임워크이다.</p>
<h2 id="mvc-패턴">MVC 패턴</h2>
<p>Spring Web MVC를 알기전 MVC 패턴에 대해 알고 있어야 한다. MVC 패턴은 웹 애플리케이션을 개발할 때 사용하는 디자인 패턴이다. 개발 영역을 Model-View-Controller로 구분해서 각 역할에 맞게 코드를 작성하는 개발 방식으로 사용자 인터페이스로부터 비즈니스 로직을 분리하여 서로에게 영향을 주지 않아 유연하고 확장성 있게 웹 애플리케이션을 만들 수 있다.</p>
<h4 id="model">Model</h4>
<p>애플리케이션의 정보, 데이터의 가공을 책임지고 데이터베이스와 상호작용하여 비즈니스 로직을 처리하는 모듈이다. 클라이언트의 요청 사항을 처리하는 영역을 서비스 계층, Java 코드로 구현한 것을 비즈니스 로직이라 한다.</p>
<h5 id="규칙">규칙</h5>
<ul>
<li>사용자가 이용하려는 모든 데이터를 가지고 있어야 한다.</li>
<li>View 또는 Controller에 대해 어떤 정보도 알 수 없어야 한다.</li>
<li>변경이 일어났을 때 처리 방법을 구현해야 한다.</li>
<li>모델은 재사용이 가능해야 하며 다른 인터페이스에도 변하지 않아야 한다.</li>
</ul>
<h4 id="view">View</h4>
<p>컨트롤러로부터 전달받은 Model을 클라이언트에게 시각적으로 보여주는 역할. 즉, 사용자 인터페이스 요소를 말한다.</p>
<h5 id="규칙-1">규칙</h5>
<ul>
<li>Model이 가지고 있는 데이터를 저장하면 안된다.</li>
<li>Model이나 Controller에 대한 정보를 알면 안된다.</li>
<li>데이터를 받아 단순히 화면에 표현하는 역할만 한다.</li>
<li>재사용이 가능하게끔 설계를 해야 하며 다른 정보들을 표현할 때 쉽게 설계해야 한다.</li>
</ul>
<h4 id="controller">Controller</h4>
<p>클라이언트로측의 요청을 직접적으러 전달받는 엔드포인트로 Model과 View의 상호작용을 해주는 역할을 한다. 클라이언트로부터 요청이 들어왔을 때 어떤 로직을 실행시킬 것인지 Model과 View를 연결해주며 제어하는 모듈이다.</p>
<h5 id="규칙-2">규칙</h5>
<ul>
<li>Model 또는 View에 대한 정보를 알아야 한다.</li>
<li>Model 또는 View의 변경을 인지하여 대처해야한다.</li>
<li>Model이나 View의 변경을 통지 받으면 이를 해성해서 각각의 구성 요소에게 통지해야 한다.</li>
<li>애플리케이션의 메인 로직을 담당한다.</li>
</ul>
<h3 id="mvc1--mvc2">MVC1 &amp; MVC2</h3>
<p>MVC는 MVC1, MVC2 두가지로 나눌 수 있다. 둘의 차이점은 클라이언트의 요청 사항을 모듈화 하지 않고 하나의 파일로 처리할 것인가, 각각의 기능을 담당하는 모듈을이 역할을 분담하여 처리할 것인가로 정해진다.</p>
<h4 id="mvc1">MVC1</h4>
<p><img src="https://velog.velcdn.com/images/b-joon/post/bee24082-cdb6-4bfc-9e89-3f35ba6be53f/image.png" alt="">
MVC1 패턴은 JSP가 Controller와 View의 기능을 동시에 담당하여 JSP 페이지에서 비즈니스 로직을 처리하기 위한 코드와 웹 브라우저에 결과를 보여주기 코드가 같이 작성되는 구조이다.</p>
<p>JSP가 두 가지 역할을 담당하기 때문에 너무 많은 코드가 들어가서 가독성이 떨어지고 복잡해질 가능성이 생긴다.</p>
<h4 id="mvc2">MVC2</h4>
<p><img src="https://velog.velcdn.com/images/b-joon/post/180e2a6f-cf59-4636-8366-c7dd4c2f0563/image.png" alt="">
MVC2 패턴은 MVC1 패턴의 단점을 보안하기 위해 나왔다. Controller와 View의 역할을 모두 JSP가 수행했지만 MVC2에서는 JSP가 View의 역할만 수행하고 Controller 역할은 Servlet이 수행하게 된다. 클라이언트의 요청을 Servlet이 받아서 비즈니스 로직을 수행하고 View 역할을 하는 JSP에 전달하여 시각화 한다.</p>
<h1 id="spring-web-mvc의-동작-원리">Spring Web MVC의 동작 원리</h1>
<p>MVC 패턴을 알아보았으니 이제는 Spring의 역할과 동작 순서를 알아보도록 하자.
<img src="https://velog.velcdn.com/images/b-joon/post/d04847c1-c7fe-4e8b-b354-0bba54b0a7d7/image.png" alt="">
Spring framework의 동작 원리는 MVC2의 구조를 기반으로 한다.</p>
<h3 id="구성-요소">구성 요소</h3>
<h4 id="dispatcherservlet">DispatcherServlet</h4>
<p>클라이언트로부터 애플리케이션으로 들어오는 모든 HTTP 요청을 받아들여 직접적으로 요청을 처리하지 않고 다른 구성요소에게 요청을 위임하는 역할을 한다.</p>
<h4 id="handlermapping">HandlerMapping</h4>
<p>클라이언트의 HTTP 요청을 바탕으로 어떤 Controller의 메소드를 실행할지 탐색하는 역할을 한다.</p>
<h4 id="handleradapter">HandlerAdapter</h4>
<p>Mapping된 Controller의 정보를 토대로 메소드를 호출하는 역할을 한다.</p>
<h4 id="controller-1">Controller</h4>
<p>호출된 정보를 토대로 비즈니스 로직을 실행 후 처리 결과와 View에 관한 정보(View name)를 return 하는 역할을 한다.</p>
<h4 id="viewresolver">ViewResolver</h4>
<p>View name을 확인 후 Controller로부터 받은 결과를 전달할 View 파일을 탐색하는 역할을 한다.</p>
<h4 id="view-1">View</h4>
<p>Controller에서 전달받은 결과를 반영한 화면을 생성하여 클라이언트에게 보여주는 역할을 한다.</p>
<h3 id="실행-순서">실행 순서</h3>
<ol>
<li>클라이언트로부터 HTTP Request가 들어오면 URL이 <code style="font-weight: bold;">DispatcherServlet</code> 클래스에게 전달된다.</li>
<li><code style="font-weight: bold;">DispatcherServlet</code>은 클라이언트로부터 전달받은 URL을 <code style="font-weight: bold;">HandlerMapping</code> 클래스에게 전달한다.</li>
<li><code style="font-weight: bold;">HandlerMapping</code>은 URL을 가지고 클라이언트의 요청을 처리할 Controller를 찾아서 <code style="font-weight: bold;">DispatcherServlet</code> 클래스에게 반환한다.<ul>
<li>Controller의 Method 정보도 같이 반환</li>
</ul>
</li>
<li>Controller 정보를 전달받은 <code style="font-weight: bold;">DispatcherServlet</code>은 <code style="font-weight: bold;">HandlerAdapter</code> 클래스에게 Controller 정보를 전달한다.</li>
<li><code style="font-weight: bold;">HandlerAdapter</code>는 전달받은 정보를 가지고 Controller의 Method를 호출한다.</li>
<li><code style="font-weight: bold;">Controller</code>의 Method는 비즈니스 로직을 실행 후 반환받은 Model 데이터와 View name을 <code style="font-weight: bold;">HandlerAdapter</code> 클래스에게 반환한다.</li>
<li><code style="font-weight: bold;">HandlerAdapter</code>는 Controller에게 받은 Model 데이터와 View name을 <code style="font-weight: bold;">DispatcherServlcet</code> 클래스에게 반환한다.</li>
<li><code style="font-weight: bold;">DispatchetServlcet</code>은 반환받은 View name을 <code style="font-weight: bold;">ViewResolver</code> 클래스에게 전달한다.</li>
<li><code style="font-weight: bold;">ViewResolver</code>는 View name에 맞는 View를 찾아 <code style="font-weight: bold;">DispatcherServlet</code>에게 전달한다.</li>
<li><code style="font-weight: bold;">DispatcherSevlcet</code>은 <code style="font-weight: bold;">View</code>에게 Model 데이터를 전달하고 최종 결과를 클라이언트에게 노출할 수 있도록 요청한다.</li>
<li><code style="font-weight: bold;">View</code>는 Model 데이터를 가지고 화면에 표시하여 클라이언트에게 응답한다.</li>
</ol>
<hr>
출처

<p><a href="https://docs.spring.io/spring-framework/reference/web/webmvc.html">Spring Docs</a>
<a href="https://developer.mozilla.org/ko/docs/Glossary/MVC">MDN Web Docs</a>
<a href="https://ko.wikipedia.org/wiki/%EB%AA%A8%EB%8D%B8-%EB%B7%B0-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC">위키백과</a>
<a href="https://ss-o.tistory.com/160">https://ss-o.tistory.com/160</a>
<a href="https://ittrue.tistory.com/234">https://ittrue.tistory.com/234</a>
<a href="https://kotlinworld.com/326">https://kotlinworld.com/326</a>
<a href="https://kchs94.tistory.com/201">https://kchs94.tistory.com/201</a>
<a href="http://www.techblue.co.kr/?page_id=5464">http://www.techblue.co.kr/?page_id=5464</a>
<a href="https://velog.io/@wnsdnjs70/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EC%9D%98-%EC%A0%95%EC%9D%98%ED%8A%B9%EC%A7%95%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC">https://velog.io/@wnsdnjs70/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EC%9D%98-%EC%A0%95%EC%9D%98%ED%8A%B9%EC%A7%95%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC</a>
<a href="https://starkying.tistory.com/entry/Spring-MVC-%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC-%EA%B5%AC%EC%84%B1%EC%9A%94%EC%86%8C">https://starkying.tistory.com/entry/Spring-MVC-%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC-%EA%B5%AC%EC%84%B1%EC%9A%94%EC%86%8C</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Java 레코드(record)]]></title>
            <link>https://velog.io/@b-joon/Java-Java-%EB%A0%88%EC%BD%94%EB%93%9Crecord</link>
            <guid>https://velog.io/@b-joon/Java-Java-%EB%A0%88%EC%BD%94%EB%93%9Crecord</guid>
            <pubDate>Mon, 12 Feb 2024 05:09:16 GMT</pubDate>
            <description><![CDATA[<h1 id="record">Record</h1>
<p>record는 불변 데이터를 객체 간에 전달하는 작업을 간단하게 만든다. Java 14부터 도입되어 16 버전에서 정식으로 채택된 클래스이다. record Type을 사용하면 불필요한 코드를 제거할 수 있고, 적은 코드로도 명확한 의도를 표현할 수 있다.</p>
<h3 id="특징">특징</h3>
<ul>
<li>맴버변수는 private final로 선언된다.</li>
<li>equals, hashCode, toString, getter를 자동으로 생성한다.</li>
<li>다른 클래스로 상속 받을 수 없지만 인터페이스로 구현이 가능하다.</li>
<li>불변 객체로 abstract로 선언할 수 없으며 암시적으로 final로 선언된다.</li>
<li>모든 필드를 매개변수로 사용하는 생성자를 자동으로 생성한다.</li>
</ul>
<h2 id="코드예제">코드예제</h2>
<h4 id="dto">DTO</h4>
<pre><code class="language-java">public class UserDto {
    private String userName;
    private String userPhoneNumber;

    public UserDto(String userName, String userPhoneNumber) {
        this.userName = userName;
        this.userPhoneNumber = userPhoneNumber;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPhoneNumber() {
        return userPhoneNumber;
    }

    public void setUserPhoneNumber(String userPhoneNumber) {
        this.userPhoneNumber = userPhoneNumber;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserDto userDto = (UserDto) o;
        return Objects.equals(userName, userDto.userName) &amp;&amp; 
                Objects.equals(userPhoneNumber, userDto.userPhoneNumber);
    }

    @Override
    public int hashCode() {
        return Objects.hash(userName, userPhoneNumber);
    }

    @Override
    public String toString() {
        return &quot;UserDto{&quot; +
                &quot;userName=&#39;&quot; + userName + &#39;\&#39;&#39; +
                &quot;, userPhoneNumber=&#39;&quot; + userPhoneNumber + &#39;\&#39;&#39; +
                &#39;}&#39;;
    }
}</code></pre>
<p>유저 정보를 가지는 Dto 입니다. 이름과 전화번호만 사용하는데 보일러 플레이트 코드가 많은 것을 볼 수 있다.</p>
<blockquote>
<p>보일러 플레이트 코드
최소한의 변경으로 여러 곳에서 재사용 되면 반복적으로 비슷한 형태를 가지고 있는 코드
(getter, setter, equals, hashCode,toString</p>
</blockquote>
<h5 id="record-1">record</h5>
<pre><code class="language-java">public record UserRecordDto(String userName, String userPhoneNumber) { }</code></pre>
<p>UserDto 코드와 비교하면 많은 것들이 사라진 것을 볼 수 있다.
Record의 구조는 <code>recorde (header) {body}</code>의 구조로 되어있다. 컴파일러는 헤더를 통해 String type의 userName, userPhoneNumber 이 있다는 것을 인식 후 코드에 명시적으로 접근제어자, constructor, getter, hashCode, toString, equals의 구현을 자동으로 제공한다.</p>
<h5 id="dto-test">DTO Test</h5>
<pre><code class="language-java">public class DtoTest {

    public static void main(String[] args) {
        UserDto userDto = new UserDto();
        userDto.setUserName(&quot;aaaa&quot;);
        userDto.setUserPhoneNumber(&quot;00000000&quot;);

        System.out.println(
                userDto.getUserName() + userDto.getUserPhoneNumber()
        );

        UserRecordDto userRecordDto = new UserRecordDto(&quot;bbbb&quot;, &quot;1111111&quot;);

        System.out.println(
                userRecordDto.userName() + userRecordDto.userPhoneNumber()
        );

    }
}</code></pre>
<p>또한 record를 사용하게 되면 <code>getUserName(), getUserPhoneNumber()</code> 을 사용하는 것이 아닌 <code>userName(), userPhoneNumber()</code> 만 사용하는 것을 볼 수 있다.</p>
<p>FastCampus 강의를 보다가 강의 내용에 record를 사용하는 것을 보고 실무에서 Java 16 버전 이상을 사용한다면 적용해보고 싶어서 간략하게 정리를 해봤습니다.</p>
<hr>
출처

<p><a href="https://docs.oracle.com/en/java/javase/14/language/records.html#GUID-6699E26F-4A9B-4393-A08B-1E47D4B2D263">Oracle Java Record</a>
<a href="https://openjdk.org/jeps/395">openjdk</a>
<a href="https://s7won.tistory.com/2">https://s7won.tistory.com/2</a>
<a href="https://coding-start.tistory.com/355">https://coding-start.tistory.com/355</a>
<a href="https://devhooney.tistory.com/203">https://devhooney.tistory.com/203</a>
<a href="https://velog.io/@power0080/java%EC%9E%90%EB%B0%94-record%EB%A5%BC-entity%EB%A1%9C">https://velog.io/@power0080/java%EC%9E%90%EB%B0%94-record%EB%A5%BC-entity%EB%A1%9C</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[디자인 패턴 (Design Pattern)]]></title>
            <link>https://velog.io/@b-joon/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-Design-Pattern</link>
            <guid>https://velog.io/@b-joon/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-Design-Pattern</guid>
            <pubDate>Wed, 17 Jan 2024 08:49:25 GMT</pubDate>
            <description><![CDATA[<style>
.organize {
    color: #98fb98;
}
</style>

<h1 id="디자인-패턴이란">디자인 패턴이란?</h1>
<p>소프트웨어 디자인 과정에서 자주 발생하는 문제들에 대한 전형적인 해결책이다. 이는 코드에서 반복되는 디자인 문제들을 해결하기 위해 맞춤화할 수 있는 미리 만들어진 청사진과 비슷하다. 여기서 패턴은 재사용할 수 있는 코드 조각이 아니라 특정 문제를 해결하는 방식을 알려주는 일반적인 개념이다. </p>
<p>쉽게 설명하자면 같은 실수를 반복하지 않기 위해 시행착오를 바탕으로 특정 상황에서 발생하는 문제 패턴을 발견하고 해결방안을 기록한 것을 디자인 패턴이라 부릅니다.</p>
<h3 id="장점">장점</h3>
<ul>
<li>개발자간의 원활한 소통이 가능하다.</li>
<li>소프트웨어 구조 파악이 쉽고, 재사용을 통한 개발 시간을 단축할 수 있다.</li>
<li>설계 변경 요청에 대한 유연한 대처가 가능하다.</li>
<li>엔터프라이즈 시스템이 확장될 때 용이하고, 개발 소요 시간 및 유지보수 시간 단축이 가능하다.</li>
<li>개발의 효율성과 유지보수성, 운용성이 높아져서 프로그램의 최적화에 도움된다.</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li>프로젝트의 복잡도를 증가시키고 코드의 가독성을 저해할 수 있다.</li>
<li>추상화를 통해 일반적인 문제 해결책을 제공하지만, 과도한 추상화는 코드의 유지보수를 어렵게 만든다.</li>
<li>잘못된 패턴 선택으로 인해 코드가 복잡해지고 가독성이 저하될 수 있다.</li>
<li>과도하게 사용하면 패턴을 적용하는 데 필요한 비용과 시간이 증가하게 된다.</li>
<li>적용을 위한 일정 수준의 기술과 경험이 필요하다.</li>
</ul>
<h2 id="디자인-패턴의-종류">디자인 패턴의 종류</h2>
<p>객체 지향적 디자인 패턴에는 생성패턴, 구조패턴, 행동패턴 3가지 카테고리로 분류하고 있다. 세부적으로는 23개의 패턴이 있습니다.</p>
<table>
<thead>
<tr>
<th>생성패턴(Creational)</th>
<th>구조패턴(Structural)</th>
<th>행위패턴(Behavioral)</th>
</tr>
</thead>
<tbody><tr>
<td>싱글톤(Singleton)</td>
<td>어댑터(Adapter)</td>
<td>커맨드 패턴(Command Pattern)</td>
</tr>
<tr>
<td>빌터(Builder)</td>
<td>프록시(Proxy)</td>
<td>인터프리터(Interpreter)</td>
</tr>
<tr>
<td>팩토리 메소드(Factory Method)</td>
<td>브릿지(Bridge)</td>
<td>상태(state)</td>
</tr>
<tr>
<td>추상 팩토리(Abstract Factory)</td>
<td>컴포짓(Composite)</td>
<td>전략(Strategy)</td>
</tr>
<tr>
<td>프로토타입(Prototype)</td>
<td>퍼사드(Facade)</td>
<td>메멘토(Memento)</td>
</tr>
<tr>
<td></td>
<td>데코레이터(Decorator)</td>
<td>옵저버(Observer)</td>
</tr>
<tr>
<td></td>
<td>플라이웨이트(Flyweight)</td>
<td>비지터(Visitor)</td>
</tr>
<tr>
<td></td>
<td></td>
<td>중재자(Mediator)</td>
</tr>
<tr>
<td></td>
<td></td>
<td>이터레이터(Iterator)</td>
</tr>
<tr>
<td></td>
<td></td>
<td>탬플릿 메소드(Template Method)</td>
</tr>
<tr>
<td></td>
<td></td>
<td>책임 연쇄<br>(Chain-of-Responsibility)</td>
</tr>
</tbody></table>
<h3 id="생성패턴">생성패턴</h3>
<p>객체의 생성과 변경이 시스템에 미치는 영향을 최고화 하고, 코드의 유연성을 높여준다.</p>
<h3 id="구조패턴">구조패턴</h3>
<p>프로그램 내의 자료구조나 인터페이스 구조 등 프로그램의 구조를 설계하는 데에 활용될 수 있는 패턴을 의미한다. 큰 규모의 시스템에서는 많은 클래스 들이 서로 의존성을 갖는데, 이런 복잡한 구조를 개발하기 용이하게 만들고 유지보수를 더욱 간편하게 만들어 주는 것이 구조패턴에 해당된다.</p>
<h3 id="행위패턴">행위패턴</h3>
<p>클래스나 객체들이 상호작용하는 방법과 책임을 분산하는 방법으로 행위 관련 패턴을 사용하여 독립적으로 일을 처리하고자 할 때 사용한다.</p>
<hr>

<h5 id="정리">정리</h5>
<p><Strong class="organize">디자인 패턴</Strong>이란, 같은 실수를 반복하지 않기 위해 시행착오를 바탕으로 특정 상황에서 발생하는 문제 패턴을 발견하고 해결방안을 기록한 것이다. <Strong class="organize">장점</Strong>은 개발자간의 원활한 소통, 소프트웨어의 구조 파악이 쉬우며 재사용을 통한 개발 시간을 단축, 설계 변경 요청에 대한 유연한 대처 가능, 엔터프라이즈 시스템의 확장 용이, 개발 소요 시간 및 유지보수 시간 단축, 개발의 효율성, 유지보수성, 운용성 증가로 인한 프로그램 최적화에 도움됨. <Strong  class="organize">단점</Strong>으로는 복잡도를 증가시고 가동성을 저해, 과도한 추상화로 어려운 유지보수, 잘못된 패턴 선택으로 코드가 복잡, 과도한 패턴 적용으로 인한 비용과 시간이 증가,일정 수준의 기술과 경험이 필요. <Strong  class="organize">종류</Strong>는 생성패턴, 구조패턴, 행동패턴 이렇게 3가지 카테고리로 분류하고 있고 세부적으로는 23가지 패턴이 있다.</p>
<hr>
출처

<p><a href="https://refactoring.guru/ko/design-patterns/what-is-pattern">https://refactoring.guru/ko/design-patterns/what-is-pattern</a>
<a href="https://m.hanbit.co.kr/channel/category/category_view.html?cms_code=CMS6705039023">https://m.hanbit.co.kr/channel/category/category_view.html?cms_code=CMS6705039023</a>
<a href="https://velog.io/@poiuyy0420/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%A2%85%EB%A5%98">https://velog.io/@poiuyy0420/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%A2%85%EB%A5%98</a>
<a href="https://hoons-dev.tistory.com/113">https://hoons-dev.tistory.com/113</a>
<a href="https://www.dak.so/design-patterns/cons">https://www.dak.so/design-patterns/cons</a>
<a href="https://effortguy.tistory.com/182">https://effortguy.tistory.com/182</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Mac 터미널에서 인스턴스에  ssh key 접속]]></title>
            <link>https://velog.io/@b-joon/Mac-%ED%84%B0%EB%AF%B8%EB%84%90%EC%97%90%EC%84%9C-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4%EC%97%90-ssh-key-%EC%A0%91%EC%86%8D</link>
            <guid>https://velog.io/@b-joon/Mac-%ED%84%B0%EB%AF%B8%EB%84%90%EC%97%90%EC%84%9C-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4%EC%97%90-ssh-key-%EC%A0%91%EC%86%8D</guid>
            <pubDate>Tue, 09 Jan 2024 07:53:10 GMT</pubDate>
            <description><![CDATA[<ol>
<li>Homebrew가 설치되어 있지 않다면 <a href="https://brew.sh/ko/">Homebrew</a>를 설치 한다.</li>
</ol>
<img alt="스크린샷 2024-01-09 오후 4 18 27" src="https://github.com/B-joon/HttpSessionLogin/assets/75296934/1c5a30d0-d8b9-4117-9f74-6cf885605905">

<ol start="2">
<li>설치가 완료되었거나 했었다면 터미널에 명령어를 입력하여 putty를 설치한다.</li>
</ol>
<pre><code class="language-bash">brew install putty</code></pre>
<ol start="3">
<li>터미널에서 ppk가 존재하는 폴더로 이동하여 ppk를 pem 파일로 변환하는 명령어를 입력한다.
(pem 파일을 가지고 있다면 바로 4번 과정을 진행하면 된다.)</li>
</ol>
<pre><code class="language-bash">puttygen 변환할파일명.ppk -O private-openssh -o 변환될파일명.pem</code></pre>
<ol start="4">
<li>pem 본인만 읽을 수 있도록 퍼미션을 설정해준다.</li>
</ol>
<pre><code class="language-bash">chmod 400 변환한파일명.pem</code></pre>
<ol start="5">
<li>SSH 접속</li>
</ol>
<pre><code class="language-bash">ssh -i 변환한파일명.pem 서버사용자이름@서버dns 또는 서버공용ip
(ex. ssh -i aaa.pem root@255.255.255.255)

키가 없는 경우
ssh -i 서버사용자이름@서버dns or 서버공용ip</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] 컴파일언어인가 인터프리터 언어인가.]]></title>
            <link>https://velog.io/@b-joon/Java%EB%8A%94-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EC%96%B8%EC%96%B4%EC%9D%B8%EA%B0%80-%EC%9D%B8%ED%84%B0%ED%94%84%EB%A6%AC%ED%84%B0-%EC%96%B8%EC%96%B4%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@b-joon/Java%EB%8A%94-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EC%96%B8%EC%96%B4%EC%9D%B8%EA%B0%80-%EC%9D%B8%ED%84%B0%ED%94%84%EB%A6%AC%ED%84%B0-%EC%96%B8%EC%96%B4%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Mon, 08 Jan 2024 05:43:40 GMT</pubDate>
            <description><![CDATA[<h1 id="컴파일-언어란">컴파일 언어란</h1>
<p>컴파일 언어는 소스 코드를 컴파일한 후, 기계어를 메모리와 CPU를 통해 읽어서 실행하는 방식으로 동작하는 언어를 말한다. 컴파일 후, 프로세서가 실행할 수 있도록 변환된 기계어 코드를 별도의 파일에 저장한다.</p>
<h3 id="특징">특징</h3>
<ul>
<li>컴파일을 하기 때문에 규모가 큰 프로그램일 경우 컴파일하는 데 오랜 시간이 소요된다.</li>
<li>한번 컴파일하면, 이후에는 기계어를 읽어 들이기 때문에 실행속도가 빠르다.</li>
<li>기계어를 통해 프로그램이 실행되기 때문에 프로그램의 소스코드가 유출되기 어렵다.</li>
<li>OS마다 기계어가 상이하기 때문에 OS에 따라 작업을 다르게 해주어야 한다.</li>
<li>컴파일러가 소스코드를 기계어로 변환하면 기계어가 메모리에 적재된다.</li>
</ul>
<h3 id="장점">장점</h3>
<ul>
<li>컴파일 단계와 실행 단계가 분리되어서 실행 속도가 빠르다.</li>
<li>컴파일 단계에서 에러가 발생하면 프로그램이 실해되지 않아 런타임 환경 전에 오류를 수정할 수 있다.</li>
<li>개발자가 메모리 관리, CPU 사용과 같은 하드웨어 측면에 대한 많은 제어 권한을 가지므로 PC 자원을 효율적으로 관리할 수 있다.</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li>코드에 수정이 있을 때마다 빌드 과정을 거쳐야해서 전체적으로 개발 기간이 늘어난다.</li>
<li>컴파일 시 지정된 플랫폼에 최적화 되도록 만들어져서 실행환경에 제약이 있으므로 플랫폼에 맞게 컴파일 해야해서 개발 기간이 늘어난다.</li>
</ul>
<h1 id="인터프리터-언어란">인터프리터 언어란</h1>
<p>소스코드를 컴파일하지 않고 코드를 한 줄씩 읽어서 바로 실행하는 언어이다. 빌드 과정을 거치지 않기 때문에 번역과 실행이 동시에 이루어진다.</p>
<h3 id="특징-1">특징</h3>
<ul>
<li>프로그램을 수정하고 컴파일 해야하는 과정을 생략할 수 있다.</li>
<li>오류가 발생하면 해당 부분부터 실행되지 않으므로 오류 발견이 쉽다.</li>
</ul>
<h3 id="장점-1">장점</h3>
<ul>
<li>빌드 과정이 없어서 바로 실행가능하다.</li>
<li>코드 수정이 용이해서 개발 기간이 컴파일 언어보다 적다.</li>
<li>플랫폼에 독립적이기 때문에 각 플랫폼에 지원하는 인터프리터만 있으면 실행 가능하다.</li>
</ul>
<h3 id="단점-1">단점</h3>
<ul>
<li>프로그램 실행 전에는 버그를 발견하기 어렵다.</li>
<li>실행할 때마다 인터프리터 과정이 반복되므로 실행 속도가 느리다.</li>
</ul>
<h1 id="그렇다면-자바는-어떤-언어인가">그렇다면 자바는 어떤 언어인가.</h1>
<p>Java는 컴파일 언어가 될 수 있고 인터프리터 언어가 될 수 있다. Java는 다른 컴파일 언어들이 동작하듯 Java 컴파일러가 JVM이 실행할 수 있는 바이트 코드로 번역을 해준다. 그리고 컴파일된 파일을 실행하기 위해 JVM이 컴퓨터가 이해할 수 있는 2진 코드로 번역하기 위해 Java 인터프리터를 이용하여 한 줄씩 읽으면서 번역 후 실행한다.</p>
<p>Java는 기존 언어들의 단점이었던 운영체제와 하드웨어에 영향을 받는 부분을 없애고자 인터프리터 언어를 컴파일을 진행 후 인터프리터로 변환하는 작업을 진행하도록 처리했다.</p>
<h2 id="jit-컴파일러">JIT 컴파일러</h2>
<p>JIT 컴파일러란 자바에서 속도에 대한 이슈를 해결하고자 노력하면서 등장하게 됐다. JIT 컴파일러는 프로그램이 실행되는 동안 JVM이 자주 사용되는 코드를 찾게 되면 해당 코드를 기계어로 컴파일을 한다. 컴파일 과정에서 어느정도 시간이 소요되지만 컴파일된 코드는 나중에 다시 실행될 때 빠르게 재사용 되므로 프로그램 전체 실행 시간을 줄이는데 기여를 하게 된다.</p>
<hr>
출처

<p><a href="https://jooona.tistory.com/157">https://jooona.tistory.com/157</a>
<a href="https://noodabee.tistory.com/entry/%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC-%EC%96%B8%EC%96%B4%EC%99%80-%EC%9D%B8%ED%84%B0%ED%94%84%EB%A6%AC%ED%84%B0-%EC%96%B8%EC%96%B4">https://noodabee.tistory.com/entry/%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC-%EC%96%B8%EC%96%B4%EC%99%80-%EC%9D%B8%ED%84%B0%ED%94%84%EB%A6%AC%ED%84%B0-%EC%96%B8%EC%96%B4</a>
<a href="https://well-made-codestory.tistory.com/30">https://well-made-codestory.tistory.com/30</a>
<a href="https://velog.io/@rmsry123/%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC-%EC%96%B8%EC%96%B4%EC%99%80-%EC%9D%B8%ED%84%B0%ED%94%84%EB%A6%AC%ED%84%B0-%EC%96%B8%EC%96%B4">https://velog.io/@rmsry123/%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC-%EC%96%B8%EC%96%B4%EC%99%80-%EC%9D%B8%ED%84%B0%ED%94%84%EB%A6%AC%ED%84%B0-%EC%96%B8%EC%96%B4</a>
<a href="https://gusrb3164.github.io/computer-science/2021/03/01/compile,-interpreter-language/">https://gusrb3164.github.io/computer-science/2021/03/01/compile,-interpreter-language/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Garbage Collection(GC)]]></title>
            <link>https://velog.io/@b-joon/Garbage-CollectionGC</link>
            <guid>https://velog.io/@b-joon/Garbage-CollectionGC</guid>
            <pubDate>Wed, 27 Dec 2023 04:32:20 GMT</pubDate>
            <description><![CDATA[<h1 id="garbage-collection">Garbage Collection</h1>
<p>메모리 관리 기법 중의 하나로, 프로그램이 동적으로 할당했던 메모리 영역 중에서 필요없게 된 영역을 해제하는 기능이다. C, C++ 등의 프로그래밍 언어에서는 수동으로 메모리를 관리해야 하지만 Java나 Kotlin을 이용해 개발을 하면 JVM의 가비지 컬렉터(GC)가 불필요한 메모리를 알아서 정리 해주기 때문에 Java 프로세스가 한정된 메모리를 효율적으로 사용할 수 있게 해주고, 개발자 입장에서 메모리 관리, 메모리 누수 문제를 관리하지 않아도 돼서 개발에만 집중할 수 있는 장점이 있다.</p>
<p>단점으로는 개발자가 메모리가 언제 해제되는지 정확하게 알 수 없어서 제어하기 힘들고, 가비지 컬렉션(GC)이 동작하는 동안에는 다른 동작을 멈추기 때문에 오버헤드가 발생한다. 오버헤드가 자주 발생하게 되면 성능 하락의 문제가 되기도 한다.</p>
<blockquote>
<p>Java에서도 System.gc()를 이용해 호출할 수 있지만,
오버헤드가 굉장히 크므로 가비지 컬렉션(GC)에게 메모리 해제를 맡기는 것이 좋다.</p>
</blockquote>
<h4 id="장점">장점</h4>
<p>메모리를 수동으로 관리하던 것에서 비롯된 에러를 예방할 수 있다.</p>
<ul>
<li>개발자의 실수로 인한 메모리 누수</li>
<li>해제된 메모리를 또 해제하는 이중 해제</li>
<li>해제된 메모리에 접근</li>
</ul>
<h4 id="단점">단점</h4>
<ul>
<li>가비지 컬렉션(GC)의 메모리 해제 타이밍을 개발자가 정확히 알기 어렵다.</li>
<li>어떤한 메모리 영역이 해제의 대상이 될 지 검사하고, 실제로 해제하는 일이 모두 오버헤드이다.</li>
</ul>
<h2 id="garbage-collection의-대상">Garbage Collection의 대상</h2>
<p>가비지 컬렉션(GC)는 객체에 레퍼런스가 있다면 Reachable로 구분하고, 객체에 유효한 레퍼런스가 없다면 Unreachable로 구분 후 수거한다.</p>
<ul>
<li>Reachable : 객체가 참조되고 있는 상태</li>
<li>Unreachable : 객체가 참조되고 있지 않은 상태</li>
</ul>
<p><img src="https://velog.velcdn.com/images/gayeong39/post/26baf5f0-6d5e-473f-8392-dde5c568cf90/image.png" alt="">
(이미지 출처 : <a href="https://velog.io/@gayeong39/Garbage-Collection%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98">https://velog.io/@gayeong39/Garbage-Collection%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98</a>)</p>
<p>객체들은 실질적으로 Heap 영역에서 생성되고 Method Area이나 Stack Area에서는 Heap Area에 생성된 객체의 주소만 참조하는 형식으로 구성된다. 하지만 이렇게 생성된 Heap Area의 객체들이 메서드가 끝나는 등의 특정 이벤트들로 인하여 Heap Area 객체의 메모리 주소를 가지고 있는 참조 변수가 삭제되는 현상이 발생하면, 위의 그림에서 빨간색 객체(Unreachable)와 같이 Heap 영역에서 어디든 참조하고 있지 않은 객체들이 발생한다. 이러한 객체들을 주기적으로 가비지 컬렉터가 제거해준다.</p>
<h2 id="garbage-collection의-알고리즘">Garbage Collection의 알고리즘</h2>
<h3 id="reference-counting">Reference Counting</h3>
<p>Garbage Detection에 초첨이 맞추어진 초기 알고리즘이다. 각 객체마다 Reference Count를 관리하여 Reference Count가 0이 되면 가비지 컬렉션(GC)을 수행한다.
이 방식은 각 객체마다 Reference Count를 변경해 주어야 하기 때문에 그에 대한 관리 비용이 크고, 참조를 많이 하고 있는 객체의 Reference Count가 0이 될 경우 연쇄적으로 가비지 컬렉션(GC)가 발생할 수 있는 문제가 있다. 또한 메모리 누수가 발생할 가능성도 크다.</p>
<h3 id="mark-and-sweep">Mark and Sweep</h3>
<p>Reference Counting 알고리즘의 단점을 극복하기 위해 나온 알고리즘이다. 가비지 컬렉션(GC)는 스택의 모든 변수 또는 Reachable 객체를 스캔하면서 각각 어떤 객체를 참고하는지 탐색한다. 그리고 사용되고 있는 메모리를 식별(Mark)하고 식별되지 않은 객체들을 메모리에서 제거(Sweep)한다.</p>
<ul>
<li>Mark : 사용되는 메모리와 사용되지 않는 메모리를 식별</li>
<li>Sweep : Mark 단계에서 사용되지 않음으로 식별된 메모리를 제거</li>
</ul>
<p>별도의 오버헤드가 없어서 성능이 비교적 좋지만, 가비지 컬렉션(GC)가 수행되는 도중 Mark 작업의 정확성과 Memory Corruption을 방지하기 위해 Heap의 사용이 제한되기 때문에 지연(Suspend) 현상이 발생한다. 그리고 객체들이 지워진 공간이 분열된(fragmentation) 것으로 남게 되어 메모리 할당이 불가능한 상태가 된다.</p>
<h3 id="mark-and-compact">Mark and Compact</h3>
<p>Mark and Sweep 알고리즘의 fragmentation 약점을 극복하기 위해 나온 알고리즘이다. Sweep이 사라진 것이 아니고 Compact 안에 포함되어 있다. Mark and Compact 알고리즘은 기존의 Sweep 과정까지는 동일 하지만 Compact 과정을 더 거치게 된다.</p>
<p>Sweep 후에 분산된 객체들을 Heap 영역의 시작 주소로 모아 메모리가 할당된 부분과 fragmentation한 부분을 압축해서 메모리 공간의 효율을 높일 수 있다. 하지만 Compact 작업 이후 할당된 사용되는 메모리들의 Reference를 업데이트 하는 작업이 필요하기 때문에 부가적인 오버헤드가 발생한다.</p>
<h2 id="heap-메모리-구조">Heap 메모리 구조</h2>
<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbti1oP%2FbtrvtcdoBC9%2FupBBOdB4mJF6tfyhL8GPbK%2Fimg.png" alt="">
(이미지 출처 : <a href="https://coding-factory.tistory.com/829">https://coding-factory.tistory.com/829</a>)</p>
<p>JVM의 Heap 영역은 동적으로 레퍼런스 데이터가 저장되는 공간으로, 가비지 컬렉션(GC)에 대상이 되는 공간이다. Heap 영역은 처음 설계될 때 다음의 2가지를 전제(Weak Generational Hypothesis)로 설계 되었다.</p>
<ul>
<li>대부분의 객체는 금방 접근 불가능한 상태(Unreachable)가 된다.</li>
<li>오래된 객체에서 새로운 객체로 참조는 아주 적게 존재한다.</li>
</ul>
<p>즉, 객체는 대부분 일회성되며, 메모리에 오랫동안 남아있는 경우는 드물다. 그렇기 때문에 객체는 생존 기간에 따라 물리적인 Heap 영역을 나누게 되고 Young, Old 총 2가지 영역으로 설계되었다. 초기에는 Perm 영역도 존재했지만 Java 8부터 제거되었다.</p>
<h5 id="young-generation">Young Generation</h5>
<ul>
<li>새롭게 생성된 객체가 할당(Allocation)되는 영역</li>
<li>대부분의 객체가 금방 Unreachable 상태가 되기 때문에, 많은 객체가 Young 영역에 생성되었다가 사라진다.</li>
<li>Young 영역에 대한 가비지 컬렉션(GC)을 Minor GC라고 부른다.</li>
</ul>
<blockquote>
<p>Young 영역은 더욱 효율적인 GC를 위해 3가지 영역으로 나눈다.</p>
</blockquote>
<ul>
<li>Eden<ul>
<li>new를 통해 사로 생성된 객체가 위치</li>
<li>정기적인 쓰레기 수집 후 살아남은 객체들은 Survivor 영역으로 보냄</li>
</ul>
</li>
<li>Survivor 0 / Survivor 1<ul>
<li>최소 1번의 가비지 컬렉션(GC) 이상 살아남은 객체가 존재하는 영역</li>
<li>Suvivor 영역에는 특별한 규칙이 있는데 Suvivor 0 또는 1 둘 중 하나는 꼭 비어 있어야 한다.</li>
</ul>
</li>
</ul>
<h5 id="old-generation">Old Generation</h5>
<ul>
<li>Young 영역에서 Reachable 상태를 유지하여 살아남은 객체가 복사되는 영역</li>
<li>Young 영역보다 크게 할당되며, 영역의 크기가 큰 만큼 가비지는 적게 발생한다.</li>
<li>Old 영역에 대한 가비지 컬렉션(GC)을 Major GC 또는 Full GC 라고 부른다.</li>
</ul>
<p>Old 영역이 Young 영역보다 크게 할당되는 이유는 Young 영역의 수명이 짧은 객체들은 큰 공간을 필요로 하지 않으며 큰 객체들은 Young 영역이 아니라 바로 Old 영역에 할당되기 때문이다.</p>
<h2 id="garbage-collection-동작-과정">Garbage Collection 동작 과정</h2>
<p><img src="https://user-images.githubusercontent.com/58318041/96338345-41e59280-10c8-11eb-9b63-a5f0ef6aa124.png" alt="">
(이미지 출처 : <a href="https://wooody92.github.io/java/GC-%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC/">https://wooody92.github.io/java/GC-%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC/</a>)</p>
<p>Young 영역은 일반적인 Old 영역보다 크기가 작기 때문에 가비지 컬렉션(GC)가 보통 0.5초에서 1초 사이에 끝난다. 그렇기 때문에 Minor GC는 애플리케이션에 크게 영향을 주지 않지만 Old 영역의 Major GC는 일반적으로 Minor GC 보다 시간이 오래 걸리며, 10배 이상의 시간을 사용한다.</p>
<h3 id="minor-gc">Minor GC</h3>
<ol>
<li>새로 생성된 객체가 Young 영역의 일부인 Eden에 age-bit 0으로 할당 된다. age-bit는 Minor GC에서 살아 남을 때마다 1씩 증가한다.</li>
<li>새로운 객체가 계속 생성되어 Eden 영역이 꽉차게 되면 Minor GC 가 실행된다.</li>
<li>Mark 동작을 통해 Reachable 객체를 탐색한다.</li>
<li>Reachable 객체는 Suvivor 영역으로 이동되며 age-bit 값이 1씩 증가되고, Unreachable 객체는 메모리가 해제된다.</li>
<li>Eden 영역에 신규 객체들이 생성되어 다 쌓이게 되면 Young 영역(Eden + Survivor)에 있는 Reachable 객체들은 비어있는 Survivor 영역으로 이동하고 age-bit 값이 1 증가 된다.</li>
<li>위 과정을 반복한다.</li>
</ol>
<h3 id="major-gc-or-full-gc">Major GC or Full GC</h3>
<ol>
<li>Minor GC가 발생하며 age-bit 값이 JVM에서 설정해놓은 임계치에 도달하게 되면 Old 영역으로 이동된다. 이 과정을 Promotion 이라고 한다.</li>
<li>1번의 동작이 반복되어 Old 영역에 할당된 메모리가 부족하게 되면 Major GC가 발생한다.</li>
</ol>
<h3 id="minor-gc--major-gc-차이점">Minor GC / Major GC 차이점</h3>
<table>
<thead>
<tr>
<th>GC 종류</th>
<th>Minor GC</th>
<th>Major GC</th>
</tr>
</thead>
<tbody><tr>
<td>대상</td>
<td>Young Generation</td>
<td>Old Generation</td>
</tr>
<tr>
<td>실행 시점</td>
<td>Eden 영역이 꽉 찬 경우</td>
<td>Old 영역이 꽉 찬 경우</td>
</tr>
<tr>
<td>실행 속도</td>
<td>빠르다</td>
<td>느리다</td>
</tr>
</tbody></table>
<h2 id="garbage-collection-실행-방식">Garbage Collection 실행 방식</h2>
<p>JVM에서는 애플리케이션과 가비지 컬렉션(GC)을 병행하여 실행할 수 있는 여러 옵션들을 제공한다. 다양한 가비지 컬렉션(GC)가 어떠 방식으로 애플리케이션 실행과 병행되는지 살펴 보기 전에 Stop The World(STW) 개념을 알아야 한다. Stop The World란 가비지 컬렉션(GC)을 실행하기 위해 JVM이 애플리케이션 실행을 멈추는 것을 말한다.</p>
<h3 id="serial-gc">Serial GC</h3>
<ul>
<li>서버의 CPU 코어가 1개일 때 사용하기 위해 개발된 가장 단순한 가비지 컬렉션(GC)</li>
<li>싱글 스레드이기 때문에 Stop The World 시간이 가장 길다.</li>
<li>Minor GC 에는 Mark and Sweep를 사용하고, Major GC에는 Mark and Compact를 사용한다.<img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fee944481-c360-4639-8eeb-271ba3a2ac8e%2FUntitled.png?table=block&id=739c2288-b44d-4af3-ac20-da319e33999f&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" style="width: 10%"/>
(이미지 출처 : <https://steady-coding.tistory.com/584>)

</li>
</ul>
<h5 id="실행-명령어">실행 명령어</h5>
<ul>
<li>자바 프로그램을 실행할 때 <code>-XX:+UseSerialGC</code>GC 옵션을 지정하여 해당 가비지 컬렉션 알고리즘으로 힙 메모리를 관리하도록 실행할 수 있다.</li>
</ul>
<pre><code>java -XX:+UseSerialGC -jar Application.java</code></pre><h3 id="parallel-gc">Parallel GC</h3>
<ul>
<li>Java 8의 디폴트 가비지 컬렉션(GC)</li>
<li>멀티 코어 환경에서 애플리케이션 처리 속도를 향상시키기 위해 사용(Minor GC는 멀티 스레딩을 수행하지만, Major GC는 싱글 스레드로 수행)</li>
<li>Serial GC에 비해 Stop the World 시간 감소<img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F7b9d7734-0139-4eeb-9096-9a8b853bdc11%2FUntitled.png?table=block&id=fea9b2f8-b7a5-4903-92df-8dfd3dd02338&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" style="width: 50%">
(이미지 출처 : <https://steady-coding.tistory.com/584>)

</li>
</ul>
<h5 id="실행-명령어-1">실행 명령어</h5>
<ul>
<li>GC 스레드는 기본적으로 CPU 개수만큼 할당된다.</li>
<li>옵션을 통해 GC를 수행할 스레드의 갯수 등을 설정해줄 수 있다.</li>
</ul>
<pre><code class="language-bash">java -XX:+UseParallelGC -java Application.java
# -XX:ParallelGCThreads=N -&gt; 사용할 스레드 갯수</code></pre>
<h3 id="paraller-old-gc">Paraller Old GC</h3>
<ul>
<li>Parallel GC 를 개선한 버전</li>
<li>Young 영역 뿐만 아니라, Old 영역에서도 멀티 스레드로 가비지 컬렉션(GC) 수행</li>
<li>새로운 가비지 컬렉션 청소 방식인 Mark Summary Compact 방식을 이용(Old 영역도 멀티 스레드로 처리)<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtyQsa%2FbtsiheMJJfD%2FL3Gye5kHReIShR1ScxdTV0%2Fimg.png" style="width: 50%"/>
(이미지 출처 : <https://steady-coding.tistory.com/584>)

</li>
</ul>
<h5 id="실행-명령어-2">실행 명령어</h5>
<pre><code class="language-bash">java -XX:+UseParallelOldGC -jar Application.java</code></pre>
<h3 id="cms-gc">CMS GC</h3>
<ul>
<li>애플리케이션의 스레드와 가비지 컬렉션(GC) 스레드가 동시에 실행되어 Stop The World 시간을 최대한 줄이기 위해 고안된 가비지 컬렉션(GC)이다.</li>
<li>가비지 컬렉션(GC) 과정이 매우 복잡해진다.</li>
<li>가비지 컬렉션(GC) 대상을 파악하는 과정이 복잡한 여러 단계로 수행되기 때문에 다른 가비지 컬렉션(GC) 대비 CPU 사용량이 높다.</li>
<li>메모리 파편화 문제</li>
<li>Java 9 버전부터 Deprecated 되었고 Java 14 에서는 사용이 중지 되었다.<img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F8b203a00-163a-4deb-a3dc-537ea613c38a%2FUntitled.png?table=block&id=b9764bfc-93c2-45cb-8fc6-c30d339eb8f5&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" style="width: 50%"/>
(이미지 출처 : <https://steady-coding.tistory.com/584>)

</li>
</ul>
<h5 id="실행-명령어-3">실행 명령어</h5>
<pre><code class="language-bash"># Java 9 버전부터 Deprecated 되었고 Java 14 에서는 사용이 중지
java -XX:+UseConcMarkSweepGC -jar Application.java</code></pre>
<h3 id="g1-gc">G1 GC</h3>
<ul>
<li>Java 9 이상부터 G1 GC를 기본 GC 실행 방식으로 사용</li>
<li>4GB 이상의 힘 메모리. Stop The World 시간이 0.5초 정도 필요한 상황에서 사용(Heap 메모리가 너무 작을 경우 미사용을 권장함)</li>
<li>가비지로 가득찬 영역을 빠르게 회수하여 빈 공간을 확보하므로, 결국 가비지 컬렉션(GC) 빈도가 줄어드는 효과를 얻게 된다.</li>
<li>기존 GC 알고리즘에서 Heap 영역에 물리적으로 고정된 Young/Old 영역으로 나누어 사용했지만, G1 GC는 Region이라는 개념을 새로 도입하여 필요에 따라 영역별 Region 개수를 튜닝함으로써 Stop the World를 최소화 할 수 있다.</li>
<li>Heap 영역을 Resion이라는 영역으로 체스같이 분할하여 상황에 따라 Eden, Survivor, Old 등 역할을 고정이 아닌 동적으로 부여한다.<img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Ff435c5c9-f5a3-4306-9fc3-0ce127778ed4%2FUntitled.png?table=block&id=ca35c7d9-cfaa-430e-a225-5baf3964c3b5&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" style="width: 50%"/>
(이미지 출처 : <https://steady-coding.tistory.com/584>)

</li>
</ul>
<h5 id="실행-명령어-4">실행 명령어</h5>
<pre><code class="language-bash">java -XX:+UseG1GC -jar Application.java</code></pre>
<hr>
출처

<p><a href="https://ko.wikipedia.org/wiki/%EC%93%B0%EB%A0%88%EA%B8%B0_%EC%88%98%EC%A7%91_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EA%B3%BC%ED%95%99)">위키백과 가비지 컬렉션</a>
<a href="https://mangkyu.tistory.com/118">https://mangkyu.tistory.com/118</a>
<a href="https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98GC-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%F0%9F%92%AF-%EC%B4%9D%EC%A0%95%EB%A6%AC">https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98GC-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%F0%9F%92%AF-%EC%B4%9D%EC%A0%95%EB%A6%AC</a>
<a href="https://coding-factory.tistory.com/829">https://coding-factory.tistory.com/829</a>
<a href="https://steady-coding.tistory.com/584">https://steady-coding.tistory.com/584</a>
<a href="https://yoon1fe.tistory.com/152">https://yoon1fe.tistory.com/152</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Framework]]></title>
            <link>https://velog.io/@b-joon/Spring-Framework</link>
            <guid>https://velog.io/@b-joon/Spring-Framework</guid>
            <pubDate>Mon, 18 Dec 2023 08:33:53 GMT</pubDate>
            <description><![CDATA[<h1 id="spring">Spring</h1>
<p>스프링은 자바 엔터프라이즈 개발을 위한 오픈소스 경량 애플리케이션 프레임워크이다. Spring Framework, Spring Boot, Spring MVC, Spring Data 등 다양한 프로젝트로 구분되어 있으며, 엔터프라이즈 애플리케이션을 개발의 다양한 영역에 바로 활용할 수 있는 방대한 양의 기술 API를 제공한다.</p>
<h5 id="엔터프라이즈">엔터프라이즈</h5>
<p>기업을 대상으로 하는 개발, 수많은 데이터처리 등 동시에 여러 사용자로부터 행해지는 대규모의 환경을 말한다.</p>
<h5 id="오픈소스">오픈소스</h5>
<p>오픈소스ㄹ한 모든 사용자에게 무료로 열려 있다는 것을 의미한다. 즉, 개인 및 기업도 스프링을 사용하여 웹 애플리케이션을 개발 할 수 있고, 스프링 코드 일부를 수정하여 사용해도 무관하다. 스프링은 오픈소스 프레임워크이지만, 안정적인 개발과 개선이 보장된다.</p>
<h5 id="프레임워크">프레임워크</h5>
<p>목적에 따라 고민할 필요없이 이용할 수 있도록 일괄로 가져다 쓰도록 만들어 놓은 틀, 프로그래밍에서 특정 운영 체제를 위한 응용 프로그램 표준 구조를 구현하는 클래스와 라이브러리 모임.</p>
<h2 id="특징">특징</h2>
<h4 id="pojoplain-old-java-object">POJO(Plain Old Java Object)</h4>
<p>스프링의 가장 큰 특징으로 POJO 프로그래밍을 지향한다. POJO란 순수 Java만을 통해서 생성한 객체를 의미한다. 순수 Java 만을 사용한다는 것은 Java 및 Java의 스펙에 정의된 기술만 사용한다는 의미이다.
POJO를 사용하면 다른 기술과의 의존성이 줄어들어 테스트 및 유지 보수가 편리한 유연성을 가진다.</p>
<pre><code class="language-java">// 필드와 이에 해당하는 getter 및 setter만 구성된 기본적인 POJO의 예시
public class User{

    private String Id;
    private String password;

    public String getId() {
        return id;
    }

    public String setId(String id) {
        this.id = id;
    }

    public String getPassword() {
        return password;
    }

    public String setPassword(String password) {
        this.password = password;
    }

}</code></pre>
<blockquote>
<p>필요성</p>
</blockquote>
<ul>
<li>특정 환경이나 기술에 종속적이지 않으면 재사용 가능하고, 확장 가능한 유연한 코드를 작성할 수 있다.</li>
<li>저수준 레벨의 기술과 환경에 종속적인 코드를 애플리케이션 코드에서 제거 함으로써 코드가 깔끔해진다.</li>
<li>코드가 깔끔해지기 때문에 디버깅하기도 상대적으로 쉽다.</li>
<li>특정 기술이나 환경이 종속적이지 않기 때문에 테스트 역시 단순해진다.</li>
<li><strong>객체 지향적인 설계를 제한없이 적용할 수 있다.</strong></li>
</ul>
<h4 id="경량-컨테이너">경량 컨테이너</h4>
<p>자바 객체를 직접 관리하고, 각각의 객체 생성, 소멸과 같은 라이프 사이클을 관리하며 스프링으로부터 필요한 객체를 얻어올 수 있다.</p>
<h4 id="제어의-역전-iocinversion-of-control">제어의 역전 IOC(Inversion Of Control)</h4>
<p>IOC는 코드의 흐름을 제어하는 주체를 바꾸는 패턴을 말한다. 개발자가 아닌 컨테이너가 객체간의 관계를 설정, 객체의 생성과 호출 시점을 관리한다. 객체 생성과 관리를 컨테이너에 위임하면 코드의 유지보수성이 높아지며 객체간의 결함도가 낮아지므로 코드의 재사용성과 확장성이 좋아진다.</p>
<pre><code class="language-java">@Service
public class BoardService {

    @Autowired
    private BoardMapper mapper;

    public String boardInsert(BoardVo board) {
                ...
    }

---------------------------------------------------

    private BoardMapper mapper;

    public BoardService(BoardMapper mapper) {
        this.mapper = mapper;
    }

    public String boardInsert(BoardVo board) {
                ...
    }
}</code></pre>
<pre><code class="language-java">@Controller
public class BoardController{

    @Autowired
    private BoardService service;

    public String insert(BoardVO board) {
        service.boardInsert(board);
            ...
    }

    ------------------------------------

    private BoardService service;

    public BoardController(BoardService service) {
        this.service = service
    }

    public String insert(BoardVO board) {
        service.boardInsert(board);
            ...
    }
}</code></pre>
<blockquote>
<p>@Autowired란
의존 관계 주입을 할 때 사용하는 어노테이션(Annotation)으로
의존 객체의 타입에 해당하는 빈(Bean)을 찾아서 주입하는 역할을 한다.</p>
</blockquote>
<p>BoardController 를 보면 개발자가 따로 BoardService에 대한 객체 생성을 하지 않아도 정상 동작한다. 이유는 생성자 또는 @Autowired를 통해 BoardMapper 또는 BoardService를 자동으로 주입을 받기 때문인데 이 때 자동으로 주입해 객체를 생성해주는 주체는 스프링이다. 이렇게 개발자가 아닌 스프링이 직접 의존 관계를 맺어주는 것을 IOC(제어의 역전)라고 한다.</p>
<h4 id="의존성-주입-didependentcy-injection">의존성 주입 DI(Dependentcy Injection)</h4>
<p>각 객체가 서로 의존하는 관계가 될 수 있도록 외부에서 주입시켜주는 패턴이다. 즉, 객체가 필요로 하는 어떤 것을 외부에서 전달해 주는 것이라고 할 수 이다. 강하게 결합된 클래스들을 분리하고, 애플리케이션 실행 시점에 객체간의 관계를 결정해 줌으로써 결합도를 낮추고 유연성을 확보해준다. </p>
<ul>
<li>생성자 주입</li>
</ul>
<pre><code class="language-java">public class BoardVO {
    private String title;
    private String content;

    public BoardVO(String title, String content) {
        this.title = title;
        this.content = content;
    }
            ...
}</code></pre>
<ul>
<li>수정자 주입(setter 주입) </li>
</ul>
<pre><code class="language-java">public class BoardVO {
            ...
    public void setTitle(String title) {
        this.title = title;
    }

    public void setContent(String content) {
        this.content = content;
    }
}</code></pre>
<ul>
<li>필드 주입</li>
</ul>
<pre><code class="language-java">@Controller
public class BoardController{

    @Autowired
    private BoardService service;

}</code></pre>
<p>DI 프레임워크에서는 생성자 주입을 권장하고 있다. 생성자 주입은 객체의 불변성을 확보할 수 있으며, 테스트가 편리하고, final 키워드와 Lombok을 활용하여 간결하게 작성이 가능하고, 순환참조 에러를 방지할 수 있기 때문이다.</p>
<h4 id="관점-지향-프로그래밍-aopaspect-oriented-programming">관점 지향 프로그래밍 AOP(Aspect Oriented Programming)</h4>
<p>기능 단위를 분리하여 개발의 복잡성을 낮추기 위한 프로그래밍 패러다임이다. 객체 지향 프로그래밍은 주요한 기능에 단일 책임 원칙(SRP : Single Responsibility Principle)에 따라 클래스를 분리한다. 애플리케이션을 개발할 때 공통 기능을 비즈니스 로직으로부터 분리해내는 것을 AOP라고 한다.</p>
<p>기능을 분리할 때 공통되지 않는 주요 비즈니스 로직을 핵심 관심사(Core Concern)라고 하며, 핵심 관심사항에 공통적으로 적용되는 관심 사항을 횡단 관심사(Cross Cutting Concern)라고 한다.</p>
<p>AOP는 프록시 패턴(Proxy Pattern)을 통해 구현된다.</p>
<blockquote>
<p>프록시 패턴이란
대상 원본 객체를 대리하여 대신 처리하게 함으로써 로직의 흐름의 제어하는 패턴.
누군가에게 어떤 일을 대신 시키는 것을 의미한다.</p>
</blockquote>
<h4 id="일관된-서비스-추상화-psaportable-service-abstractin">일관된 서비스 추상화 PSA(Portable service Abstractin)</h4>
<p>환경 변화 및 세부기술의 변경과 상과없이 일관된 방식으로 기술에 접근할 수 있는 화경을 제공하려는 추상화 구조이다. 스프링은 스프링을 통해 동작하는 라이브러리들이 POJO원칙을 지키게끔 PSA 형태로 추상화 되어있다. 즉, 복잡한 기술은 내부에 숨기면서 개발자에게 편의성을 제공한다.</p>
<p>Spring Web MVC와 Transaction을 예를 들자면, Spring은 Servlet 기반의 애플리케이션을 만들고 있다. 하지만 Servlet 코드는 보이지 않는다. @Controller, @GetMapping, @PostMapping 등의 Annotation을 사용하면 추가적으로 코드를 작성하지 않아도 get, post 등의 통신이 가능해진다.
그리고 JDBC를 통해 DB에 접근하거나 JPA를 통해 DB에 접근을 하든 @Transaction Annotation을 사용하기만 하면 코드를 추가하지 않고 Transaction 서비스를 사용할 수 있다.</p>
<h2 id="주요-모듈">주요 모듈</h2>
<p>스프링 프레임워크는 20여개의 모듈로 구성되어 있으며 각 모듈은 전부 사용해야 하는 것이 아니라 필요한 것만 사용할 수 있도록 설계되어 있다. 이를 통해 큰 규모의 애플리케이션을 구축하더라도 용이하게 사용할 수 있으며 AOP, MVC, TEST 등의 핵심적인 모듈을 통해 편리하게 애플리케이션을 개발할 수 있다.
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcE1zI%2Fbtrctw1ZTsB%2FKvRaDvsvWGklSbdfNJElL0%2Fimg.png" alt=""></p>
<h3 id="core-container">Core Container</h3>
<p>스프링 프레임워크의 핵심인 Bean의 생명주기와 설정 그리고 처리 방법을 관리하는 스프링 컨테이너다.
모든 스프링 모듈은 Core Container 기반으로 구축된다.</p>
<h3 id="aspects-instrumentation">Aspects, Instrumentation</h3>
<ul>
<li>Aspects : 스프링이 제공하는 AspectJ AOP를 사용할 때 필요한 모듈</li>
<li>특정 애플리케이션 서버에서 사용할 클래스 계측 지원 및 클래스 로더 구현을 제공</li>
</ul>
<h3 id="messaging">Messaging</h3>
<p>Message, MesageChannel, MessageHandler 등의 스프링 통함 프로젝트를 포함하고 있으며 메시지 기반 애플리케이션을 구축하는데 역할을 한다.</p>
<h3 id="data-access-integration">Data Access, Integration</h3>
<p>스프링은 JDBC, ORM, Transaction 등의 서비스를 추상화를 통해 쉽게 데이터에 접근하는 방법을 제공한다.</p>
<h3 id="web">Web</h3>
<p>스프링은 다양한 MVC 프레임워크를 사용할 수 있지만 스프링 자체적으로 제공하는 Spring MVC 모듈들이 있다. 또한 스프링의 리모팅 기술로 RMI, Hessian, HTTP호출자, REST API 모듈 등을 제공한다.</p>
<h3 id="test">Test</h3>
<p>스프링은 테스트에 전념할 수 있도록 Test 모듈을 제공한다. JUnit, TensNg를 이용하여 테스트 컨텍스트 프레임워크나 Mock 오브젝트 등을 이용하여 테스트를 할 때 사용한다.</p>
<hr>
출처

<p><a href="https://ko.wikipedia.org/wiki/%EC%8A%A4%ED%94%84%EB%A7%81_%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC">스프링 프레임워크 위키백과</a>
<a href="https://m.blog.naver.com/goottjob/223017496733">https://m.blog.naver.com/goottjob/223017496733</a>
<a href="https://www.codestates.com/blog/content/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8">https://www.codestates.com/blog/content/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8</a>
<a href="https://huimang2.github.io/java/spring">https://huimang2.github.io/java/spring</a>
<a href="https://memodayoungee.tistory.com/102">https://memodayoungee.tistory.com/102</a>
<a href="https://www.castingn.com/sourcing/kkultip_detail/110">https://www.castingn.com/sourcing/kkultip_detail/110</a>
<a href="https://velog.io/@sana/DI-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85Dependency-Injection-%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-%EB%B0%A9%EB%B2%95">https://velog.io/@sana/DI-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85Dependency-Injection-%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-%EB%B0%A9%EB%B2%95</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로세스와 스레드]]></title>
            <link>https://velog.io/@b-joon/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C</link>
            <guid>https://velog.io/@b-joon/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C</guid>
            <pubDate>Fri, 15 Dec 2023 06:52:38 GMT</pubDate>
            <description><![CDATA[<h1 id="프로그램">프로그램</h1>
<p>프로그램은 일반적으로 하드 디스크 등에 저장 되어 있는 실행코드를 뜻하고, 컴퓨터가 실행할 수 있는 명령어들의 집합.</p>
<h1 id="프로세스">프로세스</h1>
<p>프로그램을 실행 시켜 정적인 프로그램이 동적으로 변하여 프로그램이 돌아가고 있는 상태. 즉, 컴퓨터에서 작업 중인 프로그램을 의미한다. 여러 개의 프로세서를 사용하는 것을 <strong>멀티프로세싱</strong>이라고 하며 같은 시간에 여러 개의 프로그램을 띄우는 시분할 방식을 멀티태스킹이라고 한다.</p>
<ul>
<li>운영체제로부터 자원을 할당받은 <strong>작업의 단위</strong></li>
<li>각각의 프로세스는 독립된 메모리의 공간을 할당 받음</li>
<li>명령어들과 데이터를 가짐</li>
</ul>
<h2 id="프로세스의-구조">프로세스의 구조</h2>
<p>프로세스가 만들어지면 4가지의 메모리 영역으로 구성되어 할당 받는다.</p>
<p><img src="https://velog.velcdn.com/images%2Flamknh%2Fpost%2Ff9b1d1c9-ef1d-49d1-9bf8-5e8fa023b5da%2Fimage.png" alt="">
(사진 출처 : <a href="https://velog.io/@lamknh/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-3.-Processes">https://velog.io/@lamknh/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-3.-Processes</a>)</p>
<ul>
<li><strong>코드 영역(Code/Text) : 프로그램 함수들의 코드가 CPU가 해석 가능한 기계어 형태로 저장.</li>
<li>데이터 영역(Data) : 코드가 실행되면서 사용하는 전역 변수나 여러 데이터들이 모여 있음.</li>
<li>스택 영역(Stack) : 함수 호출시 할당되고 호출이 완료 되면 소멸한다. 이 때 함수 안에서 선언된 지역변수, 매개변수, 리턴 값 등이 저장됨. Stack영역을 초과하면 Stack Overflow 에러 발생.</li>
<li>힙 영역(Heap) : 메모리 주소에 의해서 참조되고 사용되는 영역. 동적으로 할당되는 데이터들을 위해 존재하는 공간.</strong></li>
</ul>
<h2 id="멀티-프로세스">멀티 프로세스</h2>
<p>하나의 응용 프로그램에 대해 동시에 여러 개의 프로세스를 실행할 수 있게 하는 기술</p>
<h5 id="장점">장점</h5>
<ul>
<li>프로그램 안정성 : 각 프로세스가 독립적인 메모리 공간을 가지므로, 한 프로세스가 비정상적으로 종료되어도 다른 프로세스에 영향을 주지 않는다.</li>
<li>프로그램 병렬성 : 다중 CPU 시스템에서 각 프로세스를 병렬적으로 실행하여 성능을 향상 시킬 수 있다.</li>
<li>시스템 확장성 : 새로운 기능이나 모듈을 추가하거나 수정할 때 다른 프로세스에 영향을 주지 않는다.</li>
</ul>
<h5 id="단점">단점</h5>
<ul>
<li>컨텍스트 스위칭 오버헤드 : 메모리를 공유하지 않기 때문에 컨텍스트 스위칭 과정에서 성능 저하가 올 수 있다.</li>
<li>자원 공유 비효율성 : 독립적인 메모리 공간을 가지기 때문에 결과적으로 메모리 사용량이 증가한다.</li>
</ul>
<blockquote>
<p>컨텍스트 스위칭 오버헤드
컨텍스트 스위칭이 일어나는 과정에서 두 개 이상의 프로세스의 상태(context)를 보관하고 복구하는 과정에서 생기는 간극을 말한다.</p>
</blockquote>
<h2 id="멀티-프로그래밍">멀티 프로그래밍</h2>
<p>하나의 프로그램이 종료되지 않고 I/O 작업을 한다고 해도 쉬지 않고 다음 프로그램을 실행한다. 즉, 입출력이 완료될 때까지 기다리는 시간을 버리지 않고 다른 프로세스를 처리할 수 있도록 해주는 것이다.</p>
<h5 id="특징">특징</h5>
<ul>
<li>멀티 프로그램은 cpu 사용률을 극대화 시키는데 목적이 있다.</li>
</ul>
<h5 id="단점-1">단점</h5>
<ul>
<li>cpu 사용 기간이 길어지면 다른 프로세스는 계속 대기.</li>
</ul>
<h2 id="멀티-태스킹">멀티 태스킹</h2>
<p>프로세스가 한번 cpu를 사용할 때 아주 짧은 시간(quantum)만 cpu에서 실행되도록 한다. 멀티 프로그래밍처럼 동시에 여러 프로그램을 실행시킨다는 면에서는 비슷하지만 cpu 실행 시간을 쪼개서 그 쪼개진 시간 안에서 프로그램들이 번갈아 가면서 실행될 수 있도록 했다는 차이가 있다.</p>
<h5 id="특징-1">특징</h5>
<ul>
<li>프로세스의 응답 시간을 최소화 시키는데 목적이 있다.</li>
</ul>
<h5 id="단점-2">단점</h5>
<ul>
<li>하나의 프로세스가 동시에 여러 작업을 수행하지는 못함.</li>
</ul>
<h1 id="스레드">스레드</h1>
<ul>
<li>프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위.</li>
<li>프로세스는 한 개 이상의 스레드를 가질 수 있다.</li>
<li>cpu에서 실행되는 단위.</li>
<li>같은 프로세스의 스레드들끼리 컨텍스트 스위칭은 가볍다.</li>
<li>스레드들은 자신들이 속한 프로세스의 힙 메모리 영역을 공유</li>
</ul>
<p><img src="https://gmlwjd9405.github.io/images/os-process-and-thread/thread.png" alt="">
(사진 출처 : <a href="https://thsd-stjd.tistory.com/149">https://thsd-stjd.tistory.com/149</a>)</p>
<h2 id="멀티-스레딩">멀티 스레딩</h2>
<p>멀티 태스킹의 확장된 방식으로 동작을 하며 병렬적으로 스레드가 실행되어 동시에 프로그램 실행이 가능하며 여러 프로세스와 여러 스레드가 아주 짧게 쪼개진 cpu time을 나눠 갖는 것을 말한다.</p>
<h5 id="특징-2">특징</h5>
<ul>
<li>하나의 프로세스가 동시에 여러 작업을 실행하는데 목적이 있다.</li>
</ul>
<h5 id="장점-1">장점</h5>
<ul>
<li>프로세스보다 가볍다 : 프로세스 내에서 생성되기 때문에 스레드의 실행 환경을 설정하는 작업이 매우 간단해서 생성 및 종료가 빠르다.</li>
<li>자원의 효율성 : 프로세스 내에서 여러개의 스레드가 생성되기 때문에, 힙 영역의 메모리를 공유 해서 시스템 자원 소모가 줄어든다.</li>
<li>컨텍스트 스위칭 비용 감소 : 프로세스 컨텍스트 스위칭은 메모리를 공유하지 않기 때문에 스위칭을 할 때 메모리 주소를 변환해주고 캐시를 비워주고 새로운 프로세스 정보를 캐시에 담아줘야 하지만 스레드 컨텍스트 스위칭은 스레드간 공유하는 자원을 제외한 스레드 정보만 교체하면 돼서 상대적으로 비용이 낮다.</li>
<li>응답시간 단축 : 프로세스보다 가볍고 오버헤드가 작기 때문에 응답 시간이 빠르다.</li>
</ul>
<h5 id="단점-3">단점</h5>
<ul>
<li>안정성 : 프로세스는 독립적으로 동작하여 하나의 프로세스에 문자가 발생하여도 프로그램이 종료되지 종료되지 않고 계속 동작할 수 있지만, 스레드는 자원을 공유하기 때문에 다른 스레드들도 영향을 받아 프로그램이 종료 될 수 있다.</li>
<li>동기화로 인한 성능 저하 : 동기화 작업으로 동시 수정과 같은 현상을 일어나지 않지만, 여러 스레드들의 접근을 제한하게 되어 병목 현상이 일어나서 성능 저하될 사능성이 높다.</li>
<li>데드락 : 서로 하나의 자원을 점유하여 무한정 기다리게 되는 상황이 발생할 수 있는데 이는 멀티 프로스세도 스레드와 같은 상황이 발생할 수 있다.</li>
<li>컨텍스트 스위칭 오버헤드 : 프로세스 컨텍스트 스위칭 오버헤드보다는 작다고 하지만 그래도 오버헤드 비용을 무시할수는 없다.</li>
<li>디버깅 : 여러 개의 스레드가 동시에 실행되기 때문에 추적하기 어렵고, 어떤 순서로 실행되는지 등을 파악하기 어려울 수 있다.</li>
</ul>
<h1 id="컨텍스트-스위칭">컨텍스트 스위칭</h1>
<p>cpu/코어에서 실행 중이던 프로세스/스레드가 다른 프로세스/스레드로 교체되는 것. 구체적으로 설명하자면, 동작 중인 프로세스가 대기를 하면서 해당 프로세스의 상태(context)를 보관하고, 대기하고 있던 다음 순서의 프로세스가 동작하면서 이전에 보관했던 프로세스의 상태를 복구하는 작업. 컨텍스트란 cpu, 메모리 등에서 프로세스/스레드의 상태를 말한다. </p>
<h3 id="발생">발생</h3>
<p>주어진 time slice(quantum)를 프로세스/스레드가 다 사용했거나, I/O 작업을 해야하거나, 다른 리소스를 기다려야 하거나 등의 이유로 컨텍스트 스위칭이 발생한다. 이 때 컨텍스트 스위칭은 커널모드에서 실행된다.
스위칭이 발생하면 cpu의 레지스터 상태를 교체한다.</p>
<blockquote>
<p>이 때 컨텍스트 스위칭을 실행하는 주체는
OS 커널(Kernel)이 실행한다.
OS 커널은 각종 리소스를 관리/감동하는 역할을 한다.</p>
</blockquote>
<h2 id="프로세스-컨텍스트-스위칭">프로세스 컨텍스트 스위칭</h2>
<p>cpu에서 실행되기 위해 어느 한 프로세스에서 다른 프로세스로 교체되는 것. 프로세스 교체시 서로의 메모리 주소가 다르기 때문에 가상(virtual) 메모리 주소 관련 처리를 추가로 수행해야 한다. 스위칭이 발생하면 MMU(Memory Management Unit)이 새로운 프로세스의 주소를 바라보도록 수정을 하고 캐시 역할을 하는 TLB(Translation Lookaside Buffer)를 비워줘야 한다.</p>
<h2 id="스레드-컨텍스트-스위칭">스레드 컨텍스트 스위칭</h2>
<p>같은 프로세스의 스레드들끼리 스위칭 하는 것이다. 프로세스 컨텍스트 스위칭과는 반대로 스레드는 메모리를 공유하기 때문에 주소를 수정하고 TLB를 비워줘야하는 일련의 작업을 하지 않는다.</p>
<hr>
출처

<p><a href="https://ko.wikipedia.org/wiki/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4">프로세스 위키백과</a>
<a href="https://www.youtube.com/watch?v=QmtYKZC0lMU">쉬운코드 youtube</a>
<a href="https://www.youtube.com/watch?v=Xh9Nt7y07FE">쉬운코드 youtube</a>
<a href="https://inpa.tistory.com/entry/%F0%9F%91%A9%E2%80%8D%F0%9F%92%BB-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%E2%9A%94%EF%B8%8F-%EC%93%B0%EB%A0%88%EB%93%9C-%EC%B0%A8%EC%9D%B4">https://inpa.tistory.com/entry/%F0%9F%91%A9%E2%80%8D%F0%9F%92%BB-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%E2%9A%94%EF%B8%8F-%EC%93%B0%EB%A0%88%EB%93%9C-%EC%B0%A8%EC%9D%B4</a>
<a href="https://gmlwjd9405.github.io/2018/09/14/process-vs-thread.html#google_vignette">https://gmlwjd9405.github.io/2018/09/14/process-vs-thread.html#google_vignette</a>
<a href="https://sorjfkrh5078.tistory.com/56">https://sorjfkrh5078.tistory.com/56</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript / li 태그를 활용한 라디오 버튼 직접 구현 1]]></title>
            <link>https://velog.io/@b-joon/JavaScript-li-%ED%83%9C%EA%B7%B8%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EB%9D%BC%EB%94%94%EC%98%A4-%EB%B2%84%ED%8A%BC-%EC%A7%81%EC%A0%91-%EA%B5%AC%ED%98%84-1</link>
            <guid>https://velog.io/@b-joon/JavaScript-li-%ED%83%9C%EA%B7%B8%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EB%9D%BC%EB%94%94%EC%98%A4-%EB%B2%84%ED%8A%BC-%EC%A7%81%EC%A0%91-%EA%B5%AC%ED%98%84-1</guid>
            <pubDate>Tue, 12 Dec 2023 07:21:43 GMT</pubDate>
            <description><![CDATA[<h3 id="라디오-버튼">라디오 버튼</h3>
<ul>
<li>사용자가 여러 개의 선택지 중 1개만 선택할 수 있다.</li>
<li>옵션 버튼으로 불리기도 한다.</li>
<li>사용자가 잘못된 여러 개의 옵션을 선택하지 못하도록 방지한다.</li>
</ul>
<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRCa5s%2FbtrGWzgCp8E%2FuLCV5PDMEibaOyIOqq3ID1%2Fimg.png" alt=""></p>
<h4 id="직접-구현한-라디오-버튼">직접 구현한 라디오 버튼</h4>
<p>아래의 버튼은 복지관에서 일하는 친구의 부탁으로 구현하게 됐는데요. 아래 사진을 보시면 설문조사를 하는 표입니다. 어르신들의 성별과 나이 등 여러 가지를 조사하고 남자 몇 명 여자 몇 명 나이대 등을 체크해서 합계와 퍼센트를 구하고 프린트가 가능하도록 하는 페이지를 구현하는 것입니다.
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbakfD2%2FbtrGYAlOQLc%2F9jwEQJLADg5mEHUKtxmLaK%2Fimg.png" alt="">
그래서 일반적인 라디오 버튼을 디자인해서 사용하려고 했지만 직접 구현해보고 싶어서 처음부터 하나하나 로직을 구현했습니다.</p>
<blockquote>
<p>li태그 동그라미 숫자 적용</p>
</blockquote>
<p>해당 코드는 다른 분이 작성한 코드를 활용했습니다. 여러가지를 많이 찾아봤지만 제가 원하는 방식으로 노출이 가능해서 위 코드를 적용시켰습니다. 처음에는 png이미지를 이용해서 ui를 구현하려고 했지만 css와 이미지 편집 부분이 시간적으로 오래 걸릴 것 같아서 아래 방식을 선택했습니다.</p>
<h5 id="javascript">Javascript</h5>
<pre><code class="language-javascript">const circled_symbol = [&#39;①&#39;, &#39;②&#39;, &#39;③&#39;, &#39;④&#39;, &#39;⑤&#39;, &#39;⑥&#39;, &#39;⑦&#39;, &#39;⑧&#39;, &#39;⑨&#39;, &#39;⑩&#39;, &#39;⑪&#39;, &#39;⑫&#39;, &#39;⑬&#39;, &#39;⑭&#39;, &#39;⑮&#39;];

const ul_elements = document.getElementsByClassName(&#39;circled&#39;);
Array.prototype.forEach.call(ul_elements, (ul) =&gt; {
    let li_elements = ul.getElementsByTagName(&#39;li&#39;);
    Array.prototype.forEach.call(li_elements, (li, index) =&gt; {
        if (index &lt; circled_symbol.length) {
            li.innerText = circled_symbol[index] + &#39; &#39; + li.innerText;
        }
    });
});</code></pre>
<h5 id="css">CSS</h5>
<pre><code class="language-css">ul.circled-horizontal-left {
    list-style-type: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    margin: 0px;
    padding-left: 2px;
}

ul.circled-horizontal-left &gt; li {
    display: inline-block;
    list-style: none;
    margin: 1px 20px 1px 5px;
}</code></pre>
<blockquote>
<p>li태그 클릭 이벤트</p>
</blockquote>
<p>li 태그 클릭은 Jquery를 사용해서 구현했습니다. 학원에서 JavaScript 보다는 Jquery를 많이 사용해서 좀 더 익숙해서 사용하게 됐어요. JavaScript와 Jquery는 많이 사용하지 않다보니 구글링을 많이 했습니다.</p>
<pre><code class="language-javascript">$(document).ready(function() {
    $(&quot;#page&quot;).on(&quot;click&quot;, &quot;li&quot;, function() {
            console.log(&#39;들어왔니?&#39;);
    });
});</code></pre>
<h4 id="전체-코드">전체 코드</h4>
<p>코드와 변수명이 동작만 할 수 있도록 작성하다보니 많이 TheLove습니다. 아직 값을 저장하는 로직도 없고 css 부분도 수정해야 해요. 동작만 되는 것을 우선으로 작성해서 코드를 보면서 이걸 왜 이렇게 라는 부분이 상당히 많습니다. </p>
<h5 id="javascript-1">Javascript</h5>
<pre><code class="language-javascript">const circled_symbol = [&#39;①&#39;, &#39;②&#39;, &#39;③&#39;, &#39;④&#39;, &#39;⑤&#39;, &#39;⑥&#39;, &#39;⑦&#39;, &#39;⑧&#39;, &#39;⑨&#39;, &#39;⑩&#39;, &#39;⑪&#39;, &#39;⑫&#39;, &#39;⑬&#39;, &#39;⑭&#39;, &#39;⑮&#39;];

const ul_elements = document.getElementsByClassName(&#39;circled&#39;);
Array.prototype.forEach.call(ul_elements, (ul) =&gt; {
    let li_elements = ul.getElementsByTagName(&#39;li&#39;);
    Array.prototype.forEach.call(li_elements, (li, index) =&gt; {
        if (index &lt; circled_symbol.length) {
            li.innerText = circled_symbol[index] + &#39; &#39; + li.innerText;
        }
    });
});

$(document).ready(function () {
    let count = 0;
    $(&quot;.page&quot;).on(&quot;click&quot;, &#39;li&#39;, function () {
        this.className = &#39;a&#39; + count++;

          // 체크된 li 태그를 연속 클릭 시 체크 이미지가 증가되는 것을 방지
        if (this.children.length == 1) {
            let lng = this.children[0].className.length;
            let delClass = this.children[0].className.substring(8, lng)
            $(&#39;.&#39;+delClass+&#39;&#39;).remove()
        }
        //  li 태그에 이미지를 추가해서 동그라미 숫자 위에 체크 표시를 하기 위한 로직입니다.
        let imgTag = document.createElement(&#39;img&#39;);
        let clickLi = $(this);
        imgTag.setAttribute(&#39;src&#39;, &#39;../static/image/ck.png&#39;);
        imgTag.setAttribute(&#39;class&#39;, &#39;checked &#39; + &#39;a&#39; + count++)
        clickLi.append(imgTag);
 // 같은 영역에서 형제들 중 img 태그를 가지고 있으면 img태그를 지움
 let lis = clickLi.siblings();
        for (let i = 0; i &lt; lis.length; i++) {
            if (lis[i].children.length == 1) {
                let alng = lis[i].children[0].className.length;
                let adelClass = lis[i].children[0].className.substring(8, alng)
                $(&#39;.&#39;+adelClass+&#39;&#39;).remove()
            }
        }
    });
});</code></pre>
<h5 id="css-1">CSS</h5>
<pre><code class="language-css">ul.circled-horizontal-left {
    list-style-type: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    margin: 0px;
    padding-left: 2px;
}

ul.circled-horizontal-left &gt; li {
    display: inline-block;
    list-style: none;
    margin: 1px 20px 1px 5px;
}

.checked {
    position: relative;
    text-align: center;
    width: 15px;
    right: 83%;
    bottom: 5px;
}</code></pre>
<h5 id="html">html</h5>
<pre><code class="language-html">&lt;div class=&quot;page&quot; id=&quot;pdfArea&quot;&gt;                
    &lt;table class=&quot;table2&quot;&gt;
        &lt;colgroup&gt;
            &lt;col width=&quot;16%&quot;&gt;
        &lt;/colgroup&gt;
        &lt;tbody&gt;
            &lt;tr&gt;
                &lt;th class=&quot;table-color&quot;&gt;&amp;nbsp;1. 성&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;별&lt;/th&gt;
                &lt;th&gt;
                    &lt;ul class=&quot;circled circled-horizontal-left&quot;&gt;
                        &lt;li&gt;남자&lt;/li&gt;
                        &lt;li&gt;여자&lt;/li&gt;
                    &lt;/ul&gt;
                &lt;/th&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;th class=&quot;table-color&quot;&gt;&amp;nbsp;2. 연&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;령&lt;/th&gt;
                &lt;th&gt;
                    &lt;ul class=&quot;circled circled-horizontal-left&quot;&gt;
                        &lt;li&gt;60세 미만&lt;/li&gt;
                        &lt;li&gt;60~65세&lt;/li&gt;
                        &lt;li&gt;66~70세&lt;/li&gt;
                        &lt;li&gt;71~75세&lt;/li&gt;
                        &lt;li&gt;76~80세&lt;/li&gt;
                        &lt;li&gt;81~85세&lt;/li&gt;
                        &lt;li&gt;86~90세&lt;/li&gt;
                        &lt;li&gt;90세 이상&lt;/li&gt;
                   &lt;/ul&gt;
                &lt;/th&gt;
            &lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
&lt;/div&gt;</code></pre>
<hr>
출처

<p><a href="https://runspace.tistory.com/12">https://runspace.tistory.com/12</a>
<a href="https://doctorson0309.tistory.com/165">https://doctorson0309.tistory.com/165</a>
<a href="https://6u2ni.tistory.com/33">https://6u2ni.tistory.com/33</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[알고리즘 / 버블 정렬]]></title>
            <link>https://velog.io/@b-joon/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%B2%84%EB%B8%94-%EC%A0%95%EB%A0%AC</link>
            <guid>https://velog.io/@b-joon/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%B2%84%EB%B8%94-%EC%A0%95%EB%A0%AC</guid>
            <pubDate>Tue, 12 Dec 2023 07:13:01 GMT</pubDate>
            <description><![CDATA[<h3 id="거품버블정렬">거품/버블정렬</h3>
<p>두 인접한 원소를 검사하여 정렬하는 방법이다.
시간 복잡도가 상당히 느리지만, 코드가 단순하기 때문에 자주 사용된다.
원소의 이동이 커품이 수면으로 올라오는 듯한 모습을 보이기 때문에 지어진 이름이다.</p>
<h4 id="눈으로-보는-버블-정렬">눈으로 보는 버블 정렬</h4>
<p><img src="https://blog.kakaocdn.net/dn/z0qZj/btrFE5m5VRX/MQlZChAXnU5KhxRTgHIIfK/img.gif" alt="알고리즘 도감 / 버블 정렬 하는 과정"></p>
<ul>
<li>해당 사진의 출처는 <a href="https://play.google.com/store/apps/details?id=wiki.algorithm.algorithms&amp;hl=ko&amp;gl=US&amp;pli=1">알고리즘 도감</a>이라는 앱에 있다.</li>
<li>이미지를 보면 두 숫자를 비교해서 차순에 맞게 숫자를 이동 시킨다.</li>
<li>정렬이 끝나게 되면 회색으로 바뀐다.</li>
</ul>
<h4 id="정렬-예제">정렬 예제</h4>
<pre><code class="language-java">public class BubbleSort {

    public static void main(String[] args) {

        int[] nums = {1, 5, 3, 6, 2, 7, 4, 9, 0};

        System.out.println(Arrays.toString(bubbleSort(nums)));

    }

    public static int[] bubbleSort(int[] nums) {

        for (int i = 0; i &lt; nums.length - 1; i++) {
            for (int j = 1; j &lt; nums.length - i; j++) {
                // if (nums[j - 1] &lt; num[j]) {        내림차순
                if (nums[j - 1] &gt; nums[j]) {    //     오름차순
                    int temp = nums[j - 1];
                    nums[j - 1] = nums[j];
                    nums[j] = temp;
                }
            }
        }

        return nums;
    }

}</code></pre>
<hr>
출처

<p><a href="https://ko.wikipedia.org/wiki/%EA%B1%B0%ED%92%88_%EC%A0%95%EB%A0%AC">버블 정렬 위키백과</a>
<a href="https://todaycode.tistory.com/46">https://todaycode.tistory.com/46</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[알고리즘 / 재귀 함수]]></title>
            <link>https://velog.io/@b-joon/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9E%AC%EA%B7%80-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@b-joon/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9E%AC%EA%B7%80-%ED%95%A8%EC%88%98</guid>
            <pubDate>Tue, 12 Dec 2023 07:08:41 GMT</pubDate>
            <description><![CDATA[<h3 id="재귀recursion">재귀(Recursion)</h3>
<p>컴퓨터 과학에 있어서 재귀는 자신을 정의할 때 자기 자신을 재 참조하는 방법을 뜻함.
프로그래밍에 재귀 호출(Recursion call)의 형태로 많이 사용된다.</p>
<h4 id="재귀-함수recursion-function">재귀 함수(Recursion Function)</h4>
<ul>
<li>함수에서 자기 자신을 다시 호출해 작업을 수행하는 방식</li>
<li>특정 분기까지 자기 자신을 계속해서 호출한다.</li>
<li>반복문을 사용하는 코드는 항상 재귀 함수를 통해 구현하는 것이 가능하며 반대도 가능하다.</li>
<li>재귀함수 작성 유의 사항<ul>
<li>함수 내에서 다시 자신을 호출한 후 그 함수가 끝날 때까지 함수 호출 이후의 명령문이 수행되지 않는다</li>
<li>종료 조건이 꼭 포함되어야 무한루프를 방지할 수 있다.</li>
</ul>
</li>
</ul>
<h5 id="장점">장점</h5>
<ul>
<li>변수 사용을 줄여주어 mutable state가 취할 수 있는 경우의 수를 줄여준다.</li>
<li>코드를 효율적으로 짤 수 있다.</li>
<li>함수를 단순하게 만들고, 불변적으로 유지될 수 있도록 만든다.</li>
</ul>
<h5 id="단점">단점</h5>
<ul>
<li>속도가 느리다.<ul>
<li>지속적으로 함수를 호출하게 되면서 지역변수, 매개변수, 반환 값을 모두 process stack에 저장해야 해서 선언한 변수의 값만 사용하는 반복문에 비해서 메모리를 더 많이 사용하게 된다.</li>
</ul>
</li>
<li>함수 호출<ul>
<li>복귀를 위한 콘텍스트 스위칭에 비용이 발생하게 된다.
(콘텍스트 스위칭 : 멀티 프로세스 환경에서 CPU가 어떤 하나의 프로세스를 실행하고 있는 상태에서 인터럽트 요청에 의해 다음 우선순위의 프로세스가 실행되어야 할 때 기존의 프로세스의 상태 또는 레지스터 값(Context)을 저장하고 CPU가 다음 프로세스를 수행하도록 새로운 프로세스의 상태 또는 레지스터 값을 교체하는 작업)</li>
</ul>
</li>
<li>종료 조건을 넣지 않으면 Stack Overflow가 발생한다.</li>
</ul>
<h4 id="재귀-함수-예제">재귀 함수 예제</h4>
<p>최대공약수를 유클리드 호제법을 사용한 재귀 함수</p>
<pre><code class="language-java">public class Recursion {

    public static void main(String[] args) {

        int num1 = 3;
        int num2 = 12;

        System.out.println(gcd(num1, num2));

    }

    public static int gcd(int num1, int num2) {
        if (num2 != 0) {
            return num1;
        }
        return gcd(num1, num1 % num2);
    }

}</code></pre>
<blockquote>
<p>반복문으로 변경</p>
</blockquote>
<pre><code class="language-java">public class Recursion {

    public static void main(String[] args) {

        int num1 = 3;
        int num2 = 12;

        System.out.println(gcdWhile(num1, num2));

    }

    public static int gcdWhile(int num1, int num2) {

        while (num2 != 0) {
            int temp = num1 % num2;
            num1 = num2;
            num2 = temp;
        }
        return num1;
    }

}</code></pre>
<hr>
출처

<p><a href="https://catsbi.oopy.io/dbcc8c79-4600-4655-b2e2-b76eb7309e60">https://catsbi.oopy.io/dbcc8c79-4600-4655-b2e2-b76eb7309e60</a>
<a href="https://ko.wikipedia.org/wiki/%EC%9E%AC%EA%B7%80_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EA%B3%BC%ED%95%99)">위키백과 재귀</a>
<a href="https://gomguard.tistory.com/111">https://gomguard.tistory.com/111</a>
<a href="https://applefarm.tistory.com/105">https://applefarm.tistory.com/105</a>
<a href="https://velog.io/@tilsong/%EC%9E%AC%EA%B7%80-%ED%95%A8%EC%88%98%EB%8A%94-%EC%96%B8%EC%A0%9C-%EC%8D%A8%EC%95%BC-%ED%95%A0%EA%B9%8C">https://velog.io/@tilsong/%EC%9E%AC%EA%B7%80-%ED%95%A8%EC%88%98%EB%8A%94-%EC%96%B8%EC%A0%9C-%EC%8D%A8%EC%95%BC-%ED%95%A0%EA%B9%8C</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA / 객체 간의 상속]]></title>
            <link>https://velog.io/@b-joon/JAVA-%EA%B0%9D%EC%B2%B4-%EA%B0%84%EC%9D%98-%EC%83%81%EC%86%8D</link>
            <guid>https://velog.io/@b-joon/JAVA-%EA%B0%9D%EC%B2%B4-%EA%B0%84%EC%9D%98-%EC%83%81%EC%86%8D</guid>
            <pubDate>Tue, 12 Dec 2023 07:00:24 GMT</pubDate>
            <description><![CDATA[<h3 id="상속">상속</h3>
<ul>
<li>상속이란 기존 클래스의 변수와 메서드를 물려받아 새로운 클래스(더 나은, 더 구체적인 클래스)를 구성하는 것을 의미함.</li>
<li>이러한 상속은 캡슐화, 추상화, 다형성과 더불어 객체지향 프로그래밍을 구성하는 특징 중 하나.</li>
<li>예시로 현실세계에서 부모의 생물학적 특성을 자식이 물려받는 유전과 비슷하다 볼 수 있다.</li>
</ul>
<h5 id="장점">장점</h5>
<ul>
<li>기존 클래스의 변수와 코드를 재사용할 수 있어 개발 시간이 단축된다.</li>
<li>먼저 작성된 검증된 프로그램을 재사용하기 때문에 신뢰성 있는 프로그램을 개발할 수 있다.</li>
<li>클래스 간 계층적 분류 및 관리가 가능하여 유지보수가 용이하다.</li>
</ul>
<h5 id="단점">단점</h5>
<ul>
<li>자바에서는  클래스의 다중 상속을 지원하지 않는다.</li>
<li>자바에서는 상속의 횟수에 제한을 두지 않는다.</li>
<li>자바에서는 계층구조의 최상위에 java.lang.Object 클래스가 있다.</li>
</ul>
<h4 id="클래스-상속">클래스 상속</h4>
<ul>
<li>새로운 클래스를 정의할 때 이미 구현된 클래스를 상속(inheritance) 받아서 속성이나 기능을 확장하여 클래스를 구현함</li>
<li>이미 구현된 클래스보다 더 구체적인 이능을 가진 클래스를 구현해야 할 때 기존 클래스를 상속함</li>
<li>상속하는 클래스 : 상위 클래스, parent class, base class, super class</li>
<li>상속받는 클래스 : 하위 클래스, child class, derived class, sub class</li>
</ul>
<h5 id="상속-구현">상속 구현</h5>
<ul>
<li>상위 클래스는 하위 클래스 보다 더 일반적인 개념과 기능을 가짐</li>
<li>하위 클래스는 상위 클래스 보다 더 구체적인 개념과 기능을 가짐</li>
<li>하위 클래스가 상위 클래스의 속성과 기능을 확장(extends) 한다는 의미</li>
</ul>
<h5 id="상속-선언">상속 선언</h5>
<ul>
<li>상속을 선언할 때는 extends 키워드를 사용한다.</li>
<li>extends 키워드 뒤에는 단 하나의 클래스만 올 수 있음</li>
<li>public class Human extends Mammal {}</li>
</ul>
<h4 id="상속-예제">상속 예제</h4>
<p>회사에서 고객 정보를 활용한 맞춤 서비스를 하기 위해 일반 고객(customer)과 이보다 충성도가 높은 우수고객(VIPCustomer)에 따른 서비스를 제공하고자 함
물품을 구매 할때 적용되는 할인율과 적용되는 보너스 포인트와 비율이 다름
여러 맴버십에 대한 각각 다양한 서비스를 제공할 수 있음
멤버십에 대한 구현을 클래스 상속을 활용하여 구현해보기</p>
<h5 id="일반-고객">일반 고객</h5>
<ul>
<li>고객의 속성 : 고객 아이디, 고객 이름, 고객 등급, 보너스 포인트, 보너스 포인트 적합 비율</li>
<li>일반 고객의 경우 물품 구매 시 1%의 보너스 포인트 적립</li>
</ul>
<pre><code class="language-java">public class Customer {

    protected int customerId;
    protected String customerName;
    protected String customerGrade;
    int bonusPoint;
    double bonusRatio;

    public Customer() {
        customerGrade = &quot;SILVER&quot;;
        bonusRatio = 0.01;
    }

    public int calcPrice(int price) {
        bonusPoint += price * bonusRatio;
        return price;
    }

    public int getCustomerId() {
        return customerId;
    }

    public void setCustomerId(int customerId) {
        this.customerId = customerId;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public String getCustomerGrade() {
        return customerGrade;
    }

    public void setCustomerGrade(String customerGrade) {
        this.customerGrade = customerGrade;
    }

    public String showCustomerInfo() {
        return customerName + &quot;님의 등급은&quot; + customerGrade + &quot;이며, 보너스 포인트는 &quot; + bonusPoint + &quot;입니다.&quot;;
    }

}</code></pre>
<blockquote>
<p>protected 접근 제어자</p>
</blockquote>
<ul>
<li>외부 클래스는 접근할 수 없지만, 하위 클래스는 접근할 수 있도록 protected 접근 제어자를 사용</li>
<li>protected 멤버는 부모 클래스에 대해서는 public 멤버처럼 취급되며, 외부에서는 private 멤버처럼 취급</li>
<li>접근할 수 있는 영역<ul>
<li>이 멤버를 선언한 클래스의 멤버</li>
<li>이 멤버를 선언한 클래스가 속한 패키지의 멤버</li>
<li>이 멤버를 선언한 클래스를 상속받은 자식 클래스(child class)의 멤버</li>
</ul>
</li>
</ul>
<h5 id="우수-고객">우수 고객</h5>
<ul>
<li>Customer 클래스에 추가해서 구현하는 것은 좋지 않음</li>
<li>VIPCustomer 클래스를 따로 구현</li>
<li>이미 Customer에 구현된 내용이 중복되므로 Customer를 확장하여 구현함(상속)</li>
</ul>
<pre><code class="language-java">public class VIPCustomer extends Customer{

    private String agentId;
    double saleRatio;

    public VIPCustomer() {
        bonusRatio = 0.05;
        saleRatio = 0.1;
        customerGrade = &quot;VIP&quot;;
    }

    public String getAgentId() {
        return agentId;
    }

}</code></pre>
<h5 id="일반-고객-우수고객-테스트">일반 고객 우수고객 테스트</h5>
<pre><code class="language-java">public class CustomerTest {

    public static void main(String[] args) {

        Customer customerLee = new Customer();

        customerLee.setCustomerName(&quot;이순신&quot;);
        customerLee.setCustomerId(10010);
        customerLee.bonusPoint = 1000;
        System.out.println(customerLee.showCustomerInfo());

        VIPCustomer customerKim = new VIPCustomer();

        customerKim.setCustomerName(&quot;김유신&quot;);
        customerKim.setCustomerId(10020);
        customerKim.bonusPoint = 10000;
        System.out.println(customerKim.showCustomerInfo());

    }

}</code></pre>
<pre><code>이순신 님의 등급은 SILVER이며, 보너스 포인트는 1000입니다.
김유신 님의 등급은 VIP이며, 보너스 포인트는 10000입니다.</code></pre><hr>
출처

<p><a href="https://danmilife.tistory.com/21">https://danmilife.tistory.com/21</a>
<a href="http://www.tcpschool.com/java/java_modifier_accessModifier">http://www.tcpschool.com/java/java_modifier_accessModifier</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA / 객체 배열을 구현한 클래스 ArrayList]]></title>
            <link>https://velog.io/@b-joon/JAVA-%EA%B0%9D%EC%B2%B4-%EB%B0%B0%EC%97%B4%EC%9D%84-%EA%B5%AC%ED%98%84%ED%95%9C-%ED%81%B4%EB%9E%98%EC%8A%A4-ArrayList</link>
            <guid>https://velog.io/@b-joon/JAVA-%EA%B0%9D%EC%B2%B4-%EB%B0%B0%EC%97%B4%EC%9D%84-%EA%B5%AC%ED%98%84%ED%95%9C-%ED%81%B4%EB%9E%98%EC%8A%A4-ArrayList</guid>
            <pubDate>Tue, 12 Dec 2023 06:53:21 GMT</pubDate>
            <description><![CDATA[<h3 id="arraylist">ArrayList</h3>
<ul>
<li>ArrayList란 Collection 프레임워크의 일부이며 java.util 패키지에 소속되어 있다.</li>
<li>표준 배열보다는 느리지만 배열에서 많은 조작이 필요한 경우 유용하게 사용할 수 있다.</li>
<li>List 인터페이스에서 상속받아 사용이 된다.</li>
<li>저장 용량(capacity)이 가변적으로 변하는 선형 리스트이다.</li>
<li>이미 많은 메서드들이 최적의 알고리즘으로 구현되어 있어 각 메서드의 사용 방법만 익히면 유용하게 사용할 수 있다.</li>
</ul>
<h4 id="주요-메서드">주요 메서드</h4>
<ul>
<li>boolean add(E e) : 요소 하나를 배열에 추가합니다. E는 요소의 자료형을 의미합니다.</li>
<li>int size() : 배열에 추가된 요소 전체 개수를 반환합니다.</li>
<li>E get(int index) : 배열의 index 위치에 있는 요소 값을 반환합니다.</li>
<li>E remove(int index) : 배열의 index 위치에 있는 요소 값을 제거하고 그 값을 반환합니다.</li>
<li>boolean isEmpty() : 배열이 비어 있는지 확인합니다.</li>
</ul>
<h4 id="예제">예제</h4>
<pre><code class="language-java">import java.util.ArrayList;
import ch21.Book;

public class ArrayListTest {

    public static void main(String[] args) {

        // ArrayList() 선언 방법 (java.util.ArrayList 를 import 해줘야 한다.)
        ArrayList&lt;Book&gt; library = new ArrayList&lt;&gt;(); // 배열의 default size는 10이다.

        // ArrayList에 값을 추가 하는 방법
        library.add(new Book(&quot;태백산맥1&quot;, &quot;조형래&quot;));
        library.add(new Book(&quot;태백산맥2&quot;, &quot;조형래&quot;));
        library.add(new Book(&quot;태백산맥3&quot;, &quot;조형래&quot;));
        library.add(new Book(&quot;태백산맥4&quot;, &quot;조형래&quot;));
        library.add(new Book(&quot;태백산맥5&quot;, &quot;조형래&quot;));

        // library.size() 는 library의 크기
        for (int i = 0; i &lt; library.size(); i++) {
            //library.get(index) : 해당 배열의 값 호출
            library.get(i).showInfo();
        }

    }

}</code></pre>
<p><spen style="color: red"><strong>
★ 제네릭에는 선언할 수 있는 타입이 객체 타입이다. int는 기본자료형이기 때문에 들어갈 수 없으므로 객체화시킨 Wrapper Clas를 사용해야 한다.
</strong></spen></p>
<p><code>ex) ArrayList&lt;Integer&gt; nums = new ArrayList&lt;&gt;();</code></p>
<hr>
출처

<p><a href="https://crazykim2.tistory.com/558">https://crazykim2.tistory.com/558</a>
<a href="https://shpk333.tistory.com/10">https://shpk333.tistory.com/10</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA / 객체 배열 사용하기]]></title>
            <link>https://velog.io/@b-joon/JAVA-%EA%B0%9D%EC%B2%B4-%EB%B0%B0%EC%97%B4-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@b-joon/JAVA-%EA%B0%9D%EC%B2%B4-%EB%B0%B0%EC%97%B4-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 12 Dec 2023 06:36:51 GMT</pubDate>
            <description><![CDATA[<h3 id="객체-배열-선언과-구현">객체 배열 선언과 구현</h3>
<p>기본 자료형 배열은 선언과 동시에 배열의 크기만큼의 메모리가 할당되지만, 객체 배열의 경우엔 요소가 되는 객체의 주소가 들어갈(4바이트, 8바이트) 메모리만 할당되고(null) 각 요소 객체는 생성하여 저장해야 함</p>
<table style="border-collapse: collapse; width: 100%;" border="1" data-ke-align="alignLeft" data-ke-style="style9">
<tbody>
<tr>
<td style="width: 20%; text-align: center;">library[0]</td>
<td style="width: 20%; text-align: center;">library[1]</td>
<td style="width: 20%; text-align: center;">library[2]</td>
<td style="width: 20%; text-align: center;">library[3]</td>
<td style="width: 20%; text-align: center;">library[4]</td>
</tr>
<tr>
<td style="width: 20%; text-align: center;">null</td>
<td style="width: 20%; text-align: center;">null</td>
<td style="width: 20%; text-align: center;">null</td>
<td style="width: 20%; text-align: center;">null</td>
<td style="width: 20%; text-align: center;">null</td>
</tr>
</tbody>
</table>

<h4 id="객체-배열-예제">객체 배열 예제</h4>
<pre><code class="language-java">public class Book {

    private String title;
    private String author;

    public Book() {

    }

    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }

    public void showInfo() {
        System.out.println(title + &quot;,&quot; + author);
    }

}

------------------------------------------------

public class BookTest {

    public static void main(String[] args) {

        // 객체 배열 선언 및 객체 초기화
        Book[] library = new Book[5]; // 선언을 해줘도 책이 5개 잡히는게 아니다.

//        for (int i = 0; i &lt; library.length; i++) {
//            System.out.println(library[i]);
//        }

        // 객체 초기화 후 정보 입력
        library[0] = new Book(&quot;태백산맥1&quot;, &quot;조정래&quot;);
        library[1] = new Book(&quot;태백산맥2&quot;, &quot;조정래&quot;);
        library[2] = new Book(&quot;태백산맥3&quot;, &quot;조정래&quot;);
        library[3] = new Book(&quot;태백산맥4&quot;, &quot;조정래&quot;);
        library[4] = new Book(&quot;태백산맥5&quot;, &quot;조정래&quot;);

        for (Book book : library) {
            // 객체 주소 값 확인
            System.out.println(book);
            // 객체 값 확인
            book.showInfo();
        }

    }

}</code></pre>
<pre><code>ch21.Book@2a139a55
태백산맥1,조정래
ch21.Book@15db9742
태백산맥2,조정래
ch21.Book@6d06d69c
태백산맥3,조정래
ch21.Book@7852e922
태백산맥4,조정래
ch21.Book@4e25154f
태백산맥5,조정래</code></pre><h3 id="객체-배열-복사">객체 배열 복사</h3>
<ul>
<li>System.arrayCopy(src, srcPos, dest, destPos, length) 지바에서 제공되는 배열 복사 메서드</li>
</ul>
<h4 id="얕은-복사">얕은 복사</h4>
<ul>
<li>객체 주소만 복사되어 한쪽 배열의 요소를 수정하면 같이 수정됨
(하나의 주소 값을 가지고 있으므로 하나라고 볼 수 있다.)</li>
<li>두 배열이 같은 객체를 가리킴</li>
</ul>
<h5 id="얕은-복사-예제">얕은 복사 예제</h5>
<pre><code class="language-java">public class ObjectCopyTest {

    public static void main(String[] args) {

        Book[] library = new Book[5];

        Book[] copyLibrary = new Book[5];

        library[0] = new Book(&quot;태백산맥1&quot;, &quot;조정래&quot;);
        library[1] = new Book(&quot;태백산맥2&quot;, &quot;조정래&quot;);
        library[2] = new Book(&quot;태백산맥3&quot;, &quot;조정래&quot;);
        library[3] = new Book(&quot;태백산맥4&quot;, &quot;조정래&quot;);
        library[4] = new Book(&quot;태백산맥5&quot;, &quot;조정래&quot;);

        System.arraycopy(library, 0, copyLibrary, 0, 5);

        System.out.println(&quot;=== library ===&quot;);
        for (Book book : library) {
            System.out.println(book);
            book.showInfo();
        }

        System.out.println(&quot;=== copyLibrary ===&quot;);
        for (Book book : copyLibrary) {
            System.out.println(book);
            book.showInfo();
        }

        library[0].setAuthor(&quot;박완서&quot;);
        library[0].setTitle(&quot;나목&quot;);

        System.out.println(&quot;=== changeLibrary ===&quot;);
        for (Book book : library) {
            System.out.println(book);
            book.showInfo();
        }

        System.out.println(&quot;=== changeCopyLibrary ===&quot;);
        for (Book book : copyLibrary) {
            System.out.println(book);
            book.showInfo();
        }
    }

}</code></pre>
<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbLQXz%2FbtrFg6felqd%2FR4nAZaHsHBheiXLvFN6Z2K%2Fimg.png" alt=""></p>
<ul>
<li>library[0]번째 값을 바꾸면 copyLibrary[0]번째 값도 바뀌는 것을 볼 수 있다.</li>
</ul>
<h4 id="깊은-복사">깊은 복사</h4>
<ul>
<li>각각의 객체를 생성하여 그 객체의 값을 복사하여 배열이 서로 다른 객체를 가리키도록 함</li>
</ul>
<h5 id="깊은-복사-예제">깊은 복사 예제</h5>
<pre><code class="language-java">public class DeepCopyTest {

    public static void main(String[] args) {

        Book[] library = new Book[5]; // 선언을 해줘도 책이 5개 잡히는게 아니다.

        Book[] copyLibrary = new Book[5];

        library[0] = new Book(&quot;태백산맥1&quot;, &quot;조정래&quot;);
        library[1] = new Book(&quot;태백산맥2&quot;, &quot;조정래&quot;);
        library[2] = new Book(&quot;태백산맥3&quot;, &quot;조정래&quot;);
        library[3] = new Book(&quot;태백산맥4&quot;, &quot;조정래&quot;);
        library[4] = new Book(&quot;태백산맥5&quot;, &quot;조정래&quot;);

        copyLibrary[0] = new Book();
        copyLibrary[1] = new Book();
        copyLibrary[2] = new Book();
        copyLibrary[3] = new Book();
        copyLibrary[4] = new Book();

        for (int i = 0; i &lt; library.length; i++) {
            copyLibrary[i].setAuthor(library[i].getAuthor());
            copyLibrary[i].setTitle(library[i].getTitle());
        }

        System.out.println(&quot;=== library ===&quot;);
        for (Book book : library) {
            System.out.println(book);
            book.showInfo();
        }

        System.out.println(&quot;=== copyLibrary ===&quot;);
        for (Book book : copyLibrary) {
            System.out.println(book);
            book.showInfo();
        }

        library[0].setAuthor(&quot;박완서&quot;);
        library[0].setTitle(&quot;나목&quot;);

        System.out.println(&quot;=== changeLibrary ===&quot;);
        for (Book book : library) {
            System.out.println(book);
            book.showInfo();
        }

        System.out.println(&quot;=== changeCopyLibrary ===&quot;);
        for (Book book : copyLibrary) {
            System.out.println(book);
            book.showInfo();
        }

    }

}</code></pre>
<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVgPGJ%2FbtrE8TnXLzh%2FIOkgdJnKrAeKT2hxHZNv9K%2Fimg.png" alt=""></p>
<ul>
<li>바뀐 결과 값을 보면 chargeCopyLibrary의 값은 변화 없고 주소 값은 달라진 것을 확인할 수 있다.</li>
</ul>
<hr>
출처

<p><a href="https://coding-factory.tistory.com/548">https://coding-factory.tistory.com/548</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA / static 응용 - 싱글톤 패턴(singleton pattern)]]></title>
            <link>https://velog.io/@b-joon/JAVA-static-%EC%9D%91%EC%9A%A9-%EC%8B%B1%EA%B8%80%ED%86%A4-%ED%8C%A8%ED%84%B4singleton-pattern</link>
            <guid>https://velog.io/@b-joon/JAVA-static-%EC%9D%91%EC%9A%A9-%EC%8B%B1%EA%B8%80%ED%86%A4-%ED%8C%A8%ED%84%B4singleton-pattern</guid>
            <pubDate>Tue, 12 Dec 2023 06:32:58 GMT</pubDate>
            <description><![CDATA[<h3 id="싱글톤-패턴">싱글톤 패턴</h3>
<ul>
<li>프로그램에서 객체의 인스턴스가 단 한 개만 생성되어야 하는 경우 사용하는 디자인 패턴</li>
<li>static변수, 메서드를 활용하여 구현할 수 있음</li>
<li>생성자의 호출이 반복적으로 이뤄져도 실제로 생성되는 객체는 최초 생성된 객체를 반환해 주는 것</li>
</ul>
<h4 id="사용-이유">사용 이유</h4>
<ul>
<li>한 번의 객체 생성으로 재 사용이 가능하기 때문에 메모리 낭비를 방지할 수 있다.</li>
<li>다른 클래스 간에 데이터 공유가 쉽다.</li>
<li>도메인 관점에서 인스턴스가 한 개만 존재하는 것을 보증하고 싶은 경우 사용한다.</li>
</ul>
<h4 id="문제점">문제점</h4>
<ul>
<li>객체의 역할이 복잡한 경우 싱글톤 객체를 사용하는 다른 객체 간의 결함도가 높아져서 객체 지향 설계 원칙에 어긋난다.</li>
<li>패턴을 구현하는 코드 자체가 많이 필요하다.<ul>
<li>정적 팩토리 메서드에서 객체 생성을 확인하고 생성자를 호출하는 경우 멀티 스레딩 환경에서 발생할 수 있는 동시성 문제 해결을 위해 syncronized 키워드를 사용해야 함.</li>
</ul>
</li>
<li>테스트 하기 어렵다.<ul>
<li>애플리케이션 전역에서 상태를 공유하기 때문에 격리된 환경에서 수행되려면 매번 인스턴스의 상태를 초기화시켜주어야 한다.</li>
</ul>
</li>
<li>의존 관계상 클라이언트가 구체 클래스에 의존하게 된다.<ul>
<li>new 키워드를 직접 사용하여 클래스 안에서 객체를 생성하고 있으므로, 이는 SOLID원칙 중 DIP를 위반하게 되고 OCP 원칙 또한 위반할 가능성이 높다.</li>
</ul>
</li>
</ul>
<h4 id="싱글톤-패턴-예제">싱글톤 패턴 예제</h4>
<pre><code class="language-java">public class Company {

     // 클래스 내부에 유일한 private 인스턴스 생성
    private static Company instance = new Company();

    // 생성자는 private로 선언
    private Company() {
    }

    // 외부에서 유일한 인스턴스를 참조할 수 있는 public 메서드 제공
    public static Company getInstance() {

        if (instance == null) {
            instance = new Company();
        }

        return instance;
    }

}

-----------------------------------------------------------

public class CompanyTest {

    public static void main(String[] args) {

        Company company1 = Company.getInstance();
        Company company2 = Company.getInstance();

        System.out.println(company1);
        System.out.println(company2);

//        Calendar cal = Calendar.getInstance();
    }

}</code></pre>
<hr>
출처

<p><a href="https://tecoble.techcourse.co.kr/post/2020-11-07-singleton/">https://tecoble.techcourse.co.kr/post/2020-11-07-singleton/</a>
<a href="https://elfinlas.github.io/2019/09/23/java-singleton/">https://elfinlas.github.io/2019/09/23/java-singleton/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA / static 메서드]]></title>
            <link>https://velog.io/@b-joon/JAVA-static-%EB%A9%94%EC%84%9C%EB%93%9C</link>
            <guid>https://velog.io/@b-joon/JAVA-static-%EB%A9%94%EC%84%9C%EB%93%9C</guid>
            <pubDate>Tue, 12 Dec 2023 06:19:28 GMT</pubDate>
            <description><![CDATA[<h3 id="static-메서드">static 메서드</h3>
<ul>
<li>static 메서드는 객체의 생성 없이 호출이 가능</li>
<li>객체에서는 호출이 가능하지만 지양한다.</li>
<li>일반적으로 유틸리티 관련 함수는 static 메서드로 구현하는 것이 적합</li>
<li>대표적인 Util Class는 java.util.Math가 있다.</li>
</ul>
<h4 id="static-메서드class-mathod에서는-인스턴스-변수를-사용할-수-없다">static 메서드(Class Mathod)에서는 인스턴스 변수를 사용할 수 없다.</h4>
<ul>
<li>static 메서드는 인스턴스 생성과 무관하게 클래스 이름으로 호출 될 수 있음</li>
<li>인스턴스 생성 전에 호출 될 수 있으므로 static 메서드 내부에서는 인스턴스 변수의 사용을 허용하지 않음</li>
<li>인스턴스 변수 · 메서드에선 static이 붙은 멤버들을 사용하는 것은 가능하다.</li>
</ul>
<h4 id="변수의-유효-범위와-메모리">변수의 유효 범위와 메모리</h4>
<ul>
<li>변수의 유효 범위(scope)와 생성과 소멸(life cycle)은 각 변수의 종류마다 다름</li>
<li>지역변수, 멤버 변수,  클래스 변수는 유효 범위와 life cycle, 사용하는 메모리도 다름</li>
</ul>
<table style="border-collapse: collapse; width: 100%; height: 220px;" border="1" data-ke-align="alignCenter" data-ke-style="style9">
<tbody>
<tr style="height: 20px;">
<td style="width: 15%; text-align: center; height: 20px;">변수 유형</td>
<td style="width: 15%; text-align: center; height: 20px;">선언 위치</td>
<td style="width: 23%; text-align: center; height: 20px;">사용 범위</td>
<td style="width: 15%; text-align: center; height: 20px;">메모리</td>
<td style="width: 23%; text-align: center; height: 20px;">생성과 소멸</td>
</tr>
<tr style="height: 40px;">
<td style="width: 15%; text-align: center; height: 40px;">지역 변수<br>(로컬 변수)</td>
<td style="width: 15%; height: 40px;">함수 내부에 선언</td>
<td style="width: 23%; height: 40px;">함수 내부에서만 사용</td>
<td style="width: 15%; height: 40px;">스택</td>
<td style="width: 23%; height: 40px;">함수가 호출될 때 생성되고 함수가 끝나면 소멸함</td>
</tr>
<tr style="height: 80px;">
<td style="width: 15%; text-align: center; height: 80px;">멤버 변수<br>(인스턴스 변수)</td>
<td style="width: 15%; height: 80px;">클래스 멤버 변수로 선언</td>
<td style="width: 23%; height: 80px;">클래스 내부에서 사용하고 private이 아니면 참조 변수로 다른 클래스에서 사용 가능</td>
<td style="width: 15%; height: 80px;">힙</td>
<td style="width: 23%; height: 80px;">인스턴스가 생성될 때 힙에 생성되고, Garbage Collector가 메모리를 수거할 때 소멸 됨</td>
</tr>
<tr style="height: 80px;">
<td style="width: 15%; text-align: center; height: 80px;">static 변수<br>(클래스 변수)</td>
<td style="width: 15%; height: 80px;">static 예약어를 사용하여 클래스 내부에 선언</td>
<td style="width: 23%; height: 80px;">클래스 내부에서 사용하고 private이 아니면 클래스 이름으로 다른 클래스에서 사용 가능</td>
<td style="width: 15%; height: 80px;">데이터<br>영역</td>
<td style="width: 23%; height: 80px;">프로그램이 처음 시작할 때 상수와 함께 데이터 영역에 생성되고 프로그램이 끝나고 메모리를 해제할 때 소멸 됨</td>
</tr>
</tbody>
</table>

<ul>
<li>static 변수는 프로그램이 메모리에 있는 동안 계속 그 영역을 차지하므로 너무 큰 메모리를 할당하는 것은 좋지 않음</li>
<li>클래스 내부의 여러 메서드에서 사용하는 변수는 멤버 변수로 선언하는 것이 좋음</li>
<li>멤버 변수가 너무 많으면 인스턴스 생성 시 쓸대없는 메모리가 할당됨</li>
<li>상황에 적절하게 변수를 사용해야 함</li>
</ul>
<hr>
출처

<p><a href="https://mangkyu.tistory.com/47">https://mangkyu.tistory.com/47</a>
<a href="https://dev-coco.tistory.com/23">https://dev-coco.tistory.com/23</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA / static 변수]]></title>
            <link>https://velog.io/@b-joon/JAVA-static-%EB%B3%80%EC%88%98</link>
            <guid>https://velog.io/@b-joon/JAVA-static-%EB%B3%80%EC%88%98</guid>
            <pubDate>Tue, 12 Dec 2023 06:08:36 GMT</pubDate>
            <description><![CDATA[<h3 id="static-변수">static 변수</h3>
<ul>
<li>static 키워드를 통해 생성된 정적멤버는 static 메모리 영역에 할당된다.</li>
<li>static 메모리 영역에 할당된 모든 객체는 공유되어 하나의 멤버를 어디서든지 참조할 수 있다.</li>
<li>Garbage Collector의 관리 영역 밖에 존재해 static 영역에 있는 멤버들은 프로그램이 종료 될때까지 메모리가 할당된 상태로 존재한다.</li>
<li>static을 남발하면 시스템 성능에 악영향을 줄 수 있다.</li>
<li>static 변수는 클래스 변수이다.</li>
<li>객체를 생성하지 않아도 static 자원에 접근이 가능하다.</li>
</ul>
<h4 id="공통으로-사용하는-변수가-필요한-경우">공통으로 사용하는 변수가 필요한 경우</h4>
<ul>
<li>여러 인스턴스가 공유하는 기준 값이 필요한 경우</li>
<li>학생마다 새로운 학번 생성</li>
<li>카드회사에서 카드를 새로 발급할때마다 새로운 카드 번호를 부여</li>
<li>회사에 사원이 입사할때 마다 새로운 사번이 필요한 경우</li>
</ul>
<h4 id="static-변수-선언과-사용하기">static 변수 선언과 사용하기</h4>
<p>static int serialNum;</p>
<ul>
<li>인스턴스가 생성될 때 만들어지는 변수가 아닌, 처음 프로그램이 메모리에 로딩될 때 메모리를 할당</li>
<li>클래스 변수, 정적변수라고도 함 (인스턴스 변수)</li>
<li>인스턴스 생성과 상관없이 사용 가능하므로 클래스 이름으로 직접 참조</li>
</ul>
<p>Student serialNum = 100;</p>
<h5 id="static-변수-예제-1">static 변수 예제 1</h5>
<pre><code class="language-java">public class Employee {

    public static int serialNum = 1000;

    private int employeeId;
    private String employeeName;
    private String department;

    public int getEmployeeId() {
        return employeeId;
    }
    public void setEmployeeId(int employeeId) {
        this.employeeId = employeeId;
    }
    public String getEmployeeName() {
        return employeeName;
    }
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }
    public String getDepartment() {
        return department;
    }
    public void setDepartment(String department) {
        this.department = department;
    }

}

---------------------------------------------------

public class EmployeeTest {

    public static void main(String[] args) {

        Employee employeeLee = new Employee();
        employeeLee.setEmployeeName(&quot;이순신&quot;);

        System.out.println(employeeLee.serialNum);

        Employee employeeKim = new Employee();
        employeeKim.setEmployeeName(&quot;김유신&quot;);
        employeeKim.serialNum++;

        System.out.println(employeeLee.serialNum);
        System.out.println(employeeKim.serialNum);

    }

}</code></pre>
<ul>
<li>employeeLee.serialNum =&gt; 1000</li>
<li>employeeLee.serialNum =&gt; 1001</li>
<li>employeeKim.serialNum =&gt; 1001</li>
</ul>
<h5 id="static-변수-예제-2">static 변수 예제 2</h5>
<pre><code class="language-java">public class Employee {

    public static int serialNum = 1000;

    private int employeeId;
    private String employeeName;
    private String department;

    public Employee() {

        serialNum++;
        employeeId = serialNum; // 따로 변수에 담아줘야 다른 번호를 받는다.

    }

    public int getEmployeeId() {
        return employeeId;
    }
    public void setEmployeeId(int employeeId) {
        this.employeeId = employeeId;
    }
    public String getEmployeeName() {
        return employeeName;
    }
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }
    public String getDepartment() {
        return department;
    }
    public void setDepartment(String department) {
        this.department = department;
    }

}

---------------------------------------------------

public class EmployeeTest {

    public static void main(String[] args) {

        Employee employeeLee = new Employee();
        employeeLee.setEmployeeName(&quot;이순신&quot;);

        System.out.println(Employee.serialNum);

        Employee employeeKim = new Employee();
        employeeKim.setEmployeeName(&quot;김유신&quot;);
        employeeKim.serialNum++;

        System.out.println(employeeLee.getEmployeeName() + &quot;님의 사번은 &quot; + employeeLee.getEmployeeId());
        System.out.println(employeeKim.getEmployeeName() + &quot;님의 사번은 &quot; + employeeKim.getEmployeeId());

    }

}</code></pre>
<ul>
<li>Employee.serialNum =&gt; 1001</li>
<li>employeeLee.getEmployeeName() + &quot;님의 사번은 &quot; + employeeLee.getEmployeeId()
이순신님의 사번은 1001</li>
<li>employeeKim.getEmployeeName() + &quot;님의 사번은 &quot; + employeeKim.getEmployeeId()
김유신님의 사번은 1002</li>
</ul>
<hr>
출처

<p><a href="https://coding-factory.tistory.com/524">https://coding-factory.tistory.com/524</a>
<a href="https://mangkyu.tistory.com/47">https://mangkyu.tistory.com/47</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA / 객체 간의 협력(Collaboration)]]></title>
            <link>https://velog.io/@b-joon/JAVA-%EA%B0%9D%EC%B2%B4-%EA%B0%84%EC%9D%98-%ED%98%91%EB%A0%A5Collaboration</link>
            <guid>https://velog.io/@b-joon/JAVA-%EA%B0%9D%EC%B2%B4-%EA%B0%84%EC%9D%98-%ED%98%91%EB%A0%A5Collaboration</guid>
            <pubDate>Tue, 12 Dec 2023 06:03:41 GMT</pubDate>
            <description><![CDATA[<h3 id="객체-지향-프로그래밍에서-협력">객체 지향 프로그래밍에서 협력</h3>
<ul>
<li>객체 지향 프로그램에서 객체 간에는 협력이 이루어짐</li>
<li>협력을 위해서는 필요한 메시지를 전송하고 이를 처리하는 기능이 구현되어야 함</li>
<li>매개 변수로 객체가 전달되는 경우가 발생</li>
</ul>
<h3 id="객체-간의-협력-예제">객체 간의 협력 예제</h3>
<ul>
<li><p>James와 Tomas는 각각 버스와 지하철을 타고 학교에 갑니다.</p>
</li>
<li><p>James는 5000원을 가지고 있었고, 100번 버스를 타면서 1000원을 지불합니다.</p>
</li>
<li><p>Tomas는 10000원을 가지고 있었고, 초록색 지하철을 타면서 1200원을 지불합니다.</p>
</li>
<li><p>두 학생이 버스와 지하철을 타는 상황을 구현해 보자</p>
<pre><code class="language-java">public class Student {

  String studentName;
  int money;

  public Student(String studentName, int money) {
      this.studentName = studentName;
      this.money = money;
  }

  public void takeBus(Bus bus) {
      bus.take(1000);
      this.money -= 1000;
  }

  public void takeSubway(Subway subway) {
      subway.take(1200);
      this.money -= 1200;
  }

  public void showInfo() {
      System.out.println(studentName + &quot;님의 남은 돈은 &quot; + money + &quot;원 입니다.&quot;);
  }
</code></pre>
</li>
</ul>
<p>}</p>
<hr>
<p>public class Bus {</p>
<pre><code>int busNumber;
int passengerCount;
int money;

public Bus(int busNumber) {
    this.busNumber = busNumber;
}

public void take(int money) {
    this.money += money;
    passengerCount++;
}

public void showBusInfo() {
    System.out.println(busNumber + &quot;번의 승객수는 &quot; + passengerCount + &quot;명 이고, 수입은 &quot; + money + &quot;원 입니다.&quot;);
}</code></pre><p>}</p>
<hr>
<p>public class Subway {</p>
<pre><code>int subwayNumber;
int passengerCount;
int money;

public Subway(int subwayNumber) {
    this.subwayNumber = subwayNumber;
}

public void take(int money) {
    this.money += money;
    passengerCount++;
}

public void showSubwayInfo() {
    System.out.println(subwayNumber + &quot;번의 승객수는 &quot; + passengerCount + &quot;명 이고, 수입은 &quot; + money + &quot;원 입니다.&quot;);
}</code></pre><p>}</p>
<hr>
<p>public class TakeTransTest {</p>
<pre><code>public static void main(String[] args) {

    Student studentJ = new Student(&quot;James&quot;, 5000);
    Student studentT = new Student(&quot;Tomas&quot;, 10000);

    Bus bus100 = new Bus(100);
    Bus bus500 = new Bus(500);

    studentJ.takeBus(bus100);

    Subway greenSubway = new Subway(2);

    studentT.takeSubway(greenSubway);

    studentJ.showInfo();
    studentT.showInfo();

    bus100.showBusInfo();
    greenSubway.showSubwayInfo();

    bus500.showBusInfo();

}</code></pre><p>}</p>
<p>```</p>
<ul>
<li>studentJ.showInfo() =&gt; James님의 남은 돈은 4000원 입니다.</li>
<li>studentT.showInfo() =&gt; Tomas님의 남은 돈은 8800원 입니다.</li>
<li>bus100.showBusInfo() =&gt; 100번의 승객수는 1명 이고, 수입은 1000원 입니다.</li>
<li>greenSubway.showSubwayInfo() =&gt; 2번의 승객수는 1명 이고, 수입은 1200원 입니다.</li>
<li>bus500.showBusInfo() =&gt; 500번의 승객수는 0명 이고, 수입은 0원 입니다.</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>