<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>한남_더힐_태환</title>
        <link>https://velog.io/</link>
        <description>뭐 어떻게 잘 되겠지 </description>
        <lastBuildDate>Mon, 26 Dec 2022 23:32:20 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>한남_더힐_태환</title>
            <url>https://images.velog.io/images/thehill_hannam/profile/775ba95d-5c3a-424d-99a1-cea3ef4bc431/my-neighbor-jake-gif-by-JJ-Harrison.gif</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 한남_더힐_태환. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/thehill_hannam" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Kotlin] - 반복문]]></title>
            <link>https://velog.io/@thehill_hannam/Kotlin-%EB%B0%98%EB%B3%B5%EB%AC%B8-mf3a86pb</link>
            <guid>https://velog.io/@thehill_hannam/Kotlin-%EB%B0%98%EB%B3%B5%EB%AC%B8-mf3a86pb</guid>
            <pubDate>Mon, 26 Dec 2022 23:32:20 GMT</pubDate>
            <description><![CDATA[<h1 id="반복문">반복문</h1>
<h2 id="for-each문">for each문</h2>
<h3 id="java">Java</h3>
<pre><code class="language-java">List&lt;Long&gt; numbers = Arrays.asList(1L, 2L, 3L);
for (Long number : numbers) {
    System.out.println(number);
}</code></pre>
<h3 id="kotlin">Kotlin</h3>
<pre><code class="language-kotlin">val numbers = listOf(1L, 2L, 3L)
for (number in numbers) {
    println(number)
}</code></pre>
<h3 id="차이점">차이점</h3>
<ul>
<li><strong><code>Collection</code></strong> 생성 방법</li>
<li>Java <strong><code>:</code></strong>, Kotlin <strong><code>in</code></strong><h2 id="증가-감소하는-반복문">증가/ 감소하는 반복문</h2>
<h3 id="java-1">Java</h3>
<pre><code class="language-java">// 1씩 증가
for (int i = 1 ; i &lt;= 3 ; i++) {
  System.out.println(i);
}
</code></pre>
</li>
</ul>
<p>// 2씩 증가
for (int i = 1 ; i &lt;= 5 ; i += 2) {
    System.out.println(i);
}</p>
<p>// 감소
for (int i = 3 ; i &gt;= 1 ; i--) {
    System.out.println(i);
}</p>
<pre><code>### Kotlin
``` kotlin
// 증가
for (i in 1..3) {
    println(i)
}

// 2씩 증가
for (i in 1..5 step 2) {
    println(i)
}

// 감소
for (i in 3 downTo 1) {
    println(i)
}</code></pre><h3 id="작동-원리">작동 원리</h3>
<p><strong><code>1..3</code></strong> 부분이 <strong><code>IntRange</code></strong>를 만드는 함수라는 걸 알 수 있다
<img src="https://velog.velcdn.com/images/thehill_hannam/post/79ac4d9d-3a9f-4a73-ba55-2af743d772ff/image.png" alt="">
<strong><code>IntRange</code></strong>는 <strong><code>IntProgression</code></strong>을 상속받을 때 기본 값으로 step이 1로 되어 있다.
<img src="https://velog.velcdn.com/images/thehill_hannam/post/e6fbb0e7-5243-4590-96e4-051490554e13/image.png" alt=""></p>
<p><strong><code>1..3</code></strong>은 1부터 3까지 1씩 증가하는 등차 수열을 만드는 것이다.</p>
<h1 id="정리">정리</h1>
<ul>
<li>for each<ul>
<li>Java <strong><code>:</code></strong></li>
<li>Kotlin <strong><code>in</code></strong><ul>
<li>일반적인 for 문에서 등차수열과 in 사용</li>
<li>그 외의 for문 문법은 모두 동일하다.</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin] 조건문]]></title>
            <link>https://velog.io/@thehill_hannam/Kotlin-%EC%A1%B0%EA%B1%B4%EB%AC%B8</link>
            <guid>https://velog.io/@thehill_hannam/Kotlin-%EC%A1%B0%EA%B1%B4%EB%AC%B8</guid>
            <pubDate>Wed, 03 Aug 2022 16:31:45 GMT</pubDate>
            <description><![CDATA[<h1 id="조건문">조건문</h1>
<h2 id="if문">IF문</h2>
<h3 id="java">Java</h3>
<pre><code class="language-java">private void validateScoreIsNotNegative(int score) {
    if (score &lt; 0) {
        throw new IllegalArgumentException(String.format(&quot;%s는 0보다 작을 수 없습니다.&quot;), score));
    }
}

private String getPassOrFail(int score) {
    if (score &gt;= 50) {
        return &quot;P&quot;;
    } else {
        return &quot;F&quot;;
    }
}</code></pre>
<h3 id="kotlin">Kotlin</h3>
<pre><code class="language-kotlin">fun validateScoreIsNotNegative(score: Int) {
    if (score &lt; 0) {
        throw IllegalArgumentException(&quot;${socre}는 0보다 작을 수 없습니다.}&quot;);
    }
}

fun getPassOrFail(int score): String{
    if (score &gt;= 50) {
        return &quot;P&quot;
    } else {
        return &quot;F&quot;
    }
}</code></pre>
<ul>
<li>함수에서 <strong><code>Unit(void)</code></strong> 생략</li>
<li>Java에서 if - elses는 <strong><code>Statement</code></strong>이지만
Kotlin에서는 <strong><code>Expression</code></strong>이다.<h2 id="expression과-statement">Expression과 Statement</h2>
<h3 id="statement">Statement</h3>
프로그램의 문장, 하나의 값으로 도출되지 않는다.<h3 id="expression">Expression</h3>
하나의 값으로 도출되는 문장<h4 id="java-1">Java</h4>
<pre><code class="language-java">private String getPassOrFail(int score) {    
  // java에서 if - else는 Statement라 하나의 값으로 도출되지 않는다.
  if (score &gt;= 50) {    
      return &quot;P&quot;;
  } else {
      return &quot;F&quot;;
  }
}
</code></pre>
</li>
</ul>
<p>private String getPassOrFail(int score) {
    // 3항 연산자는 하나의 값으로 취급되는 Expression이다.
    return score &gt;= 50 ? &quot;P&quot; : &quot;F&quot;;
}</p>
<pre><code>#### Kotlin
Kotlin에서는 if - else를 Expression으로 사용할 수 있기 때문에 3항 연산자가 없다.
``` kotlin
fun getPassOrFail(score: Int): String {    
    // Kotlin에서 if - else는 Expression이다.
    return if (score &gt;= 50) {    
        &quot;P&quot;
    } else {
        &quot;F&quot;
    }
}</code></pre><h3 id="범위-조건문">범위 조건문</h3>
<h4 id="java-2">Java</h4>
<pre><code class="language-java">private void validateScoreIsNotNegative(int score) {
    if (0 &gt; score &amp;&amp; score &gt; 100) {
        thorw new IllegalArgumentException(&quot;score의 범위는 0이상 100 이하입니다.&quot;);
    }
}</code></pre>
<h4 id="kotlin-1">Kotlin</h4>
<pre><code class="language-kotlin">fun validateScoreIsNotNegative(score: Int) {    
    if (score !in 0..100) {
        thorw IllegalArgumentException(&quot;score의 범위는 0이상 100 이하입니다.&quot;);
    }
}</code></pre>
<h2 id="switch와-when">switch와 when</h2>
<h2 id="switch">switch</h2>
<h3 id="java-3">Java</h3>
<pre><code class="language-java">int num = 10;
num = 20;</code></pre>
<h3 id="kotlin-2">Kotlin</h3>
<p><strong><code>switch</code></strong> 대신 <strong><code>when</code></strong> , <strong><code>case</code></strong> 대신 <strong><code>-&gt;</code></strong> ,  <strong><code>default</code></strong> 대신 <strong><code>else</code></strong> 사용.</p>
<pre><code class="language-kotlin">fun getGradeWithSwift(score: Int): String {
    // Kotlin에서 when은 Expression이다.
    return when (score / 10) {
        9 -&gt; &quot;A&quot;
        8 -&gt; &quot;B&quot;
        7 -&gt; &quot;C&quot;
        else -&gt; &quot;D&quot;
    }
}

fun getGradeWithSwift(score: Int): String {
    return when (score) {
        in 90..99 -&gt; &quot;A&quot;
        in 80..89 -&gt; &quot;B&quot;
        in 70..79 -&gt; &quot;C&quot;
        else -&gt; &quot;D&quot;
    }
}</code></pre>
<h1 id="정리">정리</h1>
<p><strong><code>if / if - else</code></strong> 모두 Java와 문법이 동일하다.</p>
<ul>
<li>Kotlin에서는 Expression으로 취급</li>
</ul>
<p><strong><code>switch</code></strong> 는 <strong><code>when</code></strong> 으로 대체되었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin] Type 다루기]]></title>
            <link>https://velog.io/@thehill_hannam/Kotlin-Type-%EB%8B%A4%EB%A3%A8%EA%B8%B0</link>
            <guid>https://velog.io/@thehill_hannam/Kotlin-Type-%EB%8B%A4%EB%A3%A8%EA%B8%B0</guid>
            <pubDate>Sun, 31 Jul 2022 05:13:35 GMT</pubDate>
            <description><![CDATA[<h1 id="type">Type</h1>
<h2 id="선언된-기본-값으로-타입을-추론한다">선언된 기본 값으로 타입을 추론한다.</h2>
<h3 id="java">java</h3>
<pre><code class="language-java">int intType = 3;            // Int
long longType =3L;            // Long
Double doubleType = 3.0;    // Double
Float floatType = 3.0f        // Float</code></pre>
<h3 id="kotlin">kotlin</h3>
<pre><code class="language-kotlin">val intType = 3            // Int
val longType = 3L        // Long
val doubleType = 3.0    // Double
val floatType = 3.0f    // Float</code></pre>
<h2 id="convert-type">Convert Type</h2>
<h3 id="java-1">java</h3>
<p><strong><code>Java</code></strong> : 기본 타입간의 변환은 <strong><code>암시적</code></strong>으로 이루어질 수 있다.</p>
<pre><code class="language-java">int intType = 1;
long longType = intType;

System.out.println(intType + longType);</code></pre>
<h3 id="kotlin-1">kotlin</h3>
<p><strong><code>Kotlin</code></strong> : 기본 타입간의 변환은 <strong><code>명시적</code></strong>으로 이루어져야 한다.</p>
<pre><code class="language-kotlin">val intType = 4
// val longType: Long = intType        // 컴파일 오류
val longType: Long = intType.toLong()

println(intType + longType)</code></pre>
<ul>
<li><strong><code>nullable</code></strong> 처리<pre><code class="language-kotlin">val intType: Int? = 4
val longType: Long = intType?.toLong() ?: 0L
</code></pre>
</li>
</ul>
<p>println(intType + longType)</p>
<pre><code>## 타입 캐스팅
### java
``` java
public static void getPersonAge(Object obj) {
    if (obj instanceof Person) {
        Person person = (Person) obj;
        System.out.println(person.getAge());
    }

    if (!(obj instanceof Person) {
        System.out.println(&quot;object is not Person tpye&quot;);
    }
}</code></pre><h3 id="kotlin-2">kotlin</h3>
<pre><code class="language-kotlin">fun getPersonAge(obj: Any) {
    if (obj is Person) {    // is == instanceof(java)
        val person = obj as Person    // 생략 가능, as Person == (Person) in java
        println(person.age)
    }

    if (obk !is Person) {
        println(&quot;object is not Person tpye&quot;)
    }
}</code></pre>
<ul>
<li><strong><code>nullable</code></strong> 타입<pre><code class="language-kotlin">fun getPersonAge(obj: Any?) {
  if (obj is Person) {
      val person = obj as? Person
      println(person.age)
  }
}</code></pre>
<h2 id="any-unit-nothing">Any, Unit, Nothing</h2>
<h3 id="any">Any</h3>
</li>
<li>모든 객체의 최상위 타입(Java의 Object 역할)</li>
<li>모든 Primitive Type의 최상위 타입도 Any</li>
<li>Any 자체로는 null 포함 불가능</li>
<li>equals, hashCode, toString 존재<h3 id="unit">Unit</h3>
</li>
<li>Java의 void와 동일한 역할</li>
<li>Unit 자체로 타입 인자로 사용 가능</li>
<li>함수형 프로그래밍에서 Unit은 단 하나의 인스턴스만 갖는 타입을 의미<h3 id="nothing">Nothing</h3>
</li>
<li>함수가 정상적으로 끝나지 않았다는 사실을 표현</li>
<li>무조건 예외를 반환하는 함수, 무한 루프 함수 등<pre><code class="language-kotlin">fun fail(message: String): Nothing {
  throw IllegalArgumentException (message)
}</code></pre>
<h2 id="string-type">String Type</h2>
<h3 id="string-interpolation">String interpolation</h3>
<h4 id="java-2">Java</h4>
<pre><code class="language-java">Person person = new Person(&quot;김태환&quot;, 29);
</code></pre>
</li>
</ul>
<p>String log = String.format(&quot;이름 : %s, 나이 %s 입니다.&quot;, pserson.getName(), person.getAge());</p>
<p>StringBuilder builder = new StringBuilder();
builder.append(&quot;이름 : &quot;);
builder.append(pserson.getName());
builder.append(&quot;, 나이는 : &quot;);
builder.append(person.getAge());
builder.append(&quot; 입니다.&quot;);</p>
<pre><code>
#### Kotlin
**``${변수}``**를 사용
``` kotlin
val person = Person(&quot;김태환&quot;, 29)
var log = &quot;사람의 이름은 ${person.name},  나이 ${person.age} 입니다.&quot;

// 변수일 경우 중괄호 생략 가능
val name = &quot;김태환&quot;
val age = 29
log = &quot;사람의 이름은 $name,  나이 $age 입니다.&quot;

log = &quot;&quot;&quot;
    사람의 이름은
    $name,
    니아 $age
    입니다.
&quot;&quot;&quot;.trimIndent()</code></pre><h2 id="string-indexing">String indexing</h2>
<h3 id="java-3">Java</h3>
<pre><code class="language-java">String str = &quot;김태환&quot;;
char ch = str.charAt(1);</code></pre>
<h3 id="kotlin-3">Kotlin</h3>
<pre><code class="language-kotlin">val str = &quot;김태환&quot;
val s = str[1]
}</code></pre>
<h1 id="정리">정리</h1>
<ul>
<li>코틀린의 변수는 초기값을 보고 타입을 추론하며, 기본 타입들간의 변환은 명시적으로 이루어진다.</li>
<li><strong><code>is</code></strong>,<strong><code>!is</code></strong> 를 이용해 타입을 확인하고 <strong><code>as</code></strong>,<strong><code>as?</code></strong> 를 사용하여 타입 캐스팅한다.</li>
<li><strong><code>Any</code></strong> 는 java의 Object과 같은 최상위 타입이다.</li>
<li><strong><code>Unit</code></strong> 은 java의 void와 동일하다.</li>
<li><strong><code>Nothing</code></strong> 은 정상적으로 끝나지 않는 함수의 반환을 의미한다.</li>
<li>문자열을 가공할때 <strong><code>${변수}</code></strong>와 <strong><code>&quot;&quot;&quot; &quot;&quot;&quot;</code></strong>을 사용하면 깔끔한 코딩이 가능하다.</li>
<li>문자열에서 문자를 가져올때의 java의 배열처럼 <strong><code>[]</code></strong>를 사용한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin] Null 다루기]]></title>
            <link>https://velog.io/@thehill_hannam/Kotlin-Null</link>
            <guid>https://velog.io/@thehill_hannam/Kotlin-Null</guid>
            <pubDate>Fri, 15 Jul 2022 13:44:00 GMT</pubDate>
            <description><![CDATA[<h3 id="kotlin-playground">Kotlin Playground</h3>
<p>[Kotlin Playground]  (<a href="https://play.kotlinlang.org/#eyJ2ZXJzaW9uIjoiMS43LjEwIiwicGxhdGZvcm0iOiJqYXZhIiwiYXJncyI6IiIsIm5vbmVNYXJrZXJzIjp0cnVlLCJ0aGVtZSI6ImlkZWEiLCJjb2RlIjoiLyoqXG4gKiBZb3UgY2FuIGVkaXQsIHJ1biwgYW5kIHNoYXJlIHRoaXMgY29kZS5cbiAqIHBsYXkua290bGlubGFuZy5vcmdcbiAqL1xuZnVuIG1haW4oKSB7XG4gICAgcHJpbnRsbihcIkhlbGxvLCB3b3JsZCEhIVwiKVxufSJ9">https://play.kotlinlang.org/#eyJ2ZXJzaW9uIjoiMS43LjEwIiwicGxhdGZvcm0iOiJqYXZhIiwiYXJncyI6IiIsIm5vbmVNYXJrZXJzIjp0cnVlLCJ0aGVtZSI6ImlkZWEiLCJjb2RlIjoiLyoqXG4gKiBZb3UgY2FuIGVkaXQsIHJ1biwgYW5kIHNoYXJlIHRoaXMgY29kZS5cbiAqIHBsYXkua290bGlubGFuZy5vcmdcbiAqL1xuZnVuIG1haW4oKSB7XG4gICAgcHJpbnRsbihcIkhlbGxvLCB3b3JsZCEhIVwiKVxufSJ9</a>)
<img src="https://velog.velcdn.com/images/thehill_hannam/post/f65994d0-627a-44eb-9649-0b8059217f92/image.png" alt="Kotlin Playground"></p>
<hr>
<h1 id="null-check">Null Check</h1>
<pre><code class="language-java">public boolean startsWithA(String str) {
    // &quot;A&quot;로 시작하면 true, 아니면 false 반환
    return str.startWithA(&quot;A&quot;);
}</code></pre>
<p>위 소스는 <strong><code>str</code></strong>이 null이 들어갈 수 있으므로 안전하지 않다.</p>
<h2 id="예외처리">예외처리</h2>
<h3 id="java-예외처리">Java 예외처리</h3>
<pre><code class="language-java">public boolean startsWithA1(String str) {
    if (null == str) {
        throw new IllegalArgumentException(&quot;str is null&quot;)
    }
    return str.startsWith(&quot;A&quot;);
}</code></pre>
<h3 id="kotlin-예외처리">Kotlin 예외처리</h3>
<pre><code class="language-kotlin">fun startsWithA1(str: String?): Boolean {
    if (null == str) {
        throw IllegalArgumentException(&quot;str is null&quot;)
    }
    return str.startsWith(&quot;A&quot;)
}</code></pre>
<h2 id="return-null">return null</h2>
<h3 id="java-return-null">Java return null</h3>
<pre><code class="language-java">public boolean startsWithA2(String str) {
    if (null == str) {
        return null;
    }
    return str.startsWith(&quot;A&quot;);
}</code></pre>
<h3 id="kotlin-return-null">Kotlin return null</h3>
<pre><code class="language-kotlin">fun startsWithA2(str: String?): Boolean? {
    if (null == str) {
        return null
    }
    return str.startsWith(&quot;A&quot;)
}</code></pre>
<p>fun startsWithA(str: String?) Boolean<strong><code>?</code></strong> 처럼 return type 에 <strong><code>?</code></strong>을 붙여주면 <strong><code>return null</code></strong> 가능하다.</p>
<h2 id="return-false">return false</h2>
<h3 id="java-return-false">Java return false</h3>
<pre><code class="language-java">public boolean startsWithA3(String str) {
    if (null == str) {
        return false;
    }
    return str.startsWith(&quot;A&quot;);
}</code></pre>
<h3 id="kotlin-return-false">Kotlin return false</h3>
<pre><code class="language-kotlin">fun startsWithA3(str: String?): Boolean {
    if (null == str) {
        return false
    }
    return str.startsWith(&quot;A&quot;)
}</code></pre>
<h1 id="safe-call-elvis-연산자">Safe Call, Elvis 연산자</h1>
<h2 id="safe-call">Safe Call</h2>
<p>null이면 그대로 null 반환, null이 아니면 실행</p>
<pre><code class="language-kotlin">val str1: String? = &quot;ABC&quot;
str.length // 불가능
str?.length // return 3

val str2: String? = null
str.length    // 불가능
str?.length // return null</code></pre>
<h2 id="elvis-연산자">Elvis 연산자</h2>
<p>null이 아니면 실행, null이면 <strong><code>?:</code></strong> 뒤에 값 return </p>
<pre><code class="language-kotlin">val str1: String? = null
str?.length ?: 10 // return 10</code></pre>
<h2 id="startswitha-refactoring">startsWithA Refactoring</h2>
<pre><code class="language-kotlin">fun startsWithA1(str: String?): Boolean {
    return str.startsWith(&quot;A&quot;) ?: throw IllegalArgumentException(&quot;str is null&quot;)
}

fun startsWithA2(str: String?): Boolean {
    return str?.startsWith(&quot;A&quot;)
}

fun startsWithA3(str: String?): Boolean {
    return str?.startsWith(&quot;A&quot;) ?: false
}</code></pre>
<h3 id="kotlin-early-return">kotlin early return</h3>
<pre><code class="language-kotlin">fun calculate(number: Long?): Long {
    number ?: return 0
}</code></pre>
<h3 id="kotlin-early-return-1">kotlin early return</h3>
<pre><code class="language-kotlin">fun calculate(number: Long?): Long {
    number ?: return 0
}</code></pre>
<h1 id="null-아님-단언">Null 아님 단언</h1>
<p>nullable type이지만, 아무리 생각해도 null이 될 수 없는 경우 호출 시<strong><code>!!</code></strong>을 붙인다.
parameter로 null이 들어올시 <strong><code>NullPointerException</code></strong>이 발생한다.</p>
<pre><code class="language-kotlin">fun startsWith(str: String?): Boolean {
    return str!!.startsWith(&quot;A&quot;)
}</code></pre>
<h1 id="정리">정리</h1>
<p>null이 들어갈 수 있는 Type은 완전히 다르게 간주된다.
null이 아닌 경우에만 호출되는 Safe Call(e. g. str?.length)이 있다.
null인 경우에만 호출되는 Elvis 연산자(e. g. str?.length ?: 0)이 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kotlin] 변수]]></title>
            <link>https://velog.io/@thehill_hannam/Kotlin</link>
            <guid>https://velog.io/@thehill_hannam/Kotlin</guid>
            <pubDate>Fri, 15 Jul 2022 12:32:26 GMT</pubDate>
            <description><![CDATA[<h3 id="kotlin-철학">Kotlin 철학</h3>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/ac22c956-3a43-414c-b7b2-b47c351693f4/image.png" alt="코틀린 장점">
<strong><code>Modern</code></strong> : 현대
<strong><code>Concise</code></strong> : 간결
<strong><code>Safe</code></strong>: 안전</p>
<h1 id="변수-선언">변수 선언</h1>
<h2 id="varvariable">var(Variable)</h2>
<p><code>가변 변수</code> 선언 키워드 </p>
<h3 id="java">Java</h3>
<pre><code class="language-java">int num = 10;
num = 20;</code></pre>
<h3 id="kotlin">Kotlin</h3>
<pre><code class="language-kotlin">var num = 10
num = 20</code></pre>
<h2 id="valvalue">val(Value)</h2>
<p><code>불변 변수</code> 선언 키워드</p>
<h3 id="java-1">Java</h3>
<pre><code class="language-java">final int num = 10;
num = 20; // 에러</code></pre>
<h3 id="kotlin-1">Kotlin</h3>
<pre><code class="language-kotlin">val num = 10
num = 20 // 컴파일 에러</code></pre>
<h1 id="변수-타입">변수 타입</h1>
<p>컴파일러가 자동으로 추론해주기때문에 원하면 <code>: Type</code> 으로  작성</p>
<h3 id="java-2">Java</h3>
<pre><code class="language-java">int num1 = 10;
final Long num2 = 10L;</code></pre>
<h3 id="kotlin-2">Kotlin</h3>
<pre><code class="language-kotlin">var num1: Int = 10
val num2: Long = 10L</code></pre>
<h1 id="primitive-type">Primitive Type</h1>
<h3 id="java-3">Java</h3>
<pre><code class="language-java">long num1 = 10L; // primitive type
Long num2 = 10L; // reference type</code></pre>
<h3 id="kotlin-3">Kotlin</h3>
<p>Kotlin이 알아서 처리해줌.</p>
<h1 id="nullable-변수">Nullable 변수</h1>
<h3 id="java-4">Java</h3>
<pre><code class="language-java">int num1 = null; // 에러
Integer num2 = null;</code></pre>
<h3 id="kotlin-4">Kotlin</h3>
<pre><code class="language-kotlin">var num1: Int = null // 에러
var num2: Int? = null</code></pre>
<h1 id="객체-인스턴스화">객체 인스턴스화</h1>
<h3 id="java-5">Java</h3>
<pre><code class="language-java">Person person = new Person(&quot;탄지로&quot;)</code></pre>
<h3 id="kotlin-5">Kotlin</h3>
<pre><code class="language-kotlin">var person = Person(&quot;탄지로&quot;)</code></pre>
<h1 id="정리">정리</h1>
<p>모든 변수는 <strong><code>var</code></strong>, <strong><code>val</code></strong>을 붙인다.</p>
<ul>
<li><strong>var</strong> : 변경 가능</li>
<li><strong>val</strong> : 변경 불가능</li>
</ul>
<p>타입을 명시적으로 작성하지 않아도, <strong><code>타입이 추론</code></strong>된다.
<strong><code>Primitive Type</code></strong>, <strong><code>Reference Type</code></strong>을 구분하지 않아도 된다.
<strong><code>Null</code></strong>이 들어갈 수 있는 변수는 타입 뒤에 <strong><code>?</code></strong>를 붙인다.
객체를 인스턴스화 할 때 <strong><code>new</code></strong>를 붙이지 않는다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL]]></title>
            <link>https://velog.io/@thehill_hannam/MySQL</link>
            <guid>https://velog.io/@thehill_hannam/MySQL</guid>
            <pubDate>Sat, 04 Jun 2022 07:13:26 GMT</pubDate>
            <description><![CDATA[<p>ㄴㅁㅇㄹ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[IntelliJ] cannot resolve symbol]]></title>
            <link>https://velog.io/@thehill_hannam/IntelliJ-cannot-resolve-symbol</link>
            <guid>https://velog.io/@thehill_hannam/IntelliJ-cannot-resolve-symbol</guid>
            <pubDate>Sat, 21 May 2022 07:19:28 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/1dc6747c-29f2-415f-bceb-10d470bd6d54/image.png" alt="cannot resolve symbol"></p>
<p>IntelliJ를 사용하다보면 build.gradle 설정을 제대로 했음에도 불구하고, <code>cannot resolve symbol...</code> 에러가 발생하는 경우가 종종 있다.</p>
<h2 id="해결-방법">해결 방법</h2>
<h3 id="프로젝트-리빌드">프로젝트 리빌드</h3>
<p>Build &gt; Rebuild Project</p>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/b3b2024c-4847-4293-a4ed-07ea2b02b124/image.png" alt=""></p>
<h3 id="캐쉬-삭제-후-재-시작">캐쉬 삭제 후 재 시작</h3>
<p>File &gt; Invalidate Caches / Restart</p>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/0b30dc3a-ce29-4611-85ee-d95ee238a5af/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SwiftUI - ForEach]]></title>
            <link>https://velog.io/@thehill_hannam/SwiftUI-ForEach</link>
            <guid>https://velog.io/@thehill_hannam/SwiftUI-ForEach</guid>
            <pubDate>Thu, 12 May 2022 15:49:08 GMT</pubDate>
            <description><![CDATA[<h1 id="foreach">ForEach</h1>
<p>SwiftUI에서 <code>ForEach</code>를 사용하여 View를 반복한다.
struct 구조 이므로 직접 view를 반환한다.
<code>List</code>와 함께 사용한다.</p>
<pre><code class="language-swift">import SwiftUI

struct SymbolInfo {
    var SEQ: Int
    var systemName: String = &quot;&quot;
    var name: String = &quot;&quot;
}
struct ContentView: View {

    var symbolLoist = [
        SymbolInfo(SEQ: 1, systemName: &quot;facemask.fill&quot;, name: &quot;마스크&quot;),
        SymbolInfo(SEQ: 2, systemName: &quot;brain&quot;, name: &quot;뇌&quot;),
        SymbolInfo(SEQ: 3, systemName: &quot;cross.fill&quot;, name: &quot;십자가&quot;),
        SymbolInfo(SEQ: 4, systemName: &quot;staroflife.fill&quot;, name: &quot;눈&quot;),
        SymbolInfo(SEQ: 5, systemName: &quot;heart.fill&quot;, name: &quot;하트&quot;)
    ]

    var body: some View {
        List {
            ForEach(symbolLoist, id: \.SEQ) { symbolInfo in
                HStack {
                    Text(&quot;\(symbolInfo.SEQ)&quot;)
                    Image(systemName: symbolInfo.systemName)
                    Text(&quot;\(symbolInfo.name)&quot;)
                }
            }

            ForEach(0..&lt;symbolLoist.count) { index in
                HStack {
                    Text(&quot;\(symbolLoist[index].SEQ + symbolLoist.count)&quot;)
                        .foregroundColor(Color.white)
                    Image(systemName: symbolLoist[index].systemName)
                        .foregroundColor(Color.white)
                    Text(&quot;\(symbolLoist[index].name)&quot;)
                        .foregroundColor(Color.white)
                    Spacer()
                }
                .background(Color.black)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ContentView()
        }
    }
}
</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/e594ecc4-46a0-4076-ab79-c0fc0926c5c0/image.png" alt=""></p>
<h1 id="list">List</h1>
<p>단일 열에 정렬된 데이터 행을 표시하는 컨테이너이다.</p>
<h2 id="list-section">List Section</h2>
<pre><code class="language-swift">import SwiftUI

struct ContentView: View {

    var body: some View {
        List {
            Section(header: Text(&quot;Hearder Area&quot;)) {
                Text(&quot;A&quot;)
                Text(&quot;A&quot;)
                Text(&quot;A&quot;)
            }

            Section(footer: Text(&quot;Footer Area&quot;)) {
                Text(&quot;A&quot;)
                Text(&quot;A&quot;)
                Text(&quot;A&quot;)
            }

            Section(header: Text(&quot;Hearder Area&quot;), footer: Text(&quot;Footer Area&quot;)) {
                Text(&quot;A&quot;)
                Text(&quot;A&quot;)
                Text(&quot;A&quot;)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ContentView()
        }
    }
}
</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/b148996e-cabf-49fb-9fef-f73e793e7d69/image.png" alt=""></p>
<h3 id="데이터-분류-및-정렬">데이터 분류 및 정렬</h3>
<pre><code class="language-swift">
import SwiftUI

struct Animal: Identifiable {
    let id = UUID()
    let name: String
    let type : String
    let index: Int
}

struct ContentView: View {

    var animalList = [
        Animal(name: &quot;푸들&quot;, type: &quot;강아지&quot;, index: 1),
        Animal(name: &quot;시츄&quot;, type: &quot;강아지&quot;, index: 2),
        Animal(name: &quot;시바견&quot;, type: &quot;강아지&quot;, index: 3),
        Animal(name: &quot;닥스훈트&quot;, type: &quot;강아지&quot;, index: 11),
        Animal(name: &quot;웰시코기&quot;, type: &quot;강아지&quot;, index: 5),
        Animal(name: &quot;먼치킨&quot;, type: &quot;고양이&quot;, index: 8),
        Animal(name: &quot;페르시안&quot;, type: &quot;고양이&quot;, index: 4),
        Animal(name: &quot;스핑크스&quot;, type: &quot;고양이&quot;, index: 7),
        Animal(name: &quot;뱅골&quot;, type: &quot;고양이&quot;, index: 10),
        Animal(name: &quot;라가머핀&quot;, type: &quot;고양이&quot;, index: 6),
        Animal(name: &quot;러시안 블루&quot;, type: &quot;고양이&quot;, index: 9)
    ]

    var AnimalGroup: [String : [Animal]] {
        // Type으로 분류
        var data =  Dictionary(grouping: animalList) { animal in
            animal.type
        }

        // Index로 정렬
        for(key, value) in data {
            data[key] = value.sorted(by: {$0.index &lt; $1.index})
        }

        return data
    }

    // section 분류 
    var groupKey: [String] {
        AnimalGroup.map({$0.key})
    }

    var body: some View {
        List {
            ForEach(groupKey, id: \.self) { animalKey in
                Section(header: Text(&quot;\(animalKey)&quot;)) {
                    ForEach(AnimalGroup[animalKey]!) { animal in
                        HStack {
                            Text(&quot;\(animal.name)&quot;)
                            Text(&quot;\(animal.index)&quot;)
                        }
                    }
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ContentView()
        }
    }
}
</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/ab67ff9d-246b-4673-b2d7-407ca3b4bae7/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SwiftUI - @Binding]]></title>
            <link>https://velog.io/@thehill_hannam/SwiftUI-Toggle</link>
            <guid>https://velog.io/@thehill_hannam/SwiftUI-Toggle</guid>
            <pubDate>Wed, 11 May 2022 16:29:14 GMT</pubDate>
            <description><![CDATA[<h1 id="binding">@Binding</h1>
<blockquote>
<p><strong><code>@Binding</code></strong>은 부모 View의 @State와 같은 값 연결 시켜준다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/701edcb4-f066-4815-aafa-abdb33f89436/image.gif" alt=""></p>
<h2 id="예제-소스">예제 소스</h2>
<pre><code class="language-swift">
import SwiftUI

struct ParentsView: View {

    @State private var isOn = false

    var body: some View {
        VStack {
            Toggle(&quot;On / Off&quot;, isOn: $isOn)
            ChildView(isOn: $isOn)
        }
    }
}

struct ChildView: View {

    @Binding var isOn: Bool

    var imageName: String {
        if isOn {
            return &quot;lightbulb.fill&quot;
        } else {
            return &quot;lightbulb&quot;
        }
    }

    var imageColor: Color {
        if isOn {
            return Color.yellow
        } else {
            return Color.black
        }
    }

    var body: some View {
        Image(systemName: imageName)
            .resizable()
            .frame(width: 50, height: 50, alignment: .center)
            .foregroundColor(imageColor)

    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ParentsView()
        }
    }
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[SwiftUI -  @State]]></title>
            <link>https://velog.io/@thehill_hannam/SwiftUI-State</link>
            <guid>https://velog.io/@thehill_hannam/SwiftUI-State</guid>
            <pubDate>Wed, 11 May 2022 14:25:58 GMT</pubDate>
            <description><![CDATA[<h1 id="state">@State</h1>
<blockquote>
<p>하나의 view 안에서 변경되는 변수값을 확인하여 화면을 다시 보여준다.</p>
</blockquote>
<p>SwiftUI는 struct는 값 타입이여서 struct내의 값을 변경할 수 없으며, 언제든지 삭제되거나 재생성된다.
따라서, <strong><code>@State</code></strong>를 제공해 struct내의 값을 변경할 수 있게 해준다.
단, String, Int, Bool과 같은 간단한 타입에만 사용되는 것이 좋다.
일반적으로 @State 변수는 하나의 view에서만 사용되므로 private으로 선언되고, 다른 view와 공유되지 않는다.
다른 view와 값을 공유하고 싶다면, <code>@Binding</code>, <code>@ObservedObject</code>, <code>@EnvironmentObject</code>사용한다.</p>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/143793bc-1b14-486d-9f29-acba2a86b416/image.gif" alt=""></p>
<h2 id="예제-소스">예제 소스</h2>
<pre><code class="language-swift">import SwiftUI

struct ContentView: View {

    @State private var heartCount = 0

    var buttonImage: String {
        if heartCount &gt; 0 {
            return &quot;heart.fill&quot;
        } else {
            return &quot;heart&quot;
        }
    }

    var textColor: Color {
        if heartCount &gt; 0 {
            return Color.red
        } else {
            return Color.black
        }
    }

    var body: some View {

        VStack {
            Button {
                heartCount += 1
            } label: {
                // 형태
                HStack {
                    Image(systemName: buttonImage)
                        .foregroundColor(Color.red)
                    Text(&quot;\(heartCount)명이 좋아합니다.&quot;)
                        .foregroundColor(textColor)
                }
            }

        }

    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[XML Parsing 시 유니코드 변환 오류]]></title>
            <link>https://velog.io/@thehill_hannam/XML-Parsing-%EC%8B%9C-%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C-%EB%B3%80%ED%99%98-%EC%98%A4%EB%A5%98</link>
            <guid>https://velog.io/@thehill_hannam/XML-Parsing-%EC%8B%9C-%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C-%EB%B3%80%ED%99%98-%EC%98%A4%EB%A5%98</guid>
            <pubDate>Tue, 10 May 2022 03:46:26 GMT</pubDate>
            <description><![CDATA[<h1 id="xml-parsing-error">XML Parsing Error</h1>
<p>운영중인 서비스에서 XML Parsing 시 유니코드 에러가 발생하였다.
<img src="https://velog.velcdn.com/images/thehill_hannam/post/0a07f04d-e56f-4c17-9bc7-87a2ac450a4a/image.png" alt=""></p>
<p>해당 데이터를 찾아보니 처음 보는 유니코드였다.
<img src="https://velog.velcdn.com/images/thehill_hannam/post/c95be150-1f34-4790-b392-818e1f68b0dc/image.png" alt=""></p>
<p>해당 유니코드를 확인해보니 <code>&lt;BS\&gt;</code>, Backspace 였다.</p>
<table>
<thead>
<tr>
<th align="center">유니코드 값</th>
<th align="center">이름</th>
<th align="center">형식화된 이름(Format name)</th>
</tr>
</thead>
<tbody><tr>
<td align="center">\u0009</td>
<td align="center">Tab</td>
<td align="center">&lt;TAB&gt;</td>
</tr>
<tr>
<td align="center">\u000B</td>
<td align="center">Vertical Tab</td>
<td align="center">&lt;VT&gt;</td>
</tr>
<tr>
<td align="center">\u000C</td>
<td align="center">Form Feed</td>
<td align="center">&lt;FF&gt;</td>
</tr>
<tr>
<td align="center">\u0020</td>
<td align="center">Space</td>
<td align="center">&lt;SP&gt;</td>
</tr>
<tr>
<td align="center">\u000A</td>
<td align="center">Line Feed</td>
<td align="center">&lt;LF&gt;</td>
</tr>
<tr>
<td align="center">\u000D</td>
<td align="center">Carriage Return</td>
<td align="center">&lt;CR&gt;</td>
</tr>
<tr>
<td align="center">\u0008</td>
<td align="center">Backspace</td>
<td align="center">&lt;BS&gt;</td>
</tr>
<tr>
<td align="center">\u0009</td>
<td align="center">Horizontal Tab</td>
<td align="center">&lt;HT&gt;</td>
</tr>
<tr>
<td align="center">\u0022</td>
<td align="center">Double Quote</td>
<td align="center">&quot;</td>
</tr>
<tr>
<td align="center">\u0027</td>
<td align="center">Single Quote</td>
<td align="center">&#39;</td>
</tr>
<tr>
<td align="center">\u005C</td>
<td align="center">Backslash</td>
<td align="center">\</td>
</tr>
</tbody></table>
<h2 id="해결-방법">해결 방법</h2>
<pre><code class="language-java">xmlString = xmlString.replaceAll(&quot;[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD\\u10000-\\u10FFF]+&quot;, &quot;&quot;);</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[SwiftUI - Image]]></title>
            <link>https://velog.io/@thehill_hannam/SwiftUI-Image</link>
            <guid>https://velog.io/@thehill_hannam/SwiftUI-Image</guid>
            <pubDate>Mon, 09 May 2022 15:48:22 GMT</pubDate>
            <description><![CDATA[<h1 id="image">Image</h1>
<h2 id="이미지-추가">이미지 추가</h2>
<p><code>Assets</code>에 이미지 추가
<img src="https://velog.velcdn.com/images/thehill_hannam/post/59c0a1a7-5b69-4439-ae87-aa876fd12329/image.png" alt="이미지 추가"></p>
<h3 id="이미지-호출">이미지 호출</h3>
<pre><code class="language-swift">// image name : &quot;fine&quot;, size : 744 * 960
Image(&quot;fine&quot;)</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/a6bcf943-50be-4452-91cb-2f5cb324c4a2/image.png" alt=""></p>
<p>위 이미지의 파란 네모 박스가 Image 크기이다. 크기가 화면에 안맞는다.</p>
<blockquote>
<p>Iphone&#39;s maxWidth : 414
Image width : 744</p>
</blockquote>
<h3 id="frame-설정">Frame 설정</h3>
<pre><code class="language-swift">Image(&quot;fine&quot;)
    .frame(width: 300)</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/b4dc9770-1058-4c1a-8ff5-8cb966ad18d1/image.png" alt="">
Frame을 설정 하여도 이미지 크기는 줄어들지 않았다.</p>
<h3 id="resizable">Resizable</h3>
<pre><code class="language-swift">Image(&quot;fine&quot;)
    .resizable()
    .frame(width: 300)</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/3a952d5e-842c-4820-a7fe-1231e17ba395/image.png" alt=""></p>
<p>Image에 <code>resizable</code> 설정을 해줘야 이미지 크기가 변경된다.</p>
<h3 id="edgesignoringsafearea">EdgesIgnoringSafeArea</h3>
<pre><code class="language-swift">Image(&quot;fine&quot;)
    .resizable()
    .frame(width: 300)
    .edgesIgnoringSafeArea(.all)</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/cb9dfe0c-3114-473e-8b97-55a7c092b3dc/image.png" alt=""></p>
<p>Imag에 <code>edgesIgnoringSafeArea</code>설정을 추가하면 전체 화면이 된다.</p>
<h3 id="aspectratio">AspectRatio</h3>
<h4 id="fit">fit</h4>
<pre><code class="language-swift">Image(&quot;fine&quot;)
    .resizable()
    .edgesIgnoringSafeArea(.all)
    .aspectRatio(contentMode: .fit)</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/95d7be36-5a99-4357-ac33-84d664d168df/image.png" alt=""></p>
<p>이미지의 비율을 유지 + 이미지의 전체를 보여준다.</p>
<h4 id="fill">fill</h4>
<pre><code class="language-swift">Image(&quot;fine&quot;)
    .resizable()
    .edgesIgnoringSafeArea(.all)
    .aspectRatio(contentMode: .fill)</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/85a39498-2d43-4b40-9324-211527451ebc/image.png" alt=""></p>
<p>이미지의 비율을 유지 + 이미지가 잘리더라도 꽉채움</p>
<h3 id="mask">Mask</h3>
<pre><code class="language-swift">Image(&quot;fine&quot;)
    .resizable()
    .edgesIgnoringSafeArea(.all)
    .aspectRatio(contentMode: .fill)
    .mask {
        VStack {
            Circle()
        }
    }</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/9d37397b-84f2-49af-bb51-4403099671a1/image.png" alt=""></p>
<h4 id="귀여운-루피">귀여운 루피</h4>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/38800929-a9bf-458b-945b-e594f9ca777d/image.png" alt=""></p>
<h2 id="sf-symbols">SF Symbols</h2>
<p><a href="https://developer.apple.com/sf-symbols/">SF Symbols</a>
<img src="https://velog.velcdn.com/images/thehill_hannam/post/7f31cb07-816a-46df-bfd3-0475a00a6229/image.png" alt="">
SF Symbols 프로그램을 설치하면 여러 심볼을 볼 수 있다.
해당 심볼들은 Xcode에 이미 저장되어 있어 따로 이미지 추가 없이 호출하여 부를 수 있다.
<code>foregroundColor</code>를 사용하여 색 변경도 가능하다.</p>
<pre><code class="language-swift">Image(systemName: &quot;message.circle&quot;)
    .resizable()
    .edgesIgnoringSafeArea(.all)
    .aspectRatio(contentMode: .fit)
    .foregroundColor(.blue)    // 색 변경 가능
    .padding()</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/4b44e1fd-ca82-4ecf-a295-9d18edc61a89/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SwiftUI - Text]]></title>
            <link>https://velog.io/@thehill_hannam/SwiftUI-Text</link>
            <guid>https://velog.io/@thehill_hannam/SwiftUI-Text</guid>
            <pubDate>Mon, 09 May 2022 12:40:31 GMT</pubDate>
            <description><![CDATA[<h1 id="text">Text</h1>
<h2 id="기능">기능</h2>
<h3 id="폰트">폰트</h3>
<pre><code class="language-swift">Text(&quot;Swift UI&quot;).font(.headline)</code></pre>
<h3 id="밑줄">밑줄</h3>
<pre><code class="language-swift">Text(&quot;Swift UI&quot;).underline()</code></pre>
<h3 id="굵게">굵게</h3>
<pre><code class="language-swift">Text(&quot;Swift UI&quot;).bold()</code></pre>
<h3 id="글자색">글자색</h3>
<pre><code class="language-swift">Text(&quot;Swift UI&quot;)
    .bold()
    .foregroundColor(.blue)</code></pre>
<h3 id="모서리-둥글게">모서리 둥글게</h3>
<pre><code class="language-swift">Text(&quot;Swift UI&quot;)
    .padding()
    .background(Color.yellow)
    .cornerRadius(10)</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/684deae8-01f0-4912-b3c3-c5cdb6dc217d/image.png" alt="모서리 둥글게"></p>
<h3 id="배경색">배경색</h3>
<pre><code class="language-swift">//  배경색 설정 후 패딩 설정
Text(&quot;Swift UI&quot;)
    .background(Color.yellow)
    .padding()

//  패딩 설정 후 배경색 설정
Text(&quot;Swift UI&quot;)
    .padding()
    .background(Color.yellow)</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/21236e3b-1f8c-45c3-95d0-aa69b71d655d/image.png" alt="배경색">
<strong><code>배경색 설정 후 패딩 설정, 패딩 설정 후 배경색 설정 다르다</code></strong></p>
<h3 id="잘림">잘림</h3>
<pre><code class="language-swift">//  강제로 크기를 줄이면 ... 으로 잘림
Text(&quot;Swift UI&quot;)
    .frame(width: 50, height: 30)
    .background(Color.green)</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/95eb2f16-2b2e-4393-b8a6-f95cb681ce00/image.png" alt="강제 잘림"></p>
<pre><code class="language-swift">//  lineLimit 설정
Text(&quot;Swift UI&quot;)
    .lineLimit(1)
    .frame(width: 50)
    .background(Color.blue)</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/fa431ac0-1a3a-4eb4-9a63-6807992b6d5c/image.png" alt="라인 잘림"></p>
<pre><code class="language-swift">//  앞 잘림
Text(&quot;Swift UI Swift UI Swift UI Swift UI Swift UI Swift UI Swift UI&quot;)
    .bold()
    .lineLimit(1)
    .truncationMode(.head)
    .padding()</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/c2f4f4dc-bfda-44b5-8f72-f4633485d7d1/image.png" alt="앞 잘림"></p>
<pre><code class="language-swift">//  중간 잘림
Text(&quot;Swift UI Swift UI Swift UI Swift UI Swift UI Swift UI Swift UI&quot;)
    .bold()
    .lineLimit(1)
    .truncationMode(.middle)
    .padding()</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/1089c113-eb59-44de-9503-dd5fca7a9768/image.png" alt="중간 잘림"></p>
<pre><code class="language-swift">//  뒤 잘림
Text(&quot;Swift UI Swift UI Swift UI Swift UI Swift UI Swift UI Swift UI&quot;)
    .bold()
    .lineLimit(1)
    .truncationMode(.tail)
    .padding()</code></pre>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/f68430da-7078-431b-8c35-26eddce9437b/image.png" alt="뒤 잘림"></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오라클 - 숫자형 문자형 정렬]]></title>
            <link>https://velog.io/@thehill_hannam/%EC%98%A4%EB%9D%BC%ED%81%B4-%EC%88%AB%EC%9E%90%ED%98%95-%EB%AC%B8%EC%9E%90%ED%98%95-%EC%A0%95%EB%A0%AC</link>
            <guid>https://velog.io/@thehill_hannam/%EC%98%A4%EB%9D%BC%ED%81%B4-%EC%88%AB%EC%9E%90%ED%98%95-%EB%AC%B8%EC%9E%90%ED%98%95-%EC%A0%95%EB%A0%AC</guid>
            <pubDate>Mon, 09 May 2022 09:07:53 GMT</pubDate>
            <description><![CDATA[<h1 id="숫자형-문자형-정렬">숫자형 문자형 정렬</h1>
<h2 id="order-by-오류-발생">Order by 오류 발생</h2>
<p>Order by 로 String 형태의 필드(varchar2, char 등)를 정렬할때 문자형으로 정렬이 된다.
ex ) <code>1,2,3,4,11,12,13,14 -&gt;  1,11,12,13,14,2,3,4</code>
보통 <code>TO_NUMBER(Column)</code> 형변환된 칼럼으로 정렬을 하였는데 이때 문자열이 있으면 오류가 발생한다. 
<img src="https://velog.velcdn.com/images/thehill_hannam/post/2d40a171-fbbf-47e4-80bb-9ce42d64c553/image.png" alt=""></p>
<h2 id="해결방법">해결방법</h2>
<h3 id="lpad-rpad-zero-padding">LPAD, RPAD Zero Padding</h3>
<p><a href="https://velog.io/@thehill_hannam/%EC%98%A4%EB%9D%BC%ED%81%B4-LPAD-RPAD">오라클 - LPAD, RPAD</a>
<img src="https://velog.velcdn.com/images/thehill_hannam/post/a4c8f313-608b-4f97-8ce9-7fca57b24178/image.png" alt="LPAD 결과"></p>
<p>하지만 Column의 길이가 일정하지 않으면 사용하기 힘들다.</p>
<h3 id="length">LENGTH()</h3>
<p>필드수가 많지 않아 부하 걱정이 없다면 LENGTH(Column)을 추가하는 것도 방법이다.
<img src="https://velog.velcdn.com/images/thehill_hannam/post/ab9637f8-8a79-432a-893d-54e7a33213ba/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오라클 - LPAD, RPAD]]></title>
            <link>https://velog.io/@thehill_hannam/%EC%98%A4%EB%9D%BC%ED%81%B4-LPAD-RPAD</link>
            <guid>https://velog.io/@thehill_hannam/%EC%98%A4%EB%9D%BC%ED%81%B4-LPAD-RPAD</guid>
            <pubDate>Mon, 09 May 2022 08:57:33 GMT</pubDate>
            <description><![CDATA[<h1 id="lpad-rpad">LPAD, RPAD</h1>
<h2 id="lpad">LPAD</h2>
<p>지정한 길이 만큼 <code>왼쪽</code>부터 특정 문자로 채워준다.</p>
<blockquote>
<p><strong>LPAD(&quot;값&quot;, &quot;총 문자 길이&quot;, &quot;채움 문자&quot;)</strong></p>
</blockquote>
<pre><code class="language-sql">WITH LPAD_TEST AS (
    SELECT &#39;A1&#39; AS SEQ FROM DUAL
) SELECT SEQ
     , LPAD(SEQ, 5, &#39; &#39;) AS LPAD_SPACE-- 공백
     , LPAD(SEQ, 3, &#39;0&#39;) AS LPAD_ZERO_PADDING_3 -- Zero Padding 3글자
     , LPAD(SEQ, 5, &#39;0&#39;) AS LPAD_ZERO_PADDING_5 -- Zero Padding 5글자
     , LPAD(SEQ, 5, &#39;a&#39;) AS LPAD_a_5 --  a 채우기 5글자
  FROM LPAD_TEST
</code></pre>
<h4 id="lpad-결과">LPAD 결과</h4>
<table>
<thead>
<tr>
<th align="center">SEQ</th>
<th align="center">LPAD_SPACE</th>
<th align="center">LPAD_ZERO_PADDING_3</th>
<th align="center">LPAD_ZERO_PADDING_5</th>
<th align="center">LPAD_a_5</th>
</tr>
</thead>
<tbody><tr>
<td align="center">A1</td>
<td align="center">A1</td>
<td align="center">0A1</td>
<td align="center">000A1</td>
<td align="center">aaaA1</td>
</tr>
<tr>
<td align="center">## RPAD</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center">지정한 길이 만큼 <code>오른쪽</code>부터 특정 문자로 채워준다.</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
<blockquote>
<p><strong>RPAD(&quot;값&quot;, &quot;총 문자 길이&quot;, &quot;채움 문자&quot;)</strong></p>
</blockquote>
<pre><code class="language-sql">WITH RPAD_TEST AS (
    SELECT &#39;A1&#39; AS SEQ FROM DUAL
) SELECT SEQ
     , RPAD(SEQ, 5, &#39; &#39;) AS RPAD_SPACE-- 공백
     , RPAD(SEQ, 3, &#39;0&#39;) AS RPAD_ZERO_PADDING_3 -- Zero Padding 3글자
     , RPAD(SEQ, 5, &#39;0&#39;) AS RPAD_ZERO_PADDING_5 -- Zero Padding 5글자
     , RPAD(SEQ, 5, &#39;a&#39;) AS RPAD_a_5 --  a 채우기 5글자
  FROM RPAD_TEST
</code></pre>
<h4 id="rpad-결과">RPAD 결과</h4>
<table>
<thead>
<tr>
<th align="center">SEQ</th>
<th align="center">RPAD_SPACE</th>
<th align="center">RPAD_ZERO_PADDING_3</th>
<th align="center">RPAD_ZERO_PADDING_5</th>
<th align="center">RPAD_a_5</th>
</tr>
</thead>
<tbody><tr>
<td align="center">A1</td>
<td align="center">A1</td>
<td align="center">A10</td>
<td align="center">A1000</td>
<td align="center">A1aaa</td>
</tr>
</tbody></table>
<h3 id="사용-예시">사용 예시</h3>
<table>
<thead>
<tr>
<th align="center">NAME</th>
<th align="center">ORDER_NO</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Kim</td>
<td align="center">1</td>
</tr>
<tr>
<td align="center">Alice</td>
<td align="center">2</td>
</tr>
<tr>
<td align="center">Emma</td>
<td align="center">3</td>
</tr>
<tr>
<td align="center">Laura</td>
<td align="center">4</td>
</tr>
<tr>
<td align="center">Henry</td>
<td align="center">5</td>
</tr>
<tr>
<td align="center">Oscar</td>
<td align="center">6</td>
</tr>
<tr>
<td align="center">William</td>
<td align="center">7</td>
</tr>
<tr>
<td align="center">Thomas</td>
<td align="center">8</td>
</tr>
<tr>
<td align="center">Nicole</td>
<td align="center">9</td>
</tr>
<tr>
<td align="center">Sierra</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">Riley</td>
<td align="center">11</td>
</tr>
<tr>
<td align="center">Anna</td>
<td align="center">12</td>
</tr>
<tr>
<td align="center">Edith</td>
<td align="center">13</td>
</tr>
<tr>
<td align="center">Adam</td>
<td align="center">14</td>
</tr>
<tr>
<td align="center">Paul</td>
<td align="center">15</td>
</tr>
<tr>
<td align="center">Naomi</td>
<td align="center">16</td>
</tr>
<tr>
<td align="center">Sophia</td>
<td align="center">17</td>
</tr>
<tr>
<td align="center">David</td>
<td align="center">18</td>
</tr>
<tr>
<td align="center">Abigail</td>
<td align="center">19</td>
</tr>
<tr>
<td align="center">Christina</td>
<td align="center">20</td>
</tr>
</tbody></table>
<h4 id="order-by-order_no">Order by ORDER_NO</h4>
<table>
<thead>
<tr>
<th align="center">NAME</th>
<th align="center">ORDER_NO</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Kim</td>
<td align="center">1</td>
</tr>
<tr>
<td align="center">Sierra</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">Riley</td>
<td align="center">11</td>
</tr>
<tr>
<td align="center">Anna</td>
<td align="center">12</td>
</tr>
<tr>
<td align="center">Edith</td>
<td align="center">13</td>
</tr>
<tr>
<td align="center">Adam</td>
<td align="center">14</td>
</tr>
<tr>
<td align="center">Paul</td>
<td align="center">15</td>
</tr>
<tr>
<td align="center">Naomi</td>
<td align="center">16</td>
</tr>
<tr>
<td align="center">Sophia</td>
<td align="center">17</td>
</tr>
<tr>
<td align="center">David</td>
<td align="center">18</td>
</tr>
<tr>
<td align="center">Abigail</td>
<td align="center">19</td>
</tr>
<tr>
<td align="center">Alice</td>
<td align="center">2</td>
</tr>
<tr>
<td align="center">Christina</td>
<td align="center">20</td>
</tr>
<tr>
<td align="center">Emma</td>
<td align="center">3</td>
</tr>
<tr>
<td align="center">Laura</td>
<td align="center">4</td>
</tr>
<tr>
<td align="center">Henry</td>
<td align="center">5</td>
</tr>
<tr>
<td align="center">Oscar</td>
<td align="center">6</td>
</tr>
<tr>
<td align="center">William</td>
<td align="center">7</td>
</tr>
<tr>
<td align="center">Thomas</td>
<td align="center">8</td>
</tr>
<tr>
<td align="center">Nicole</td>
<td align="center">9</td>
</tr>
</tbody></table>
<h4 id="order-by-lpadorder_no-3-0">Order by LPAD(ORDER_NO, 3, &#39;0&#39;)</h4>
<table>
<thead>
<tr>
<th align="center">NAME</th>
<th align="center">ORDER_NO</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Kim</td>
<td align="center">001</td>
</tr>
<tr>
<td align="center">Alice</td>
<td align="center">002</td>
</tr>
<tr>
<td align="center">Emma</td>
<td align="center">003</td>
</tr>
<tr>
<td align="center">Laura</td>
<td align="center">004</td>
</tr>
<tr>
<td align="center">Henry</td>
<td align="center">005</td>
</tr>
<tr>
<td align="center">Oscar</td>
<td align="center">006</td>
</tr>
<tr>
<td align="center">William</td>
<td align="center">007</td>
</tr>
<tr>
<td align="center">Thomas</td>
<td align="center">008</td>
</tr>
<tr>
<td align="center">Nicole</td>
<td align="center">009</td>
</tr>
<tr>
<td align="center">Sierra</td>
<td align="center">010</td>
</tr>
<tr>
<td align="center">Riley</td>
<td align="center">011</td>
</tr>
<tr>
<td align="center">Anna</td>
<td align="center">012</td>
</tr>
<tr>
<td align="center">Edith</td>
<td align="center">013</td>
</tr>
<tr>
<td align="center">Adam</td>
<td align="center">014</td>
</tr>
<tr>
<td align="center">Paul</td>
<td align="center">015</td>
</tr>
<tr>
<td align="center">Naomi</td>
<td align="center">016</td>
</tr>
<tr>
<td align="center">Sophia</td>
<td align="center">017</td>
</tr>
<tr>
<td align="center">David</td>
<td align="center">018</td>
</tr>
<tr>
<td align="center">Abigail</td>
<td align="center">019</td>
</tr>
<tr>
<td align="center">Christina</td>
<td align="center">020</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[NoSQL 종류]]></title>
            <link>https://velog.io/@thehill_hannam/NoSQL-%EC%A2%85%EB%A5%98</link>
            <guid>https://velog.io/@thehill_hannam/NoSQL-%EC%A2%85%EB%A5%98</guid>
            <pubDate>Sun, 08 May 2022 17:40:30 GMT</pubDate>
            <description><![CDATA[<h1 id="key-value키값">Key-Value(키/값)</h1>
<p>키와 값으로 이루어진 데이터 베이스이며, 저장과 조회라는 가장 간단한 원칙에 충실한 데이터베이스.
** <code>Join</code> ** 을 고려하지 않으므로 외부키나, 컬럼별 제약 조건 등이 필요 없다.
Key값은 고유값이며, Key Value는 모든 데이터 타입을 허용한다. </p>
<blockquote>
<p>간단한 데이터 모델을 대상으로 데이터를 자주 읽고 쓰는 애플리케이션에 적합하다.</p>
</blockquote>
<ul>
<li><p>성능 향상을 위해 RDB에서 데이터 캐싱</p>
</li>
<li><p>장바구니 같은 웹 애플리케이션에서 일시적인 속성 추적</p>
</li>
<li><p>모바일 애플리케이션용 사용자 데이터 정보,세션 정보, 구성 정보 등 저장</p>
</li>
<li><p>이미지나 오디오 파일 같은 대용량 객체 저장</p>
</li>
<li><p>Redis</p>
</li>
<li><p>Riak</p>
</li>
<li><p>Oracle Berkely</p>
</li>
<li><p>AWS DynamoDB
<img src="https://velog.velcdn.com/images/thehill_hannam/post/703cb36c-fc34-449c-8840-1072705b1de4/image.png" alt=""></p>
</li>
</ul>
<h1 id="document도큐먼트">Document(도큐먼트)</h1>
<blockquote>
</blockquote>
<ul>
<li>대용량 데이터를 읽고 쓰는 웹 사이트용 백엔드 지원</li>
<li>제품처럼 다양한 속성이 있는 데이터 관리</li>
<li>다양한 유형의 메타데이터 추적</li>
<li>JSON 데이터 구조를 사용하는 애플리케이션</li>
<li>비정규화된 중첩 구조의 데이터를 사용하는 애플리케이션</li>
</ul>
<ul>
<li>MongoDB</li>
<li>CouchDB</li>
<li>Couchbase</li>
</ul>
<pre><code class="language-JSON">[
    {
        &quot;year&quot; : 2013,
        &quot;title&quot; : &quot;Turn It Down, Or Else!&quot;,
        &quot;info&quot; : {
            &quot;directors&quot; : [ &quot;Alice Smith&quot;, &quot;Bob Jones&quot;],
            &quot;release_date&quot; : &quot;2013-01-18T00:00:00Z&quot;,
            &quot;rating&quot; : 6.2,
            &quot;genres&quot; : [&quot;Comedy&quot;, &quot;Drama&quot;],
            &quot;image_url&quot; : &quot;http://ia.media-imdb.com/images/N/O9ERWAU7FS797AJ7LU8HN09AMUP908RLlo5JF90EWR7LJKQ7@@._V1_SX400_.jpg&quot;,
            &quot;plot&quot; : &quot;A rock band plays their music at high volumes, annoying the neighbors.&quot;,
            &quot;actors&quot; : [&quot;David Matthewman&quot;, &quot;Jonathan G. Neff&quot;]
        }
    },
    {
        &quot;year&quot;: 2015,
        &quot;title&quot;: &quot;The Big New Movie&quot;,
        &quot;info&quot;: {
            &quot;plot&quot;: &quot;Nothing happens at all.&quot;,
            &quot;rating&quot;: 0
        }
    }
]</code></pre>
<h1 id="graph그래프">Graph(그래프)</h1>
<h1 id="wide-column와이드-컬럼">Wide Column(와이드 컬럼)</h1>
<h2 id="📖-참고">📖 참고</h2>
<p><a href="https://aws.amazon.com/ko/nosql/key-value/">AWS - NoSQL</a>
<a href="https://jaemunbro.medium.com/nosql-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%ED%8A%B9%EC%84%B1-%EB%B9%84%EA%B5%90-c9abe1b2838c">jaemunbro Blog</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[RDB vs NoSQL]]></title>
            <link>https://velog.io/@thehill_hannam/RDB-vs-NoSQL</link>
            <guid>https://velog.io/@thehill_hannam/RDB-vs-NoSQL</guid>
            <pubDate>Sun, 08 May 2022 16:29:09 GMT</pubDate>
            <description><![CDATA[<h1 id="rdb-vs-nosql">RDB vs NoSQL</h1>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/4306356b-3a0c-4f96-b70a-7dad8cb3e0c5/image.png" alt="데이터 베이스 종류"></p>
<h2 id="rdb">RDB</h2>
<p>** <code>Relational Database</code> ** 뜻 그래도 관계형 데이터 베이스이다.
관계형 데이터 모델을 기초로 두고 모든 데이터를 2차원(행,열) 테이블 형태로 표현한다.
테이블간의 관계에서 외래 키를 이용한 테이블 간 <code>Join</code>이 가능하다는 게 가장 큰 특징이다.</p>
<h2 id="nosql">NoSQL</h2>
<p>** <code>Not Only SQL</code> ** RDB 형태의 관계형 데이터베이스가 아닌 다른 형태의 데이터 저장한다.</p>
<h3 id="데이터-저장-방식">데이터 저장 방식</h3>
<h4 id="도큐먼트">도큐먼트</h4>
<p>데이터 하나를 도큐먼트 형식으로 표현한다.
자유로운 스키마 구조를 가지며 구조가 확정되지 않은 데이터를 밀어넣고, 자유롭게 작업하기 좋다.</p>
<h4 id="그래프">그래프</h4>
<p>데이터를 노드와 엣지로 그래프에 표현하는 방식이다.
데이터 사이의 유기적인 관계를 표현하기에 적합하다. </p>
<h4 id="키값">키/값</h4>
<p>하나의 키에 값을 맵핑하는 해시 구조의 데이터 모델이다.
빠르게 데이터에 접근할 수 있는 장점이 있다.</p>
<h4 id="와이드-컬럼">와이드 컬럼</h4>
<p>테이블 형태를 취하지만 행마다 갖는 컬럼의 형태가 고정되어 있지 않은 데이터 모델이다.
쿼리 속도, 확장성 및 유연한 데이터 모델이 장점이다.</p>
<blockquote>
<p><strong>RDB</strong> 모두 여러 열에 걸쳐 있는 행이 있는 테이블에 데이터를 저장합니다. 
<strong>Wide-Column</strong> 여전히 행의 개념이 있지만 데이터 행을 읽거나 쓰는 것은 개별 열을 읽거나 쓰는 것으로 구성됩니다. </p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/fdfa1c81-9cc2-42af-a57a-8b521f3d5b97/image.png" alt="NoSQL 데이터 저장 방식"></p>
<h2 id="rdb-vs-nosql-비교">RDB vs NoSQL 비교</h2>
<table>
<thead>
<tr>
<th align="center"></th>
<th align="center">RDB</th>
<th align="center">NoSQL DB</th>
</tr>
</thead>
<tbody><tr>
<td align="center">적합 업무</td>
<td align="center">정형 및 비정형 데이터 분석 업무</br>초당 동시 처리가 중요한 업무<br>로그 및 이력 등의 단순 기록형 업무</td>
<td align="center">데이터 무결성 및 일관성이 중요한 트랜잭션 업무<br>온라인에서 다양한 집계 및 통계를 분석하는 업무<br>복잡한 계산 및 실시간 데이터 정합성이 필요한 업무</td>
</tr>
<tr>
<td align="center">장    점</td>
<td align="center">쿼리 프로세싱이 단순화되어 대용량 데이터 처리 성능이 향상</td>
<td align="center">데이터 중복 배제로 데이터 이상 발생 및 용량 증가를 최소화</td>
</tr>
<tr>
<td align="center">단    점</td>
<td align="center">데이터 중복에 의해 데이터 일관성이 저하되고 용량이 증가</td>
<td align="center">조인이 복잡한 경우 쿼리 프로세싱도 복잡해져 성능이 저하</td>
</tr>
</tbody></table>
<h2 id="📖-참고">📖 참고</h2>
<p><a href="https://abcloudz.com/services/nosql-databases/">Abcloudz - nosql-databases</a>
<a href="https://ud803.github.io/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4/2021/11/16/RDB-vs.-NoSQL-%EC%96%B8%EC%A0%9C-%EB%88%84%EA%B5%AC%EB%A5%BC-%EC%8D%A8%EC%95%BC%ED%95%A0%EA%B9%8C/">ud803 git Hub</a>
<a href="https://im-designloper.tistory.com/67">im-designloper Tistory</a>
<a href="https://meetup.toast.com/posts/274">NHN Cloud Meet Up! - mongoDB Story</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[순위 검색 - 프로그래머스(Lv. 2, 2021 KAKAO BLIND RECRUITMENT)]]></title>
            <link>https://velog.io/@thehill_hannam/%EC%88%9C%EC%9C%84-%EA%B2%80%EC%83%89-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv.-2-2021-KAKAO-BLIND-RECRUITMENT</link>
            <guid>https://velog.io/@thehill_hannam/%EC%88%9C%EC%9C%84-%EA%B2%80%EC%83%89-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4Lv.-2-2021-KAKAO-BLIND-RECRUITMENT</guid>
            <pubDate>Fri, 06 May 2022 06:20:58 GMT</pubDate>
            <description><![CDATA[<h3 id="🎯-rgb-거리">🎯 RGB 거리</h3>
<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/72412">순위검색 - Lv. 2, 2021 KAKAO BLIND RECRUITMENT</a></p>
</blockquote>
<p><a href="https://tech.kakao.com/2021/01/25/2021-kakao-recruitment-round-1/">순위 검색 - 카카오 Tech 해설</a></p>
<hr>
<h3 id="🧐-알고리즘접근방법">🧐 알고리즘[접근방법]</h3>
<p>순위 검색 문제는 Lv. 2 문제인데 <code>[본 문제는 정확성과 효율성 테스트 각각 점수가 있는 문제입니다.]</code> 라는 끔찍한 문구가 들어 있다.
매 쿼리 문의 조건마다 INFO 배열에서 조건에 해당하는 지원자들을 찾으면서 X점 이상 받은 사람은 몇 명인지 구한다면 정확성 테스트를 통과할 수 있지만, 효율성 테스트의 경우에는 위와 같은 방식으로 매번 지원자들을 찾는다면 통과할 수 없다.<code>(정답률 :정확성 44.07%, 효율성 4.49%)</code>
지원자들의 조건으로 만들 수 있는 모든 조건을 만들어야한다.
예를 들어 java backend junior pizza 150 인 지원자가 있으면 아래와 같이 총 16가지 경우의 수를 모두 만족시킬 수 있다.</p>
<table>
<thead>
<tr>
<th align="center"><strong>언 어</strong></th>
<th align="center"><strong>직 군</strong></th>
<th align="center"><strong>경 력</strong></th>
<th align="center"><strong>소울 푸드</strong></th>
<th align="center"><strong>점 수</strong></th>
</tr>
</thead>
<tbody><tr>
<td align="center">java</td>
<td align="center">backend</td>
<td align="center">junior</td>
<td align="center">pizza</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">java</td>
<td align="center">backend</td>
<td align="center">junio</td>
<td align="center">-</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">java</td>
<td align="center">backend</td>
<td align="center">-</td>
<td align="center">pizza</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">java</td>
<td align="center">-</td>
<td align="center">junior</td>
<td align="center">pizza</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">java</td>
<td align="center">backend</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">java</td>
<td align="center">-</td>
<td align="center">junior</td>
<td align="center">-</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">java</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">pizza</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">java</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">-</td>
<td align="center">backend</td>
<td align="center">junior</td>
<td align="center">pizza</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">-</td>
<td align="center">backend</td>
<td align="center">junior</td>
<td align="center">-</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">-</td>
<td align="center">backend</td>
<td align="center">-</td>
<td align="center">pizza</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">-</td>
<td align="center">backend</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">junior</td>
<td align="center">pizza</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">junior</td>
<td align="center">-</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">pizza</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">150</td>
</tr>
<tr>
<td align="center">---</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
<h3 id="👨💻-소스">👨‍💻 소스</h3>
<pre><code class="language-java">import java.util.*;

public class Main {

    static HashMap&lt;String, ArrayList&lt;Integer&gt;&gt; personMap;    // 지원자 모든 경우의 수가 담긴 Map

    public static int[] solution(String[] info, String[] query) {
        int[] answer = new int[query.length];

        personMap = new HashMap&lt;String, ArrayList&lt;Integer&gt;&gt;();

        setPerson(info);

        for (String key : personMap.keySet()) {
          System.out.println(&quot;key : &quot; + key);
            Collections.sort(personMap.get(key));
        }

        for (int j = 0; j &lt; query.length; j++) {
            String[] temp = query[j].split(&quot; &quot;);
            String key = temp[0] + temp[2] + temp[4] + temp[6];
            int score = Integer.parseInt(temp[7]);

            if (personMap.containsKey(key)) {
              answer[j] = countPerson(key, score);
            } else {
              answer[j] = 0;
            }
        }


        return answer;
    }

    public static void main(String[] args) {
        String[] info = { &quot;java backend junior pizza 150&quot;,
                          &quot;python frontend senior chicken 210&quot;,
                          &quot;python frontend senior chicken 150&quot;,
                          &quot;cpp backend senior pizza 260&quot;,
                          &quot;java backend junior chicken 80&quot;,
                          &quot;python backend senior chicken 50&quot; };

        String[] query = { &quot;java and backend and junior and pizza 100&quot;,
                           &quot;python and frontend and senior and chicken 200&quot;,
                           &quot;cpp and - and senior and pizza 250&quot;,
                           &quot;- and backend and senior and - 150&quot;,
                           &quot;- and - and - and chicken 100&quot;,
                           &quot;- and - and - and - 150&quot; };

        int[] result = {1, 1, 1, 1, 2, 4};

        solution(info, query);

    }

    // 지원자 세팅
    public static void setPerson(String[] info) {
        for (int i = 0; i &lt; info.length; i++) {
            String[] personInfo = info[i].split(&quot; &quot;);
            addAllGroup(personInfo, &quot;&quot;, 0);
        }
    }

      // 지원자의 모든 경우의 수 DFS를 사용하여 구한다.
    public static void addAllGroup(String[] personInfo, String s, int depth) {
        if (4 == depth) {
            if (!personMap.containsKey(s)) {
                personMap.put(s, new ArrayList&lt;Integer&gt;());
            }
            personMap.get(s).add(Integer.parseInt(personInfo[4]));
            return;
        }

        addAllGroup(personInfo, s + &quot;-&quot;, depth + 1);
        addAllGroup(personInfo, s + personInfo[depth], depth + 1);
    }

    // 쿼리에 부합되는 지원자를 이분탐색을 통해 구한다.
    public static int countPerson(String key, int score) {
        ArrayList&lt;Integer&gt; list = personMap.get(key);

        int start = 0;
        int end = list.size() - 1;

        while (start &lt;= end) {
            int mid = (start + end) / 2;
            if (list.get(mid) &lt; score) {
                start = mid + 1;
            } else {
                end = mid - 1;
            }
        }

        return list.size() - start;
    }
}
</code></pre>
<hr>
<h3 id="🏅-결과">🏅 결과</h3>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/2496bdbe-a688-4581-b280-ea931b254572/image.png" alt="순위 검색 결과"></p>
<blockquote>
<p> 정확성 테스트 2,3,4,7,13,16번이 런타임 오류가 날 경우 쿼리에 해당하는 사용자가 없는 경우 이다.</p>
</blockquote>
<hr>
<h3 id="📖-관련-지식">📖 관련 지식</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[[우아한 테크 캠프 Pro] 자동차 경주 게임(프리코스 2주차)]]></title>
            <link>https://velog.io/@thehill_hannam/%EC%9A%B0%EC%95%84%ED%95%9C-%ED%85%8C%ED%81%AC-%EC%BA%A0%ED%94%84-Pro-%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B2%BD%EC%A3%BC-%EA%B2%8C%EC%9E%84%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-2%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@thehill_hannam/%EC%9A%B0%EC%95%84%ED%95%9C-%ED%85%8C%ED%81%AC-%EC%BA%A0%ED%94%84-Pro-%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B2%BD%EC%A3%BC-%EA%B2%8C%EC%9E%84%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-2%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Mon, 02 May 2022 15:24:04 GMT</pubDate>
            <description><![CDATA[<h1 id="우아한-테크-캠프-프리코스-2주차">우아한 테크 캠프 프리코스 2주차</h1>
<p>2주차 과제 메일이 도착했다.
기간은 역시 1주일이며, github를 통해 기본 세팅을 받고 코딩 후 제출 하는 방식이였다.
과제는 크게 <code>기능 요구사항</code>, <code>프로그래밍 요구사항</code>, <code>과제 진행 요구사항</code> 3가지로 구성 되었다.</p>
<h2 id="기능-요구사항">기능 요구사항</h2>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/8cc13696-6f25-4be3-86a7-d6f010ee6fbd/image.png" alt="기능 요구사항1">
<img src="https://velog.velcdn.com/images/thehill_hannam/post/520e668f-7299-4cc1-931a-1e108f04a948/image.png" alt="기능 요구사항2">
<img src="https://velog.velcdn.com/images/thehill_hannam/post/d91809ba-411e-4871-afe6-079c8db5c02a/image.png" alt="기능 요구사항3"></p>
<p>기능 요구사항은 Java를 배우면서 만들어 봤던 단순 숫자야구였다.</p>
<h2 id="프로그래밍-요구사항">프로그래밍 요구사항</h2>
<ul>
<li><a href="https://github.com/woowacourse/woowacourse-docs/tree/master/styleguide/java">자바 코드 컨벤션</a>을 지키면서 프로그래밍한다.<ul>
<li><a href="https://google.github.io/styleguide/javaguide.html">Google Java Style Guide</a></li>
<li><a href="https://github.com/JunHoPark93/google-java-styleguide">한글 번역 - 1기 제이</a></li>
<li><a href="https://newwisdom.tistory.com/m/96">한글 번역 - 3기 아마찌</a></li>
</ul>
</li>
</ul>
<ul>
<li><p>indent(인덴트, 들여쓰기) depth를 2가 넘지 않도록 구현한다.(1까지만 허용)</p>
<pre><code class="language-java">         while(index &gt; 0) { // depth 1
              for (int i = 0; i &lt; list.size(); i++) { // depth 2
                  ...
              }
          }</code></pre>
<ul>
<li>indent depth를 줄이는 좋은 방법은 함수(또는 메소드)를 분리하면 된다.</li>
</ul>
</li>
<li><p>자바 8에 추가된 stream api를 사용하지 않고 구현해야 한다. 단, 람다는 사용 가능하다.</p>
</li>
<li><p>else 예약어를 쓰지 않는다.</p>
<ul>
<li>힌트: If 조건절에서 return하는 방식으로 구현하면 else를 사용하지 않아도 된다.</li>
<li>else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다.</li>
</ul>
</li>
<li><p>함수(또는 메소드)의 길이가 10라인을 넘어가지 않도록 구현한다.</p>
<ul>
<li>함수(또는 메소드)가 한가지 일만 잘 하도록 구현한다.</li>
</ul>
</li>
</ul>
<h3 id="2주차-추가-요구사항">2주차 추가 요구사항</h3>
<p><a href="https://developerfarm.wordpress.com/2012/02/01/object_calisthenics_/">일급콜렉션을 활용해 구현한다.</a>
Collection을 포장하면서, 그 외 다른 멤버 변수가 없는 상태를 일급 컬렉션이라 한다.</p>
<ol>
<li>비지니스에 종속적인 자료구조</li>
<li>Collection의 불변성을 보장</li>
<li>상태와 행위를 한 곳에서 관리</li>
<li>이름이 있는 컬렉션
<code>경주용 차량 객체를 리스트로 가지는 경주용 차량 리스트 객체를 일급 콜렉션을 활용해 구현했다.</code></li>
</ol>
<p><a href="https://developerfarm.wordpress.com/2012/01/27/object_calisthenics_4/">모든 원시값과 문자열을 포장한다</a></p>
<h2 id="과제-진행-요구사항">과제 진행 요구사항</h2>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/833f780a-eeaa-4527-be49-b7ef1e08ad3f/image.png" alt=""></p>
<h2 id="프리코스-2주차-후기">프리코스 2주차 후기</h2>
<p><a href="https://github.com/KimTH94/java-racingcar-precourse/tree/KimTH94">프리코스 2주차 자동차 경주 게임</a>를 작성하고 과제를 제출했다.
1주 차 피드백처럼 기능 목록을 상세히 작성하려고 노력했다.
작성한 기능 목록을 토대로 TDD개발을 진행했는데 역시 실전은 달랐다.
2주 차 추가 요구사항인 <strong>일급콜렉션 활용</strong>, <strong>모든 원시값과 문자열을 포장한다.</strong> 2가지를 구글링하면서 나름대로 이해하여 코딩했지만 올바르게 했는지는 잘 모르겠다.
위 2가지 추가 요구사항은 <a href="http://www.yes24.com/Product/Goods/3290339">소트웍스 엔솔러지</a>책에 있는 내용인데 나중에 시간이 되면 읽어봐야겠다.
우아한 테크 캠프 Pro 프리 코스가 끝났다. 정규과정도 배우고 싶은 내용이 많지만 프리코스 2주차 내용만 해도 많은 도움이 되었고 어느 정도 변환점이 된 거 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[우아한 테크 캠프 Pro] 숫자 야구 피드백(프리코스 1주차 - 피드백)]]></title>
            <link>https://velog.io/@thehill_hannam/%EC%9A%B0%EC%95%84%ED%95%9C-%ED%85%8C%ED%81%AC-%EC%BA%A0%ED%94%84-Pro-%EC%88%AB%EC%9E%90-%EC%95%BC%EA%B5%AC-%ED%94%BC%EB%93%9C%EB%B0%B1%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-1%EC%A3%BC%EC%B0%A8-%ED%94%BC%EB%93%9C%EB%B0%B1</link>
            <guid>https://velog.io/@thehill_hannam/%EC%9A%B0%EC%95%84%ED%95%9C-%ED%85%8C%ED%81%AC-%EC%BA%A0%ED%94%84-Pro-%EC%88%AB%EC%9E%90-%EC%95%BC%EA%B5%AC-%ED%94%BC%EB%93%9C%EB%B0%B1%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-1%EC%A3%BC%EC%B0%A8-%ED%94%BC%EB%93%9C%EB%B0%B1</guid>
            <pubDate>Mon, 02 May 2022 13:53:41 GMT</pubDate>
            <description><![CDATA[<h1 id="우아한-테크-캠프-프리코스-1주차-피드백">우아한 테크 캠프 프리코스 1주차 피드백</h1>
<p>2주차 과제와 함께 1주차 피드백 관련 문서도 같이 왔다.
1주차 피드백 문서에는 1주차 관련 강의와 미션 진행하면서 공통 피드백이 같이 왔다.</p>
<h2 id="강의-내용">강의 내용</h2>
<p>해당 강의는 직접 TDD 개발방식으로 1주차 주요기능을 코딩하면서 설명해주는 강의였다.</p>
<p><strong>Production Code</strong> 와 <strong>Test Code</strong></p>
<pre><code class="language-java">public class Calculator {

    // Production Code
    int add(int i, int j) {
        return i + j;
    }

    int subtract(int i, int j) {
        return i - j;
    }

    int multiply(int i, int j) {
        return i * j;
    }

    int divide(int i, int j) {
        return i / j;
    }

    // Test Code
    public static void main(String[] args) {
        Calculator cal = new Calculator();
        System.out.println(cal.add(3, 4));
        System.out.println(cal.subtract(5, 4));
        System.out.println(cal.multiply(2, 6));
        System.out.println(cal.divide(8, 4));
    }

}</code></pre>
<p>TDD = TFD(Test First Development) + 리팩토링
TDD  : Test Code 구현 ➡ 기능 구현 ➡ 리팩토링</p>
<p><img src="https://velog.velcdn.com/images/thehill_hannam/post/1610aa27-8895-4b1a-9cf2-7bd91317761b/image.png" alt="TDD Cycle"></p>
<blockquote>
<p><strong>TDD Cycle</strong></p>
</blockquote>
<ol>
<li>Test Fails(실패하는 테스트를 구현한다.)</li>
<li>Test passes(테스트가 성공하도록 프로덕션 코드를 구현한다.)</li>
<li>Refactoring(프로덕션 코드와 테스트 코드를 리팩토링 한다.)</li>
</ol>
<p><code>TDD를 잘하기 위해서는 To-do List를 잘 정리해야한다. == 요구사항 분석을 잘 해야한다.</code></p>
<h2 id="공통-피드백">공통 피드백</h2>
<h3 id="이름을-통해-의도를-드러내라">이름을 통해 의도를 드러내라.</h3>
<p><code>변수 이름, 함수(메소드)이름, 클래스 이름을 짓는데 시간을 투자하라.</code>
<code>이름을 통해 변수의 역할, 함수의 역할, 클래스의 역할에 대한 의도를 드러내기 위해 노력하라.</code>
연속적인 숫자를 덧붙인 이름(a1, a2, ..., aN) 덧붙이거나 불용어(Info, Data, a, an, the)를 추가하는 방식은 적절하지 못하다.</p>
<p>그 동안 코딩하면서 num1, num2 등 변수 이름, Student s = new Student() 등 이름을 너무 대충 지은거 같다.</p>
<hr>
<h3 id="축약하지-마라">축약하지 마라.</h3>
<p><code>의도를 드러낼 수 있다면 이름이 길어져도 괜찮다.</code></p>
<p>짧고 깔끔한 코드가 보기도 좋고 좋은 코드라고 생각했는데 이 항목을 보면서 그 동안 내가 보기엔 깔끔한 코드였지만 다른 개발자가 보기엔 별로 좋지 않은 코드라고 생각할거 같았다.</p>
<hr>
<h3 id="개발-도구의-code-format-기능을-활용해라">개발 도구의 code format 기능을 활용해라.</h3>
<p>IntelliJ 또는 Eclipse의 formatting 기능을 활용한다.(<a href="https://velog.io/@thehill_hannam/IntelliJ-Code-Convention-%EC%A0%81%EC%9A%A9">Google Java Style Guide 적용하기</a>)</p>
<blockquote>
<p>IntelliJ 단축키는 Ctrl+Alt+L(윈도우), Cmd+Alt+L(mac)
Eclipse 단축키는 Ctrl+Shift+F(윈도우), Cmd+Shift+F(mac)</p>
</blockquote>
<hr>
<h3 id="space공백도-convention협약이다">space(공백)도 convention(협약)이다.</h3>
<p><code>for, while, if문 사이의 space도 convention이다.</code></p>
<pre><code class="language-java">for (int index = 0; index &lt; list.size(); index++) {
    ...
}

while (true) {
    ...
}

if (true) {
    ...
}</code></pre>
<hr>
<h3 id="불필요하게-공백-라인을-만들지-않는다">불필요하게 공백 라인을 만들지 않는다.</h3>
<p>공백 라인을 뛰우는 것도 코드상에 문맥이 달라지는 부분에 의도를 가지고 뛰우면 좋겠다.</p>
<pre><code class="language-java">class Student {
    // 변수
    String studentNo;
    String name;
    // 공백(BLANK LINE)
    // 생성자
    Student(String name, String studentNo) {
        ...
    }
}</code></pre>
<h3 id="구현-순서도-convention이다">구현 순서도 convention이다.</h3>
<p>클래스의 구현 순서에 대한 convention을 지키는 것도 읽기 좋은 코드를 구현하는데 의미가 있다.</p>
<pre><code class="language-java">// 상수 -&gt; 클래스 변수 -&gt; 인스턴스 변수 -&gt; 생성자 -&gt; 메소드
class Student {
    // 상수
    static final int MIN_GRADE = 1;
    static final int MAX_GRADE = 3;

    // 클래스 변수
    static String schoolName;

    // 인스턴스 변수
    String studentNo;
    String name;

    // 생성자
    Student(String name, String studentNo) {
        ...
    }

    // 메소드
    public void setName() {
        ...
    }
}</code></pre>
<hr>
<h3 id="반복하지-마라">반복하지 마라.</h3>
<p>중복은 소프트웨어에서 모든 악의 근원이다.</p>
<blockquote>
<p><strong>중복은 함수로 처리</strong></p>
</blockquote>
<hr>
<h3 id="space-vs-tab-혼용-하지-마라">space vs tab 혼용 하지 마라.</h3>
<p>들여쓰기에 space와 tab을 혼용하지 않는다. 둘 중에 하나만 사용한다.</p>
<hr>
<h3 id="의미없는-주석을-달지-않는다">의미없는 주석을 달지 않는다.</h3>
<p>변수 이름, 함수(메소드) 이름을 통해 어떤 의도인지가 드러난다면 굳이 주석을 달지 않는다.
모든 변수와 함수에 주석을 달기보다 가능하면 이름을 통해 의도를 드러내고,
<strong>의도를 드러내기 힘든 경우 주석을 다는 연습을 한다.</strong></p>
<hr>
<h3 id="값을-하드코딩하지-마라">값을 하드코딩하지 마라.</h3>
<p>문자열 숫자 등의 값을 하드코딩하지 마라.
상수를 만들고 이름을 부여해 이 변수의 역할이 무엇인지 의도를 드러내라.</p>
<pre><code class="language-java">class Student {
    static final int MIN_GRADE = 1;
    static final int MAX_GRADE = 3;

    int grade;

    Stduent(int grade) {
        if (MIN_GRADE &gt; grade || MAX_GRADE &lt; grade) {
            throw new exception(&quot;[Error] grade range&quot;);
        }
    }

}</code></pre>
<hr>
<h3 id="git-commit-메시지를-의미있게-작성">git commit 메시지를 의미있게 작성</h3>
<p>commit 메시지에 해당 commit에서 작업한 내용에 대한 이해가 가능하도록 작성한다.
<img src="https://velog.velcdn.com/images/thehill_hannam/post/ded113aa-9223-4be9-a4a7-478345cdf7ef/image.png" alt=""></p>
<hr>
<h3 id="기능-목록-업데이트한다">기능 목록 업데이트한다.</h3>
<p>README.md 파일에 작성하는 기능 목록은 기능 구현을 하면서 변경될 수 있다.
<code>시작할 때 모든 기능 목록을 완벽하게 정리해야 한다는 부담을 가지기 보다 기능을 구현하면서 문서를 계속 업데이트한다.</code></p>
<hr>
<h3 id="기능-목록-구현을-재검토한다">기능 목록 구현을 재검토한다.</h3>
<p>기능 목록을 클래스 설계와 구현, 함수 설계와 구현과 같이 너무 상세하게 작성하지 않는다.
클래스 이름, 함수(메소드) input/output은 언제든지 변경될 수 있기 때문이다.
너무 세세한 부분까지 정리하기 보다 구현해야할 기능 목록을 정리하는데 집중한다.
정상적인 경우도 중요하지만 예외적인 상황도 기능 목록에 정리한다.
특히 예외 상황은 시작단계에서 모두 찾기 힘들기 때문에 기능을 구현하면서 계속해서 추가해 나간다.</p>
<hr>
<h3 id="readememd를-상세히-작성한다">READEME.md를 상세히 작성한다.</h3>
<p>README.md는 소스코드에 앞서 해당 프로젝트가 어떠한 프로젝트인지 마크다운으로 작성하여 소개하는 문서이다.
해당 프로젝트가 어떠한 프로젝트이며, 어떤 기능을 담고 있는지 기술해야 한다.</p>
<h2 id="프리코스-1주차-피드백-후기">프리코스 1주차 피드백 후기</h2>
<p>TDD 강의와 1주 차 과제를 TDD로 개발하는 과정을 지켜보고 나서 TDD에 대한 기본적으로 이해를 하게 되었다.
피드백 강의를 들으면서 처음부터 어렵게 하지 말고 쉬운 기능부터 해보라고 말씀하셨고, 정 어려우면 먼저 개발하고 코드를 삭제하고 TDD 방식으로 다시 개발해보라고 하셨다.
이미 과제를 제출 후여서 해당 강의 내용이 이해가 쉬웠던 거 같다.
앞으로 새로운 기술 및 지식을 공부할 때 급하게 하지 말고 돌아가더라도 이해해야 한다고 생각 들었다.
또한, 공통 피드백 내용은 공감이 많이 갔다.
<strong>반복하지 마라.</strong>, <strong>불필요하게 공백 라인을 만들지 않는다.</strong> 같은 내용은 평소에 나름 프로젝트 품질을 높이기 위해 노력했다고 생각하는데 많이 놓쳤던 부분이였다.
위의 내용 중 이해 안가는 부분이 있어 찾아보니 <code>Clean Code</code>에 적혀져 있는 내용 같았다.
나중에 시간이 되면 해당 책을 읽어봐야겠다.</p>
]]></description>
        </item>
    </channel>
</rss>