<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>babambak.velog</title>
        <link>https://velog.io/</link>
        <description>주니어 백엔드 개발자의 개발 log💻</description>
        <lastBuildDate>Sun, 07 Dec 2025 13:34:44 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>babambak.velog</title>
            <url>https://velog.velcdn.com/images/jinny-park/profile/9c55f482-625c-4316-a3f2-d49c89cb5895/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. babambak.velog. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jinny-park" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[스프링 API RequestDTO 구조/설계에 대한 정리]]></title>
            <link>https://velog.io/@jinny-park/%EC%8A%A4%ED%94%84%EB%A7%81-API-RequestDTO-%EA%B5%AC%EC%A1%B0%EC%84%A4%EA%B3%84%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@jinny-park/%EC%8A%A4%ED%94%84%EB%A7%81-API-RequestDTO-%EA%B5%AC%EC%A1%B0%EC%84%A4%EA%B3%84%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 07 Dec 2025 13:34:44 GMT</pubDate>
            <description><![CDATA[<p>스프링에서 API RequestDTO 구조 설계를 어떻게 해야하는지에 대해 알아보고 싶은게 있어서 정리한다. </p>
<p>일단 requestBody 어노테이션을 통해서 요청 DTO를 처리 할때 List<DTO> 형태로 받는것이 맞는 것인지 DTO 클래스 안에 List<DTO>를 정의해서 받는 것이 맞는 것 일지 궁금증이 생겼다. </p>
<p>✅ 1. @RequestBody List<DTO>로 받는 것 — 가능함</p>
<pre><code>@PostMapping(&quot;/test&quot;)
public ResponseEntity&lt;Void&gt; test(@RequestBody List&lt;DTO&gt; request) {
    ...
}</code></pre><p>✔ 장점</p>
<ul>
<li>구조가 단순해서 한번에 여러 DTO를 보낼 때 직관적이다</li>
<li>불필요한 wrapper 객체가 필요 없다,. 
✔ 단점</li>
<li>확장성(추가 필드 필요시)이 떨어진다.</li>
<li>특정기업/서비스의 공통 API 규약과 충돌이 날 수 있다. 
  → 많은 기업은 항상 객체 기반 JSON을 요구 (배열 루트 구조 금지)\</li>
</ul>
<p>✅ 2. DTO 안에 List를 포함해서 받는 것 — 조직·확장성 좋은 구조</p>
<pre><code>@PostMapping(&quot;/test&quot;)
public ResponseEntity&lt;Void&gt; test (@RequestBody TestRequest request) {
    ...
}
public class TestRequest {
    private List&lt;DTO&gt; tests;
}
</code></pre><p>✔ 장점</p>
<ul>
<li>확장이 매우 쉽다. </li>
<li>API 문서화 및 버전 관리가 용이하다.</li>
<li>대부분의 회사/플랫폼 API 규칙과 일관성 있다. 
✔ 단점</li>
<li>단순 배열 요청보다 구조가 한단계 깊어진다. </li>
</ul>
<p>✅결론 요약을 하자면 
<img src="https://velog.velcdn.com/images/jinny-park/post/b8debcda-dd19-42a7-8b5e-c5584b2d4233/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JDK 11 제네릭 메소드에 대한 정리 ]]></title>
            <link>https://velog.io/@jinny-park/JDK-11-%EC%A0%9C%EB%84%A4%EB%A6%AD-%EB%A9%94%EC%86%8C%EB%93%9C%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@jinny-park/JDK-11-%EC%A0%9C%EB%84%A4%EB%A6%AD-%EB%A9%94%EC%86%8C%EB%93%9C%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 07 Dec 2025 13:14:22 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-전체-구조-분석">✔️ 전체 구조 분석</h3>
<pre><code>public static &lt;T&gt; Myclass&lt;T&gt; method() { }</code></pre><p>[접근제어자] [static] &lt;타입매개변수&gt; 반환타입 메서드명(매개변수...) </p>
<p>여기서 타입매개변수 부분이 바로 제네릭 메서드임을 선언하는 부분이다. </p>
<h3 id="✔️-포인트-핵심">✔️ 포인트 핵심</h3>
<p>1) <T> 는 메서드 자체의 제네릭 타입 선언을 의미한다. 
  이 메서드는 내부에서 사용할 T타입을 메서드에서 선언한 것이다. 
  즉, 클래스가 제네렉이 아니더라도 메서드는 제네릭일 수 있음을 의미한다. </p>
<pre><code>   public class Test {
    public static &lt;T&gt; T identity(T value) {
        return value;
    }
}</code></pre><p>2) 반환 타입이 Myclass<T></p>
<p>이 메서드는 T타입을 타입 인자로 하는 Myclass객체를 반환한다.</p>
<pre><code>Myclass&lt;String&gt; obj = method();  // T가 String으로 추론
Myclass&lt;Integer&gt; obj2 = method();  // T가 Integer로 추론</code></pre><p>3) static 메서드이므로 클래스 제네릭과는 무관</p>
<pre><code>public class A&lt;T&gt; {
    public static T method() {}  // ❌ 불가능
}</code></pre><p>static에서는 클래스 제네릭 T를 쓸 수 없다. 
그래서 static 메서드에서 제네릭을 쓰고 싶다면 무조건 <T>를 선언해야한다. </p>
<pre><code>public class A {
    public static &lt;T&gt; T method() {}  // ⭕

}</code></pre><p>✔️ 팁
static에서 제네릭 사용 시 항상 <T>를 메서드 선언 앞에 넣는다.
<T>는 “메서드 전용 제네릭 타입”임을 나타낸다.
<T>는 반환타입 앞에만 붙을 수 있다 (접근 제어자와 static 뒤).</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB Config설정과 TransactionManager 정리]]></title>
            <link>https://velog.io/@jinny-park/DB-Config%EC%84%A4%EC%A0%95-%ED%8C%8C%EC%9D%BC-%EC%84%A4%EB%AA%85%EA%B3%BC-TransactionManager-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@jinny-park/DB-Config%EC%84%A4%EC%A0%95-%ED%8C%8C%EC%9D%BC-%EC%84%A4%EB%AA%85%EA%B3%BC-TransactionManager-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 07 Dec 2025 12:54:38 GMT</pubDate>
            <description><![CDATA[<p>스프링 부트에서 사용되는 DataSource와 TransactionManager에 대한 개념을 정리해보려고한다. </p>
<h3 id="✅-한-줄-요약">✅ 한 줄 요약</h3>
<p>🔹 Hikari = 빠른 커넥션 푼 + 로컬 트랜잭션 전용
🔹 Atomikos = 전역(JTA/XA) 분산 트랜잭션 용 
둘은 같은 DataSource처럼 보이지만, 역할이 완전히 다르다.</p>
<h3 id="✅-hikari">✅ Hikari?</h3>
<ol>
<li>JDBC 커넥션 풀</li>
<li>목적 : DB커넥션을 빠르고, 적게, 효율적으로 재사용하기 위해 존재</li>
</ol>
<p>트랜잭션 매니저 없음 ❌
분산 트랜잭션 없음 ❌
그냥 커넥션 대여소 역할만 함</p>
<p>✅ Hikari의 역할 정리
<img src="https://velog.velcdn.com/images/jinny-park/post/318da507-9ce5-4f0b-8bec-78dea39a8cd3/image.png" alt=""></p>
<p>✅ Hikari + Spring 트랜잭션 구조</p>
<p>[서비스 @Transactinal]
        ⬇️
[DataSourceTransactionManager]    ← 스프링이 커밋/롤백을 담당한다.
        ⬇️
[HikariDataSource]                  ← 커넥션만 빌려줌
        ⬇️
[DB]</p>
<p>정리?
• 커밋/롤백 주체는 스프링이다.
• Hikari는 커넥션만 제공한다.
• 트랜잭션 범위 = DB 1개( 로컬 크랜잭션)
• dataSource 빈 등록 할 떄 트랜잭션 매니저 등록도 이루어져야지 스프링 트랜잭션 매니저가 관리</p>
<p>✅ Hikari는 언제 쓰냐?
 • 단일 DB 트랜잭션
 • 일반적인 웹 서비스 90%
 • MyBatis, JPA 대부분의 경우
 • 분산 트랜잭션 필요 없을 때</p>
<h3 id="✅-atomikos란">✅ Atomikos란?</h3>
<ol>
<li>JTA/XA 기반 전역(분산) 트랜잭션 매니저</li>
<li>목적 : 여러 DB, 여러 시스템을 하나의 트랜젹션처럼 묶기 위해 존재</li>
<li>커넥션풀이 아니다.</li>
<li>그냥 dataSource도 맞지만, 사실상 JTA 트랜잭션 참가용 리소스를 의미한다. </li>
</ol>
<p>✅ Atomikos의 역할 정리
<img src="https://velog.velcdn.com/images/jinny-park/post/13b98bb5-2f73-4d6d-b5b7-c94fd4475ffe/image.png" alt=""></p>
<p>✅ Atomikos + Spring 트랜잭션 구조</p>
<p>[ 서비스 @Transactional ]
        ↓
[ JtaTransactionManager ]      ← ✅ Spring이 Atomikos에게 위임
        ↓
[ AtomikosTransactionManager ]← ✅ 실제 전역 트랜잭션 매니저
        ↓
[ AtomikosDataSourceBean ]     ← ✅ XA 리소스
        ↓
[ DB1 ][ DB2 ][ MQ ]           ← ✅ 전부 하나의 트랜잭션</p>
<p>정리?
• 커밋/롤백 주체는 Atomikos다.
• 스프링은 트랜잭션 시작/종료 타이밍만 제어한다.
• 트랜잭션 범위는 여러 DB, MQ, 외부 시스템이다. </p>
<p>✅ Atomikos는 언제 쓰냐?</p>
<p>• db 두개 이상을 한번에 같이 커밋/롤백 해야할 때 사용한다. 
• db + 메세지큐(kafka, rabbitMQ) 같이 묶을 때
• 금융, 정산, 결제, 회계 시스템일 경우
• MSA에서 데이터 정합성을 강하게 보장해야할 때 사용한다.</p>
<p>✅ 3️⃣ Hikari vs Atomikos 핵심 비교표
<img src="https://velog.velcdn.com/images/jinny-park/post/e74ac965-8383-420b-9bd8-a6e1082c558f/image.png" alt=""></p>
<p>✅ Hikari 쓸 때
@Transactional
→ DataSourceTransactionManager
→ HikariDataSource
→ DB</p>
<p>✔ Spring이 commit / rollback 직접 수행
✔ autocommit은 트랜잭션 밖에서만 의미 있음
✔ 단일 DB 전용</p>
<p>✅ Atomikos 쓸 때
@Transactional
→ JtaTransactionManager
→ AtomikosTransactionManager
→ AtomikosDataSourceBean
→ 여러 DB / MQ</p>
<p>✔ 커밋 / 롤백은 Atomikos가 수행
✔ autocommit 개념은 사실상 무효
✔ 전역 트랜잭션</p>
<p>✅ 5️⃣ 언제 뭘 써야 하는지 “실무 기준”</p>
<p>✅ Hikari만 쓰면 되는 경우 (대부분)
“DB 하나만 쓰고”
“서비스 하나만 묶으면 되고”
“속도가 중요하고”
“분산 트랜잭션 필요 없음”
👉 이 경우 Atomikos 쓰면 오히려 독임</p>
<p>✅ Atomikos를 써야 하는 경우
✅ DB A + DB B 동시에 성공해야 함
✅ DB + MQ 같이 묶어야 함
✅ 중간 하나라도 실패하면 전부 롤백되어야 함
👉 이때만 Atomikos가 의미 있음</p>
<p>✅ 최종 결론</p>
<ol>
<li>Hikari는 “빠른 커넥션 풀 + 로컬 트랜잭션용”</li>
<li>Atomikos는 “느리지만 강력한 전역(JTA) 분산 트랜잭션용”</li>
<li>둘은 경쟁 관계가 아니라 완전히 다른 계층의 도구</li>
</ol>
<p>내가 궁금해서 찾아본것은 dataSource 등록 할 때 transactionManager 등록 및 사용에 대한 것이다.</p>
<p>✅ Hikari든 Atomikos든,
@transactional 로 스프링이 트랜잭션을 관리하려면 반드시 <strong>PlatformTransactionManager이</strong> 필요하다. </p>
<p>🔹 차이점은 “누가 그 매니저를 만들어주느냐”다.
Hikari → 내가 직접 만들어줘야 하는 경우가 대부분
Atomikos → Spring Boot가 자동으로 만들어주는 경우가 대부분</p>
<p>그래서 정리하자면</p>
<p>✅ Hikari는 보통 내가 DataSourceTransactionManager를 직접 등록해야 하고,
✅ Atomikos는 Spring Boot starter를 쓰면 JtaTransactionManager가 자동 등록된다.
하지만 둘 다 결국은 PlatformTransactionManager가 있어야
@Transactional이 실제로 동작한다는 점은 완전히 동일하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Hmac / Aes 비밀키 정리 ]]></title>
            <link>https://velog.io/@jinny-park/Hmac-Aes-%EB%B9%84%EB%B0%80%ED%82%A4-%EC%83%9D%EC%84%B1-%EB%B0%8F-%EC%82%AC%EC%9A%A9%EC%97%90-%EB%8C%80%ED%95%B4-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@jinny-park/Hmac-Aes-%EB%B9%84%EB%B0%80%ED%82%A4-%EC%83%9D%EC%84%B1-%EB%B0%8F-%EC%82%AC%EC%9A%A9%EC%97%90-%EB%8C%80%ED%95%B4-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Thu, 27 Nov 2025 16:27:17 GMT</pubDate>
            <description><![CDATA[<p>일단 용어에 대한 간단한 개념 정리!</p>
<h3 id="단방향">단방향</h3>
<p>복호화가 불가능한 해시/서명용 HMAC 키 생성 (예 : HMAC-SHA256)</p>
<h3 id="양방향">양방향</h3>
<p>암/복호화가 가능한 대칭키 (AES-GCM) 생성</p>
<p>✅ 키 설계와 길이 권장안 정리</p>
<table>
<thead>
<tr>
<th>용도</th>
<th>알고리즘</th>
<th align="right">키 길이</th>
<th>비고</th>
</tr>
</thead>
<tbody><tr>
<td>단방향</td>
<td>HMAC-SHA256</td>
<td align="right"><strong>32바이트</strong> (256비트) 이상</td>
<td>토큰 서명/검증, 비밀번호 해시의 “pepper” 등</td>
</tr>
<tr>
<td>양방향</td>
<td>AES-256-GCM</td>
<td align="right"><strong>32바이트</strong> (256비트)</td>
<td>인증(무결성) 포함. Nonce/IV는 <strong>12바이트</strong> 권장</td>
</tr>
</tbody></table>
<p>‼️윈도우 기준으로 정리 예정‼️</p>
<p>이렇게 생성한 단방향/양방향 비밀키들은 시스템 환경변수에 저장하여 OS 로부터 프로젝트에서 호출 받아 사용하면 더 높은 단계의 보안성을 가진 프로젝트를 구성할 수 있다. </p>
<h4 id="windows에서-키-생성powershell">Windows에서 키 생성(PowerShell)</h4>
<ol>
<li>HMAC 키(32바이트) 생성 → Base64</li>
<li>AES-256 키(32바이트), GCM Nonce(12바이트) 생성 → Base64
 1) GCM의 Nonce/IV는 매 암호화마다 새로 생성. 환경변수에 “기본값”을 둘 수도 있지만, 실제 데이터 암호화 시에는 중복되지 않도록 매번 새로 만들고 함께 저장(또는 전송)해야 안전</li>
</ol>
<h4 id="환경변수-설정-windows">환경변수 설정 (Windows)</h4>
<p>시스템(머신) 환경변수에 저장(관리자 권한 PowerShell)</p>
<h4 id="yml에-정의하여-os에-생성한-비밀키를-불러온다">YML에 정의하여 OS에 생성한 비밀키를 불러온다.</h4>
<p>이때 yml에 정의한 비밀키 변수가 환경변수에 저장되지 않을 경우 서버 에러 발생</p>
<h4 id="base64-decoding을-통해-키-객체-생성">base64 decoding을 통해 키 객체 생성</h4>
<ol>
<li>스프링에서 base64를 통해 인코딩한 비밀키 값을 다시 decoding 을 진행 → 진짜 바이트 배열로 변환</li>
<li>SecretKeySpec로 HMAC-SHA256용 키 객체 생성</li>
</ol>
<p>✅ 두 메소드 차이 요약</p>
<table>
<thead>
<tr>
<th>항목</th>
<th>HMAC 키</th>
<th>AES 키</th>
</tr>
</thead>
<tbody><tr>
<td>역할</td>
<td>메시지 무결성 (단방향)</td>
<td>데이터 암복호화 (양방향)</td>
</tr>
<tr>
<td>유효 길이</td>
<td>자유지만 32바이트↑ 권장</td>
<td><strong>정확히 16/24/32 바이트만</strong></td>
</tr>
<tr>
<td>알고리즘</td>
<td><code>HmacSHA256</code></td>
<td><code>AES</code></td>
</tr>
</tbody></table>
<p>✅ 비유로 쉽게 설명
환경변수에 저장된 키 문자열 = 금고 열쇠 그림 파일
base64(...) = 그림을 진짜 금속 열쇠로 만드는 과정
SecretKeySpec(...) = 열쇠를 자물쇠 규격에 맞게 가공</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 빈 주입과 필드 주입에 대한 정리]]></title>
            <link>https://velog.io/@jinny-park/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88-%EC%A3%BC%EC%9E%85%EA%B3%BC-%ED%95%84%EB%93%9C-%EC%A3%BC%EC%9E%85%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@jinny-park/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88-%EC%A3%BC%EC%9E%85%EA%B3%BC-%ED%95%84%EB%93%9C-%EC%A3%BC%EC%9E%85%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Thu, 27 Nov 2025 15:47:30 GMT</pubDate>
            <description><![CDATA[<h3 id="필드-주입-value-autowired">필드 주입 (@Value, @AutoWired)</h3>
<p>스프링이 객체 생성 후 리플렉션으로 필드에 값을 넣는 방식</p>
<h3 id="빈-주입생성자-주입-autowired--requiredargsconstructor">빈 주입(생성자 주입 @Autowired / @RequiredArgsConstructor)</h3>
<p>객체를 만들기 전에 생성자 파라미터로 의존성을 넣어주는 방식</p>
<h4 id="🔍-1-빈-주입--생성자-주입">🔍 1. &quot;빈 주입&quot; = 생성자 주입</h4>
<pre><code>
@Component
@RequiredArgsConstructor
public class MyService {

    private final UserRepository userRepository;
}

/*lombok이 만든 생성자 */
public MyService(UserRepository userRepository) {
    this.userRepository = userRepository;
}</code></pre><p>스프링은 해당 코드를 보고 아래의 step으로 생각한다.
-&gt; Myservice를 생성하려면 UserRepository가 필요함
-&gt; 그럼 UserRepository 빈을 찾아서 생성자 파라미터에 넣어야함 </p>
<p><strong>즉, 스프링이 객체 생성 시점에 빈을 넣어주는 방식
-&gt; 그래서 final 필드도 가능하고
-&gt; 의존성 없으면 그자리에서 에러가 발생
-&gt; 타입이 일치하는 빈을 스프링 컨테이너에서 찾음</strong></p>
<h4 id="🔍-2-필드-주입--인스턴스-생성-후-필드에-값-채워넣기">🔍 2. &quot;필드 주입&quot; = 인스턴스 생성 후 필드에 값 채워넣기</h4>
<pre><code>@Component
public class MyUtil {

    @Value(&quot;${my.prop}&quot;)
    private String prop;
}</code></pre><p>해당 코드는 생성자가 아니라 객체 생성 후에 리플렉션으로 값을 넣는 방식이다. </p>
<p>여기서 스프링 컨테이너 흐름 정리를 하자면 </p>
<ol>
<li>객체 인스턴스 생성(기본 생성자를 호출)</li>
<li>스프링이 리플렉션으로 필드를 찾음</li>
<li>그 위에 @Value가 붙어있으면 yml값을 꽂아 넣어줌</li>
</ol>
<p>즉, 생성 -&gt; 주입 순서이다. </p>
<h4 id="두-방식에서-중요한-차이는-">두 방식에서 중요한 차이는 ?</h4>
<ol>
<li>필드주입은 final필드에 값 넣을 수가 없다. (이미 객체가 생성된 후이기 떄문에 final은 변경이 불가함)</li>
<li>@RequiredArgsConstructor가 final필드를 생성자 파라미터로 만들어버리면
 1) 스프링은 string 빈을 주입해야한다고 판단
 2) 하지만 String 빈이 없어서 에러 발생</li>
</ol>
<p>여기서! 헷갈리는 실수</p>
<p>🧨 왜 @Value + final + @RequiredArgsConstructor 조합이 터지는가?</p>
<pre><code>@Component
@RequiredArgsConstructor
public class MyClass {

    @Value(&quot;${my.prop}&quot;)
    private final String prop;
}

/*그러면 롬복은 이렇게 생성자를 만든다.*/
public MyClass(String prop) {
    this.prop = prop;
}
</code></pre><p>그런데 여기서 @Value로 yml의 값을 넣고자 한다면?
스프링은 @Value가 붙어 있는 것을 신경쓰지 않음 -&gt; 즉, 스프링 입장에서는 클래스 객체 생성하려면 String type의 빈이 필요한데 스프링 컨테이너에 String 빈이 없네? -&gt; 에러 터짐</p>
<p>정리하자면 @Value 가 적용되기 전에 @RequiredArgsConstructor가 먼저 적용되어서 필드가 <em><strong>생성자 주입 대상이</strong></em> 되어버린 것이다.</p>
<p>🎯 최종 정리</p>
<table>
<thead>
<tr>
<th>주입 방식</th>
<th>시점</th>
<th>final 가능?</th>
<th>스프링이 뭘 찾나?</th>
</tr>
</thead>
<tbody><tr>
<td><strong>생성자 주입(빈 주입)</strong></td>
<td>객체 생성 <em>전</em></td>
<td>✔ 가능</td>
<td><strong>스프링 빈</strong></td>
</tr>
<tr>
<td><strong>필드 주입(@Value, field @Autowired)</strong></td>
<td>객체 생성 <em>후</em></td>
<td>❌ 불가능</td>
<td><code>@Value</code> → yml 값<br><code>@Autowired</code> → 빈</td>
</tr>
</tbody></table>
<p>🎯 완전 요약</p>
<p>@RequiredArgsConstructor
→ final 필드를 생성자 주입 대상으로 만듦
→ 스프링은 “해당 타입의 빈이 필요하다”고 생각함
@Value
→ 생성자 호출 후 리플렉션으로 주입
→ final 필드에는 값 못 넣음
두 개를 같이 쓰면
→ 스프링이 yml 값이 아니라 “String 빈”을 요구
→ 당연히 없음 → 에러!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 API 요청 별 DTO 매핑 어노테이션 정리]]></title>
            <link>https://velog.io/@jinny-park/%EC%8A%A4%ED%94%84%EB%A7%81-API-%EC%9A%94%EC%B2%AD-%EB%B3%84-DTO-%EB%A7%A4%ED%95%91-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@jinny-park/%EC%8A%A4%ED%94%84%EB%A7%81-API-%EC%9A%94%EC%B2%AD-%EB%B3%84-DTO-%EB%A7%A4%ED%95%91-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 24 Nov 2025 15:12:09 GMT</pubDate>
            <description><![CDATA[<p>API 요청 별 DTO 매핑 어노테이션 방식에 대한 것 을 정리하고자 기록한다. </p>
<p>주로 GET 방식으로 요청 할 때 queryString을 DTO로 변환해주는 @ModelAttribute 와 @RequestParam을 썼던 것 같고
POST방식에서는 @RequestBody 방식을 많이 썼다. </p>
<p>이번에 form-data 전송을 위한 MultipartFile데이터 처리에 대한 궁금이 생겨 기록 고고띵 한다. </p>
<p>일단! MultipartFile은 은 @RequestParam랑은 써봤던 것 같은데 @RequestPart 이번에 써보게 되면서 궁금해짐 👀 </p>
<p>내 궁금증에 대한 요약을 해보자면 ❗️</p>
<p>✅ 결론 요약
✔ MultipartFile은 @RequestParam 또는 @RequestPart만 가능하다.
❌ @RequestBody MultipartFile는 절대 안 된다. (스프링 구조상 불가능)</p>
<p>🔍 왜 MultipartFile은 @RequestBody로 받을 수 없을까?</p>
<p>1) @RequestBody는 순수한 Body(JSON/XML/Raw data) 를 받아서 변환하는 구조를 가지며 이런 걸 <em><strong>HttpMessageConverter</strong></em> 로 변환해주는 방식이다. ➡️ 그런데 multipart/form-data는 메시지 컨버터가 아니라 <strong><em>MultipartResolver가</em></strong> 처리함.</p>
<p>2) multipart/form-data는 하나의 Body가 아니라 여러 파트의 조합 ➡️ form-data([key, value]) , form-data([key2,value2])</p>
<p>🔥 스프링이 Multipart를 처리하는 흐름</p>
<p>요청이 오면 → MultipartResolver가 multipart를 파싱
각 part를 Map 형태로 저장
file part는 → MultipartFile 객체로 매핑
그리고 컨트롤러 파라미터로 바인딩됨
즉, MultipartFile은 MultipartResolver가 생성한 객체이기 때문에
@RequestBody처럼 메시지 컨버터가 처리할 수 없음.</p>
<p>그리고 두번째로 파일 데이터 처리하면서 궁금했떤 RequestPart 랑 RequestParam 차이점 ‼️</p>
<p>🔥 핵심 요약 (한 문장 버전)
✔ @RequestParam → form-data의 “텍스트 필드” 또는 “파일” 같은 단순 파트에 사용
✔ @RequestPart → JSON + 파일처럼 “multipart/form-data 내부의 객체(JSON) 또는 파일 파트&quot;를 명확히 구분해 받는 데 사용한다. 
즉, 단순 텍스트 + 파일 → @RequestParam
JSON + 파일 → @RequestPart</p>
<p>@RequestParam으로 JSON 매핑 ? 가능은 하다. 
근데 JSON 이 스트링 형식으로 변환되어서 요청이 오기 때문에 직접 역직렬화 작업을 진행해야 한다. </p>
<p>✅ 파일 업로드에서 @ModelAttribute를 쓸까 ?
✔ @ModelAttribute는 텍스트 필드 + 파일을 함께 DTO로 묶어서 받고 싶을 때 가능하다.
✔ JSON + 파일 조합에서는 절대 사용 못함 → 이건 반드시 @RequestPart.
✔ 추가로 @ModelAttribute는 GET 요청에서 쿼리 스트링(query string)을 DTO로 매핑할 때 가장 대표적으로 쓰는 방식이다.</p>
<p>요청시 매핑하고 싶은 DTO 예시를 들자면 이렇게 텍스트와+파일 조합의 form-data를 보내고 아래 예시와 같은 DTO로 @ModelAttribute가 변환한다. </p>
<pre><code>/*DTO*/
public class UploadRequest {

    private String title;
    private String description;
    private MultipartFile file;

    // getter/setter
}


/*컨트롤러에서 요청 처리시 예시 */
@PostMapping(value = &quot;/upload&quot;, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity&lt;?&gt; upload(@ModelAttribute UploadRequest request) {
}</code></pre><p>📌 GET에서 ModelAttribute가 좋은 이유
✔ DTO의 모든 필드에 자동으로 바인딩된다
스프링의 DataBinder가 필드명과 동일하게 파라미터를 매칭함.
✔ 기본값 처리, 타입 변환이 자동
int, boolean 같은 primitive 타입도 자동 변환.
✔ 파라미터 개수가 많아질수록 유지보수성 증가
필드 추가해도 컨트롤러 시그니처 변경할 필요 없음.
✔ 검증(Validation)도 쉽게 적용 가능
@Valid + @ModelAttribute 조합이 자연스럽게 동작.</p>
<p>🔥 스프링 웹 요청 매핑 어노테이션 완전 비교표
📌 RequestParam / RequestPart / ModelAttribute / RequestBody 전체 비교</p>
<table>
<thead>
<tr>
<th>구분</th>
<th>@RequestParam</th>
<th>@RequestPart</th>
<th>@ModelAttribute</th>
<th>@RequestBody</th>
</tr>
</thead>
<tbody><tr>
<td><strong>주 사용 용도</strong></td>
<td>단순 파라미터(key=value), 단일 파일</td>
<td>JSON + 파일 조합 (multipart 파트 구분)</td>
<td>쿼리스트링, form-data(text+file) DTO 매핑</td>
<td>JSON을 DTO로 받을 때</td>
</tr>
<tr>
<td><strong>주로 사용하는 Content-Type</strong></td>
<td><code>multipart/form-data</code>, <code>application/x-www-form-urlencoded</code>, <code>query-string</code></td>
<td><code>multipart/form-data</code></td>
<td><code>multipart/form-data</code>, <code>query-string</code>, <code>x-www-form-urlencoded</code></td>
<td><code>application/json</code></td>
</tr>
<tr>
<td><strong>JSON 받을 수 있는가?</strong></td>
<td>❌ 직접 받을 수 없음 (String만 가능)</td>
<td>✔ JSON → DTO 자동 매핑</td>
<td>❌ 불가능</td>
<td>✔ JSON → DTO 자동 매핑</td>
</tr>
<tr>
<td><strong>파일(MultipartFile) 받을 수 있는가?</strong></td>
<td>✔ 가능</td>
<td>✔ 가능</td>
<td>✔ 가능 (DTO 필드로 가능)</td>
<td>❌ 불가능</td>
</tr>
<tr>
<td><strong>자동 객체 변환</strong></td>
<td>기본 타입만</td>
<td>JSON / 파일 자동 분리</td>
<td>DTO 자동 바인딩 (Key-Value)</td>
<td>JSON → DTO 메시지 컨버터</td>
</tr>
<tr>
<td><strong>언제 주로 쓰는가?</strong></td>
<td>텍스트 + 파일 간단 업로드</td>
<td>JSON 메타데이터 + 파일 업로드</td>
<td>GET 쿼리스트링 → DTO 매핑 / form-data DTO 매핑</td>
<td>JSON POST/PUT 요청</td>
</tr>
<tr>
<td><strong>클라이언트 FormData 요구 방식</strong></td>
<td><code>formData.append(&quot;file&quot;, file)</code></td>
<td><code>formData.append(&quot;meta&quot;, blob(JSON))</code></td>
<td>key=value 구조 그대로 사용</td>
<td>JSON body</td>
</tr>
<tr>
<td><strong>복잡한 구조 처리</strong></td>
<td>X</td>
<td>✔</td>
<td>X</td>
<td>✔</td>
</tr>
<tr>
<td><strong>멀티파트 구조 인식</strong></td>
<td>부분적으로</td>
<td>✔ multipart 파트 단위로 분석</td>
<td>✔ 값 바인딩 형태</td>
<td>X (multipart 자체는 못 파싱)</td>
</tr>
<tr>
<td><strong>스프링 내부 처리 방식</strong></td>
<td>WebDataBinder</td>
<td>MultipartResolver + HttpMessageConverter</td>
<td>WebDataBinder</td>
<td>HttpMessageConverter</td>
</tr>
<tr>
<td><strong>GET 요청에 사용</strong></td>
<td>✔</td>
<td>거의 안 씀</td>
<td>✔ (대표적)</td>
<td>❌</td>
</tr>
</tbody></table>
<p>🔍 각 어노테이션 핵심 요약 (1줄씩)
@RequestParam
→ 단순한 form-data / query parameter / 파일을 받을 때 가장 일반적인 방식.
@RequestPart
→ multipart/form-data 안에서 JSON + 파일 같은 복합 구조를 받을 때 필수.
@ModelAttribute
→ 여러 텍스트 필드를 DTO로 묶고 싶을 때 (GET/POST 모두), 파일도 DTO에 포함 가능. (쿼리 스트링으로 온 요청도 해당 어노테이션으로 매핑가능)
@RequestBody
→ JSON 요청 바디를 DTO로 변환할 때 유일하게 사용해야 하는 방식.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ApplicationEventPublisher와 스프링부트 이벤트 등록 기능 ]]></title>
            <link>https://velog.io/@jinny-park/ApplicationEventPublisher%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%93%B1%EB%A1%9D-%EA%B8%B0%EB%8A%A5</link>
            <guid>https://velog.io/@jinny-park/ApplicationEventPublisher%EC%99%80-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%93%B1%EB%A1%9D-%EA%B8%B0%EB%8A%A5</guid>
            <pubDate>Thu, 20 Nov 2025 13:31:02 GMT</pubDate>
            <description><![CDATA[<h3 id="applicationeventpublisher란-">ApplicationEventPublisher란 ?</h3>
<p>Spring 프레임워크에서 ApplicationEventPublisher는 <strong>이벤트를 발행</strong>(publish)하는 역할을 담당하는** 인터페이스 **</p>
<p>쉽게 말하면, &quot;스프링 애플리케이션 내부에서 발생한 <strong>어떤 사건(이벤트)을 다른 컴포넌트들에게 알리는 메신저</strong>&quot;를 의미한다.</p>
<p>Spring은 <strong>Observer 패턴을 기반</strong>으로 한 애플리케이션 이벤트 시스템을 갖고 있고, ApplicationEventPublisher는 이 이벤트 시스템의 <strong>“발사 버튼” 역할</strong> 수행</p>
<p>이걸 사용하는 예시 ? 약간 요런거에 쓰이는거 같음 ! </p>
<ol>
<li>회원가입 후 email전송</li>
<li>긴급 메세지 발송 </li>
</ol>
<p>비니스 로직을 한 클래스 내부에서 전부 처리하면 결합도가 높아지고 유지보수가 힘들어진다. </p>
<p>✅ 어떻게 동작할까</p>
<ol>
<li>publisher가 이벤트를 발행</li>
<li>Spring 컨테이너는 해당 이벤트를 듣고 있는 @EventListener 또는 ApplicationListener 를 찾아 호출!</li>
<li>이벤트 발행은 트랜잭션 내부에서 하면 리스너도 트랜잭션 영향을 받을 수 있음 -&gt; 확실히 제어하려면 _*<em>@TransactionalEventListener를 *</em>_사용.</li>
</ol>
<h3 id="transactionaleventlistener-">@TransactionalEventListener ?</h3>
<p>트랜잭션 phrase 별로 이벤트리스너 동작을 제어하고 싶을 경우에는 
@TransactionalEventListener(phase=TransactionPhase.AFTER_COMMIT) 요러한 옵션들이 따로 존재함.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[@Configuration과 @Component 정리]]></title>
            <link>https://velog.io/@jinny-park/Configuration%EA%B3%BC-Component-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@jinny-park/Configuration%EA%B3%BC-Component-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 25 Aug 2025 23:55:54 GMT</pubDate>
            <description><![CDATA[<p>@Configuration 이란 ?
Java 기반 설정 클래스 임을 나타낸다. 
이 클래스 안에 있는 @bean 메서드들은 스프링 컨테이너에 등록할 객체를 정의한다. </p>
<p>@Component란 일반적인 스프링 빈으로 등록하게되는 기본적인 어노테이션이다. 
@Service, @Repository, @Controller등 모두 @Component의 특수화이다.</p>
<p>즉!!
@Configuation은 이미 @Component를 포함한다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[직렬화랑 역직렬화 정리 ]]></title>
            <link>https://velog.io/@jinny-park/%EC%A7%81%EB%A0%AC%ED%99%94%EB%9E%91-%EC%97%AD%EC%A7%81%EB%A0%AC%ED%99%94-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@jinny-park/%EC%A7%81%EB%A0%AC%ED%99%94%EB%9E%91-%EC%97%AD%EC%A7%81%EB%A0%AC%ED%99%94-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Fri, 22 Aug 2025 13:55:10 GMT</pubDate>
            <description><![CDATA[<p>직렬화랑 역직렬화 뭔지 궁금해서 찾아봄</p>
<p>왜 찾아보게 됐냐면 flutter -&gt; vue로 restful api 응답값 전달할때 , backend에서 dto &lt;-&gt; json 매핑 직렬화랑 역직렬화가 엮여있음</p>
<p><em>1.직렬화(Serialization)</em></p>
<p>정의: 객체(Object)나 자료구조를 <strong>바이트(byte) 형태로 변환하</strong>는 과정</p>
<p>목적: 메모리에 존재하는 객체는 프로그램이 실행되는 동안만 유지됨 → 파일, DB, 네트워크로 보내려면 이진 데이터 형태가 필요함. 직렬화를 통해 객체를 저장하거나 네트워크로 전송 가능</p>
<p>예시:</p>
<blockquote>
<p>Java: ObjectOutputStream → 객체를 파일로 직렬화
JSON/XML 변환 → 네트워크 API 응답을 위해 객체를 문자열(JSON)로 직렬화</p>
</blockquote>
<p>2.<em>역직렬화(Deserialization)</em></p>
<p><strong>정의: 직렬화된 데이터(바이트나 문자열)를 다시 객체로 복원하는 과정</strong></p>
<p>목적:
저장된 파일을 다시 객체로 불러오기
<strong>네트워크에서 받은 JSON을 DTO로 변환하기</strong></p>
<p>예시:
Java: ObjectInputStream → 파일에서 객체 복원
*<em>JSON → DTO 매핑 *</em>(Jackson, Gson 등 사용)</p>
<p>한마디로 </p>
<p>vue &lt;-&gt; flutter &lt;-&gt; springboot 구조에서 </p>
<p>백엔드에서 받은 데이터를 플러터에서는 직렬화된(json string) 상태로 받음!
이걸 바로 뷰에 전달해서 값을 처리하려고 하면 뷰에서는 직렬화된 데이터 처리를 스트링으로 인식하기 때문에 객체로 처리가 안됨!</p>
<p>그래서 플러터에서 jsonDecode인가 이거로 역직렬화 하여 객체형태로 vue에 전달 해줘야함 </p>
<blockquote>
</blockquote>
<p>Spring Boot DTO → (Jackson 직렬화) → JSON 문자열
→ Flutter 수신 → (jsonDecode 등 역직렬화) → Dart 객체
→ (브릿지 전송 시 다시 jsonEncode 직렬화) → 문자열
→ Vue 수신 → (JSON.parse 역직렬화) → JS 객체</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DTO 생성과 Builder 패턴]]></title>
            <link>https://velog.io/@jinny-park/DTO-%EC%83%9D%EC%84%B1%EA%B3%BC-Builder-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@jinny-park/DTO-%EC%83%9D%EC%84%B1%EA%B3%BC-Builder-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Fri, 22 Aug 2025 13:20:39 GMT</pubDate>
            <description><![CDATA[<p>DTO 생성에 대한 의문이 있어서 찾아봄</p>
<p>비즈니스 로직에서 가변 DTO와 불변 DTO에 대한 역할 분리의 필요성을 느꼈다.</p>
<p>로직내에서 유동적으로 변해야 하는것은 한번 생성한 DTO에서 필드 값만 변경하는게 좋을지 새 DTO를 생성해서 각자의 역할 분담을 해주는게 좋을지 그게 궁금했었다. </p>
<p><img src="https://velog.velcdn.com/images/jinny-park/post/1c7e0275-d23f-4f6f-8d41-35bd682ed699/image.png" alt=""></p>
<p>나는 가변 DTO를 쓸 때는 Builder 어노테이션을 사용해서 객체 생성하는 것을 선호하는 편인데 빌더로 설정한 dto 클래스는 마이바티스에서 응답값 전달을 받을때 제대로 실행이 안되고 오류가 난다는 문제가 있다. </p>
<p>왜냐 ?</p>
<p>이유는 마이바티스 실행 로직상 응답값 dto 를 매칭할 때 dto를 기본 생성자와 setter로 객체 생성을 하기 때문이다. </p>
<p>dto클래스를 빌더로 설정해 버리면 기본 생성자로 객체를 생성할 수 없어서 충돌이 나는 것임...</p>
<p>❗ 왜 @Builder가 안 되나?
MyBatis는 다음과 같은 방식으로 DTO를 채웁니다:</p>
<pre><code>UserDTO dto = new UserDTO();
dto.setName(rs.getString(&quot;name&quot;));
dto.setAge(rs.getInt(&quot;age&quot;));</code></pre><p>즉, 기본 생성자를 통해 객체를 만들고, Setter로 값 주입한다.
그런데 @Builder를 쓰면 다음과 같은 생성자가 생기고</p>
<pre><code>public UserDTO(String name, int age, boolean active) {
    this.name = name;
    this.age = age;
    this.active = active;
}</code></pre><p>➡️ 기본 생성자가 사라지거나, MyBatis가 무시하게 됨
결과적으로 빌더 생성자는 MyBatis 입장에선 쓸 수 없는 생성자가 된다.</p>
<p>암튼 지피티 햄이 이렇게 정리해쥼</p>
<p>그래서 실무에서는 마이바티스용과 내부 비즈니스로직에서 사용할 dto분리해서 구현하는걸 선호한다고 한다. </p>
<ol start="3">
<li>MyBatis 매핑 전용 DTO 따로 분리
➡️ 실무에서는 이걸 가장 선호</li>
</ol>
<pre><code>// MyBatis Result 전용 DTO
@Data
public class UserResultDTO {
    private String name;
    private int age;
    private boolean active;
}

// 내부 로직에 사용할 빌더 DTO
@Data
@Builder
public class UserDTO {
    private String name;
    private int age;
    private boolean active;
}</code></pre><p>그리고 핵심적으로 이 내용을 정리하게된 이유는 !!!
가변 DTO를 생성하게 될때 두개의 dto를 생성해야하는데 그 두개가 컬럼 하나로만 나뉜다면 ? 
이때 하나의 dto를 돌려쓸지 담당 기능을 분리할지가 고민이었는데 분리해서 역할을 명확하게 나누는게 좋다고 한다. </p>
<p>=&gt; 즉 setter로 값만 바꾸는게 아니라 그냥 새 dto 생성하셈ㅇㅇ 어차피 dto는 가볍기때문에 무시가능한 수준임. </p>
<p>❗동일 dto를 가변적으로 사용할 때 단점
불변성이 깨짐 (값 변경을 의도하지 않았더라도 변경 가능)
멀티스레드 상황에서 위험 (공유 DTO라면 더 위험)
의도가 불명확해짐 (&quot;왜 갑자기 status가 바뀌었지?&quot; 혼란 유발 가능)</p>
<p>근데 이제 이거를 빌더패턴으로 또 생성해주기는 번거로우니 toBuilder를 사용해서 새로운 dto를 만들어내는 것이다</p>
<pre><code>UserSearchDTO inactiveDto = dto.toBuilder()
    .status(&quot;INACTIVE&quot;)
    .build();</code></pre><blockquote>
<p>장점
불변성 유지
명확한 의도 표현: 두 개의 다른 조회 조건
나중에 디버깅하거나 유지보수할 때 혼란 없음</p>
</blockquote>
<blockquote>
<p>단점
객체가 한 개 더 생김 (하지만 DTO는 가볍기 때문에 무시 가능한 수준)</p>
</blockquote>
<p>그리고 toBuilder를 쓰기 위해서는 </p>
<pre><code>
@Builder(toBuilder = true)
public class UserSearchDTO {
    // ...
}
</code></pre><p>요렇코롬 toBuilder = true 를 설정해줘야 사용 가능하다는 점 !</p>
<p>✅ 결론: 실무에서는 Builder로 새 DTO를 생성하는 방식 권장
✔ 의도를 명확하게 표현하고,
✔ 불변성을 유지하면서,
✔ 잠재적인 Side Effect를 방지하기 위해
toBuilder()로 새 DTO를 만드는 방식이 안전하고 유지보수에 좋습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[생성자 ]]></title>
            <link>https://velog.io/@jinny-park/%EC%83%9D%EC%84%B1%EC%9E%90</link>
            <guid>https://velog.io/@jinny-park/%EC%83%9D%EC%84%B1%EC%9E%90</guid>
            <pubDate>Wed, 06 Aug 2025 03:28:00 GMT</pubDate>
            <description><![CDATA[<p>1) @NoArgsConstructor
기능: 파라미터 없는 기본 생성자 생성</p>
<p>2) @RequiredArgsConstructor
기능: final 또는 @NonNull 필드만 파라미터로 받는 생성자 생성
언제 쓰나
Spring DI(생성자 주입) 최적 → 의존성은 final로 두고 이 어노테이션만 붙이면 됨
단일 생성자면 Spring은 @Autowired 없이도 주입</p>
<p>3) @AllArgsConstructor
기능: 모든 필드를 파라미터로 받는 생성자 생성
언제 쓰나
DTO나 값 전달 객체에 편리
엔티티에서는 남용 금지(불변식/비즈니스 규칙 무시 위험), 필요 시 가시성 낮추기</p>
<p>a , c dto 클래스의 필드를 가지고 b dto 클래스 생성자를 만들고 싶은데, a,c의 일부 필드만 사용하고 싶을 경우 대상 필드를 별도 클래스로 생성한다. </p>
<p>각 Request DTO에서 이 클래스를 꺼낼 수 있게 구성</p>
<pre><code>class A {
 string a;
 string b;
 string c;

 b createBDto (){
     return new b(a,b,c);
 }
}</code></pre><pre><code>class C {
 string a;
 string b;
 string d;

 b createBDto (){
     return new b(a,b,d);
 }
}</code></pre><p>이렇게 각 dto 클래스에 b dto 생성 메소드 만든 후 a.createBDto(), c.createBDto() 이렇게 처리 가능하다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[lombok 의존성 주입 ]]></title>
            <link>https://velog.io/@jinny-park/lombok-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85</link>
            <guid>https://velog.io/@jinny-park/lombok-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85</guid>
            <pubDate>Wed, 02 Jul 2025 10:36:06 GMT</pubDate>
            <description><![CDATA[<p>스프링부트 lombok 라이브러리 의존성 주입 시에
implement로 주입하는게 아니라 compileOnly로 의존성을 주입해야한다. </p>
<p>이유는 ?</p>
<ul>
<li>lombok은 컴파일때 필요한 도구지 런타임까지 끌고갈 필요 없음</li>
</ul>
<p>✅ 핵심 개념부터 정리</p>
<p>Gradle 설정    의미
implementation    컴파일 + 런타임 모두 필요
compileOnly    컴파일할 때만 필요, 런타임에는 필요 없음
annotationProcessor    컴파일 시 애노테이션 처리용 도구 등록</p>
<p>✅ 그럼 Lombok은?</p>
<p>Lombok은 컴파일 타임에만 필요한 도구
즉, 소스 코드에 실제 메서드(getter/setter, 등)를 생성해주는 역할만 하고, 앱이 실행될 때는 전혀 필요 없음</p>
<p>✅ 왜 실제 배포에 문제 없냐면?</p>
<p>📌 1. <strong>Lombok은 컴파일 시점에만 작동해</strong>
@Getter, @Setter, @Builder, @EqualsAndHashCode 같은 애노테이션들은
→ 컴파일할 때 자동으로 자바 코드로 변환됨
즉, <strong>실제 컴파일 결과물(.class) 안에는 Lombok이 아예 없음
lombok.jar이 앱에 포함되지 않음 → 런타임엔 존재조차 안 함</strong></p>
<p>📌 2. 배포 파일 (예: .jar, .war, .aab, .apk) 안에도 없음
<strong>Gradle이 compileOnly으로</strong> 설정된 라이브러리는
→ classpath에는 포함되지만,
→ build/libs/my-app.jar 같은 <strong>배포 파일엔 포함되지 않음</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[@configuration과 @bean 그리고 의존성 주입(추가로 @postConstruct)]]></title>
            <link>https://velog.io/@jinny-park/webClient-bean-%EC%A3%BC%EC%9E%85</link>
            <guid>https://velog.io/@jinny-park/webClient-bean-%EC%A3%BC%EC%9E%85</guid>
            <pubDate>Wed, 02 Jul 2025 00:30:44 GMT</pubDate>
            <description><![CDATA[<p>@configuration은 설정 클래스임을 명시하는 어노테이션을 의미하며 여기서 빈생성이 가능하다. @bean 으로 프로젝트 전체에서 사용할 빈 등록가능</p>
<ul>
<li>like firebaseconfigclass, webclientConfigClass 같은것들</li>
<li>싱글톤 형태로 인스턴스를 프로젝트 전체에 하나만 생성할 경우에도 사용하는 것 같음</li>
</ul>
<p>@Bean은 스프링 컨테이너가 객체를 생성하면 거기서 @Bean으로 등록된다.</p>
<ul>
<li>인스턴스 생성 그 자체</li>
<li>컨테이너 생성 시작 시 (초기화 단계)에 빈이 등록</li>
<li>객체 생성을 목적으로 한다 </li>
</ul>
<p>의존성 주입은 빈생성 후에 다른 클래스에 의존성을 주입을 하기 위한 것</p>
<ul>
<li>생성자 또는 필드 등을 통해 필요한 객체를 넣어주는 과정</li>
<li>객체간의 관계에 집중한다. </li>
<li>@Autowired: 필드, 생성자, 세터 등에 의존성 자동 주입 (비권장, 생성자 주입 선호)</li>
<li>@RequiredArgsConstructor : lombok라이브러리를 사용한 것으로 final 필드 기반 생성자 자동 생성</li>
</ul>
<p>postConstruct는 는 의존성 주입 후 초기화 진행히 필요할 때 사용하는 것으로 의존성이 주입된 이후에 초기화가 필요할 때 사용한다 .</p>
<p>✅ 먼저 Spring Bean의 생성과 초기화 전체 흐름 정리</p>
<p>[1] 객체 생성 (Bean 인스턴스 생성)
[2] 의존성 주입 (필드/생성자/세터 등)
[3] 초기화 (초기 상태 설정, @PostConstruct 등)
[4] 사용
[5] 소멸 (Context 종료 시)</p>
<p><img src="https://velog.velcdn.com/images/jinny-park/post/30bc4f11-c716-4ee7-9071-3b3ee904f2bf/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Mac OS 자바 환경 변수 설정 방법 ]]></title>
            <link>https://velog.io/@jinny-park/Mac-OS-%EC%9E%90%EB%B0%94-%ED%99%98%EA%B2%BD-%EB%B3%80%EC%88%98-%EC%84%A4%EC%A0%95-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@jinny-park/Mac-OS-%EC%9E%90%EB%B0%94-%ED%99%98%EA%B2%BD-%EB%B3%80%EC%88%98-%EC%84%A4%EC%A0%95-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Mon, 03 Feb 2025 14:04:50 GMT</pubDate>
            <description><![CDATA[<p>이어서...! 맥 환경에서 자바 환경 변수를 설정 하는 방법을 기록해야징</p>
<h2 id="1-일단-자바를-설치해준다">1. 일단 자바를 설치해준다!</h2>
<p>전편에 기록한 자바 설치 방법을 참고하기</p>
<p>헤헷 고고!</p>
<blockquote>
<p><a href="https://velog.io/@jinny-park/Mac-OS-%EC%9E%90%EB%B0%94-jdk-21-%EC%84%A4%EC%B9%98-%EB%B0%A9%EB%B2%95">https://velog.io/@jinny-park/Mac-OS-자바-jdk-21-설치-방법</a></p>
</blockquote>
<h2 id="2-맥-터미널을-실행한다">2. 맥 터미널을 실행한다.</h2>
<p>터미널 실행 후 자바가 설치된 경로를 찾는다. 
나의 경우 해당 경로에 자바 Home이 설치 되어 있는걸 확인 할 수 있었다.</p>
<p><strong>/Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home</strong></p>
<p>여기서 Library 폴더는 Users 폴더하위에 있는 디렉토리가 아니라 루트 바로 밑에 있는 디렉토리이다.</p>
<p>난 잘못찾아가지고 조금 몇분 삽질했다.</p>
<p><img src="https://velog.velcdn.com/images/jinny-park/post/202df9eb-5520-4491-864a-39e4b8998b4d/image.png" alt=""></p>
<h2 id="3-jdk-경로-자바-home-입력">3. jdk 경로 자바 Home 입력</h2>
<p>vi ~/.bash_profile 명령어를 통해 .bash_profile에 홈 설정을 진행한다. </p>
<p>홈 설정해주기위해서는 위에서 복사한 자바 경로가 필요하다.</p>
<p><img src="https://velog.velcdn.com/images/jinny-park/post/2ae46563-4b0e-418a-af8b-5e054e235ddc/image.png" alt=""></p>
<p>해당 내용을 작성 후 esc를 눌러 insert 모드에서 벗어난다.
그리고 shift + ; 를 눌러주면 종료 모드가 되는데 이때 밑에 : 가 생긴다.</p>
<p>: 생기면 wq!(저장 후 종료를 의미) 명령어를 입력해주어서 편집기 사용을 종료해준다. </p>
<h2 id="4-입력한-home-설정하기">4. 입력한 home 설정하기</h2>
<p>source .bash_profile 명령어를 통해 입력한 경로를 home 으로 설정한다.</p>
<p><img src="https://velog.velcdn.com/images/jinny-park/post/eca9fcf7-8670-43c5-8214-297a32b93021/image.png" alt=""></p>
<h2 id="5-환경변수-설정-값-확인하기">5. 환경변수 설정 값 확인하기</h2>
<p>echo $JAVA_HOME 명령어를 통해 자바 홈 설정 경로가 제대로 설정 된 것인지 확인할 수 있다. </p>
<p>이렇게 위에서 설정한 경로가 나오면 제대로 환경설정이 이루어 진 것이다!</p>
<p><img src="https://velog.velcdn.com/images/jinny-park/post/766964f1-14fa-46ee-83c2-46475215481d/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Mac OS 자바 jdk 21 설치 방법]]></title>
            <link>https://velog.io/@jinny-park/Mac-OS-%EC%9E%90%EB%B0%94-jdk-21-%EC%84%A4%EC%B9%98-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@jinny-park/Mac-OS-%EC%9E%90%EB%B0%94-jdk-21-%EC%84%A4%EC%B9%98-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Mon, 03 Feb 2025 13:42:11 GMT</pubDate>
            <description><![CDATA[<p>윈도우에서는 자바 설치를 많이 해봤는데 이번에 맥북에어로 바꾸면서 mac 환경에서 환경설정은 처음 진행해본당.</p>
<h2 id="1-oracle-jdk-다운로드">1. oracle jdk 다운로드</h2>
<p><a href="https://www.oracle.com/java/technologies/downloads/#jdk22-mac">https://www.oracle.com/java/technologies/downloads/#jdk22-mac</a></p>
<p><img src="https://velog.velcdn.com/images/jinny-park/post/c01a4d5c-7ea7-4971-babe-b51afa2a00f5/image.png" alt=""></p>
<p>맥북 cpu 아키텍처에 맞는 jdk 파일을 설치하기 !
내 맥북의 경우는 ARM 64 아키텍처를 사용중이기 때문에 ARM64 DMG Installer 를 다운 받았다.</p>
<p>인텔기반의 cpu 일 경우에는 x64 아키텍처 파일을 다운로드 받으면 된다.</p>
<h2 id="2-download-폴더에서-설치파일-클릭하기">2. download 폴더에서 설치파일 클릭하기</h2>
<p><img src="https://velog.velcdn.com/images/jinny-park/post/f2c2b273-81ed-488b-9ab3-5542b7f9d6fe/image.png" alt=""></p>
<p>설치파일 클릭 시 해당 jdk.pkg 파일이 담긴 폴더가 열리고 이 파일을 클릭하기
<img src="https://velog.velcdn.com/images/jinny-park/post/78d729ee-7f58-4456-958f-0b6dcb6830df/image.png" alt=""></p>
<p>클릭 후 해당 설치 응용프로그램이 실행되면 계속 눌러준다.
이때 자바 설치 경로를 본인이 설정할 수 있음 </p>
<p><img src="https://velog.velcdn.com/images/jinny-park/post/59916d89-59c2-4936-bc3f-eef9f1dc5372/image.png" alt=""></p>
<h2 id="3-설치-후-터미널에서-설치된-자바-확인하기">3. 설치 후 터미널에서 설치된 자바 확인하기</h2>
<p>java --version 명령어를 통해 터미널에서 설치된 자바 확인 가능
<img src="https://velog.velcdn.com/images/jinny-park/post/6ebffbba-6957-4a9a-9595-1a11c5f6236f/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[벨로그 강제 비공개 글 전환]]></title>
            <link>https://velog.io/@jinny-park/%EB%B2%A8%EB%A1%9C%EA%B7%B8-%EA%B0%95%EC%A0%9C-%EB%B9%84%EA%B3%B5%EA%B0%9C-%EA%B8%80-%EC%A0%84%ED%99%98</link>
            <guid>https://velog.io/@jinny-park/%EB%B2%A8%EB%A1%9C%EA%B7%B8-%EA%B0%95%EC%A0%9C-%EB%B9%84%EA%B3%B5%EA%B0%9C-%EA%B8%80-%EC%A0%84%ED%99%98</guid>
            <pubDate>Fri, 18 Aug 2023 08:35:01 GMT</pubDate>
            <description><![CDATA[<p>스프링부트와 머스테치 엔진 사용해서 웹 서비스 로컬로 구현하는걸 기술 블로그에 기록 했는데 왜 때문인지 강제 비공개가 됐다...
특정 키워드가 포함되면 강제 비공개가 되는 것 같은데 키워드 기준을 모르니 비공개가 안 풀려서 답답하다... ㅠㅠ </p>
<p>다음 포스팅 주제는 스프링 시큐리티 인데 ... 이것도 비공개 되려나 </p>
<p><img src="https://velog.velcdn.com/images/jinny-park/post/78cbe3e3-dc1e-426f-a581-1231e6f10c6d/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[신입 CS 질문] 알고리즘]]></title>
            <link>https://velog.io/@jinny-park/%EC%8B%A0%EC%9E%85-CS-%EC%A7%88%EB%AC%B8-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</link>
            <guid>https://velog.io/@jinny-park/%EC%8B%A0%EC%9E%85-CS-%EC%A7%88%EB%AC%B8-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</guid>
            <pubDate>Thu, 03 Aug 2023 04:26:31 GMT</pubDate>
            <description><![CDATA[<h2 id="동적-계획법dp">동적 계획법(DP)</h2>
<ul>
<li>주어진 문제를 풀기 위해, 문제를 여러 개의 하위 문제로 나누어 푸는 방법</li>
</ul>
<h2 id="버블-정렬">버블 정렬</h2>
<ul>
<li>버블 정렬는 서로 인접한 두 원소를 비교하여 정렬하는 알고리즘입니다.</li>
<li>시간 복잡도는 O(n^2)입니다.</li>
</ul>
<h2 id="선택-정렬">선택 정렬</h2>
<ul>
<li><p>선택 정렬은 첫 번째 값을 두번째 부터 마지막 값까지 차례대로 비교하여 최솟값을 찾아 첫 번째에 놓고, 두 번째 값을 세 번째 부터 마지막 값까지 비교하여 최솟값을 찾아 두 번째 위치에 놓는 과정을 반복하며 정렬하는 알고리즘입니다. </p>
</li>
<li><p>시간복잡도는 O(n^2)입니다.</p>
</li>
</ul>
<h2 id="삽입-정렬">삽입 정렬</h2>
<ul>
<li><p>삽입 정렬은 두 번째 값부터 시작해 그 앞에 존재하는 원소들과 비교하여 삽입할 위치를 찾아 삽입하는 정렬 알고리즘입니다.</p>
</li>
<li><p>평균 시간복잡도는 O(n^2)이며, Best Case 의 경우 O(n)까지 높아질 수 있습니다.</p>
</li>
</ul>
<h2 id="힙정렬">힙정렬</h2>
<ul>
<li><p>힙 정렬은 주어진 데이터를 힙 자료구조로 만들어 최댓값 또는 최솟값부터 하나씩 꺼내서 정렬하는 알고리즘입니다.</p>
</li>
<li><p>시간 복잡도는 O(nlogn)입니다.</p>
</li>
</ul>
<h2 id="병합-정렬">병합 정렬</h2>
<ul>
<li>병합 정렬은 주어진 배열을 크기가 1인 배열로 분할하고 합병하면서 정렬을 진행하는 분할/정복 알고리즘입니다.</li>
<li>시간 복잡도는 O(nlogn)입니다.</li>
</ul>
<h2 id="퀵-정렬">퀵 정렬</h2>
<ul>
<li><p>분할 정복 알고리즘 중 하나로 피봇을 설정하고 피봇보다 큰 값과 작은 값으로 분할하여 정렬 합니다.</p>
</li>
<li><p>시간 복잡도는 O(nlogn)이며 worst case 경우 O(n^2)까지 나빠질 수 있습니다.</p>
</li>
</ul>
<h2 id="재귀-알고리즘">재귀 알고리즘</h2>
<ul>
<li>재귀 알고리즘이란 함수 내부에서 함수가 자기 자신을 또 다시 호출하여 문제를 해결하는 알고리즘입니다.</li>
<li>반복을 중단할 조건이 반드시 필요합니다.</li>
</ul>
<blockquote>
<p>출처
<a href="https://dev-coco.tistory.com/160">https://dev-coco.tistory.com/160</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[신입 CS 질문] 자료구조]]></title>
            <link>https://velog.io/@jinny-park/%EC%8B%A0%EC%9E%85-CS-%EC%A7%88%EB%AC%B8-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@jinny-park/%EC%8B%A0%EC%9E%85-CS-%EC%A7%88%EB%AC%B8-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Thu, 03 Aug 2023 03:52:40 GMT</pubDate>
            <description><![CDATA[<h2 id="arraylist의-가장-큰-특징과-그로-인해-발생하는-장점과-단점">Array(List)의 가장 큰 특징과 그로 인해 발생하는 장점과 단점</h2>
<ul>
<li>순차적 데이터 저장</li>
<li>0부터 시작하는 index를 토해 특정 요소의 검색과 조작이 쉽다는 장점 </li>
<li>중간에 요소의 삽입, 삭제가 일어나는 경우 뒤의 모든 요소들을 옮겨야 하는 단점이 있음 </li>
<li>정보가 자주 삭제되거나 추가되는 데이터를 담기에는 적절하지 않음 </li>
</ul>
<h2 id="array를-적용시키면-좋을-데이터의-예">Array를 적용시키면 좋을 데이터의 예</h2>
<ul>
<li>주식 차트는 순서가 날짜별로 가져야 저장되어야 하며 중간에 데이터에대한 추가 및 삭제가 없기 때문에 좋은 예시 </li>
<li>순서가 가장 중요하므로 순서를 보장해주는 array 자료구조가 적합 </li>
</ul>
<h2 id="stack">Stack</h2>
<ul>
<li>선형 자료구조</li>
<li>Array와 LinkedList로 구현</li>
<li>후입선출(LIFO) 구조 </li>
<li>자바의 지역변수, 매개변수 데이터 값이 저장되는 메모리 영역 </li>
</ul>
<h2 id="queue">QUEUE</h2>
<ul>
<li>선형 자료구조</li>
<li>Array와 LinkedList로 구현</li>
<li>선입선출(FIFO)구조</li>
<li>OS에서 자원의 할당과 회수를 하는 스케쥴러 역할 </li>
</ul>
<h2 id="priority-queue우선순위-큐">Priority Queue(우선순위 큐)</h2>
<ul>
<li><p>우선순위 큐는 들어간 순서에 상관없이 우선순위가 높은 데이터를 먼저 꺼내기 위해 고안된 자료구조</p>
</li>
<li><p>우선순위 큐 구현 방식에는 배열, 연결 리스트, 힙이 있고, 그중 힙 방식이 worst case라도 시간 복잡도 O(logN)을 보장하기 때문에 일반적으로 완전 이진트리 형태의 힙을 이용해 구현</p>
</li>
</ul>
<h2 id="tree">TREE</h2>
<ul>
<li>비선형 구조</li>
<li>계층적 관계 표현</li>
</ul>
<h2 id="heap">HEAP</h2>
<ul>
<li>최댓값 또는 최솟값을 찾아내기 위해 고안된 구조</li>
<li>완전 이진트리이며</li>
<li>각 노드의 키 값이 자식의 키 값보다 작지 않은 최대힙을 가짐</li>
<li>각 노드의 키 값이 자식의 키 값보다 크지 않은 최소힙을 가짐</li>
</ul>
<h2 id="완전이진트리">완전이진트리</h2>
<ul>
<li>마지막 레벨을 제외하고 모든 레벨은 노드가 완전히 채워져 있으며, 마지막 레벨이 모든 노드는 가능한 가장 왼쪽에 있는 트리</li>
</ul>
<h2 id="array와-arraylist의-차이점">Array와 ArrayList의 차이점</h2>
<ul>
<li>Array는 크기가 고정적이고, ArrayList는 크기가 가변적</li>
<li>Array는 초기화 시 메모리에 할당되어 ArrayList보다 속도가 빠름</li>
<li>ArrayList는 데이터 추가 및 삭제 시 메모리를 재할당하기 때문에 속도가 Array보다 느림</li>
</ul>
<h2 id="array와-linkedlist의-장단점">Array와 LinkedList의 장/단점</h2>
<h3 id="array">Array</h3>
<ul>
<li>Array는 검색이 빠르지만, 삽입, 삭제가 느리다.</li>
</ul>
<h3 id="linkedlist">LinkedList</h3>
<ul>
<li>LinkedList는 삽입, 삭제가 빠르지만, 검색이 느리다.</li>
</ul>
<h2 id="해시-테이블hash-table과-시간-복잡도">해시 테이블(Hash Table)과 시간 복잡도</h2>
<ul>
<li><p>해시 테이블은 (Key, Value)로 데이터를 저장하는 자료구조 중 하나로 빠르게 데이터를 검색할 수 있는 자료구조</p>
</li>
<li><p>Key값은 해시함수에 의해 고유한 index를 가지게 되어 바로 접근할 수 있으므로 평균 O(1)의 시간 복잡도를 가짐</p>
</li>
</ul>
<h2 id="hash-map과-hash-table의-차이점">Hash Map과 Hash Table의 차이점</h2>
<ul>
<li>동기화 지원 여부와 null 값 허용 여부의 차이<h3 id="해시-테이블hash-table">해시 테이블(Hash Table)</h3>
</li>
<li>병렬 처리를 할 때 (동기화를 고려해야 하는 상황) Thread-safe 하다.</li>
<li>Null 값을 허용하지 않는다.</li>
</ul>
<h3 id="해시-맵hash-map">해시 맵(Hash Map)</h3>
<ul>
<li>Null 값을 허용한다.</li>
</ul>
<h2 id="bstbinary-search-tree와-binary-tree에-대해-설">BST(Binary Search Tree)와 Binary Tree에 대해 설</h2>
<h3 id="이진트리">이진트리</h3>
<ul>
<li>이진트리(Binary Tree)는 자식 노드가 최대 두 개인 노드들로 구성된 트리</li>
</ul>
<h3 id="이진탐색트리">이진탐색트리</h3>
<ul>
<li>이진 탐색 트리(BST)는 이진 탐색과 연결 리스트를 결합한 자료구조</li>
<li>왼쪽 트리의 모든 값은 바드시 부모 노드보다 작아야하고, 오른쪽 트리의 값은 부모노드보다 커야 한다. </li>
<li>높이가 H일때 시간 복잡도는 O(h)이며, 트리의 균형이 한쪽으로 치우쳐진 경우 worst case가 디ㅗ고 O(n)의 시간 복잡도를 가진다. </li>
</ul>
<h2 id="rbtred-black-tree에-대해-설명해주세요">RBT(Red-Black Tree)에 대해 설명해주세요.</h2>
<ul>
<li><p>RBT(Red-Black Tree)는 이진 탐색 트리를 기반으로 하는 트리 형식 자료구조</p>
</li>
<li><p>이진 탐색 트리의 worst case를 막기위해 나온 구조</p>
</li>
<li><p>BST의 삽입, 삭제 연산 과정에서 발생할 수 있는 문제점을 해결하기 위해 만들어졌음</p>
</li>
<li><p>노드의 child가 없을 경우 child를 가리키는 포인터는 NIL 값을 저장합니다. 이러한 NIL들을 leaf node로 간주합니다.</p>
</li>
</ul>
<blockquote>
<p>참조 
<a href="https://dev-coco.tistory.com/159">https://dev-coco.tistory.com/159</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[신입 CS 질문] 프로젝트 관련 기술 질문 ]]></title>
            <link>https://velog.io/@jinny-park/%EC%8B%A0%EC%9E%85-CS-%EC%A7%88%EB%AC%B8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B4%80%EB%A0%A8-%EA%B8%B0%EC%88%A0-%EC%A7%88%EB%AC%B8</link>
            <guid>https://velog.io/@jinny-park/%EC%8B%A0%EC%9E%85-CS-%EC%A7%88%EB%AC%B8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B4%80%EB%A0%A8-%EA%B8%B0%EC%88%A0-%EC%A7%88%EB%AC%B8</guid>
            <pubDate>Mon, 31 Jul 2023 07:09:56 GMT</pubDate>
            <description><![CDATA[<h1 id="인턴-프로젝트">인턴 프로젝트</h1>
<h3 id="db-정규화">DB 정규화</h3>
<ul>
<li>Db 정규화란 릴레이션 간의 잘못된 종속 관계로 인해 데이터베이스 이상 현상이 일어나서 이를 해결하기위해 릴레이션을 여러 개로 분리하는 과정입니다. </li>
</ul>
<h3 id="db-반정규화">DB 반정규화</h3>
<ul>
<li>데이터베이스 성능 향상을 위해 중복을 허용하고 조인을 줄이는 것</li>
</ul>
<h3 id="db--이상현상">DB  이상현상</h3>
<ul>
<li>데이터베이스 이상 현상에는 삽입이상, 갱신이상, 삭제이상이 존재합니다.</li>
</ul>
<h3 id="mybatis를-사용한-이유가-있나요">Mybatis를 사용한 이유가 있나요?</h3>
<ul>
<li>빠른 시간내에 프로젝트를 완성 시켜야 했기 때문에 다수의 팀원들이 사용 경험이 있었던 mybatis를 선택하게 되었습니다. 또한 작성해야 할 쿼리들이 복잡했기 때문에 복잡한 쿼리문의 작성이 가능한 mybatis를 선택했습니다. </li>
</ul>
<h3 id="jpa와-my-batis의-차이점을-설명해-주세요">Jpa와 My batis의 차이점을 설명해 주세요</h3>
<ul>
<li>Jap는 orm의 기술 표준이며 CRUD 메소드를 기본적으로 제공하기에 쿼리를 만들지 않아도 된다는 특징이 있습니다. Mybatis는 java에서 sql mapper를 지원해주는 프레임워크로 sql을직접 작성해 수행 결과를 객체와 매핑한다는 특징이 있으며 xml로 쿼리문을 작성합니다. </li>
</ul>
<h3 id="orm-이란-무엇인가요-">ORM 이란 무엇인가요 ?</h3>
<ul>
<li>ORM이란 객체와 DB테이블이 매핑을 이루는 것을 말한다. 즉 객체가 테이블이 되도록 매핑 시켜주는 것을 말함</li>
</ul>
<h3 id="ajax">Ajax</h3>
<ul>
<li>전체 페이지를 고치지 않고도 페이지의 일부분만을 위한 데이터 로드 기법</li>
<li>자바스크립트를 사용한 비동기 통신 방식</li>
</ul>
<h3 id="인턴십을-하면서-배운-문서화-작업에는-어떠한-것들이-있었나요">인턴십을 하면서 배운 문서화 작업에는 어떠한 것들이 있었나요?</h3>
<ul>
<li>계획서 및 설계서와 같은 문서화 작업을 진행했습니다. 설계서는 화면 설계서나 api 명세서와 같은 것을 주로 작성했으며 양식은 따로 없었고 자유롭게 작성하요 보고하라고 하셨습니다. </li>
</ul>
<h3 id="웹-렌더링에-대해서-설명해-주세요">웹 렌더링에 대해서 설명해 주세요.</h3>
<ul>
<li>브라우저 렌더링은 HTML, CSS, JavaScript 등의 웹 페이지 자원을 브라우저가 화면에 그리는 과정을 말합니다.</li>
<li>Dom 트리를 생성합니다.</li>
<li>CSS 파싱을 통해 CSSOM 트리를 생성하고 </li>
<li>DOM트리와 CSSSOM 트리를 결합하여 렌더 트리를 사용하여 최종 사용자 웹 페이지를 생성 합니다. </li>
</ul>
<h3 id="http에-대해서-설명해-주세요">http에 대해서 설명해 주세요</h3>
<ul>
<li>웹상에서 서버와 클라이언트 사이의 통신을 위한 프로토콜</li>
</ul>
<h3 id="https">Https</h3>
<ul>
<li>애플리케이션 계층과 전송 계층 사이에 신뢰 계층인 ssl/ TLS 계층을 넣은 신뢰할 수 있는 http 요청을 말합니다. </li>
<li>Ssl / Tls 는 전송 계층에서 보안을 제공하는 프로토콜 </li>
</ul>
<h3 id="스프링-부트란">스프링 부트란</h3>
<ul>
<li>개발의 간편화를 최우선으로하는 자바 프레임워크입니다. </li>
<li>spirng mvc 기반의 자바 웹 개발을 더 쉽게 만들어주는 특징이 있습니다.
스프링 부트를 쓰면 좋은 점</li>
<li>편리함과 생산성이 가장 큰 장점입니다.</li>
</ul>
<h3 id="spring-boot와-spring-mvc-차이점">Spring boot와 Spring mvc 차이점</h3>
<ul>
<li>spring mvc는 모델-뷰-컨트롤러 디자인 패턴을 사용하는 일관된 구조를 제공하면서 자바 웹 개발을 쉽게 하게 해줍니다. </li>
<li>스프링부트는 spring mvc를 포함하는 spring 프레임워크를 가지고 웹 개발을 하면서 가지는 환경설정, 의존성관리를 더 간편하고 쉽게 개발하게 해줍니다. </li>
</ul>
<h3 id="spring-boot와-spring-framework의-차이점을-설명해주세요">Spring Boot와 Spring Framework의 차이점을 설명해주세요.</h3>
<ul>
<li>가장 큰 차이점은 Auto Configuration의 차이인 것 같습니다. Spring은 프로젝트 초기에 다양한 환경설정을 해야 하지만,</li>
<li>Spring Boot는 설정의 많은 부분을 자동화하여 사용자가 편하게 스프링을 활용할 수 있도록 돕습니다.</li>
<li>spring boot starter dependency만 추가해주면 설정은 끝나고, 내장된 톰캣을 제공해 서버를 바로 실행할 수 있습니다.</li>
</ul>
<h3 id="spring-mvc에-대해-설명해주세요">Spring MVC에 대해 설명해주세요.</h3>
<ul>
<li><p>MVC는 Model, View, Controller의 약자이며, 각 레이어간 기능을 구분하는데 중점을 둔 디자인 패턴입니다.</p>
</li>
<li><p>Model은 데이터 관리 및 비즈니스 로직을 처리하는 부분이며, (DAO, DTO, Service 등)</p>
</li>
<li><p>View는 비즈니스 로직의 처리 결과를 통해 유저 인터페이스가 표현되는 구간입니다</p>
</li>
<li><p>Controller는 사용자의 요청을 처리하고 Model과 View를 중개하는 역할을 합니다. </p>
</li>
</ul>
<h3 id="vo와-bo-dao-dto에-대해-설명해주세요">VO와 BO, DAO, DTO에 대해 설명해주세요.</h3>
<ul>
<li>DAO(Data Access Object) DB의 데이터에 접근을 위한 객체를 말합니다. (Repository 또는 Mapper에 해당)</li>
<li>BO(Business Object) 여러 DAO를 활용해 비즈니스 로직을 처리하는 객체를 말합니다. (Service에 해당)</li>
<li>DTO(Data Transfer Object) 각 계층간의 데이터 교환을 위한 객체를 말합니다. (여기서 말하는 계층은 Controller, View, Business Layer, Persistent Layer)
VO (Value Object) 실제 데이터만을 저장하는 객체를 말합니다.</li>
</ul>
<h3 id="스프링부트-오토-컨피규레이션">스프링부트 오토 컨피규레이션</h3>
<ul>
<li>빌드하고자 하는 애플리케이션이 어떤 종류의 애플리케이션인지 탐지해서 필요로하는 컴포넌트들을 자동으로 설정해 준다. </li>
</ul>
<h3 id="스프링부트-스타더-디펜던시">스프링부트 스타더 디펜던시</h3>
<ul>
<li>스프링부트에서 의존성 관리 문제를 해결해주는 역할을 합니다.</li>
</ul>
<h1 id="캡스톤-프로젝트">캡스톤 프로젝트</h1>
<h3 id="retrofit-라이브러리에-대해서-설명해-주세요">Retrofit 라이브러리에 대해서 설명해 주세요</h3>
<ul>
<li>안드로이드에서 rest api 통신연결을 위해 개발된 라이브러리입니다. 간단한 구현과 빠른 성능 특징입니다. 실제로 이전 통신 방식인 httpurlconnection 방식에 비해서 어노테이션 작성을 통한 가독성 증가와 connection 및 stream과 인코딩 설정을 라이브러리로 넘겨서 설정하기 때문에 구현 방식이 간단합니다. </li>
</ul>
<h3 id="주제를-선정은-누구의-아이디어-인가요">주제를 선정은 누구의 아이디어 인가요?</h3>
<ul>
<li>팀장의 아이디어 였습니다. 모든 팀원들이 각자 아이디어를 제시 했고 그 중에서 결식 아동을 위한 가맹점 정보와 선한 영향력 캠페인에 참여하는 가맹점에 대한 정보를 동시에 제공하는 모바일 앱 서비스가 없다는 점에서 차별점을 두었기 때문에 선택하게 되었습니다. </li>
</ul>
<h3 id="개발을-하면서-어려웠던-점이-있었나요">개발을 하면서 어려웠던 점이 있었나요?</h3>
<ul>
<li>Rest api 연동을 위한 retrofit 통신 개발 부분이 가장 어려웠습니다. </li>
</ul>
<h3 id="jwt가-뭔지-설명해주세요">JWT가 뭔지 설명해주세요</h3>
<ul>
<li>JWT는 서버와 클라이언트 간 정보를 주고 받을 때 Http 리퀘스트 헤더에 JSON 토큰을 넣은 후 서버는 별도의 인증 과정없이 헤더에 포함되어 있는 토큰 정보를 통해 인증합니다.</li>
</ul>
<h3 id="restful-api">RESTFUL API</h3>
<ul>
<li>http 프로토콜을 기반으로 하는 웹 서비스 아키텍처</li>
<li>자원을 이름으로 구분하여 해당 자원의 상태를 주고받는 것을 의미 </li>
<li>URL을 통해 자원을 명시하고 HTTP 메소드를 통해 해다 자원에 대한 CRUD를 적용 </li>
<li>표준 HTTP 메소드(GET, POST, PUT, DELETE)를 사용하여 서버와 통신</li>
</ul>
<h3 id="aws란">AWS란?</h3>
<p>aws는 Amazon Web Services의 약자로, 아마존닷컴에서 운영하는 Cloud Computing Platform이다.
다른 웹 사이트나 클라이언트측 응용 프로그램에 대해 온라인 서비스를 제공하고 있다.</p>
<h1 id="교육원-홈페이지-개발-프로젝트">교육원 홈페이지 개발 프로젝트</h1>
<h3 id="jsp와-my-sql을-사용한-이유가-무엇인가요">Jsp와 my sql을 사용한 이유가 무엇인가요?</h3>
<ul>
<li>학과 홈페이지를 개발했던 기술 스택이 jsp와 my sql이었습니다. 이러한 이유로 담당 지도 교수님께서 웹 개발에 대한 경험을 처음 쌓기에는 해당 기술을 사용해서 하는 것도 괜찮을 것이라고 하여서 jsp와 mysql을 사용하여 백엔드 부분을 개발했습니다. </li>
</ul>
<h3 id="구글-로그인을-없애고-다시-원래의-방식으로-바꾸게-된-이유가-있을까요">구글 로그인을 없애고 다시 원래의 방식으로 바꾸게 된 이유가 있을까요?</h3>
<ul>
<li>구글auth 에서 ssl 프로코콜 정책이 바뀌어서 서버 컴에 인증서를 받아야 했습니다 하지만 학과 서버 앞단에는 학교 전산원이 있다보니 인증서 관리주체에 대한 문제가 있어서 원래의 방식으로 다시 복구하게 되었습니다. </li>
</ul>
<h3 id="ssl-프로토콜이-무엇인가요">Ssl 프로토콜이 무엇인가요?</h3>
<ul>
<li>Ssl / Tls 는 전송 계층에서 보안을 제공하는 프로토콜</li>
</ul>
<h3 id="jsp">JSP</h3>
<ul>
<li>JavaServer Pages 의 약자이며</li>
<li>HTML 코드에 JAVA 코드를 넣어 동적웹페이지를 생성하는 웹어플리케이션 도구이다.</li>
</ul>
<h3 id="개발하면서-어려웠던-점">개발하면서 어려웠던 점</h3>
<ul>
<li>개발 중간에 요청사항이 바뀌는 점이 가장 어려웠 던 것 같습니다. 하지만 요청사항들을 완료하기 위해 책임감을 가지고 프로젝트를 완료 했으며 이로 인해 개발자로서의 책임 의식을 배우게 되었습니다. </li>
</ul>
<h3 id="ajax-1">Ajax</h3>
<ul>
<li>전체 페이지를 고치지 않고도 페이지의 일부분만을 위한 데이터 로드 기법 </li>
<li>자바스크립트를 사용한 비동기 통신 방식 </li>
<li>연속적인 데이터 요청 시 서버 부하가 증가하여 페이지가 느려짐 </li>
</ul>
<h3 id="동기">동기</h3>
<ul>
<li>결과가 동시에 이루어지는 것</li>
<li>결과가 주어질 때 까지 아무것도 하지 못하고 대기해야 함 </li>
</ul>
<h3 id="비동기">비동기</h3>
<ul>
<li>결과가 주어지는 시간이 걸리더라도 그 시간동안 다른 작업을 해서 자원을 효율적으로 이용 </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[신입 CS 질문] 자바]]></title>
            <link>https://velog.io/@jinny-park/%EC%8B%A0%EC%9E%85-CS-%EC%A7%88%EB%AC%B8-%EC%9E%90%EB%B0%94</link>
            <guid>https://velog.io/@jinny-park/%EC%8B%A0%EC%9E%85-CS-%EC%A7%88%EB%AC%B8-%EC%9E%90%EB%B0%94</guid>
            <pubDate>Mon, 31 Jul 2023 07:04:01 GMT</pubDate>
            <description><![CDATA[<h2 id="java">JAVA</h2>
<h3 id="자바의-특징">자바의 특징</h3>
<ul>
<li>객체지향 프로그래밍 언어</li>
</ul>
<h3 id="객체지향-프로그래밍oop">객체지향 프로그래밍(OOP)</h3>
<ul>
<li>객체들의 집합으로 프로그램의 상호 작용을 표현</li>
<li>데이터를 객체로 취급하여 객체 내부에 선언된 메소드를 활용하는 방식 </li>
<li>설계에 많은 시간이 소요되고 처리 속도가 느림 </li>
</ul>
<h3 id="객체-지향-프로그래밍의-특징">객체 지향 프로그래밍의 특징</h3>
<h4 id="추상화">추상화</h4>
<ul>
<li>핵심적인 개념 또는 기능을 간추려 내는 것 <h4 id="캡슐화">캡슐화</h4>
</li>
<li>객체의 속성과 메서드를 하나로 묶고 일부를 외부에 감추어 은닉 <h4 id="다형성">다형성</h4>
</li>
<li>상위 클래스가 동일한 메시지로 하위 클래스들을 서로 다르게 동작시키는 객체 지향 원리</li>
<li>오버로딩</li>
<li>오버라이딩 <h4 id="상속성">상속성</h4>
</li>
<li>상위 클래스의 특성을 하위클래스가 이어받아 재사용하거나 확정하는 것 </li>
</ul>
<h3 id="오버로딩과-오버라이딩">오버로딩과 오버라이딩</h3>
<h4 id="오버로딩">오버로딩</h4>
<ul>
<li>같은 이름을 가진 메서드를 여러개 두는것을 말함.</li>
<li>메서드의 타입, 매개변수의 유형, 개수 등이 달라짐</li>
<li>컴파일 중에 발생하는 정적 다형성 </li>
</ul>
<h4 id="오버라이딩">오버라이딩</h4>
<ul>
<li>상위 클래스로부터 상속받은 메서드를 하위클래스에서 재 정의하여 사용하는 것</li>
<li>런타임 중에 발생하는 동적 다형성 </li>
</ul>
<h3 id="oop의-장점과-단점">OOP의 장점과 단점</h3>
<h4 id="장점">장점</h4>
<ul>
<li>코드 재사용 용이</li>
<li>유지보수 용이</li>
<li>생산성 향상</li>
</ul>
<h4 id="단점">단점</h4>
<ul>
<li>실행속도 저하</li>
<li>설계에 소요가 많음 </li>
</ul>
<h3 id="oop-5가지-설계-원칙">OOP 5가지 설계 원칙</h3>
<h4 id="단일책임원칙">단일책임원칙</h4>
<ul>
<li>하나의 클래스는 하나의 책임만 가진다.<h4 id="개방-폐쇠원칙">개방-폐쇠원칙</h4>
</li>
<li>확장에는 열려있고 변경에는 닫혀있다. <h4 id="리스코프치환원칙">리스코프치환원칙</h4>
</li>
<li>프로그램의 정확성을 깨드리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 함<h4 id="인터페이스분리원칙">인터페이스분리원칙</h4>
</li>
<li>일반적인 인터페이스 보다는 구체적인 여러개의 인터페이스를 만들어야 함<h4 id="의존-역전-원칙">의존 역전 원칙</h4>
</li>
<li>추상화된 인터페이스나 상위클래스를 두어 변하기 쉬운것의 변화에 영향을 받지 않게 하는 원칙 </li>
</ul>
<h3 id="자바의-장점">자바의 장점</h3>
<ul>
<li>JVM위에서 동작하기 때문에 운영체제에 독립적이다.</li>
<li>가비지 컬렉터를 통해서 자동적인 메모리 관리가 가능</li>
</ul>
<h3 id="자바-단점">자바 단점</h3>
<ul>
<li>JVM 위에서 동작하기 때문에 실행속도가 상대적으로 느림</li>
<li>다중 상속이나 타입에 엄격하며, 제약이많음</li>
</ul>
<h3 id="자바-jvm-역할-설명">자바 JVM 역할 설명</h3>
<ul>
<li>JVM은 스택 기반으로 동작하며 자바 바이트 코드를 OS에 맞게 해석해주는 역할을하며 가비지 컬렉션을 통해 자동적인 메모리 관리를 해줌</li>
</ul>
<h3 id="자바-컴파일-과정">자바 컴파일 과정</h3>
<ul>
<li>.java 파일 생성</li>
<li>빌드</li>
<li>컴파일러를 통해 바이트 코드를 생성</li>
<li>클래스 로더를 통해 JVM 메모리 내로 로드</li>
<li>실행 엔진을 통해 각 운영체제에 맞는 기계어로 해석 </li>
</ul>
<h3 id="생성자">생성자</h3>
<ul>
<li>클래스와 같은 이름의 메서드로, 새 객체가 생성될 때 호출되는 메서드</li>
<li>파라미터를 다르게 해 오버로딩 할 수 있음 </li>
</ul>
<h3 id="자바-원시-타입과-각-몇-바이트를-차지하나">자바 원시 타입과 각 몇 바이트를 차지하나?</h3>
<ul>
<li>정수형 byte(1), short(2), int(4), long(8) </li>
<li>실수형 float(4), double(8)</li>
<li>문자형 char (2)</li>
<li>논리형 boolean (1)</li>
</ul>
<h3 id="지역변수">지역변수</h3>
<ul>
<li>메서드 안에서 정의되어 메서드 안의 스코프에서만 존재</li>
</ul>
<h3 id="인스턴스변수">인스턴스변수</h3>
<ul>
<li>클래스에서 정의되어 클래스 전체의 스코프 안에서 존재</li>
<li>필드라고 생각하면 됨 </li>
</ul>
<h3 id="객체">객체</h3>
<ul>
<li>클래스를 기반으로 생성되는 데이터 </li>
</ul>
<h3 id="인스턴스">인스턴스</h3>
<ul>
<li>객체에 메모리가 할당되어 실제로 활용되는 실체</li>
</ul>
<h3 id="클래스란">클래스란?</h3>
<ul>
<li>클래스는 객체를 만들기 위한 틀 혹은 설계도</li>
</ul>
<h3 id="메소드란">메소드란?</h3>
<ul>
<li>클래스에 종속되어 인스턴스와 연결되어 있는 어떤 특정 작업을 수행하기 위한 명령문의 집합</li>
</ul>
<h3 id="불변-객체란">불변 객체란?</h3>
<ul>
<li>객체 생성 이후 내부의 상태가 변하지 않는 객체</li>
<li>자바에서는 필드가 원시타입일 경우 final을 사용해 불변 객체를 만들수 있음</li>
</ul>
<h3 id="참조-타입">참조 타입</h3>
<ul>
<li>객체 참조</li>
<li>배열</li>
<li>리스트</li>
</ul>
<h3 id="불변-객체나-final을-사용해야하는-이유">불변 객체나 final을 사용해야하는 이유?</h3>
<ul>
<li>메소드 호출 시 파라미터 값이 변하지 않는 것을 보장</li>
<li>부수효과를(변수의 값이 변함)피해 오류 최소화 </li>
</ul>
<h3 id="상속">상속</h3>
<ul>
<li>자식 클래스가 부모 클래스의 메서드 등을 상속받아 사용</li>
<li>자식 클래스에서 추가 및 확장을 할 수 있는 것</li>
<li>재사용성, 중복성의 최소화 </li>
</ul>
<h3 id="구현">구현</h3>
<ul>
<li>부모 인터페이스를 자식 클래스에서 재정의하여 구현</li>
<li>상속과는 달리 반드시 부모 클래스의 메서드를 재 정의 해야함 </li>
</ul>
<h3 id="추상클래스">추상클래스</h3>
<ul>
<li>클래스 안에 추상메서드가 하나 이상 포함되거나 abstract로 정의된 경우</li>
<li>상속 받아서 기능을 이용하고 확장할 수 있음 </li>
<li>static이나 final이 아닌 필드를 가질 수 있음 </li>
<li>일반 변수, 메서드를 가질 수 있음 </li>
<li>인스턴스를 생성할 수 없음 </li>
<li>다중 상속 불가능함 </li>
</ul>
<h3 id="인터페이스">인터페이스</h3>
<ul>
<li>모든 메소드가 추상 메소드로만 이루어져 있는 것을 말함  </li>
<li>상수(static final)와 추상메서드의 집합 </li>
<li>추상 클래스와 다르게 구현부가 있는 일반 메소드와, 일반 멤버 변수를 가질 수 없음 </li>
<li>다중 구현이 가능 </li>
<li>인스턴스를 생성할 수 없음 </li>
<li>상속받은 클래스는 반드시 추상 메서드를 구현해야 한다.</li>
</ul>
<h4 id="공통점">공통점</h4>
<ul>
<li>new 연산자로 인스턴스 생성 불가능</li>
<li>사용하기 위해서는 하위 클래스에서 확장/구현 해야 한다.<h4 id="차이점">차이점</h4>
</li>
<li>인터페이스는 그 인터페이스를 구현하는 모든 클래스에 대해 특정한 메소드가 반드시 존재하도록 강제함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jinny-park/post/f57ced36-38fd-4442-a1af-a6a6f0d52ef8/image.png" alt=""></p>
<blockquote>
<p>출처 <a href="https://code-lab1.tistory.com/287">https://code-lab1.tistory.com/287</a></p>
</blockquote>
<h3 id="call-by-value">Call by value</h3>
<ul>
<li>값에 의한 호출 </li>
<li>함수 호출 시 전달되는 변수의 값을 복사하여 함수의 인자로 전달 </li>
<li>복사된 인자는 함수의 지역변수로 사용 </li>
</ul>
<h3 id="call-by-reference">call by reference</h3>
<ul>
<li>참조에의한 호출</li>
<li>함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달 </li>
<li>함수 안에서 인자의 값이 변경되면,함수 호출시에 있던 변수들도 값이 변함 </li>
</ul>
<h4 id="자바의-경우-데이터-타입에-따라서-함수-호출-방식이-달라짐">자바의 경우 데이터 타입에 따라서 함수 호출 방식이 달라짐</h4>
<ol>
<li>기본형 : call by value (int, short, long, double, boolean, char)</li>
<li>참조형 : call by reference (Array, Class instace, String)</li>
</ol>
<h3 id="불변객체-string">불변객체 STRING</h3>
<ul>
<li>한번 값이 할당되면 변하지 않음 (불변)</li>
<li>값을 변화시킬 때, heap에 새로운 메모리를 사용하고, 참조되는 주소만을 바꿔줌</li>
</ul>
<h3 id="string이-불변인-이유">String이 불변인 이유</h3>
<ul>
<li>강제로 참조에 대한 문자열 값을 변경하는 것이 불가능해서 보안에 유리</li>
<li>여러 스레드에서 동시에 특정 객체를 참조하더라도 안전함 </li>
</ul>
<h3 id="string-string-builder--string-buffer">STRING/ STRING BUILDER / STRING BUFFER</h3>
<h4 id="string">STRING</h4>
<ul>
<li>한번 값이 할당되면 변하지 않음 (불변)</li>
<li>값을 변화시킬 때, heap에 새로운 메모리를 사용하고, 참조되는 주소만을 바꿔줌</li>
<li>불변이라는 특징으로 인해 이를 해결하기위해 string builder, string buffer 클래스 사용 </li>
</ul>
<h4 id="string-builder-클래스">STRING BUILDER 클래스</h4>
<ul>
<li><p>문자열을 더할 때 새 객체를 생성하는 것이 아니라 기존 문자열에 더하는 형식이라 속도가 빠름 </p>
</li>
<li><p>동기화를 지원하지 않기에 멀티 스레드 환경에서 사용하는 것은 적합하지 않음 </p>
</li>
<li><p>단일스레드에서는 String buffer보다 성능이 뛰어남 </p>
</li>
</ul>
<h4 id="string-buffer-클래스">STRING BUFFER 클래스</h4>
<ul>
<li><p>내부에 독립적인 버퍼를 가지며 16개의 문자를 저장할 수 있음</p>
</li>
<li><p>문자열을 기존 문자열에 더해 추가할 수 있으며 공간 낭비 없이 속도도 빠르다.</p>
</li>
<li><p>동기화를 지원하여 멀티 스레드 환경에서 안전 </p>
</li>
</ul>
<h3 id="가비지-컬렉터">가비지 컬렉터</h3>
<ul>
<li>더 이상 참조되지 않는 메모리/ 객체를 정리해주는 역할 </li>
<li>HEAP 영역 위주로 탐색하여 메모리를 정리해 줌 </li>
</ul>
<h3 id="제네릭">제네릭</h3>
<ul>
<li>타입을 일반화하는 것으로 클래스 내부에서 정하는 것이 아닌 사용자 호출에 의해서 결정하는 것 </li>
<li>재사용성 증가/ 컴파일 시 에러 발견 가능</li>
</ul>
<h3 id="자바-메모리-영역">자바 메모리 영역</h3>
<h4 id="method">METHOD</h4>
<ul>
<li>전역변수와 static변수를 저장하며, 메소드 영역은 프로그램의 시작부터 종료까지 메모리에 남아있음 </li>
<li>JVM이 동작해서 클래스가 로딩될 때 생성</li>
</ul>
<h4 id="heap">HEAP</h4>
<ul>
<li>동적 할당할 때,인스턴스, 배열 등이 힙 영역에 저장</li>
<li>가비지컬렉션에 의해 메모리가 관리됨</li>
<li>런타임 당시 할당 </li>
</ul>
<h4 id="stack">STACK</h4>
<ul>
<li>메소드 호출 정보, 지역변수, 매개변수들이 저장되는 공간 </li>
<li>메소드가 호출될 때 메모리에 할당되고 종료되면 메모리가 해제 </li>
<li>컴파일 당시 할당 </li>
<li>스택영역은 동적으로 크기가 늘어날 수 있기에 힙과 영역이 겹치면 안돼서 힙과 스택 사이에 공간을 비워 둠</li>
</ul>
<h3 id="wrapper-class">Wrapper class</h3>
<ul>
<li>기본 자료형에 대한 객체 표현</li>
<li>기본 자료형을 래퍼 클래스로 변환하는 것을 박싱</li>
<li>래퍼 클래스에서 기본 자료형으로 변환하는 것을 언박싱</li>
</ul>
<h3 id="new-string과-리터럴-차이">new String()과 리터럴(&quot;&quot;) 차이</h3>
<ul>
<li>new String()은 new 키워드로 새로운 객체를 생성하기 때문에 Heap 메모리 영역에 저장</li>
<li>리터럴은 heap 안에 있는 String Pool 영역에 저장</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jinny-park/post/bbd9ffdb-8339-4d0e-a9e5-9813a417645b/image.png" alt=""></p>
<blockquote>
<p>참조 = <a href="https://dev-coco.tistory.com/153">https://dev-coco.tistory.com/153</a></p>
</blockquote>
<h3 id="접근-제한자">접근 제한자</h3>
<ul>
<li>변수 또는 메소드의 접근 범위를 설정해주기 위해서 사용</li>
<li>public 접근 제한이 없다. (같은 프로젝트 내 어디서든 사용 가능)</li>
<li>protected 해당 패키지 내, 다른 패키지에서 상속받아 자손 클래스에서 접근 가능하다.</li>
<li>default 해당 패키지 내에서만 접근 가능</li>
<li>private  해당 클래스에서만 접근 가능</li>
</ul>
<h3 id="클래스-멤버-변수-초기화-순서">클래스 멤버 변수 초기화 순서</h3>
<ul>
<li>static 변수 선언부 : 클래스가 로드 될 때 변수가 제일 먼저 초기화</li>
<li>필드 변수 선언부 : 객체가 생성될 때 생성자 block 보다 앞서 초기화</li>
<li>생성자 block : 객체가 생성될 때 JVM이 내부적으로 locking( thread-safe 영역 )</li>
</ul>
<h3 id="static이란">static이란?</h3>
<ul>
<li>static 키워드를 사용한 변수,메소드는 클래스가 메모리에 올라갈 때 자동으로 생성되며 클래스 로딩이 끝나면 바로 사용 가능</li>
<li>즉 인스턴스 생성없이 사용 가능함 </li>
<li>모든 객체가 메모리를 공유한다는 특징이 있음</li>
<li>가비지 컬렉터 관리 영역 밖에 있어 프로그램이 종료 될 때까지 메모리에 값이 유지</li>
</ul>
<h3 id="static을-사용하는-이유">static을 사용하는 이유</h3>
<ul>
<li>인스턴스 생성 없이 바로 사용이 가능하기 때문에 프로그램 내에서 공통으로 사용되는 데이터들을 관리할 때 사용</li>
</ul>
<h3 id="전역변수">전역변수</h3>
<ul>
<li>class 안의 전체영역에서 사용하는 변수</li>
<li>전역변수 값은 new 를 만나면 초기화</li>
<li>초기화 없이 값을 유지하려면 static 사용</li>
</ul>
<h3 id="정적static변수">정적(static)변수</h3>
<ul>
<li>여러 인스턴스가 공유해서 사용할 수 있는 변수</li>
</ul>
<h3 id="inner-class-장점">Inner class 장점</h3>
<ul>
<li>내부 클래스에서 외부 클래스의 멤버에 손 쉽게 접근 </li>
<li>관련 있는 클래스를 묶어서 캡슐화를 증가</li>
<li>외부에서는 내부클래스를 접근할 수 없어서 보안성 높임</li>
</ul>
<h3 id="에러와-예외의-차이">에러와 예외의 차이</h3>
<ul>
<li>에러는 실행 중 일어날 수 있는 치명적인 오류로 컴파일 시에 체크 안됨</li>
<li>예외는 트라이 캐치 문으로 프로그램의 비정상 종료를 막을 수 있음 </li>
</ul>
<h3 id="컬렉션-프레임-워크">컬렉션 프레임 워크</h3>
<ul>
<li>다수의 데이터를 쉽고 효과적으로 관리할 수 있는 클래스의 집합</li>
</ul>
<h3 id="list">LIST</h3>
<ul>
<li>순서가 있는 데이터 집합</li>
<li>중복 허용</li>
<li>Arraylist, Vector, LinkedList, Stack, Queue</li>
</ul>
<h3 id="set">SET</h3>
<ul>
<li>순서가 없는 데이터 집합</li>
<li>중복 허용 안 함</li>
<li>HashSet/ 순서 보장을 위해서는 LinkedHashSet</li>
</ul>
<h3 id="map">MAP</h3>
<ul>
<li>키와 값이 쌍을 이루는 데이터 집합</li>
<li>중복을 허용하지 않으며 순서가 없음</li>
<li>key의 순서를 보장하기 위해서는 LinkedHashMap을 이용</li>
</ul>
<h3 id="stack-1">STACK</h3>
<ul>
<li>LIFO 구조</li>
</ul>
<h3 id="queue">QUEUE</h3>
<ul>
<li>큐인터페이스는 linkedList에 new 키워드를 적용해 사용</li>
<li>FIFO 구조</li>
</ul>
<h3 id="fianl">fianl</h3>
<ul>
<li>클래스, 메소드, 변수, 인자를 선언할 때 사용할 수 있으며, 한 번만 할당하고 싶을 때 사용</li>
</ul>
<blockquote>
<p>출처 <a href="https://dev-coco.tistory.com/153">https://dev-coco.tistory.com/153</a></p>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>