<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>tech-blog.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sun, 24 Nov 2024 09:30:55 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. tech-blog.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/tech-blog" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[SpringBoot 효율적인 Null 체크]]></title>
            <link>https://velog.io/@tech-blog/SpringBoot-%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%B8-Null-%EC%B2%B4%ED%81%AC-23bq723h</link>
            <guid>https://velog.io/@tech-blog/SpringBoot-%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%B8-Null-%EC%B2%B4%ED%81%AC-23bq723h</guid>
            <pubDate>Sun, 24 Nov 2024 09:30:55 GMT</pubDate>
            <description><![CDATA[<h1 id="springboot-효율적인-null-체크">SpringBoot 효율적인 Null 체크</h1>
<p>SpringBoot를 사용하면서 Null 체크는 필수적인 작업 중 하나다. Null 체크를 효율적으로 처리하지 않으면 코드가 복잡해지고, 예외 처리가 어려워질 수 있다. 오늘은 SpringBoot에서 Optional과 Stream을 사용하여 효율적으로 Null 체크를 하는 방법에 대해 알아보자.</p>
<h2 id="optional을-활용한-null-체크">Optional을 활용한 Null 체크</h2>
<p>Java 8부터 도입된 <code>Optional</code>은 Null을 처리하는 데 유용한 도구다. <code>Optional</code>을 사용하면 NullPointerException을 방지하고, 코드의 가독성을 높일 수 있다. <code>Optional</code>은 값이 존재할 수도 있고, 존재하지 않을 수도 있는 컨테이너 객체다.</p>
<h3 id="optional의-기본-사용법">Optional의 기본 사용법</h3>
<p><code>Optional</code>을 사용하면 객체가 Null인지 아닌지를 명시적으로 처리할 수 있다. 다음은 <code>Optional</code>의 기본적인 사용 예제다.</p>
<pre><code class="language-java">Optional&lt;String&gt; optionalString = Optional.ofNullable(getString());
optionalString.ifPresent(s -&gt; System.out.println(s));</code></pre>
<p>위 코드에서 <code>getString()</code> 메서드가 Null을 반환할 수 있는 상황이라면, <code>Optional.ofNullable()</code>을 사용하여 안전하게 Null 체크를 수행할 수 있다. <code>ifPresent()</code> 메서드를 사용하여 값이 존재할 때만 특정 로직을 수행하도록 한다.</p>
<h2 id="stream과-optional을-활용한-null-체크">Stream과 Optional을 활용한 Null 체크</h2>
<p><code>Stream</code>과 <code>Optional</code>을 함께 사용하면 더욱 강력한 Null 체크와 데이터 처리 로직을 구현할 수 있다. 특히, 데이터 변환 및 필터링 작업을 수행할 때 유용하다.</p>
<h3 id="실전-예제">실전 예제</h3>
<p>다음은 <code>Optional</code>과 <code>Stream</code>을 사용하여 Null 체크를 수행하는 실제 코드 예제다.</p>
<pre><code class="language-java">ResponseEntity&lt;VelogPostResponseDto&gt; response = sendPostRequest(webClient, query, cookie);

Optional.ofNullable(response.getBody()) // Response body의 null 체크
    .map(VelogPostResponseDto::getData)
    .map(VelogPostResponseDto.VelogResponseData::getWritePost) // Posting 실패 예외처리
    .orElseThrow(() -&gt; {
        updateVelogTokens(member, response.getHeaders()); // Token 업데이트
        throw new CustomException(ErrorCode.VELOG_POSTING_ERROR); // Retry 될 수 있도록 예외 Throw
    });</code></pre>
<p>위 코드에서는 <code>sendPostRequest</code> 메서드를 통해 얻은 <code>ResponseEntity</code> 객체의 body가 Null인지 체크하고 있다. <code>Optional.ofNullable()</code>을 사용하여 Null 체크를 수행하고, <code>map()</code> 메서드를 통해 필요한 데이터로 변환한다. 만약 데이터가 존재하지 않는다면 <code>orElseThrow()</code>를 통해 예외를 발생시킨다. 이 과정에서 토큰을 업데이트하는 로직도 포함되어 있다.</p>
<h2 id="결론">결론</h2>
<p>SpringBoot에서 Null 체크는 필수적인 작업이며, 이를 효율적으로 처리하기 위해 <code>Optional</code>과 <code>Stream</code>을 활용할 수 있다. 이러한 방법을 사용하면 코드의 가독성을 높이고, 예외 처리를 보다 명확하게 할 수 있다. 앞으로 SpringBoot 프로젝트를 진행할 때, 이러한 방법을 활용하여 안전한 서비스를 개발하자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SpringBoot 효율적인 Null 체크]]></title>
            <link>https://velog.io/@tech-blog/SpringBoot-%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%B8-Null-%EC%B2%B4%ED%81%AC-ty8qf8zb</link>
            <guid>https://velog.io/@tech-blog/SpringBoot-%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%B8-Null-%EC%B2%B4%ED%81%AC-ty8qf8zb</guid>
            <pubDate>Sun, 24 Nov 2024 06:39:04 GMT</pubDate>
            <description><![CDATA[<h1 id="springboot-효율적인-null-체크">SpringBoot 효율적인 Null 체크</h1>
<p>SpringBoot를 사용하면서 Null 체크는 필수적인 작업이다. NullPointerException은 예상치 못한 곳에서 발생할 수 있어, 이를 방지하기 위한 다양한 방법들이 존재한다. 오늘은 SpringBoot에서 효율적으로 Null 체크를 수행하기 위해 <code>Optional</code>과 <code>Stream</code>을 사용하는 방법을 공부했다.</p>
<h2 id="optional을-활용한-null-체크">Optional을 활용한 Null 체크</h2>
<p>Java 8에서 도입된 <code>Optional</code> 클래스는 Null을 명시적으로 처리할 수 있는 방법을 제공한다. <code>Optional</code>을 사용하면 객체가 존재할 수도 있고, 존재하지 않을 수도 있는 상황을 보다 명확하게 표현할 수 있다. 이를 통해 코드의 가독성을 높이고, NullPointerException을 방지할 수 있다.</p>
<h3 id="optional의-기본-사용법">Optional의 기본 사용법</h3>
<p><code>Optional</code>은 주로 다음과 같은 메서드들을 사용하여 Null 체크를 수행한다:</p>
<ul>
<li><code>Optional.ofNullable()</code>: 객체가 Null인지 아닌지를 확인하고, Null일 경우 빈 Optional 객체를 반환한다.</li>
<li><code>map()</code>: Optional 객체가 값을 가지고 있을 경우, 해당 값을 변환하여 새로운 Optional 객체를 반환한다.</li>
<li><code>orElseThrow()</code>: Optional 객체가 값을 가지고 있지 않을 경우, 지정된 예외를 발생시킨다.</li>
</ul>
<h2 id="stream을-활용한-데이터-처리">Stream을 활용한 데이터 처리</h2>
<p>Java의 <code>Stream</code> API는 컬렉션 데이터를 처리하는 데 있어 강력한 도구이다. <code>Stream</code>을 사용하면 데이터의 필터링, 매핑, 축소 등의 작업을 간결하게 수행할 수 있다. 특히, <code>Optional</code>과 함께 사용하면 더욱 효율적인 Null 체크 및 데이터 처리가 가능하다.</p>
<h2 id="실전-예제-코드">실전 예제 코드</h2>
<p>다음은 <code>Optional</code>과 <code>Stream</code>을 활용하여 SpringBoot에서 Null 체크를 수행하는 예제 코드이다:</p>
<pre><code class="language-java">ResponseEntity&lt;VelogPostResponseDto&gt; response = sendPostRequest(webClient, query, cookie);

Optional.ofNullable(response.getBody()) // Response body의 null 체크
        .map(VelogPostResponseDto::getData)
        .map(VelogPostResponseDto.VelogResponseData::getWritePost) // Posting 실패 예외처리
        .orElseThrow(() -&gt; {
            updateVelogTokens(member, response.getHeaders()); // Token 업데이트
            throw new CustomException(ErrorCode.VELOG_POSTING_ERROR); // Retry 될 수 있도록 예외 Throw
        });</code></pre>
<h3 id="코드-설명">코드 설명</h3>
<ol>
<li><code>sendPostRequest</code> 메서드를 통해 <code>ResponseEntity</code> 객체를 받아온다.</li>
<li><code>Optional.ofNullable(response.getBody())</code>를 사용하여 Response body가 Null인지 체크한다.</li>
<li><code>map</code> 메서드를 사용하여 <code>VelogPostResponseDto</code> 객체의 데이터를 추출하고, 필요한 경우 변환 작업을 수행한다.</li>
<li><code>orElseThrow</code>를 통해 만약 데이터가 존재하지 않을 경우, 예외를 발생시킨다. 이 과정에서 토큰 업데이트 등의 추가 작업도 수행할 수 있다.</li>
</ol>
<p>이와 같은 방법을 통해 SpringBoot 애플리케이션에서 보다 안전하고 효율적인 Null 체크를 수행할 수 있다. <code>Optional</code>과 <code>Stream</code>을 적절히 활용하면 코드의 가독성을 높이고, 예외 처리 로직을 간결하게 유지할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SpringBoot 효율적인 Null 체크]]></title>
            <link>https://velog.io/@tech-blog/SpringBoot-%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%B8-Null-%EC%B2%B4%ED%81%AC</link>
            <guid>https://velog.io/@tech-blog/SpringBoot-%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%B8-Null-%EC%B2%B4%ED%81%AC</guid>
            <pubDate>Sun, 24 Nov 2024 05:45:37 GMT</pubDate>
            <description><![CDATA[<h1 id="springboot-효율적인-null-체크">SpringBoot 효율적인 Null 체크</h1>
<p>SpringBoot 애플리케이션을 개발하면서 Null 체크는 필수적인 작업이다. NullPointerException을 방지하고 코드의 안정성을 높이기 위해 다양한 방법을 사용할 수 있다. 오늘은 SpringBoot에서 효율적으로 Null 체크를 수행하기 위해 <code>Optional</code>과 <code>Stream</code>을 사용하는 방법을 공부했다.</p>
<h2 id="optional을-활용한-null-체크">Optional을 활용한 Null 체크</h2>
<p>Java 8에서 도입된 <code>Optional</code>은 Null을 처리하는 데 유용한 도구다. <code>Optional</code>은 값이 존재할 수도 있고 존재하지 않을 수도 있는 컨테이너 객체로, Null을 직접 다루는 대신 <code>Optional</code>을 사용하여 Null을 안전하게 처리할 수 있다.</p>
<h3 id="optional-사용-예제">Optional 사용 예제</h3>
<p>다음은 <code>Optional</code>을 사용하여 Null 체크를 수행하는 예제 코드다:</p>
<pre><code class="language-java">ResponseEntity&lt;VelogPostResponseDto&gt; response = sendPostRequest(webClient, query, cookie);

Optional.ofNullable(response.getBody()) // Response body의 null 체크
    .map(VelogPostResponseDto::getData)
    .map(VelogPostResponseDto.VelogResponseData::getWritePost) // Posting 실패 예외처리
    .orElseThrow(() -&gt; {
        updateVelogTokens(member, response.getHeaders()); // Token 업데이트
        throw new CustomException(ErrorCode.VELOG_POSTING_ERROR); // Retry 될 수 있도록 예외 Throw
    });</code></pre>
<p>위 코드에서 <code>Optional.ofNullable()</code> 메서드를 사용하여 <code>response.getBody()</code>의 결과가 Null인지 아닌지를 체크한다. 만약 Null이 아니라면 <code>map()</code> 메서드를 통해 연속적으로 데이터를 변환하고, 최종적으로 <code>orElseThrow()</code>를 사용하여 Null일 경우 예외를 던진다.</p>
<h2 id="stream을-활용한-null-체크">Stream을 활용한 Null 체크</h2>
<p><code>Stream</code> API는 컬렉션 데이터의 처리를 간결하게 만들어준다. <code>Stream</code>을 사용하면 Null 체크뿐만 아니라 데이터의 필터링, 매핑, 수집 등을 쉽게 수행할 수 있다.</p>
<h3 id="stream-사용-예제">Stream 사용 예제</h3>
<p><code>Stream</code>을 활용하여 Null 체크를 수행하는 방법은 다음과 같다:</p>
<pre><code class="language-java">List&lt;VelogPostResponseDto&gt; responses = getResponses();

responses.stream()
    .filter(Objects::nonNull) // Null 체크
    .map(VelogPostResponseDto::getData)
    .map(VelogPostResponseDto.VelogResponseData::getWritePost)
    .forEach(data -&gt; {
        // 데이터 처리 로직
    });</code></pre>
<p>위 코드에서는 <code>filter(Objects::nonNull)</code>을 사용하여 Null이 아닌 객체만을 처리하도록 필터링한다. 이후 <code>map()</code>을 통해 데이터를 변환하고, <code>forEach()</code>를 통해 각 데이터를 처리한다.</p>
<h2 id="결론">결론</h2>
<p>SpringBoot에서 Null 체크를 효율적으로 수행하기 위해 <code>Optional</code>과 <code>Stream</code>을 활용할 수 있다. <code>Optional</code>은 Null을 안전하게 처리하는 데 유용하며, <code>Stream</code>은 데이터의 필터링과 변환을 간결하게 만들어준다. 이러한 도구들을 적절히 활용하여 코드의 안정성과 가독성을 높일 수 있다. Null 체크는 작은 부분이지만, 애플리케이션의 안정성을 크게 향상시킬 수 있는 중요한 요소다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[NPE 문제 해결]]></title>
            <link>https://velog.io/@tech-blog/NPE-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0</link>
            <guid>https://velog.io/@tech-blog/NPE-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0</guid>
            <pubDate>Fri, 02 Aug 2024 06:51:42 GMT</pubDate>
            <description><![CDATA[<h1 id="이슈-정의">이슈 정의</h1>
<p>Java에서 NPE(Null Pointer Exception) 문제는 객체가 초기화되지 않은 상태에서 해당 객체의 메서드나 필드에 접근할 때 발생한다. 특히, 초기화되지 않은 List 필드에 접근할 때 자주 발생한다. 이 블로그 포스트에서는 Java의 ArrayNPE 문제를 다루고, 이를 해결하는 방법을 제시한다.</p>
<h1 id="issue-example-code">issue example code</h1>
<pre><code class="language-java">public class Example {
    private ArrayList&lt;String&gt; list;

    public void addItem(String item) {
        list.add(item); // 여기서 NPE 발생 가능
    }

    public static void main(String[] args) {
        Example example = new Example();
        example.addItem(&#39;Hello&#39;);
    }
}</code></pre>
<p>위 코드에서 <code>ArrayList&lt;String&gt; list</code> 필드는 선언되었지만 초기화되지 않았다. 따라서 <code>addItem</code> 메서드에서 <code>list.add(item)</code>을 호출할 때 NPE가 발생할 수 있다.</p>
<h1 id="원인-추론">원인 추론</h1>
<p>NPE 문제는 주로 객체가 초기화되지 않은 상태에서 해당 객체의 메서드나 필드에 접근할 때 발생한다. 위 예제에서는 <code>list</code> 필드가 초기화되지 않았기 때문에 <code>list.add(item)</code> 호출 시 NPE가 발생한다. 이를 해결하기 위해서는 <code>list</code> 필드를 초기화해야 한다.</p>
<h1 id="해결-방법">해결 방법</h1>
<p>Java의 ArrayNPE 문제는 초기화되지 않은 List 필드에 접근할 때 발생한다. 이를 해결하기 위해서는 List 필드를 <code>ArrayList</code>와 같은 List의 구현 클래스의 인스턴스로 초기화하면 된다.</p>
<h1 id="solution-example-code">solution example code</h1>
<pre><code class="language-java">import java.util.ArrayList;

public class Example {
    private ArrayList&lt;String&gt; list = new ArrayList&lt;&gt;(); // 초기화

    public void addItem(String item) {
        list.add(item); // NPE 발생하지 않음
    }

    public static void main(String[] args) {
        Example example = new Example();
        example.addItem(&#39;Hello&#39;);
    }
}</code></pre>
<p>위 예제와 같이 <code>new ArrayList&lt;&gt;();</code>를 통해 List 필드를 초기화하면 ArrayNPE 문제를 예방할 수 있다. 초기화된 <code>list</code> 필드는 <code>addItem</code> 메서드에서 안전하게 접근할 수 있다.</p>
<h1 id="참고-자료">참고 자료</h1>
<ul>
<li><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html">Java 공식 문서 - NullPointerException</a></li>
<li><a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html">Java 공식 문서 - ArrayList</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[소공전 457]]></title>
            <link>https://velog.io/@tech-blog/%EC%86%8C%EA%B3%B5%EC%A0%84-457</link>
            <guid>https://velog.io/@tech-blog/%EC%86%8C%EA%B3%B5%EC%A0%84-457</guid>
            <pubDate>Fri, 02 Aug 2024 06:49:12 GMT</pubDate>
            <description><![CDATA[<h1 id="이슈-정의">이슈 정의</h1>
<p>Spring JPA를 사용하여 엔티티 클래스를 정의할 때, <code>@NoArgsConstructor(access = AccessLevel.PRIVATE)</code>를 사용하면 &#39;Class &#39;StoreEntity&#39; should have [public, protected] no-arg constructor&#39; 에러가 발생할 수 있다. 이 문제는 JPA가 엔티티 클래스를 프록시로 생성할 때 기본 생성자에 접근할 수 없기 때문에 발생한다.</p>
<h1 id="issue-example-code">issue example code</h1>
<pre><code class="language-java">import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
@NoArgsConstructor(access = AccessLevel.PRIVATE) // 여기서 문제가 발생
public class StoreEntity {
    @Id
    private Long id;
    private String name;
}</code></pre>
<h1 id="원인-추론">원인 추론</h1>
<p>JPA는 엔티티 객체를 프록시로 생성할 때 기본 생성자에 접근해야 한다. 하지만 <code>@NoArgsConstructor(access = AccessLevel.PRIVATE)</code>를 사용하면 기본 생성자의 접근 레벨이 private으로 설정되어 JPA가 이를 사용할 수 없게 된다. 따라서 JPA는 기본 생성자의 접근 레벨이 public 또는 protected여야 한다.</p>
<h1 id="해결-방법">해결 방법</h1>
<p>기본 생성자의 접근 레벨을 public 또는 protected로 변경해야 한다. 이를 위해 <code>@NoArgsConstructor(access = AccessLevel.PROTECTED)</code>를 사용하면 된다. 이렇게 하면 JPA가 엔티티 객체를 프록시로 생성할 때 기본 생성자에 접근할 수 있게 된다.</p>
<h1 id="solution-example-code">solution example code</h1>
<pre><code class="language-java">import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 접근 레벨을 protected로 변경
public class StoreEntity {
    @Id
    private Long id;
    private String name;
}</code></pre>
<p>이렇게 수정하면 JPA가 엔티티 객체를 프록시로 생성할 때 기본 생성자에 접근할 수 있어 &#39;Class &#39;StoreEntity&#39; should have [public, protected] no-arg constructor&#39; 에러가 발생하지 않는다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[test]]></title>
            <link>https://velog.io/@tech-blog/test-jnjrodm5</link>
            <guid>https://velog.io/@tech-blog/test-jnjrodm5</guid>
            <pubDate>Fri, 02 Aug 2024 05:54:09 GMT</pubDate>
            <description><![CDATA[<h1 id="이슈-정의">이슈 정의</h1>
<p>JPA를 사용하다 보면 종종 N+1 문제를 마주하게 된다. 이는 데이터베이스 쿼리 성능에 큰 영향을 미칠 수 있는 문제로, 특히 대량의 데이터를 다룰 때 심각한 성능 저하를 초래할 수 있다. 이번 블로그 포스트에서는 JPA N+1 문제의 원인과 이를 해결하는 방법에 대해 알아보겠다.</p>
<h1 id="issue-example-code">issue example code</h1>
<pre><code class="language-java">@Entity
public class Author {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToMany(mappedBy = &#39;author&#39;)
    private List&lt;Book&gt; books = new ArrayList&lt;&gt;();
}

@Entity
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;

    @ManyToOne
    @JoinColumn(name = &#39;author_id&#39;)
    private Author author;
}

public List&lt;Author&gt; findAllAuthors() {
    return entityManager.createQuery(&#39;SELECT a FROM Author a&#39;, Author.class).getResultList();
}</code></pre>
<p>위 코드에서 <code>findAllAuthors</code> 메서드는 모든 저자를 조회하는 쿼리를 실행한다. 하지만 각 저자에 대해 책 목록을 조회할 때 추가적인 쿼리가 실행되며, 이는 N+1 문제를 야기한다.</p>
<h1 id="원인-추론">원인 추론</h1>
<p>N+1 문제는 기본적으로 지연 로딩(Lazy Loading)으로 인해 발생한다. <code>Author</code> 엔티티를 조회할 때 <code>books</code> 필드는 지연 로딩으로 설정되어 있어, 실제로 접근할 때마다 추가적인 쿼리가 실행된다. 이로 인해 저자 수가 N명이라면, N개의 추가 쿼리가 실행되어 총 N+1개의 쿼리가 발생하게 된다.</p>
<h1 id="해결-방법">해결 방법</h1>
<p>N+1 문제를 해결하기 위해서는 조인을 사용하여 한 번의 쿼리로 필요한 데이터를 모두 가져오는 것이 좋다. JPA에서는 <code>fetch join</code>을 사용하여 이를 해결할 수 있다.</p>
<h1 id="solution-example-code">solution example code</h1>
<pre><code class="language-java">public List&lt;Author&gt; findAllAuthorsWithBooks() {
    return entityManager.createQuery(
        &#39;SELECT a FROM Author a JOIN FETCH a.books&#39;, Author.class)
        .getResultList();
}</code></pre>
<p>위 코드에서는 <code>JOIN FETCH</code>를 사용하여 저자와 책을 한 번의 쿼리로 가져오도록 수정하였다. 이를 통해 N+1 문제를 해결할 수 있다.</p>
<p>공식 문서에서도 <code>fetch join</code>을 사용하여 N+1 문제를 해결하는 방법을 설명하고 있다. 자세한 내용은 [Hibernate 공식 문서](<a href="https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#">https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#</a> fetching-fetch-join)를 참고하길 바란다.</p>
<p>이와 같이 JPA N+1 문제를 해결하면 데이터베이스 쿼리 성능을 크게 향상시킬 수 있다. 앞으로 JPA를 사용할 때 N+1 문제를 주의 깊게 살펴보고, 필요할 때 <code>fetch join</code>을 활용하여 최적화된 쿼리를 작성하길 바란다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java NPE 문제]]></title>
            <link>https://velog.io/@tech-blog/Java-NPE-%EB%AC%B8%EC%A0%9C</link>
            <guid>https://velog.io/@tech-blog/Java-NPE-%EB%AC%B8%EC%A0%9C</guid>
            <pubDate>Thu, 01 Aug 2024 16:13:12 GMT</pubDate>
            <description><![CDATA[<h1 id="이슈-정의">이슈 정의</h1>
<p>Java에서 NPE(NullPointerException) 문제는 주로 초기화되지 않은 필드를 접근할 때 발생한다. 특히, List와 같은 컬렉션 필드를 초기화하지 않고 접근할 경우 NPE가 발생할 수 있다.</p>
<h1 id="issue-example-code">issue example code</h1>
<pre><code class="language-java">public class Example {
    private ArrayList&lt;String&gt; list;

    public void addItem(String item) {
        list.add(item); // 여기서 NPE 발생 가능
    }

    public static void main(String[] args) {
        Example example = new Example();
        example.addItem(&#39;Hello&#39;);
    }
}</code></pre>
<p>위 코드에서 &#39;ArrayList<String> list&#39; 필드는 선언되었지만 초기화되지 않았다. 이로 인해 addItem 메서드에서 NPE가 발생할 수 있다.</p>
<h1 id="원인-추론">원인 추론</h1>
<p>NPE 문제는 주로 초기화되지 않은 필드를 접근할 때 발생한다. 위 코드에서는 &#39;list&#39; 필드가 초기화되지 않았기 때문에 addItem 메서드에서 list.add(item) 호출 시 NPE가 발생한다. 이 문제를 해결하기 위해서는 &#39;list&#39; 필드를 초기화해야 한다. 디버깅 툴을 활용하여 필드가 초기화되지 않았음을 확인할 수 있다.</p>
<h1 id="해결-방법">해결 방법</h1>
<p>&#39;list&#39; 필드를 초기화하여 NPE 문제를 해결할 수 있다. 이를 위해 &#39;list&#39; 필드를 ArrayList의 인스턴스로 초기화하면 된다.</p>
<h1 id="solution-example-code">solution example code</h1>
<pre><code class="language-java">import java.util.ArrayList;

public class Example {
    private ArrayList&lt;String&gt; list = new ArrayList&lt;&gt;(); // 초기화

    public void addItem(String item) {
        list.add(item); // NPE 발생하지 않음
    }

    public static void main(String[] args) {
        Example example = new Example();
        example.addItem(&#39;Hello&#39;);
    }
}</code></pre>
<p>위 예제 코드에서 보듯이, &#39;list&#39; 필드를 new ArrayList&lt;&gt;();로 초기화함으로써 NPE 문제를 방지할 수 있다. 초기화된 필드를 사용하면 NPE가 발생하지 않는다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[코테 합격을 위해서]]></title>
            <link>https://velog.io/@tech-blog/%EC%BD%94%ED%85%8C-%ED%95%A9%EA%B2%A9%EC%9D%84-%EC%9C%84%ED%95%B4%EC%84%9C</link>
            <guid>https://velog.io/@tech-blog/%EC%BD%94%ED%85%8C-%ED%95%A9%EA%B2%A9%EC%9D%84-%EC%9C%84%ED%95%B4%EC%84%9C</guid>
            <pubDate>Thu, 01 Aug 2024 15:13:55 GMT</pubDate>
            <description><![CDATA[<h1 id="이슈-정의">이슈 정의</h1>
<p>코딩테스트에 떨어졌다는 것은 많은 개발자들이 겪는 문제 중 하나이다. 특히 알고리즘 문제를 틀려서 떨어지는 경우가 많다. 이 글에서는 코딩테스트에서 알고리즘 문제를 틀리는 원인과 그 해결 방법에 대해 다룬다.</p>
<h1 id="issue-example-code">issue example code</h1>
<pre><code class="language-java">public class AlgorithmExample {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5};
        int target = 9;
        boolean result = findPairWithSum(numbers, target);
        System.out.println(&#39;Pair found: &#39; + result);
    }

    public static boolean findPairWithSum(int[] numbers, int target) {
        for (int i = 0; i &lt; numbers.length; i++) {
            for (int j = i + 1; j &lt; numbers.length; j++) {
                if (numbers[i] + numbers[j] == target) {
                    return true;
                }
            }
        }
        return false;
    }
}</code></pre>
<h1 id="원인-추론">원인 추론</h1>
<p>위의 코드에서 <code>findPairWithSum</code> 메서드는 두 숫자의 합이 주어진 타겟 값과 같은지 확인하는 알고리즘을 구현하고 있다. 그러나 이 알고리즘은 시간 복잡도가 O(n^2)로, 입력 배열의 크기가 커질수록 성능이 급격히 저하된다. 이는 코딩테스트에서 시간 초과로 이어질 수 있다.</p>
<h1 id="해결-방법">해결 방법</h1>
<p>효율적인 알고리즘을 사용하여 문제를 해결할 수 있다. 예를 들어, 해시맵을 사용하여 시간 복잡도를 O(n)으로 줄일 수 있다. 이는 각 숫자를 한 번만 순회하면서 필요한 값을 빠르게 찾을 수 있게 해준다.</p>
<h1 id="solution-example-code">solution example code</h1>
<pre><code class="language-java">import java.util.HashMap;

public class AlgorithmExample {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5};
        int target = 9;
        boolean result = findPairWithSum(numbers, target);
        System.out.println(&#39;Pair found: &#39; + result);
    }

    public static boolean findPairWithSum(int[] numbers, int target) {
        HashMap&lt;Integer, Integer&gt; map = new HashMap&lt;&gt;();
        for (int number : numbers) {
            int complement = target - number;
            if (map.containsKey(complement)) {
                return true;
            }
            map.put(number, 1);
        }
        return false;
    }
}</code></pre>
<p>위의 코드에서는 해시맵을 사용하여 각 숫자의 보수를 빠르게 찾을 수 있게 하였다. 이를 통해 시간 복잡도를 O(n)으로 줄여 코딩테스트에서 시간 초과 문제를 해결할 수 있다. 알고리즘 공부를 통해 다양한 문제 해결 방법을 익히는 것이 중요하다. 공식 문서와 알고리즘 책을 참고하여 꾸준히 공부하는 것이 필요하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바 NPE 문제 해결]]></title>
            <link>https://velog.io/@tech-blog/%EC%9E%90%EB%B0%94-NPE-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0</link>
            <guid>https://velog.io/@tech-blog/%EC%9E%90%EB%B0%94-NPE-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0</guid>
            <pubDate>Wed, 31 Jul 2024 07:59:09 GMT</pubDate>
            <description><![CDATA[<h1 id="이슈-정의">이슈 정의</h1>
<p>Java에서 문자열(String) 관련 문제는 종종 발생할 수 있다. 특히, 문자열을 다루는 과정에서 NullPointerException(NPE) 문제가 자주 발생한다. 이 문제는 주로 초기화되지 않은 문자열 변수를 접근할 때 발생한다.</p>
<h1 id="issue-example-code">issue example code</h1>
<pre><code class="language-java">public class StringExample {
    private String text;

    public void printText() {
        System.out.println(text.length()); // 여기서 NPE 발생 가능
    }

    public static void main(String[] args) {
        StringExample example = new StringExample();
        example.printText();
    }
}</code></pre>
<p>위 코드에서 <code>String text</code> 필드는 선언되었지만 초기화되지 않았다. 따라서 <code>printText</code> 메서드에서 <code>text.length()</code>를 호출할 때 NPE가 발생할 수 있다.</p>
<h1 id="원인-추론">원인 추론</h1>
<p>문자열 변수를 초기화하지 않고 접근하려고 하면 NPE가 발생한다. 이는 Java에서 객체가 초기화되지 않은 상태에서 메서드를 호출하려고 할 때 발생하는 일반적인 문제다.</p>
<h1 id="해결-방법">해결 방법</h1>
<p>문자열 변수를 초기화하여 NPE 문제를 해결할 수 있다. 문자열 변수를 선언할 때 빈 문자열로 초기화하거나, 생성자에서 초기화하는 방법이 있다.</p>
<h1 id="solution-example-code">solution example code</h1>
<pre><code class="language-java">public class StringExample {
    private String text = &#39;&#39;; // 초기화

    public void printText() {
        System.out.println(text.length()); // NPE 발생하지 않음
    }

    public static void main(String[] args) {
        StringExample example = new StringExample();
        example.printText();
    }
}</code></pre>
<p>위 예제에서 <code>String text</code> 필드를 빈 문자열로 초기화하여 NPE 문제를 방지할 수 있다. 이렇게 하면 <code>printText</code> 메서드에서 <code>text.length()</code>를 호출할 때 NPE가 발생하지 않는다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[제목입니다.]]></title>
            <link>https://velog.io/@tech-blog/%EC%A0%9C%EB%AA%A9%EC%9E%85%EB%8B%88%EB%8B%A4</link>
            <guid>https://velog.io/@tech-blog/%EC%A0%9C%EB%AA%A9%EC%9E%85%EB%8B%88%EB%8B%A4</guid>
            <pubDate>Mon, 01 Jul 2024 15:04:03 GMT</pubDate>
            <description><![CDATA[<h1 id="이슈-정의-python-코드를-작성할-때-변수의-자료형이-예상과-다르게-설정되어-오류가-발생할-수-있다-특히-int형-변수를-string형으로-잘못-설정하면-계산이나-비교-연산에서-문제가-발생할-수-있다">이슈 정의 Python 코드를 작성할 때, 변수의 자료형이 예상과 다르게 설정되어 오류가 발생할 수 있다. 특히, int형 변수를 string형으로 잘못 설정하면 계산이나 비교 연산에서 문제가 발생할 수 있다.</h1>
]]></description>
        </item>
        <item>
            <title><![CDATA[안녕하세요]]></title>
            <link>https://velog.io/@tech-blog/%EC%95%88%EB%85%95%ED%95%98%EC%84%B8%EC%9A%94</link>
            <guid>https://velog.io/@tech-blog/%EC%95%88%EB%85%95%ED%95%98%EC%84%B8%EC%9A%94</guid>
            <pubDate>Thu, 27 Jun 2024 15:21:06 GMT</pubDate>
            <description><![CDATA[<p>string</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[test]]></title>
            <link>https://velog.io/@tech-blog/test-nfuu4ncb</link>
            <guid>https://velog.io/@tech-blog/test-nfuu4ncb</guid>
            <pubDate>Thu, 27 Jun 2024 15:12:39 GMT</pubDate>
            <description><![CDATA[<p>string</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[test]]></title>
            <link>https://velog.io/@tech-blog/test-id1vbf72</link>
            <guid>https://velog.io/@tech-blog/test-id1vbf72</guid>
            <pubDate>Thu, 27 Jun 2024 15:02:08 GMT</pubDate>
            <description><![CDATA[<p>string</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[test]]></title>
            <link>https://velog.io/@tech-blog/test-awldzzq9</link>
            <guid>https://velog.io/@tech-blog/test-awldzzq9</guid>
            <pubDate>Thu, 27 Jun 2024 15:00:29 GMT</pubDate>
            <description><![CDATA[<p>string</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[test]]></title>
            <link>https://velog.io/@tech-blog/test-6vxc1r14</link>
            <guid>https://velog.io/@tech-blog/test-6vxc1r14</guid>
            <pubDate>Thu, 27 Jun 2024 14:42:16 GMT</pubDate>
            <description><![CDATA[<p>string</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[test]]></title>
            <link>https://velog.io/@tech-blog/test</link>
            <guid>https://velog.io/@tech-blog/test</guid>
            <pubDate>Thu, 27 Jun 2024 14:40:47 GMT</pubDate>
            <description><![CDATA[<p>string</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SpringBoot] @NoArgsConstructor 접근 레벨]]></title>
            <link>https://velog.io/@tech-blog/SpringBoot-NoArgsConstructor-%EC%A0%91%EA%B7%BC-%EB%A0%88%EB%B2%A8</link>
            <guid>https://velog.io/@tech-blog/SpringBoot-NoArgsConstructor-%EC%A0%91%EA%B7%BC-%EB%A0%88%EB%B2%A8</guid>
            <pubDate>Fri, 07 Jun 2024 15:07:00 GMT</pubDate>
            <description><![CDATA[<h1 id="이슈-정의">이슈 정의</h1>
<p>Spring JPA를 사용하면서 <code>@NoArgsConstructor(access = AccessLevel.PRIVATE)</code> 어노테이션을 사용한 경우, &#39;Class &#39;StoreEntity&#39; should have [public, protected] no-arg constructor&#39; 에러가 발생할 수 있다. 이 문제는 JPA가 엔티티 클래스를 프록시로 생성할 때 매개변수가 없는 생성자의 접근 레벨이 public 또는 protected여야 하기 때문이다.</p>
<h1 id="issue-example-code">issue example code</h1>
<pre><code class="language-java">import lombok.NoArgsConstructor;
import lombok.AccessLevel;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class StoreEntity {
    @Id
    private Long id;
    private String name;
}</code></pre>
<h1 id="원인-추론">원인 추론</h1>
<p>JPA는 엔티티 클래스를 프록시로 생성할 때 기본 생성자를 사용한다. 그러나 기본 생성자의 접근 레벨이 private인 경우, JPA는 해당 생성자에 접근할 수 없어 에러가 발생한다. 따라서 기본 생성자의 접근 레벨을 public 또는 protected로 설정해야 한다.</p>
<h1 id="해결-방법">해결 방법</h1>
<p>기본 생성자의 접근 레벨을 private에서 protected로 변경한다. 이렇게 하면 JPA가 엔티티 클래스를 프록시로 생성할 수 있다.</p>
<h1 id="solution-example-code">solution example code</h1>
<pre><code class="language-java">import lombok.NoArgsConstructor;
import lombok.AccessLevel;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class StoreEntity {
    @Id
    private Long id;
    private String name;
}</code></pre>
<p>이렇게 수정하면 JPA가 엔티티 클래스를 프록시로 생성할 때 문제가 발생하지 않는다. 엔티티 클래스는 매개변수가 없는 생성자의 접근 레벨이 public 또는 protected로 해야 한다는 점을 기억하자.</p>
]]></description>
        </item>
    </channel>
</rss>