<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>heesoohi.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Wed, 12 Feb 2025 12:27:37 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>heesoohi.log</title>
            <url>https://velog.velcdn.com/images/d_d/profile/548afb66-c4b5-4ae5-b58e-bbea4c28b46b/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. heesoohi.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/d_d" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[클라우드 보안을 위한 AWS IAM 개념 정리 - 사용자, 정책, 보안 설정 
]]></title>
            <link>https://velog.io/@d_d/%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EB%B3%B4%EC%95%88%EC%9D%84-%EC%9C%84%ED%95%9C-AWS-IAM-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%A0%95%EC%B1%85-%EB%B3%B4%EC%95%88-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@d_d/%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EB%B3%B4%EC%95%88%EC%9D%84-%EC%9C%84%ED%95%9C-AWS-IAM-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%A0%95%EC%B1%85-%EB%B3%B4%EC%95%88-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Wed, 12 Feb 2025 12:27:37 GMT</pubDate>
            <description><![CDATA[<h3 id="span-stylebackground-color-e3cef6-1-iam--identity-and-access-management-span"><span style="background-color: #E3CEF6"> 1. IAM (= Identity and Access Management) </span></h3>
<p>서비스 중 하나인 IAM 은 <span style="color: #0489B1"><u><strong>사용자를 생성하고 그룹에 배치</strong></u></span>하는 기능을 제공한다. 
IAM은 글로벌 서비스이기 때문에 region을 따로 선택하지 않아도 된다. </p>
<p>AWS에서 계정을 생성할 때 루트 계정이 기본으로 생성된다.
이후에 루트 계정은 더이상 사용하거나 공유해서는 안 되고,
루트 계정으로 생성한 사용자를 이용하는 것!</p>
<p>이렇게 생성된 사용자들을 필요에 따라 그룹으로 묶어 관리한다. 
그룹에는 사용자만 배치할 수 있다. <span style="color: red">(그룹에 그룹 포함은 불가)</span>
한 사용자가 다수의 그룹에 속하는 것은 가능하다 (⬇️ 아래 이미지 참고)</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/380a3961-fccd-4fa6-9e19-8f5085b8fd96/image.png" alt=""></p>
<h4 id="1-1-🤔-이렇게-사용자와-그룹을-생성하는-이유는-뭘까">1-1. 🤔 <em>이렇게 사용자와 그룹을 생성하는 이유는 뭘까?</em></h4>
<p>   -&gt; 계정을 가진 사용자들이 AWS 계정을 사용하도록 허용하기 위함!
   -&gt; 허용하기 위해서는 이들에게 <u>권한을 부여</u>해야 함!</p>
<p>   #</p>
<h4 id="1-2-✅-permissions---권한을-부여하는-방법">1-2. ✅ Permissions - 권한을 부여하는 방법</h4>
<ul>
<li>사용자 or 그룹에게 &#39;IAM 정책&#39;이라는 JSON 문서를 지정<ul>
<li>JSON 문서에는 <u><em>사용자 or 그룹에 속한 사용자들이 어떤 작업에 권한을 가지는지</em></u> 설명되어 있음</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/d_d/post/910b1329-78e9-4b4b-a03e-bd8ffb1c0e21/image.png" alt=""></p>
<p>⬆️ 위 이미지와 같은 JSON 문서를 사용자에게 지정함으로서 <strong>&#39;AWS 서비스를 이용하도록 허용&#39;</strong></p>
<p> -&gt; <u><strong>최소 권한의 원칙 적용:</strong></u> 모든 사용자에게 모든 것을 허용하지 않는다. 
 -&gt; 사용자에게 필요 이상의 권한을 주지 않음으로서, <span style="color: red">보안이나 큰 비용 발생 등의 문제를 막을 수 있다.</span> </p>
<h3 id="span-stylebackground-color-e3cef6-2-iam-policies-span"><span style="background-color: #E3CEF6"> 2. IAM Policies </span></h3>
<p>특정 권한을 부여하는 것을 정책(policy)라고도 할 수 있다. </p>
<p>어떤 <u><strong>그룹에 적용된 정책</strong></u>이 있다면, 해당 정책이 <u><strong>그룹의 모든 구성원에게 적용</strong></u>된다. 
이를 <span style="color: #0489B1"><strong>&#39;정책의 상속 = IAM Policies Inheritance&#39;</strong></span> 이라고도 한다. </p>
<p>사용자가 그룹에 속해 있든 아니든, 특정 사용자에게 인라인 정책을 적용하는 것도 가능하다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/c592a744-acaa-463a-aede-94c8bed35052/image.png" alt=""></p>
<h4 id="2-1-정책-구조">2-1. 정책 구조</h4>
<ul>
<li><p><strong>Version</strong>: 정책의 언어 버전 (보통 2012-10-17)</p>
</li>
<li><p><strong>Id</strong>: 정책 식별 아이디 (optional)</p>
</li>
<li><p><strong>Statement</strong>: 하나 이상의 statements 로 구성 (Required)</p>
<ul>
<li><p><strong>Sid</strong>: statement의 id(=식별자) (optional)</p>
</li>
<li><p><strong><span style="color: blue">Effect</span></strong>: statement가 특정 API에 접근하는걸 허용할지 거부할지 -&gt; Allow 혹은 Deny 값을 가짐</p>
</li>
<li><p><strong><span style="color: blue">Principal</span></strong>: 정책이 적용될 유저/계정/역할</p>
</li>
<li><p><strong><span style="color: blue">Action</span></strong>: effect에 기반하여 허옹 혹은 거부되는 API 호출 목록</p>
</li>
<li><p><strong><span style="color: blue">Resource</span></strong>: action이 적용될 리소스 목록</p>
</li>
<li><p><strong>Condition</strong>: statement가 언제 적용될지 결정 (optional)</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/d_d/post/376ec377-1e37-466e-8ece-92fcbcd19c0a/image.png" alt=""></p>
<p>#</p>
<h3 id="span-stylebackground-color-e3cef6-3-password-policy---비밀번호-정책-span"><span style="background-color: #E3CEF6"> 3. Password Policy - 비밀번호 정책 </span></h3>
<p>사용자와 그룹이 손상되지 않도록 보호해야 하는데, <u><em>두가지 방어 메커니즘</em></u>을 사용할 수 있다.</p>
<p><strong>1. 패스워드 설정</strong>    </p>
<ul>
<li>비밀번호 정책을 정의하여 방어할 수 있다!</li>
<li>비밀번호가 강력할수록 계정 보안이 강화됨 </li>
</ul>
<p>  #</p>
<p><strong>2. MFA - 다중 인증</strong></p>
<p>Multi Factor Authentication 의 약자로, AWS에서 필수로 사용해야 하는 방어 메커니즘이다. </p>
<p>사용자가 기억하는 <span style="background-color: #FFBF00">비밀번호</span>와 사용자가 소유하는 <span style="background-color: #FFBF00"><strong>실물 보안 장치</strong></span>를 모두 사용하는 방식으로, 단순히 비밀번호만 사용하는 것보다 보안이 강화된다!</p>
<h4 id="📱mfa-devices-options-in-aws">📱MFA devices options in AWS</h4>
<ol>
<li><strong><span style="color: #084B8A">가상 MFA 장치 - Virtual MFA device</span></strong><pre><code> : 모바일로 발급된 번호로 인증
단일 장치에서 여러 토큰을 지원하기 떄문에, 원하는 만큼 많은 유저와 계정을 보유할 수 있음</code></pre></li>
</ol>
<p>   <img src="https://velog.velcdn.com/images/d_d/post/b7da1b71-81f9-424d-9860-ea56fe56547b/image.png" alt=""></p>
<ol start="2">
<li><strong><span style="color: #084B8A">U2F 보안키 - Universal 2nd Factor Security Key</span></strong><pre><code> : 물리적인 장치
이를 보안 토큰에 달면 사용 가능
단일 보안키를 사용하여 여러 루트 &amp; IAM 사용자 지원</code></pre></li>
</ol>
<p><strong><span style="color: #084B8A">Hardware Key Fob MFA Device, Hardware Key Fob MFA Device for AWS GovCloud(us) </span></strong> 등의 하드웨어 보안 토큰도 사용 가능!</p>
<h3 id="span-stylebackground-color-e3cef6-4-aws에-엑세스-하는-방법-span"><span style="background-color: #E3CEF6"> 4. AWS에 엑세스 하는 방법 </span></h3>
<p>AWS에 액세스하는 방법은 3가지가 있다. </p>
<h4 id="1-aws-management-console">1. AWS Management Console</h4>
<p> : 지금까지 살펴본 &#39;비밀번호 + MFA&#39; 방식</p>
<h4 id="2-aws-clicommand-line-interface">2. AWS CLI(Command Line Interface)</h4>
<p> : 액세스 키에 의해 보호되는 방식으로, 컴퓨터에서 설정할 수 있음</p>
<p> 🤔 <strong>CLI</strong>란?
      -&gt; 명령줄 인터페이스
    -&gt; AWS CLI 는 명령줄 셸에서 명령어를 사용하여, AWS 서비스들과 상호작용할 수 있도록 하는 도구
    -&gt; CLI를 사용하면 AWS 서비스의 공용 API로 직접 액세스 가능</p>
<p>   ⬇️ CLI에서 명령줄을 입력하면 아래 이미지와 같이 결과가 반환됨. </p>
<p>   <img src="https://velog.velcdn.com/images/d_d/post/44ad9c8c-4c08-48b9-91b1-b231a6be333a/image.png" alt=""></p>
<p> 🤔 <strong>액세스 키</strong>란?
   -&gt; 자격 증명으로, 터미널에서의 AWS 액세스를 가능하게 해줌
   -&gt; 액세스 키는 관리 콘솔에서 생성할 수 있음
    -&gt; 사용자들이 자신들의 액세스 키를 직접 관리
    -&gt; 사용자 입장에서 액세스 키는 비밀번호와 같은 암호이니, 공유해선 안 됨!</p>
<h4 id="3-aws-sdksoftware-developer-kit">3. AWS SDK(Software Developer Kit)</h4>
<p> : AWS로 부터 애플리케이션 코드 내에 API를 호출할 때 사용하는 방식
  CLI와 동일한 액세스 키로 보호됨. </p>
<p> 🤔 <strong>SDK</strong>란?
: 소프트웨어 개발 키트로, 특정 언어로 된 라이브러이의 집합이다. 
    (-&gt; 프로그래밍 언어에 따라 개별 SDK가 있음)
-&gt; SDK를 사용해서도 AWS 서비스와 API에 액세스할 수 있음</p>
<p>but! CLI와 달리 터미널 내에서 사용하는 것이 아니라, <u>애플리케이션 내에 자체적으로 존재</u></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS는 왜 필요할까? 클라우드 컴퓨팅의 탄생 배경과 핵심 개념 ]]></title>
            <link>https://velog.io/@d_d/%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C</link>
            <guid>https://velog.io/@d_d/%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C</guid>
            <pubDate>Tue, 11 Feb 2025 14:59:57 GMT</pubDate>
            <description><![CDATA[<p><strong>💡 이 글에서 다루는 개념들</strong></p>
<p>✔️ 서버의 기본 구조 – CPU, RAM, 스토리지, 데이터베이스, 네트워크
✔️ 클라우드 도입 이전의 IT 환경 – 데이터센터의 한계와 유지보수 비용
✔️ 클라우드 컴퓨팅이란? – 언제든 원하는 만큼 사용하는 IT 리소스
✔️ 클라우드의 3가지 서비스 모델 – IaaS, PaaS, SaaS
✔️ AWS 리전과 가용 영역(AZ) – 데이터 보호와 지연 시간 최소화 전략
✔️ 공동 책임 모델(Shared Responsibility Model) – AWS와 사용자의 보안 역할</p>
<hr>
<p>AWS는 어느 날 갑자기 하늘에서 떨어진 기술이 아니다. 필요에 의해 만들어진 기술이다.</p>
<p>그럼 도대체 왜 AWS가 생겨난걸까? 🤔</p>
<p>본격적으로 AWS를 알아보기 전에, 기본적인 서버의 구조와 기존의 IT는 어떤 모습이었을지 한 번 훑어보고 가자!</p>
<h3 id="span-stylebackground-color-e3cef6-1-서버의-구성-span"><span style="background-color: #E3CEF6"> 1. 서버의 구성 </span></h3>
<p>서버는 크게 5가지로 이루어져 있다. </p>
<ol>
<li><p><strong>Compute</strong>: CPU (계산을 담당)</p>
</li>
<li><p><strong>Memory</strong>: RAM </p>
<pre><code> -&gt; CPU와 RAM이 합쳐지면 마치 두뇌와 같다. 
    연산한 결과를 기억하고, 기억한 정보로 또 다른 연산을 해내니까!</code></pre></li>
<li><p><strong>Storage</strong>: 데이터가 저장되는 곳</p>
</li>
<li><p><strong>Database</strong>: 구조적으로 데이터를 저장하는 곳. like 컴퓨터의 파일. </p>
<pre><code>      데이터베이스에 저장된 데이터는 검색하여 쉽게 찾을 수 있고, 쿼리가 가능하다. </code></pre></li>
<li><p><strong>Network</strong>: 라우터(Routers), 스위치(Switch), DNS 서버 등</p>
<pre><code>     라우터: 컴퓨터 네트워크 간의 데이터 패킷을 전달하는 기기. 
           like 배달 서비스. 어디로 정보를 보낼지 파악하고, 실제로 전송까지 

     스위치: 라우터로 부터 받은 패킷을 네트워크 내의 정확한 서버 or 클라이언트에게 전송</code></pre></li>
</ol>
<h3 id="span-stylebackground-color-e3cef6-2-클라우드가-도입되기-전-it는-어땠을까-span"><span style="background-color: #E3CEF6"> 2. 클라우드가 도입되기 전 IT는 어땠을까? </span></h3>
<p>서비스가 사랑을 받고 유저가 많아질수록, 저장해야 하는 데이터의 양이 늘어난다. </p>
<p>-&gt; 데이터 센터와 서버 구매 비용 증가
-&gt; 쿨링, 고장 등 유지 보수 비용 증가
-&gt; 데이터 센터 확장이 어려움 (서버 추가 구매하고, 기존 서버와 연결해야 함. 늘어난 만큼 유지보수도 추가로!)
-&gt; 최악의 상황으로 재난이라도 일어난다면? .. <em>감당 불가..</em></p>
<p>이런 문제들의 해결책으로 나타난 것이 바로 👉 클라우드 👈 이다!</p>
<h3 id="span-stylebackground-color-e3cef6-3-클라우드-컴퓨팅이란-span"><span style="background-color: #E3CEF6"> 3. 클라우드 컴퓨팅이란? </span></h3>
<p>컴퓨팅 성능, 데이터베이스 스토리지, 애플리케이션, 기타 IT 리소스들을 
<strong><em>원할 때 원하는 만큼 (= on-demand)</em></strong> 제공하는 서비스</p>
<p>-&gt; 이메일, iCould같은 클라우드 스토리지 서비스, 넷플릭스 등이 클라우드 컴퓨팅을 바탕으로 설계되었다.</p>
<h3 id="span-stylebackground-color-e3cef6-4-클라우드-컴퓨팅의-종류-span"><span style="background-color: #E3CEF6"> 4. 클라우드 컴퓨팅의 종류 </span></h3>
<ol>
<li><p><strong>IaaS</strong>(Infrastructure as a Service) - 서비스형 인프라</p>
<ul>
<li><p>네트워킹, 컴퓨터, 데이터 스토리지 공간 등 클라우드 IT의 구성 요소를 원시 형태로 제공</p>
</li>
<li><blockquote>
<p>이 블록들을 사용해 자유롭게 조립할 수 있음 (like 레고)</p>
</blockquote>
</li>
<li><blockquote>
<p>유연성이 높아짐 (기존 IT(on-premise)에서 클라우드로 이동하며 생긴 변화와 유사)</p>
</blockquote>
</li>
<li><p>클라우드에서 <span style="color: #0489B1"><u><strong>가상화, 서버, 스토리지, 네트워킹</strong></u></span>을 관리해줌. </p>
</li>
<li><p>사용자는 <span style="color: #0489B1"><u><strong>애플리케이션, 데이터, 런타임, 미들웨어, 운영체제</strong></u></span>를 관리</p>
</li>
</ul>
</li>
<li><p><strong>PaaS</strong>(Platform as a Service) - 서비스형 플랫폼</p>
<ul>
<li><p>기본 인프라를 관리하지 않아도 됨</p>
</li>
<li><p>배포와 애플리케이션 관리에만 집중할 수 있음</p>
</li>
<li><p>사용자는 <span style="color: #0489B1"><u><strong>애플리케이션, 데이터</strong></u></span>만 관리</p>
</li>
</ul>
</li>
</ol>
<ol start="3">
<li><p><strong>SaaS</strong>(Service as a Service) - 서비스형 소프트웨어</p>
<ul>
<li><p>서비스 제공 업체가 온전히 운영하고 관리하는, 완성된 제품.</p>
<ul>
<li>사용자가 관리해야 하는 것이 없음! (like 메일, 아이클라우드, 줌 등..)</li>
</ul>
</li>
</ul>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/d_d/post/cdcd934b-d483-41e0-b47b-93900045f38a/image.png" alt=""></p>
<h3 id="span-stylebackground-color-e3cef6-5-aws-regions-span"><span style="background-color: #E3CEF6"> 5. AWS Regions </span></h3>
<p>AWS 서비스를 사용할 때 대부분의 서비스들은 특정 region에 연결 및 국한된다. 
따라서 한 region에서 사용되던 서비스를 다른 region에서 사용하려고 하면, 그 서비스를 처음 사용하는 셈!</p>
<h4 id="🧐-_how-to-choose-an-aws-region-_">🧐 _How to choose an AWS Region? _</h4>
<p>새로운 애플리케이션을 출시할 때, 어떤 AWS 리전을 선택해야 할까?
-&gt; 아래의 4가지 요인들을 고려해 결정할 수 있다. </p>
<ol>
<li><p><strong>법률 준수</strong>(Compliance with data governance and legal requirements)</p>
<p> 애플리케이션이 출시될 나라의 법률을 준수해야 한다. 
 ex) 정부가 관련 데이터가 대상 국가 내에 보관되기를 원한다면, 해당 region에서 출시해야 함.</p>
</li>
<li><p><strong>지연 시간</strong>(Proximity to customers)</p>
<p> 사용자들이 많은 지역과 가까운 region에서 출시해야 지연 시간이 줄어듦.</p>
<p> 만약 미국 사용자들을 위한 애플리케이션을 호주에서 출시한다면? -&gt; 사용자들이 랙을 경험하게 될 것</p>
</li>
<li><p><strong>region에서 사용 가능한 서비스인지</strong> (Available services within a Region)</p>
<p> region마다 사용 가능한 서비스에 차이가 있음. </p>
<p> 특정 서비스를 활용하여 개발된 애플리케이션을 출시하려면, 
 해당 서비스를 가지고 있는 region인지 확인해야 함. </p>
</li>
<li><p><strong>요금</strong>(Pricing)</p>
<p> Region 마다 요금이 다르기 때문에 서비스 요금 페이지를 참고하여 결정해야 함. </p>
</li>
</ol>
<h4 id="🌐-aws-availability-zones---가용-영역">🌐 AWS Availability Zones - 가용 영역</h4>
<p>재난 상황 같이 혹시 모를 상황에 대비하여 가용 영역(AZ)들이 분리 되어 있다. </p>
<p>각각의 region은 일반적으로 3개의 AZ를 가지고 있다. (최소 2개/최대 6개) 
각각의 가용 영역(AZ)은 여분의 전원, 네트워킹, 통신 기능을 갖춘 1-2개의 개별적인 데이터 센터로 이루어져 있다.</p>
<p>가용 영역들은 서로 단절되어 있기 때문에, 하나의 AZ에 문제가 발생해도, 다른 AZ에 영향을 미치지 않는다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/32cb2cd5-75e2-4c3b-a544-e4ee4698d5a8/image.png" alt=""></p>
<p>⬆️ 이러한 데이터 센터들과 AZ들은 높은 대역폭의 초저지연 네트워킹으로 서로 연결되어 region을 형성한다.</p>
<h4 id="🌐-aws-points-of-presence-edge-locations---전송-지점">🌐 AWS Points of Presence (Edge Locations) - 전송 지점</h4>
<p>AWS는 전세계에 200개 이상의 전송지점을 가지고 있다.
-&gt; 최소 지연 시간으로 최종 사용자에게 컨텐츠를 전달!</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/27f39af5-c257-47c4-97f0-fdb262720341/image.png" alt=""></p>
<h3 id="span-stylebackground-color-e3cef6-6-공동-책임-모델---shared-responsibility-model-span"><span style="background-color: #E3CEF6"> 6. 공동 책임 모델 - Shared Responsibility Model </span></h3>
<p>클라우드를 사용할 때, 사용자와 AWS가 책임져야 하는 부분이 따로 존재한다. 
결국 공동으로 책임 지는 것!</p>
<ul>
<li><strong>사용자의 책임</strong> 
<em><strong>&quot;Responsibility for the security <span style="color: #0489B1"><u>in</u></span> the cloud&quot;</strong></em></li>
</ul>
<p>   -&gt; 클라우드에서 무엇을 사용할지, 어떻게 구성할지
   -&gt; 보안, 데이터, 운영체제, 네트워크, 방화벽 구성 등에 대한 책임이 있음. (= 클라우드 내의 보안 책임)</p>
<h1 id=""></h1>
<ul>
<li><strong>AWS의 책임</strong>
<em><strong>&quot;Responsibility for the security <span style="color: #0489B1"><u>of</u></span> the cloud&quot;</strong></em></li>
</ul>
<p>   -&gt; 모든 인프라, 하드웨어, 소프트웨어, <u>자체 내부</u> 보안에 대한 책임이 있음. (= 클라우드에 관한 보안 책임)</p>
<p>   <img src="https://velog.velcdn.com/images/d_d/post/1ec16029-ccbc-428a-a914-e5a3d80d431a/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[연관관계 매핑 (Association Mapping)]]></title>
            <link>https://velog.io/@d_d/%EC%97%B0%EA%B4%80%EA%B4%80%EA%B3%84-%EB%A7%A4%ED%95%91-Association-Mapping</link>
            <guid>https://velog.io/@d_d/%EC%97%B0%EA%B4%80%EA%B4%80%EA%B3%84-%EB%A7%A4%ED%95%91-Association-Mapping</guid>
            <pubDate>Mon, 10 Feb 2025 08:36:34 GMT</pubDate>
            <description><![CDATA[<p>연관관계 매핑이란 <strong>엔티티 간의 관계를 설정</strong>하는 것!</p>
<p>Entity 사이의 관계는 크게 3가지로 나눌 수 있는데, 각각 
1:1(일대일), 1:N(일대다), N:M(다대다) 이다.</p>
<h3 id="11">1:1</h3>
<p>하나의 엔티티가 다른 엔티티와 관계를 맺는 경우. 
예를 들어 유저 엔티티와 유저 프로필 엔티티가 서로 1:1 관계를 맺을 수 있음. </p>
<p>그런데 대부분의 경우, 그냥 하나의 테이블에 쓰면 되기 때문에, 굳이 1:1로 연관관계를 매핑하지 않아도 ㄱㅊ!</p>
<h3 id="1n--n1">1:N / N:1</h3>
<p>하나의 엔티티가 여러 개의 다른 엔티티와 관계를 맺는 경우.
예를 들어, 게시글 엔티티와 댓글 엔티티는 1:N 관계를 갖는다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/405a2082-c181-42b6-8836-a43d02ae2ca6/image.png" alt=""></p>
<p>게시글 하나에 여러개의 댓글이 달릴 수 있는 경우이기에 1:N 관계이고, 
@ManyToOne, @JoinColumn(name = &quot;board_id&quot;) 어노테이션으로 댓글 엔티티가 게시글의 고유 식별자를 필드로 가지게 된다. </p>
<p>아래에서 볼 N:M 관계에서도 @ManyToOne 을 각 엔티티에 더해주면 연관관계 관리하는데 오류가 현저하게 줄어들기 떄문에, 사실상 가장 많이 사용되는 연관관계임!</p>
<h3 id="nm">N:M</h3>
<p>두 엔티티가 서로 여러개의 관계를 맺는 경우
책과 작가 같은 관계. (책은 여러명의 저자를 가질 수 있고(공동저자), 한 저자는 여러명의 책을 쓴 경우가 있음)</p>
<p>주의할 점!
N:M 관계를 1:N + N:1 로 풀어서 중간 엔티티를 생성하여 연관관계를 관리하는 편이 안전함</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[엔티티 설계 및 구현 방법 정리 - JPA를 활용한 앱 개발]]></title>
            <link>https://velog.io/@d_d/%EC%97%94%ED%8B%B0%ED%8B%B0-%EC%84%A4%EA%B3%84-%EB%B0%8F-%EA%B5%AC%ED%98%84-%EB%B0%A9%EB%B2%95-%EC%A0%95%EB%A6%AC-JPA%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%95%B1-%EA%B0%9C%EB%B0%9C</link>
            <guid>https://velog.io/@d_d/%EC%97%94%ED%8B%B0%ED%8B%B0-%EC%84%A4%EA%B3%84-%EB%B0%8F-%EA%B5%AC%ED%98%84-%EB%B0%A9%EB%B2%95-%EC%A0%95%EB%A6%AC-JPA%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%95%B1-%EA%B0%9C%EB%B0%9C</guid>
            <pubDate>Thu, 06 Feb 2025 11:35:30 GMT</pubDate>
            <description><![CDATA[<p>엔티티를 설계 및 구현하는 단계를 구체적으로 정리해보겠다.</p>
<h3 id="1-일단-구현에-앞서-어떤-객체테이블이-필요한지-결정해야-한다">1. 일단 구현에 앞서, 어떤 객체/테이블이 필요한지 결정해야 한다.</h3>
<p>예를 들어, 유저가 스케줄을 저장하는 스케쥴러를 만든다면, 유저 객체(테이블)과 스케쥴 객체(테이블)이 필요할 것이다. 각 객체(테이블)이 어떤 필드를 가져야 하는지도 결정해야 한다.</p>
<p>ex)</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/8f355669-3e9e-4771-88a0-d61845fecec6/image.png" alt=""></p>
<p>객체(테이블) 간의 연관관계도 결정해야 한다. 
예를 들어, 한 명의 유저가 여러개의 스케쥴을 작성할 수 있다는 식으로. 이 경우 단방향 연관관계를 가진다.</p>
<h3 id="2-baseentity-설계-및-적용">2. BaseEntity 설계 및 적용</h3>
<p>베이스 엔티티(Base Entity)는 여러 엔티티(데이터 객체)에서 공통으로 쓰이는 속성(예: 생성 날짜, 수정 날짜 등)을 모아둔 기본 클래스이다. 베이스 엔티티가 가지고 있는 속성을 필요로 하는 테이블이 있다면, 베이스 엔티티를 상속하여 사용함으로서, 중복 코드 없이 공통 속성을 쉽게 관리할 수 있다. 즉, 여러 엔티티가 같은 기능을 공유하도록 도와주는 틀이라고 이해하면 된다.</p>
<p>유저 테이블과 스케쥴 테이블 모두 공통적으로 &#39;생성일, 수정일&#39;을 가지기 때문에, 해당 필드를 베이스 엔티티로 구현하여 관리할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/9e7bcb41-6b20-405a-9999-48e775a66fee/image.png" alt=""></p>
<p>아래의 예시처럼, 베이스엔티티 기능을 할 수 있도록 적절한 어노테이션을 사용해주고, 각각의 필드들도 특징에 맞게 어노테이션을 추가하여 관리가 쉽도록 한다.</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/e0b5a08c-26c9-43d7-8942-30d791ac3773/image.png" alt=""></p>
<h3 id="3-각-객체테이블-설계-및-구현">3. 각 객체(테이블) 설계 및 구현</h3>
<p>공통 속성을 베이스엔티티로 구현하였다면, 이제 각각의 테이블을 구현해주면 된다.</p>
<p>스케줄러 예시에서는 1. 유저 테이블과 2. 스케쥴 테이블을 만들어야 할 것이다.</p>
<p><strong>베이스엔티티를 상속받는 유저 객체:</strong></p>
<p><img src="https://velog.velcdn.com/images/d_d/post/250dbb97-d7c8-4120-80f6-6b17bc6ca5cd/image.png" alt=""></p>
<p>PK인 id는 데이터베이스가 직접 관리하며 자동증가 하여 값을 저장하도록 적절한 어노테이션을 붙여주고
필수값, 중복되면 안되는 값들도 적절한 어노테이션으로 처리</p>
<p><strong>베이스엔티티를 상속받는 스케쥴 객체:</strong></p>
<p><img src="https://velog.velcdn.com/images/d_d/post/815e60a7-8f67-4b46-b166-30eeebd401b0/image.png" alt=""></p>
<h3 id="4-연관관계-설정">4. 연관관계 설정</h3>
<p>스케줄러 예시에서 한명의 회원이 여러개의 일정을 등록할 수 있는데, 이 경우 연관관계는 N:1 단방향이다.</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/50e2388c-3cda-42df-8be1-1768ec11116c/image.png" alt=""></p>
<p>위와 같이, N인 객체에 @ManyToOne, @JoinColumn 어노테이션을 추가하여 연관관계를 설정할 수 있다. 조인된 컬럼이 foreign key 가 된다!</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/c4b9869e-d26e-46c0-a95d-9c0e7c3e74cf/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[스프링부트] JPA를 사용하는 이유와 사용 시 고려해야 할 사항]]></title>
            <link>https://velog.io/@d_d/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0%EC%99%80-%EC%82%AC%EC%9A%A9-%EC%8B%9C-%EA%B3%A0%EB%A0%A4%ED%95%B4%EC%95%BC-%ED%95%A0-%EC%82%AC%ED%95%AD</link>
            <guid>https://velog.io/@d_d/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0%EC%99%80-%EC%82%AC%EC%9A%A9-%EC%8B%9C-%EA%B3%A0%EB%A0%A4%ED%95%B4%EC%95%BC-%ED%95%A0-%EC%82%AC%ED%95%AD</guid>
            <pubDate>Wed, 05 Feb 2025 11:01:37 GMT</pubDate>
            <description><![CDATA[<p>JPA는 자바로 RDB를 객체지향적으로 다룰 수 있는 기술이다. </p>
<h3 id="jpa를-사용하는-이유">JPA를 사용하는 이유</h3>
<h4 id="1-객체지향과-rdb의-패러다임-불일치가-해결-된다">1. 객체지향과 RDB의 패러다임 불일치가 해결 된다!</h4>
<p>개발자는 자바를 가지고 객체 중심으로 개발을 하지만, RDB에 데이터는 테이블로 저장된다. 
JPA가 객체와 데이터베이스를 매핑하는 역할을 해주는 덕에 DB의 활용이 쉬워워짐..!</p>
<h4 id="2-sql-문제-해결">2. SQL 문제 해결</h4>
<p>JPA에서 객체를 저장하면 SQL이 자동 생성되기 때문에 
데이터를 CRUD하기 위해 SQL문을 직접 작성할 필요가 없게 되고, 그 대신 비즈니스 로직에 집중할 수 있게 된다는 장점이 있다! (JDBD를 사용할 때 SQL문 계속 수정하고 어쩌구 하느라 힘들었는데,, JPA쓰면 훨씬 쉬워짐!)</p>
<h4 id="3-생산성-및-유지보수성-향상">3. 생산성 및 유지보수성 향상</h4>
<p>JPA에서 Entity 클래스를 수정하면 자동으로 변경 사항들이 반영되기 때문에, 테이블에 컬럼이 추가되거나 내용을 바꿀때마다 SQL을 일일이 수정할 필요가 없이 JPA가 알아서 쳐리해준다!</p>
<h3 id="jpa-사용-시-고려해야-하는-사항">JPA 사용 시 고려해야 하는 사항</h3>
<h4 id="1차-캐시--영속성-컨텍스트">1차 캐시 &amp; 영속성 컨텍스트</h4>
<p>동일한 데이터를 반복해서 조회하는 경우, 조회할 때마다 데이터베이스에서 데이터를 가져오면 메모리 효율이 떨어질 것이다. (쓸데없이 같은 일 반복하면 효율이 떨어진다는건 당연한 소리) 
JPA는 엔티티를 영속성 컨텍스트에 저장하며 이런 문제를 해결한다!
처음에 데이터를 가져온 다음 그 객체를 영속성 컨텍스트에 저장하고, 동일 트랙잭션 내에서 만일 같은 요청이 들어온다면 해당 객체를 계속 재사용한다. 
같은 엔티티를 여러번 조회하더라도 데이터베이스에 같은 쿼리를 반복해서 날리지 않고도 데이터를 가져올 수 있는 것! -&gt; 성능 최적화</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[스프링부트] Validation 기본 구조]]></title>
            <link>https://velog.io/@d_d/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-Validation-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@d_d/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-Validation-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Tue, 04 Feb 2025 14:09:03 GMT</pubDate>
            <description><![CDATA[<p>Spring Boot에서 유효성 검사(=validation)는 입력 데이터의 신뢰성을 보장하기 위해 필수로 사용된다. 클라이언트가 요청한 데이터의 형식과 조건이 적절한지 확인하는 작업이 중요하기 때문!</p>
<h3 id="spring-boot-validation-기본-구조">Spring Boot Validation 기본 구조</h3>
<h4 id="1-dto에-유효성-검사-어노테이션-적용">1. DTO에 유효성 검사 어노테이션 적용</h4>
<p>DTO(Data Transfer Object)에 유효성 검사 어노테이션을 추가하여, 필드별로 검증을 수행할 수 있다.</p>
<p>@NotBlank  // 공백 및 빈 문자열 허용 X
@Email        // 이메일 형식 검사
@NotNull<br>@Min        // 최소값 설정
@Max        // 최대값 설정</p>
<p>위와 같은 어노테이션을 사용할 수 있다. 괄호 안에 검증에 대한 메시지를 추가할 수도 있다. </p>
<p>예) </p>
<pre><code>@NotBlank(message = &quot;이름은 필수 입력값입니다.&quot;)
private String name;</code></pre><h4 id="2-controller에서-valid-또는-validated-사용">2. Controller에서 @Valid 또는 @Validated 사용</h4>
<p>Controller에서는 @Valid 또는 @Validated 어노테이션을 활용하여 DTO 검증할 수 있다. </p>
<p>@Valid
@Valid</p>
<p>예시 코드)</p>
<pre><code>@PostMapping(&quot;/create&quot;)
public ResponseEntity&lt;String&gt; createUser(@Valid @RequestBody UserDTO userDTO) {
        return ResponseEntity.ok(&quot;회원 생성 성공!&quot;);
    }</code></pre><h4 id="3-전역-예외-처리로-검증-오류-관리">3. 전역 예외 처리로 검증 오류 관리</h4>
<p>컨트롤러에서 직접 에러 메시지를 관리하는 대신, 전역 예외 처리 (@RestControllerAdvice)를 활용하여 한 곳에서 처리.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[트러블 슈팅] 예외 처리 개선 - 데이터베이스 반환값을 활용하여 예외 처리 강화]]></title>
            <link>https://velog.io/@d_d/%ED%8A%B8%EB%9F%AC%EB%B8%94%EC%8A%88%ED%8C%85</link>
            <guid>https://velog.io/@d_d/%ED%8A%B8%EB%9F%AC%EB%B8%94%EC%8A%88%ED%8C%85</guid>
            <pubDate>Mon, 03 Feb 2025 12:29:33 GMT</pubDate>
            <description><![CDATA[<h2 id="트러블-슈팅">트러블 슈팅</h2>
<h3 id="1-문제-상황">1. 문제 상황</h3>
<p>일정 관리 서비스를 구현하는 과정에서, deleteTaskById() 메서드는 id를 파라미터 값으로 받아서 task 테이블에서 해당 id의 행을 삭제하는 기능을 수행한다. 기존 코드는 아래와 같이 작성되어 있었다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/bb5f5cdc-4e1b-4ee1-8bb2-a0831a5fa4ee/image.png" alt=""></p>
<p>이 코드의 문제점은, _<strong>존재하지 않는 id가 입력되었을 때 예외 처리가 없어 사용자에게 적절한 피드백을 제공하지 못한다는 것</strong>_이었다. </p>
<p>이로 인해 사용자는 일정이 정상적으로 삭제되었는지 여부를 알 수 없었고, 시스템의 신뢰성이 떨어지는 문제가 발생할 수 있었다.</p>
<h3 id="2-문제-원인">2. 문제 원인</h3>
<p>jdbcTemplate.update() 메서드는 반환 타입으로 int를 갖는다. SQL 문을 실행한 다음, 이 메서드의 영향을 받은 행(row)의 수를 반환하는 것.</p>
<p>기존 코드에서는 삭제된 행의 개수를 반환하도록 되어있었는데, 
이 반환값을 활용하지 않았기 때문에, 삭제할 행이 존재하지 않아도 별도의 예외를 발생시키지 않았다. 
이로 인해 사용자는 삭제가 실패했는지 여부를 알 수 없었다.</p>
<h3 id="3-해결-방법">3. 해결 방법</h3>
<p>이 문제를 해결하기 위해, jdbcTemplate.update() 메서드의 반환값인 영향을 받은 행의 수를 체크하고, 
삭제할 행이 없는 경우(affectedRows == 0) 예외를 발생시키도록 코드를 수정하였다. 
수정된 코드는 다음과 같다.</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/a22ca4f6-e5d4-41a6-a7cb-f48b9e462bc2/image.png" alt=""></p>
<h3 id="4-해결-결과">4. 해결 결과</h3>
<p>이제 deleteTaskById() 메서드는 삭제할 행이 없는 경우 IllegalArgumentException을 발생시키면서 사용자에게 적절한 피드백을 제공할 수 있게 되었다. </p>
<p>이를 통해 시스템의 신뢰성이 향상되었고, 사용자는 삭제 작업의 성공 여부를 명확히 알 수 있게 되었다.</p>
<h3 id="5-결론">5. 결론</h3>
<p>이번에 deleteTaskById() 메서드의 예외 처리 부족 문제를 해결한 방식으로 데이터베이스 작업 시 반환값을 적극 활용하여 예외 처리를 강화하면 시스템의 안정성과 사용자 경험을 개선할 수 있다. 앞으로도 비슷한 문제가 발생할 경우, 이와 같은 접근 방식을 활용하여 문제를 해결할 예정이다.</p>
<h3 id="6-추가-개선-가능성">6. 추가 개선 가능성</h3>
<ol>
<li><strong>예외 처리의 세분화</strong>: 현재는 IllegalArgumentException을 사용하고 있지만, 더 구체적인 예외 클래스를 정의하여 사용하면 더욱 명확한 에러 처리가 가능할 것이다. 예를 들어, TaskNotFoundException과 같은 커스텀 예외 정의 </li>
<li><strong>로깅</strong>: 예외 발생 시 로그를 남겨, 문제 발생 시 원인을 더 쉽게 추적할 수 있도록 할 수 있을 것이다.</li>
<li><strong>테스트 코드 작성</strong>: 수정된 코드에 대한 테스트 코드를 작성하여, 예외가 정상적으로 발생하는지 확인한다.</li>
</ol>
<p>이와 같은 추가 개선 사항을 통해, 더욱 견고하고 유지보수하기 쉬운 코드를 작성할 수 있을 것이라 기대된다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JSON 기초 정리]]></title>
            <link>https://velog.io/@d_d/JSON-%EA%B8%B0%EC%B4%88-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@d_d/JSON-%EA%B8%B0%EC%B4%88-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 22 Jan 2025 11:41:11 GMT</pubDate>
            <description><![CDATA[<h4 id="json">JSON:</h4>
<p>백엔드와 프론트엔드 간에 데이터 교환 형식 (key : value 형식)</p>
<h4 id="json의-직렬화와-역직렬화">JSON의 직렬화와 역직렬화</h4>
<p>직렬화: 외부 시스템에서도 데이터를 사용할 수 있게 바이트(byte) 형식으로 변환하는 기술
역직렬화: 직렬화의 반대</p>
<p>예를 들어 프론트엔드에서 &quot;Hello World&quot; 라고 입력했을 때
백엔드가 해당 데이터(String 타입)을 DB로 넘겨줄 때 데이터 형식을 바꿔줄 필요가 있다. 
이것을 역직렬화라고 하며, JSON.parse()로 사용</p>
<p>키-밸류 타입으로 
{
&quot;content&quot; : &quot;Hello World&quot;
}
위와 같은 JSON 형태로 바꿔서 백엔드로 넘겨줘야 
백엔드가 저 데이터를 가공해서 데이터베이스로 넣어줄 수 있음</p>
<p>반대로 DB에서 데이터를 가져와서 프론트엔드에 찍어줄 때에도 JSON으로 보내줘야 함. </p>
<ul>
<li>문자열을 객체로 바꿀 때, 프론트엔드의 문자열이 백엔드로 넘어왔을 때 역직렬화</li>
<li>객체를 문자열로 바꿀 때 JSON.stringify(), 백엔드에서 다시 프론트엔드로 넘겨줄 때 직렬화</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTTP 기본 내용 정리]]></title>
            <link>https://velog.io/@d_d/HTTP-%EA%B8%B0%EB%B3%B8-%EB%82%B4%EC%9A%A9-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@d_d/HTTP-%EA%B8%B0%EB%B3%B8-%EB%82%B4%EC%9A%A9-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Tue, 21 Jan 2025 11:37:21 GMT</pubDate>
            <description><![CDATA[<p>HTTP는 인터넷에서 사용하는 네트워크 통신의 프로토콜이다. </p>
<h3 id="http의-특징">HTTP의 특징</h3>
<ol>
<li><p>무상태(stateless)</p>
<p> 무상태(stateless) 프로토콜은 각 요청이 독립적으로 처리되며, 
 서버가 클라이언트의 요청을 기억하지 않는다. </p>
<p> 따라서 클라이언트가 서버에 요청할 때마다, 이전 요청들을 함께 보내줘야 한다.</p>
<p> 로그인 등 상태 유지가 필요한 경우 cookie, token, session등을 활용해야 한다</p>
</li>
<li><p>비연결성(connectionless)</p>
<p> 요청이 끝나면 더이상 연결을 유지하지 않는다. </p>
</li>
</ol>
<h3 id="http-메시지-구조">HTTP 메시지 구조</h3>
<ul>
<li>HTTP Method: 클라이언트의 의도를 표현하는 명령어로 GET, POST, PUT, PATCH, DELETE 등이 있다</li>
<li>상태코드: 서버의 응답 상태를 나타낸다. <pre><code>    1**(정보), 2**(성공), 3**(리다이렉션), 4**(클라이언트 에러), 5**(서버 에러)</code></pre></li>
<li>HTTP Header: Request와 response에 대한 부가 정보를 담고 있다. </li>
</ul>
<h3 id="http-api-설계">HTTP API 설계</h3>
<p>HTTP API는 Restful하게 설계해야 사용성과 확장성이 높아진다. 
최소 성숙도 레벨 2(리소스와 메서드의 명확한 분리)를 지켜줘야 한다. </p>
<h3 id="servlet-was">Servlet, WAS</h3>
<ul>
<li>Servlet은 자바에서 요청과 응답을 처리하는데 사용되는 객체이다. </li>
<li>Servlet Container에서 Servlet객체를 싱글톤(singleton)으로 관리해 자원을 효율적으로 사용한다</li>
<li>웹 어플리케이션 서버(WAS)는 여러 사용자의 요청을 Multi Thread로 처리하여 높은 성능을 유지할 수 있다 </li>
</ul>
<h3 id="ssr과-csr">SSR과 CSR</h3>
<ul>
<li><p>SSR(Server-Side Rendering):
  서버에서 완성된 HTML 페이지를 브라우저로 보내주는 방식</p>
</li>
<li><p>CSR(Client-Side Rendering):
브라우저에서 HTTP API 통신으로 데이터를 받아 동적으로 화면을 구성하는 방식</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[트러블슈팅 - 로직 설계 단계에서 매개변수 선정의 중요성..!]]></title>
            <link>https://velog.io/@d_d/%ED%8A%B8%EB%9F%AC%EB%B8%94%EC%8A%88%ED%8C%85-%EB%A1%9C%EC%A7%81-%EC%84%A4%EA%B3%84-%EB%8B%A8%EA%B3%84%EC%97%90%EC%84%9C-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EC%84%A0%EC%A0%95%EC%9D%98-%EC%A4%91%EC%9A%94%EC%84%B1</link>
            <guid>https://velog.io/@d_d/%ED%8A%B8%EB%9F%AC%EB%B8%94%EC%8A%88%ED%8C%85-%EB%A1%9C%EC%A7%81-%EC%84%A4%EA%B3%84-%EB%8B%A8%EA%B3%84%EC%97%90%EC%84%9C-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EC%84%A0%EC%A0%95%EC%9D%98-%EC%A4%91%EC%9A%94%EC%84%B1</guid>
            <pubDate>Mon, 20 Jan 2025 04:31:55 GMT</pubDate>
            <description><![CDATA[<h2 id="트러블슈팅--printmenu-메서드-호출-시-불필요한-출력-발생-문제-해결">트러블슈팅 : printMenu 메서드 호출 시 불필요한 출력 발생 문제 해결</h2>
<h3 id="문제-상황">문제 상황</h3>
<p>Kiosk 클래스의 start 메서드에서 printMenu 메서드를 호출할 때, 프로그램은 전체적으로 실행되었지만, 원치 않는 출력이 추가로 표시되는 문제가 있었습니다.</p>
<h3 id="원인-분석">원인 분석</h3>
<ul>
<li>printMenu 메서드가 실행 중 애플리케이션의 상태를 제어할 수 있는 매개변수를 고려하지 않았습니다.</li>
<li>start 메서드에서 루프 내 조건 없이 printMenu를 호출했기 때문에, 불필요한 출력이 계속해서 생성되었습니다.</li>
<li>실행 흐름 제어를 위한 boolean isRunning 변수가 제대로 전달되지 않아, 불필요한 출력이 반복적으로 발생한 것입니다.</li>
</ul>
<h3 id="해결-방법">해결 방법</h3>
<ol>
<li><p>매개변수 추가
 printMenu 메서드에 boolean isRunning 매개변수를 추가하여, 프로그램의 실행 상태를 기반으로 출력 로직을 제어할 수 있도록 수정했습니다.</p>
</li>
<li><p>호출부 수정
 start 메서드에서 isRunning 변수를 적절히 갱신하면서, 이를 printMenu에 전달하도록 업데이트했습니다.</p>
</li>
</ol>
<h3 id="수정된-코드">수정된 코드</h3>
<h4 id="기존-코드">기존 코드</h4>
<pre><code>public void start() {
    while (true) {
        printMenu(cart, scanner);
    }
}

private void printMenu(Cart cart, Scanner scanner) {
    System.out.println(&quot;Menu options...&quot;);
    // 잘못된 상태에서 불필요한 출력 발생
}
</code></pre><h4 id="수정-후">수정 후</h4>
<p><img src="https://velog.velcdn.com/images/d_d/post/6d1b13ea-bfc8-42a0-9b2b-786590252326/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/d_d/post/e63a45cb-b061-4978-8235-fffc7d39dd13/image.png" alt=""></p>
<h3 id="결과">결과</h3>
<ul>
<li>isRunning 변수를 통해 실행 흐름을 명확히 제어하면서 불필요한 출력이 발생하지 않도록 개선되었습니다.</li>
<li>프로그램이 의도한 대로 동작하며, 사용자 경험이 향상되었습니다.</li>
</ul>
<h3 id="배운점">배운점</h3>
<p>이 문제를 해결하면서 프로그램 실행 흐름 제어의 중요성을 깨달았습니다. 특히, 상태를 관리하는 변수를 명확히 정의하고, 이를 적절히 활용하는 것이 프로그램의 안정성과 유지보수성을 크게 높인다는 점을 배웠습니다.</p>
<p>또한 불필요한 출력을 제어하는 과정에서 로직 설계 단계에서의 매개변수 선정이 얼마나 중요한지를 실감했습니다. 이 경험을 바탕으로, 앞으로는 메서드 설계 시 매개변수로 전달해야 할 상태나 조건을 사전에 꼼꼼히 고려할 것입니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바의 메모리 정리]]></title>
            <link>https://velog.io/@d_d/%EC%9E%90%EB%B0%94%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@d_d/%EC%9E%90%EB%B0%94%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Fri, 17 Jan 2025 12:30:07 GMT</pubDate>
            <description><![CDATA[<p>코드가 실행될 때 선언된 필드, 메서드 등이 메모리로 올라간다. 메모리로 올라가 있는 필드와 메서드 등이 코드가 실행되면서 사용되는 것이다. </p>
<p>클래스를 만들고, 메인 메서드에서 해당 클래스의 필드와 메서드를 사용하려 할 때 
Class.feild;
Class.method();
이러한 방식으로 호출할 수 없는 이유는, 인스턴스화 되지 않은 클래스는 실체가 없어서 해당 클래스가 메모리에 올라오지 않았기 때문이다. 
클래스가 메모리에 없기 때문에, 해당 클래스의 필드와 메서드도 사용할 수 없는 것은 당연한 일 일거다. </p>
<p>클래스를 사용하려면 
Class class = new Class(); 
와 같이 먼저 인스턴스화 시켜줘야 한다. </p>
<p>객체로 만들어진 클래스는 메모리로 올라오고, 메모리에 있기 때문에 사용할 수 있다. 
class.feild;<br>이렇게 말이다. </p>
<p>그렇다면 
System.out.print()
이런 경우는 어떻게 가능할까??</p>
<p>해당 클래스가 static인 경우 인스턴스화 시킬 필요 없이 사용할 수 있다. </p>
<p>static 키워드가 붙어있는 경우, 실행될 때 바로 메모리에 올라간다. 따라서 객체를 만들 필요 없이 바로 사용 가능!</p>
<p>그럼 전부 static으로 만들지, 왜 굳이 힘들게 인스턴스화 시키고 어쩌구 저쩌구 복잡하게 하냐고??
-&gt; 
static 은 정적이라는 뜻을 가지고 있다. 즉 한 번 메모리에 올라가서 변하지 않는다. </p>
<p>Human human1 = new Human();
Human human2 = new Human();</p>
<p>human1.name = 장원영;
human2.name = 차은우;</p>
<p>이렇게 만들어진 객체별로 다른 이름을 가질 수 있어야 하는데, static으로 메모리에 올라간 경우에는 위의 경우 human1, human2 모두 차은우 이름을 가지게 된다. </p>
<p>따라서 의도적으로 static을 사용하는 경우를 제외하고, 대부분의 경우 static을 사용하지 않는다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바] 리스트에서 특정 요소의 데이터 가져오기 getter]]></title>
            <link>https://velog.io/@d_d/%EC%9E%90%EB%B0%94</link>
            <guid>https://velog.io/@d_d/%EC%9E%90%EB%B0%94</guid>
            <pubDate>Tue, 14 Jan 2025 01:47:30 GMT</pubDate>
            <description><![CDATA[<p>키오스크 기능을 구현하면서 원하는 메뉴의 번호를 선택하면 해당 메뉴에 대한 이름/가격/설명만 출력되도록 하고 싶었는데, 모든 메뉴의 정보가 다 나오는 문제가 있었다. 아래와 같이 출력되었다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/106f1079-4230-4bff-b3a6-c1931f9f4c61/image.png" alt=""></p>
<p>모든 메뉴가 출력되었던 이유는 menuItemX.getMenuItem()을 호출했을 때 선택한 메뉴만 출력하는 대신, 
getMenuItem이 반환하는 문자열을 그대로 출력하기 때문이었음!
문제는 getMenuItem 메서드가 메뉴 이름, 가격, 설명을 전부 포함한 문자열을 반환하도록 설계되어 있다는 점에 있었다.</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/416dc27b-99ba-4b5b-9651-94f12e7c7bc8/image.png" alt=""></p>
<p>아래 두가지를 수정할 필요가 있었다. </p>
<ol>
<li>각 데이터에 접근할 메서드를 별도로 추가하여 필요한 정보만 가져오도록</li>
<li>switch 구문에서 getMenuItem() 대신 필요한 데이터만 출력하도록 변경</li>
</ol>
<p>MenuItem 클래스에서 getMenuItem 대신, 이름/가격/설명의 정보를 가져오는 get메서드를 각각 생성했다.</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/e4aa3b88-cb46-4543-bc9a-400954d78547/image.png" alt=""></p>
<p>main메서드 에서는 선택된 메뉴의 이름/가격/설명을 각각 가져와 출력하게 했다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/908bd007-3dab-4602-a442-50b1d2aabc0f/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바] Get 메서드로 객체의 내용을 가져오고 싶은데, 메모리 주소가 반환될 때]]></title>
            <link>https://velog.io/@d_d/%EC%9E%90%EB%B0%94-Get-%EB%A9%94%EC%84%9C%EB%93%9C%EB%A1%9C-%EA%B0%9D%EC%B2%B4%EC%9D%98-%EB%82%B4%EC%9A%A9%EC%9D%84-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B3%A0-%EC%8B%B6%EC%9D%80%EB%8D%B0-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%A3%BC%EC%86%8C%EA%B0%80-%EB%B0%98%ED%99%98%EB%90%A0-%EB%95%8C</link>
            <guid>https://velog.io/@d_d/%EC%9E%90%EB%B0%94-Get-%EB%A9%94%EC%84%9C%EB%93%9C%EB%A1%9C-%EA%B0%9D%EC%B2%B4%EC%9D%98-%EB%82%B4%EC%9A%A9%EC%9D%84-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B3%A0-%EC%8B%B6%EC%9D%80%EB%8D%B0-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%A3%BC%EC%86%8C%EA%B0%80-%EB%B0%98%ED%99%98%EB%90%A0-%EB%95%8C</guid>
            <pubDate>Mon, 13 Jan 2025 12:04:40 GMT</pubDate>
            <description><![CDATA[<p>키오스크 기능을 구현하는 과제를 진행하던 중 객체의 내용을 출력하고 싶은데, 메모리 주소가 출력되는 문제가 있었다. 당시 코드는 아래와 같았다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/b374e585-c452-4994-9dc9-d3fef40a75f1/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/d_d/post/33bea11f-9088-44b9-8b57-65614db03c3e/image.png" alt=""></p>
<p>MenuItem 클래스의 getMenuItem 메서드는 this 객체를 반환하고 있다. 
그래서 System.out.println(menuItem.getMenuItem());이 실행될 때 menuItem 객체의 메모리 주소가 출력되고 있다. </p>
<p>이를 수정하려면, MenuItem 클래스에 toString 메서드를 오버라이딩 하거나 getMenuItem 메서드를 수정해 메뉴 이름, 가격, 설명을 반환하도록 해야 할 것이다.</p>
<p>따라서 아래와 같이 수정해보았다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/ab863b1b-af14-445a-8533-b93645b78058/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/d_d/post/7fa24657-2c6f-47db-a5fa-a63475872165/image.png" alt=""></p>
<p>getMenuItem() 메서드에서 MenuItem의 내용들을 String타입으로 반환하도록 수정하였고,
main메서드에서 menuItems 리스트에 저장된 menuItme의 getMenuItem() 메서드를 호출하도록 수정하여 문제를 해결할 수 있었다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[사칙연산 계산기 과제 트러블 슈팅 - Scanner,  IndexOutOfBoundsException]]></title>
            <link>https://velog.io/@d_d/%EC%82%AC%EC%B9%99%EC%97%B0%EC%82%B0-%EA%B3%84%EC%82%B0%EA%B8%B0-%EA%B3%BC%EC%A0%9C-%ED%8A%B8%EB%9F%AC%EB%B8%94-%EC%8A%88%ED%8C%85-Scanner-IndexOutOfBoundsException</link>
            <guid>https://velog.io/@d_d/%EC%82%AC%EC%B9%99%EC%97%B0%EC%82%B0-%EA%B3%84%EC%82%B0%EA%B8%B0-%EA%B3%BC%EC%A0%9C-%ED%8A%B8%EB%9F%AC%EB%B8%94-%EC%8A%88%ED%8C%85-Scanner-IndexOutOfBoundsException</guid>
            <pubDate>Fri, 10 Jan 2025 01:40:47 GMT</pubDate>
            <description><![CDATA[<p>사칙연산 계산기 과제를 진행하면서 크고 작은 문제들을 마주했고, 그것들을 해결하며 코딩을 +1 더 알게 된 것 같다. 오늘은 그 내용을 정리해보려 한다. </p>
<h3 id="1-scanner로-입력받을-때-예외-발생">1. Scanner로 입력받을 때 예외 발생</h3>
<p>현상:
피연산자, 연산자, 데이터 조회 여부, 저장 여부, 삭제 여부 등등 사용자로 부터 여러 입력을 받아 계산기가 구동하도록 코드를 짰기 때문에, 적절하지 않은 입력이 들어왔을 때 예외가 발생하며 프로그램이 비정상적으로 종료되었다. 이로 인해 예외 이후의 코드가 실행되지 못하고 사용자는 프로그램을 재실행해야만 하는 문제가 있었다. </p>
<p>원인:
Scanner.nextInt() 메서드는 입력값이 정수형이 아닌 경우 InputMismatchException을 발생시킨다. 사용자가 잘못된 입력을 하는 경우는 그래도 예외의 원인을 찾기 쉽지만, 입력 버퍼에 개행 문자(\n)이 남아있는 경우에는 이유도 모른채 예외가 발생하곤 한다. 또한 해당 예외를 처리하지 않으면 프로그램이 강제로 종료된다.</p>
<p>해결 과정:
    1. 예외 처리 추가
    try-catch 블럭을 추가하여 예외가 발생했을 때 프로그램이 종료되지 않고 사용자에게 재입력을
    요청하도록 했다. </p>
<ol start="2">
<li>남은 입력값 제거
입력 버퍼에 남아 있는 잘못된 입력값을 제거하지 않으면 무한 루프에 빠질 위험이 있다. 이를 방지하기 위해 catch블럭에서 Scanner.nextLine()을 호출하여 잘못된 입력을 제거했다. 
<img src="https://velog.velcdn.com/images/d_d/post/11efb335-c119-4fcb-91a8-b612e1405415/image.png" alt=""></li>
</ol>
<ol start="3">
<li>예외 테스트
다양한 잘못된 입력값(문자, 특수문자, 공백 등)을 입력하여 예외처리가 제대로 작동하는지 확인하였고, 테스트 결과, 오류가 발생했을 때 프로그램이 종료되지 않고 정상적으로 재입력을 받을 수 있음을 확인했다. </li>
</ol>
<p>결과:
이러한 수정 작업을 통해 사용자 입력 오류가 발생하더라도 프로그램이 종료되지 않고 안정적으로 작동하도록 개선되었으며, 잘못된 입력값으로 인한 무한 루프 문제가 해결되어 프로그램의 사용성을 높였다. </p>
<h3 id="2-list-조회-시-indexoutofboundsexception">2. List 조회 시 IndexOutOfBoundsException</h3>
<p>현상:
저장된 연산결과가 없는 상태에서 사용자가 결과를 조회하려고 getList() 메서드를 호출하면 IndexOutOfBoundsException이 발생하며 프로그램이 종료되었다.</p>
<p>원인:
getList() 메서드는 내부적으로 리스트의 마지막 요소를 가져오기 위해 list.get(list.size() - 1)을 호출한다. 그러나 리스트가 비어 있는 경우 list.size()는 0이 되고, 인덱스가 -1로 계산되어 예외가 발생한다. 이는 비어 있는 리스트에 접근하려는 시도가 문제의 핵심</p>
<p>해결 과정:
getList() 메서드에 리스트가 비어 있는지 확인하는 조건문을 추가했다. 만약 리스트가 비어 있다면 예외를 발생시키는 대신 사용자에게 &quot;저장된 연산 결과가 없습니다.&quot;라는 메시지를 출력하고 null을 반환하도록 수정</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/94411b13-be38-4f3e-aafc-f1a90f2190b4/image.png" alt=""></p>
<p>결과:
리스트가 비어 있을 때 발생하던 예외를 방지하고, 사용자에게 결과가 없음을 명확히 알릴 수 있도록 프로그램의 안정성과 사용자 경험을 개선. 이는 이후 다른 메서드(removeResult 등)에서도 동일한 문제가 발생하지 않도록 기본적인 방어 코드를 추가하였다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바 열거형(Enum)을 활용하여 상수 값을 하나의 데이터 타입으로 관리하기]]></title>
            <link>https://velog.io/@d_d/%EC%9E%90%EB%B0%94-%EC%97%B4%EA%B1%B0%ED%98%95Enum%EC%9D%84-%ED%99%9C%EC%9A%A9%ED%95%98%EC%97%AC-%EC%83%81%EC%88%98-%EA%B0%92%EC%9D%84-%ED%95%98%EB%82%98%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%EC%9C%BC%EB%A1%9C-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@d_d/%EC%9E%90%EB%B0%94-%EC%97%B4%EA%B1%B0%ED%98%95Enum%EC%9D%84-%ED%99%9C%EC%9A%A9%ED%95%98%EC%97%AC-%EC%83%81%EC%88%98-%EA%B0%92%EC%9D%84-%ED%95%98%EB%82%98%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%EC%9C%BC%EB%A1%9C-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 09 Jan 2025 11:37:23 GMT</pubDate>
            <description><![CDATA[<h3 id="enum">Enum</h3>
<p>Enum(열거형)은 여러 상수 값을 하나의 데이터 타입으로 정의할 수 있는 클래스이다. 
고정된 값들을 안전하게 다룰 수 있다는 장점이 있고, 
클래스처럼 생성자, 메서드 등을 정의할 수 있어서 다양한 기능을 포함할 수 있다. </p>
<p>enum 키워드를 사용하여 정의하며, 기본적으로 아래와 같은 형식을 가진다. </p>
<pre><code>public enum EnumName {
    CONSTANT1,
    CONSTANT2,
    CONSTANT3;
}</code></pre><p>과제로 만들고 있는 &#39;사칙연산 수행하는 계산기&#39; 에서 연산자로 받는 문자 종류에 따라 문제가 발생할 수 있어서, 연산자를 Enum으로 정의하여 활용해보았다. 아래와 같다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/8fcd71e8-b1be-4e1d-9771-91bdabecdb57/image.png" alt=""></p>
<p>기존에 String 타입으로 연산자를 받았을 때 지정된 연산자 이외의 String 값이 실수로 입력되는 경우 문제가 되었는데, 이렇게 enum을 사용하여 해당 문제를 개선할 수 있었다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바 예외 처리 try {throw new Exception(); } catch (Exception e) {}]]></title>
            <link>https://velog.io/@d_d/%EC%9E%90%EB%B0%94-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC-try-throw-new-Exception-catch-Exception-e</link>
            <guid>https://velog.io/@d_d/%EC%9E%90%EB%B0%94-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC-try-throw-new-Exception-catch-Exception-e</guid>
            <pubDate>Tue, 07 Jan 2025 12:13:38 GMT</pubDate>
            <description><![CDATA[<p>코드를 짜고 실행하는 과정에서 여러 문제들이 발생할 수 있고,
예상되는 문제들을 정교하게 정의 해둘수록 대응하기 좋다. </p>
<p>그래서 필요한 것이 예외 처리, exception handling 이다. </p>
<h3 id="exception">Exception</h3>
<p>발생하는 대부분의 예외들은 이미 예외 처리 방법이 정리 되어 있다. 따라서 이미 있는 예외 클래스를 활용해서 예외 처리를 하면 된다. </p>
<p>예외 클래스로 정리되어 있지 않은 예외라고 해도, 직접 해당 예외를 정의하여 사용하면 된다. </p>
<p>오늘은 이미 구현체가 있는 예외를 처리하는 방법에 대해 먼저 정리해보겠다. </p>
<h3 id="try--catch-">try {} catch {}</h3>
<p>try 문에 예외가 발생할 가능성이 있는 코드를 적고
catch 블럭 내에는 예외가 발생했을 때 구현되어야 하는 코드를 적는다. </p>
<p>전체 구조는 아래와 같다. </p>
<pre><code>try {

} catch (Exception1 e1) {

} catch (Exception2 e2) {

}</code></pre><p>숫자 2개와 연산자 1개를 받아 사칙연산을 수행하는 계산기를 만드는 과제를 진행하고 있는데, try ~ catch    를 사용하여 예외처리를 해보았다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/30fc80f3-2351-41c2-ac49-16906c71e67b/image.png" alt=""></p>
<p>if 에서 적합하지 않은 연산자가 확인되면, 예외를 발생 시켜서 throw 하고, 아래 catch 문들 중 해당 예외 조건에 맞는 catch문이 실행된다. </p>
<p>switch에서도 마찬가지로 분모에 0이 들어왔을 때 예외를 발생시켜 throw 하고, catch 문들 중 해당 예외에 맞는 catch 문이 실행된다. </p>
<hr>
<p>예외를 발생 시켜 throw하지 않는 방식으로도 try ~ catch 를 활용할 수 있다. </p>
<p>아래는 계산 관련 필드와 메서드가 선언되어 있는 클래스를 실행해보는 메인 메서드의 모습 중 일부이다. </p>
<p>계산할 숫자, 연산자 등 Scanner를 통해 입력받는 값이 많아, 오류가 많을 것으로 예상 된다. </p>
<p>따라서 기존에 작성했던 모든 코드들을 try {} 에 넣고,
catch (Exception) {} 을 추가하여,
예상치 못한 예외가 발생하였을 때, 비정상 종료 없이 계산기를 계속 실행할 수 있도록 하였다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/0eda4330-a6a2-4bb7-bec3-43c2eeacec4b/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/d_d/post/ff5aba26-94ee-439e-bb33-9add4a7b40b0/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[java] 접근제어자로 보호된 데이터 조회/수정 - getter, setter]]></title>
            <link>https://velog.io/@d_d/java-%EC%A0%91%EA%B7%BC%EC%A0%9C%EC%96%B4%EC%9E%90%EB%A1%9C-%EB%B3%B4%ED%98%B8%EB%90%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A1%B0%ED%9A%8C%EC%88%98%EC%A0%95-getter-setter</link>
            <guid>https://velog.io/@d_d/java-%EC%A0%91%EA%B7%BC%EC%A0%9C%EC%96%B4%EC%9E%90%EB%A1%9C-%EB%B3%B4%ED%98%B8%EB%90%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A1%B0%ED%9A%8C%EC%88%98%EC%A0%95-getter-setter</guid>
            <pubDate>Fri, 03 Jan 2025 12:49:54 GMT</pubDate>
            <description><![CDATA[<p>코딩을 하다 보면 감춰야 하는 데이터가 생기기 마련이다. 
이때 접근제어자 (public, default 등)을 사용하여 데이터를 보호할 수 있다. </p>
<p>그러나 접근제어자로 보호된 데이터를 사용해야 하는 경우도 있지 않겠는가!</p>
<p>이때 필요한 기능이 바로 getter와 setter이다. </p>
<h3 id="getter">Getter</h3>
<p>: 외부에서 객체의 private한 필드를 읽어올 필요가 있을 때, getter 메서드를 사용할 수 있다. </p>
<p>ex, </p>
<pre><code>private String model;
private double price;

public String getModel() {
    return model;
}

public double getPrice(){
    return price;
}</code></pre><p>getter 메서드의 이름은 카멜케이스를 기초로 하며, &#39;get + 필드명&#39;으로 짓는 것이 원칙이다. </p>
<p>인스턴스를 생성한 후
인스턴스명.getPrice();
로 호출하여 getter 메서드를 사용할 수 있다. </p>
<h3 id="setter">Setter</h3>
<p>: 외부에서 객체의 private한 필드를 수정/저장해야 할 때, setter 메서드를 사용하면 된다. </p>
<p>ex,</p>
<pre><code>public void setModel(String model){
    this.model = model;
}

public void setPrice(double Price){
    this.price = price;
}</code></pre><p>Setter의 이름 짓는 법과 호출 방법은 getter와 동일하다. </p>
<h3 id="실제-사용-예시">실제 사용 예시</h3>
<p>계산기 과제를 하다가, 계산 결과를 저장하는 컬랙션을 private으로 캡슐화하고,
해당 데이터를 조회 및 추가 저장 할 수 있도록 getter, setter 메서드를 활용해보았다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/648262e6-e8f2-4a1f-a526-f5c93667608d/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/d_d/post/550149cc-1b43-4d0d-8edc-69410e983606/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바 오류 이유 : 배열 길이 선언 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length]]></title>
            <link>https://velog.io/@d_d/%EC%9E%90%EB%B0%94-%EC%98%A4%EB%A5%98-%EC%9D%B4%EC%9C%A0-%EB%B0%B0%EC%97%B4-%EA%B8%B8%EC%9D%B4-%EC%84%A0%EC%96%B8-Exception-in-thread-main-java.lang.ArrayIndexOutOfBoundsException-Index-0-out-of-bounds-for-length</link>
            <guid>https://velog.io/@d_d/%EC%9E%90%EB%B0%94-%EC%98%A4%EB%A5%98-%EC%9D%B4%EC%9C%A0-%EB%B0%B0%EC%97%B4-%EA%B8%B8%EC%9D%B4-%EC%84%A0%EC%96%B8-Exception-in-thread-main-java.lang.ArrayIndexOutOfBoundsException-Index-0-out-of-bounds-for-length</guid>
            <pubDate>Thu, 02 Jan 2025 00:46:22 GMT</pubDate>
            <description><![CDATA[<p>프로그래머스 &#39;x만큼 간격이 있는 n개의 숫자&#39; 알고리즘 문제를 풀다가 마주한 문제들과 해결 과정을 정리해보려 한다. </p>
<p>처음에 아래와 같이 코드를 작성해서 체점을 해보니</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/ad77a2f6-68c1-4360-963f-44f78ceb4a47/image.png" alt=""></p>
<p>이런 오류 문구가 떴다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/64a431ab-091a-46ba-b915-2ae74667d207/image.png" alt=""></p>
<p>알아보니, 인덱스의 크기가 배열의 크기보다 크게 나온 경우 혹은 마이너스로 나오는 경우 위와 같은 에러가 난다고 한다. </p>
<p>다시 코드를 보니, 문제를 켰을 때 자동으로 선언되는 배열을 그대로 쓰느라 길이도 제대로 선언하지 않은 것 확인..</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/7c3378d1-a229-4a20-bc2e-42245a033386/image.png" alt=""></p>
<p>이번엔 배열을 제대로 선언했는데,</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/783e99a1-6807-46b4-ba86-6a349fd5b1db/image.png" alt=""></p>
<p>배열에 들어가는 값을 잘못 계산하도록 한 문제도 있었음!</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/f676d5a0-c6c2-49e0-8bd7-fb90573a8230/image.png" alt=""></p>
<p>제대로 계산하도록 바꿨는데도??
<img src="https://velog.velcdn.com/images/d_d/post/2a646822-0b6d-4165-880d-93b4cc338c79/image.png" alt=""></p>
<p>테스트 13,14는 계속 오류..ㅠㅠ </p>
<p>다시 찬찬히 살펴보니, 
<img src="https://velog.velcdn.com/images/d_d/post/d0227a80-c95d-4f27-b6c3-83d41216eff1/image.png" alt=""></p>
<p>x 크기가 커서 int로 감당할 수 없는 것이었던 것!</p>
<p>프로그래머스에서 기본으로 세팅할 때 왜 long[]이라고 했는지 눈치를 챘었어야 함!</p>
<p>long으로 형변환을 한 뒤에야 마참내 정답! </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/5df43773-7bf9-48a5-b2a7-e18a1d9aa2e6/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바 알고리즘] 숫자를 array로 변환하는 방법]]></title>
            <link>https://velog.io/@d_d/%EC%9E%90%EB%B0%94-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%88%AB%EC%9E%90%EB%A5%BC-array%EB%A1%9C-%EB%B3%80%ED%99%98%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@d_d/%EC%9E%90%EB%B0%94-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%88%AB%EC%9E%90%EB%A5%BC-array%EB%A1%9C-%EB%B3%80%ED%99%98%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Fri, 27 Dec 2024 11:50:34 GMT</pubDate>
            <description><![CDATA[<p>자바 알고리즘 문제를 풀다 아래와 같은 문제를 만났는데..! 어려웠다..ㅎ</p>
<p><img src="https://velog.velcdn.com/images/d_d/post/8c8ad55f-d370-4ec6-8b8f-18fed6d27079/image.png" alt=""></p>
<p>주어지는 자연수 N의 각 자릿수를 array로 만들고
for문으로 array의 모든 값을 더해주면 되겠다는 생각은 했지만,
문제는 !그래서 그걸 어케 하는 건지! 모르겠었음</p>
<ol>
<li>int를 String으로 형변환 하는 법</li>
<li>String을 String Array로 만드는 법</li>
<li>String Array를 int Array로 변환하는 법</li>
</ol>
<p>위 3가지 방법을 하나하나 구글링해서, 숫자의 각 자연수를 array로 만들고 문제를 풀었다..!</p>
<ol>
<li><p>int를 String으로 형변환 </p>
<pre><code> String str = new String(n + &quot;&quot;);</code></pre></li>
</ol>
<p>n의 모든 자릿수를 각각 string으로 만들어준다.</p>
<ol start="2">
<li><p>String을 String Array로</p>
<pre><code> String strArr[] = str.split(&quot;&quot;);</code></pre></li>
</ol>
<p>strArr이라는 문자 배열을 선언하고
문자열 str의 모든 글자를 쪼개 준다</p>
<ol start="3">
<li><p>String Array를 int Array로 </p>
<pre><code>   int answer[] = new int[strArr.length];

 for (int i=0; i&lt;strArr.length; i++) {
     answer[i] = Integer.parseInt(strArr[i]);
 }    </code></pre></li>
</ol>
<p>for문을 활용하여 strArr[]의 원소 하나하나를 int로 형변환해줍니다. </p>
<p>이렇게 자연수 N을 int Array로 만들어주었으면,
for문으로 array의 요소를 모두 더해주면 끝!</p>
<pre><code>import java.util.*;

public class Solution {
    public int solution(int n) {
        String str = new String(n + &quot;&quot;);
        String strArr[] = str.split(&quot;&quot;);

          int answer[] = new int[strArr.length];

        for (int i=0; i&lt;strArr.length; i++) {
            answer[i] = Integer.parseInt(strArr[i]);
        }        

        int sum = 0;
        for (int i =0; i&lt;answer.length;i++){
            sum = sum +answer[i];
        }

        return sum;
    }
}




</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[java] 나눗셈 한 뒤 소수점까지 출력하는 법 ]]></title>
            <link>https://velog.io/@d_d/java-%EB%82%98%EB%88%97%EC%85%88-%ED%95%9C-%EB%92%A4-%EC%86%8C%EC%88%98%EC%A0%90%EA%B9%8C%EC%A7%80-%EC%B6%9C%EB%A0%A5%ED%95%98%EB%8A%94-%EB%B2%95</link>
            <guid>https://velog.io/@d_d/java-%EB%82%98%EB%88%97%EC%85%88-%ED%95%9C-%EB%92%A4-%EC%86%8C%EC%88%98%EC%A0%90%EA%B9%8C%EC%A7%80-%EC%B6%9C%EB%A0%A5%ED%95%98%EB%8A%94-%EB%B2%95</guid>
            <pubDate>Thu, 26 Dec 2024 11:33:18 GMT</pubDate>
            <description><![CDATA[<p>프로그래머스 알고리즘 문제를 풀다 아래와 같은 문제를 만났다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/8cdff7f9-0a8e-4ad6-a42e-93800818e586/image.png" alt=""></p>
<p>원소의 평균값을 리턴해야 하므로, 원소를 다 더하고, 원소의 개수만큼 나눈 값을 리턴하도록 아래와 같이 코딩했는데 실패가 떴다.</p>
<pre><code>class Solution {
    public double solution(int[] numbers) {
        double answer = 0;
        int sum = 0;
        for(int i = 0; i &lt; numbers.length; i++){
            sum = sum + numbers[i];
        }
        answer = sum / numbers.length;
        return answer;
    }
}</code></pre><p>그 이유는, 자바에선 나누기로 &#39;/&#39;기호를 쓰면 몫만 결과값으로 가지게 되기 때문!</p>
<p>나누기할 때에 소수점까지 결과로 가져오고 싶다면, 나누는 수 혹은 나누어지는 수를 double로 형변환(형 설정?)을 해주어야 한다. </p>
<pre><code>    answer = sum / (double)numbers.length;

    answer = (double)sum / numbers.length;

    answer = (double)sum / (double)numbers.length;</code></pre><p>위의 세가지 경우 모두 정답으로 처리 되었다..!</p>
<p>다만 아래와 같이 (double)(sum / numbers.length); 이라고 작성하는 경우에는 정답이 아니게 된다. </p>
<p>자바의 나누기(/) 연산이 끝난 시점에서 이미 소수점 정보를 잃어버린 int로 결과값을 가지게 되어버린 상태이고, 그 이후에 double로 바꿔줘봤자 잃어버린 소수점을 되찾을 수 없어서 라고 해석할 수 있을 것이다. </p>
<p><img src="https://velog.velcdn.com/images/d_d/post/c321eb33-e8fd-40df-8188-81fd569fd176/image.png" alt=""></p>
]]></description>
        </item>
    </channel>
</rss>