<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hi_potato.log</title>
        <link>https://velog.io/</link>
        <description>나는 말하는 감자다</description>
        <lastBuildDate>Mon, 20 Apr 2026 04:18:51 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>hi_potato.log</title>
            <url>https://velog.velcdn.com/images/hi_potato/profile/6b19e4af-57c4-4d18-a097-5141beb75db8/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. hi_potato.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hi_potato" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[취업/이직을 위한 면접 가이드]]></title>
            <link>https://velog.io/@hi_potato/%EC%B7%A8%EC%97%85%EC%9D%B4%EC%A7%81%EC%9D%84-%EC%9C%84%ED%95%9C-%EB%A9%B4%EC%A0%91-%EA%B0%80%EC%9D%B4%EB%93%9C</link>
            <guid>https://velog.io/@hi_potato/%EC%B7%A8%EC%97%85%EC%9D%B4%EC%A7%81%EC%9D%84-%EC%9C%84%ED%95%9C-%EB%A9%B4%EC%A0%91-%EA%B0%80%EC%9D%B4%EB%93%9C</guid>
            <pubDate>Mon, 20 Apr 2026 04:18:51 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h1 id="취업이직을-위한-면접-가이드">취업/이직을 위한 면접 가이드</h1>
</blockquote>
<h2 id="📌-1분-자기소개">📌 1분 자기소개</h2>
<p><strong>1. 키워드 Hook(10초)</strong> <em>: 나를 정의하는 한 문장 + 일하는 방식</em> 
예) 나는 [문제 해결방식/일하는 스타일]로 [어떤] 성과를 만들어내는 사람입니다. </p>
<p><strong>2. 대표 경험(30초)</strong> <em>:성과 + 과정 + 나다움</em> </p>
<ul>
<li>어떤 상황/문제였는지 </li>
<li>내가 어떻게 저근했는지 (과정 + 차별점) </li>
<li>결과 </li>
</ul>
<p>예) [문제 상황]에서 저는 [나만의 방식]으로 접근했고, 그 결과 [구체적인 성과/수치]를 만들어냈습니다. </p>
<p><strong>3. 핵심강점(10초)</strong> <em>: 최근 성과 + 수치로 입증</em> </p>
<ul>
<li>JD 키워드 직접 끌어오기 </li>
<li>&quot;그래서 이 직무에 맞다&quot;를 논리적으로 연결 </li>
</ul>
<p><strong>4. 마무리(10초)</strong> <em>: 기여 의지</em> 
예) 이러한 강점을 바탕으로 [회사/직무]에서 [어떤 기여]를 만들어내겠습니다.</p>
<blockquote>
<h3 id="📍-답변규칙">📍 답변규칙</h3>
</blockquote>
<ul>
<li>1가지 핵심 메시지에 집중</li>
<li>구체적인 숫자로 성과 표현</li>
<li>내 역할 분리 : 팀 vs 개인 기여 명확히</li>
</ul>
<hr>

<h2 id="📌-면접을-위한-마인드셋">📌 면접을 위한 마인드셋</h2>
<p><strong>📍 긴장의 역설</strong>
오히려 너무 안 떨면 간절함이 없어보일 수 있습니다.
*&quot;죄송합니다. 긴장이 되네요. 한 번 정리하고 답변드리겠습니다.&quot;*</p>
<p><strong>📍 모르는 질문 대처</strong>
&quot;지금은 답변이 어렵지만, 이렇게 접근해보고 다음 인터뷰 때 공유 드리겠습니다.&quot;</p>
<p><strong>📍 성장하겠다는 태도 강조</strong>
&quot;혹시 제가 놓친 부분이 있다면, 알려주시면 감사하겠습니다.&quot;</p>
<p><strong>📍 태도가 중요</strong>
협업의 용이성, 책임감, 학습 민첩성 등을 강조</p>
<p><strong>📍 긴장했다는 점을 받아들이기</strong>
&quot;너무 오고 싶던 회사라, 긴장이 많이 된다&quot;고 솔직하게 말하기</p>
<p><strong>📍 모르는 부분 인정</strong>
&quot;현재 그 부분은 미처 생각하지 못했지만, 기회를 주신다면 보완하겠습니다.&quot;</p>
<p><strong>📍 진성성 있는 소통</strong>
면접관은 정답 채점하는 기계가 아닌, 조직에 잘 적응할 수 있는 동료를 찾고 있습니다.</p>
<blockquote>
<h3 id="💡-tip">💡 TIP!</h3>
</blockquote>
<ul>
<li>면접시 나만의 긍정적인 징크스 만들기</li>
<li>면접 시간보다 빨리 도착해서 긴장 완화하기</li>
<li>질문 끝날 때까지 기다렸다 2초 후 답변하기</li>
</ul>
<hr>

<h2 id="📌-마지막-한-마디">📌 마지막 한 마디</h2>
<p><strong>1. 감사인사</strong> <em>: 면접관에게 진심 어린 감사를 표시하기</em>
예) &quot;바쁘신 와중에 시간 내주셔서 감사합니다.&quot;</p>
<p><strong>2. 겸손한 회고</strong> <em>: 인간미와 열정을 보여주기</em>
예) &quot;긴장해서 모든 걸 다 보여드리지 못해 아쉽습니다.&quot;</p>
<p><strong>3. 강점 재 각인</strong>
예) 저의 어떤 점이 OO사의 과제 해결에 유효하다고 자신합니다.&quot;</p>
<p><strong>4. 합류 의지 표출</strong>
예) &quot;합류 시 [첫 90일 액션 1~2개]로 기여하겠습니다.&quot;</p>
<hr>

<h2 id="📌-면접-시-답변-태도">📌 면접 시 답변 태도</h2>
<h3 id="to-do">TO DO</h3>
<p><strong>📍 사전 숙지</strong>
모든 내용과 스토리를 완벽하게 숙지</p>
<p><strong>📍 예상 질문</strong>
면접관의 질문을 미리 예측하고 대비하기</p>
<p><strong>📍 나의 기여도 명확화</strong>
&quot;내가 맡은 역할&quot;과 &quot;나의 핵심 기여&quot;를 강조</p>
<p><strong>📍 성과는 숫자로</strong>
모든 성과는 구체적인 수치로 표현</p>
<p><strong>📍 학습과 성장 강조</strong>
무엇을 배우고 성장했는지를 보여주기</p>
<p><strong>📍 기업 맞춤형 준비</strong>
지원 기업의 인재상이나 최근 프로젝트에 맞춰 준비</p>
<p><strong>📍 솔직하고 진정성 있는 태도</strong>
답변하기 어려운 질문에는 노력하겠다는 다짐</p>
<p><strong>📍 적당히 무해한 단점 어필</strong>
개선하려는 노력이 보이는 단점을 선택</p>
<h3 id="not-to-do">NOT TO DO</h3>
<p><strong>📍 포트폴리오만 맹신</strong>
포트폴리오는 답변을 뒷받침하는 도구</p>
<p><strong>📍 과도한 설명</strong>
핵심만 먼저 말하고, 더 궁금해하면 추가 설명</p>
<p><strong>📍 대외비 언급</strong>
회사 기밀 정보나 데이터 절대 언급 금지</p>
<p><strong>📍 부정적인 퇴사 사유</strong>
면접에서 가장 조심해야 할 질문 중 하나</p>
<p><strong>📍 자신감 없는 태도</strong>
부정적인 인상을 줄 수 있음</p>
<p><strong>📍 지나친 암기식 답변</strong>
자연스럽고 진정성 있는 대화가 좋은 인상을 줌</p>
<p><strong>📍 모호한 성과 표현</strong>
추상적인 말만 하면 신뢰도가 떨어짐</p>
<p><strong>📍 면접관 말을 자주 끊기</strong>
끝까지 경청한 후, 차분하게 답변</p>
<hr>

<h2 id="📌-면접-복기">📌 면접 복기</h2>
<p><strong>📍 받은 질문/의도 분석</strong>
면접관이 왜 이 질문을 했는지, 무엇을 평가하려 했는지 정리</p>
<p><strong>📍 답한 핵심 문장 정리</strong>
내가 답변한 핵심 내용을 2~3문장으로 압축</p>
<p><strong>📍 놓친 데이터/사례 기록</strong>
아쉬웠던 부분과 다음에 보완할 구체적 사례</p>
<p><strong>📍 다음에 보완할 한 문장</strong>
다음 면접에서 개선할 한 문장으로 정리</p>
<blockquote>
<p><strong>📑 출처</strong>
260415 zero-base YouTube 라이브
[0-7년차 스펙 및 경험 완벽 포장 면접 가이드]</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin] 코틀린에서 함수를 다루는 방법]]></title>
            <link>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-%ED%95%A8%EC%88%98%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-%ED%95%A8%EC%88%98%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Wed, 25 Jun 2025 06:02:51 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="자바-개발자를-위한-코틀린-입문">자바 개발자를 위한 코틀린 입문</h2>
</blockquote>
<h3 id="8강-코틀린에서-함수를-다루는-방법">8강. 코틀린에서 함수를 다루는 방법</h3>
<h1 id="📌-함수-선언-문법">📌 함수 선언 문법</h1>
<h2 id="📍-두-정수를-받아-더-큰-정수를-반환하는-예제">📍 두 정수를 받아 더 큰 정수를 반환하는 예제</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/949c35ca-4fbf-41b8-a58c-fed12fe1fa26/image.png" alt=""></p>
<blockquote>
<h3 id="함수-구성">함수 구성</h3>
</blockquote>
<ol>
<li>접근 지시어 <code>public</code> 은 생략 가능하다.</li>
<li>함수를 의미하는 키워드 <code>fun</code></li>
<li>함수이름</li>
<li>함수의 매개변수, <code>매개변수명: 타입</code></li>
<li>함수의 반환 타입 (Unit인 경우 생략 가능)</li>
<li>중괄호 안에 본문</li>
<li>함수가 하나의 결과값이면 block 대신 <code>=</code> 사용 가능</li>
</ol>
<p>if-esle가 Expression이므로 <code>return</code>을 하나로 모을 수 있다.
<img src="https://velog.velcdn.com/images/hi_potato/post/740a9607-5ee9-4ef0-b382-ba18356505f4/image.png" alt=""></p>
<p><code>return</code> 앞에 붙여서 전체가 하나의 결과값이 된다.
코틀린에 block(중괄호)을 없애고 <code>=</code>으로 쓸 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/11adde9e-b0f0-43fe-908c-27572a8c29c4/image.png" alt=""></p>
<p>중괄호 대신 <code>=</code>을 쓰게 되면 코틀린은 타입을 자동으로 추론할 수 있기 때문에 반환 타입을 생략할 수 있다.
그리고 if-else를 개행을 하지않고 한번에 쓸 수 있다.
<img src="https://velog.velcdn.com/images/hi_potato/post/f8be1965-18f4-449a-bd28-dd5eb7408201/image.png" alt=""></p>
<p>block <code>{}</code>을 사용하는 경우에는 반환 타입이 Unit이 아니면, 명시적으로 작성해주어야 한다.
함수는 클래스 안에 있을 수도, 파일 최상단에 있을 수도 있다. 또한, 한 파일 안에 여러 함수들이 있을 수도 있다.</p>
<h1 id="📌-default-parameter">📌 default parameter</h1>
<h2 id="📍-주어진-문자열을-n번-출력하는-예제">📍 주어진 문자열을 N번 출력하는 예제</h2>
<p>Java에서는 자주 쓰는 파라미터들을 위해 Overloading을 통해 같은 명칭의 함수를 여러개 선언할 수 있다.
메소드를 여러개 만드는 것은 중복되므로 코틀린에서는 default parameter를 사용한다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/d57f8554-fc36-4d31-887c-54da11465caf/image.png" alt=""></p>
<p>밖에서 파라미터를 넣어주지 않으면 기본값을 사용한다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/c32edd57-bbf1-46e6-8245-a5446b04f025/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/6904ca3b-454d-4290-8f49-3c054d19c10d/image.png" alt=""></p>
<p>기본 값을 넣어줘도 같은 결과 값이 나온다.</p>
<h1 id="📌-named-argument">📌 named argument</h1>
<p><code>repeat</code>을 호출할 때 <code>num</code>은 3 그대로 쓰고 <code>useNewLine</code>은 false를 쓰고 싶다면
<img src="https://velog.velcdn.com/images/hi_potato/post/c365d005-8cc5-4c81-9c5e-976b1f3b3d4d/image.png" alt=""></p>
<p><code>num</code>을 그대로 적어서 보내는 방식도 있지만
어떤 파라미터에 이 값을 넣을 거야 라고 함수를 호출하는 쪽에서 명시해줄 수 있다.</p>
<blockquote>
<p>변수 이름을 통해 직접 값을 지정한다.
지정되지 않은 매개변수는 기본값을 사용한다.</p>
</blockquote>
<p>builder를 직접 만들지 않고 builder의 장점을 가지게 된다.
값을 넣어줄 때 실수로 값을 바꿔서 넣을 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/98cb1d49-7c34-4d90-bf52-c3e3eae38b5f/image.png" alt=""></p>
<p>builder를 쓰게 되면</p>
<pre><code class="language-java">.name(&quot;말하는 감자&quot;)
.gender(&quot;FEMALE&quot;)</code></pre>
<p>변수와 값에 대한 확인이 명확해지는 장점이 있는데 코틀린의 named argument를 쓰게 되면 이 장점을 가져갈 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/0db9d22a-65b0-46c9-9e08-dcbc0c4554cb/image.png" alt=""></p>
<blockquote>
<h4 id="주의❗">주의❗</h4>
<p>코틀린에서 JAVA 함수를 가져다 사용할 때는 named argument를 사용할 수 없다.</p>
</blockquote>
<h1 id="📌-같은-타입의-여러-파라미터-받기-가변인자">📌 같은 타입의 여러 파라미터 받기 (가변인자)</h1>
<p>JAVA에서는 타입 뒤에 <code>...</code>을 써줌으로써 가변인자를 받는다. (ex <code>String...</code>)</p>
<p>코틀린에서는 타입 앞에 <code>vararg</code>을 써준다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/ffb860af-3d6a-4450-950b-2ef64a5c3f4c/image.png" alt=""></p>
<p>배열을 쓰는 경우 JAVA에서는 가변인자에 배열을 바로 넣어주지만 코틀린에서는 배열을 가변인자에 넣어줄 때 앞에 별표<code>*</code> 를 붙혀줘야 한다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/cb114296-ccd6-4bc4-901c-a96da89937ed/image.png" alt=""></p>
<ul>
<li><code>*</code> : spread 연산자. 배열 안에 있는 것들을 마친 그냥 <code>,</code>를 쓰는 것처럼 꺼내준다.</li>
</ul>
<hr>

<blockquote>
<h3 id="📑-출처">📑 출처</h3>
</blockquote>
<ul>
<li>자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide) (인프런/최태현)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin] 코틀린에서 예외를 다루는 방법]]></title>
            <link>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-%EC%98%88%EC%99%B8%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-%EC%98%88%EC%99%B8%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Wed, 25 Jun 2025 05:38:07 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="자바-개발자를-위한-코틀린-입문">자바 개발자를 위한 코틀린 입문</h2>
</blockquote>
<h3 id="7강-코틀린에서-예외를-다루는-방법">7강. 코틀린에서 예외를 다루는 방법</h3>
<h1 id="📌-try-catch-finally-구문">📌 try catch finally 구문</h1>
<h2 id="📍-주어진-문자열을-정수로-변경하는-예제">📍 주어진 문자열을 정수로 변경하는 예제</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/e74c75a7-2892-4f14-b8e1-93c79a76f330/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/4e599319-e933-4c86-b744-e7aa0658a099/image.png" alt=""></p>
<ul>
<li>기본타입간의 형변환은 <code>toType()</code>을 사용한다.</li>
<li>타입이 뒤에 위치한다.</li>
<li><code>new</code>를 사용하지 않는다.</li>
<li>포맷팅이 간결하다.</li>
</ul>
<p>try-catch 구문은 문법적으로 동일하다.</p>
<h2 id="📍-주어진-문자열을-정수로-변경하는-예제-1">📍 주어진 문자열을 정수로 변경하는 예제</h2>
<p>실패하면 null을 반환</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/6255c28d-ef79-494f-b113-21a5a7daa0ca/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/a617ec70-0b5c-49a4-8e63-d4c941126e0c/image.png" alt=""></p>
<ul>
<li>try catch가 Exprssion이기 때문에 <code>return</code>을 한번만 사용할 수 있다.</li>
</ul>
<p>try catch finally 역시 동일하다.</p>
<h1 id="📌-checked-exception과-unchecked-exception">📌 Checked Exception과 Unchecked Exception</h1>
<h2 id="📍-프로젝트-내-파일의-내용물을-읽어오는-예제">📍 프로젝트 내 파일의 내용물을 읽어오는 예제</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/1adc2f1a-f17c-43c0-aaa2-f2baf81848b9/image.png" alt=""></p>
<h3 id="java">JAVA</h3>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/4279ea2b-d8b7-4aab-b30b-799e362cebf9/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/b072f4df-7edd-47fc-ad0d-afb318759e2a/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/686dea1a-9c2b-407b-9672-e5ed15e0a7a2/image.png" alt=""></p>
<h3 id="kotlin">Kotlin</h3>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/635acf9e-5cca-4d62-a521-d87909392f76/image.png" alt=""></p>
<ul>
<li>Java와 다르게 <code>IOException</code>을 별도로 명시하지 않아도 된다.
➡ <code>throw</code> 구문이 없다.</li>
</ul>
<p>Kotlin에서는 Checked Exception과 Unchecked Exception을 구분하지 않는다.
모두 <strong>Unchecked Exception</strong>이다.</p>
<h1 id="📌-try-with-resources">📌 try with resources</h1>
<h2 id="📍-프로젝트-내-파일의-내용물을-읽어오는-예제-1">📍 프로젝트 내 파일의 내용물을 읽어오는 예제</h2>
<h3 id="java-1">JAVA</h3>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/2ea1afe2-e8f3-4358-82a6-c1419dbf601a/image.png" alt=""></p>
<h3 id="kotlin-1">Kotlin</h3>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/29aac522-51c2-4057-bf1c-fefac9201a9d/image.png" alt=""></p>
<p>코틀린에서는 try with resources 구문이 없다.
대신 <code>use</code>라는 inline 확장함수를 사용해야 한다.
코틀린의 언어적 특징을 활용해 <code>close</code>를 호출해준다. (<code>use</code>가 끝나면 자동 <code>close</code>가 된다.)</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/10f87298-5b3a-416b-8d27-4235efbf89ab/image.png" alt=""></p>
<hr>

<blockquote>
<h3 id="📑-출처">📑 출처</h3>
</blockquote>
<ul>
<li>자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide) (인프런/최태현)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin] 코틀린에서 반복문을 다루는 방법]]></title>
            <link>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-%EB%B0%98%EB%B3%B5%EB%AC%B8%EC%9D%84-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-%EB%B0%98%EB%B3%B5%EB%AC%B8%EC%9D%84-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Wed, 25 Jun 2025 05:16:47 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="자바-개발자를-위한-코틀린-입문">자바 개발자를 위한 코틀린 입문</h2>
</blockquote>
<h3 id="6강-코틀린에서-반복문을-다루는-방법">6강. 코틀린에서 반복문을 다루는 방법</h3>
<h1 id="📌-for-each문">📌 for-each문</h1>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/8f7707a6-a027-40a7-8e46-7dab1e9e968c/image.png" alt=""></p>
<ul>
<li><code>:</code> 대신 <code>in</code>을 사용한다</li>
<li><code>in</code>뒤에는 Interable이 구현된 타입이라면 모두 들어갈 수 있다.</li>
</ul>
<h1 id="📌-전통적인-for문">📌 전통적인 for문</h1>
<h2 id="📍-i가-1씩-증가하는-경우">📍 <code>i</code>가 1씩 증가하는 경우</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/f1156211-9148-4934-8ffe-82f413159b81/image.png" alt=""></p>
<ul>
<li><code>1..3</code> : 1부터 3의 범위</li>
</ul>
<h2 id="📍-i가-1씩-감소하는-경우">📍 <code>i</code>가 1씩 감소하는 경우</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/6f89c5b7-139b-490d-be41-bff16b3d3000/image.png" alt=""></p>
<ul>
<li><code>downTo</code>로 감소시킨다.</li>
</ul>
<h2 id="📍-i가-2씩-증가하는-경우">📍 <code>i</code>가 2씩 증가하는 경우</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/049550a8-a327-4c9a-b232-24db0da37867/image.png" alt=""></p>
<ul>
<li><code>step</code>으로 증가하는 구간 설정 가능하다.</li>
</ul>
<h1 id="📌-progression과-range">📌 Progression과 Range</h1>
<ul>
<li><code>..</code> 연산자 : 범위를 만들어 내는 연산자 
범위를 뜻하는 IntRange라는 클래스는 IntProgression (등차수열) 클래스를 상속한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/765bae64-9fce-4637-b816-d57811709142/image.png" alt=""></p>
<p>등차수열이라는 것은 &#39;시작 값&#39;, &#39;끝 값&#39;, &#39;공차&#39;가 필요하다.</p>
<ul>
<li><code>3 downTo 1</code> : 시작값 3, 끝값 1, 공차 -1인 등차수열</li>
<li><code>1..5 step 2</code> : 시작값 1, 끝값 5, 공차가 2인 등차수열</li>
</ul>
<p><code>downTo</code>, <code>step</code>도 함수이다! (중위 호출 함수)
<code>변수.함수이름(argument)</code>대신 <code>변수 함수이름 argument</code></p>
<h2 id="📍-전통적인-for문-동작-순서">📍 전통적인 for문 동작 순서</h2>
<p><code>1..5 step 2</code></p>
<ol>
<li><code>1..5</code> : 1부터 5까지 공차가 1인 등차수열 생성</li>
<li><code>step 2</code> : 등차수열에 대한 함수 호출, <code>등차수열.step(2)</code>
➡ 1부터 5까지 공차가 2인 등차수열
등차수열에 구현된 Iterable에 의해 <code>1, 3, 5</code> 가 나온다.</li>
</ol>
<blockquote>
<p>Kotlin에서 전통적인 for문은 등차수열을 이용한다!</p>
</blockquote>
<h1 id="📌-while문">📌 While문</h1>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/a87a93af-9d0f-41ec-bdf6-574ffb129276/image.png" alt=""></p>
<p>while문은 Java와 완전히 동일하다.
do-while문도 똑같다.</p>
<hr>

<blockquote>
<h3 id="📑-출처">📑 출처</h3>
</blockquote>
<ul>
<li>자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide) (인프런/최태현)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin] 코틀린에서 조건문을 다루는 방법]]></title>
            <link>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-%EC%A1%B0%EA%B1%B4%EB%AC%B8%EC%9D%84-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-%EC%A1%B0%EA%B1%B4%EB%AC%B8%EC%9D%84-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Sat, 17 May 2025 07:50:01 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="자바-개발자를-위한-코틀린-입문">자바 개발자를 위한 코틀린 입문</h2>
</blockquote>
<h3 id="5강-코틀린에서-조건문을-다루는-방법">5강. 코틀린에서 조건문을 다루는 방법</h3>
<h1 id="📌-if문">📌 if문</h1>
<h2 id="📍-java">📍 JAVA</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/6b7a3810-b26a-44df-be28-2f8fcc747a0f/image.png" alt=""></p>
<h2 id="📍-kotlin">📍 Kotlin</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/adb4837a-58cb-4ce9-8a1e-beddf2b9e211/image.png" alt=""></p>
<ul>
<li><code>Unit</code> (<code>void</code>)가 생략됨</li>
<li>함수를 만들 때 <code>fun</code>을 사용함</li>
<li><code>new</code>를 사용하지 않고 예외를 throw함
➡️ 자바와 거의 차이가 없다.</li>
</ul>
<h1 id="📌-statemnet와-expression">📌 Statemnet와 Expression</h1>
<p>하지만 한가지 다른 점이 있다.</p>
<blockquote>
<p>Java에서 if-else는 <strong>Statemnet</strong>이지만,
Kotlin에서는 <strong>Expression</strong>이다.</p>
</blockquote>
<ul>
<li>Statement : 프로그램의 문장, 하나의 값으로 도출되지 않는다.</li>
<li>Expression : 하나의 값으로 도출되는 문장</li>
</ul>
<p>Java에서는 expression을 사용하기 위해서는 3항 연산자를 사용해야 한다.
<img src="https://velog.velcdn.com/images/hi_potato/post/09002d60-77d4-4c39-9e61-46a668d59fd9/image.png" alt=""></p>
<p>Kotlin는 if-else를 expression으로 사용할 수 있기 때문에 3항 연산자가 없다.
<img src="https://velog.velcdn.com/images/hi_potato/post/22458d0a-7e4f-4840-9077-d50ccadbb3c5/image.png" alt=""></p>
<p>if-else if-else 문도 문법이 동일하다.</p>
<h2 id="📍-java-1">📍 JAVA</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/77b76a12-ff40-4fa5-a4e5-6e5a0400f510/image.png" alt=""></p>
<h2 id="📍-kotlin-1">📍 Kotlin</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/9b8fca3f-bcf8-40a8-ab01-b63f679441ef/image.png" alt=""></p>
<blockquote>
<h4 id="💡-간단한-tip">💡 간단한 TIP</h4>
<p>어떠한 값이 특정 범위에 포함되어 있는지, 포함되어 있지 않은지
<img src="https://velog.velcdn.com/images/hi_potato/post/fc02f965-4818-4c36-b4e2-da3d411cd4f0/image.png" alt="">
<img src="https://velog.velcdn.com/images/hi_potato/post/bc807ff9-b892-4611-a26e-182ab7fc1873/image.png" alt=""></p>
</blockquote>
<h1 id="📌-switch-와-when">📌 switch 와 when</h1>
<h2 id="📍-java-2">📍 JAVA</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/80baecfe-21d4-4b77-832b-dedbef733ad3/image.png" alt=""></p>
<h2 id="📍-kotlin-2">📍 Kotlin</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/735c0106-5bb0-489a-b04b-a93d90a08d89/image.png" alt=""></p>
<p><code>when</code> 역시 하나의 expression이기 때문에 <code>when</code>을 통해서 나온 결과를 바로 return 할 수 있다.</p>
<p>Kotlin의 <code>when</code>은 Java의 <code>switch</code>보다 다양하게 사용 가능하다.
특정 값이 아닌 범위로도 분기처리 가능하다.
<img src="https://velog.velcdn.com/images/hi_potato/post/e2ebf54c-eb5e-4da0-9767-3e1e1d5e3764/image.png" alt=""></p>
<pre><code class="language-java">when (값) {
    조건부 -&gt; 어떠한 구문
    조건부 -&gt; 어떠한 구문
    else -&gt; 어떠한 구문
}</code></pre>
<ul>
<li>조건부에는 어떠한 expression이라도 들어갈 수 있다. (ex. <code>is Type</code>)</li>
<li>조건부에서 여러개의 조건을 동시에 검사할 수 있다. (<code>,</code>로 구분)</li>
<li>값이 없을 수도 있다. - early return 처럼 동작 </li>
</ul>
<h2 id="📍-java-3">📍 JAVA</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/8d826536-53fd-4816-bc3c-084f1f6f1e73/image.png" alt=""></p>
<h2 id="📍-kotlin-3">📍 Kotlin</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/8a915586-ba67-4944-9244-c61a4590b003/image.png" alt=""></p>
<p><code>when</code>은 <strong>Enum Class</strong> 혹은 <strong>Sealed Class</strong>와 함께 사용할 경우, 더욱 더 진가를 발휘한다.
(이건 class를 다룰 때 자세하게 설명할 예정)</p>
<hr>

<blockquote>
<h3 id="📑-출처">📑 출처</h3>
</blockquote>
<ul>
<li>자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide) (인프런/최태현)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin] 코틀린에서 연산자를 다루는 방법]]></title>
            <link>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-%EC%97%B0%EC%82%B0%EC%9E%90%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-%EC%97%B0%EC%82%B0%EC%9E%90%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Sat, 17 May 2025 06:04:49 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="자바-개발자를-위한-코틀린-입문">자바 개발자를 위한 코틀린 입문</h2>
</blockquote>
<h3 id="4강-코틀린에서-연산자를-다루는-방법">4강. 코틀린에서 연산자를 다루는 방법</h3>
<h1 id="📌-단항-연산자--산술-연산자">📌 단항 연산자 / 산술 연산자</h1>
<ul>
<li>단항 연산자 : ++ , --</li>
<li>산술 연산자 : +, -, *, /, %</li>
<li>산술대입 연산자: +=, -=, *=, /=, %=
자바와 완전하게 동일하다.</li>
</ul>
<h1 id="📌-비교-연산자와-동등성-동일성">📌 비교 연산자와 동등성, 동일성</h1>
<ul>
<li>비교 연산자 : &gt;, &lt;, &gt;=, &lt;=
자바와 사용법이 동일하다.</li>
</ul>
<p>단, 자바와 다르게 객체를 비교할 때 비교 연산자를 사용하면 자동으로 <code>compareTo</code>를 호출해준다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/62b272ec-a397-4039-9a7c-dbd6efce6672/image.png" alt=""></p>
<p>자바에서는</p>
<pre><code class="language-java">if(money1.compareTo(money2) &gt; 0 ) {
    System.out.println(&quot;money1이 money2보다 금액이 큽니다.&quot;);
}</code></pre>
<p>로 작성해야한다.</p>
<p>코틀린이 자바보다 가독성이 좋다.</p>
<blockquote>
<ul>
<li><strong>동등성(Equality)</strong> : 두 객체의 값이 같은가?</li>
</ul>
</blockquote>
<ul>
<li><strong>동일성(Identity)</strong> : 완전히 동일한 객체인가? 즉, 주소가 같은가?</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/f374df97-1818-49fd-a3a2-a893efbebf36/image.png" alt=""></p>
<ul>
<li><code>===</code> : 주소값까지 같은 객체인지 확인</li>
<li><code>==</code> : 값이 동일한지 확인. (<code>==</code>을 눌러보면 <code>equals()</code> 로 이동된다.)
<img src="https://velog.velcdn.com/images/hi_potato/post/22bacb29-a7c8-4cb4-a90f-4cbdabd64a8b/image.png" alt=""></li>
</ul>
<h1 id="📌-논리-연산자와-코틀린에-있는-특이한-연산자">📌 논리 연산자와 코틀린에 있는 특이한 연산자</h1>
<ul>
<li>논리 연산자 : &amp;&amp;, ||, !
자바와 완전히 동일하다.</li>
</ul>
<p>자바처럼 Lazy 연산을 수행한다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/96e76daf-bf28-4810-9e66-e662542e68a6/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/5a88d637-84ea-437a-96ca-93fb3b0ef3f1/image.png" alt=""></p>
<p>조건절에서 <code>fun1()</code>이 이미 true 이므로 <code>fun2()</code>를 실행하지 않는다.</p>
<p>반대로 아래의 상황에서는 <code>fun2()</code>가 이미 false 이므로 <code>fun1()</code>를 실행하지 않는다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/e28d75ff-37a6-4804-bbda-36719ed65ec3/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/9937294f-d323-4930-9364-f3c7366b861c/image.png" alt=""></p>
<h3 id="in--in">in / !in</h3>
<ul>
<li>컬렉션이나 범위에 포함되어 있다. / 포함되어있지 않다.<h3 id="ab">a..b</h3>
</li>
<li>a부터 b까지의 범위 객체를 생성한다. <h3 id="ai">a[i]</h3>
</li>
<li>a에서 특정 index i로 값을 가져온다.<h3 id="ai--b">a[i] = b</h3>
</li>
<li>a의 특정 index i에 b를 넣는다.</li>
</ul>
<h1 id="📌-연산자-오버로딩">📌 연산자 오버로딩</h1>
<p>코틀린에서는 객체마다 연산자를 직접 정의할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/97340862-eec0-4cf5-925e-08d658f5ea9d/image.png" alt=""></p>
<p><code>toString</code>이 구현되어 있어서 가능하다.</p>
<hr>

<blockquote>
<h3 id="📑-출처">📑 출처</h3>
</blockquote>
<ul>
<li>자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide) (인프런/최태현)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin] 코틀린에서 Type을 다루는 방법]]></title>
            <link>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-Type%EC%9D%84-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-Type%EC%9D%84-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Sat, 17 May 2025 05:54:53 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="자바-개발자를-위한-코틀린-입문">자바 개발자를 위한 코틀린 입문</h2>
</blockquote>
<h3 id="3강-코틀린에서-type을-다루는-방법">3강. 코틀린에서 Type을 다루는 방법</h3>
<h1 id="📌-기본-타입">📌 기본 타입</h1>
<ul>
<li>Byte, Short, Int, Long, Float, Double, 부호 없는 정수들
코틀린에서는 선언된 기본값을 보고 타입을 추론한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/f144a16a-8abe-405f-aea3-009a5751ba84/image.png" alt=""></p>
<blockquote>
<p>자바에서는 기본 타입간의 변환은 <strong>암시적으로</strong> 이루어질 수 있다.
코틀린에서는 기본 타입간의 변환은 <strong>명시적으로</strong> 이루어져야 한다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/c433a457-73c3-4f10-b74b-2310bb9ba894/image.png" alt=""></p>
<p>변수가 nullable이라면 적절한 처리가 필요하다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/1bc30432-d0ae-4a42-a443-d9f0ecdd41f6/image.png" alt=""></p>
<h1 id="📌-타입-캐스팅">📌 타입 캐스팅</h1>
<h2 id="📍-java">📍 JAVA</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/45701aec-c407-411b-a1ee-3575f76dcb18/image.png" alt=""></p>
<ul>
<li><code>instanceof</code> : 변수가 주어진 타입이면 true, 그렇지 않으면 false를 반환한다.</li>
<li><code>(타입)</code> : 주어진 변수를 해당 타입으로 변경한다.</li>
</ul>
<h2 id="📍-kotlin">📍 Kotlin</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/ef741fc2-fd0f-4739-8560-19d7a246018c/image.png" alt=""></p>
<ul>
<li><code>is</code>: 자바의 <code>instanceof</code>와 같은 역할. 변수가 주어진 타입이면 true, 그렇지 않으면 false를 반환한다.</li>
<li><code>as</code>: 주어진 변수를 해당 타입으로 변경한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/545d469c-8a41-42fe-be74-8e3ddf40e74a/image.png" alt=""></p>
<p><code>as Person</code>을 생략하여도 <code>Person</code>타입으로 인식한다. (Java에서는 명시적 형변환 필수)</p>
<ul>
<li>스마트 캐스트 : 코틀린 컴파일러가 컨텍스트를 분석한 후 <code>if</code> 에서 타입 체크를 했으니 해당 변수는 이 타입으로 간주될 수 있겠구나를 인지하여 처리한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/cef93553-8255-4ddc-ae80-cac76d7d93a8/image.png" alt=""></p>
<ul>
<li><code>!is</code> : <code>instanceof</code>와 <code>is</code>의 반대. 변수가 주어진 타입이면 false, 그렇지 않으면 true를 반환한다.</li>
</ul>
<p><code>as</code>에 null이 들어온다면 <code>as</code>에 Safe Call을 붙혀줘야 한다.</p>
<ul>
<li><code>as?</code> : 객체가 null이 아니라면 타입을 변환하고 아니라면 null을 반환한다.</li>
</ul>
<h2 id="📍-kotlin의-특이한-타입-3가지">📍 Kotlin의 특이한 타입 3가지</h2>
<h3 id="any">Any</h3>
<ul>
<li>Java의 Object 역할. (모든 객체의 최상위 타입)</li>
<li>모든 Primitive Type의 최상의 타입도 <code>Any</code>이다.</li>
<li><code>Any</code> 자체로는 null을 포함할 수 없어 null을 포함하고 싶다면, <code>Any?</code>로 표현한다.</li>
<li><code>Any</code>에 <code>equals</code> / <code>hashCode</code> / <code>toString</code> 가 존재한다.
<img src="https://velog.velcdn.com/images/hi_potato/post/a2ecbd6e-35d6-44a0-b235-95b0080287ad/image.png" alt=""></li>
</ul>
<h3 id="unit">Unit</h3>
<ul>
<li><code>Unit</code>은 Java의 <code>void</code>와 동일한 역할.</li>
<li><code>void</code>와 다르게 <code>Unit</code>은 그 자체로 타입 인자로 사용 가능하다. (<code>void</code>는 void 제네릭을 쓰려면 <code>Void</code>를 가져와야 하지만 <code>Unit</code>은 그대로 사용 가능하다.)</li>
<li>함수형 프로그래밍에서 <code>Unit</code>은 단 하나의 인스턴스만 갖는 타입을 의미한다. 즉, 코틀린의 </li>
<li><code>Unit</code>은 실제 존재하는 타입이라는 것을 표현한다.</li>
</ul>
<h3 id="nothing">Nothing</h3>
<ul>
<li><code>Nothing</code>은 함수가 정상적으로 끝나지 않았다는 사실을 표현하는 역할이다.</li>
<li>무조건 예외를 반환하는 함수 / 무한 루프 함수 등
<img src="https://velog.velcdn.com/images/hi_potato/post/0056bb2e-66ca-46b6-a9c6-559deeecd27d/image.png" alt=""></li>
</ul>
<h1 id="📌-string-interpolation--string-indexing">📌 String interpolation / String indexing</h1>
<ul>
<li><p><code>${변수}</code>를 사용하면 값이 들어가진다. 
<img src="https://velog.velcdn.com/images/hi_potato/post/5790594d-5858-4437-805e-ff7580bcc3bc/image.png" alt=""></p>
</li>
<li><p><code>$변수</code>를 사용할 수도 있다.
<img src="https://velog.velcdn.com/images/hi_potato/post/50365ba2-234a-412f-87b1-63cc96dbc997/image.png" alt=""></p>
</li>
</ul>
<blockquote>
<h3 id="💡-tip">💡 Tip</h3>
<p>변수 이름만 사용하더라도 <code>${변수}</code>를 사용하는 것이
<strong>1) 가독성
2) 일괄 변환
3) 정규식 활용</strong>
측면에서 좋다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/70767d43-6315-4214-a7e2-6635db9fe59f/image.png" alt="">
<code>&quot;&quot;&quot;</code>을 치고 엔터를 누르면 앞에 탭 공간(indent)를 제거해주는 <code>trimIndent()</code> 함수가 생긴다.
자유롭게 문자열 작성이 가능하다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/a6760dda-80cd-42b4-8e00-d66434931701/image.png" alt=""></p>
<p>문자열에서 특정 문자를 가져올 때는 자바의 배열처럼 대괄호([])안에 원하는 위치의 인덱스를 넣어주면 된다.</p>
<hr>

<blockquote>
<h3 id="📑-출처">📑 출처</h3>
</blockquote>
<ul>
<li>자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide) (인프런/최태현)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin] 코틀린에서 null을 다루는 방법]]></title>
            <link>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-null%EC%9D%84-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-null%EC%9D%84-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Tue, 06 May 2025 06:27:53 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="자바-개발자를-위한-코틀린-입문">자바 개발자를 위한 코틀린 입문</h2>
</blockquote>
<h3 id="2강-코틀린에서-null을-다루는-방법">2강. 코틀린에서 null을 다루는 방법</h3>
<h1 id="📌-kotlin에서의-null-체크">📌 Kotlin에서의 null 체크</h1>
<h2 id="📍-java의-stringstartwith함수-만들어보기">📍 Java의 <code>String.startWith()</code>함수 만들어보기</h2>
<h3 id="java">Java</h3>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/b147367c-53e3-4d54-b3c7-9c10ec830cf4/image.png" alt=""></p>
<h3 id="kotlin">Kotlin</h3>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/6db2913b-2f42-4925-a5af-f815e362f7aa/image.png" alt=""></p>
<h1 id="📌-safe-call과-elvis-연산자">📌 Safe Call과 Elvis 연산자</h1>
<p>코틀린에서는 null이 가능한 타입을 <strong>완전히 다르게 취급</strong>한다!
<strong>null이 가능한 타입만</strong>을 위한 기능은 없나?!</p>
<h2 id="📍-safe-call">📍 Safe Call</h2>
<p><code>.?</code>
null이 아니면 실행하고, null이면 실행하지 않는다. (그대로 null)
<img src="https://velog.velcdn.com/images/hi_potato/post/883f1ce5-2e23-4ded-b27e-ed8a2b6f450c/image.png" alt=""></p>
<p>null이 들어갈 수 있는 변수에 대해서는 <code>.</code>을 바로 쓸 수 없다고 에러가 난다.
<img src="https://velog.velcdn.com/images/hi_potato/post/c8fe19db-ae6c-41b6-9ad9-66f7bf9e378f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/af19ea84-3d63-44ac-98c6-84aff6e7ad38/image.png" alt=""></p>
<p>Safe Call(<code>?.</code>) 을 사용하면 null이 아닌 경우에만 호출하게 된다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/a68de34b-9296-499b-a868-ed0921f639f3/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/58ce7fe8-3f16-4722-a423-c1fcd70f151c/image.png" alt=""></p>
<p><code>str</code>이 null이면 null을 반환한다.</p>
<h2 id="📍-elvis-연산자">📍 Elvis 연산자</h2>
<p><code>?:</code>
앞의 연산 결과가 null이면 뒤의 값을 사용한다.
<img src="https://velog.velcdn.com/images/hi_potato/post/562fb1d0-499a-4fe3-b69c-51998a9f6112/image.png" alt=""></p>
<h2 id="📍-safe-call과-elvis-연산자를-이용해-코드를-보다-코틀린-스럽게-바꿔보기">📍 Safe Call과 Elvis 연산자를 이용해 코드를 보다 코틀린 스럽게 바꿔보기</h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/d0a0ccff-fd4d-4e15-8da7-bd987cc44ec5/image.png" alt=""></p>
<h1 id="📌-널-아님-단언">📌 널 아님 단언!!</h1>
<p><code>!!.</code>
nullable type이지만, 아무리 생각해도 null이 될 수 없는 경우에 사용한다.
이 변수는 절대 null이 아니라는 뜻이다.
<img src="https://velog.velcdn.com/images/hi_potato/post/9f118800-ed86-455f-8915-733ae4b01b74/image.png" alt=""></p>
<p>null이 들어오면 런타임 에러가 발생한다.
정말 null이 아닌 게 확실한 경우에만 널 아님 단언<code>!!</code>을 사용해야 한다.</p>
<h1 id="📌-플랫폼-타입">📌 플랫폼 타입</h1>
<p>코틀린에서 자바 코드를 가져다 사용할 때 어떻게 처리될까?
<img src="https://velog.velcdn.com/images/hi_potato/post/12d51e98-3fc7-4b02-b92c-fabdb721a95c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/30bfaf8a-b52a-402a-aa3f-0660bd279cc6/image.png" alt=""></p>
<p><code>Person</code>객체의 <code>name</code>에 <code>@Nullable</code> 어노테이션이 있으면 컴파일 오류가 발생한다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/9a15eb44-343a-4a6d-8cc2-5f3a32b962e4/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/85cddc6e-7491-4526-9efd-b0626da83746/image.png" alt=""></p>
<p><code>@NotNull</code> 어노테이션이 있을 때는 괜찮다.
이렇게 null에 대한 어노테이션 정보를 코틀린이 이해한다.</p>
<p>하지만 <code>@Nullable</code>과 <code>@NotNull</code>이 없다면 코틀린에서는 이 값이 nullable인지 non-nullable인지 알 수가 없다.</p>
<h2 id="📍-플랫폼-타입">📍 플랫폼 타입</h2>
<p>코틀린이 null 관련 정보를 알 수 없는 타입을 말한다.
Runtime 시 Exception이 날 수 있다.</p>
<p>그래서 코틀린에서 자바 코드를 사용할 때는 null 관련 정보를 꼼꼼하게 작성해줘야 한다.</p>
<p>애당초 그런게 작성되어 있지 않은 라이브러리를 가져다 써야한다면 그 라이브러리를 열어서 이 값에 null이 들어갈 수 있는건지, 없는건지 확인을 하면 좋다.</p>
<p>그 다음에 최초의 코틀린에서 자바 라이브러리를 가져다 쓴 지점을 랩핑해서 단일 지점으로 만듦으로써 추후에 이슈가 났을 때 보다 쉽게 대응할 수 있게 만들면 좋다.</p>
<p><img src="blob:https://velog.io/671321de-b438-4638-90c7-b40eb3caa0e5" alt="업로드중.."></p>
<p>(마지막 문장 무슨 말인지 이해가 안가서 Chat GPT에게 설명해달라고 함... 코틀린에서 관리할 수 있도록 공통 함수를 만들라는 것으로 이해했다.)</p>
<hr>

<blockquote>
<h3 id="📑-출처">📑 출처</h3>
</blockquote>
<ul>
<li>자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide) (인프런/최태현)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin] 코틀린에서 변수를 다루는 방법]]></title>
            <link>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-%EB%B3%80%EC%88%98%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90%EC%84%9C-%EB%B3%80%EC%88%98%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Tue, 06 May 2025 06:16:13 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="자바-개발자를-위한-코틀린-입문">자바 개발자를 위한 코틀린 입문</h2>
</blockquote>
<h3 id="1강-코틀린에서-변수를-다루는-방법">1강. 코틀린에서 변수를 다루는 방법</h3>
<h1 id="📌-변수-선언-키워드---var과-val의-차이점">📌 변수 선언 키워드 - var과 val의 차이점</h1>
<p>JAVA에서 long 과 final long의 차이 -&gt; 가변인가, 불변인가(read-only)</p>
<p>var -&gt; 가변 - 값이 변경될 수 있는 변수 (varialbe의 약자)
val -&gt; 불변 - 값이 변경될 수 없는 변수 (value의 약자)</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/843576f7-eaba-43d4-a101-128b7936c1a5/image.png" alt=""></p>
<blockquote>
<h3 id="코틀린에서는-모든-변수에-수정-가능-여부var--val를-명시해주어야-한다">코틀린에서는 모든 변수에 수정 가능 여부(var / val)를 명시해주어야 한다.</h3>
</blockquote>
<p>코틀린에서는 타입을 자동으로 컴파일러가 추론해 주기 때문에 타입을 의무적으로 작성하지 않아도 되지만 원한다면 <code>변수: 타입</code>으로 작성할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/9ea404fc-acd9-4018-ba8f-9124ed0ed4de/image.png" alt=""></p>
<p>초기값을 지정해주지 않는 경우?</p>
<h2 id="📍-var">📍 <code>var</code></h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/dcc6d868-f6fa-4210-a32b-ace72122a727/image.png" alt=""></p>
<p>타입을 정의하지 않으면 오류가 난다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/f7ea7c52-4b5a-4749-8475-e731d6cbe05d/image.png" alt=""></p>
<p>타입을 정의하면 오류는 사라지지만 값을 선언하지 않고 사용하려고 하면 오류가 난다.</p>
<h2 id="📍-val">📍 <code>val</code></h2>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/0f8f7b12-e570-4dfd-b4a5-c6661f3f1a9d/image.png" alt=""></p>
<p>마찬가지로 값이 선언되어있지 않은 상태에서 타입을 정의해주지 않거나</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/09e68df0-d9c5-4612-a4dd-95604a7f9832/image.png" alt=""></p>
<p>변수를 사용하려고 하면 오류가 난다.</p>
<p><code>val</code> 컬렉션에는 element를 추가할 수 있다.</p>
<blockquote>
<h4 id="간단한-tip">간단한 TIP</h4>
<p>모든 변수는 우선 val로 만들고 꼭 필요한 경우 var로 변경한다.</p>
</blockquote>
<h1 id="📌-kotlin에서의-primitive-type">📌 Kotlin에서의 Primitive Type</h1>
<p>자바에서 <code>long은</code> primitive type / <code>Long</code>은 reference type이다.
코틀린에서는 모두 <code>Long</code>을 사용한다.
-&gt; primitive type과 reference type의 구분이 없다.</p>
<blockquote>
<h3 id="kotlin-공식-문서">Kotlin 공식 문서</h3>
<p>숫자, 문자, 불리언과 같은 몇몇 타입은 내부적으로 특별한 표현을 갖는다.
이 타입들은 실행시에 primitive value로 표현되지만, 코드에서는 평범한 클래스처럼 보인다.</p>
</blockquote>
<p><code>Long</code> 타입으로 합쳐져 있지만 만약 연산을 하게 될 경우에는 코틀린이 알아서 똑똑하게 상황에 따라서는 내부적으로 primitive type으로 바꿔서 적절히 처리를 해준다.</p>
<h2 id="📍-코틀린-코드를-자바-코드로-바꿔보기">📍 코틀린 코드를 자바 코드로 바꿔보기</h2>
<p>인텔리제이 Tools &gt; Kotlin &gt; Show Kotlin Bytecode
<img src="https://velog.velcdn.com/images/hi_potato/post/9d2ff59a-94dc-4bff-a811-701a68d57662/image.png" alt=""></p>
<p>Decompile 버튼을 누르면 자바 코드로 변경해준다.
<img src="https://velog.velcdn.com/images/hi_potato/post/8c67507a-857c-4a2d-bd39-6ded5d15e0f9/image.png" alt=""></p>
<p><code>long</code>으로 primitive type으로 들어가진 것을 알 수 있다.</p>
<blockquote>
<h3 id="💡-즉-프로그래머가-boxing-unboxing을-고려하지-않아도-되도록-kotlin이-알아서-처리-해준다">💡 즉, 프로그래머가 boxing/ unboxing을 고려하지 않아도 되도록 Kotlin이 알아서 처리 해준다.</h3>
</blockquote>
<h1 id="📌-kotlin에서의-nullable-변수">📌 Kotlin에서의 nullable 변수</h1>
<p>코틀린에서는 자바와 다르게 &#39;null이 들어갈 수 있는&#39;을 다르게 표현한다.
<img src="https://velog.velcdn.com/images/hi_potato/post/54c7ac74-7601-4fd9-a5eb-ce7156d008fc/image.png" alt=""></p>
<p>코틀린은 기본적으로 모든 변수를 null이 들어갈 수 없게끔 설계해놓는다.
<img src="https://velog.velcdn.com/images/hi_potato/post/e7015d9f-cd22-4e84-901a-f6b297c4756b/image.png" alt=""></p>
<p>null이 변수에 들어갈 수 있다면 <code>타입?</code>를 사용해야 한다.</p>
<h1 id="📌-객체-인스턴스화">📌 객체 인스턴스화</h1>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/987a9b58-c011-4909-a993-974ae17f2dd5/image.png" alt=""></p>
<p>객체 인스턴스화 할 때에는 자바와 달리 <code>new</code>키워드 없이 객체를 생성해야한다.</p>
<hr>

<blockquote>
<h3 id="📑-출처">📑 출처</h3>
</blockquote>
<ul>
<li>자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide) (인프런/최태현)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin] 코틀린에 관한 TMI (feat. Java와의 비교)]]></title>
            <link>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90-%EA%B4%80%ED%95%9C-TMI-feat.-Java%EC%99%80%EC%9D%98-%EB%B9%84%EA%B5%90</link>
            <guid>https://velog.io/@hi_potato/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%97%90-%EA%B4%80%ED%95%9C-TMI-feat.-Java%EC%99%80%EC%9D%98-%EB%B9%84%EA%B5%90</guid>
            <pubDate>Tue, 06 May 2025 05:57:21 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="자바-개발자를-위한-코틀린-입문">자바 개발자를 위한 코틀린 입문</h2>
</blockquote>
<h3 id="0강-코틀린에-관한-34가지-tmi-feat-java와의-비교">0강. 코틀린에 관한 34가지 TMI (feat. Java와의 비교)</h3>
<h1 id="📌-코틀린에-관한-사실">📌 코틀린에 관한 사실</h1>
<ul>
<li>코틀린은 JetBrains라는 회사에서 만들었다.</li>
<li>코틀린은 정적 타입 언어이다. 프로그램 구성 요소의 타입을 컴파일 시점에 알 수 있고, 프로그램 안에서 필드나 메소드를 사용할 때 컴파일러가 타입을 검증해준다는 뜻이다.</li>
<li>코틀린은 객체지향형 프로그래밍(OOP)과 함수형 프로그래밍(FP)를 조화롭게 지원하고 있다.</li>
<li>코틀린 언어 개발자들은, 코틀린 언어의 간결함을 살리기 위해 프로그래머가 작성하는 코드에서 의미 없는 부분을 줄이고, 언어가 요구하는 구조를 만족시키기 위해 별 뜻은 없지만 프로그램에 꼭 넣어야 하는 부수적인 요소를 줄이기 위해 많은 노력을 하였다.</li>
<li>코틀린의 파일 확장자는 .kt이다.</li>
<li>코틀린에서는 java와 달리, 세미콜론(;)을 붙이지 않아도 된다.</li>
<li>주석을 처리하는 방법은 java와 동일하다.</li>
<li>별도의 지시어가 없다면 모두 public으로 인식한다.</li>
<li>출력을 할 때에 System.out.println() 대신 println() 만 작성하면 된다.</li>
<li>함수를 작성할 때 fun이라는 키워드를 사용한다.</li>
<li>java에서는 &#39;타입 변수명&#39;을 사용했지만, 코틀린에서는 TS와 유사하게 &#39;변수명: 타입&#39;을 사용한다. </li>
</ul>
<hr>

<blockquote>
<h3 id="📑-출처">📑 출처</h3>
</blockquote>
<ul>
<li>자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide) (인프런/최태현)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[항해플러스 백엔드 7기] 길고 짧았던 항해 후기]]></title>
            <link>https://velog.io/@hi_potato/%ED%95%AD%ED%95%B4-%ED%94%8C%EB%9F%AC%EC%8A%A4-%EB%B0%B1%EC%97%94%EB%93%9C-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@hi_potato/%ED%95%AD%ED%95%B4-%ED%94%8C%EB%9F%AC%EC%8A%A4-%EB%B0%B1%EC%97%94%EB%93%9C-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Sat, 08 Mar 2025 04:46:34 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h1 id="항해-플러스-백엔드-7기">항해 플러스 백엔드 7기</h1>
</blockquote>
<h3 id="🎆-끝내는-마음">🎆 끝내는 마음</h3>
<blockquote>
<h3 id="📌-20만원-등록금-할인을-받을-수-있는-추천-코드">📌 20만원 등록금 할인을 받을 수 있는 추천 코드</h3>
</blockquote>
<h3 id="welxjd">weLxjd</h3>
<h1 id="📌-수료-완료">📌 수료 완료!</h1>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/45363c67-5e92-444a-81ce-43231788e96b/image.png" alt=""></p>
<p><em>학습시간은 미처 타이머를 재지 않고 공부하는 순간들도 많았기에 흐린눈 부탁드린다...!!</em></p>
<p>미처 캡처는 못했지만 10주동안 매주 2개씩 제공되는 총 20개의 과제를 <strong>ALL PASS</strong>하여 항해플러스 백엔드 7기 코스를 마무리 하였다.</p>
<hr>

<h1 id="📌-블랙배지를-받을-수-있었던-이유">📌 블랙배지를 받을 수 있었던 이유</h1>
<blockquote>
<p>블랙뱃지의 조건이 <strong>과제 90% 합격과 하나의 따봉</strong>을 받아야한다.</p>
</blockquote>
<h2 id="감자의-루틴">감자의 루틴</h2>
<p>퇴근하면 8시<del>8시반, 대충 저녁을 먹고 zep에 접속하면 8시반</del>9시이다. (때때론 저녁을 안먹고 8시에 접속한다.)
그럼 그 이후로 아무리 빨라도 11시, 늦으면 5~6시까지 공부와 과제를 한다.</p>
<p>금요일 오전 10시까지 과제 제출이기 때문에 목요일이나 금요일에 연차 사용도 많이 했는데 목요일에 연차라면 목요일 내내 과제를 하다가 새벽 3시쯤에 잠이 들었고 금요일 연차라면 아침 9시까지 과제를 했다.</p>
<p>수면 부족과 운동 부족으로 인해 건강이 실시간으로 차감되는 게 느껴지지만 머릿 속이 실시간으로 차오르는 게 느껴지는... 건강과 지식을 맞교환하면 된다.ㅎ</p>
<h2 id="과제">과제</h2>
<p>어디에서나 늘 그렇듯이 날고기는 사람들이 굉장히 많았는데 이 안에서 따봉은 커녕 과제 90% 이상 통과할 수 있을까?를 많이 걱정했는데 굉장히 부질없는 걱정이었다. 이 과정은 상대평가가 아닌 개인평가이므로 남들과 상관없이 나만 잘하면 되는 거다. <strong>기 죽을 필요 없다 이 말이여!!!!</strong></p>
<p>감자는 테스트 코드도 처음이고 동시성 제어도 처음이고 JPA, redis, kafka는 초면이다.
테스트 코드의 경우 거의 매 과제에 존재했다고 해도 과언이 아니었다. 사전 스터디에서 공부한 테스트 코드가 도움이 되었지만 공부와 실전이 어찌 같겠는가... 혼자 열심히 헤매고 동기들에게 도움 요청도 하며 겨우겨우 테스트 코드를 작성했었다 처음엔.
그래도 두세번 해보니 그 뒤론 나름 방법을 터득하여 혼자서도 작성할 수 있게 되어서 정말 뿌듯했다.</p>
<p><strong>과제를 하루벌어 하루사는 사람처럼 일주일 공부해서 겨우겨우 과제를 해냈다.</strong>
더 잘하고 싶다는 욕심은 안타깝지만 넣어뒀다. 퇴근 후 공부하고 과제할 수 있는 시간은 안타깝게도 다음 출근시간 전까지이기 때문에 더욱히 다음날 업무를 위해 컨디션 조절을 아예 안할 수도 없는 노릇이기에 기본이 없는 감자는 무조건 기본에 충실해야했다. 새로운 기술을 배웠다는 것에 의미를 두고 왜 필요하며 어떻게 활용하는 지에 집중했다.</p>
<p>동기들이 &quot;요올 감자 올패스야~&quot; 하면 늘 [기본에 충실했다.]라고 변명아닌 변명을 하곤 했는데 그 때마다 다들 &quot;교과서 위주로 공부했어요&quot;라며 놀렸다...ㅋㅋ
<img src="https://velog.velcdn.com/images/hi_potato/post/6603fba4-a8bd-461f-8a14-21621e798f2a/image.png" alt=""></p>
<h2 id="따봉">따봉</h2>
<p>따봉은 코치님이 채점하시다가 잘했다고 생각되는 우수 과제에 부여해주는 일종의 추천이다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/b99c20d1-4d64-43f2-a5e2-779d2762893a/image.png" alt=""></p>
<p>나도 의문이었던 따봉... 받을 줄 몰랐다.
때는 지옥의 4주차... 정말 코딩에 코딩만 주구장창하는 주차였다.
회사였어도 이삼주는 족히 줬을 것 같은 양인데 그걸 일주일만에 테스트코드까지 해야한다니... 눈물이 좔좔 났다...
이번 주 드롭할까... 포기할까... 만 수십번 되내인 듯 하다ㅠ</p>
<p>그럼에도 쉽게 포기하고 싶지 않아서 어떻게든 부여잡고 꾸역꾸역 하다가 더는 안되겠다.하고 제출한 과제.
사실 fail도 각오하고 제출했는데 받은 pass와 따봉이었다.</p>
<p>많이 엉성한 코드를 제출하게 되어 너무 죄송했는데 다행히 코치님께서 좋게 봐주셨다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/a807c4e7-fa96-4fdf-ba38-0dfea1f006e7/image.png" alt=""></p>
<p>빅테크 시니어 개발자가 감자의 경력을 제대로 봐주셨다...
별 거 아닐 수 있지만 물경력이 되어가는 거 같아서 슬펐는데 감자가 멈춰있는 게 아니라 성장하고 있었나보다 싶어서 지금까지 고민한 시간을 보상받는 느낌이었다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/d59c2115-1bc3-4bcc-b41f-4bf7262d135b/image.png" alt=""></p>
<p>함께 일하고 싶은 동료라는 최고의 칭찬도 함께...💛</p>
<h2 id="동기들">동기들</h2>
<p>감자와 함께 밤새주고 고민해주고 웃으며 놀아주기도 하는 소중한 감자의 7기 동기들...</p>
<p>ZEP에서 항상 오손도손 떠들기도 하고 의견 공유도 하고 조용히 모각코를 하기도 했다. 우리 동기들 덕분에 자극 많이 받고 더 열심히 했다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/fb86091e-7f32-4967-b9d8-fc13e536bab1/image.png" alt=""></p>
<p>매주 토요일마다 발제를 하는데 오프라인으로 모여 다 같이 발제를 들은 후 친목을 위한 술자리도 항상 열렸다.
여기서 새로운 동기들과 많이 친해질 수 있었다.
<img src="https://velog.velcdn.com/images/hi_potato/post/f63eebb9-212e-4e32-8d45-74b03471aa52/image.png" alt=""></p>
<p>사진들이 대부분 얼굴 나와서 초상권을 위해 손 사진으로...✌️</p>
<p>100명 넘는 동기들 중에서도 나와 늘 함께해주고 응원해주던 32팀이 최고다‼️ 32팀 사랑해❤️❤️
(⚠️항해플러스 백엔드 7기엔 31팀밖에 없다.)</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/1d8bfed2-f259-473d-8d22-c81b49dd32d6/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/e33d9902-75cf-4c4d-a536-9fa2104037b2/image.png" alt=""></p>
<p>항해 홈페이지에 박제될 정도로 끈끈한 인연이라구요!!
실제로 수료 후에도 많이 만났다.</p>
<hr>

<h1 id="📌-항해-이후">📌 항해 이후</h1>
<p>항해를 하면서 많은 기술을 배우고 많은 또래 개발자들을 보게 되면서 느낀 점은</p>
<blockquote>
<h3 id="아직-공부해야할-게-많구나">아직 공부해야할 게 많구나!!</h3>
</blockquote>
<p>이다.</p>
<p>감자는 이정도면 부족하긴 해도 그럭저럭 실무할 수 있지 않나...? 라는 생각을 가지고 안일하게 있었던 것 같다.</p>
<p>발제를 하면 공부를 시작하는 감자는 발제하기 전부터 +a로 알고 있어서 심도 깊은 고민을 하는 다들 동기들과 스스로를 순간적으로 비교하게 되었다.
열등감이 없다고는 표현 못하는 감자는 그 동안 뭐했나라며 스스로를 망치지 않고 자극을 받아 더 나아가는 발판으로 삼기로 결정했다.</p>
<p><strong>공부를 많이 해서 똑똑한 동기들이 부럽다? 그럼 그들처럼 하면 돼!!</strong></p>
<p>항해플러스를 하면서 배운 기술들이 완전하게 감자의 것이라고 절대 할 수 없다. 이 기술들도 심도 깊게 공부를 하고 활용해봐야한다.
코치님들이 계속 강조하신 CS도 이미 배웠지만 시간이 지나 잘 기억이 나지 않으니 다시 공부하면 된다.
코틀린을 사용하는 동기들과 이야기하다 보니 코틀린도 굉장히 매력적인 언어인 것 같다. 코틀린도 공부해봐야지.</p>
<p>항해 전과 다른 점이 있다면 혼자 공부하다가도 막히면 도움을 요청할 다른 동기들과 코치님들이 생겼다는 게 가장 크지 않을까?
혼자가 아니니 무섭다고 덮어두고 외면할 필요가 없을 것 같다.</p>
<p>공부할 게 많으니 다소 막막한 감이 있지만 뭐 어때! 이 길을 선택한 건 감자니 감자가 해내야지!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[항해플러스 백엔드 7기] 시작하는 마음]]></title>
            <link>https://velog.io/@hi_potato/%ED%95%AD%ED%95%B4%ED%94%8C%EB%9F%AC%EC%8A%A4-%EB%B0%B1%EC%97%94%EB%93%9C-7%EA%B8%B0-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EB%A7%88%EC%9D%8C</link>
            <guid>https://velog.io/@hi_potato/%ED%95%AD%ED%95%B4%ED%94%8C%EB%9F%AC%EC%8A%A4-%EB%B0%B1%EC%97%94%EB%93%9C-7%EA%B8%B0-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EB%A7%88%EC%9D%8C</guid>
            <pubDate>Sat, 14 Dec 2024 06:20:51 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h1 id="항해-플러스-백엔드-7기">항해 플러스 백엔드 7기</h1>
</blockquote>
<h3 id="🪽-시작하는-마음">🪽 시작하는 마음</h3>
<h1 id="📌-지금까지의-회고">📌 지금까지의 회고</h1>
<p>어느덧 4년차에 다다르고 있는 감자의 풀스택 개발 커리어!!
그런데 이 길을 잘 향하고 있는가에 대한 대답은 <strong>&quot;잘 모르겠다&quot;</strong> 이다.</p>
<p>이커머스 SI 업체에서 SI 풀스택 개발자로 살아가기란 생각보다 고여있다는 생각이 많이 든다.
회사에서 사람도 고이고 만드는 기능과 코드도 다 고인다. 늘 같은 기능, 같은 방식으로 개발하고 고객사의 요구사항에 따라 조금씩 달라지는 형식...</p>
<p>좋은 코드가 아닌 동작만 되면 되는 코드를 무한 복사하는 느낌이다...</p>
<blockquote>
<p><strong>이대로 계속 이 곳에 만족하여 이 상태에 머물러 있다면 감자는 그렇게 썩어가지 않을까??</strong></p>
</blockquote>
<p>회사에서 여러번 소리를 냈으나 돌아오는 것은 새로운 기술이나 시스템이 아닌 고집 부리고 하라는 대로 안하고 목소리를 낸다는 듯한 표정, 까다롭다는 듯한 말투.</p>
<h4 id="정말-이대로-괜찮은-걸까">정말 이대로 괜찮은 걸까??</h4>
<h1 id="📌-항해-플러스-참여-계기">📌 항해 플러스 참여 계기</h1>
<p>감자가 속해있는 곳을 바꿀 수 없다면 그것은 감자의 능력, 지식 부족일 수도 있다.
감자가 머물러있는 곳을 바꿔야한다면 감자가 먼저 바뀌어야한다.
하지만 &quot;몸짱이 될거야!!&quot; 라고 등록한 헬스도 금방 그 때의 진심을 잃고 돈만 버리는 이 의지박약 감자가 어떻게 바뀔 수 있을까?</p>
<blockquote>
<h3 id="돈으로-의지를-사면-돼">돈으로 의지를 사면 돼!!!!!</h3>
</blockquote>
<p>헬스만 끊어선 운동을 안한다면 PT를 끊으면 된다!!
운동을 게을리하면 회원님 개인 운동 언제하세요?라고 감자를 끌고 나올 트레이너님을 필요로 한다 이 감자는!!!</p>
<p>그래서 늘 완강도 하고 TIL도 벨로그에 작성할거야!! 라며 야심차게 인프런 강의를 결제하나 1강이라도 들으면 다행인 감자의 선택은 <strong>항해 플러스 과정</strong>이었다.</p>
<p>여기서 팀원들을 위해서라도 기본은 하고 매니저님들과 코치님들을 통해 가장 효율적인 방향성을 찾아갈 수 있을 거라고 생각했다.</p>
<p><em>역시 돈이 최고야. 짜릿해.</em></p>
<h1 id="📌-향후-5년-뒤-커리어-방향성">📌 향후 5년 뒤 커리어 방향성</h1>
<p>일단 지금 재직하고 있는 회사에서 탈출하고 싶다.
감자는 새로워지고 싶다. 그렇다면 새로운 곳으로 가야하지 않을까?</p>
<p>동작만 되면 되는 코드가 아닌 좋은 코드를 위해 노력하는 개발자.
고객사의 요구사항에 의해 기존에 만든 설계를 부수고 시간에 쫓겨 다시 설계하는 것이 아니라 안정성과 확장성을 위해 꼼꼼하게 설계하는 개발자.</p>
<p>감자가 원하는 개발자는 그런 개발자이다.
감자의 꿈은 그런 것이었다.</p>
<p>이제 기본 경험을 익혔으니 꿈을 향해 나아갈 때라고 생각한다.</p>
<p>지금부터 탄탄히 공부하여 5년 뒤에는 감자가 원하는 개발자가 되어있을 것이다.</p>
<h1 id="📌-10주간의-목표">📌 10주간의 목표</h1>
<p>앞서 말했지만 감자는 의지박약이 심하다.
감자의 진심은 늘 한순간이고 흐지부지되는 경우가 많았다.</p>
<p>게으른 완벽주의자.
완벽하지 않다면 하고 싶지 않은 욕심때문에 끝을 보지 못한 일들이 많다.</p>
<p>최선을 다하려고 하면 늘 욕심이 앞서 감자를 망치는 거 같다.</p>
<p><strong>&quot;이번엔 진짜 잘해야지. 최선을 다 할거야. 근데 최선을 다 한다는 것은 어떻게 하는 거지? 아니 애초에 내가 최선을 다 한적이 있었나?&quot;</strong></p>
<p>그래서 생각을 고쳐 먹어보려고 한다.
최선을 다 하는 것이 아니라 <strong>그냥</strong> 해보고자 한다.</p>
<p>그냥 할 수 있는 걸 하는 거지...
너무 스트레스 받지 말고 너무 압박감에 스스로를 망치지 말고 일단 할 수 있는 것을 하자.</p>
<blockquote>
<p>한다는 거 자체가 중요하니깐!!
겁먹지 말고 스스로 무너지지 말자.</p>
</blockquote>
<h3 id="그냥-하자">그냥 하자!</h3>
<h1 id="📌-최종-목표-배지">📌 최종 목표 배지</h1>
<p>꿈은 크게 가지랬다.
그렇다면 당연히 과제 통과율 90퍼인 <strong>🖤블랙 배지🖤</strong> 아니겠는가!!!
으흐흐흐흐<del>~</del></p>
<p>하지만 감자의 10주 목표는 욕심 부리다가 자기 욕심에 무너지지 말자기 때문에 너무 매달리지 않으려고 한다.</p>
<p>사실 코딩테스트 스터디에서도 그냥 하자!! 했는데 마지막 레벨에 도달하지 않았던가!!!
저마다에게 맞는 방법이 있겠지만 땅꿀파기 장인인 감자에겐 그냥 하는 게 맞는 방법인듯 하니 &quot;하면 좋고 아니면 어쩔 수 없고~&quot; 하며 곁눈질만 해볼 생각이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[테스트 코드] Outro]]></title>
            <link>https://velog.io/@hi_potato/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-Outro</link>
            <guid>https://velog.io/@hi_potato/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-Outro</guid>
            <pubDate>Fri, 06 Dec 2024 13:42:36 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="practical-testing-실용적인-테스트-가이드">[Practical Testing: 실용적인 테스트 가이드]</h2>
</blockquote>
<h3 id="섹션-10-outro">섹션 10. Outro</h3>
<h1 id="📌-테스트를-작성하는-마음가짐">📌 테스트를 작성하는 마음가짐</h1>
<h2 id="📍-강의-정리">📍 강의 정리</h2>
<h3 id="1-테스트는-왜-필요할까">1. 테스트는 왜 필요할까?</h3>
<h4 id="1-테스트를-아예-작성하지-않는-경우">1) 테스트를 아예 작성하지 않는 경우</h4>
<p>빠르게 변화하는 소프트웨어의 품질을 일정 수준 이상으로 가져가기가 어려울 수 있다.
사람이 항상 모든 것을 테스트 해야 되는데 소프트웨어가 발전하는 속도보다 사람이 커버할 수 있는 속도와 리소스가 맞지 않기 때문에 기계에 힘을 빌려야 한다.</p>
<h4 id="2-테스트-코드를-작성하더라도-그-테스트-코드가-병목이-되는-경우">2) 테스트 코드를 작성하더라도 그 테스트 코드가 병목이 되는 경우</h4>
<p>테스트 코드를 엉망으로 작성한다면 테스트 코드 자체가 애물단지가 될 수 있다. 그래서 테스트 코드를 점차 작성하기 어려워지게 되고 결국은 안짜게 되는 그런 상황이 발생할 수 있다.
혹은 테스트를 잘못 작성하면 잘못된 검증을 하게 되거나 잘못되었는데 올바르다고 인식을 하고 넘어갈 수도 있다.</p>
<h3 id="2-단위-테스트">2. 단위 테스트</h3>
<ul>
<li>JUnit : 단위 테스트 도구</li>
<li>단위 테스트 : 작은 코드 단위를 독립적으로 테스트 하는 것.</li>
<li>가장 작은 레벨, 가장 작은 단위에서 풍부한 단위 테스트를 작성하는 것자체가 소프트웨어의 안정성을 보장하는 시작 단계</li>
</ul>
<h3 id="3-tdd">3. TDD</h3>
<p>프로덕션 코드보다 테스트 코드를 먼저 우선시 작성하여 테스트가 구현 과정을 주도하도록 하는 방법론 중에 하나이다.
외부에서 프로덕션 코드를 바라보는 클라이언트 관점에서 코드에 피드백을 줄 수 있다.</p>
<h3 id="4-테스트는-문서다">4. 테스트는 문서다.</h3>
<p>개인이 했던 고민의 결과물을 팀 차원의 지식으로 승격을 시키는 것이 중요하다.</p>
<h3 id="5-spring--jpa-기반-테스트">5. Spring &amp; JPA 기반 테스트</h3>
<h4 id="레이어드-아키텍처">레이어드 아키텍처</h4>
<p>레이어별 관심사가 다르기 때문에 레이어가 나눠지게 되었고 그에 맞추어서 테스트가 필요하다.</p>
<h4 id="통합-테스트">통합 테스트</h4>
<p>두 가지 이상의 클래스나 혹은 듈이 결합했을 때의 시너지가 어떻게 날지 예측하기 어려울 수 있기 때문에 통합 테스트를 통해서 단위 테스트로 다 커버하지 못하는 부분을 보장 해줘야 된다.</p>
<h3 id="6-mock을-대하는-자세">6. Mock을 대하는 자세</h3>
<ul>
<li>Mock : 테스트 더블, 대역</li>
<li>Stubbing : 가짜 행위를 정의하는 것</li>
<li>Mockito : Mock 프레임워크</li>
<li>클래시스트 vs 머키스트</li>
</ul>
<h3 id="7-더-나은-테스트를-작성하기-위한-구체적-조언">7. 더 나은 테스트를 작성하기 위한 구체적 조언</h3>
<ul>
<li>한 문단에 한 주제 ➡ 한 테스트에 한 가지 목적의 검증만 수행</li>
<li>제어할 수 없는 값/환경에 대한 것들은 배제하고 제어할 수 있는 값들로만 테스트 대역을 만들거나 제어하기 어려운 외부 시스템같은 것들은 Mocking 처리를 한다.</li>
<li>테스트 환경의 독립성을 보장하자.</li>
<li>테스트 간 의존관계를 갖지 말자.</li>
<li>Test Fixture - given절에 작성하는 테스트 대역들과 테스트 내용과 직접적인 관련이 없는 세팅은 setup절에서 구성하면 좋다.</li>
<li>Test Fixture 클렌징 - deleteAllInBatch() / deleteAll() / @Transactional</li>
<li>@ParameterizedTest - 다중 케이스가 필요한 경우</li>
<li>@DynamicTest - 상태 공유가 필요한 시나리오 작성이 필요한 경우</li>
<li>테스트 수행하는 것도 비용이다. ➡ 공통된 환경을 모아서 환경 통합하기</li>
<li>private method의 테스트는 할 필요가 없다.</li>
<li>프로덕션에 없는 메서드지만 테스트에서 필요해서 만들고 싶을 때는 고민을 해봐야한다.</li>
</ul>
<h3 id="8-appendix">8. Appendix</h3>
<ul>
<li>학습 테스트 : 작성하지 않은 코드 (ex 라이브러리, 프레임워크)를 재밌게 학습하기 위한 방법</li>
<li>Spring REST Docs : 테스트 코드를 통한 문서 자동화 도구 중에 하나</li>
</ul>
<h2 id="📍-테스트-작성을-방해하는-것">📍 테스트 작성을 방해하는 것?</h2>
<p align="center">
<img src="https://velog.velcdn.com/images/hi_potato/post/85c82c9b-232b-4ce8-a131-c86e49ed9b7d/image.png" width="30%">
</p>
<h2 style="text-align:center;">시간</h2>

<p>비즈니스에선 시간이라는 축이 있다.</p>
<p>그래서 항상 한정된 시간 안에서 무언가를 만들어내야 된다.
이런 한정된 시간 내에서 올바른 테스트를 작성하려면 어떻게 해야할까?</p>
<blockquote>
<p><strong>1. 테스트 케이스를 추론하고 구체화 시키는 연습이 많이 필요하다.
2. TDD가 손에 익도록 많은 연습이 필요하다.</strong></p>
</blockquote>
<p>시간의 압박이 있는 경우에 당장 눈앞에 놓인 요구사항에 매몰되어서 프로덕션 코드를 작성하기 쉽다.</p>
<p>근데 잠깐 키보드에서 손을 떼고 숨을 잠시 고르고 어떤 케이스가 있어야 지금 작성하려는 프로덕션 코드가 더 단단해질까? 어떤 케이스로 검증을 하면 좋을까?를 고민을 해봐야 된다.</p>
<p>그리고 그 케이스들이 정리가 되었다면 빠르고 정확하게 문서로서의 테스트를 작성하고 프로덕션 코드를 그에 맞춰서 구현을 해야 된다.</p>
<h2 id="📍-타협하지-않는-마음">📍 타협하지 않는 마음</h2>
<blockquote>
<p><strong>가까이 보면 느리지만, 멀리 보면 가장 빠르다.</strong></p>
</blockquote>
<p>테스트를 작성하는 귀찮은 마음과 시간적인 압박이 있더라도 지금 시간을 30분, 1시간 더 투자해서 테스트를 작성하는 게 나중에 3시간, 10시간 또는 하루 더 수 많은 시간을 아낄 수 있다.</p>
<hr>

<blockquote>
<h3 id="📑-출처">📑 출처</h3>
</blockquote>
<ul>
<li>[Practical Testing: 실용적인 테스트 가이드]  (인프런/박우빈)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[테스트 코드] Appendix]]></title>
            <link>https://velog.io/@hi_potato/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-Appendix</link>
            <guid>https://velog.io/@hi_potato/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-Appendix</guid>
            <pubDate>Fri, 06 Dec 2024 13:20:52 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="practical-testing-실용적인-테스트-가이드">[Practical Testing: 실용적인 테스트 가이드]</h2>
</blockquote>
<h3 id="섹션-9-appendix">섹션 9. Appendix</h3>
<h1 id="📌-학습-테스트">📌 학습 테스트</h1>
<ul>
<li>잘 모르는 기능, 라이브러리, 프레임워크를 학습하기 위해 작성하는 테스트</li>
<li>여러 테스트 케이스를 스스로 정의하고 검증하는 과정을 통해 보다 구체적인 동작과 기능을 학습할 수 있다.</li>
<li>관련 문서만 읽는 것보다 훨씬 재미있게 학습할 수 있다. </li>
</ul>
<h2 id="📍-guava">📍 Guava</h2>
<p>구글에서 오픈소스로 제공하는 라이브러리.</p>
<blockquote>
<p>📑 공식문서 : <a href="https://github.com/google/guava">https://github.com/google/guava</a></p>
</blockquote>
<pre><code class="language-java">// Guava 의존성 주입
implementation(&quot;com.google.guava:guava:33.3.1-jre&quot;)</code></pre>
<h1 id="📌-spring-rest-docs">📌 Spring REST Docs</h1>
<p>API 문서를 만들 수 있는 도구들 중 하나.
구현한 API를 문서로 만들고 싶다! 혹은 API를 만들기 전에 명세하고 싶다! 할 때 사용한다.</p>
<ul>
<li>테스트 코드를 통한 API 문서 자동화 도구</li>
<li>API 명세를 문서로 만들고 외부에 제공함으로써 협업을 원활하게 한다.</li>
<li>기본적으로 AsciiDoc을 사용하여 문서를 작성한다.</li>
</ul>
<blockquote>
<h3 id="asciidoctor">AsciiDoctor</h3>
<p>AsciiDoc 문법을 html로 변환해주는 사이트
<a href="https://asciidoctor.org/">https://asciidoctor.org/</a></p>
</blockquote>
<h2 id="📍-rest-docs">📍 REST Docs</h2>
<h3 id="장점">장점</h3>
<ul>
<li>테스트를 통과해야 문서가 만들어진다. (신뢰도가 높다.)</li>
<li>프로덕션 코드에 비침투적이다.</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li>코드 양이 많다.</li>
<li>설정이 어렵다.</li>
</ul>
<h2 id="📍-swagger">📍 Swagger</h2>
<h3 id="장점-1">장점</h3>
<ul>
<li>적용이 쉽다.</li>
<li>문서에서 바로 API 호출을 수행해볼 수 있다.</li>
</ul>
<h3 id="단점-1">단점</h3>
<ul>
<li>프로덕션 코드에 침투적이다. (어노테이션들을 Controller에 달아서 문서를 작성하게 되는데 이로 인해 프로덕션 코드가 지저분해질 수 있다.)</li>
<li>테스트와 무관하기 때문에 신뢰도가 떨어질 수 있다.</li>
</ul>
<h2 id="📍-sts에서-docs가-생성된-파일이-안보인다면">📍 STS에서 docs가 생성된 파일이 안보인다면</h2>
<p>Package Explorer &gt; Filters... &gt; Gradle build folder 체크 해제 &gt; OK</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/87df056a-fb84-4ae1-92da-72e810b45adb/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/f3808a91-ce02-4905-9dfc-7af6036854fb/image.png" alt=""></p>
<hr>

<blockquote>
<h3 id="📑-출처">📑 출처</h3>
</blockquote>
<ul>
<li>[Practical Testing: 실용적인 테스트 가이드]  (인프런/박우빈)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[99클럽 코테 스터디] 35일동안의 여정을 마치며]]></title>
            <link>https://velog.io/@hi_potato/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-35%EC%9D%BC%EB%8F%99%EC%95%88%EC%9D%98-%EC%97%AC%EC%A0%95%EC%9D%84-%EB%A7%88%EC%B9%98%EB%A9%B0</link>
            <guid>https://velog.io/@hi_potato/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-35%EC%9D%BC%EB%8F%99%EC%95%88%EC%9D%98-%EC%97%AC%EC%A0%95%EC%9D%84-%EB%A7%88%EC%B9%98%EB%A9%B0</guid>
            <pubDate>Mon, 02 Dec 2024 14:38:14 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="99클럽-코테-스터디-후기">99클럽 코테 스터디 후기</h2>
</blockquote>
<h3 id="35일동안의-여정을-마치며">35일동안의 여정을 마치며</h3>
<h4 id="20241028--20241201">2024.10.28. ~ 2024.12.01.</h4>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/468c7375-38b3-4137-90b9-c7fc8ce269cb/image.png" alt=""></p>
<p>끝나지 않을 것 같던 코딩 스터디 또한 끝이 났다.</p>
<h3 id="1-신청-이유">1. 신청 이유</h3>
<p>코딩 테스트... 애증의 코딩 테스트...!!!
정말 공부하면서도 이게 뭐지... 어떻게 공부해야하는 거지... 얼마나 더 해야하는 거지... 하고 낙담하기 쉽다.</p>
<p>웃긴 게 생각보다 감자의 실무와 많은 차이가 나기때문에 코딩 테스트 실력과 관계없이 일을 하고 있다. 그런데 취업과 이직을 위해선 코딩 테스트가 필수라니요?</p>
<p>감자는 코딩테스트가 무섭다.
어느정도 하면 &quot;적당한&quot; 실력을 갖게 되는 건지 답이 없기 때문이다.
아니 애초에 코딩에 적당하다는 것 자체가 없다.
코딩테스트를 풀이하는 방법조차 정답이 없다.</p>
<p>알고리즘에 취약한 감자는 코딩테스트 스터디가 있다는 말에 부리나케 신청했다.
레벨은 &quot;비기너&quot;, &quot;미들러&quot;, &quot;첼린저&quot;.
첼린저는 확실히 아니다. 그렇다면 비기너와 미들러.
나는 지금 어디에 있지??</p>
<p>신청하는 단계에서 가장 오래 걸린 것은 레벨을 선택하는 것이었다.
나름 실무자인데 미들러...?
기초부터 탄탄하게 비기너...??
감자는 코딩테스트가 무섭다.</p>
<p>비기너를 선택한 것은 다행이면서도 후회스러운 선택이었다.</p>
<h3 id="2-스터디-방법">2. 스터디 방법</h3>
<p>안타깝게도 스터디가 끝난지 하루가 되자마자 LMS에 접속이 되지 않아 캡쳐본은 없다...</p>
<p>항해99의 LMS에 접속해서 문제 풀기를 누르면 타이머가 돌아가면서 새탭으로 문제 사이트가 뜬다.
문제 사이트는 프로그래머스, 백준, 리트코드이다.
그러다보니 이미 감자가 푼 문제가 나오기도 했다.</p>
<p>문제 풀이 권장 시간은 비기너는 주로 30분, 미들러는 40~60분 정도였다. (첼린저는 모르겠다...)</p>
<p>권장 시간 안에 문제 풀이 인증 캡쳐본을 제출하고 <em>(물론 권장 시간은 초기화도 가능하며 초과해도 제출이 가능하다)</em> 해당 문제 풀이에 대한 글을 블로그나 노션에 올려 해당 링크로 TIL 인증까지 하면 일일 미션은 완료된다. (TIL 인증은 선택)</p>
<p>그리고 매주 목요일 8시에서 10시까지 디스코드에서 레벨별로 보너스 문제 공개 및 풀이 시간을 갖고 특강을 해주신다.
비기너는 풀이 권장 시간이 적기 때문에 주로 8시에서 9시까지만 진행한다.</p>
<h3 id="3-좋았던-점">3. 좋았던 점</h3>
<h4 id="1-공부하는-습관-생성">1. 공부하는 습관 생성</h4>
<p>항해99에서 진행했던 <a href="https://velog.io/@hi_potato/%EC%8A%A4%ED%82%AC%EC%97%85Docker%EA%B8%B0%EB%B0%98-CICD-%ED%8C%8C%EC%9D%B4%ED%94%84%EB%9D%BC%EC%9D%B8-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0-%ED%9B%84%EA%B8%B0">Docker 스터디</a>에서도 좋았던 점이지만 차이점이 있다면 Docker 스터디는 일주일에 정해진 분량을 채우면 되는 거라서 한번에 몰아서가 가능하지만 코딩 스터디는 매일 인증을 해야하기때문에 정말 매.일.매.일. 공부를 한다는 것이다.
주말까지 인증해야하다보니 약속이 끝난 밤 늦은 시간에 앉아서 미션을 진행하곤 했지만 덕분에 인증할 미션이 없으니 이렇게 앉아서 후기라도 작성하게 만들 정도로 사람을 부지런하게 만들었다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/f66e0c85-0ef4-4db8-8256-7baba1314c34/image.png" alt=""></p>
<p>TIL을 작성해놓고 링크 공유 안해서 TIL이 두개 부족한 걸로 나온다...🥲</p>
<h4 id="2-정기-특강-녹화본-제공">2. 정기 특강 녹화본 제공</h4>
<p>매주 목요일 8시에 참가할 수 있는가!
가능은 하겠지만 야근과 회식과 약속이 도사리고 있는 바쁘다 바빠 현대사회인은 확신할 수 없다.
그리고 나는 비기너지만 미들러의 특강을 보고 싶다?!
그렇다면 녹화본을 통해 보충할 수 있는 것이다.</p>
<h4 id="3-다양한-이벤트">3. 다양한 이벤트</h4>
<p>인증한 문제 수와 제출한 TIL 수에 따라 알이 성장하는 작은 육아 시물레이션(?)이 있는데 이 알이 얼마나 부화했느냐에 따라 보상이 있었다.</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/cc041635-9ed6-4510-bfbf-4636bd18cf99/image.png" alt=""></p>
<p>그리고 디스코드에서 다양한 이벤트도 진행을 했다.
할로윈 기념 으쓱한 실수 경험담 푸는 이벤트, 알에서 무엇이 부화할지 예상하는 이벤트, 빼빼로데이 기념 11줄 혹은 121줄로 문제 풀어보는 이벤트 등 다양했다.
여기서 당첨되는 경우에는 네이버페이 포인트나 TIL 면제권 등을 받을 수 있다.</p>
<p>참고로 감자는 당첨되어서 네이버페이 5천원 받았다.
<img src="https://velog.velcdn.com/images/hi_potato/post/fc0b4862-f34e-4d8a-a7c2-f9b877f37173/image.png" alt=""></p>
<p>앗싸❗</p>
<h3 id="4-아쉬웠던-점">4. 아쉬웠던 점</h3>
<h4 id="1-감자에게만-적용되는-다소-쉬운-문제-난이도">1. (감자에게만 적용되는) 다소 쉬운 문제 난이도</h4>
<p>감자가 너무 쫄았나보다.
비기너의 문제는 대부분 자료구조에 가깝고 알고리즘이랄게 없어서 문제 풀고 TIL까지 작성하는게 30분만에 끝난 적이 많았다.</p>
<p>안쓰던 자료구조들을 접하게 되니 반갑고 재밌긴한데 머리 쓴다는 느낌이 안들었다.
감자는 비기너를 갔어야 했나 싶다가도
초반엔 Docker 스터디와 겹치기도 했고 후반엔 항해플러스 사전스터디와 겹친지라 이보다 문제가 어려웠다면 시간적/정신적 여유가 너무 없었으리라 싶다.</p>
<h4 id="2-반복되는-문제-유형">2. 반복되는 문제 유형</h4>
<p>10월 31일에 단체 카톡에 이렇게 의견을 주신 분이 계셨다.
<img src="https://velog.velcdn.com/images/hi_potato/post/589d235b-5b70-48f8-9e9a-74d2c461e0e4/image.png" alt=""></p>
<p>네오님의 생각 = 감자의 생각
코테 스터디를 시작한지 얼마 안되었는데 벌써 3일 내내 너무 비슷한 거 아냐? 싶었다.
근데 그 뒤로 비기너/미들러분들이 자신들은 만족한다고 의견을 내주셔서 첼린저만 알고리즘을 더 다양하게 내는 걸로 변경되고 비기너/미들러는 유지되었다.</p>
<p>덕분에 감자는 전날 TIL에서 코드를 베껴와 약간만 수정하면 되는 날이 꽤 있었다.
(그래서 문제 풀이+TIL 작성이 30분도 안걸리는 날이 많았던 거 같다.)</p>
<p>비기너가 끝나면 미들러가 될 수 있는 정도로 다양한 알고리즘과 난이도를 겪어봐야한다고 생각하는데 이정도면 비기너 끝난다고 미들러 못하지 않을까 싶었다...
자료구조만 확실하게 조지고 가는 느낌?</p>
<h4 id="3-시간에-쫓기는-특강들">3. 시간에 쫓기는 특강들</h4>
<p>정기 특강은 8시에 시작하여 다 같이 보너스 문제를 푼다.
8시반부터 비기너 특강이 시작되고 9시부터 미들러 특강이 시작되는데 특강을 해주는 클럽장님이 한분이다보니 이리저리 디스코드 방을 이동하기도 하고 시간안에 설명과 QnA를 맞추려고 헐레벌떡 마무리하는 경우가 많았다.</p>
<p>정기 특강 외 특강도 목요일 7시부터 시작한 경우가 있었는데 디스코드에 문제가 생겨 다소 늦게 시작했더니 8시안에 끝내려고 특강을 속사포로 진행하시고 준비해온 내용을 다 알려주지 못했다고 못내 아쉬워하며 정리하셨다.</p>
<p>계속 시간에 쫓겨 도망가듯이 공부를 하게 되니 약간의 스트레스가 생기는 것은 어쩔 수 없었다.</p>
<h3 id="5-배웠던-것들">5. 배웠던 것들</h3>
<p>Hash, Stack, Queue, Heap 등등...
자료구조 진짜 오랜만이었다!!
사실 실무에선 많이 안쓰는 녀석들이었는데 항해99 코테 스터디 덕분에 대학생 시절로 돌아간 느낌이었다.</p>
<p>그리고 코테 문제들에 적혀 있는 조건들...
반례때문에 실패를 하게 되면 아 이런 케이스도 있겠구나 하고 뒷통수를 맞은 느낌이었다. 매일 더 다양한 시점에서 문제를 보려 노력했다.
문제 조건들 중 시간 제한이 제일 무서웠다ㅠㅠ 널 어떻게 해야 빠르게 만들 수 있을까...!!!!
그래도 덕분에 더 빠르고 정확한 코드는 무엇일까 열심히 고민해봤다!!</p>
<h3 id="6-마지막으로">6. 마지막으로</h3>
<p>이야~ 35일 은근 빠르잖아?!
일주일은 긴데 35일은 빠르다!</p>
<p>시작은</p>
<blockquote>
<p>시작하기 전에는 내가 매일매일 인증할 수 있을까?
35개 전부는 아니더라도 최대한 해보자!!</p>
</blockquote>
<p>였는데
감자의 욕심은 끝이 없었고 캘린더를 어떻게든 빨간색으로 꽉꽉 채우려고 회식 후에도 달려와서 앉게 되었다...ㅎ</p>
<h4 id="나-꽤나-갓생살고-있는-거였을지도-ㅋㅋㅋㅋㅋㅋ">나 꽤나 갓생살고 있는 거였을지도? ㅋㅋㅋㅋㅋㅋ</h4>
<p>시간적/정신적 여유가 되면 미들러 문제도 같이 풀어보고 TIL을 작성하고 싶었는데 너무 욕심이었나보다.
Docker 스터디와 항해플러스 사전스터디를 병행하면서 두개를 하기엔 시간이 되어도 체력이 안되고 체력이 되면 다른 일정이 생겼다.<em><del>(다 핑계)</del></em></p>
<p>그래도 문제 내역들이 있으니 여유가 될 때 풀어보거나 아님 다시 코테 스터디를 미들러로 신청해봐도 되지 않을까?!</p>
<p>누군가가 추천하냐고 한다면 매우 <span style="color:red;"><strong>YES!!!!!!!!!!!!!!</strong></span>
감자도 다시 신청할 의향이 있다!!!!!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[테스트 코드] 더 나은 테스트를 작성하기 위한 구체적 조언]]></title>
            <link>https://velog.io/@hi_potato/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EB%8D%94-%EB%82%98%EC%9D%80-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%A5%BC-%EC%9E%91%EC%84%B1%ED%95%98%EA%B8%B0-%EC%9C%84%ED%95%9C-%EA%B5%AC%EC%B2%B4%EC%A0%81-%EC%A1%B0%EC%96%B8</link>
            <guid>https://velog.io/@hi_potato/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EB%8D%94-%EB%82%98%EC%9D%80-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%A5%BC-%EC%9E%91%EC%84%B1%ED%95%98%EA%B8%B0-%EC%9C%84%ED%95%9C-%EA%B5%AC%EC%B2%B4%EC%A0%81-%EC%A1%B0%EC%96%B8</guid>
            <pubDate>Sun, 01 Dec 2024 15:11:37 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="practical-testing-실용적인-테스트-가이드">[Practical Testing: 실용적인 테스트 가이드]</h2>
</blockquote>
<h3 id="섹션-8-더-나은-테스트를-작성하기-위한-구체적-조언">섹션 8. 더 나은 테스트를 작성하기 위한 구체적 조언</h3>
<h1 id="📌-한-문단에-한-주제">📌 한 문단에 한 주제!</h1>
<p>한 문단에는 주제가 너무 다양하거나 여러개이면 안되고 주제가 명확하지 않으면 안된다. ➡ <strong>한 문단에는 단 한가지의 주제만 있어야 한다.</strong></p>
<p>테스트는 문서로서의 기능을 한다.</p>
<p>테스트 코드라는 것을 글쓰기의 관점에서 봤을 때 하나의 테스트가 한 문단이라고 생각을 해보면 하나의 테스트는 하나의 주젬나을 가져야된다라는 원칙이 동일하게 적용될 수 있다.</p>
<h1 id="📌-완벽하게-제어하기">📌 완벽하게 제어하기</h1>
<p>테스트를 하기 위한 환경을 조성할 때 모든 조건을 완벽하게 제어할 수 있어야 한다.</p>
<blockquote>
<p>예시 🎈 <a href="https://velog.io/@hi_potato/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EB%8B%A8%EC%9C%84%ED%85%8C%EC%8A%A4%ED%8A%B8">단위테스트 &gt; 테스트하기 어려운 영역을 구분하고 분리하기</a></p>
</blockquote>
<h1 id="📌-테스트-환경의-독립성을-보장하자">📌 테스트 환경의 독립성을 보장하자</h1>
<p>대부분 given절에서 테스트 행위를 하기 위해 그 이전 준비 과정들을 만든다. 이런 테스트 환경에서 다른 API를 사용하다보면 테스트간 결합도가 생기는 케이스가 발생할 수 있다. <strong>하나의 테스트 내에서의 독립성을 보장하자.</strong></p>
<h1 id="📌-테스트-간-독립성을-보장하자">📌 테스트 간 독립성을 보장하자</h1>
<p><strong>두 개 이상의 테스트에 대한 독립성</strong>을 보장하자.</p>
<p>테스트 간에 순서가 없어야 하며 무관해야 한다. 각각 독립적으로 언제 수행되든 항상 같은 결과를 내야 된다. 그러므로 테스트 간 공유 자원을 사용하지 않아야 된다.</p>
<h1 id="📌-한-눈에-들어오는-test-fixture-구성하기">📌 한 눈에 들어오는 Test Fixture 구성하기</h1>
<ul>
<li>Fixture : 고정물, 고정되어 있는 물체
테스트를 위해 원하는 상태로 고정시킨 일련의 객체</li>
<li>Test Fixture : given절에서 생성했던 모든 객체들을 의미
(테스트 목적, 환경을 위해서 원하는 상태 값으로 고정시킨 객체)</li>
</ul>
<pre><code class="language-java">@BeforeEach
void setUp() {
   // before method

   // 각 테스트 입장에서 봤을 때 : 아예 몰라도 테스트 내용을 이해하는 데에 문제가 없는가?
   // 수정해도 모든 테스트에 영향을 주지 않는가?
   // 위의 질문에 만족한 Test Fixture 여기에 존재해도 된다.
}</code></pre>
<h1 id="📌-test-fixture-클렌징">📌 Test Fixture 클렌징</h1>
<pre><code class="language-java">orderRepository.deleteAll();
orderRepository.deleteAllInBatch();</code></pre>
<h2 id="📍-deleteallinbatch">📍 deleteAllInBatch()</h2>
<p>테이블을 전부 삭제 (Delete From)
순서를 고려해야 한다. Foreign Key(외래키)같은 조건을 가지고 있는 테이블을 먼저 지워야 한다.</p>
<h2 id="📍-deleteall">📍 deleteAll()</h2>
<p>연관관계가 있는 테이블을 전체 Select 한 다음 데이터 건당 삭제 처리
모든 연관관계를 확인하고 하나씩 지우기 때문에 성능상 이슈 발생 가능</p>
<h2 id="📍-transactional">📍 @Transactional</h2>
<p>부작용만 잘 고려하면 롤백 클랜징이 잘 작동된다.
트랜잭션이 여러개 걸리면 트랜잭션 롤백을 사용하기 어렵다. Spring Batch 등을 사용한 배치 통합 테스트 시 여러 트랜잭션 경계가 참여한다.</p>
<h1 id="📌-parameterizedtest">📌 @ParameterizedTest</h1>
<pre><code class="language-java">@DisplayName(&quot;상품 타입이 재고 관련 타입인지를 체크한다.&quot;)
@Test
void containsStockType3() {
    // given
    ProductType givenType1 = ProductType.HANDMADE;
    ProductType givenType2 = ProductType.BOTTLE;
    ProductType givenType3 = ProductType.BAKERY;

    // when
    boolean result1 = ProductType.containsStockType(givenType1);
    boolean result2 = ProductType.containsStockType(givenType2);
    boolean result3 = ProductType.containsStockType(givenType3);

    // then
    assertThat(result1).isFalse();
    assertThat(result2).isTrue();
    assertThat(result3).isTrue();
}</code></pre>
<p><code>ProductType</code>에 대해서 체크 매소드를 확인해보고 싶다.</p>
<p>핸드메이드일 때는 재고와 관련된 타입이 아니기 때문에 <code>false</code>가 나올 것이고 병음료나 베이커리 같은 경우에는 <code>true</code>가 나올 것이다.</p>
<p>하나의 케이스에서 값만 변경하여 모든 상황을 체크하고 싶은 상황에서 활용할 수 있는 게 <code>@ParameterizedTest</code>이다.</p>
<pre><code class="language-java">@DisplayName(&quot;상품 타입이 재고 관련 타입인지를 체크한다.&quot;)
@CsvSource({&quot;HANDMADE,false&quot;,&quot;BOTTLE,true&quot;,&quot;BAKERY,true&quot;})
@ParameterizedTest
void containsStockType4(ProductType productType, boolean expected) {
    // when
    boolean result = ProductType.containsStockType(productType);

    // then
    assertThat(result).isEqualTo(expected);
}</code></pre>
<p>Csv로 데이터값과 결과값을 넣어줄 수 있다.</p>
<pre><code class="language-java">private static Stream&lt;Arguments&gt; provideProductTypesForCheckingStockType() {
    return Stream.of(
        Arguments.of(ProductType.HANDMADE, false),
        Arguments.of(ProductType.BOTTLE, true),
        Arguments.of(ProductType.BAKERY, true)
    );
}

@DisplayName(&quot;상품 타입이 재고 관련 타입인지를 체크한다.&quot;)
@MethodSource(&quot;provideProductTypesForCheckingStockType&quot;)
@ParameterizedTest
void containsStockType5(ProductType productType, boolean expected) {
    // when
    boolean result = ProductType.containsStockType(productType);

    // then
    assertThat(result).isEqualTo(expected);
}</code></pre>
<p>혹은 매서드를 생성하여 사용할 수 있다.</p>
<blockquote>
<h4 id="📑-parameterizedtest-공식-문서">📑 @ParameterizedTest 공식 문서</h4>
<p><a href="https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests">https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests</a></p>
</blockquote>
<h1 id="📌-dynamictest">📌 @DynamicTest</h1>
<p>여러 테스트들이 하나의 공유변수를 사용하여 테스틑 하는 것을 지양할 필요가 있다. 테스트 간에 순서가 생기고 서로 강결합 형태가 되기 때문에 독립성이 보장되지 않기 때문이다.</p>
<p>그럼에도 불구하고 어떤 하나의 환경을 설정해놓고 이 환경에 변화를 주면서 사용자 시나리오를 테스트하고 싶다면 <code>@DynamicTest</code>를 사용하는 것이 좋다.</p>
<pre><code class="language-java">@DisplayName(&quot;&quot;)
@TestFactory
Collection&lt;DynamicTest&gt; dynamicTest() {

    return List.of(
        DynamicTest.dynamicTest(&quot;&quot;, () -&gt; {

        }),
           DynamicTest.dynamicTest(&quot;&quot;, () -&gt; {

        })
    );
}</code></pre>
<h1 id="📌-테스트-수행도-비용이다-환경-통합하기">📌 테스트 수행도 비용이다. 환경 통합하기</h1>
<p>테스트는 사람이 수동으로 검증하는 것대신 기계의 도움을 받아서 수시로 피드백을 받고 프로덕션 코드를 발전시켜 나갈 수 있는 도구이다.</p>
<p>이 테스트 자체를 자주 수행하려면 테스트가 수행되는 시간 같은 것들이 전부 비용이기 때문에 관리가 필요하다.</p>
<pre><code class="language-java">@ActiveProfiles(&quot;test&quot;)
@SpringBootTest
class OrderServiceTest {

...

class OrderServiceTest extends IntegrationTestSupport {</code></pre>
<p>서버의 공통적인 환경을 하나의 추상 클래스로 만들어서 상속 및 관리하면 서버가 뜨는 횟수가 줄어든다.</p>
<h1 id="📌-q-private-메서드의-테스트는-어떻게-하나요">📌 Q. private 메서드의 테스트는 어떻게 하나요?</h1>
<blockquote>
<h3 id="a-할-필요가-없다">A. 할 필요가 없다!</h3>
<p>어차피 하려고 해도 안된다!</p>
</blockquote>
<p>private 메서드를 테스트하고 싶은 시점에 <strong>&quot;객체를 분리할 시점인가?&quot;</strong> 라는 질문을 던져봐야 한다.</p>
<p>public 메서드를 테스트 하면서 private 메서드도 함께 검증이 된다. public 메서드를 테스트하면서 private 메서드도 함께 검증이 되는 게 맞는가?라는 의문이 들면 객체를 분리할 시점인지 고민해보면 된다. public 메서드의 책임과 private 메서드의 책임을 별개로 보고 다른 클래스로 분리해야 한다.</p>
<h1 id="📌-테스트에서만-필요한-메서드가-생겼는데-프로덕션-코드에서는-필요-없다면">📌 테스트에서만 필요한 메서드가 생겼는데 프로덕션 코드에서는 필요 없다면?</h1>
<blockquote>
<h3 id="a-만들어도-된다-하지만-보수적으로-접근하기">A. 만들어도 된다. 하지만 &quot;보수적으로&quot; 접근하기!</h3>
</blockquote>
<p>테스트에서 꼭 사용해야만 할 것 같은 메소드들은 만들어도 된다.</p>
<p>테스트에서만 사용되는 메소드를 막 만들어내는 것은 지양해야 한다. 무엇을 테스트하고 있는지를 명확히 인지를 해야 한다.</p>
<hr>

<blockquote>
<h3 id="📑-출처">📑 출처</h3>
</blockquote>
<ul>
<li>[Practical Testing: 실용적인 테스트 가이드]  (인프런/박우빈)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[99클럽 코테 스터디 35일차 TIL] 프로그래머스 숫자 짝꿍]]></title>
            <link>https://velog.io/@hi_potato/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-35%EC%9D%BC%EC%B0%A8-TIL-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%88%AB%EC%9E%90-%EC%A7%9D%EA%BF%8D</link>
            <guid>https://velog.io/@hi_potato/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-35%EC%9D%BC%EC%B0%A8-TIL-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%88%AB%EC%9E%90-%EC%A7%9D%EA%BF%8D</guid>
            <pubDate>Sun, 01 Dec 2024 10:57:40 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="99클럽-코테-스터디-35일차-til">99클럽 코테 스터디 35일차 TIL</h2>
</blockquote>
<h3 id="💙-java-비기너">💙 JAVA 비기너</h3>
<h3 id="📌-오늘의-학습-키워드">📌 오늘의 학습 키워드</h3>
<ul>
<li>문자열</li>
</ul>
<h3 id="📌-공부한-내용">📌 공부한 내용</h3>
<h4 id="📍-오늘의-문제">📍 오늘의 문제</h4>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/5cf6f76a-ef61-404c-9b97-d29b6a449217/image.png" alt=""></p>
<h4 id="📍-작성-코드">📍 작성 코드</h4>
<pre><code class="language-java">class Solution {
    public String solution(String X, String Y) {
        StringBuilder answer = new StringBuilder();

        int[] xCntArr = new int[10];
        int[] yCntArr = new int[10];

        for(int i=0; i&lt;X.length(); i++) {
            xCntArr[X.charAt(i) - &#39;0&#39;] += 1;
        }

        for(int i=0; i&lt;Y.length(); i++) {
            yCntArr[Y.charAt(i) - &#39;0&#39;] += 1;
        }

        for(int i=9; i&gt;=0; i--) {
            int N = Math.min(xCntArr[i], yCntArr[i]);
            for(int j=0; j&lt;N; j++) {
                answer.append(i);
            }
        }

        if(&quot;&quot;.equals(answer.toString())) {
            return &quot;-1&quot;;
        } else if(&#39;0&#39; == (answer.toString().charAt(0))) {
            return &quot;0&quot;;
        } else return answer.toString();

    }
}</code></pre>
<h3 id="📌-오늘의-회고">📌 오늘의 회고</h3>
<p>몇번이나 실패했는지...!!!!
처음에는 단순하게 이중for문을 통해 하나하나 비교하도록 만들었다.</p>
<h4 id="📍-실패한-첫번째-코드">📍 실패한 첫번째 코드</h4>
<pre><code class="language-java">class Solution {
    public String solution(String X, String Y) {
        String answer = &quot;&quot;;

        String[] xArr = X.split(&quot;&quot;);
        String[] yArr = Y.split(&quot;&quot;);
        ArrayList&lt;Integer&gt; answerList = new ArrayList&lt;&gt;();

        for(int i=0; i&lt;xArr.length; i++) {
            for(int j=0; j&lt;yArr.length; j++) {
                if(xArr[i].equals(yArr[j])) {
                    answerList.add(Integer.parseInt(xArr[i]));
                    yArr[j] = &quot;x&quot;;
                    break;
                }
            }
        }

        answerList.sort(Comparator.reverseOrder());

        if(answerList.isEmpty()) {
            answer = &quot;-1&quot;;
        } else {
             boolean first = true;
            for(int num : answerList) {
                answer += num;
                if(first == true &amp;&amp; num == 0) {
                    break;
                } else if(first == true) {
                    first = false;
                }
            }
        }

        return answer;
    }
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/5c452dc0-1856-49ea-aa6d-3e1b2d22f8a7/image.png" alt=""></p>
<p>하지만 시간초과로 실패...</p>
<p>그 뒤로 StringBuilder로 바꿔보기도 하고 다양한 방법을 시도해봤으나 계속 실패였다...</p>
<p>HashMap을 사용해서 같은 숫자 수를 저장할까? 고민하다가 <strong>배열</strong>로 하면 안되나? 싶어서 만들어본 두번째 코드</p>
<h4 id="📍-실패한-두번째-코드">📍 실패한 두번째 코드</h4>
<pre><code class="language-java">class Solution {
    public String solution(String X, String Y) {
        String answer = &quot;&quot;;

        int[] xCntArr = new int[10];
        int[] yCntArr = new int[10];

        for(int i=0; i&lt;X.length(); i++) {
            xCntArr[X.charAt(i) - &#39;0&#39;] += 1;
        }

        for(int i=0; i&lt;Y.length(); i++) {
            yCntArr[Y.charAt(i) - &#39;0&#39;] += 1;
        }

        for(int i=9; i&gt;=0; i--) {
            int N = Math.min(xCntArr[i], yCntArr[i]);
            for(int j=0; j&lt;N; j++) {
                answer += i;
            }
        }

        if(&quot;&quot;.equals(answer)) {
            answer = &quot;-1&quot;;
        } else if(&#39;0&#39; == (answer.charAt(0))) {
            answer = &quot;0&quot;;
        }

        return answer;
    }
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/371d9e8a-0fd6-46be-bd5c-d1adb064f26a/image.png" alt=""></p>
<p>첫번째보다 더 느려진 코드...
&quot;감자의 생각은 어리석었을뿐인가...?ㅠㅠㅠ 다시 싹 지우고 HashMap으로 변경할까?&quot; 하고 절망하다가
<code>answer</code>이 너무 여러번 바뀌면서 메모리와 시간을 많이 잡아먹는 게 아닐까? 싶어서 <code>answer</code>을 StringBuilder로 변경해보았다.</p>
<p>그 코드는 위에 올린 작성 코드!!</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/c709cae7-84b7-409b-b5fb-4e4eca178ccf/image.png" alt=""></p>
<p>드디어 성고유ㅠㅠㅠㅠㅠ
심지어 속도가 첫번째보다 훠워어어어어얼씨이이인 빠르다...
StringBuilder가 진짜 빠르구나...</p>
<p>그렇다면 첫번째 코드도 StringBuilder로 전면교체 해본다면?!</p>
<h4 id="📍-실패한-네번째-코드">📍 실패한 네번째 코드</h4>
<pre><code class="language-java">import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

class Solution {
    public String solution(String X, String Y) {
        StringBuilder answer = new StringBuilder();

        StringBuilder xSb = new StringBuilder(X);
        StringBuilder ySb = new StringBuilder(Y);
        ArrayList&lt;Integer&gt; answerList = new ArrayList&lt;&gt;();

        for(int i=0; i&lt;xSb.length(); i++) {
            String xNum = xSb.substring(i,i+1);
            for(int j=0; j&lt;ySb.length(); j++) {
                if(xNum.equals(ySb.substring(j,j+1))) {
                    answerList.add(Integer.parseInt(xNum));
                    ySb.deleteCharAt(j);
                    break;
                }
            }
        }

        answerList.sort(Comparator.reverseOrder());

        if(answerList.isEmpty()) {
            return &quot;-1&quot;;
        } else {
             boolean first = true;
            for(int num : answerList) {
                answer.append(num);
                if(first == true &amp;&amp; num == 0) {
                    break;
                } else if(first == true) {
                    first = false;
                }
            }
        }

        return answer.toString();
    }
}</code></pre>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/f7f75473-bb88-4457-bc20-6a82ade5d3d3/image.png" alt=""></p>
<p><strong>응. 안돼. 돌아가.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[테스트 코드] Mock을 마주하는 자세]]></title>
            <link>https://velog.io/@hi_potato/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-Mock%EC%9D%84-%EB%A7%88%EC%A3%BC%ED%95%98%EB%8A%94-%EC%9E%90%EC%84%B8</link>
            <guid>https://velog.io/@hi_potato/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-Mock%EC%9D%84-%EB%A7%88%EC%A3%BC%ED%95%98%EB%8A%94-%EC%9E%90%EC%84%B8</guid>
            <pubDate>Sat, 30 Nov 2024 15:46:29 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="practical-testing-실용적인-테스트-가이드">[Practical Testing: 실용적인 테스트 가이드]</h2>
</blockquote>
<h3 id="섹션-7-mock을-마주하는-자세">섹션 7. Mock을 마주하는 자세</h3>
<h1 id="📌-실습-오류-해결">📌 실습 오류 해결</h1>
<p>실습을 따라하다가 테스트를 실행하니 갑자기 오류가 발생했다.</p>
<details>
<summary>길고 긴 오류 내용...</summary>

<pre><code class="language-java">  org.springframework.dao.InvalidDataAccessApiUsageException: For queries with named parameters you need to provide names for method parameters; Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:368)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:550)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:335)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:160)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:136)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223)
    at jdk.proxy2/jdk.proxy2.$Proxy181.findOrdersBy(Unknown Source)
    at sample.cafekiosk.spring.api.service.order.OrderStatisticsService.sendOrderStatisticsMail(OrderStatisticsService.java:23)
    at sample.cafekiosk.spring.api.service.order.OrderStatisticsServiceTest.sendOrderStatisticsMail(OrderStatisticsServiceTest.java:83)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: java.lang.IllegalStateException: For queries with named parameters you need to provide names for method parameters; Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters
    at org.springframework.data.jpa.repository.query.QueryParameterSetterFactory.lambda$1(QueryParameterSetterFactory.java:136)
    at java.base/java.util.Optional.orElseThrow(Optional.java:403)
    at org.springframework.data.jpa.repository.query.QueryParameterSetterFactory.getRequiredName(QueryParameterSetterFactory.java:136)
    at org.springframework.data.jpa.repository.query.QueryParameterSetterFactory.findParameterForBinding(QueryParameterSetterFactory.java:127)
    at org.springframework.data.jpa.repository.query.QueryParameterSetterFactory$BasicQueryParameterSetterFactory.create(QueryParameterSetterFactory.java:249)
    at org.springframework.data.jpa.repository.query.ParameterBinderFactory.createQueryParameterSetter(ParameterBinderFactory.java:146)
    at org.springframework.data.jpa.repository.query.ParameterBinderFactory.createSetters(ParameterBinderFactory.java:135)
    at org.springframework.data.jpa.repository.query.ParameterBinderFactory.createQueryAwareBinder(ParameterBinderFactory.java:102)
    at org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery.createBinder(AbstractStringBasedJpaQuery.java:143)
    at org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery.createBinder(AbstractStringBasedJpaQuery.java:139)
    at org.springframework.data.util.Lazy.getNullable(Lazy.java:135)
    at org.springframework.data.util.Lazy.get(Lazy.java:113)
    at org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery.doCreateQuery(AbstractStringBasedJpaQuery.java:130)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:243)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:129)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:92)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:152)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:140)
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170)
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158)
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:169)
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:148)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:70)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:379)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:138)
    ... 12 more
</code></pre>
</details>

<p>엥... 뭔데 이게...</p>
<p>이번에도 폭풍 서칭...</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/c7924a8e-8a55-41d4-8ed1-aaad2053fe65/image.png" alt=""></p>
<blockquote>
<h4 id="프로젝트--properties--java-compiler--store-information-about-method-parameters-usable-via-reflection-체크--apply">프로젝트 &gt; Properties &gt; Java Compiler &gt; Store information about method parameters (usable via reflection) 체크 &gt; Apply</h4>
</blockquote>
<p>하면 오류가 사라진다.</p>
<h1 id="📌-test-double">📌 Test Double</h1>
<p>스턴트맨(대역)을 영어로 Stunt Double이라고 한다.
<img src="https://velog.velcdn.com/images/hi_potato/post/e3d26f67-a926-4a41-a98f-d4500525ec1e/image.png" alt=""></p>
<p>Stunt Double에서 차용된 단어가 Test Double이다.</p>
<blockquote>
<h3 id="📑-마틴-파울러의-글">📑 마틴 파울러의 글</h3>
<p><a href="https://martinfowler.com/articles/mocksArentStubs.html">https://martinfowler.com/articles/mocksArentStubs.html</a>
👍 테스트 더블의 정의와 종류가 잘 설명되어 있다.</p>
</blockquote>
<h2 id="📍-test-double의-특징">📍 Test Double의 특징</h2>
<h3 id="dummy">Dummy</h3>
<p>: 아무 것도 하지 않는 깡통 객체</p>
<h3 id="fake">Fake</h3>
<p>: 단순한 형태로 동일한 기능은 수행하나, 프로덕션에서 쓰기에는 부족한 객체 (ex. FakeRepository)</p>
<h3 id="stub">Stub</h3>
<p>: 테스트에서 요청한 것에 대해 미리 준비한 결과를 제공하는 객체. 그 외에는 응답하지 않는다.</p>
<h3 id="spy">Spy</h3>
<p>: Stub이면서 호출된 내용을 기록하여 보여줄 수 있는 객체. 일부는 실제 객체처럼 동작시키고 일부만 Stubbing할 수 있다.</p>
<h3 id="mock">Mock</h3>
<p>: 행위에 대한 기대를 명세하고, 그에 따라 동작하도록 만들어진 객체</p>
<blockquote>
<h3 id="💡-stub과-mock">💡 Stub과 Mock</h3>
<p>가짜 객체이고 기댓값을 미리 정의하는 것은 비슷하나
검증하려는 목적이 다르다.</p>
</blockquote>
<ul>
<li>Stub : <strong>상태 검증 (State Verification)</strong></li>
<li>Mock : <strong>행위 검증 (Behavior Verification)</strong></li>
</ul>
<h1 id="📌-bddmockito">📌 BDDMockito</h1>
<p>: 행동주도개발</p>
<pre><code class="language-java">// given
Mockito.when(mailSendClient.sendEmail(anyString(), anyString(), anyString(), anyString()))
    .thenReturn(true);

BDDMockito.given(mailSendClient.sendEmail(anyString(), anyString(), anyString(), anyString()))
    .willReturn(true);</code></pre>
<p>given절에서 <code>when</code>을 사용하면 어색하다.</p>
<p>그래서 <code>Mockito</code>를 상속받고 있는 <code>BDDMockito</code>를 사용하여 <code>given</code>으로 표시한다.
<code>BDDMockito</code>는 <code>Mockito</code>와 기능은 동일하나 이름만 바꾼 것이다.</p>
<h1 id="📌-classicist-vs-mockist">📌 Classicist VS. Mockist</h1>
<ul>
<li><strong>Mockist</strong> : 모든 걸 Mocking위주로 하자!단위 테스트 시 잘 되었으니 통합 테스트 시에는 기능 보장된 것들은 mocking처리를 해서 우리가 잘라서 테스트를 간단하게 하자!
<img src="https://velog.velcdn.com/images/hi_potato/post/ac00bf3b-1ab4-4323-9bf8-d2a29deb115e/image.png" alt=""></li>
</ul>
<ul>
<li><strong>Classicist</strong> : 다 Mocking해버리면 프로덕션 코드가 동작할 때 진짜 객체들이 협업을 하는데 어떻게 보장하느냐! 진짜 객체로 최대한 테스트를 해봐야 한다! 꼭 필요한 경우에만 Mocking하자! 
<img src="https://velog.velcdn.com/images/hi_potato/post/7def2a7e-5e82-4d45-94a7-b6c0e65914ca/image.png" alt=""></li>
</ul>
<blockquote>
<h4 id="❓-실제-프로덕션-코드에서-런타임-시점에-일어날-일을-정확하게-stubbing-했다고-단언할-수-있는가">❓ 실제 프로덕션 코드에서 런타임 시점에 일어날 일을 정확하게 Stubbing 했다고 단언할 수 있는가?</h4>
<p>❗ Classicist 강사님 : 리스크를 안고 갈 바에는 비용을 조금이라도 더 들여서 통합 테스트에서 최대한 넓은 범위의 실제 객체/구현체를 불러와서 테스트하는 것이 훨씬 낫다!</p>
</blockquote>
<hr>

<blockquote>
<h3 id="📑-출처">📑 출처</h3>
</blockquote>
<ul>
<li>[Practical Testing: 실용적인 테스트 가이드]  (인프런/박우빈)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[99클럽 코테 스터디 34일차 TIL] 프로그래머스 햄버거 만들기]]></title>
            <link>https://velog.io/@hi_potato/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-34%EC%9D%BC%EC%B0%A8-TIL-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%96%84%EB%B2%84%EA%B1%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@hi_potato/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-34%EC%9D%BC%EC%B0%A8-TIL-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%96%84%EB%B2%84%EA%B1%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Sat, 30 Nov 2024 15:24:44 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="99클럽-코테-스터디-34일차-til">99클럽 코테 스터디 34일차 TIL</h2>
</blockquote>
<h3 id="💙-java-비기너">💙 JAVA 비기너</h3>
<h3 id="📌-오늘의-학습-키워드">📌 오늘의 학습 키워드</h3>
<ul>
<li>배열</li>
</ul>
<h3 id="📌-공부한-내용">📌 공부한 내용</h3>
<h4 id="📍-오늘의-문제">📍 오늘의 문제</h4>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/6739ede1-6abf-4c9b-b325-644e6d8a0c8e/image.png" alt=""></p>
<h4 id="📍-작성-코드">📍 작성 코드</h4>
<pre><code class="language-java">class Solution {
    public int solution(int[] ingredient) {
        int answer = 0;

        StringBuilder sb = new StringBuilder();

        for(int igdt : ingredient) {
            sb.append(igdt);

            if(sb.length() &gt;= 4) {
                if(&quot;1231&quot;.equals(sb.substring(sb.length() - 4))) {
                    sb.delete(sb.length() - 4, sb.length());
                    answer++;
                }
            }
        }

        return answer;
    }
}</code></pre>
<h3 id="📌-오늘의-회고">📌 오늘의 회고</h3>
<p>사실 첫번째 코드는 실패했다.</p>
<h4 id="📍-실패한-첫번째-코드">📍 실패한 첫번째 코드</h4>
<pre><code class="language-java">class Solution {
    public int solution(int[] ingredient) {
        int answer = 0;

        String ingredients = &quot;&quot;;

        for(int igdt : ingredient) {
            ingredients += igdt;

            if(ingredients.contains(&quot;1231&quot;)) {
                answer++;
                ingredients = ingredients.replace(&quot;1231&quot;, &quot;&quot;);
            }
        }

        return answer;
    }
}</code></pre>
<p>단순하게 <code>ingredient</code>를 문자열로 만들어서 &quot;1231&quot;이 있을 때마다 <code>answer</code>를 1 증가해주고 문자열에서 &quot;1231&quot;을 지우면 되는 거 아니야!? 하고 작성했는데</p>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/8f1f57ec-98bb-44f4-a87d-04d1678e2abf/image.png" alt=""></p>
<p>두둥탁...!!!</p>
<p>시간 초과로 인해 실패하였다...</p>
<p>아니... 왜? 그럼 ArrayList로 해야하는건가?? 그럼 한번 비교할 때마다 4개씩...?? 하고 검색하다가 StringBuilder의 존재를 기억하게 되었다.</p>
<p>그래서 StringBuilder로 구현해보려고 했으나 너무 오랜만인 까닭에 다시 공부해야했다.</p>
<p>StringBuilder <code>sb</code>에 <code>ingredient</code>를 하나씩 넣어주고 <code>sb</code>의 길이가 4이상이 되면 마지막 4개의 항목에 &quot;1231&quot;이 있는지 확인한다. 마지막 4개만 검사하는 이유는 for문이 돌면서 이미 앞에 있는 요소들도 확인했기 때문이다.</p>
<p>마지막 4개의 항목에 &quot;1231&quot;이 있다면 <code>sb</code>에서 &quot;1231&quot;을 삭제하고 <code>answer</code>를 1 증가해준다.</p>
<blockquote>
<h3 id="📑-stringbuilder-공부자료">📑 StringBuilder 공부자료</h3>
<p><a href="https://myeongju00.tistory.com/61">https://myeongju00.tistory.com/61</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[99클럽 코테 스터디 33일차 TIL] 백준 13419번 탕수육]]></title>
            <link>https://velog.io/@hi_potato/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-33%EC%9D%BC%EC%B0%A8-TIL-%EB%B0%B1%EC%A4%80-13419%EB%B2%88-%ED%83%95%EC%88%98%EC%9C%A1</link>
            <guid>https://velog.io/@hi_potato/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-33%EC%9D%BC%EC%B0%A8-TIL-%EB%B0%B1%EC%A4%80-13419%EB%B2%88-%ED%83%95%EC%88%98%EC%9C%A1</guid>
            <pubDate>Fri, 29 Nov 2024 14:36:15 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="99클럽-코테-스터디-33일차-til">99클럽 코테 스터디 33일차 TIL</h2>
</blockquote>
<h3 id="💙-java-비기너">💙 JAVA 비기너</h3>
<h3 id="📌-오늘의-학습-키워드">📌 오늘의 학습 키워드</h3>
<ul>
<li>배열</li>
</ul>
<h3 id="📌-공부한-내용">📌 공부한 내용</h3>
<h4 id="📍-오늘의-문제">📍 오늘의 문제</h4>
<p><img src="https://velog.velcdn.com/images/hi_potato/post/56b30e9e-ec92-4016-af51-ebb236f02a5b/image.png" alt=""></p>
<h4 id="📍-작성-코드">📍 작성 코드</h4>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class Main {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        int N = Integer.parseInt(br.readLine());

        for(int i=0; i&lt;N; i++) {
            String word = br.readLine();

            if(word.length() % 2 != 0) word += word;

            String[] wordArr = word.split(&quot;&quot;);

            String first = &quot;&quot;;
            String second = &quot;&quot;;
            for(int j=0; j&lt;wordArr.length; j++) {
                if(j % 2 == 0) first += wordArr[j];
                else second += wordArr[j];
            }

            bw.write(first + &quot;\n&quot; + second + &quot;\n&quot;);
        }

        br.close();

        bw.flush();

        bw.close();

    }
}
</code></pre>
<h3 id="📌-오늘의-회고">📌 오늘의 회고</h3>
<p>감자가 탕수육 게임 절대 지지 않았던 이유!!
남의 말 듣지 않고 감자가 해야하는 말만 하기!!!
탕!!육!!수!!!!
상대도 같은 방법으로 하다보면 게임 안끝난다...ㅎ</p>
<p>이게 1:1 게임이라면 단어의 문자 수가 홀수이냐 짝수이냐가 큰 차이를 결정한다.
짝수라면 각자 말하는 단어의 격문자만 반복하면 되지만 (ex a:감! b:자!)
홀수라면 두세트만 돌아도 단어의 모든 문자를 말하게 된다. (ex a:탕!육!수! b:수!탕!육!)</p>
<p>그래서 짝수라면 한 세트를 각각 나눠가지면 되지만
홀수라면 두 세트가 필요하다.
문자를 입력받고 해당 문자의 문자 수가 짝수라면 그대로 가고 홀수하면 단어를 한번 더 추가해 짝수개의 단어로 만든 후 각자 말해야하는 문자를 알려준다.</p>
<p>탕수육 게임은 한 단어를 서로 번갈아가면서 말하기 때문에 for문을 돌면서 하나씩 분배해준면 된다.</p>
]]></description>
        </item>
    </channel>
</rss>