<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>suyeon_tech.log</title>
        <link>https://velog.io/</link>
        <description>렛츠고</description>
        <lastBuildDate>Wed, 25 Feb 2026 00:18:53 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>suyeon_tech.log</title>
            <url>https://velog.velcdn.com/images/suyeon_tech/profile/14f5de42-94aa-41c2-a728-94185a36c4eb/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. suyeon_tech.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/suyeon_tech" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Java → Kotlin 마이그레이션 실전기]]></title>
            <link>https://velog.io/@suyeon_tech/Java-Kotlin-%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98-%EC%8B%A4%EC%A0%84%EA%B8%B0</link>
            <guid>https://velog.io/@suyeon_tech/Java-Kotlin-%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98-%EC%8B%A4%EC%A0%84%EA%B8%B0</guid>
            <pubDate>Wed, 25 Feb 2026 00:18:53 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p>팀 프로젝트에서 Java로 작성된 Spring Boot 백엔드를 Kotlin으로 점진적으로 마이그레이션하기로 했다. &quot;한 번에 다 바꾸자&quot;는 욕심을 버리고, <strong>entity/dto 클래스부터 시작해서 충돌을 최소화하며 전환하는 방식</strong>을 선택했다. 이 글은 그 과정에서 마주친 문제들과 선택의 이유를 기록한 글이다.</p>
<hr>
<h2 id="1-첫-번째-시도-lombok을-그냥-두면-안-될까">1. 첫 번째 시도: Lombok을 그냥 두면 안 될까?</h2>
<p>처음엔 단순하게 생각했다. Java 클래스를 Kotlin으로 변환할 때 Lombok 어노테이션(<code>@Getter</code>, <code>@Builder</code>, <code>@AllArgsConstructor</code> 등)을 그냥 유지하면 되지 않을까?</p>
<pre><code class="language-kotlin">// 이렇게 하면 되지 않을까?
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
class Policy { ... }</code></pre>
<p>결과는 빌드 실패였다.</p>
<pre><code>error: cannot find symbol
Policy.builder()</code></pre><h3 id="왜-안-될까">왜 안 될까?</h3>
<p><strong>kapt(Kotlin Annotation Processing Tool)</strong> 는 Kotlin 코드에서 어노테이션을 처리하는 도구인데, <strong>Kotlin primary constructor에 붙은 Lombok 어노테이션은 제대로 처리하지 못한다.</strong> Lombok은 원래 Java 컴파일러의 APT(Annotation Processing Tool)를 기반으로 동작하도록 설계되었기 때문이다.</p>
<h3 id="해결책-companion-object-builder-패턴">해결책: Companion Object Builder 패턴</h3>
<p>Lombok <code>@Builder</code>를 대체하기 위해 Kotlin의 <strong>companion object에 Builder 클래스를 직접 구현</strong>했다.</p>
<pre><code class="language-kotlin">@Entity
@Table(name = &quot;policy&quot;)
class Policy(
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Int? = null,
    var plcyNo: String? = null,
    // ... 모든 필드를 primary constructor로
) {
    companion object {
        // Java 코드에서 Policy.builder() 그대로 사용 가능
        @JvmStatic fun builder() = Builder()

        @JvmStatic fun from(item: PolicyItem, rawJson: String?): Policy = Policy(
            plcyNo = item.plcyNo(),
            // ...
        )
    }

    // 마이그레이션 안정성을 위해 임시로 builder 패턴 직접 구현
    // 최종적으로는 삭제 필요
    class Builder {
        private var plcyNo: String? = null
        fun plcyNo(v: String?) = apply { plcyNo = v }
        fun build() = Policy(plcyNo = plcyNo, ...)
    }
}</code></pre>
<p>핵심은 <strong>기존 Java 코드(<code>Policy.builder()...build()</code>)를 전혀 수정하지 않아도 된다</strong>는 점이다. <code>@JvmStatic</code>을 붙이면 Java에서 companion object 메서드를 정적 메서드처럼 호출할 수 있다.</p>
<hr>
<h2 id="2-kapt--jdk-25-조합의-함정">2. kapt + JDK 25 조합의 함정</h2>
<p>빌드가 계속 실패했는데, 원인이 의외의 곳에 있었다.</p>
<pre><code>&gt; Error while evaluating property &#39;javacOptions&#39; of task &#39;:kaptKotlin&#39;.
   &gt; 25.0.1</code></pre><p><strong>kapt가 JDK 25 버전 문자열을 파싱하지 못하는 버그</strong>였다. 버전 번호가 두 자리(<code>25</code>)가 되면서 kapt 내부 파싱 로직이 실패하는 것이다.</p>
<p>이 문제 때문에 kapt가 실행 자체를 못하게 되니:</p>
<ul>
<li>Lombok <code>@AllArgsConstructor</code> → 생성자 생성 ❌</li>
<li>QueryDSL <code>@QueryProjection</code> → Q클래스 생성 ❌</li>
</ul>
<p>즉, <strong>앞서 마주쳤던 여러 오류의 근본 원인이 사실 하나</strong>였다.</p>
<h3 id="임시-해결">임시 해결</h3>
<pre><code class="language-bash">JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home \
./gradlew clean build</code></pre>
<p><code>build.gradle.kts</code>에 이미 <code>java { toolchain { languageVersion = JavaLanguageVersion.of(21) } }</code> 가 설정되어 있었지만, <strong>Gradle toolchain 설정이 kapt에는 자동으로 적용되지 않는다</strong>는 함정이 있었다. kapt는 별도의 Gradle Worker로 실행되기 때문이다.</p>
<hr>
<h2 id="3-kotlin--java--lombok-혼재의-구조적-한계">3. Kotlin + Java + Lombok 혼재의 구조적 한계</h2>
<p><code>PolicySearchCondition</code>이라는 Java 클래스를 Kotlin 컨트롤러에서 사용할 때 문제가 생겼다.</p>
<pre><code class="language-java">// Java
@Getter @Builder @NoArgsConstructor @AllArgsConstructor
public class PolicySearchCondition {
    private String keyword;
    private Integer age;
    // ...
}</code></pre>
<pre><code class="language-kotlin">// Kotlin
val condition = PolicySearchCondition(
    request.keyword,
    request.age,
    // ... 8개 인수
) // ❌ Too many arguments for &#39;constructor(): PolicySearchCondition&#39;</code></pre>
<p>JDK 21로 바꿔도 동일한 오류가 발생했다. 이건 JDK 버전 문제가 아니라 <strong>Kotlin + Java + Lombok 혼재의 구조적 문제</strong>였다.</p>
<p>Kotlin 컴파일러는 Java Lombok이 생성한 생성자를 컴파일 타임에 알 수 없다. kapt가 stub을 생성해줘야 하는데, Kotlin → Java 혼재 프로젝트에서 이 순서가 꼬이는 것이다.</p>
<h3 id="해결책-kotlin-data-class로-전환">해결책: Kotlin data class로 전환</h3>
<pre><code class="language-kotlin">data class PolicySearchCondition(
    val keyword: String? = null,
    val age: Int? = null,
    val earn: Int? = null,
    val regionCode: String? = null,
    val jobCode: String? = null,
    val schoolCode: String? = null,
    val marriageStatus: String? = null,
    val keywords: List&lt;String&gt;? = null,
)</code></pre>
<p>Lombok 의존을 완전히 제거하고 Kotlin <code>data class</code>로 전환하면 kapt 없이도 생성자가 자동 생성된다.</p>
<hr>
<h2 id="4-kotlin-기본값-파라미터와-java-호환성-jvmoverloads">4. Kotlin 기본값 파라미터와 Java 호환성: @JvmOverloads</h2>
<p><code>ServiceException</code>을 Kotlin으로 마이그레이션할 때 또 다른 호환성 문제가 생겼다.</p>
<pre><code class="language-kotlin">// Kotlin
class ServiceException(
    val resultCode: String,
    val msg: String,
    cause: Throwable? = null  // 기본값!
) : RuntimeException(...)</code></pre>
<p>Kotlin에서는 <code>cause</code>를 생략할 수 있지만, Java에서는 기본값을 인식하지 못한다.</p>
<pre><code class="language-java">// Java
throw new ServiceException(&quot;AUTH-401&quot;, &quot;인증 정보가 없습니다.&quot;);
// ❌ required: String, String, Throwable
//    found:    String, String</code></pre>
<h3 id="해결책-jvmoverloads">해결책: @JvmOverloads</h3>
<pre><code class="language-kotlin">class ServiceException @JvmOverloads constructor(
    val resultCode: String,
    val msg: String,
    cause: Throwable? = null
) : RuntimeException(...)</code></pre>
<p><code>@JvmOverloads</code>를 붙이면 Kotlin 컴파일러가 Java용 오버로딩 생성자를 자동 생성해준다:</p>
<pre><code class="language-java">// Java에서 둘 다 사용 가능
new ServiceException(&quot;AUTH-401&quot;, &quot;인증 오류&quot;)       // ✅
new ServiceException(&quot;AUTH-401&quot;, &quot;인증 오류&quot;, e)    // ✅</code></pre>
<p><strong>단점</strong>도 있다. 파라미터가 많으면 불필요한 오버로딩 조합이 많이 생성되고, 의도하지 않은 생성자가 외부에 노출될 수 있다. 하지만 <code>ServiceException</code>처럼 파라미터가 적은 경우엔 가장 깔끔한 선택이다.</p>
<hr>
<h2 id="5-마이그레이션-순서-전략-의존성-방향을-따라가라">5. 마이그레이션 순서 전략: 의존성 방향을 따라가라</h2>
<p>점진적 마이그레이션에서 가장 중요한 것은 <strong>순서</strong>다. 잘못된 순서로 바꾸면 연쇄 충돌이 발생한다.</p>
<p>우리가 선택한 순서:</p>
<pre><code>1단계: 독립적인 클래스 (다른 클래스를 참조하지 않는 것)
   └── enum 클래스, 예외 클래스

2단계: 단순 설정/프로퍼티 클래스
   └── @ConfigurationProperties, BaseEntity

3단계: 서비스/유틸 클래스
   └── 단방향 의존 구조인 것부터

나중에: Spring Batch, 인증 관련
   └── 팀원 코드가 많거나 안정성이 중요한 것</code></pre><p>그리고 한 가지 중요한 원칙을 지켰다:</p>
<blockquote>
<p><strong>다른 파일 수정이 필요하면 먼저 설명하고 승인받기</strong></p>
</blockquote>
<p>처음에 이 원칙 없이 진행했다가 팀원 코드를 건드리거나 범위를 벗어나는 변경이 생겼다. 마이그레이션은 혼자 하는 작업이 아니기 때문에, 변경 범위를 명확히 하는 것이 중요하다.</p>
<hr>
<h2 id="마치며">마치며</h2>
<p>Java → Kotlin 마이그레이션에서 가장 큰 복병은 <strong>kapt</strong>였다. Lombok, QueryDSL 등 어노테이션 기반 코드 생성 도구들이 Kotlin과 완벽하게 호환되지 않기 때문에, 이 부분을 먼저 이해하고 전략을 세우는 것이 핵심이다.</p>
<p>핵심 교훈을 정리하면:</p>
<table>
<thead>
<tr>
<th>상황</th>
<th>해결책</th>
</tr>
</thead>
<tbody><tr>
<td>Kotlin class에 Lombok <code>@Builder</code> 불가</td>
<td>Companion object Builder 직접 구현</td>
</tr>
<tr>
<td>kapt + JDK 25 파싱 버그</td>
<td>JDK 21로 빌드 또는 toolchain 고정</td>
</tr>
<tr>
<td>Java에서 Kotlin 기본값 파라미터 불인식</td>
<td><code>@JvmOverloads</code></td>
</tr>
<tr>
<td>Kotlin에서 Lombok Java 클래스 생성자 불인식</td>
<td>Kotlin <code>data class</code>로 전환</td>
</tr>
</tbody></table>
<p>점진적 마이그레이션은 느리지만 안전하다. 팀원과의 충돌을 최소화하면서 코드베이스를 개선해나가는 것, 그게 실무에서의 마이그레이션이다.</p>
<hr>
<p>어떠세요? 분량이나 톤, 추가하고 싶은 내용이 있으면 말씀해주세요!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Policy.java를 코틀린으로 마이그레이션하지 않은 이유]]></title>
            <link>https://velog.io/@suyeon_tech/Policy.java%EB%A5%BC-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%9C%BC%EB%A1%9C-%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98%ED%95%98%EC%A7%80-%EC%95%8A%EC%9D%80-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@suyeon_tech/Policy.java%EB%A5%BC-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%9C%BC%EB%A1%9C-%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98%ED%95%98%EC%A7%80-%EC%95%8A%EC%9D%80-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Mon, 23 Feb 2026 06:38:12 GMT</pubDate>
            <description><![CDATA[<h1 id="policyjava를-코틀린으로-마이그레이션하지-않은-이유">Policy.java를 코틀린으로 마이그레이션하지 않은 이유</h1>
<h2 id="배경">배경</h2>
<p>Java + Kotlin 혼재 프로젝트에서 policy 도메인을 코틀린으로 마이그레이션하던 중, <code>Policy.java</code>(@Entity)를 <code>Policy.kt</code>로 전환하면서 예상치 못한 문제들을 마주쳤습니다.</p>
<hr>
<h2 id="문제의-시작-qpolicy를-찾을-수-없음">문제의 시작: QPolicy를 찾을 수 없음</h2>
<p><code>Policy.java</code> → <code>Policy.kt</code> 전환 후 빌드하자 다음 오류가 발생했습니다.</p>
<pre><code>cannot find symbol: class QPolicy</code></pre><p><strong>원인</strong>: QueryDSL은 <code>@Entity</code> 클래스를 감지해 Q클래스를 자동 생성합니다. 이 과정은 Java 전용 도구인 <strong>APT(Annotation Processing Tool)</strong> 가 담당합니다. APT는 <code>.java</code> 파일만 처리하기 때문에 <code>Policy.kt</code>로 전환하자 <code>QPolicy</code>가 생성되지 않았습니다.</p>
<pre><code>Policy.java → APT → QPolicy.java 생성 ✅
Policy.kt   → APT 인식 불가 → QPolicy 미생성 ❌</code></pre><hr>
<h2 id="시도한-해결책-kapt-도입">시도한 해결책: kapt 도입</h2>
<p>코틀린 파일도 APT가 처리할 수 있도록 <strong>kapt(Kotlin Annotation Processing Tool)</strong> 를 도입했습니다. kapt는 <code>.kt</code> 파일을 Java 스텁으로 변환한 뒤 APT에 넘겨주는 번역기 역할을 합니다.</p>
<pre><code>Policy.kt → kapt(Java 스텁 변환) → APT → QPolicy 생성 ✅</code></pre><p><code>build.gradle.kts</code>에 kapt를 추가했고, 실제로 <code>QPolicy</code>는 생성됐습니다.</p>
<hr>
<h2 id="예상치-못한-부작용-프로젝트-전체-java-파일에-영향">예상치 못한 부작용: 프로젝트 전체 Java 파일에 영향</h2>
<p>kapt를 추가하자 policy와 전혀 무관한 파일들에서 연쇄적으로 오류가 발생했습니다.</p>
<pre><code>variable memberRepository not initialized in the default constructor
cannot find symbol: variable log
constructor EstateRegionDto cannot be applied to given types</code></pre><p><strong>근본 원인</strong>: kapt는 <code>QPolicy</code> 생성을 위해 <code>Policy.kt</code>만 처리하는 게 아니라, <strong>프로젝트의 모든 파일을 스텁으로 변환</strong>합니다. 이 과정에서 Lombok이 아직 처리되지 않은 상태로 Java 파일들의 스텁이 만들어지면서 오류가 발생했습니다.</p>
<pre><code>kapt 스텁 생성 단계 (Lombok 처리 전):

ActorProvider.java
  @RequiredArgsConstructor → 생성자 미생성 → private final 필드 초기화 불가 💥

EstateRegionCache.java  
  @Slf4j → log 변수 미생성 💥

EstateRegionDto.java
  @AllArgsConstructor → 전체 인자 생성자 미생성 💥</code></pre><hr>
<h2 id="kapt의-한계">kapt의 한계</h2>
<p>kapt/KSP 모두 <strong>스텁 생성 단계가 Lombok 처리보다 먼저 실행</strong>되는 구조적 한계가 있습니다. 이는 도구의 문제가 아니라 <strong>Java + Kotlin + Lombok이 혼재하는 환경의 컴파일 순서 문제</strong>입니다.</p>
<pre><code>kapt 없을 때:
Java → annotationProcessor(Lombok 처리) → 컴파일 ✅

kapt 추가 후:
전체 파일 → kapt 스텁 생성 (Lombok 미처리) → 💥</code></pre><hr>
<h2 id="최종-결론-policyjava-유지">최종 결론: Policy.java 유지</h2>
<p>결국 <strong><code>Policy.java</code>를 그대로 유지</strong>하는 방향으로 결정했습니다.</p>
<p>| 방법 | 결과 |
|---|---|| <code>Policy.kt</code> + kapt | QPolicy 생성되지만 프로젝트 전체 Lombok 파일 오류 💥 |
| <strong><code>Policy.java</code> 유지</strong> | QPolicy 정상 생성, Lombok 문제 없음 ✅ |</p>
<p><strong>핵심 교훈</strong>: 코틀린은 Java와 마찰 없이 혼재할 수 있지만, <strong>QueryDSL의 Q클래스 생성이 필요한 <code>@Entity</code> 클래스는 Java로 유지</strong>하는 것이 현실적입니다. 비즈니스 로직이 담긴 Service, Repository, DTO 등은 코틀린으로 자유롭게 전환할 수 있으며, 이것만으로도 코틀린의 장점을 충분히 활용할 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Jump to Spring Boot]]></title>
            <link>https://velog.io/@suyeon_tech/Jump-to-Spring-Boot</link>
            <guid>https://velog.io/@suyeon_tech/Jump-to-Spring-Boot</guid>
            <pubDate>Mon, 29 Dec 2025 06:34:07 GMT</pubDate>
            <description><![CDATA[<p>2025.12.27</p>
<p>데브코스 강사님이 점프투 스프링부트 교재를 추천해 주셔서, 따로 공부하면서 기억할 만한 내용을 작성하려고 한다. 정리를 잘할 생각은 없고 일단 기록하는 게 목적!</p>
<ul>
<li>JPA(Java Persistance API): 스프링부트에서 사용하는 ORM(Object-Relational Mapping)기술의 표준. 인터페이스 모음이다</li>
<li>Hibernate: JPA를 구현한 실제 클래스이자, JAVA의 ORM 프레임워크</li>
<li>JDBC(Java Database Connectivity): 자바 애플리케이션이 다른 RDBMS와 통신하고 데이터를 조회, 삽입, 수정, 삭제할 수 있도록 돕는 표준 API</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스_while문]]></title>
            <link>https://velog.io/@suyeon_tech/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4while%EB%AC%B8</link>
            <guid>https://velog.io/@suyeon_tech/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4while%EB%AC%B8</guid>
            <pubDate>Fri, 14 Nov 2025 08:27:53 GMT</pubDate>
            <description><![CDATA[<p>데브코스 중에 매우 간단한 예제를 풀다가 생각지 못한 문제를 마주하여 글을 쪄봄...</p>
<p><img src="https://velog.velcdn.com/images/suyeon_tech/post/f1c432b8-59ee-4764-b27a-c8111e968de6/image.png" alt="">
문제는 다음과 같이 amazing할 정도로 단순하다. 그런데 무슨 문제가 있었냐!</p>
<h3 id="나의-첫-코드">나의 첫 코드</h3>
<pre><code class="language-java">public static void main(String[] args) {
        int i = 0;
        int result = 0;

        // 0부터 10까지 중 홀수들의 합을 구하세요.
        while (i &lt;= 10) {
            if (i % 2 == 1) result += i++;
        }

        System.out.println(result);
    }
</code></pre>
<p>나름 코테 좀 풀어봤겠다, 최소한의 코드로 풀어 보려고 했다. 당연히 될 줄 알고 자신만만했는데 무한반복이 돌아 버렸다... 대체왜?
뭔가 문제점이 바로 안 보여서 지피티한테 물어봤다. 여기서 보이는 사람 있으신지...</p>
<p>정답은 바로 
<img src="https://velog.velcdn.com/images/suyeon_tech/post/52357509-0a84-4b4b-8fb1-a39201b1b3a9/image.png" alt="">
그렇다! 짝수일때 i가 변화하지 않아서 무한반복을 돌았던 것임ㅋㅋㅋㅋㅋ 바보...
그래서 평범하게 i++; 를 바깥으로 빼줬다.</p>
<h3 id="두번째-코드">두번째 코드</h3>
<pre><code class="language-java">public static void main(String[] args) {
        int i = 0;
        int result = 0;

        // 0부터 10까지 중 홀수들의 합을 구하세요.
        while (i &lt;= 10) {
            if (i % 2 == 1) result += i;
            i++; // 여기에서 증가시켰다.
        }

        System.out.println(result);
    }
</code></pre>
<p>멀쩡하게 잘됐다. 그리고 짱구를 굴려서 조금 더 짧게도 만들어봤다.</p>
<h3 id="세번째-코드">세번째 코드</h3>
<pre><code class="language-java">public static void main(String[] args) {
        int i = 0;
        int result = 0;

        // 0부터 10까지 중 홀수들의 합을 구하세요.
        while (i++ &lt; 10) {  //여기서 증가시켰다
            if (i % 2 == 1) result += i;
        }

        System.out.println(result);
    }
</code></pre>
<p>이런것도 해봄. 근데 0이 들어가지 않아서 0부터 10까지를 모두 탐색하지 않는 것이 조금 불편하기는 하다. 프로그래밍으로 문제해결한 것이 아니라 조건에 맞게 수학적으로 꼼수 부린 느낌? 무슨소린지 나도 모르겠다. 참고로 i랑 result 정의해준 기본 틀은 깨지 않으려고 했다.</p>
<p>아무튼 오늘은 여기까지</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스_짝수의 합(Stream 활용)]]></title>
            <link>https://velog.io/@suyeon_tech/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%A7%9D%EC%88%98%EC%9D%98-%ED%95%A9Stream-%ED%99%9C%EC%9A%A9</link>
            <guid>https://velog.io/@suyeon_tech/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%A7%9D%EC%88%98%EC%9D%98-%ED%95%A9Stream-%ED%99%9C%EC%9A%A9</guid>
            <pubDate>Thu, 06 Nov 2025 01:17:41 GMT</pubDate>
            <description><![CDATA[<p>프로그래머스 문제를 풀다가 이번에 배운 stream 을 사용하여 풀어보기로 했다.
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/120831">프로그래머스_짝수의 합</a></p>
<hr>
<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/suyeon_tech/post/86ccd848-cbde-437d-b25d-eed3c76557cd/image.png" alt=""></p>
<h3 id="설명">설명</h3>
<p>문제 자체는 매우 간단하다! 주어진 정수 n이하의 짝수를 모두 더하면 된다.</p>
<h3 id="풀이">풀이</h3>
<pre><code class="language-java">import java.util.stream.*;

class Solution {
    public int solution(int n) {
        int sum = IntStream.rangeClosed(1, n) //1부터 n까지의 정수 stream
            .filter(value -&gt; value % 2 == 0) //짝수만 filter
            .sum(); //값을 모두 더함!

        return sum;
    }
}</code></pre>
<p>stream을 베운 김에 사용해봤다. 별것 아니지만 뿌듯하다. 람다식도 그렇게 능숙하지 않았는데, 많이 사용해봐야겠다. 재미있구만!</p>
<h3 id="배운-점">배운 점</h3>
<p>처음에 java.util.*; 을 적어놓고 시작했는데, IntStream 심볼을 찾을 수 없다는 오류가 떴다. 
java.util.stream.*; 으로 바꾼 후에 정상 동작했다. 이게 안된다는 건 처음 알았잖아...?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 25-11-03]]></title>
            <link>https://velog.io/@suyeon_tech/TIL-25-11-05</link>
            <guid>https://velog.io/@suyeon_tech/TIL-25-11-05</guid>
            <pubDate>Wed, 05 Nov 2025 00:39:53 GMT</pubDate>
            <description><![CDATA[<h2 id="과제-제출하는-법">과제 제출하는 법</h2>
<ol>
<li>local 리포지토리에서 우선 gradle 방식으로 코딩</li>
<li>강사님의 제출용 리포지토리 fork 후 local에 clone</li>
<li>필요한 파일만 복사하여 적용한 후 git add .</li>
<li>git checkout -b BE10-wonsuyeon</li>
<li>git commit -m “커밋 메시지”</li>
<li>git push origin BE10-wonsuyeon </li>
</ol>
<hr>
<h2 id="string에서-특정-문자열-검색">String에서 특정 문자열 검색</h2>
<pre><code class="language-java">String string = &quot;abc&quot;;
string.equals(&quot;abc&quot;);
string.startsWith(&quot;ab&quot;);</code></pre>
<hr>
<h2 id="파일-입출력하기">파일 입출력하기</h2>
<h3 id="입력">입력</h3>
<pre><code class="language-java">String fileName = &quot;src/main/test.txt&quot;;

try (FileWriter writer = new FileWriter(fileName)) {
    writer.write(makeJson(quote));
}</code></pre>
<p>FileWriter의 경우 인수로 전달된 이름의 파일이 없으면 생성하고, 있으면 해당 파일에 접근. But 상위 폴더가 있어야함. 없을경우 에러</p>
<h3 id="출력">출력</h3>
<pre><code class="language-java">File file = new File(fileName);

if (file.exists()) {
    try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
        String line = reader.readLine(); //한줄읽기
    }
}</code></pre>
<p>File은 상위폴더가 없더라도 동작. 객체는 생성됨</p>
<p>파일을 한줄씩 모두 읽는경우 while(line = reader.readLine() != null) 사용</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모임방 검색기능 수정]]></title>
            <link>https://velog.io/@suyeon_tech/%EB%AA%A8%EC%9E%84%EB%B0%A9-%EA%B2%80%EC%83%89%EA%B8%B0%EB%8A%A5-%EC%88%98%EC%A0%95</link>
            <guid>https://velog.io/@suyeon_tech/%EB%AA%A8%EC%9E%84%EB%B0%A9-%EA%B2%80%EC%83%89%EA%B8%B0%EB%8A%A5-%EC%88%98%EC%A0%95</guid>
            <pubDate>Mon, 12 May 2025 14:17:03 GMT</pubDate>
            <description><![CDATA[<h3 id="1-기존-기능은-어땠고-왜-수정하려-하나">1. 기존 기능은 어땠고 왜 수정하려 하나?</h3>
<ul>
<li>우선 뭐 기능이     Service에만 작성되어 있고 Controller에는 언급조차 없음. 무슨일이 있었던 거지...?</li>
<li>내가 이미 참여되어 있는 모임방은 검색에서 제외되어야 하는데, 그런 처리과정이 없음</li>
<li>모임시간이 지나거나, 이미 인원이 가득 찬 모임방도 제외되어야 함</li>
</ul>
<h3 id="2-어떻게-수정할-것인가">2. 어떻게 수정할 것인가?</h3>
<h4 id="21-검색필터-추가">2.1. 검색필터 추가</h4>
<ul>
<li>내가 이미 참여된 모임방(내가 만든 모임방 포함) 및 모임시간이 지난 모임방, 참여인원이 가득 찬 모임방, 신고된 모임방을 검색 결과에서 제외하는 로직 추가.</li>
</ul>
<h4 id="22-controller-코드를-적절히-추가해서-api로-정상-동작하도록-하기">2.2. Controller 코드를 적절히 추가해서 API로 정상 동작하도록 하기</h4>
<h4 id="23-예외처리-로직-추가">2.3. 예외처리 로직 추가</h4>
<ul>
<li>사용자의 입력값(검색 키워드)가 null인 경우</li>
<li>키워드에 해당하는 검색 결과가 없는 경우<h4 id="24-테스트코드-추가">2.4. 테스트코드 추가</h4>
</li>
<li>지금껏 테스트코드를 제대로 사용하지 못했는데, 이것도 한번 해볼까 함</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[IntelliJ 단축키]]></title>
            <link>https://velog.io/@suyeon_tech/IntelliJ-%EB%8B%A8%EC%B6%95%ED%82%A4</link>
            <guid>https://velog.io/@suyeon_tech/IntelliJ-%EB%8B%A8%EC%B6%95%ED%82%A4</guid>
            <pubDate>Thu, 30 Jan 2025 16:39:19 GMT</pubDate>
            <description><![CDATA[<h3 id="한줄-복사붙여넣기">한줄 복사+붙여넣기</h3>
<blockquote>
<p>cmd + D</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[원격 저장소에서 pull받기 루트...]]></title>
            <link>https://velog.io/@suyeon_tech/%EC%9B%90%EA%B2%A9-%EC%A0%80%EC%9E%A5%EC%86%8C%EC%97%90%EC%84%9C-pull%EB%B0%9B%EA%B8%B0-%EB%A3%A8%ED%8A%B8</link>
            <guid>https://velog.io/@suyeon_tech/%EC%9B%90%EA%B2%A9-%EC%A0%80%EC%9E%A5%EC%86%8C%EC%97%90%EC%84%9C-pull%EB%B0%9B%EA%B8%B0-%EB%A3%A8%ED%8A%B8</guid>
            <pubDate>Sat, 11 Jan 2025 17:53:33 GMT</pubDate>
            <description><![CDATA[<p>깃허브에서 현재 상태를 가져올 때 </p>
<pre><code>git pull
git branch -a</code></pre><p>여기서 나오는 원하는 브랜치 경로를 긁어서</p>
<pre><code>git checkout [브랜치 경로]</code></pre><p>만약 커밋하지 않은 변경 사항이 있는 경우</p>
<pre><code>git stash</code></pre><p>로 변경사항을 일단 빼두고 checkout.</p>
<p><strong>stash된 데이터 삭제하려면</strong></p>
<pre><code>git stash drop //가장 최근의 데이터 삭제
git stash clear //모든 데이터 삭제</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[깃 관련 정리]]></title>
            <link>https://velog.io/@suyeon_tech/%EA%B9%83-%EA%B4%80%EB%A0%A8-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@suyeon_tech/%EA%B9%83-%EA%B4%80%EB%A0%A8-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Fri, 10 Jan 2025 02:38:51 GMT</pubDate>
            <description><![CDATA[<p>또... 깃 만지려고 이러쿵저러쿵 하다가 시간 날려먹은 인간인 관계로 정리하러 옴</p>
<h4 id="1-현재-브랜치에-커밋하기">1) 현재 브랜치에 커밋하기</h4>
<pre><code>git add [파일명]
git commit
git push origin [브랜치명]</code></pre><h4 id="2-다른-브랜치에-커밋하기">2) 다른 브랜치에 커밋하기</h4>
<p>...앞부분은 똑같고</p>
<pre><code>git push origin [현재브랜치명]:[커밋할 브랜치명]
</code></pre><h4 id="3-원격-저장소의-브랜치-상태-가져오기">3) 원격 저장소의 브랜치 상태 가져오기</h4>
<pre><code>git fetch --all</code></pre><h4 id="4-현재-브랜치-상태-모두-보기">4) 현재 브랜치 상태 모두 보기</h4>
<pre><code>git branch -a</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[태도 관련]]></title>
            <link>https://velog.io/@suyeon_tech/%ED%83%9C%EB%8F%84-%EA%B4%80%EB%A0%A8</link>
            <guid>https://velog.io/@suyeon_tech/%ED%83%9C%EB%8F%84-%EA%B4%80%EB%A0%A8</guid>
            <pubDate>Sun, 05 Jan 2025 08:13:54 GMT</pubDate>
            <description><![CDATA[<p><a href="https://velog.io/@woogur29/%EC%9A%B0%EC%95%84%ED%95%9C%ED%85%8C%ED%81%AC%EC%BD%94%EC%8A%A4-7%EA%B8%B0-%EC%B5%9C%EC%A2%85-%ED%95%A9%EA%B2%A9-%ED%9B%84%EA%B8%B0">우아한테크코스 7기 최종 합격 후기
</a>
: 우테코 합격후기인데 우테코... 한번쯤 지원은 해 볼것 같아서 모아둠</p>
<p><a href="https://velog.io/@hope0206/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EA%B3%B5%EB%B6%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%95%B4%EC%95%BC%ED%95%98%EB%82%98%EC%9A%94">개발자...공부는 어떻게 해야할까요 포스트</a>
: 공부는 어떻게 해야할까요?</p>
<p><a href="https://okky.kr/articles/697048">프로그래밍 공부법</a>
: 언어/프레임워크 나누어 설명해 줘서 좋았음</p>
<p><a href="https://velog.io/@mumv/%EA%B0%9C%EB%B0%9C-%ED%95%99%EC%8A%B5%EB%B2%95%EB%93%A4">개발 학습법들</a>
: 개발 학습법 모으는 글에 개발 학습법 모아놓은 글</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[기술 관련]]></title>
            <link>https://velog.io/@suyeon_tech/%EA%B8%B0%EC%88%A0-%EA%B4%80%EB%A0%A8</link>
            <guid>https://velog.io/@suyeon_tech/%EA%B8%B0%EC%88%A0-%EA%B4%80%EB%A0%A8</guid>
            <pubDate>Sun, 05 Jan 2025 08:12:19 GMT</pubDate>
            <description><![CDATA[<p><a href="https://velog.io/@lionloopy/%EC%BD%94%EB%93%9C%EB%A7%8C-%EC%9E%98-%EC%A7%9C%EB%A9%B4-%EB%90%9C%EB%8B%A4%EA%B3%A0-%EC%8B%A0%EC%9E%85%EC%A3%BC%EB%8B%88%EC%96%B4-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-100%EA%B0%80%EC%A7%80-%ED%95%84%EC%88%98-%EA%BF%80%ED%8C%81-1">코드만 잘 짜면 된다고? 신입/주니어 개발자가 알아야 할 100가지 필수 꿀팁 - 1</a>
: 제목 그대로 이것저것 꿀팁. 개발 공부를 하다 보면 공부의 방향성에서 턱 막힐 때가 있는데 그럴 때 읽어 보면 좋을 것 같다</p>
<p><a href="https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-Rebase-%ED%95%98%EA%B8%B0">git rabase 방법</a>
: 솔직히 지금은 이해 안되는데 몇번 읽어 보려고 저장</p>
<p><a href="https://hongong.hanbit.co.kr/sql-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95-joininner-outer-cross-self-join/">SQL join 설명</a>
: 어려워... 상세한 설명!</p>
<p><a href="https://superfelix.tistory.com/580">IntelliJ 단축키 모음</a>
: 익숙해지기...!</p>
<p><a href="https://velog.io/@mendel/.gitignore-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC">쩐다... .gitignore관련 정리 블로그</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[밥친구 프로젝트+공부 계획]]></title>
            <link>https://velog.io/@suyeon_tech/%EB%B0%A5%EC%B9%9C%EA%B5%AC-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EA%B3%B5%EB%B6%80-%EA%B3%84%ED%9A%8D</link>
            <guid>https://velog.io/@suyeon_tech/%EB%B0%A5%EC%B9%9C%EA%B5%AC-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EA%B3%B5%EB%B6%80-%EA%B3%84%ED%9A%8D</guid>
            <pubDate>Sun, 22 Dec 2024 16:02:34 GMT</pubDate>
            <description><![CDATA[<p>밥친구 프로젝트를 어떤 식으로 구성할지... 계획하고
공부를 어떻게... 무엇을 어떻게 어떤 순서로 할지 틀을 잡고...
한 번 고심하는 시간을 가지고 가는 것이 나을 것 같다.</p>
<p>우선 계획으로서는, 계획...계획일지 모르겠지만. 아냐 그냥 한번에 쓰자</p>
<hr>
<h3 id="매일-코드를-볼-것">매일 코드를 볼 것.</h3>
<p>매일 코드를 들여다 보기라도 해야 익숙해진다. 내가 보기에 나는 아직도 코드에 익숙한 사람이 아닌 것 같다. 하루에 한 번씩은 반드시 코드를 봐야 한다. 일기 쓰듯이...</p>
<h3 id="문서화할것">문서화할것</h3>
<p>문서화해야 내가 뭘 했고 뭘 해야 하는지, 어디서 틀렸는지가 눈에 보인다.
문서화할 내용은 역시 트러블슈팅과 새로 배운 내용 정리가 있다.
추가로 코딩하는 도중 고민했던 내용들을 사소한 것이라도 적어 두면 도움이 되겠다.</p>
<h3 id="주의사항">주의사항</h3>
<p>여기서 짚고 넘어가야 할 주의사항. 내 블로그나 깃허브를 너무 멋지게 만들려고 노력하지 않기. 물론 노력한다고 딱히 멋있어지지 않는 게 포인트다. 그냥 편하게 써... 뭐라도 써서 점점 나아진다면 그게 멋진거다</p>
<h3 id="문서화---반복적인-패턴의-기록">문서화 - 반복적인 패턴의 기록</h3>
<p>특히 반복적으로 사용하는 - 예를 들어 깃허브 pr 날리기 같은 - 부분은 반드시 정리해 둔다. 나중에 이거 하겠다고 시간 낭비할 일 없게 제대로 정리한다.</p>
<h3 id="시간-쓰기">시간 쓰기</h3>
<p>아까 코드를 자주 보는 거랑 비슷한 맥락인데, 시간을 그냥 퍼다 쓰자. 경험상 초보자는 시간을 아까워해서는 안 되고, 잘못된 길로 가는 것을 두려워해서는 안 된다. 시간을 처음부터 많이 투자할 것을 염두에 두면 조금 헤메거나 꼼꼼히 문서화하는 시간도 아깝지 않을 것. 그리고 기한이 있는 작업은 일찍 시작하기... 정도가 비슷하겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[개발환경 구축]]></title>
            <link>https://velog.io/@suyeon_tech/%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95</link>
            <guid>https://velog.io/@suyeon_tech/%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95</guid>
            <pubDate>Mon, 21 Oct 2024 08:50:49 GMT</pubDate>
            <description><![CDATA[<p>Do it! 스프링부트3 교재로 공부하면서 내용을 정리하려고 한다.
우선 개발환경 구축이다.</p>
<p>STS보다는 부가 기능이 편리한 IntelliJ를 사용하였다. IntelliJ Ultimate 결제하여 사용!</p>
<p>Gradle-Groovy로 SpringBoot 프로젝트를 생성하였다.</p>
<p>github에 업로드하며 작업하기 위해 .gitignore 파일을 생성하였다.</p>
<p><a href="https://www.toptal.com/developers/gitignore">https://www.toptal.com/developers/gitignore</a>
위 링크에서 생성!
<img src="https://velog.velcdn.com/images/suyeon_tech/post/dbd2c3d6-c03e-45ff-b7fa-77c3d5c876bc/image.png" alt=""></p>
<p>설정은 다음과 같다</p>
<p>그리고 github에 업로드하였다.</p>
<p>우선 github에 repository를 새로 생성한다.
그리고 repository 링크를 복사해두기.</p>
<p>&lt;git 초기화&gt;</p>
<p><img src="https://velog.velcdn.com/images/suyeon_tech/post/6b8c7b62-5903-4a76-bed5-100f5d709c19/image.png" alt=""></p>
<p>git add 후
<img src="https://velog.velcdn.com/images/suyeon_tech/post/0a0b13f6-fdfa-4bee-9758-afe3595c1392/image.png" alt=""></p>
<p>commit
<img src="https://velog.velcdn.com/images/suyeon_tech/post/1ff69e24-7cea-48fa-8659-665b88400bd3/image.png" alt=""></p>
<p>그리고 push!
<img src="https://velog.velcdn.com/images/suyeon_tech/post/ebbfdebf-fcec-4acc-bac5-abd5a96597c7/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/suyeon_tech/post/c3f8abfe-642d-4fde-8967-22b24833c8be/image.png" alt=""></p>
<p>위와 같이 업로드되었다! 휴 이제 시작이구만</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git Extensions 정리]]></title>
            <link>https://velog.io/@suyeon_tech/Git-Extensions-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@suyeon_tech/Git-Extensions-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Fri, 13 Sep 2024 09:19:27 GMT</pubDate>
            <description><![CDATA[<p>Git 사용 강의를 듣던 도중 VSCode에서 사용하기 좋은 Git 관련 Extension들을 추천해 주셨다. 시키는 것만 하려다가 설명이 뜨길래 쭉 읽으면서 간단히 정리해 보겠다.
차례대로 Git Gragh, Git History, Git Lense다.</p>
<p>---- Git Gragh ----</p>
<p>내 repository에 대한 git graph를 볼 수 있다! 그리고 git 기능들을 graph에서 편리하게 사용 가능하다. 원하는 대로 보여지는 방식을 변경 가능하다!</p>
<p>나머지는 걍 복붙한다.
단축키도 있으니 필요하면 설명 다시 찾아볼것</p>
<p>Git Graph View:</p>
<p>  Display:</p>
<pre><code>Local &amp; Remote Branches
Local Refs: Heads, Tags &amp; Remotes
Uncommitted Changes</code></pre><p>  Perform Git Actions (available by right clicking on a commit / branch / tag):</p>
<pre><code>Create, Checkout, Delete, Fetch, Merge, Pull, Push, Rebase, Rename &amp; Reset Branches
Add, Delete &amp; Push Tags
Checkout, Cherry Pick, Drop, Merge &amp; Revert Commits
Clean, Reset &amp; Stash Uncommitted Changes
Apply, Create Branch From, Drop &amp; Pop Stashes
View annotated tag details (name, email, date and message)
Copy commit hashes, and branch, stash &amp; tag names to the clipboard</code></pre><p>  View commit details and file changes by clicking on a commit. On the Commit Details View you can:</p>
<pre><code>View the Visual Studio Code Diff of any file change by clicking on it.
Open the current version of any file that was affected in the commit.
Copy the path of any file that was affected in the commit to the clipboard.
Click on any HTTP/HTTPS url in the commit body to open it in your default web browser.</code></pre><p>  Compare any two commits by clicking on a commit, and then CTRL/CMD clicking on another commit. On the Commit Comparison View you can:</p>
<pre><code>View the Visual Studio Code Diff of any file change between the selected commits by clicking on it.
Open the current version of any file that was affected between the selected commits.
Copy the path of any file that was affected between the selected commits to the clipboard.</code></pre><p>  Code Review - Keep track of which files you have reviewed in the Commit Details &amp; Comparison Views.</p>
<pre><code>Code Review&#39;s can be performed on any commit, or between any two commits (not on Uncommitted Changes).
When a Code Review is started, all files needing to be reviewed are bolded. When you view the diff / open a file, it will then be un-bolded.
Code Reviews persist across Visual Studio Code sessions. They are automatically closed after 90 days of inactivity.</code></pre><p>  View uncommitted changes, and compare the uncommitted changes with any commit.</p>
<p>  Hover over any commit vertex on the graph to see a tooltip indicating:</p>
<pre><code>Whether the commit is included in the HEAD.
Which branches, tags and stashes include the commit.</code></pre><p>  Filter the branches shown in Git Graph using the &#39;Branches&#39; dropdown menu. The options for filtering the branches are:</p>
<pre><code>Show All branches
Select one or more branches to be viewed
Select from a user predefined array of custom glob patterns (by setting git-graph.customBranchGlobPatterns)</code></pre><p>  Fetch from Remote(s) (available on the top control bar)
  Find Widget allows you to quickly find one or more commits containing a specific phrase (in the commit message / date / author / hash, branch or tag names).</p>
<p>  Repository Settings Widget:</p>
<pre><code>Allows you to view, add, edit, delete, fetch &amp; prune remotes of the repository.
Configure &quot;Issue Linking&quot; - Converts issue numbers in commit messages into hyperlinks, that open the issue in your issue tracking system.

Configure &quot;Pull Request Creation&quot; - Automates the opening and pre-filling of a Pull Request form, directly from a branches context menu.
  Support for the publicly hosted Bitbucket, GitHub and GitLab Pull Request providers is built-in.
  Custom Pull Request providers can be configured using the Extension Setting git-graph.customPullRequestProviders (e.g. for use with privately hosted Pull Request providers). Information on how to configure custom providers is available here.

Export your Git Graph Repository Configuration to a file that can be committed in the repository. It allows others working in the same repository to automatically use the same Git Graph configuration.</code></pre><p>---- Git History ----</p>
<p>그래프와 디테일에 대한 깃 로그를 볼 수 있고, 검색할 수 있다.
지난 파일의 사본을 볼 수 있다.
history를 보고 검색할 수 있다.</p>
<p>Available Commands :
View Git History (git log) (git.viewHistory)
View File History (git.viewFileHistory)
View Line History (git.viewLineHistory)</p>
<p>그리고 위 기능들의 단축키를 지정할 수 있다!</p>
<p>---- Git Lense ----</p>
<p>GitLense를 쓴다면? 당신은 코드를 보다 잘 이해하고, 쓰고, 리뷰할 수 있다!
유료 기능도 있지만 우선 무료기능만 써본다.</p>
<p>GitLense를 사용하면 Git CodeLense를 통해 누가 언제 어떻게 이 코드를 수정하고 작성했는지 알려준다!</p>
<p>그리고 코드가 어떤 과정을 거쳐 변화했는지 history를 보여준다!</p>
<p>---- The End ----</p>
<p>*용어 정리</p>
<p>1) untapped : 아직 손대지 않은
2) on-damand : 요구할 때 즉시
3) miscellaneous : 여러 가지 종류의, 이것저것 다양한</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[VSCode Formatting 방법]]></title>
            <link>https://velog.io/@suyeon_tech/VSCode-Formatting-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@suyeon_tech/VSCode-Formatting-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Tue, 27 Aug 2024 02:58:14 GMT</pubDate>
            <description><![CDATA[<p>단축키는 일주일이면 죄다 잊어버리는 나란 인간을 위해 주섬주섬 적어두는 기록...</p>
<p>Formatting이란 VSCode에서 코드를 자동 정렬해 주는 기능이다.</p>
<p>OS마다 단축키가 다르다. 메뉴에서 찾아 쓰는 건 이 블로그가 날아가지 않는 이상 쓸 일 없을 것 같아 생략</p>
<p>Windows : Shift + Alt + F
Mac : command + option + L
Linux : Ctrl + Shift + I</p>
<p>근데 왜 리눅스만 혼자 I를 붙이는 걸까? 궁금해져 버렸다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 시작하는 법]]></title>
            <link>https://velog.io/@suyeon_tech/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EB%B2%95</link>
            <guid>https://velog.io/@suyeon_tech/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EB%B2%95</guid>
            <pubDate>Thu, 15 Aug 2024 14:27:39 GMT</pubDate>
            <description><![CDATA[<h3 id="리액트-시작하는-3가지-방법">리액트 시작하는 3가지 방법</h3>
<ol>
<li><p>manually install. 하나하나 Eslint &amp; Prettier, Typescript, Babel, Webpack을 공식 홈페이지를 참고하여 설치한다. 충돌 오류를 해결하여 주는 eslint-plugin-prettier 또한 설치 필요.</p>
</li>
<li><p>CRA(Create React App)을 사용하는 방법. TypeScript를 사용할 것이기 때문에 &#39;Creating a TypeScript app&#39; 부분을 찾아 설치하였다.</p>
</li>
<li><p>Online Code Tool인 CodeSandbox를 사용하는 방법. 온라인으로 즉시 실행 가능하다. 단순한 테스트에 적합.</p>
</li>
</ol>
]]></description>
        </item>
    </channel>
</rss>