<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://qkrrlgh519.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://qkrrlgh519.github.io/" rel="alternate" type="text/html" /><updated>2025-10-19T16:15:48+00:00</updated><id>https://qkrrlgh519.github.io/feed.xml</id><title type="html">Kyo’s Blog</title><subtitle>개발 블로그 | 박기호</subtitle><entry><title type="html">Math Algorithm(Overview)</title><link href="https://qkrrlgh519.github.io/algorithm(overview)/2025/10/19/Algorithm-Overview-Math.html" rel="alternate" type="text/html" title="Math Algorithm(Overview)" /><published>2025-10-19T03:00:00+00:00</published><updated>2025-10-19T03:00:00+00:00</updated><id>https://qkrrlgh519.github.io/algorithm(overview)/2025/10/19/Algorithm-Overview-Math</id><content type="html" xml:base="https://qkrrlgh519.github.io/algorithm(overview)/2025/10/19/Algorithm-Overview-Math.html"><![CDATA[<h2 id="math-algorithm---수학">Math Algorithm - 수학</h2>

<h3 id="01-홀수와-짝수">01. 홀수와 짝수</h3>

<ul>
  <li>
    <p>홀수 정의</p>

    <ul>
      <li>odd number</li>
      <li>2로 나누어 떨어지지 않는 정수</li>
    </ul>
  </li>
  <li>
    <p>짝수 정의</p>

    <ul>
      <li>even number</li>
      <li>2로 나누어 떨어지는 정수</li>
    </ul>
  </li>
  <li>
    <p>홀수와 짝수 판단</p>

    <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">num</span>

<span class="k">if</span><span class="p">(</span><span class="nx">num</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="dl">"</span><span class="s2">짝수</span><span class="dl">"</span>
<span class="k">if</span><span class="p">(</span><span class="nx">num</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="k">return</span> <span class="dl">"</span><span class="s2">홀수</span><span class="dl">"</span>
</code></pre></div>    </div>
  </li>
</ul>

<h3 id="02-2진수-8진수-16진수">02. 2진수, 8진수, 16진수</h3>

<ul>
  <li>
    <p>2진수를 8진수로 변환하기</p>

    <ul>
      <li>2진수의 수를 뒷자리부터 3자리씩 끊어내고, 각 자리에 4,2,1을 곱하면 8진수를 구할 수 있다. (처음 3개에 4,2,1을 곱하면, 다음 3개에는 32,16,8을 곱해야 할 것 같지만, 이미 자신의 자리 자체가 8이 곱해졌음을 의미하기에 4,2,1을 곱한다.)</li>
      <li>[2진수]100 111 101 = 1(4)0(2)0(1) 1(4)1(2)1(1) 1(4)0(2)1(1) = [8진수]4 7 5</li>
    </ul>
  </li>
</ul>

<h3 id="03-소수">03. 소수</h3>

<ul>
  <li>
    <p>정의</p>

    <ul>
      <li>1과 자기 자신 이외의 자연수로는 나누어 떨어지지 않는 자연수</li>
      <li>1은 소수가 아닌 유일한 자연수이다.</li>
    </ul>
  </li>
  <li>
    <p>에라토스테네스의 체</p>

    <ul>
      <li>소수를 찾는 방법</li>
      <li>100 이하의 소수를 구한다고 하면 1~100을 적고, 2부터 100까지 반복한다. (0, 1은 소수 아님)</li>
      <li>지워지지 않는 수 중에서 가장 작은 수는 2이다. 2는 소수이고, 2의 배수는 모두 소수가 아니므로 모두 지운다.</li>
      <li>그 다음 지워지지 않은 수 중에서 가장 작은 수는 3이고, 3도 소수이다. (소수가 아니였다면 이전에 지워졌어야 한다.) 3의 배수도 모두 지운다.</li>
      <li>위의 과정을 반복하며, 소수가 아닌 수는 모두 지운다.</li>
    </ul>

    <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 소수 찾기</span>
<span class="kd">const</span> <span class="nx">isPrime</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">N</span> <span class="o">+</span> <span class="mi">1</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span> <span class="c1">// N까지의 소수를 찾는다.</span>
<span class="nx">isPrime</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="nx">isPrime</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span> <span class="c1">// 0, 1은 소수 아님</span>

<span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;=</span> <span class="nx">N</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
	<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">isPrime</span><span class="p">[</span><span class="nx">i</span><span class="p">])</span> <span class="k">continue</span><span class="p">;</span>

	<span class="c1">// 2+2, 2+2+2, 2+2+2+2 -&gt; i의 배수 모두 지우기</span>
	<span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">j</span> <span class="o">=</span> <span class="nx">i</span> <span class="o">+</span> <span class="nx">i</span><span class="p">;</span> <span class="nx">j</span> <span class="o">&lt;=</span> <span class="nx">N</span><span class="p">;</span> <span class="nx">j</span> <span class="o">+=</span> <span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
		<span class="nx">isPrime</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>    </div>
  </li>
</ul>

<h3 id="04-약수">04. 약수</h3>

<ul>
  <li>
    <p>정의</p>

    <ul>
      <li>어떤 수를 나누어떨어지게 하는 수</li>
    </ul>
  </li>
  <li>
    <p>특징</p>
    <ul>
      <li>순서대로 나열된 약수들을 가지고 가운데를 기준으로 서로 곱하면 원래의 수가 된다.</li>
      <li>12 (1, 2, 3, 4, 6, 12)</li>
      <li>1 * 12 = 12</li>
      <li>2 * 6 = 12</li>
      <li>3 * 4 = 12</li>
    </ul>
  </li>
</ul>

<h3 id="05-최대공약수와-최소공배수">05. 최대공약수와 최소공배수</h3>

<ul>
  <li>
    <p>최대공약수 정의</p>

    <ul>
      <li>GCD (Greatest Common Divisor)</li>
      <li>두 수, 혹은 그 이상의 여러 수의 공통된 약수 중 가장 큰 것</li>
    </ul>
  </li>
  <li>
    <p>최소공배수 정의</p>

    <ul>
      <li>LCM (Least Common Multiple)</li>
      <li>두 수, 혹은 그 이상의 수들의 공통인 배수 중 가장 작은 것</li>
    </ul>
  </li>
  <li>
    <p>유클리드 호제법</p>

    <ul>
      <li>최대공약수를 찾는 방법</li>
      <li>두 양의 정수 a 와 b (a &gt; b) 에 대하여, a % b = r 이라 하면, a 와 b 의 최대공약수는 b 와 r 의 최대공약수와 같다.</li>
      <li><strong>즉, a % b = r 이라고 했을 때, GCD(a, b) = GCD(b, r)과 같고, r = 0 일때 b 가 최대공약수 이다.</strong></li>
    </ul>

    <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">GCD</span> <span class="o">=</span> <span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
	<span class="k">if</span> <span class="p">(</span><span class="nx">a</span> <span class="o">%</span> <span class="nx">b</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="nx">b</span><span class="p">;</span>
	<span class="k">else</span> <span class="k">return</span> <span class="nx">GCD</span><span class="p">(</span><span class="nx">b</span><span class="p">,</span> <span class="nx">a</span> <span class="o">%</span> <span class="nx">b</span><span class="p">);</span>
<span class="p">};</span>
</code></pre></div>    </div>
  </li>
  <li>
    <p>최대공약수(유클리드 호제법)를 이용해 최소공배수 찾기</p>

    <ul>
      <li>두 수와 최대공약수, 최소공배수 사이에는 아래와 같은 공식이 성립한다.</li>
      <li>두 수의 곱은 최대공약수와 최소공배수의 곱과 같다.</li>
      <li><strong>즉, a * b = gcd * lcm</strong></li>
      <li>lcm = (a * b) / gcd</li>
    </ul>

    <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">a</span><span class="p">,</span> <span class="nx">b</span> <span class="o">=</span> <span class="p">[</span><span class="mi">6</span><span class="p">,</span> <span class="mi">18</span><span class="p">];</span>

<span class="kd">const</span> <span class="nx">gcd</span> <span class="o">=</span> <span class="nx">GCD</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">lcm</span> <span class="o">=</span> <span class="p">(</span><span class="nx">a</span> <span class="o">*</span> <span class="nx">b</span><span class="p">)</span> <span class="o">/</span> <span class="nx">gcd</span>
</code></pre></div>    </div>
  </li>
</ul>

<h3 id="06-수열">06. 수열</h3>

<ul>
  <li>
    <p>정의</p>

    <ul>
      <li>수 또는 다른 대상의 순서 있는 나열</li>
    </ul>
  </li>
  <li>
    <p>풀이법</p>
    <ul>
      <li>값이 커지더라도 하나씩 나열하면서 그 안의 규칙을 찾아야 한다.</li>
      <li>초기에는 규칙이 없다가 나중에 규칙이 생기는 경우도 있어서, 값이 커진 후에 규칙을 찾는 것이 더욱 도움이 될 수 있다.</li>
    </ul>
  </li>
</ul>

<h3 id="07-피보나치-수">07. 피보나치 수</h3>

<ul>
  <li>
    <p>정의</p>

    <ul>
      <li>첫째 및 둘째 항이 1이며 그 뒤의 모든 항은 바로 앞의 두 항의 합인 수열이다.</li>
    </ul>
  </li>
  <li>
    <p>규칙</p>

    <ul>
      <li>1, 1, 2, 3, 5, 8</li>
      <li>f(n) = f(n - 1) + f(n - 2)</li>
    </ul>
  </li>
</ul>

<h3 id="999-원">999. 원</h3>

<ul>
  <li>BOJ 1002 토대로 작성 예정</li>
</ul>]]></content><author><name></name></author><category term="Algorithm(Overview)" /><summary type="html"><![CDATA[Math Algorithm - 수학]]></summary></entry><entry><title type="html">Sort Algorithm(Overview)</title><link href="https://qkrrlgh519.github.io/algorithm(overview)/2025/08/07/Algorithm-Overview-Sort.html" rel="alternate" type="text/html" title="Sort Algorithm(Overview)" /><published>2025-08-07T03:00:00+00:00</published><updated>2025-08-07T03:00:00+00:00</updated><id>https://qkrrlgh519.github.io/algorithm(overview)/2025/08/07/Algorithm-Overview-Sort</id><content type="html" xml:base="https://qkrrlgh519.github.io/algorithm(overview)/2025/08/07/Algorithm-Overview-Sort.html"><![CDATA[<h2 id="sort-algorithm---정렬">Sort Algorithm - 정렬</h2>

<h3 id="01-설명">01. 설명</h3>

<ul>
  <li>자료 탐색에 있어서 필수적</li>
  <li>비교 연산, 이동 연산을 최소화해야함</li>
  <li>단순/비효율 : 삽입, 선택, 거품</li>
  <li>복잡/효율 : 퀵, 힙, 합병, 기수</li>
</ul>

<h3 id="02-선택정렬">02. 선택정렬</h3>

<ul>
  <li>해당 순서에 원소를 넣을 위치(index)는 이미 정해져 있고, 어떤 원소를 넣을지 선택하는 알고리즘</li>
  <li>입력 배열에서 최소값을 발견한 다음, 이 최소값을 배열의 첫 번째 요소와 교환한다.</li>
</ul>

<h3 id="03-삽입정렬">03. 삽입정렬</h3>

<ul>
  <li>자료 배열 안에서 매 순서마다 해당 원소의 앞의 이미 정렬되어 있는 모든 요소를 차례대로 비교하여, 자신의 위치를 찾아서 삽입하는 알고리즘</li>
  <li>두 번째는 첫 번째를, 세번째는 두번째와 첫번째를 비교한 후 삽입할 위치를 찾고, 찾았으면 그 위치에 삽입하기 위해 자료를 한 칸씩 뒤로 이동시킨다.</li>
</ul>

<h3 id="04-버블정렬">04. 버블정렬</h3>

<ul>
  <li>서로 인접한 두 원소를 검사하여 크기가 순서대로 되어 있지 않으면 서로 교환하는 비교-교환 과정을 배열의 왼쪽 끝에서 시작해 오른쪽 끝까지 진행하며 정렬하는 알고리즘</li>
  <li>1회전을 수행하고 나면 가장 큰(작은)자료가 맨 뒤로 이동하므로 2회전에서는 맨 끝에 있는 자료는 정렬에서 제외된다.</li>
</ul>

<h3 id="05-합병정렬">05. 합병정렬</h3>

<ul>
  <li>하나의 리스트를 두 개의 균등한 크기로 분할하고, 분할된 부분 리스트를 정렬한 다음, 두 개의 정렬된 부분 리스트를 합하여 전체가 정렬된 리스트가 되게 하는 방법으로 분할 정복 알고리즘 중 하나</li>
  <li>합병 정렬에서 실제로 정렬이 이루어지는 시점은 2개의 리스트를 합병(Merge)하는 단계</li>
  <li>재귀 형식으로 구현 가능하며, 재귀 함수에서 재귀 함수로 타고 타고 들어가다가 더 이상 들어갈 수 없는 순간이 되면 리턴이 된 후 병합(정렬) 함수가 실행되면서 반환하고 반환되면서 정렬이 이루어진다.</li>
</ul>

<h3 id="06-퀵정렬">06. 퀵정렬</h3>

<ul>
  <li>하나의 리스트를 피벗(pivot) 기준으로 두 개의 비균등한 크기로 분할하고, 분할된 부분 리스트를 정렬한 다음, 두 개의 정렬된 부분 리스트를 합하여 전체가 정렬된 리스트가 되게 하는 방법으로 분할 정복 알고리즘 중 하나</li>
  <li>재귀 형식으로 구현 가능하며, 피벗(pivot) 기준으로 보다 작은 값은 왼쪽 리스트에 몰고, 보다 큰 값은 오른쪽 리스트에 몰은 다음에 각 두 리스트에 퀵 정렬 함수가 재귀로 실행되는 방식이다.</li>
</ul>]]></content><author><name></name></author><category term="Algorithm(Overview)" /><summary type="html"><![CDATA[Sort Algorithm - 정렬]]></summary></entry><entry><title type="html">Test Driven Develop - 2</title><link href="https://qkrrlgh519.github.io/testdrivendevelop/2025/05/21/Test-Driven-Develop-2.html" rel="alternate" type="text/html" title="Test Driven Develop - 2" /><published>2025-05-21T03:00:00+00:00</published><updated>2025-05-21T03:00:00+00:00</updated><id>https://qkrrlgh519.github.io/testdrivendevelop/2025/05/21/Test-Driven-Develop-2</id><content type="html" xml:base="https://qkrrlgh519.github.io/testdrivendevelop/2025/05/21/Test-Driven-Develop-2.html"><![CDATA[<h1 id="화폐-예제">화폐 예제</h1>

<h2 id="0장-테스트-주도-개발tdd의-리듬">0장. 테스트 주도 개발(TDD)의 리듬</h2>

<ol>
  <li>재빨리 테스트를 하나 추가한다.</li>
  <li>모든 테스트를 실행하고 새로 추가한 것이 실패하는지 확인한다.</li>
  <li>코드를 조금 바꾼다.</li>
  <li>모든 테스트를 실행하고 전부 성공하는지 확인한다.</li>
  <li>리팩토링을 통해 중복을 제거한다.</li>
</ol>

<h2 id="1장-다중-통화-지원-money-객체">1장. 다중 통화 지원 Money 객체</h2>

<h3 id="테스트-항목">테스트 항목</h3>

<ul>
  <li>통화가 다른 두 금액을 더해서 주어진 환율에 맞게 변한 금액을 결과로 얻을 수 있어야 한다.</li>
  <li>어떤 금액(주가)을 어떤 수(주식의 수)에 곱한 금액을 결과로 얻을 수 있어야 한다.</li>
</ul>

<h3 id="테스트-코드">테스트 코드</h3>

<ul>
  <li>테스트 작성시 오퍼레이션의 완벽한 인터페이스에 대해 상상해보는 것이 좋다.</li>
  <li>실패하는 테스트가 주어진 상태이고, 최대한 빨리 초록 막대를 보고 싶을 뿐이다.</li>
  <li>당장의 목표는 완벽한 해법을 구하는 것이 아니라 테스트를 통과하는 것일 뿐이다.</li>
</ul>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 간단 곱셈 테스트 코드 예시</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testMultiplication</span><span class="o">()</span> <span class="o">{</span>
	<span class="nc">Dollar</span> <span class="n">five</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">);</span>
	<span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">2</span><span class="o">);</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="mi">10</span><span class="o">,</span> <span class="n">five</span><span class="o">.</span><span class="na">amount</span><span class="o">);</span>
<span class="o">}</span>

<span class="c1">// 에러1. Dollar 클래스 없음</span>
<span class="kd">class</span> <span class="nc">Dollar</span>

<span class="c1">// 에러2. 생성자 없음</span>
<span class="nc">Dollar</span><span class="o">(</span><span class="kt">int</span> <span class="n">amount</span><span class="o">){}</span>

<span class="c1">// 에러3. times(int) 메서드 없음</span>
<span class="kt">void</span> <span class="nf">times</span><span class="o">(</span><span class="kt">int</span> <span class="n">multiplier</span><span class="o">){}</span>

<span class="c1">// 에러4. amount 필드 없음</span>
<span class="kt">int</span> <span class="n">amount</span>
</code></pre></div></div>

<h3 id="의존성과-중복">의존성과 중복</h3>

<ul>
  <li>(스티븐 프리만) 테스트와 코드 간의 문제는 중복이 아니다. 문제는 테스트와 코드 사이에 존재하는 의존성이다.</li>
  <li>즉, 코드나 테스트 중 한쪽을 수정하면 반드시 다른 한쪽도 수정해야만 한다는 것이다.</li>
  <li>우리의 목표는 코드를 바꾸지 않으면서도 뭔가 의미 있는 테스트를 하나 더 작성하는 것인데, 현재의 구현으로는 불가능하다.</li>
  <li>의존성이 문제 그 자체라면 중복(duplication)은 문제의 징후이다.</li>
  <li>중복된 로직이란 동일한 문장이 코드의 여러 장소에 나타나는 것을 의미하며, 중복된 로직을 하나로 끄집어내는 일엔 객체를 이용하는 것이 최고다.</li>
  <li>프로그램에서는 중복만 제거해주면 의존성도 제거된다. 이게 바로 TDD 의 두 번째 규칙이 존재하는 이유이다.</li>
</ul>

<h3 id="중복-제거">중복 제거</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 5와 2가 두 곳에 존재 (테스트에 있는 데이터와 코드에 있는 데이터 사이 = 테스트와 코드 사이에 존재하는 의존성)</span>
<span class="kt">int</span> <span class="n">amount</span> <span class="o">=</span> <span class="mi">5</span> <span class="o">*</span> <span class="mi">2</span><span class="o">;</span>
</code></pre></div></div>

<ul>
  <li>5와 2가 두 곳에 존재한다. 이 중복을 제거해야 한다.</li>
  <li>객체의 초기화 단계에 있는 설정 코드를 times() 메서드 안으로 옮긴다.</li>
  <li>TDD의 핵심은 이런 작은 단계를 밟아 나가며, 이런 작은 단계를 밟을 능력을 갖추는 것이다.</li>
</ul>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">amount</span>

<span class="kt">void</span> <span class="nf">times</span><span class="o">(</span><span class="kt">int</span> <span class="n">multiplier</span><span class="o">)</span> <span class="o">{</span>
	<span class="n">amount</span> <span class="o">=</span> <span class="mi">5</span> <span class="o">*</span> <span class="mi">2</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 5를 어디서 얻을 수 있을까?? 이건 생성자에서 넘어오는 값이니 amonut 변수에 저장</span>
<span class="nc">Dollar</span><span class="o">(</span><span class="kt">int</span> <span class="n">amount</span><span class="o">)</span> <span class="o">{</span>
	<span class="k">this</span><span class="o">.</span><span class="na">amount</span> <span class="o">=</span> <span class="n">amount</span><span class="o">;</span>
<span class="o">}</span>

<span class="c1">// amount 가져다 사용 가능</span>
<span class="kt">void</span> <span class="nf">times</span><span class="o">(</span><span class="kt">int</span> <span class="n">multiplier</span><span class="o">)</span> <span class="o">{</span>
	<span class="n">amount</span> <span class="o">=</span> <span class="n">amount</span> <span class="o">*</span> <span class="mi">2</span><span class="o">;</span>
<span class="o">}</span>

<span class="c1">// multiplier 의 값이 2이므로, 상수를 이 인자로 대체</span>
<span class="kt">void</span> <span class="nf">times</span><span class="o">(</span><span class="kt">int</span> <span class="n">multiplier</span><span class="o">)</span> <span class="o">{</span>
	<span class="n">amount</span> <span class="o">*=</span> <span class="n">multiplier</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="2장-타락한-객체">2장. 타락한 객체</h2>

<h3 id="일반적인-tdd-주기">일반적인 TDD 주기</h3>

<ul>
  <li>테스트 작성</li>
  <li>실행 가능하게 만들기 (가장 중요한 것은 빨리 초록 막대를 보는 것)</li>
  <li>올바르게 만들기 (직전에 저질렀던 죄악을 수습)</li>
</ul>

<h3 id="작동하는-깔끔한-코드-얻기">작동하는 깔끔한 코드 얻기</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">void</span> <span class="nf">testMultiplication</span><span class="o">()</span> <span class="o">{</span> <span class="c1">// 곱셈 테스트</span>
	<span class="nc">Dollar</span> <span class="n">five</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">);</span>
	<span class="c1">// [문제] times() 를 호출한 이후에 five 는 더 이상 5가 아니다. 그러면 새로운 객체를 반환하게 만들면 어떨까?</span>
	<span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">2</span><span class="o">);</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="mi">10</span><span class="o">,</span> <span class="n">product</span><span class="o">.</span><span class="na">amount</span><span class="o">);</span>
	<span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">3</span><span class="o">);</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="mi">15</span><span class="o">,</span> <span class="n">product</span><span class="o">.</span><span class="na">amount</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Dollar</span> <span class="n">five</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">);</span>

<span class="c1">// 메서드에 반환값이 없기 때문에 컴파일조차 되지 않는다.</span>
<span class="nc">Dollar</span> <span class="n">product</span> <span class="o">=</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">2</span><span class="o">);</span>
<span class="n">assertEquals</span><span class="o">(</span><span class="mi">10</span><span class="o">,</span> <span class="n">product</span><span class="o">.</span><span class="na">amount</span><span class="o">);</span>
<span class="n">product</span> <span class="o">=</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">3</span><span class="o">);</span>
<span class="n">assertEquals</span><span class="o">(</span><span class="mi">15</span><span class="o">,</span> <span class="n">product</span><span class="o">.</span><span class="na">amount</span><span class="o">);</span>
</code></pre></div></div>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 아래 같이 수정해야 컴파일이 된다. 하지만 실행되지 않는다.</span>
<span class="nc">Dollar</span> <span class="nf">times</span><span class="o">(</span><span class="kt">int</span> <span class="n">multiplier</span><span class="o">)</span> <span class="o">{</span>
	<span class="n">amount</span> <span class="o">*=</span> <span class="n">multiplier</span><span class="o">;</span>
	<span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<h4 id="빠르게-초록색-보는-전략">빠르게 초록색 보는 전략</h4>

<ul>
  <li>가짜로 구현하기 : 상수를 반환하게 만들고, 진짜 코드를 얻을 때까지 단계적으로 상수를 변수로 변경</li>
  <li>명백한 구현 사용하기 : 실제 구현을 입력</li>
</ul>

<h4 id="학습-내용-검토">학습 내용 검토</h4>

<ul>
  <li>설계상 결함(Dollar 부작용)을 그 결함으로 인해 실패하는 테스트로 변환</li>
  <li>스텁 구현으로 빠르게 컴파일을 통과하도록 구현</li>
  <li>올바르다고 생각하는 코드를 입력하여 테스트를 통과</li>
  <li><code class="language-plaintext highlighter-rouge">느낌(부작용에 대한 혐오감)을 테스트(하나의 Dollar 객체에 곱하기 두 번 수행)로 변환하는 것은 TDD의 일반적 주제</code></li>
</ul>

<h2 id="3장-모두를-위한-평등">3장. 모두를 위한 평등</h2>

<h3 id="값-객체-패턴-value-object-pattern">값 객체 패턴 (Value Object Pattern)</h3>

<ul>
  <li>지금의 Dollar 객체같이 객체를 값처럼 쓸 수 있는 방식</li>
  <li>객체의 인스턴스 변수가 생성자를 통해서 일단 설정된 후 결코 변하지 않는 것이 제약사항</li>
  <li>값 객체를 사용하면 별칭 문제에 대해 걱정할 필요가 없다는 것이 아주 큰 장점
    <ul>
      <li>두 번째 수표의 값 변경시 첫 번째 수표의 값까지 변경되는 것이 별칭 문제</li>
    </ul>
  </li>
</ul>

<h3 id="값-객체는-equals-를-구현">값 객체는 equals() 를 구현</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 빨간 막대</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testEquality</span><span class="o">()</span> <span class="o">{</span>
	<span class="n">assertTrue</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">).</span><span class="na">equals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">)));</span>
<span class="o">}</span>

<span class="c1">// 가짜로 구현</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="nc">Object</span> <span class="n">object</span><span class="o">)</span> <span class="o">{</span>
	<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="삼각측량법">삼각측량법</h3>

<ul>
  <li>만약 라디오 신호를 두 수신국이 감지</li>
  <li>수신국 사이의 거리가 알려져 있고, 각 수신국이 신호의 방향을 알고 있다면,</li>
  <li>이 정보들만으로 충분히 신호의 거리와 방위를 알 수 있음</li>
</ul>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">void</span> <span class="nf">testEquality</span><span class="o">()</span> <span class="o">{</span>
	<span class="n">assertTrue</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">).</span><span class="na">equals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">)));</span>
	<span class="n">assertFalse</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">).</span><span class="na">equals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">6</span><span class="o">)));</span>
<span class="o">}</span>

<span class="c1">// 동치성 일반화 =&gt; Dollar 와 Dollar 를 직접 비교 가능</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="nc">Object</span> <span class="n">object</span><span class="o">)</span> <span class="o">{</span>
	<span class="nc">Dollar</span> <span class="n">dollar</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Dollar</span><span class="o">)</span> <span class="n">object</span><span class="o">;</span>
	<span class="k">return</span> <span class="n">amount</span> <span class="o">==</span> <span class="n">dollar</span><span class="o">.</span><span class="na">amount</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="4장-프라이버시">4장. 프라이버시</h2>

<h3 id="amount-를-private-으로">amount 를 private 으로</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 개념적으로 Dollar.times() 연산은 호출받은 객체의 값에 인자로 받은 곱수만큼 곱한 값을 갖는 Dollar 를 반환해야 함</span>
<span class="c1">// 하지만 테스트가 정확히 그것을 의미하지 않음</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testMultiplication</span><span class="o">()</span> <span class="o">{</span>
	<span class="nc">Dollar</span> <span class="n">five</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">DOllar</span><span class="o">(</span><span class="mi">5</span><span class="o">);</span>
	<span class="nc">Dollar</span> <span class="n">product</span> <span class="o">=</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">2</span><span class="o">);</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="mi">10</span><span class="o">,</span> <span class="n">product</span><span class="o">.</span><span class="na">amount</span><span class="o">);</span> <span class="c1">// Dollar 를 반환하지 않는 것을 의미하는 부분</span>
	<span class="n">product</span> <span class="o">=</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">3</span><span class="o">);</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="mi">15</span><span class="o">,</span> <span class="n">product</span><span class="o">.</span><span class="na">amount</span><span class="o">);</span>
<span class="o">}</span>

<span class="c1">// 단언(assertion)을 Dollar와 Dollar를 비교하는 것으로 재작성</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testMultiplication</span><span class="o">()</span> <span class="o">{</span>
	<span class="nc">Dollar</span> <span class="n">five</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">);</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">10</span><span class="o">),</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">2</span><span class="o">));</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">15</span><span class="o">),</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">3</span><span class="o">));</span>
<span class="o">}</span>

<span class="c1">// 테스트를 고치고 나니 이제 Dollar의 amount 인스턴스 변수를 사용하는 코드는 Dollar 자신밖에 없어서, private 로 변경</span>
</code></pre></div></div>

<ul>
  <li>만약 동치성 테스트가 동치성에 대한 코드가 정확히 작동한다는 것을 검증하는 데 실패한다면, 곱하기 테스트 역시 실패한다.</li>
  <li>이것은 TDD 를 하면서 적극적으로 관리해야 할 위험요소다. 우리는 완벽함을 위해 노력하지 않는다.</li>
  <li>모든 것을 두 번 말함으로써(코드와 테스트로 한 번씩) 자신감을 가지고 전진할 수 있을 만큼만 결함의 정도를 낮추길 희망한다.</li>
  <li>그럼에도 결함이 생긴다면, 테스트를 어떻게 작성해야 했는지에 대한 교훈을 얻고 다시 앞으로 나아간다.</li>
</ul>

<h2 id="5장-솔직히-말하자면">5장. 솔직히 말하자면</h2>

<h3 id="5달러--10프랑--10달러-환율-고려">5달러 + 10프랑 = 10달러 (환율 고려)</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Dollar 객체와 비슷하게 작동하는 Franc 라는 객체</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testFrancMultiplication</span><span class="o">()</span> <span class="o">{</span>
	<span class="nc">Franc</span> <span class="n">five</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Franc</span><span class="o">(</span><span class="mi">5</span><span class="o">);</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Franc</span><span class="o">(</span><span class="mi">10</span><span class="o">),</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">2</span><span class="o">));</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Franc</span><span class="o">(</span><span class="mi">15</span><span class="o">),</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">3</span><span class="o">));</span>
<span class="o">}</span>

<span class="c1">// Dollar 코드를 복사해서 Dollar 를 Franc 로 변경</span>

<span class="c1">// 1. 테스트 작성</span>
<span class="c1">// 2. 컴파일되게 하기</span>
<span class="c1">// 3. 실패하는지 확인하기 위해 설명</span>
<span class="c1">// 4. 실행하게 만듦</span>
<span class="c1">// 5. 중복 제거</span>
</code></pre></div></div>

<ul>
  <li>각 단게에는 서로 다른 목적이 있다.</li>
  <li>처음 네 단계는 빨리 진행해야 한다. 그러면 새 기능이 포함되더라도 잘 알고 있는 상태에 이를 수 있다.</li>
  <li>주기의 다섯 번째 단계 없이는 앞의 네 단계도 제대로 되지 않는다.</li>
  <li>적절한 시기에 적절한 설계를 해라. 돌아가게 만들고, 올바르게 만들어라.</li>
</ul>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Franc</span> <span class="o">{</span>
	<span class="kd">private</span> <span class="kt">int</span> <span class="n">amount</span><span class="o">;</span>

	<span class="nc">Franc</span><span class="o">(</span><span class="kt">int</span> <span class="n">amount</span><span class="o">)</span> <span class="o">{</span>
		<span class="k">this</span><span class="o">.</span><span class="na">amount</span> <span class="o">=</span> <span class="n">amount</span><span class="o">;</span>
	<span class="o">}</span>

	<span class="nc">Franc</span> <span class="nf">times</span><span class="o">(</span><span class="kt">int</span> <span class="n">multiplier</span><span class="o">)</span> <span class="o">{</span>
		<span class="k">return</span> <span class="k">new</span> <span class="nf">Franc</span><span class="o">(</span><span class="n">amount</span> <span class="o">*</span> <span class="n">multiplier</span><span class="o">);</span>
	<span class="o">}</span>

	<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="nc">Object</span> <span class="n">object</span><span class="o">)</span> <span class="o">{</span>
		<span class="nc">Franc</span> <span class="n">franc</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Franc</span><span class="o">)</span> <span class="n">object</span><span class="o">;</span>
		<span class="k">return</span> <span class="n">amount</span> <span class="o">==</span> <span class="n">franc</span><span class="o">.</span><span class="na">amount</span><span class="o">;</span>
	<span class="o">}</span>
<span class="o">}</span>

<span class="c1">// 중복이 엄청 많다. equals() 를 일반화하는 것부터 시작하자.</span>
</code></pre></div></div>

<h2 id="6장-돌아온-모두를-위한-평등">6장. 돌아온 ‘모두를 위한 평등’</h2>

<h3 id="선-테스트통과-후-청소">선 테스트통과 후 청소</h3>

<ul>
  <li>5장에서 실제로 새로운 테스트 케이스를 하나 작동하게 만듦</li>
  <li>하지만 테스트를 빨리 통과하기 위해 몇 톤이나 되는 코드를 복사해서 붙이는 엄청난 죄를 저지름</li>
  <li>이제 청소할 시간</li>
</ul>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// !! 두 클래스의 공통 상위 클래스 찾기</span>

<span class="c1">// Money - Dollar, Franc</span>
<span class="c1">// Money 클래스가 공통의 equals 코드 갖게 하면 어떨까?</span>
<span class="kd">class</span> <span class="nc">Money</span>

<span class="c1">// Dollar 가 Money 를 상속</span>
<span class="kd">class</span> <span class="nc">Dollar</span> <span class="kd">extends</span> <span class="nc">Money</span> <span class="o">{</span>
	<span class="kd">private</span> <span class="kt">int</span> <span class="n">amount</span><span class="o">;</span>
<span class="o">}</span>

<span class="c1">// amount 인스턴스 변수를 Money 로 옮김</span>
<span class="c1">// 하위 클래스에서도 변수를 볼 수 있도록 가시성을 private 에서 protected 로 변경</span>
<span class="kd">class</span> <span class="nc">Money</span> <span class="o">{</span>
	<span class="kd">protected</span> <span class="kt">int</span> <span class="n">amount</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">class</span> <span class="nc">Dollar</span> <span class="kd">extends</span> <span class="nc">Money</span> <span class="o">{</span> <span class="o">}</span>

<span class="c1">// equals() 코드를 위(class Money)로 올리기</span>
<span class="c1">// 케스트(cast) 부분 변경 및 임시 변수 명칭 변경</span>
<span class="c1">// 이러면 이제 equals() 메서드를 Dollar 에서 Money 로 옮길 수 있다.</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="nc">Object</span> <span class="n">object</span><span class="o">)</span> <span class="o">{</span>
	<span class="nc">Money</span> <span class="n">money</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Money</span><span class="o">)</span> <span class="n">object</span><span class="o">;</span> <span class="c1">// before : Money dollar = (Dollar) object;</span>
	<span class="k">return</span> <span class="n">amount</span> <span class="o">=</span> <span class="n">money</span><span class="o">.</span><span class="na">amount</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="francequals-제거">Franc.equals() 제거</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 테스트 작성 (Dollar 테스트 복사)</span>
<span class="c1">// 또 중복 존재 (두 줄이나 더!)</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testEquality</span><span class="o">()</span> <span class="o">{</span>
	<span class="n">assertTrue</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">).</span><span class="na">equals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">)));</span>
	<span class="n">assertFalse</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">).</span><span class="na">equals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">6</span><span class="o">)));</span>
	<span class="n">assertTrue</span><span class="o">(</span><span class="k">new</span> <span class="nc">Franc</span><span class="o">(</span><span class="mi">5</span><span class="o">).</span><span class="na">equals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Franc</span><span class="o">(</span><span class="mi">5</span><span class="o">)));</span>
	<span class="n">assertFalse</span><span class="o">(</span><span class="k">new</span> <span class="nc">Franc</span><span class="o">(</span><span class="mi">5</span><span class="o">).</span><span class="na">equals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Franc</span><span class="o">(</span><span class="mi">6</span><span class="o">)));</span>
<span class="o">}</span>

<span class="c1">// Money 상속 및 amount 필드 제거</span>
<span class="kd">class</span> <span class="nc">Franc</span> <span class="kd">extends</span> <span class="nc">Money</span> <span class="o">{</span>
	<span class="kd">private</span> <span class="kt">int</span> <span class="n">amount</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">class</span> <span class="nc">Franc</span> <span class="kd">extends</span> <span class="nc">Money</span> <span class="o">{</span> <span class="o">}</span>

<span class="c1">// Franc.equals() 는 Money.equals() 와 거의 비슷</span>
<span class="c1">// Franc 의 불필요한 코드 제거 (Money 로 옮김)</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="nc">Object</span> <span class="n">object</span><span class="o">)</span> <span class="o">{</span>
	<span class="nc">Money</span> <span class="n">money</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Money</span><span class="o">)</span> <span class="n">object</span><span class="o">;</span> <span class="c1">// before : Money franc = (Franc) object;</span>
	<span class="k">return</span> <span class="n">amount</span> <span class="o">==</span> <span class="n">money</span><span class="o">.</span><span class="na">amonut</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<ul>
  <li>공통된 코드를 첫 번째 클래스(Dollar) 에서 상위 클래스(Money) 로 단계적으로 옮김 (Franc 도 마찬가지)</li>
  <li>불필요한 구현을 제거하기 전에 두 equals() 구현을 일치시킴</li>
</ul>

<h2 id="7장-사과와-오렌지-서로-다른-걸-비교할-수-없다">7장. 사과와 오렌지 (서로 다른 걸 비교할 수 없다)</h2>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Franc 과 Dollar 를 비교</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testEquality</span><span class="o">()</span> <span class="o">{</span>
	<span class="n">assertFalse</span><span class="o">(</span><span class="k">new</span> <span class="nc">Franc</span><span class="o">(</span><span class="mi">5</span><span class="o">).</span><span class="na">equals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">)));</span>
<span class="o">}</span>

<span class="c1">// 동치성 코드에서는 Dollar 가 Franc 과 비교되지 않는지 검사해야 함</span>
<span class="c1">// 두 객체의 클래스를 비교해서, 오직 금액과 클래스가 서로 동일할 때만 두 Money 가 서로 같은 것이다.</span>
<span class="c1">// 혼합된 통화 간의 연산에 대해 다루어야 함</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="nc">Object</span> <span class="n">object</span><span class="o">)</span> <span class="o">{</span>
	<span class="nc">Money</span> <span class="n">money</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Money</span><span class="o">)</span> <span class="n">object</span><span class="o">;</span>
	<span class="k">return</span> <span class="n">amount</span> <span class="o">==</span> <span class="n">money</span><span class="o">.</span><span class="na">amount</span> <span class="o">&amp;&amp;</span> <span class="n">getClass</span><span class="o">().</span><span class="na">equals</span><span class="o">(</span><span class="n">money</span><span class="o">.</span><span class="na">getClass</span><span class="o">());</span>
<span class="o">}</span>

</code></pre></div></div>

<h2 id="8장-객체-만들기">8장. 객체 만들기</h2>

<h3 id="팩토리-메서드-패턴-factory-method-pattern">팩토리 메서드 패턴 (Factory Method Pattern)</h3>

<ul>
  <li>객체 생성(인스턴스화)을 서브클래스에 위임하여, 클래스 간의 결합도를 낮추는 생성 디자인 패턴</li>
  <li>즉, 객체를 직접 생성하지 않고, 객체 생성을 위한 인터페이스만 정의하고, 실제 생성은 서브클래스에서 담당</li>
  <li>객체 생성을 캡슐화하여, 코드의 유연성과 확장성을 높인다.</li>
  <li>장점
    <ul>
      <li>확장성 향상 : 새로운 객체 생성 로직이 필요할 때, 기존 코드를 수정하지 않고 새로운 팩토리 클래스만 만들면 됨</li>
      <li>느슨한 결합 : 클라이언트는 어떤 구체적인 클래스가 생성되는지 몰라도 됨</li>
    </ul>
  </li>
  <li>단점
    <ul>
      <li>클래스 수 증가 : 구체 팩토리 및 제품 클래스가 많아질 수 있음</li>
      <li>과한 구조 : 단순 객체 생성에는 과한 구조</li>
    </ul>
  </li>
</ul>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 1. Product</span>
<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Animal</span> <span class="o">{}</span>

<span class="c1">// 2. Concrete Product</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Dog</span> <span class="kd">implements</span> <span class="nc">Animal</span> <span class="o">{}</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Cat</span> <span class="kd">implements</span> <span class="nc">Animal</span> <span class="o">{}</span>

<span class="c1">// 3. Creator</span>
<span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">AnimalFactory</span> <span class="o">{</span>
	<span class="kd">public</span> <span class="kd">abstract</span> <span class="nc">Animal</span> <span class="nf">createAnimal</span><span class="o">();</span>
<span class="o">}</span>

<span class="c1">// 4. Concrete Creator</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">DogFactory</span> <span class="kd">extends</span> <span class="nc">AnimalFactory</span> <span class="o">{</span>
	<span class="kd">public</span> <span class="nc">Animal</span> <span class="nf">createAnimal</span><span class="o">()</span> <span class="o">{</span>
		<span class="k">return</span> <span class="k">new</span> <span class="nf">Dog</span><span class="o">();</span>
	<span class="o">}</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">CatFactory</span> <span class="kd">extends</span> <span class="nc">AnimalFactory</span> <span class="o">{</span>
	<span class="kd">public</span> <span class="nc">Animal</span> <span class="nf">createAnimal</span><span class="o">()</span> <span class="o">{</span>
		<span class="k">return</span> <span class="k">new</span> <span class="nf">Cat</span><span class="o">();</span>
	<span class="o">}</span>
<span class="o">}</span>

<span class="c1">// Client</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Main</span> <span class="o">{</span>
	<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
		<span class="nc">AnimalFactory</span> <span class="n">factory</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">DogFactory</span><span class="o">();</span> <span class="c1">// 팩토리 변경시 생성 객체 변경</span>
		<span class="nc">Animal</span> <span class="n">animal</span> <span class="o">=</span> <span class="n">factory</span><span class="o">.</span><span class="na">createAnimal</span><span class="o">();</span>
	<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="두-times-구현-코드가-거의-동일">두 times() 구현 코드가 거의 동일</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Franc</span> <span class="nf">times</span><span class="o">(</span><span class="kt">int</span> <span class="n">multiplier</span><span class="o">)</span> <span class="o">{</span>
	<span class="k">return</span> <span class="k">new</span> <span class="nf">Franc</span><span class="o">(</span><span class="n">amount</span> <span class="o">*</span> <span class="n">multiplier</span><span class="o">);</span>
<span class="o">}</span>
<span class="nc">Dollar</span> <span class="nf">times</span><span class="o">(</span><span class="kt">int</span> <span class="n">multiplier</span><span class="o">)</span> <span class="o">{</span>
	<span class="k">return</span> <span class="k">new</span> <span class="nf">Dollar</span><span class="o">(</span><span class="n">amount</span> <span class="o">*</span> <span class="n">multiplier</span><span class="o">);</span>
<span class="o">}</span>

<span class="c1">// 양쪽 모두 Money 반환하게 만들어 더 비슷하게 만들 수 있음</span>
<span class="nc">Money</span> <span class="nf">times</span><span class="o">(</span><span class="kt">int</span> <span class="n">multiplier</span><span class="o">)</span> <span class="o">{</span>
	<span class="k">return</span> <span class="k">new</span> <span class="nf">Franc</span><span class="o">(</span><span class="n">amount</span> <span class="o">*</span> <span class="n">multiplier</span><span class="o">);</span>
<span class="o">}</span>
<span class="nc">Money</span> <span class="nf">times</span><span class="o">(</span><span class="kt">int</span> <span class="n">multiplier</span><span class="o">)</span> <span class="o">{</span>
	<span class="k">return</span> <span class="k">new</span> <span class="nf">Dollar</span><span class="o">(</span><span class="n">amount</span> <span class="o">*</span> <span class="n">multiplier</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<ul>
  <li>Money 의 두 하위 클래스의 역할이 거의 없어, 제거하면 좋아보임</li>
  <li>하위 클래스에 대한 직접적인 참조가 적어진다면 하위 클래스를 제거하기 위해 한 발짝 더 다가선 것</li>
  <li>Money 클래스에 Dollar 를 반환하는 팩토리 메서드(Factory Method) 도입 가능</li>
</ul>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 테스트 코드</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testMultiplication</span><span class="o">()</span> <span class="o">{</span>
	<span class="nc">Dollar</span> <span class="n">five</span> <span class="o">=</span> <span class="nc">Money</span><span class="o">.</span><span class="na">dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">);</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">10</span><span class="o">),</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">2</span><span class="o">));</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">15</span><span class="o">),</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">3</span><span class="o">));</span>
<span class="o">}</span>

<span class="c1">// Money.dollar()</span>
<span class="kd">static</span> <span class="nc">Dollar</span> <span class="nf">dollar</span><span class="o">(</span><span class="kt">int</span> <span class="n">amount</span><span class="o">)</span> <span class="o">{</span>
	<span class="k">return</span> <span class="k">new</span> <span class="nf">Dollar</span><span class="o">(</span><span class="n">amount</span><span class="o">);</span>
<span class="o">}</span>

<span class="c1">// Dollar 에 대한 참조가 사라지길 바라며 테스트 선언부 아래와 같이 변경</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testMultiplication</span><span class="o">()</span> <span class="o">{</span>
	<span class="nc">Money</span> <span class="n">five</span> <span class="o">=</span> <span class="nc">Money</span><span class="o">.</span><span class="na">dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">);</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">10</span><span class="o">),</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">2</span><span class="o">));</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Dollar</span><span class="o">(</span><span class="mi">15</span><span class="o">),</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">3</span><span class="o">));</span>
<span class="o">}</span>

<span class="c1">// Money 에는 times() 정의되지 않아서, Money 를 추상 클래스로 변경 후 times() 선언</span>
<span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">Money</span>
<span class="kd">abstract</span> <span class="nc">Money</span> <span class="nf">times</span><span class="o">(</span><span class="kt">int</span> <span class="n">multiplier</span><span class="o">);</span>

<span class="c1">// 팩토리 메서드 변경</span>
<span class="kd">static</span> <span class="nc">Money</span> <span class="nf">dollar</span><span class="o">(</span><span class="kt">int</span> <span class="n">amount</span><span class="o">)</span> <span class="o">{</span>
	<span class="k">return</span> <span class="k">new</span> <span class="nf">Dollar</span><span class="o">(</span><span class="n">amount</span><span class="o">);</span>
<span class="o">}</span>

<span class="c1">// 테스트 코드에 팩토리 메서드 적용</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testMultiplication</span><span class="o">()</span> <span class="o">{</span>
	<span class="nc">Money</span> <span class="n">five</span> <span class="o">=</span> <span class="nc">Money</span><span class="o">.</span><span class="na">dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">);</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="nc">Money</span><span class="o">.</span><span class="na">dollar</span><span class="o">(</span><span class="mi">10</span><span class="o">),</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">2</span><span class="o">));</span> <span class="c1">// 적용</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="nc">Money</span><span class="o">.</span><span class="na">dollar</span><span class="o">(</span><span class="mi">15</span><span class="o">),</span> <span class="n">five</span><span class="o">.</span><span class="na">times</span><span class="o">(</span><span class="mi">3</span><span class="o">));</span> <span class="c1">// 적용</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testEquality</span><span class="o">()</span> <span class="o">{</span>
	<span class="n">assertTrue</span><span class="o">(</span><span class="nc">Money</span><span class="o">.</span><span class="na">dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">).</span><span class="na">equals</span><span class="o">(</span><span class="nc">Money</span><span class="o">.</span><span class="na">dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">)));</span> <span class="c1">// 적용</span>
	<span class="n">assertFalse</span><span class="o">(</span><span class="nc">Money</span><span class="o">.</span><span class="na">dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">).</span><span class="na">equals</span><span class="o">(</span><span class="nc">Money</span><span class="o">.</span><span class="na">dollar</span><span class="o">(</span><span class="mi">6</span><span class="o">)));</span> <span class="c1">// 적용</span>
	<span class="n">assertTrue</span><span class="o">(</span><span class="k">new</span> <span class="nc">Franc</span><span class="o">(</span><span class="mi">5</span><span class="o">).</span><span class="na">equals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Franc</span><span class="o">(</span><span class="mi">5</span><span class="o">)));</span>
	<span class="n">assertFalse</span><span class="o">(</span><span class="k">new</span> <span class="nc">Franc</span><span class="o">(</span><span class="mi">5</span><span class="o">).</span><span class="na">equals</span><span class="o">(</span><span class="k">new</span> <span class="nc">Franc</span><span class="o">(</span><span class="mi">6</span><span class="o">)));</span>
	<span class="n">assertFalse</span><span class="o">(</span><span class="k">new</span> <span class="nc">Franc</span><span class="o">(</span><span class="mi">5</span><span class="o">).</span><span class="na">equals</span><span class="o">(</span><span class="nc">Money</span><span class="o">.</span><span class="na">dollar</span><span class="o">(</span><span class="mi">5</span><span class="o">)));</span> <span class="c1">// 적용</span>
<span class="o">}</span>
</code></pre></div></div>

<ul>
  <li>위처럼 어떤 클라이언트 코드도 Dollar 라는 이름의 하위 클래스가 있다는 사실을 모른다.</li>
  <li>하위 클래스의 존재를 테스트에서 분리(decoupling)함으로써 어떤 모델 코드에도 영향을 주지 않고 상속 구조를 마음대로 변경할 수 있게 됐다.</li>
</ul>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Franc 도 팩토리 메서드 적용</span>
<span class="kd">static</span> <span class="nc">Money</span> <span class="nf">franc</span><span class="o">(</span><span class="kt">int</span> <span class="n">amount</span><span class="o">)</span> <span class="o">{</span>
	<span class="k">return</span> <span class="k">new</span> <span class="nf">Franc</span><span class="o">(</span><span class="n">amount</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="9장-우리가-사는-시간time--곱하기">9장. 우리가 사는 시간(time = 곱하기)</h2>

<h3 id="통화-개념을-어떻게-테스트할까">통화 개념을 어떻게 테스트할까?</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">void</span> <span class="nf">testCurrency</span><span class="o">()</span> <span class="o">{</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="s">"USD"</span><span class="o">,</span> <span class="nc">Money</span><span class="o">.</span><span class="na">dollar</span><span class="o">(</span><span class="mi">1</span><span class="o">).</span><span class="na">currency</span><span class="o">());</span>
	<span class="n">assertEquals</span><span class="o">(</span><span class="s">"CHF"</span><span class="o">,</span> <span class="nc">Money</span><span class="o">.</span><span class="na">franc</span><span class="o">(</span><span class="mi">1</span><span class="o">).</span><span class="na">currency</span><span class="o">());</span>
<span class="o">}</span>

<span class="c1">// Money 에 currency() 메서드 선언 및 하위 클래스에 구현</span>
<span class="c1">// Money</span>
<span class="kd">abstract</span> <span class="nc">String</span> <span class="nf">currency</span><span class="o">();</span>

<span class="c1">// Franc</span>
<span class="nc">String</span> <span class="nf">currency</span><span class="o">()</span> <span class="o">{</span>
	<span class="k">return</span> <span class="s">"CHF"</span><span class="o">;</span>
<span class="o">}</span>

<span class="c1">// Dollar</span>
<span class="nc">String</span> <span class="nf">currency</span><span class="o">()</span> <span class="o">{</span>
	<span class="k">return</span> <span class="s">"USD"</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<ul>
  <li>두 클래스를 모두 포함할 수 있는 동일한 구현이 되어야 한다.</li>
  <li>통화를 인스턴스 변수에 저장하고, 메서드에서는 그냥 그걸 반환하게 만들 수 있게 (equals 테스트를 위해)</li>
</ul>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Franc</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">currency</span><span class="o">;</span>
<span class="nc">Franc</span><span class="o">(</span><span class="kt">int</span> <span class="n">amount</span><span class="o">)</span> <span class="o">{</span>
	<span class="k">this</span><span class="o">.</span><span class="na">amount</span> <span class="o">=</span> <span class="n">amount</span><span class="o">;</span>
	<span class="n">currency</span> <span class="o">=</span> <span class="s">"CHF"</span><span class="o">;</span>
<span class="o">}</span>
<span class="nc">String</span> <span class="nf">currency</span><span class="o">()</span> <span class="o">{</span>
	<span class="k">return</span> <span class="n">currency</span><span class="o">;</span>
<span class="o">}</span>

<span class="c1">// Dollar</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">currency</span><span class="o">;</span>
<span class="nc">Dollar</span><span class="o">(</span><span class="kt">int</span> <span class="n">amount</span><span class="o">)</span> <span class="o">{</span>
	<span class="k">this</span><span class="o">.</span><span class="na">amount</span> <span class="o">=</span> <span class="n">amount</span><span class="o">;</span>
	<span class="n">currency</span> <span class="o">=</span> <span class="s">"USD"</span><span class="o">;</span>
<span class="o">}</span>
<span class="nc">String</span> <span class="nf">currency</span><span class="o">()</span> <span class="o">{</span>
	<span class="k">return</span> <span class="n">currency</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<ul>
  <li>두 currency() 가 동일하므로, 변수 선언과 currency() 구현을 둘다 위로 올릴 수 있게 됐다.</li>
</ul>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Money</span>
<span class="kd">protected</span> <span class="nc">String</span> <span class="n">currency</span><span class="o">;</span>
<span class="nc">String</span> <span class="nf">currency</span><span class="o">()</span> <span class="o">{</span>
	<span class="k">return</span> <span class="n">currency</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="25년-7월-28일-일시정지">25년 7월 28일 일시정지</h2>]]></content><author><name></name></author><category term="TestDrivenDevelop" /><summary type="html"><![CDATA[화폐 예제]]></summary></entry><entry><title type="html">Test Driven Develop - 1</title><link href="https://qkrrlgh519.github.io/testdrivendevelop/2025/05/20/Test-Driven-Develop-1.html" rel="alternate" type="text/html" title="Test Driven Develop - 1" /><published>2025-05-20T03:00:00+00:00</published><updated>2025-05-20T03:00:00+00:00</updated><id>https://qkrrlgh519.github.io/testdrivendevelop/2025/05/20/Test-Driven-Develop-1</id><content type="html" xml:base="https://qkrrlgh519.github.io/testdrivendevelop/2025/05/20/Test-Driven-Develop-1.html"><![CDATA[<h1 id="tdd-수련법">TDD 수련법</h1>

<h2 id="hello-java">Hello Java</h2>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">HelloJava</span> <span class="o">{</span>
	<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
		<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Hello Java"</span><span class="o">);</span>
	<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<ul>
  <li>파일명과 클래스의 이름은 같아야 한다.</li>
  <li><code class="language-plaintext highlighter-rouge">{}</code> 블록을 사용해서 클래스, 메서드의 시작과 끝을 나타낸다.</li>
</ul>

<h2 id="참고--괄호">참고 : 괄호</h2>

<ul>
  <li>소괄호 : <code class="language-plaintext highlighter-rouge">()</code></li>
  <li>중괄호 : <code class="language-plaintext highlighter-rouge">{}</code></li>
  <li>대괄호 : <code class="language-plaintext highlighter-rouge">[]</code></li>
</ul>

<h2 id="주석-comment">주석 (Comment)</h2>

<h2 id="25년-7월-28일-일시정지">25년 7월 28일 일시정지</h2>]]></content><author><name></name></author><category term="TestDrivenDevelop" /><summary type="html"><![CDATA[TDD 수련법]]></summary></entry><entry><title type="html">Java - Basic1</title><link href="https://qkrrlgh519.github.io/java/2025/05/19/Java-Basic1.html" rel="alternate" type="text/html" title="Java - Basic1" /><published>2025-05-19T03:00:00+00:00</published><updated>2025-05-19T03:00:00+00:00</updated><id>https://qkrrlgh519.github.io/java/2025/05/19/Java-Basic1</id><content type="html" xml:base="https://qkrrlgh519.github.io/java/2025/05/19/Java-Basic1.html"><![CDATA[<h1 id="java---basic1">Java - Basic1</h1>

<h2 id="hello-java">Hello Java</h2>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">HelloJava</span> <span class="o">{</span>
	<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
		<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Hello Java"</span><span class="o">);</span>
	<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<ul>
  <li>파일명과 클래스의 이름은 같아야 한다.</li>
  <li><code class="language-plaintext highlighter-rouge">{}</code> 블록을 사용해서 클래스, 메서드의 시작과 끝을 나타낸다.</li>
</ul>

<h2 id="참고--괄호">참고 : 괄호</h2>

<ul>
  <li>소괄호 : <code class="language-plaintext highlighter-rouge">()</code></li>
  <li>중괄호 : <code class="language-plaintext highlighter-rouge">{}</code></li>
  <li>대괄호 : <code class="language-plaintext highlighter-rouge">[]</code></li>
</ul>

<h2 id="주석-comment">주석 (Comment)</h2>

<ul>
  <li>25년 7월 28일 일시정지</li>
</ul>]]></content><author><name></name></author><category term="Java" /><summary type="html"><![CDATA[Java - Basic1]]></summary></entry><entry><title type="html">BOJ[1138] - 한 줄로 서기 by JavaScript</title><link href="https://qkrrlgh519.github.io/boj(greedy)/2025/03/23/BOJ-Greedy-1138.html" rel="alternate" type="text/html" title="BOJ[1138] - 한 줄로 서기 by JavaScript" /><published>2025-03-23T12:30:00+00:00</published><updated>2025-03-23T12:30:00+00:00</updated><id>https://qkrrlgh519.github.io/boj(greedy)/2025/03/23/BOJ-Greedy-1138</id><content type="html" xml:base="https://qkrrlgh519.github.io/boj(greedy)/2025/03/23/BOJ-Greedy-1138.html"><![CDATA[<h1 id="한-줄로-서기">한 줄로 서기</h1>

<h2 id="문제">문제</h2>

<ul>
  <li><a href="https://www.acmicpc.net/problem/1138">백준 1138번 - 한 줄로 서기</a></li>
</ul>

<h2 id="언어">언어</h2>

<ul>
  <li>JavaScript</li>
</ul>

<h2 id="순서도">순서도</h2>

<ol>
  <li>1 번 사람부터 N 번 사람까지 각 사람마다</li>
  <li>왼쪽 키 큰 사람 수 만큼 오른쪽으로 이동하며 위치 구하기</li>
  <li>이 때, 왼쪽 키 큰 사람 수가 0 인 경우와 1 이상인 경우를 나누기
    <ol>
      <li>왼쪽 키 큰 사람 수가 0 인 경우, 이미 자리가 찬 위치 만큼 오른쪽으로 이동</li>
      <li>왼쪽 키 큰 사람 수가 1 이상인 경우, 이미 자리가 찬 위치 만큼 오른쪽으로 이동하고, 이에 더해서 왼쪽 키 큰 사람 수 만큼 오른쪽으로 이동</li>
    </ol>
  </li>
  <li>구한 위치에 사람 위치시키기</li>
</ol>

<h2 id="문제-풀이-step-1">문제 풀이 step 1</h2>

<ul>
  <li>N 명의 사람이 주어집니다.</li>
  <li>각 사람은 자기 위치에서 자기보다 키가 큰 사람이 왼쪽에 몇 명 있는지 주어집니다. (단, 사람들의 키는 1 부터 N 까지 모두 다릅니다.)</li>
  <li>이 때, 각 사람의 위치를 구하는 문제입니다.</li>
</ul>

<h2 id="문제-풀이-step-2">문제 풀이 step 2</h2>

<ul>
  <li>본 문제는 그리디 방식으로 풀 수 있습니다.</li>
  <li>매 순서마다 현재 상황에서 가장 최선의 선택(가장 적합한 위치)만 하면 되기 때문입니다.</li>
  <li>예를 들어, 1번 사람 왼쪽에 2명이 있고, 2번 사람 왼쪽에 3명이 있다고 가정하겠습니다.
    <ul>
      <li>1번 사람의 경우, 왼쪽에서 3번째 위치에 위치하게 됩니다. (<code class="language-plaintext highlighter-rouge">[ ][ ][1][ ][ ]</code>)</li>
      <li>2번 사람의 경우, 왼쪽에서 4번째 위치에 위치하게 됩니다. 단, 1번 사람의 위치를 고려해야 합니다.
        <ul>
          <li>하지만 1번 사람의 위치를 고려하는 것은 어렵지 않습니다. 왜냐하면 1번 사람은 무조건 2번 사람보다 작기 때문입니다.</li>
          <li>즉, 1번 사람은 무조건 작기 때문에 <code class="language-plaintext highlighter-rouge">[ ][ ][1][ ][ ]</code> =&gt; <code class="language-plaintext highlighter-rouge">[ ][ ][ ][ ]</code> 과 같이 1번 사람을 제외시킬 수 있고, 현재 위치에서 2번 사람을 4번째 위치에 넣으면 되는 것입니다.</li>
          <li>즉, <code class="language-plaintext highlighter-rouge">[ ][ ][ ][2]</code> 처럼 넣게 될 것이고, 여기에 아까 1번 사람의 위치를 기억했다가 다시 넣으면 <code class="language-plaintext highlighter-rouge">[ ][ ][1][ ][2]</code> 과 같이 될 것입니다.</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>물론 위 방식은 쉽게 설명하고, 그리디 방식에 어울리게 설명을 하기 위해서 약간 번거로운 과정이 들어갔습니다.</li>
  <li>실제로 구현할 때는 1번 사람의 위치를 기억했다가 다시 넣기보다는 1번 사람과 같이 이미 위치한 사람만큼 오른쪽으로 이동하면 될 것입니다.</li>
</ul>

<h2 id="후기">후기</h2>

<ul>
  <li>구현 방식의 알고리즘을 풀고 싶어서 문제를 찾았지만, 구현 보다는 그리디 성향이 더 강하기 때문에 그리디 알고리즘으로 분류하게 되었습니다.</li>
  <li>처음에는 구현 방식의 완전 탐색으로 풀어볼까 했지만, 그리디 알고리즘이 더 적합하고 로직이 간단해지기 때문에 그리디 방식을 선택하게 되었습니다.</li>
  <li>그리디 방식은 항상 느끼지만 문제 안에 숨어있는 명확한 조건 (ex. 이전 순서에서 진행한 로직은 다음 순서에서는 상관이 없다 : 1번 사람을 위치시키면 2번 사람에게는 아무 영향이 없다) 을 찾는게 중요한거 같습니다.</li>
</ul>

<h2 id="소스-코드">소스 코드</h2>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">input</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">"</span><span class="s2">fs</span><span class="dl">"</span><span class="p">)</span>
	<span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="dl">"</span><span class="s2">/dev/stdin</span><span class="dl">"</span><span class="p">)</span>
	<span class="p">.</span><span class="nx">toString</span><span class="p">()</span>
	<span class="p">.</span><span class="nx">trim</span><span class="p">()</span>
	<span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="dl">"</span><span class="se">\n</span><span class="dl">"</span><span class="p">);</span>

<span class="kd">const</span> <span class="nx">solution</span> <span class="o">=</span> <span class="p">(</span><span class="nx">input</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
	<span class="kd">const</span> <span class="nx">n</span> <span class="o">=</span> <span class="nb">Number</span><span class="p">(</span><span class="nx">input</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
	<span class="kd">const</span> <span class="nx">cntOfLeft</span> <span class="o">=</span> <span class="nx">input</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">split</span><span class="p">(</span><span class="dl">"</span><span class="s2"> </span><span class="dl">"</span><span class="p">).</span><span class="nx">map</span><span class="p">(</span><span class="nb">Number</span><span class="p">);</span>
	<span class="kd">const</span> <span class="nx">answer</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="k">from</span><span class="p">({</span><span class="na">length</span><span class="p">:</span> <span class="nx">n</span><span class="p">},</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>

	<span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
		<span class="c1">// 왼쪽 키 큰 사람 수</span>
		<span class="kd">let</span> <span class="nx">cnt</span> <span class="o">=</span> <span class="nx">cntOfLeft</span><span class="p">[</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">];</span>

		<span class="c1">// 각 사람의 위치 구하기</span>
		<span class="kd">let</span> <span class="nx">index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

		<span class="c1">// 왼쪽 키 큰 사람 수가 0 인 경우</span>
		<span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">j</span> <span class="o">&lt;</span> <span class="nx">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
			<span class="k">if</span> <span class="p">(</span><span class="nx">answer</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span> <span class="o">===</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>

			<span class="c1">// 이미 위치한 사람 수 만큼 오른쪽으로 이동</span>
			<span class="nx">index</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
		<span class="p">}</span>

		<span class="c1">// 왼쪽 키 큰 사람 수가 1 이상인 경우</span>
		<span class="k">while</span> <span class="p">(</span><span class="nx">cnt</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
			<span class="c1">// 왼쪽 키 큰 사람 수 만큼 오른쪽으로 이동</span>
			<span class="nx">index</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>

			<span class="c1">// 이동한 위치에 사람이 있다면 cnt 감소되지 않게 처리</span>
			<span class="k">if</span> <span class="p">(</span><span class="nx">answer</span><span class="p">[</span><span class="nx">index</span><span class="p">]</span> <span class="o">!==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>

			<span class="c1">// 오른쪽으로 이동한 만큼 cnt 감소</span>
			<span class="nx">cnt</span> <span class="o">-=</span> <span class="mi">1</span><span class="p">;</span>
		<span class="p">}</span>

		<span class="c1">// 해당 위치에 사람 넣기</span>
		<span class="nx">answer</span><span class="p">[</span><span class="nx">index</span><span class="p">]</span> <span class="o">=</span> <span class="nx">i</span><span class="p">;</span>
	<span class="p">}</span>

	<span class="k">return</span> <span class="nx">answer</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="dl">"</span><span class="s2"> </span><span class="dl">"</span><span class="p">);</span>
<span class="p">};</span>

<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">solution</span><span class="p">(</span><span class="nx">input</span><span class="p">));</span>
</code></pre></div></div>]]></content><author><name></name></author><category term="BOJ(Greedy)" /><summary type="html"><![CDATA[한 줄로 서기]]></summary></entry><entry><title type="html">2024 년 회고</title><link href="https://qkrrlgh519.github.io/story/2024/12/31/2024-Retrospective.html" rel="alternate" type="text/html" title="2024 년 회고" /><published>2024-12-31T03:00:00+00:00</published><updated>2024-12-31T03:00:00+00:00</updated><id>https://qkrrlgh519.github.io/story/2024/12/31/2024-Retrospective</id><content type="html" xml:base="https://qkrrlgh519.github.io/story/2024/12/31/2024-Retrospective.html"><![CDATA[<h1 id="1-회사생활">1. 회사생활</h1>

<ul>
  <li>운영 시스템 고도화 프로젝트 참여
    <ul>
      <li>선배님들께 지속적으로 개발에 대한 뜻을 표현해서 그런지 이번에 프로젝트 개발건을 제게 맡겨 주셨습니다.</li>
      <li>에전부터 너무 해보고 싶었던 일이라 정말 즐겁게 일을 했던거 같습니다.</li>
      <li>시스템 운영과 프로젝트 개발건을 같이 진행하는 것이 쉽지만은 않았지만 그래도 정말 많은 것을 배울 수 있었던 시간이었습니다.</li>
      <li>단기적으로 시스템 개선건을 개발하는 것과는 다르게 프로젝트 개발건은 연속적으로 개발건이 계획되어 있다보니, 마감 기한 내 반드시 개발건을 쳐내야 했습니다.</li>
      <li>그렇다보니 주어진 설계를 빠르게 이해하고, 개발 방향과 어떤식으로 구현할지를 빠르게 결정하는 것이 정말 중요했습니다.</li>
      <li>저의 부족한 역량을 많이 찾을 수 있었으며, 그런 부분들은 반드시 개선해야겠습니다.
        <ul>
          <li>JSP 활용 능력, DB Query 작성 능력</li>
        </ul>
      </li>
      <li>그 외에도 프로젝트를 한다는 것은 단순히 설계, 개발만 하는 것이 아니라, 고객과의 지속적인 의사소통, 외주 개발자 인력 관리, 산출물 관리, 전체적인 일정 관리 등등 중요한 업무가 많다는 것을 알게 되었습니다.</li>
      <li>회사 생활 중에 가장 재미있게 일했던 시간이었습니다.</li>
    </ul>
  </li>
  <li>새로운 트렌드 파악 및 아이디어 탐구
    <ul>
      <li>회사 생활을 하면서 깨닫게 된 저의 부족한 역량은 회사에서 매년 진행하는 금년도 과제를 선정하는 것입니다.</li>
      <li>팀의 목표에 맞게 내려오는 과제 외 별도 과제를 선정해야 하는데, 그런 부분에 참 어려운 것 같습니다.</li>
      <li>아직도 감을 잘 잡지는 못했지만, 과제를 잘 선정하기 위해서는 지속적으로 IT 트렌드 파악이 필요한 것 같습니다.</li>
      <li>꾸준히 타 회사의 개발 블로그를 참고하고, IT 컨퍼런스에 지속적인 관심을 가지는 것이 필요해보입니다.</li>
      <li>아직은 많이 부족하지만 이런 부분들도 잘 개선을 해서 나중에 리더급이 되었을 때, 좋은 과제를 선정할 수 있는 역량을 갖춰야겠습니다.</li>
    </ul>
  </li>
  <li>영어 공부 및 리눅스 마스터 2급
    <ul>
      <li>금년도는 진급년차였기 때문에 영어 인증도 따고, 리눅스 마스터 2급이라는 자격증도 취득하였습니다.</li>
      <li>오랜만에 영어 공부를 해서 너무 즐거웠고, 토스를 했는데 생각보다 어렵진 않았던 것 같습니다.</li>
      <li>리눅스에 대해서 공부하는 것도 되게 즐거웠습니다. 과거를 공부하는 기분이었습니다.</li>
    </ul>
  </li>
  <li>업무의 우선순위
    <ul>
      <li>개인의 과제보다는 팀의 과제를 우선적으로 진행하는 것이 중요하다는 것을 깨달았습니다.</li>
      <li>아직은 업무의 순서를 정하고, 진행시킬 수 있는 위치가 아니기 때문에 우선은 해당 가르침에 대해서 잘 기억하고 있는게 중요할 거 같습니다.</li>
    </ul>
  </li>
  <li>보안 관련
    <ul>
      <li>고객에게 편리함을 주기 위해서 보안 관련된 문제의 우선순위를 낮게 생각해서는 안된다는 것을 깨달았습니다.</li>
    </ul>
  </li>
</ul>

<h1 id="2-개인생활">2. 개인생활</h1>

<ul>
  <li>가족 여행
    <ul>
      <li>예전부터 부문리더님이 꼭 효도여행을 다녀오라고 얘기해주셨는데, 3년차가 되어서야 가게 되었습니다.</li>
      <li>효도 여행에 대한 무서운 얘기가 많아서 가기 전에 엄청 걱정했는데, 다행히도 불평 하나 없이 제 의견에 따라주셔서 너무 잘 다녀왔습니다.</li>
      <li>이렇게 좋아하실줄 알았으면 진작에 다녀올걸 그랬습니다.</li>
    </ul>
  </li>
</ul>

<h1 id="3-느낀점">3. 느낀점</h1>

<ul>
  <li>나중에 PL, PM 으로서의 역할을 하기 위해서는 지금 많이 개발 경험을 쌓아놓아야겠다는 생각을 많이 했습니다.</li>
  <li>개발을 하는 것은 역시나 재미있다는 것을 다시 깨달았고, 너무 즐겁게 일했습니다.</li>
  <li>현재는 개발만 잘 하면 되겠지만, 추후에는 설계에 대한 역량도 필요할 것이고, 화면 시안을 만들어내는 역량도 필요하고, 좋은 기능을 생각해내는 역량도 필요하겠습니다.</li>
  <li>또한 프로젝트 인력 관리와 고객과의 소통능력 그리고 정확한 일정과 계획을 세우는 능력도 많이 필요하겠습니다.</li>
  <li>현재 저의 위치에서는 우선 개발 역량과 설계 역량을 키워야 하니, SQLP 자격증을 따고 DB 역량을 키우는 것이 필요해보입니다.</li>
</ul>

<h1 id="4-비고">4. 비고</h1>

<ul>
  <li>시간이 많이 지나고 나서 작성을 해서, 최대한 기억나는 내용만 작성하였습니다.</li>
</ul>]]></content><author><name></name></author><category term="Story" /><summary type="html"><![CDATA[1. 회사생활]]></summary></entry><entry><title type="html">2023 년 회고</title><link href="https://qkrrlgh519.github.io/story/2023/12/31/2023-Retrospective.html" rel="alternate" type="text/html" title="2023 년 회고" /><published>2023-12-31T03:00:00+00:00</published><updated>2023-12-31T03:00:00+00:00</updated><id>https://qkrrlgh519.github.io/story/2023/12/31/2023-Retrospective</id><content type="html" xml:base="https://qkrrlgh519.github.io/story/2023/12/31/2023-Retrospective.html"><![CDATA[<h1 id="1-회사생활">1. 회사생활</h1>

<ul>
  <li>파트장님께서 SQL Query Quiz 를 내주시고, 교육시켜주셨습니다.
    <ul>
      <li>잊지못할 시간이고, 너무나 많은 것을 배울 수 있었습니다.</li>
      <li>단순히 Query 짜는 방법을 알려주시지 않고, 원리를 이해주시켜주셨고, 사고력을 키워주셨습니다.</li>
      <li>파트장님께 너무 감사드리고, 항상 감사함을 잊지 않고 회사생활을 하겠습니다.</li>
    </ul>
  </li>
  <li>회사에서 등산 동호회에 가입하였습니다.
    <ul>
      <li>등산을 좋아하지만, 고소공포증이 있어서 항상 집 뒤에 있는 낮은 산만 올랐었는데, 북한산에 가보니 신세계였습니다.</li>
      <li>항상 올라가서 정상 찍고 올라온 길로 내려와봤는데, 올라가서 정상찍고 다른 곳으로 내려와보긴 처음입니다.
        <ul>
          <li>제가 기존에 하던 방식을 원점회귀라는 것을 처음 알게 되었습니다.</li>
        </ul>
      </li>
      <li>막내라서 그런가 총무까지 하게 되었습니다.</li>
    </ul>
  </li>
  <li>법인 카드를 받았습니다.
    <ul>
      <li>법인 카드로는 할인도 받으면 안된다는 것을 알게 되었습니다.</li>
    </ul>
  </li>
  <li>시스템과 업무에 대한 파악이 모두 완료되어서, 본격적으로 문의 대응과 시스템 개선건 개발을 진행하였습니다.
    <ul>
      <li>당연히 해야하는 일이지만, 고객의 문의대응에 대한 피드백으로 감사하다는 피드백을 받을 때면 되게 보람찬 기분을 느낄 수 있었습니다.</li>
      <li>취준생일 때 했던 개발과 다르게 운영 시스템을 개발하는 것은 방향성부터 달랐습니다.
        <ul>
          <li>영향도 분석이라는 것에 대해서 처음 알게 되었습니다.</li>
          <li>기존 소스코드 작성 스타일 기반으로 작성하는 방법도 배우게 되었습니다.</li>
          <li>고객의 요구사항은 계속해서 바뀌다보니, 특정 기능에 대해서 예상치 못한 방식으로 기능을 변경해야 하는 경우도 있다는 것을 알게 되었습니다.</li>
          <li>그렇다보니, 다른 시스템 운영자들이나 제 다음으로 시스템을 운영하게 될 후배분들 위해서 주석에 히스토리를 간단하게 남기게 되었습니다.</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>실수를 하고 태도를 바꾸게된 계기가 있습니다.
    <ul>
      <li>짧은 일정 내에 두 개 시스템의 개발건을 받게 되었습니다. (당시 팀원분들 모두 프로젝트를 하고 계신 상황)</li>
      <li>당시에 개발 업무를 너무 하고 싶기도 했고, 반드시 해내고 싶다는 뜨겁기만한 열정이 가득했습니다.</li>
      <li>영향도 분석을 했을 때, 일정이 어려울 수 있다는 생각을 했음에도 불구하고, 냉정하지 못하게 꾸역꾸역 야근을 해가면서 개발을 진행했습니다.</li>
      <li>한 개 시스템은 정상적으로 배포를 완료했지만, 다른 한 개 시스템은 확인해보니 적용이 안된 부분이 확인이 되어서, 원복하고 재배포를 진행했습니다.</li>
      <li>당시에 제 자신에게 정말 실망을 많이 했습니다. 왜 항상 감정만 앞서는지 그리고 일에 있어서 그런 실수를 하는지</li>
      <li>그 때 이후로 정신을 바싹 차리게 되었습니다. 다시는 그런 실수를 하고 싶지 않았고, 선배님께 너무 죄송했고, 선배님께서 저를 커버해주시는 상황을 만들고 싶지 않았습니다.</li>
      <li>그래서 이제는 뜨겁기만한 열정보다는 냉정한 이성으로 일정을 수립하고, 선배님과 적극적으로 소통해서 일정을 객관적으로 계획하게 되었습니다.</li>
      <li>당시에는 너무 부끄러웠고, 크게 상심했지만, 지금 생각해보면 예방주사를 빨리 잘 맞은거 같기도 합니다.</li>
    </ul>
  </li>
  <li>부문리더님께서 이직을 하셨습니다.
    <ul>
      <li>사수님이 팀을 옮기신 이후부터 바쁘신 와중에도 어떻게든 틈을 내서 교육을 해주시고, 케어를 해주셔서, 솔직히 정신적으로 많이 의지하게 되었습니다.</li>
      <li>업무적으로도 배울게 너무 많았고, 닮고 싶은 분인지라 이직하신다는 소리를 들었을 때, 막막한 기분이 들었지만 그래도 한번 경험했던 일인지라 약간은 덤덤할 수 있었습니다.</li>
      <li>그동안 잘 이끌어주시고, 많이 가르쳐주시고, 힘들때면 손내밀어주셔서 정말 감사했습니다.</li>
      <li>저에게 주신 좋은 영향력 꼭 주위 동료 및 후배분들께 그대로 전달드릴 수 있게 하겠습니다.</li>
      <li>항상 감사함을 잊지 않고 회사생활을 하겠습니다.</li>
    </ul>
  </li>
  <li>마음이 잘 통하시는 선배님이 저희 팀으로 오셨습니다.
    <ul>
      <li>좋은게 있다면 항상 알려주시고, 항상 분위기도 편안하게 만들어주셔서 감사합니다.</li>
      <li>선배님 덕분에 좀 더 회사분들과 친해질 수 있었습니다. 감사합니다.</li>
    </ul>
  </li>
</ul>

<h1 id="2-개인생활">2. 개인생활</h1>

<ul>
  <li>친구가 다니는 회사의 리그오브레전드 팀 대전에 참여했습니다.
    <ul>
      <li>대학생 시절이 많이 생각났고, 오랜만에 이 친구들과 하나의 목표를 바라보면서 같이 불탈 수 있는 시간을 느껴서 너무 행복했습니다.</li>
    </ul>
  </li>
  <li>드디어 민방위에 속하게 되었습니다. 좋으면서도 씁쓸한 기분입니다.</li>
  <li>친구들과 후쿠오카 여행을 다녀왔습니다.
    <ul>
      <li>성격이 많이 내향적이고 해외 여행을 사치라고 생각하는 경향이 있어서, 항상 친구들한테 안간다고만 했었는데, 이번에 처음 친구들과 해외 여행을 가봤습니다.</li>
      <li>친구들과 여행을 가는 것이 이렇게 즐거운건지 처음 알았습니다. 정말 행복한 시간이었습니다.</li>
      <li>후쿠오카 이치란 라멘 최고!! 유후인 야마노 무소엔 료칸 최고!!</li>
    </ul>
  </li>
  <li>스타크래프트를 참 좋아합니다. 그 중에 저그 김윤환 선수를 좋아합니다.
    <ul>
      <li>과거에 날카로운 플레이를 하는 선수 시절과는 다르게 이제는 시청자들에게 웃음을 주는 방송인이 되었지만 여전히 선수 시절의 열정이 아직 남아있는 모습이 인상깊었습니다.</li>
      <li>나이도 먹고 실력도 줄어서 예전만큼의 기량은 안나오지만, 자신의 팬들을 위해서 몇 달 동안 연습하고, 못한다고 비난을 받아도, 꺾이지 않고, 대회 예선을 뚫는 모습이 정말 감동적이었습니다.</li>
      <li>김윤환 선수의 그런 모습 덕분에 학교를 마치고 와서 OGN 을 틀고 스타를 보던 시절이 생각났습니다.</li>
    </ul>
  </li>
  <li>해커스 학원에 등록해서 일본어 공부를 했습니다.
    <ul>
      <li>다음 일본 여행을 갈때는 간단한 회화 정도는 해보고 싶습니다.</li>
    </ul>
  </li>
</ul>

<h1 id="3-느낀점">3. 느낀점</h1>

<ul>
  <li>뜨거운 열정보다는 냉정한 이성으로 업무에 임하는 모습이 중요하다는 것을 배웠습니다.</li>
  <li>부문리더님께서 말씀해주신 것처럼 항상 미리 미리 준비하는 태도를 갖춰야겠습니다.</li>
  <li>저도 선배님들께 받은 좋은 영향력을 나누어줄 수 있는 그런 선배가 되어야겠습니다.</li>
</ul>

<h1 id="4-비고">4. 비고</h1>

<ul>
  <li>시간이 많이 지나고 나서 작성을 해서, 최대한 기억나는 내용만 작성하였습니다.</li>
</ul>]]></content><author><name></name></author><category term="Story" /><summary type="html"><![CDATA[1. 회사생활]]></summary></entry><entry><title type="html">2022 년 하반기 회고</title><link href="https://qkrrlgh519.github.io/story/2022/12/31/2022-SecondHalfRetrospective.html" rel="alternate" type="text/html" title="2022 년 하반기 회고" /><published>2022-12-31T03:00:00+00:00</published><updated>2022-12-31T03:00:00+00:00</updated><id>https://qkrrlgh519.github.io/story/2022/12/31/2022-SecondHalfRetrospective</id><content type="html" xml:base="https://qkrrlgh519.github.io/story/2022/12/31/2022-SecondHalfRetrospective.html"><![CDATA[<h1 id="1-회사생활">1. 회사생활</h1>

<ul>
  <li>코로나로 인해서, 재택 근무 위주로 진행했습니다.</li>
  <li>SQLD 자격증을 취득하였고, 회사에서 진행하는 인증제도 취득했습니다.</li>
  <li>회사에서 파트 단위의 세미나를 진행했습니다. (담당 시스템 관련, Git 관련)</li>
  <li>처음으로 여름 휴가라는 것을 썼습니다. 집에서 이틀정도 그냥 쉬기만 했지만..</li>
  <li>사수님께서 다른 팀으로 옮기셨습니다.
    <ul>
      <li>업무에 있어서 정말 배울점이 많은 선배님이셔서 많이 아쉬웠고, 앞으로 어떻게 해야할지 좀 막막한 기분까지 들었었습니다.</li>
      <li>당시 성격이 많이 소심해진 상태였고, 선배님이 너무 어려워서 많이 소통하고 배우진 못했지만, 무의식적으로 많이 의지하고 있었던 것 같습니다.</li>
      <li>항상 모든 일에는 장단점이 있듯이, 당시에는 많이 막막했지만, 물어볼 선배님이 없다는 핑계로 그냥 얼굴에 철판을 깔고 타부서 선배님들께 “제가 잘 모르는데 알려주실 수 있나요?” 라고 하면서, 더 많이 배울 수 있었던 점도 있었습니다.</li>
      <li>그리고 직접 부딪혀가면서 배울 수 있었고, 좀 더 빠르게 업무에 투입될 수 있었던 점은 오히려 좋았던 점이라고 생각합니다.</li>
      <li>그리고 부문 리더님이 마치 사수님처럼 케어해주시고 가르쳐주셔서 많이 배울 수 있었습니다. (부문 리더님이 항상 강조하신 미리 미리 준비 할 것!)</li>
    </ul>
  </li>
  <li>멘토링을 진행했습니다. 좋은 선배님과 좋은 동기분들과 더욱 친해질 수 있는 시간이었습니다.</li>
  <li>최대한 팀에서 제 역할을 할 수 있도록 시스템 파악과 업무 파악에만 최대한 집중했던 것 같습니다.</li>
  <li>지나고 나서 생각해보면 왜이렇게 여유가 없었을까 싶습니다. 가장 여유 있는 시기였는데 말입니다. 눈치 주는 선배님들도 안계신데, 혼자 눈치보고, 휴가도 막 안쓰고, 여행도 많이 안다니고 이제 생각해보면 참으로 아쉬운 시간들입니다.</li>
  <li>제 성격 자체가 그렇게 여유가 많은 성격도 아니고, 1년차이기도 했어서 지금 생각하면 그럴 수 있었겠다 싶습니다.</li>
</ul>

<h1 id="2-개인생활">2. 개인생활</h1>

<ul>
  <li>회사 첫월급을 받고, 학창시절을 함께 해준 노트북을 덮고, 맥북을 구매하였습니다.</li>
  <li>처음으로 돈을 모아서 은행에 가서 예금이라는 것을 해봤습니다.</li>
</ul>

<h1 id="3-느낀점">3. 느낀점</h1>

<ul>
  <li>업무를 함에 있어서, 계획을 세워야 정해진 일정 안에 해낼 수 있다는 것을 배웠습니다.
    <ul>
      <li>지나고 나서 생각해보니, 항상 사수님이 “언제까지 할 수 있겠어요?” 라는 질문을 많이 주셨는데 업무를 함에 있어서 정말 중요한 질문이었던 것 같습니다.</li>
      <li>당시 사수님께서 1년차로서는 최대한 마감 기한만 넘어가지 않게 하는 것만으로도 잘하는 거라고 하셨던게 기억이 납니다.</li>
    </ul>
  </li>
  <li>업무를 타이트하게 그리고 효율적으로 진행해야 합니다.</li>
  <li>모든 일이든 최대한 미리 준비할 수 있는 부분을 찾고, 미리 미리 준비를 하는 것이 중요하다는 것도 배웠습니다. (모든 일에는 끝이 존재하고, 짧더라도 공백 시간이 생기기 마련이니)</li>
</ul>

<h1 id="4-비고">4. 비고</h1>

<ul>
  <li>시간이 많이 지나고 나서 작성을 해서, 최대한 기억나는 내용만 작성하였습니다.</li>
</ul>]]></content><author><name></name></author><category term="Story" /><summary type="html"><![CDATA[1. 회사생활]]></summary></entry><entry><title type="html">2022 년 상반기 회고</title><link href="https://qkrrlgh519.github.io/story/2022/06/30/2022-FirstHalfRetrospective.html" rel="alternate" type="text/html" title="2022 년 상반기 회고" /><published>2022-06-30T03:00:00+00:00</published><updated>2022-06-30T03:00:00+00:00</updated><id>https://qkrrlgh519.github.io/story/2022/06/30/2022-FirstHalfRetrospective</id><content type="html" xml:base="https://qkrrlgh519.github.io/story/2022/06/30/2022-FirstHalfRetrospective.html"><![CDATA[<h1 id="1-hackathon">1. Hackathon</h1>

<ul>
  <li>신입사원끼리 팀을 이뤄서 아이디어를 떠올리고, 이를 구체화하는 해커톤을 진행했습니다.</li>
  <li>약 두 달간 진행했고, 좋은 팀원들 덕분에 우수상을 수상했습니다.</li>
  <li>해커톤을 진행하며, 가장 크게 느낀것은 저의 소통 능력 부족이었습니다.
    <ul>
      <li>알고는 있었지만, 제가 가지고 있는 생각과 아이디어를 명확하고 설득력 있게 전달하는 역량이 많이 부족하다는 것을 다시 한번 느낄 수 있었습니다.</li>
    </ul>
  </li>
  <li>해커톤 경험이 부족해서, 해커톤을 어떻게 하는 것이 좋은지 잘 몰랐던 것 같습니다.
    <ul>
      <li>내용도 중요하지만, 내용을 어떻게 보여줄지, 어떻게 설득할지, 어떤 스토리 텔링을 할지, 이런 부분들이 더 중요했던 것 같습니다.</li>
    </ul>
  </li>
  <li>매번 팀프로젝트를 할 때처럼, 이번에도 개발만 해서 저의 약점을 키우는 시간을 갖지 못한 것이 아쉬웠지만, 제가 할 수 있는 것으로 팀에 도움이 될 수 있어서 다행이었습니다.</li>
  <li>그리고 여태까지 일절 밖에 나가질 않아서 코로나에 안 걸렸었는데, 회사를 나가며 사람들을 접하게 되면서 코로나에 걸리니까 많은 회의감이 들었습니다.
    <ul>
      <li>많은 생각이 들었지만, 그냥 운이 좀 안좋았다라는 결론을 내렸습니다.</li>
      <li>아무리 조심을 해도, 사람들과 만나야하기 때문에 다들 자신의 의지와 별개의 문제라고 생각하게 되었습니다.</li>
    </ul>
  </li>
</ul>

<h1 id="2-ojt">2. OJT</h1>

<ul>
  <li>약 두 달간 OJT 를 진행했습니다.</li>
  <li>부스트캠프 교육 이후로 가장 빡세고, 밀도 있는 시간을 가졌던 것 같습니다.</li>
  <li>제가 안 해본 것들을 해야 했기 때문에 거의 매일 연장 근무를 해야했고, 개인적으로 정말 쉽지 않은 시간을 보냈습니다.</li>
  <li>OJT 를 진행하며, 가장 크게 느낀 것은 지금까지 해오던 대로 해서는 절대 안되겠다 라는 것입니다.
    <ul>
      <li>회사는 학교와 다르기 때문에, 무언가 막히는게 있을 때, 저의 호기심을 채우기 위해서 며칠씩 고민하는 행동은 절대 안된다는 것입니다.
        <ul>
          <li>학생때 그리고 취준생일때 어떻게든 해결하고 싶다는 생각에 문제를 잡고 며칠씩 고민했었는데 이것은 개인 공부할 때만 해야한다는 것입니다.</li>
        </ul>
      </li>
      <li>그리고 정해진 시간에만 일을 할 수 있고, 또한 제 기준 적은 돈을 받고 일하는 것이 아니기 때문에 주어진 시간 동안 정말 몰입해서 일을 해야한다는 것입니다.
        <ul>
          <li>제가 약간 계획도 없고, 느긋한 한량 스타일인데 이런 태도로 일을 하면 절대 마감일에 맞게 일을 해낼 수 없겠다 라는 것을 깨달았습니다.</li>
          <li>더불어 느긋하게 늘어지는 스타일로 뭔가를 하는 방식을 버려야 하겠습니다.</li>
          <li>아직은 경험이 부족하지만, 경험을 쌓고, 어떤 일은 얼마나 걸릴지 예측해서 계획을 짜고, 계획대로 일을 진행해야 한다는 것을 배웠습니다.</li>
        </ul>
      </li>
      <li>그리고 요즘 유행하는 MBTI 성향이 사수님과 정반대인데, 그런만큼 모든 부분이 다 배울점이라 감사하게 생각하고 있습니다.
        <ul>
          <li>다만, 사수님 입장에서도 저의 생각이 자신과 정반대인 경우가 많아서, 힘들어하실게 걱정이고, 저도 잘 맞춰서 해야하는데 그러지 못할까 걱정입니다.</li>
          <li>최대한 맞추고, 배우고, 노력하는 수 밖에 없을 것 같습니다.</li>
        </ul>
      </li>
      <li>그리고 일을 하거나 학습을 할 때, 핵심이 되는 부분을 우선적으로 하고, 잔바리는 좀 맞춰서 한다는 느낌으로 해야한다는 것을 배웠습니다.
        <ul>
          <li>제가 학생때부터 문제점이 공부를 할 때 중요하지 않은 것들도 하나하나 보는 경향이 있는데, 그게 그렇게 하지 않으면 뭔가 덜한 느낌이 들고, 시험볼 때도 자신감이 안들어서 그렇게 하는걸 되게 싫어합니다.</li>
          <li>하지만, 회사에서는 그런 태도를 버려야 할 것 같습니다. 그리고 앞으로도 버리고 최대한 효율적으로 핵심적인 부분 위주로 해결하고 공부하는 방식을 터득해야겠습니다.</li>
        </ul>
      </li>
      <li>일을 할 때 언제든지 윗분들에게 보고할 수 있는 상태로 만들어야 합니다.
        <ul>
          <li>이번에 저의 느긋한 성격 때문에 좀 고생을 했는데, 언제든지 윗분들에게 보고할 수 있도록 빠르게 빠르게 보여줄 수 있는 결과물을 만드는 것이 정말 중요하다는 것을 배웠습니다.</li>
        </ul>
      </li>
      <li>사람들과 어울리는 것이 정말 중요하고, 사적으로 친하게 지내야 한다는 것이 아니라 공적으로 서로에게 도움이 될 수 있는 그런 관계를 적극적으로 만드는 것이 중요하다는 것을 배웠습니다.
        <ul>
          <li>제가 특히 심하게 내향적이라 사람들과 어울리고 그런걸 못하는 성격인데, 사수님이 그런 부분은 회사일을 할때는 조금 적극적으로 했으면 한다고 얘기해주셨습니다.</li>
          <li>또 저의 그런 부족한 부분들을 바뀔 수 있도록 도와주시는 걸 보며, 적극적인 자세가 정말 중요하다는 것을 느꼈습니다.</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>사실 저보다도 사수님이 많이 고생하셔서, 그 부분이 제일 죄송하고 감사한 마음 뿐입니다.</li>
  <li>그리고 가장 핵심은 주어진 일에 대해서 얼마나 걸릴지 예측하고, 그 예측한 일정에 맞게 최대한 맞춰서 해결하는 자세와 태도 그것이 가장 중요하다고 느꼈습니다. 더불어 적극적인 소통도!!</li>
</ul>]]></content><author><name></name></author><category term="Story" /><summary type="html"><![CDATA[1. Hackathon]]></summary></entry></feed>