<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>developer_kim.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Fri, 21 Jun 2024 10:31:32 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>developer_kim.log</title>
            <url>https://velog.velcdn.com/images/developer_kim/profile/b4ab6b5b-a3ae-4fee-ac88-3b0d4e4e56ed/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. developer_kim.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/developer_kim" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[인터페이스]]></title>
            <link>https://velog.io/@developer_kim/%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4</link>
            <guid>https://velog.io/@developer_kim/%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4</guid>
            <pubDate>Fri, 21 Jun 2024 10:31:32 GMT</pubDate>
            <description><![CDATA[<h1 id="인터페이스란">인터페이스란?</h1>
<ul>
<li><em><strong>추상 메서드의 집합</strong></em></li>
<li>구현된 것이 전혀없는 설계도. 껍데기(모든 멤버가 public)</li>
</ul>
<pre><code>interface PlayingCard {
    public static final int SPADE = 4;
    final int DIAMOND = 3; // public static final
    static int HEART = 2; // public static final
    int CLOVER = 1; // public static final

    public abstract String getCardNumber();
    String getCardKind();  
    // public abstract String getCardKind();
    // public abstract를 생략한것
}</code></pre><ul>
<li>인터페이스의 조상은 인터페이스만 가능(object아님)</li>
<li>다중 상속이 가능 (추상메서드는 충돌해도 문제없음)</li>
</ul>
<pre><code>interface Fightable extends Movable, Attackable {}

interface Movable {
    void main(int x, int y);
}

interface Attackable {
    void attack(iUnit u);
}</code></pre><h1 id="인터페이스의-구현">인터페이스의 구현</h1>
<ul>
<li>인터페이스에 정의된 추상 메서드를 완성하는 것</li>
<li><strong>implements</strong> 키워드 사용</li>
<li>일부만 구현하는 경우 클래스 앞에 abstract 붙여야함 (추상클래스와 동일)</li>
</ul>
<pre><code>class 클래스이름 implements 인터페이스 이름 {
}
</code></pre><h1 id="인터페이스-다형성">인터페이스 다형성</h1>
<pre><code>interface Fighteable {
  void move(int x, int y);
  void attack(Fightable f);
}


class Fighter extends Unit implements Fightable {
  public void move(int x, int y) { ... }
  public void attack(Fightable f) { ... }
}

// 부모 = new 자식
Unit u = new Fighter();
Fightable f = new Fighter();

f.move(100, 200);
f.attack(new Fighter());
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[추상클래스와 인터페이스의 차이]]></title>
            <link>https://velog.io/@developer_kim/%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@developer_kim/%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Fri, 21 Jun 2024 10:22:01 GMT</pubDate>
            <description><![CDATA[<h2 id="추상클래스와-인터페이스의-차이는">추상클래스와 인터페이스의 차이는?</h2>
<blockquote>
<p>공통점</p>
</blockquote>
<ul>
<li>추상메서드를 가지고 있다. (미완성 설계도)
차이점:</li>
<li>추상클래스 - 일반적인 클래스의 특징을 다 가지고 있음(instance variable, instance method, constructor) + abstract methods</li>
<li>인터페이스 - 추상메서드만 가능(생성자, iv, im 불가능)</li>
</ul>
<h4 id="--추상클래스">- 추상클래스:</h4>
<p>추상메서드를 가지고 있는 클래스</p>
<ul>
<li>추상메서드 구현<pre><code>abstract class Player {
  abstract void play(int pos);
  abstract void stop();
}
</code></pre></li>
</ul>
<p>class AudioPlayer extends Player { 
    void play(int pos) { 생략... } 
    void stop() { 생략... }
}</p>
<pre><code>

#### - 인터페이스:
추상메서드와 상수를 가지고 있는 것. 모든 메서드가 public

- 인터페이스 구현</code></pre><p>interface Fightable {
    void move(int x, int y);
    void attack() 
}</p>
<p>class Fighter implements Fightable {
    public void move(int x, int y){ 생략... }
    public void attack(){ 생략... }
}
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[추상 클래스]]></title>
            <link>https://velog.io/@developer_kim/%EC%B6%94%EC%83%81-%ED%81%B4%EB%9E%98%EC%8A%A4</link>
            <guid>https://velog.io/@developer_kim/%EC%B6%94%EC%83%81-%ED%81%B4%EB%9E%98%EC%8A%A4</guid>
            <pubDate>Fri, 21 Jun 2024 10:00:56 GMT</pubDate>
            <description><![CDATA[<h2 id="추상클래스란">추상클래스란?</h2>
<ul>
<li>미완성 메서드를 가지고 있는 클래스 (=미완성 설계도)</li>
<li>여러 클래스에서 공통적으로 사용될 수 있는 부분을 추상클래스로 작성할 수 있다.</li>
</ul>
<pre><code>abstract class Player {
    abstract void play(int pos); 
    abstract void stop();
}</code></pre><h3 id="특징---추상클래스는-인스턴스-생성-불가">특징 - 추상클래스는 인스턴스 생성 불가</h3>
<p>Player p = new Player(); // 에러 발생</p>
<ul>
<li>이렇게 쓸 수 없다는 것.</li>
</ul>
<p>그렇다면 추상클래스를 왜 쓸까요?</p>
<ul>
<li>다른 클래스 작성에 도움을 주기 위해서.</li>
<li>상속을 통해 추상 메서드를 완성해야 인스턴스 생성가능<pre><code>class AudioPlayer extends Player {
  void play(int pos) { ... }
  void stop() { ... }
}
</code></pre></li>
</ul>
<p>AudioPlayer ap = new AudioPlayer();   // OK</p>
<pre><code>= 이렇게 상속을 받고 써줘야 인스턴스 생성 가능


## 추상 메서드란?
- 미완성 메서드. 구현부가 없는 메서드
- 꼭 필요하지만 ** 자손마다 다르게 구현될 것으로 예상되는 경우** 사용함
- 반드시 다 구현해야 하는건 아님
- 일부만 구현하는 경우? 아래처럼 abstract를 써줘야함
- 추상 클래스도 생성자가 있어야 함
</code></pre><p>abstract class AbstractPlayer extends Player {
    void play(int pos) { ... }</p>
<pre><code>// stop이 구현 안되어있으므로 클래스에 abstract써줘야함</code></pre><p>}</p>
<pre><code>
예제.</code></pre><p>abstract class Player {
    boolean pause;
    int currentPos;</p>
<pre><code>Player() {
} // 생성자 있어야함

abstract void play(int pos); // 추상메서드
abstract void stop(); //추상 메서드

void play() {
    play(currentPos);
}</code></pre><p>}</p>
<pre><code>
사용하려면?
- 위 추상클래스를 상속받는 자손을 구현하여 추상 메소드를 구현하고, 자손 객체를 생성한 후 play를 호출하면 됨.

AudioPlay라는 객체가 Player로 상속받아서 사용했다면
Player p = new AudioPlayer(); 이렇게 사용가능. - 다형성!!! Polymorphism






</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[다형성 polymorphism]]></title>
            <link>https://velog.io/@developer_kim/%EB%8B%A4%ED%98%95%EC%84%B1-polymorphism</link>
            <guid>https://velog.io/@developer_kim/%EB%8B%A4%ED%98%95%EC%84%B1-polymorphism</guid>
            <pubDate>Fri, 21 Jun 2024 08:17:48 GMT</pubDate>
            <description><![CDATA[<p>1) 여러가지 형태를 가질 수 있는 능력
2) 조상 타입 참조변수로 자손 타입 객체를 다루는 것</p>
<pre><code>class SmartTv extends TV {
    ....
}</code></pre><p>smartTv가 Tv부모객체를 상속받은 형태일때,</p>
<pre><code>Tv t = new SmartTV();</code></pre><p> 와 같이 사용할 수 있는 것.</p>
<p>SmartTv s = new SmartTv(); //참조변수와 인스턴스 타입이 일치
Tv t = new SmartTv(); // 조상참조변수로 자손인스턴스 참조
SmartTv s = new Tv(); // 이건 에러. * 왼쪽이 리모콘이라고 생각하면 이해하기 쉬움</p>
<h3 id="참조변수의-형-변환">참조변수의 형 변환</h3>
<p>사용할 수 있는 멤버의 갯수를 조절하는 것</p>
<pre><code>class FireEngine extends Car {
}

FireEngine f = new FireEngine();
Car c = (Car) f
FireEngine f = (FireEngine) c // 형변환 실행에러 java.lang.classCastException</code></pre><p>형변환 전에 instanceof 연산자로 형변환 가능여부를 *<em>반드시 *</em> 확인하고 변환해야 함</p>
<h4 id="if-a-instanceof-b---a는-b의-child-">if (a instanceof b) { // a는 b의 child ?</h4>
<p>}</p>
<pre><code>//c가 fireEngine인지, c가 FireEngine의 child or 자기자신인지를 확인하는 것

if (c instance of FireEngine) {
}

System.out.println(fe instanceof Object); //true
System.out.println(fe instanceof Car); // true 
System.out.println(fe instanceof FireEngine); // true </code></pre><h2 id="다형성의-장점">다형성의 장점</h2>
<p>1) 다형적 매개변수: Polymorphism allows objects to be treated as instances of their parent class</p>
<pre><code>  Product p = new TV();
  Product c = new Computer();

  class buy(Tv t) {
  }

  class buy(Computer c) {
  }

  // 이렇게 다 따로 오버로딩 해주는게 아니라 

  class buy(Product p) {
  }
  // 이렇게 하나로 써줄 수 있음 
</code></pre><p>2) 여러종류의 객체를 배열로 다루기</p>
<pre><code>Product p[] = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[기본형 변수]]></title>
            <link>https://velog.io/@developer_kim/%EA%B8%B0%EB%B3%B8%ED%98%95-%EB%B3%80%EC%88%98</link>
            <guid>https://velog.io/@developer_kim/%EA%B8%B0%EB%B3%B8%ED%98%95-%EB%B3%80%EC%88%98</guid>
            <pubDate>Wed, 15 May 2024 08:05:03 GMT</pubDate>
            <description><![CDATA[<h2 id="기본형-변수-primitive-type-8개">기본형 변수 Primitive Type (8개)</h2>
<p>논리형 - boolean
문자형 - char / string
정수형 - int / long / byte(이진데이터) / short(c언어와의 호환을 위해 추가되었으나 잘 쓰이지 않음)
실수형 - float / double</p>
<p><img src="https://velog.velcdn.com/images/developer_kim/post/4e1417a2-8b5c-4ef1-bdfe-e48924a84d92/image.png" alt="">
출처- <a href="https://www.youtube.com/watch?v=yVxsi_CBLR0&amp;list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&amp;index=18">https://www.youtube.com/watch?v=yVxsi_CBLR0&amp;list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&amp;index=18</a></p>
<p>1bit - 2진수 한 자리
1byte - 8bit</p>
<p>byte b = 3; (00000011; //이렇게 2진수로 저장)
n비트로 표현할 수 있는 값의 갯수? 2n개 
n비트로 표현할 수 있는 부호 없는 값의 갯수? 0 ~ 255
n비트로 표현할 수 있는 부호 있는 값의 갯수? -128 ~ 127</p>
<p>부호있는 정수의 범위<img src="https://velog.velcdn.com/images/developer_kim/post/acbf40b7-2b4b-4d38-aa8b-c400e450e74a/image.png" alt=""></p>
<p>short 2 byte = 16bit -2의15 ~2의 15 - 1
char 0 ~ 2의16 - 1
등등....</p>
<h3 id="println--printf">Println / Printf</h3>
<p>만약 지시자를 선택해서 출력하고 싶으면 printf()를 사용하면 된다
%b : boolean
%d : 10진수
%o : 8진수 (%#o으로 써주면 접두사가 붙음. 01...)
%x : 16진수 (%#x으로 써주면 접두사가 붙음. 0x...)
%f : float
%e, %E : 지수 exponent 
%c : character
%s : string
%g : 간략한 형식 (f 또는 e)</p>
<ul>
<li>2진수는 없음 Integer.toBinaryString(정수) : 2진수를 문자열로 출력 </li>
</ul>
<pre><code>system.out.printf(&quot;age: %d year: %d\n&quot;, 14, 2017);

float f = 123.4567890f;

system.out.printf(&quot;%f&quot;, f); 
// 123.456787 정밀도는 7자리. 그 외의 자리, 여기선 87은 의미 없음. 
// 정확한 값을 출력하고 싶으면 double사용하면 됨. 정밀도가 15자리임

system.out.printf(&quot;%e&quot;, f); 
// 1.234568e+02 지수 형식으로 출력, 마지막자리 반올림되어서 8로 나옴

System.out.printf(&quot;[%5d]%n&quot;, 10); // [   10] 앞의 세 자리는 빈 공간으로 체워짐
System.out.printf(&quot;[%-5d]%n&quot;, 10); // [10   ] 왼쪽 정렬
System.out.printf(&quot;[%05d]%n&quot;, 10); // [00010] 공백대신 0로 출력되도록

System.out.printf(&quot;[%5d]%n&quot;, 1234567); // [1234567] // 지정 자리수보다 큰 값이면, 값이 잘리는게 아니라 전부 나옴

double d = 1.23456789;
System.out.printf(&quot;[%14.10f]&quot;, d); //전제 14자리에, 소수점 10자리 =&gt; [  1.2345678900] 
System.out.printf(&quot;[%.6f]&quot;, d);  // [1.234568] 소수점 6자리
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[변수,  상수, 리터럴]]></title>
            <link>https://velog.io/@developer_kim/%EB%B3%80%EC%88%98-%EC%83%81%EC%88%98-%EB%A6%AC%ED%84%B0%EB%9F%B4</link>
            <guid>https://velog.io/@developer_kim/%EB%B3%80%EC%88%98-%EC%83%81%EC%88%98-%EB%A6%AC%ED%84%B0%EB%9F%B4</guid>
            <pubDate>Mon, 13 May 2024 07:23:03 GMT</pubDate>
            <description><![CDATA[<h4 id="1-변수variable">1. 변수(Variable)</h4>
<ul>
<li>하나의 값을 저장할 수 있는 메모리 공간(RAM)</li>
</ul>
<h4 id="2-변수의-선언-및-저장">2. 변수의 선언 및 저장</h4>
<ul>
<li>변수타입 변수이름; 
ex) int age = 10; 
age라는 메모리 공간에 10이라는 값을 저장하는 것</li>
</ul>
<h4 id="3-변수의-종류">3. 변수의 종류</h4>
<p>클래스 변수, 인스턴스 변수, 지역 변수(꼭 초기화 해야 함)</p>
<h4 id="4-변수의-타입-기본형-8가지">4. 변수의 타입 (기본형 8가지)</h4>
<p>문자 char 
정수 byte, short, int, long<br>실수 float double
논리 boolean</p>
<h4 id="5-변수와-상수-리터럴">5. 변수와 상수, 리터럴</h4>
<p>변수(variable)는 저장한 값을 변경가능하지만 상수(constant)는 &#39;한 번&#39;만 저장 가능</p>
<ul>
<li>변수 int score = 100; </li>
<li>상수 <strong>final</strong> int MAX = 100; </li>
<li>리터럴(literal) - 그 자체로 <strong>값</strong>을 의미하는 것
<img src="https://velog.velcdn.com/images/developer_kim/post/128c796e-2c85-4f6e-8ad3-8b82d82c45e4/image.png" alt="">
출처: 유투브 남궁석의 자바의 정석(<a href="https://www.youtube.com/watch?v=17FmvFm0E68&amp;list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&amp;index=13">https://www.youtube.com/watch?v=17FmvFm0E68&amp;list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&amp;index=13</a>)</li>
</ul>
<p>리터럴의 접두사와 접미사
접미사 : 대/소문자 구분 없이 사용. 
float a = 1.4f; 
byte b = 127; 
byte b = 128; -&gt; error, byte타입은 -128 ~ 127까지만 저장 가능
int i = 100;
int bi = <strong>0b</strong>0101; // 2진수
int oct = <strong>0</strong>100; // 8진수
int hex = <strong>0x</strong>100; // 16진수
long l = 10_000_000_000L; // L안붙이면 에러남. int범위를 벗어나는 값이기 때문에. _는 보기 편하라고 넣는 것임</p>
<p>float f = 3.14f; (f를 생략하면 double로 인식하여 오류가 남)
double d = 3.14d; (d는 생략가능)</p>
<p>Quiz
10. =&gt; double 10.0
.10 =&gt; double 0.10
10f =&gt; float 10.0
1e3 =&gt; double 1000.0</p>
<h4 id="변수와-리터럴의-타입-불일치">변수와 리터럴의 타입 불일치</h4>
<p>1) 가능한 케이스 : 범위가 변수 &gt; 리터럴
int i = &#39;A&#39;; // int의 저장범위가 char보다 크므로 가능함
long l = 103; // long &gt; int
double d = 3.14f; // double &gt; float</p>
<p>2) 불가능한 케이스 : 범위가 변수 &lt; 리터럴
int i = 30_000_000_000; //int의 범위(20억)를 벗어남
long l = 3.14f // long &lt; float
float f = 3.14 // float &lt; double</p>
<p>3) byte, short변수에 int리터럴 저장 가능
byte b = 100; // byte범위 -128 ~ 127에 속하므로
byte b = 128; // 이건 범위를 벗어나서 오류</p>
<h4 id="기본형과-참조형">기본형과 참조형</h4>
<p>기본형 Primitive Type</p>
<ul>
<li>boolean, char, byte, short, int, long, float, double 딱 8개
참조형 Reference type</li>
<li>기본형을 제외한 나머지(String, System등.. )</li>
<li>메모리 주소를 저장(4 byte or 8 byte)
(32bit JVM에서는 4byte, 64bit JVM에서는 8byte)</li>
</ul>
<p>참조형 변수 예제
<strong>Date</strong> today;
today = new Date();
// today에 <strong>객체의 주소</strong>를 저장하는 것 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바의 특징, 자바 가상머신]]></title>
            <link>https://velog.io/@developer_kim/%EC%9E%90%EB%B0%94%EC%9D%98-%EC%A0%95%EC%84%9D-2.-%EC%9E%90%EB%B0%94%EC%9D%98-%ED%8A%B9%EC%A7%95-%EC%9E%90%EB%B0%94-%EA%B0%80%EC%83%81%EB%A8%B8%EC%8B%A0</link>
            <guid>https://velog.io/@developer_kim/%EC%9E%90%EB%B0%94%EC%9D%98-%EC%A0%95%EC%84%9D-2.-%EC%9E%90%EB%B0%94%EC%9D%98-%ED%8A%B9%EC%A7%95-%EC%9E%90%EB%B0%94-%EA%B0%80%EC%83%81%EB%A8%B8%EC%8B%A0</guid>
            <pubDate>Thu, 09 May 2024 11:47:20 GMT</pubDate>
            <description><![CDATA[<h1 id="자바의-특징">자바의 특징</h1>
<h4 id="객체지향">객체지향</h4>
<ul>
<li>C++, Java, python등에서 사용되는 개념</li>
</ul>
<h4 id="자동-메모리-관리">자동 메모리 관리</h4>
<ul>
<li>자바가 나오기 전에는 &#39;사람&#39;이 직접 메모리를 관리를 했어야 하지만, 자바에서는 Garbage Collector(GC)가 메모리를 알아서 정리해 준다</li>
</ul>
<h4 id="멀티-쓰레드-지원">멀티 쓰레드 지원</h4>
<ul>
<li>하나의 프로그램에서 여러개의 작업을 가능하게 해줌</li>
</ul>
<h4 id="풍부한-라이브러리-제공">풍부한 라이브러리 제공</h4>
<ul>
<li>라이브러리? 프로그램을 개발하는데 자주 쓰이는 기능들을 제공해 주는 것</li>
</ul>
<h4 id="운영체제에-독립적">운영체제에 독립적</h4>
<ul>
<li>일반적으로 프로그래밍을 작성하면, 특정 운영체제에서만 운영이 가능함(=윈도우에서 작성한 프로그램은 리눅스에서 사용 불가능)</li>
<li>그치만 자바의 경우엔 어느 운영체제에서나 사용 가능</li>
<li>어째서? 자바 가상 머신 때문</li>
</ul>
<h1 id="자바-가상-머신jvm---java-virtual-machine">자바 가상 머신(JVM - Java Virtual Machine)</h1>
<p>자바 프로그램이 실행되는 가상 컴퓨터
한번 작성하면, 어디서든 실행 - Write once, Run anywhere</p>
<p><img src="https://velog.velcdn.com/images/developer_kim/post/43b5995e-3a8e-4cdc-a2ee-3919a2b2d5d4/image.png" alt="">
출처: <a href="https://www.tcpschool.com/java/java_intro_programming">https://www.tcpschool.com/java/java_intro_programming</a></p>
<p>자바는 운영체제별로 JVM이 개발되어 있어서, 자바 애플리케이션을 구현하고 나면 다른 운영체제에서도 실행함에 있어 전혀 문제가 되지 않는다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바의 정석] 자바란 ]]></title>
            <link>https://velog.io/@developer_kim/%EC%9E%90%EB%B0%94%EC%9D%98-%EC%A0%95%EC%84%9D-1.-%EC%9E%90%EB%B0%94%EB%9E%80</link>
            <guid>https://velog.io/@developer_kim/%EC%9E%90%EB%B0%94%EC%9D%98-%EC%A0%95%EC%84%9D-1.-%EC%9E%90%EB%B0%94%EB%9E%80</guid>
            <pubDate>Thu, 09 May 2024 11:31:27 GMT</pubDate>
            <description><![CDATA[<h2 id="자바란">자바란?</h2>
<ul>
<li>프로그래밍 언어</li>
<li>실행 환경(JRE) + 개발도구(JDK) + 라이브러리(API)</li>
</ul>
<h4 id="자바는-어디에-쓰이나요">자바는 어디에 쓰이나요?</h4>
<ul>
<li>PC Application - ex. 개발도구인 인텔리제이, 이클립스 또한 자바로 만들어 짐</li>
<li>Web Application</li>
<li>Android Application</li>
<li>Big Data - Hadoop</li>
<li>Game, 과학, 소형기기 등 - ex. 마인크래프트</li>
</ul>
<h4 id="왜-굳이-자바를-배워야-하나요">왜 굳이 자바를 배워야 하나요?</h4>
<ul>
<li>다양한 분야에서 활발히 사용됨</li>
<li>20년 이상 프로그래밍 1, 2위로 사용되는 언어</li>
<li>배우기 쉽고 풍부한 학습자료</li>
<li>모던 프로그래밍 언어 = 객체지향 + 함수형(자바 8부터 추가됨)</li>
<li>실무에 가장 많이 사용되는 언어</li>
</ul>
<h4 id="자바의-역사">자바의 역사</h4>
<ul>
<li>JDK 1996년 개발 </li>
<li>J2SE 1.2 1998 - J2SE(스탠다드) / J2ME(소형, 마이크로) / J2EE(대기업용)</li>
<li>J2SE 5.0 2004</li>
<li>JAVA SE8 2014 - 이 후 6개월마다 새로운 버전이 나오고 있음, 아직도 가장 많이 사용되는 버전</li>
<li>JAVA SE 21</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바] 컴파일러]]></title>
            <link>https://velog.io/@developer_kim/%EC%9E%90%EB%B0%94-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC</link>
            <guid>https://velog.io/@developer_kim/%EC%9E%90%EB%B0%94-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC</guid>
            <pubDate>Tue, 09 Apr 2024 09:55:13 GMT</pubDate>
            <description><![CDATA[<h2 id="컴파일러compiler란">컴파일러(Compiler)란?</h2>
<p>프로그래밍 언어로 작성된 소스 코드(.java)를 컴퓨터가 이해할 수 있는 기계어(.class)로 변환하는 <strong>소프트웨어 도구</strong> 를 의미한다.</p>
<p>컴파일 주요기능</p>
<ul>
<li>사람이 작성한 code를(high-level language)를 기계어(low-level language)로 바꿔주는 과정</li>
<li>Verifying syntax: 문법 검사(문장 끝에 세미콜론(;)을 붙였냐 하는걸 검사하는듯..?)</li>
<li>Semantics of source code: 변수의 정의와 사용, 함수 호출 등을 분석 </li>
<li>Code optimizations: 최적화, 시간이 많이 소요되는 작업</li>
<li>Generate machine code</li>
</ul>
<h2 id="compilation-vs-interpretion">Compilation vs Interpretion</h2>
<p>interpretation </p>
<ul>
<li>파이썬, 자바스크립트</li>
<li>실시간으로 에러를 알 수 있음 </li>
<li>compilation보다 느림</li>
</ul>
<p>compilation </p>
<ul>
<li>자바, C</li>
<li>다 작성하고 컴파일하는 것. </li>
</ul>
<p>출처
<a href="https://devparker.tistory.com/110">https://devparker.tistory.com/110</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바] 추상클래스, 인터페이스 ]]></title>
            <link>https://velog.io/@developer_kim/%EC%9E%90%EB%B0%94-%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4</link>
            <guid>https://velog.io/@developer_kim/%EC%9E%90%EB%B0%94-%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4</guid>
            <pubDate>Thu, 08 Feb 2024 10:52:00 GMT</pubDate>
            <description><![CDATA[<p>**</p>
<p>면접 단골 질문 정리</p>
<h1 id="인터페이스">인터페이스</h1>
<p>사용하는 이유? 여러명의 개발자가 협업을 할때, 미리 정해놓는 &#39;약속&#39;같은 개념
만약 여러명이 프로젝트를 한다고 생각할때, 각자 알아서 하면 나중에 수정해야 하는 경우가 많으므로,
미리 그려놓는 설계도 라고 생각하면 편하다. 
그냥 내가 만든 예시 - 아래와 같이 orderPizza라는 메서드를 구현하고 싶은 경우?
A라는 사람이 interface로 정의해 놓으면 B라는 실체를 구현하는 사람이 parameter를 어떻게 쓸 지 고민없이 사용 가능함.
이렇게 미리 인터페이스를 정의한 경우에는 추후에 변수명을 바꾼다던가 변수타입을 바꾼다든가하는 추가적인 일이 필요없다는 말임. 인터페이스가 설계도 라는 말이 이해가 되지 않으신가요? 나는 이해됨,</p>
<pre><code>interface I {
    public void orderPizza(string menu, int inch, int price);
}

class A implements I {
    public void orderPizza(string menu, int inch, int price) {
    }
}</code></pre><h4 id="인터페이스-특징">인터페이스 특징</h4>
<p>인터페이스가 구현된 클래스에서는(위에선 Class A) 인터페이스 내에 있는 메소드가 반드시 구현되어야 함
인터페이스 멤버는 무조건 public이여야 함
클래스는 여러개의 인터페이스를 구현할 수 있음
다중 상속 가능</p>
<pre><code>class A implements IA, IB, IC {
}


interface IA {
    public class A();
}

interface IB extends IA{ 
    public class B();
}

class IB {
    public class A(){ }
    public class B(){ } 
    // 둘 다 반드시 구현되어야 함
}</code></pre><h1 id="추상클래스">추상클래스</h1>
<p>추상메서드를 가진 클래스는 무조건 추상 클래스
추상메드는 상속받은 클래스에서 무조건 구현되어야 함. </p>
<ul>
<li>때문에 추상클래스에는 final키워드를 붙일 수 없다</li>
</ul>
<pre><code>public abstract class animal {
    abstract void eat();
     abstract void sleep();
}</code></pre><ul>
<li>Not able to create instance</li>
<li>즉 Animal a = new Animal() 이게 안 됨.
쉽게 이해하기 길에서 동물을 본 적 있나요? 고양이, 강아지는 봤지만 동물을 본 적은 없음. 그런 의미임</li>
</ul>
<pre><code>public abstract class 어류 extends 동물{ // 추상클래스&#39;동물&#39;을 상속받음 
}
public abstract class 포유류 extends 동물{ // 추상클래스&#39;동물&#39;을 상속받음 
}
public abstract class 조류 extends 동물{ // 추상클래스&#39;동물&#39;을 상속받음 
}</code></pre><p>이렇게하면 어류도 포유류도 인스턴스를 생성할 수 없음</p>
<pre><code>public class 고등어 extends 어류 { // 고등어는 추상클래스 &#39;동물&#39;을 상속받은 추상클래스&#39;어류&#39;를 상속받음 
}
public class 상어 extends 포유류 { // 추상클래스&#39;포유류&#39;를 상속받음 
}

public class 펭귄 extends 조류 { // 추상클래스&#39;조류&#39;를 상속받음 
}</code></pre><p>이런식으로 정의되어 있다면,
고등어, 상어, 펭귄은 &#39;물&#39;에 사는 동물이라는 공통점이 있지만, 이를 상속할 수는 없음.
쉽게 말하면 위에서 아래로만 상속 가능.</p>
<pre><code>public clas 고래 extends 포유류, 수생동물 {  -&gt; 이렇게 사용 불가능
}</code></pre><p>이럴 때 사용하는게 인터페이스!</p>
<pre><code>public interface 물생활 {
    public abstract void 수영();
}

물생활 물 = new 물생활();
물.수영(); </code></pre><p>참고 자료.  <a href="https://www.youtube.com/watch?v=SgjRG0dS66o">https://www.youtube.com/watch?v=SgjRG0dS66o</a></p>
<h1 id="정리-abstract-vs-interface">정리 Abstract vs Interface</h1>
<h4 id="공통점">공통점</h4>
<p>선언만 있고 구현 내용이 없는 클래스
상속을 받은 하위클래스는 모든 메소드를 재정의해야 함(오버라이딩)
인스턴스화 불가능 Animal a = new Animal() 불가</p>
<h4 id="차이점">차이점</h4>
<p>추상클래스는 단일 상속 = extends a (추상클래스)
인터페이스는 다중 상속 = implements a, b, c(인터페이스) /</p>
<p>추상클래스는 상속받은 클래스의 기능을 이용하고 확장하는 것
인터페이스는 하위클래스에게 일종의 설계도를 제공하는 것. 다형성과 코드 사용성을 높일 수 있음.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바] public static void main() / 도대체 왜 쓰는건데?]]></title>
            <link>https://velog.io/@developer_kim/%EC%9E%90%EB%B0%94-public-static-void-main-%EB%8F%84%EB%8C%80%EC%B2%B4-%EC%99%9C-%EC%93%B0%EB%8A%94%EA%B1%B4%EB%8D%B0</link>
            <guid>https://velog.io/@developer_kim/%EC%9E%90%EB%B0%94-public-static-void-main-%EB%8F%84%EB%8C%80%EC%B2%B4-%EC%99%9C-%EC%93%B0%EB%8A%94%EA%B1%B4%EB%8D%B0</guid>
            <pubDate>Wed, 17 Jan 2024 07:05:14 GMT</pubDate>
            <description><![CDATA[<p>생성되는대로 사용하고 있던 public static void
같이 일하던 동료가 면접에서 저거 하나 하나 설명하라는 질문을 받았다는 걸 듣고, 
<em>&#39;아 뭐 저렇게 쉬운거.. 아쒸.. 나.. 좀 설명을 못할것 같은데?&#39;</em> 라는 생각이 들었다.</p>
<p>그러므로 이참에 정리</p>
<h1 id="public-static-void-main">[public] static void main(...</h1>
<h4 id="접근-제어자modifier">접근 제어자(Modifier)</h4>
<h4 id="public">public</h4>
<ul>
<li>말 그대로 모든 class에서 접근 가능한 메소드를 생성할때 사용<h4 id="private">private</h4>
</li>
<li>외부 접근이 불가능함. 같은 클래스 내에서만 사용가능<h4 id="protected">protected</h4>
</li>
<li>상속 받은 클래스 또는 같은 패키지 내에서만 사용가능<h4 id="default--no-modifier">default / no modifier</h4>
</li>
<li>같은 패키지 내에서만 사용가능</li>
</ul>
<h3 id="그렇다면-왜-굳이-사용할까">그렇다면 왜 굳이 사용할까??</h3>
<p>이건 자바의 &#39;특성&#39;과도 관련이 있다.
OOP의 장점인 <strong>캡슐화</strong>를 위해서!!!! </p>
<pre><code>public class test {

    private String id;
    private Integer sum;

    //getter
    public String getId() {
        return id;
    }
    public String getSum() {
        return sum;
    }

    //setter
    public void set(String id) {
        this.id = id;
    }
    public void setSum(Integer a, Integer b) {
        this.sum = a + b;
    }
}</code></pre><p>이런 코드를 많이 보셨을거다.
id와 pw의 변수는 private으로 선언하여 &#39;직접&#39; 접근할 수 없게 해 두었고, 그 값을 가져오기 위해서는 getter를 사용해야 한다. 이렇게 구현하는 걸 &#39;캡슐화&#39; 라고 한다.</p>
<p>이렇게 해 두면 사용자가 직접 값을 변경할 수 없다. </p>
<pre><code>Test test = new Test();
test.sum = 10; // error</code></pre><p>이렇게 직접 바꿀수 없다는 뜻이 된다.
요런게 캡슐화</p>
<h1 id="public-static-void">public [static] void</h1>
<p>그렇다면 두번째, static은 뭘까?</p>
<p>1) static은 변수와 메소드로 사용 가능하다.</p>
<pre><code>static string developer_kim = &quot;Good&quot;;

public static class Hello() {
    System.out.println(&quot;hello!&quot;);
}</code></pre><p>2) static으로 생성한 변수, 메소드는 메모리에 한 번 할당되어서 프로그램이 종료될때 해제된다. (가비지 컬렉터의 관리를 받는 Heap이 아니라 Static영역에 저장되므로) 
이 말은 즉슨, 잘 사용하지도 않는 변수/메소드를 static으로 선언하는 경우 성능에 영향을 끼칠 수 있다는 의미가 된다. 왜냐면 그만큼 메모리를 잡아먹으니까!
근데 또 다른 한편으로는 자주 사용하는 인스턴스의 경우엔 static으로 만들어 놓고 사용한다면 성능에 좋다는 말이 된다. <em>즉, 잘 사용하면 득, 못 사용하면 실!</em></p>
<p>3) static은 메소드를 인스턴스 없이 실행할 수 있게 해 준다.</p>
<pre><code>Test test = new Test();</code></pre><p>이렇게 만들어서 접근하지 않아도 된다는 뜻이다. 근데 이 말은 반대로 객체지향의 특성을 깬다는 말이다. 붕어빵 틀에 붕어빵을 찍어내야되는데 왜 찍어내지 못하니!!</p>
<p>왜? 이건 왜 또 필요한걸까? 언제 써야 할까?</p>
<ul>
<li>유틸함수를 생성시 사용하면 좋다. Math.round(), Math.max() 뭐 이런 유틸함수는 다 static함수이다.</li>
<li>자주 사용하는 함수 변수의 경우엔 사용하면 편하고 좋으다!</li>
</ul>
<h1 id="public-static-void-1">public static [void]</h1>
<p>제일 쉬워 제일 좋아
이건 리턴값을 의미한다.
void는 말 그대로 아무것도 리턴하지 않는다는 거고 저 자리에 String, Integer, Array, 객체 등등 써서 리턴 값으로 전달할 타입을 선언하는 것</p>
<p>이렇게 오늘도 깨알 공부 끝!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바] int 와 Integer? string 과 String? 의미없이 사용해온 Wrapper class]]></title>
            <link>https://velog.io/@developer_kim/%EC%9E%90%EB%B0%94-int-%EC%99%80-Integer-string-%EA%B3%BC-String-%EC%9D%98%EB%AF%B8%EC%97%86%EC%9D%B4-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%98%A8-Wrapper-class</link>
            <guid>https://velog.io/@developer_kim/%EC%9E%90%EB%B0%94-int-%EC%99%80-Integer-string-%EA%B3%BC-String-%EC%9D%98%EB%AF%B8%EC%97%86%EC%9D%B4-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%98%A8-Wrapper-class</guid>
            <pubDate>Wed, 10 Jan 2024 07:17:31 GMT</pubDate>
            <description><![CDATA[<p>그러하다
나는 그냥 되는대로 쓰던 개발자이다
올해의 목표는 자바 기초 정리를 좀 해보는 것.
쓸 줄은 아는데 설명할 줄을 모르는 멍청한 개발자는 이제 그만 두려고 한다.</p>
<p>그래서, 새해니까, 호기롭게 자바 강의를 듣기 시작했다.
첫 강의는 여전히 variables
&#39;아 이건 겁나 쉽지 아 이걸 모를리가!!!?&#39; 라는 마음가짐으로 인스타 둘러보기나 하며 무성의 하게 듣고 있다가 
문득, 아 그럼 int와 Integer의 차이를 내가 &quot;<strong>제대로</strong>&quot; 설명할 수 있는가에 대한 의문이 들었다. 그래서 이 글을 쓰게 되었다 ^.^... </p>
<h2 id="기본형primitive-vs-래퍼클래서wrapper-class">기본형(Primitive) vs 래퍼클래서(Wrapper Class)</h2>
<p>기본형 </p>
<ul>
<li>byte, string, char, short, int, long, float, double (8가지)</li>
<li>Stack 메모리 공간에 저장</li>
</ul>
<p>래퍼클래스 </p>
<ul>
<li>Integer, Boolean, String, Character...</li>
<li>기본형을 클래스형으로 만든 것</li>
<li>Heap 메모리 공간에 저장</li>
</ul>
<h4 id="래퍼클래스의-특징">래퍼클래스의 특징</h4>
<ul>
<li>기본형의 경우 값을 비교하지만, 참조형의 경우 &#39;주소&#39; 를 비교
즉, 값을 비교하는 경우 == 사용 할 수 없음, equals를 사용해야 합니다.<pre><code>Integer a = 1; 
Integer b = 1; 
a == b  =&gt; false</code></pre>2) 불변 -&gt; 기존값을 변경할 수 <strong>없음</strong>.</li>
</ul>
<p>3) String은 조금 특별한 래퍼클래스 == / equals 둘 다 사용가능</p>
<ul>
<li>리터럴로 생성하는 경우(String a = &quot;abcd&quot;) intern()함수가 호출되어 값이 Heap String pool에 저장됨. 이 경우 == 으로 비교가능</li>
<li>new String(&quot;abcd&quot;)으로 생성하는 경우, Heap에 저장됨. 그러므로
new String(&quot;abcd&quot;) == &quot;abcd&quot;는 같지 않는 값으로 여겨짐.</li>
</ul>
<p>참조
<a href="https://www.youtube.com/watch?v=eqltmFST-N8">https://www.youtube.com/watch?v=eqltmFST-N8</a></p>
<h4 id="래퍼클래스를-도대체-왜-써야하는데">래퍼클래스를 도대체 왜 써야하는데?</h4>
<ul>
<li>형 변환이 쉽다.</li>
<li>null 비교가 용이하다(기본값이 null)</li>
</ul>
<h4 id="래퍼클래스와-꼭-함께-나오는-박스와-언박싱">래퍼클래스와 꼭 함께 나오는 박스와 언박싱</h4>
<ul>
<li>박싱은 말그대로 기본형을 객체로 만드는 것</li>
<li>언박싱은 객체형을 기본형으로 만드는 것</li>
</ul>
<h4 id="래퍼클래스---call-by-value">래퍼클래스 - Call by Value</h4>
]]></description>
        </item>
        <item>
            <title><![CDATA[Jest | Api 테스트 쉽게하기 feat. msw 라이브러리]]></title>
            <link>https://velog.io/@developer_kim/Jest-Api-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%89%BD%EA%B2%8C%ED%95%98%EA%B8%B0-feat.-msw-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</link>
            <guid>https://velog.io/@developer_kim/Jest-Api-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%89%BD%EA%B2%8C%ED%95%98%EA%B8%B0-feat.-msw-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</guid>
            <pubDate>Tue, 29 Aug 2023 11:41:16 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>구현 코드 (HomeRoute)</p>
</blockquote>
<pre><code>import Hero from &#39;../components/Hero&#39;;
import RepositoriesTable from &#39;../components/repositories/RepositoriesTable&#39;;
import useRepositories from &#39;../hooks/useRepositories&#39;;

function HomeRoute() {
  const { data: jsRepos } = useRepositories(&#39;stars:&gt;10000 language:javascript&#39;);
  const { data: tsRepos } = useRepositories(&#39;stars:&gt;10000 language:typescript&#39;);
  const { data: rustRepos } = useRepositories(&#39;stars:&gt;10000 language:rust&#39;);
  const { data: goRepos } = useRepositories(&#39;stars:&gt;10000 language:go&#39;);
  const { data: pythonRepos } = useRepositories(&#39;stars:&gt;10000 language:python&#39;);
  const { data: javaRepos } = useRepositories(&#39;stars:&gt;10000 language:java&#39;);

  return (
    &lt;div&gt;
      &lt;Hero /&gt;
      &lt;div className=&quot;container mx-auto py-8 grid grid-cols-1 gap-4 md:grid-cols-2&quot;&gt;
        &lt;RepositoriesTable
          label=&quot;Most Popular Javascript&quot;
          repositories={jsRepos}
        /&gt;
        &lt;RepositoriesTable
          label=&quot;Most Popular Typescript&quot;
          repositories={tsRepos}
        /&gt;
        &lt;RepositoriesTable label=&quot;Most Popular Rust&quot; repositories={rustRepos} /&gt;
        &lt;RepositoriesTable label=&quot;Most Popular Go&quot; repositories={goRepos} /&gt;
        &lt;RepositoriesTable
          label=&quot;Most Popular Python&quot;
          repositories={pythonRepos}
        /&gt;
        &lt;RepositoriesTable label=&quot;Most Popular Java&quot; repositories={javaRepos} /&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
}

export default HomeRoute;</code></pre><blockquote>
<p>구현 코드 (RepositoriesTable)</p>
</blockquote>
<pre><code>import { Link } from &#39;react-router-dom&#39;;
function RepositoriesTable({ label, repositories, id }) {
  const rendered =
    repositories &amp;&amp;
    repositories.map((repo, i) =&gt; {
      return (
        &lt;div key={repo.id} className=&quot;p-0.5&quot;&gt;
          &lt;Link
            className=&quot;text-blue-500&quot;
            to={`/repositories/${repo.full_name}`}
          &gt;
            {repo.full_name}
          &lt;/Link&gt;
        &lt;/div&gt;
      );
    });
  return (
    &lt;div className=&quot;border p-4 rounded&quot;&gt;
      &lt;h1 id={id || &#39;&#39;} className=&quot;text-lg font-bold border-b mb-1&quot;&gt;
        {label}
      &lt;/h1&gt;
      {rendered}
    &lt;/div&gt;
  );
}
export default RepositoriesTable;</code></pre><blockquote>
<p>테스트 코드 </p>
</blockquote>
<pre><code>import { setupServer } from &#39;msw/node&#39;;
import { rest } from &#39;msw&#39;;

export function createServer(handlerConfig) {
  const handlers = handlerConfig.map((config) =&gt; {
    return rest[config.method || &#39;get&#39;](config.path, (req, res, ctx) =&gt; {
      return res(
        ctx.json(config.res(req, res, ctx)
        )
      );
    })
  });
  const server = setupServer(...handlers);

  beforeAll(() =&gt; {
    server.listen();
  });

  afterEach(() =&gt; {
    server.resetHandlers();  
  });

  afterAll(() =&gt; {
    server.close();
  });

}


import { render, screen } from &#39;@testing-library/react&#39;;
import { setupServer } from &#39;msw/node&#39;;
import { rest} from &#39;msw&#39;;
import { MemoryRouter} from &#39;react-router-dom&#39;;
import HomeRoute from &#39;./HomeRoute&#39;
import { createServer } from &#39;../test/server&#39;;

// to make the handler test for multiple compenents ???  using createServer
createServer([
  {
    path: &#39;/api/repositories&#39;,
    method: &#39;get&#39;, 
    res: (req) =&gt; { 
      const lauguage = req.url.searchParams.get(&#39;q&#39;).split(&quot;language:&quot;)[1];
      return {
        items: [
          { id:1, full_name: `${lauguage}_one`},
          { id:2, full_name: `${lauguage}_two` }
        ]
      }
    }
  }
]);

test(&#39;Renders two links for each language&#39;, async () =&gt; {

  render(
    &lt;MemoryRouter&gt; // homeroute에 link가 있어서 memoryrouter로 감싸준다
      &lt;HomeRoute /&gt;
    &lt;/MemoryRouter&gt;
  );

  // loop over each language
  const languages = [&#39;javascript&#39;, &#39;typescript&#39;, &#39;rust&#39;, &#39;go&#39;, &#39;python&#39;, &#39;java&#39;];

  for(let language of languages) {
    const links = await screen.findAllByRole(&#39;link&#39;, {
      name: new RegExp(`${language}_`)
    })
    expect(links).toHaveLength(2);
    expect(links[0]).toHaveTextContent(`${language}_one`)
    expect(links[1]).toHaveTextContent(`${language}_two`)
    expect(links[0]).toHaveAttribute(&#39;href&#39;, `/repositories/${language}_one`)
    expect(links[1]).toHaveAttribute(&#39;href&#39;, `/repositories/${language}_two`)
  }

});
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Jest | Act Warning 해결법]]></title>
            <link>https://velog.io/@developer_kim/Jest-Act-Warning-%ED%95%B4%EA%B2%B0%EB%B2%95</link>
            <guid>https://velog.io/@developer_kim/Jest-Act-Warning-%ED%95%B4%EA%B2%B0%EB%B2%95</guid>
            <pubDate>Tue, 29 Aug 2023 11:36:32 GMT</pubDate>
            <description><![CDATA[<p>만약 데이터를 fetching 하는 react코드를 테스트 하는데 에러가 발생하는 경우,
이를 해결하는 방법을 정리해봅니다.</p>
<p>Act Warning 해결하는 방법</p>
<ul>
<li>was not wrapped in act() 어쩌구 라는 경고가 떠도 굳이 act로 감쌀 필요가 없음.
방법 1이 가장 좋은 방법, 4가 가장 나쁜 방법임.</li>
</ul>
<p>1) 데이터 fetching 후 findBy, findAllBy를 사용할 것 </p>
<pre><code>useEffect(() =&gt; {
    icons.getClass(name)
        .then((k) =&gt; setKlass(k))
        .catch(() =&gt; null);
}, [])</code></pre><p>테스트 코드</p>
<pre><code>test(&#39;&#39;, async () =&gt; {
    renderComponent();
    await screen.findByRole(&#39;img&#39;, { name: &#39;JavaScript&#39;} );
 });</code></pre><p>2) act 사용하여 해결</p>
<p>3) Jest.mock 사용
문제가 있는 부분이 FileIcon 렌더링 부분이라면, mock을 사용하여 문제가 되는 컴포넌트를 렌더링 하는걸 피할 것. </p>
<ul>
<li>실제로 fileIcon을 import하는게 아니라, 가짜로 렌더링된 것 처럼 하는 것<pre><code>jest.mock(&#39;../tree/FileIcon&#39;, () =&gt; {
  return () =&gt; {
      return &#39;File Icon Component&#39;
  };
)}</code></pre>4) act + pause 사용 - 비추!<blockquote>
<p>아래는 자동으로 &#39;act&#39;를 호출함. act로 감쌀 필요가 사실 없음.
screen.findBy
screen.findAllby
waitFor
user.keyboard(async)
user.click(async)</p>
</blockquote>
</li>
</ul>
<pre><code>import { act } from &#39;@testing-library/react&#39;

test(&#39;&#39;, async () =&gt; {
    renderComponent();
    await act(async () =&gt; {
        await pause();
    });
 });

 const pause = () =&gt; new Promise(resolve =&gt; setTimeout(resolve, 100));</code></pre><p>Data Fetching in Tests</p>
<p>1) 실제 네트워크로 요청하지 않음 - 느림
2) fake데이터로 테스트 할 것</p>
<ul>
<li>테스트 하는 법
1) mock the file that contains the data fetching code.
2) &#39;Mock&#39; axios를 위한 Library 사용 (msw library)<pre><code>rest.get(&#39;/api/repositories&#39;, (req, res, ctx) =&gt; {
return res(
  ctx.json([
  ]),
)
})</code></pre></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드 테스트 | Jest 기본 정리]]></title>
            <link>https://velog.io/@developer_kim/Jest</link>
            <guid>https://velog.io/@developer_kim/Jest</guid>
            <pubDate>Wed, 16 Aug 2023 22:04:21 GMT</pubDate>
            <description><![CDATA[<p>개인적으로 제일 재미없어 하는 테스트
프론트엔드 개발의 경우 테스트의 의미를 크게 못 느끼고 있는데, 테스트 좀 잘 하라고 그래서 강의를 들으면서 정리해본다^.^ 귀찮은걸 맨날 시키는게 회사지 뭐.</p>
<blockquote>
<p>참조 강의 - Udemy: React Testing Library and Jest: The Complete Guide
<a href="https://www.udemy.com/course/react-testing-library-and-jest/learn/">https://www.udemy.com/course/react-testing-library-and-jest/learn/</a></p>
</blockquote>
<h2 id="test-쉽게하기">Test 쉽게하기</h2>
<h4 id="screenlogtestingplaygroundurl">screen.logTestingPlaygroundURL()</h4>
<ul>
<li>testing-playground를 통해 테스트를 쉽게 도와준다<h4 id="npx-rtl-book-serve-roles-notesjs">npx rtl-book serve roles-notes.js</h4>
</li>
</ul>
<br />

<h2 id="자주-사용하는-쿼리">자주 사용하는 쿼리</h2>
<ul>
<li>getByRole</li>
<li>queryByRole</li>
<li>findByRole</li>
</ul>
<h4 id="그렇다면-언제-어떻게-사용하는지">그렇다면 언제 어떻게 사용하는지?</h4>
<ul>
<li><p>요소가 <strong>있는지</strong> 확인할때는 getBy(1개), getAllBy(여러개)</p>
<pre><code>const element = screen.getByRole(&#39;listitem&#39;);
expect(element).toBeInTheDocument();</code></pre></li>
<li><p>요소가 <strong>없는지</strong> 확인할때는 queryBy, queryAllBy</p>
<pre><code>const element = screen.queryByRole(&#39;listitem&#39;);
expect(element).not.toBeInTheDocument();</code></pre></li>
<li><p>요소가 <strong>없는지</strong> 확인할때는 findBy, findAllBy
공식문서: Make sure an element eventually exists
<em>무슨말이지? 라고 생각했는데 api를 통해 데이터를 가져오는 경우 사용하면 적합함</em></p>
<pre><code>function fakeFetchColors() {
return Promise.resolve(
    [&#39;red&#39;, &#39;green&#39;, &#39;blue&#39;]
);
}
</code></pre></li>
</ul>
<p>function LoadColor() {
  const [colors, setColors] = useState([]);</p>
<p>  useEffect(() =&gt; {
      fakeFetchColors().then(c=&gt; setColors(c));
  }, []);</p>
<p>  const renderedColors = colors.map(color =&gt; {
      return <li key={color}>{color}</li>
  }
}</p>
<p>test(&#39;findBy or findAllBy when data fetching&#39;, async () =&gt; {
    render(<LoadColor />)
    // const els = screen.getAllByRole(&#39;listitem&#39;);
    // 에러! fetch해서 데이터를 가져오는 경우엔 에러가 남.
     const els = screen.findAllByRole(&#39;listitem&#39;);
    // 베리 굿!</p>
<pre><code>expect(els).toHaveLength(3);</code></pre><pre><code>
요소를 찾기 힘들 때 자주 사용하는 방식
&gt;1. data-testid 
const rows = within(screen.getByTestId(&#39;users&#39;)).getAllByRole(&#39;row&#39;)
tr을 찾고 있음

&gt;2. querySelector
const {container} = render(&lt;userList users={users}/&gt;);
const table = container.querySelector(&#39;table&#39;);
const rows = container.querySelectorAll(&#39;tbody tr&#39;);


예제
1) textbox에 값을 넣고 button을 클릭하는 경우</code></pre><p>render(&lt;UserForm onUserAdd={() =&gt; {}} /&gt;
const nameInput = screen.getByRole(&#39;textbox&#39;, {name: /name/i} );
const emailInput = screen.getByRole(&#39;textbox&#39;, {name: /email/i });
const button = screen.getByRole(&#39;button&#39;);</p>
<p>user.click(nameInput);
user.keyboard(&#39;jane&#39;);
user.click(emailInput);
user.keyboard(&#39;jane@jane.com&#39;);
user.click(button);</p>
<pre><code>2) element가 여러개인 경우에는 aria-label or name을 사용하면 편함. ex. button 여러개</code></pre><p><label>Email</label>
<input />
<label>Search</label>
<input /></p>
<p>//<button>sign in</button>
//<button>sign out</button>
<button aria-label="sign in"><svg /></button>
<button aria-label="sign out"><svg /></button></p>
<pre><code></code></pre><p>test(&#39;버튼들이 있는지 확인&#39;, () =&gt; {
  render(<test />
  const signInButton = screen.getByRole(&#39;button&#39;, {
      name: /sign in/i // i는 대소문자 구별없이 찾기 위해
  });
  const signOutButton = screen.getByRole(&#39;button&#39;, {
      name: /sign out/i // i는 대소문자 구별없이 찾기 위해
  });
  expect(signInButton).toBeInTheDocument();
  expect(signOutButton).toBeInTheDocument();
});</p>
<pre><code>
3) getby, queryby, findby 비교: 없는 요소(ex.textbox)를 찾고자 하면?
```// 통과되는 코드임
test(&#39;없는 요소 찾으려고 할때 테스트&#39;,  async () =&gt; 
{
  render(&lt;colorList /&gt;)
  expect(() =&gt; screen.getByRole(&#39;textbox&#39;)).toThrow(); 
  expect(() =&gt; screen.queryByRole(&#39;textbox&#39;)).toEqual(null); 
  // 만약 textbox가 두개 이상있는데 위 처럼 써주면 throw error임. toThrow로 써줘야함
  let errorThrown = false;
  try {
      await screen.findByRole(&#39;textbox&#39;);  
  } catch(err) {
    errorThrown = true;
  }
  expect(errorThrown).toEqual(true);
});</code></pre><p>4) getby, queryby, findby 비교: 있는 요소(ex.textbox)를 찾고자 하면?</p>
<pre><code>test(&#39;있는 요소 찾으려고 할때 테스트&#39;,  async () =&gt; 
{
  render(&lt;colorList /&gt;)
  expect(screen.getByRole(&#39;list&#39;)).toBeInTheDocument();
  expect(screen.queryByRole(&#39;list&#39;)).toBeInTheDocument();
  expect(await screen.findByRole(&#39;list&#39;)).toBeInTheDocument();
});</code></pre><ul>
<li>findBy의 경우 async, await 사용하는 특징이 있음! 왜인지 모르는데 그냥 쓰자..</li>
</ul>
<p>5) getAllBy, queryAllBy, findAllBy 비교</p>
<pre><code>test(&#39;AllBy 테스트&#39;,  async () =&gt; 
{
  render(&lt;colorList /&gt;)
  //listitem은 li를 의미하는 것
  expect(screen.getAllByRole(&#39;listitem&#39;)).toHaveLength(3); 
  expect(screen.queryAllByRole(&#39;list&#39;)).toHaveLength(3); 
  expect(await screen.findAllByRole(&#39;list&#39;)).toHaveLength(3); 
});</code></pre><p>6) 다이나믹한 value 인 경우? RegExp사용하여 테스트</p>
<pre><code>test(&#39;Displays information about the repository&#39;, () =&gt; {
  const repository = {
    language: &#39;Javascript&#39;,
    stargazers_count: 5,
    forks: 30,
    open_issues: 1
  }

  render(&lt;RepositoriesSummary repository={repository} /&gt;);
  const language = screen.getByText(&#39;Javascript&#39;);
  const stars = screen.getByText(5);
  const forks = screen.getByText(&#39;30 Forks&#39;);
  const open_issues = screen.getByText(&#39;1 issues need help&#39;);
  expect(language).toBeInTheDocument();
  expect(stars).toBeInTheDocument();
  expect(forks).toBeInTheDocument();
  expect(open_issues).toBeInTheDocument();

  for (let key in repository) {
    const value = repository[key];
    const element = screen.getByText(new RegExp(value));
    expect(element).toBeInTheDocument();
  }

});
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[git 정리]]></title>
            <link>https://velog.io/@developer_kim/git-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@developer_kim/git-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sat, 24 Jun 2023 07:52:48 GMT</pubDate>
            <description><![CDATA[<p>개발환경에서 빠질 수 없는 git
매번 git 실수를 한 번씩 저지르는 인간으로써 명령어 정리를 해본다.</p>
<h2 id="명령어-정리">명령어 정리</h2>
<ul>
<li><p>깃 초기화
git init</p>
</li>
<li><p>소스 가져오기(local)
git clone [깃 주소]</p>
</li>
<li><p>브랜치 생성(local)
git branch [브랜치명]</p>
</li>
<li><p>브랜치 확인
git branch (local)
git branch -r (remote)
git branch -a (all)</p>
</li>
<li><p>브랜치 변경(local)
git checkout [브랜치명]</p>
</li>
<li><p>브랜치 삭제(local)
git branch -d [브랜치명]</p>
</li>
<li><p>브랜치 삭제(remote)
git push origin -d
원격저장소의 브랜치가 삭제됨(주의)</p>
</li>
<li><p>모든 파일 스테이지 상태로 올리기(local)
git add . 
(특정파일만 올리고 싶으면 . 대신 파일명 작성)</p>
</li>
<li><p>commit (local)
git commit -m &#39;[commit message]&#39;</p>
</li>
<li><p>push
git push origin [브랜치명]
: remote [브랜치명]에 변경 내용을 반영한다는 의미</p>
</li>
</ul>
<ul>
<li>만약 remote repository가 업데이트 안되는경우
git fetch --prune</li>
</ul>
<p>여러개의 로컬 브랜치와 여러개의 원격 브랜치가 있는 경우
로컬 브랜치 a, b / 원격 브랜치 a
만약 로컬 브랜치 b 에서 작업하고 원격 브랜치 a 에 올리고 싶다면?</p>
<p>1) git checkout a
2) git merge b (a에 b내용을 합침)
3) git push origin a (원격 a에 올림)</p>
<p>쉽게 말해 로컬에서 수정한 내용을 브랜치를 만들어 올리려면?
로컬에서 우선 해당 브랜치를 생성, 커밋을 하고 푸시하면 됨</p>
<h3 id="회사에서-작업하는-방식-정리">회사에서 작업하는 방식 정리</h3>
<p>1) git clone
2) git branch [브랜치명]<br>3) git checkout [브랜치명]
-작업 작업 작업 작업 작업
4) git add.
5) git commit -m &quot;message&quot;
6) git checkout main
-작업한 내용을 올리기 전에 최신버전을 받아와야 함 
7) git pull origin main
8) git checkout [브랜치명]
최신화된 main branch merger(병합) 하기
9) git merge main
-이 과정에서 conflict 발생 가능함
10) git push origin [브랜치명]</p>
<h3 id="오류-정리">오류 정리</h3>
<p>오류 1
hint: You have divergent branches and need to specify how to reconcile them.
해결 방안
git config --global pull.ff true </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Docker 도커란 무엇인가 ]]></title>
            <link>https://velog.io/@developer_kim/Docker-%EB%8F%84%EC%BB%A4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-%EC%9E%91%EC%84%B1%EC%A4%91</link>
            <guid>https://velog.io/@developer_kim/Docker-%EB%8F%84%EC%BB%A4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-%EC%9E%91%EC%84%B1%EC%A4%91</guid>
            <pubDate>Wed, 21 Jun 2023 11:48:25 GMT</pubDate>
            <description><![CDATA[<p><strong>docker hub</strong> -(pull)-&gt; <strong>image</strong> -(run)-&gt; <strong>container</strong></p>
<h3 id="도커를-쓰는-이유">도커를 쓰는 이유?</h3>
<p>빨리, 어디서든 사용할 수 있게 하는 컨테이너
왜?
과거 어플리케이션들은 한 컴퓨터안에서 운영. 
한 서비스안에서 문제가 발생해도, 같은 OS를 공유하기에 다른 서비스에도 영향을 주기도 함
이 문제 때문에, OS를 독립적으로 사용하기 위한 &#39;가상화&#39;개념 등장
그러나, 각 서비스들의 독립성이 유지되긴하나 Os위에 또 다른 guest os가 설치되므로 무거움....<br>이 문제를 해결하기 위해 최소한의 환경요소만 묶어서 컨테이너를 만들어서 적은 용량만으로 운영가능하도록 한 기술을 사용하도록 함. 이것이 바로 도커!</p>
<h4 id="1-컨테이너-생성">1) 컨테이너 생성</h4>
<p>docker run [option] image [command] [arg..]
ex) docker run httpd
-&gt; httpd 기반(web server)으로 컨테이너 만들고 실행
ex) docker run --name ws2 httpd
-&gt; 또 다른 httpd기반 컨테이너 만드는데, 이름이 ws2임</p>
<h4 id="2-컨테이너-목록-출력">2) 컨테이너 목록 출력</h4>
<p>docker ps (실행중인 컨테이너만)
docker ps -a  (모든 컨테이너)</p>
<h4 id="3-컨테이너-실행중지">3) 컨테이너 실행/중지</h4>
<p>docker start ws2 
docker stop ws2</p>
<h4 id="4-컨테이너-로그">4) 컨테이너 로그</h4>
<p>docker logs ws2 
docker logs -f ws2  (실시간으로 출력하고 싶은 경우)</p>
<h4 id="5-컨테이너-삭제">5) 컨테이너 삭제</h4>
<p>docker rm ws2 (stop으로 중지하고 지워주어야함)
docker rm --force ws2 (stop &amp; delete)</p>
<h4 id="6-이미지-삭제">6) 이미지 삭제</h4>
<p>docker rmi ws2 </p>
<p>Port forwarding
docker run -p 8000:80 http (-p: short for publish)
호스트의 8000번 포트와 컨테이너의 80번 포트가 연결 </p>
<h2 id="컨테이너-내부-실행">컨테이너 내부 실행</h2>
<p>docker exec [options] container command [arg...]
docker exec -it ws3 pwd /bin/sh
docker exec -it ws3 pwd /bin/bash</p>
<ul>
<li>컨테이너 내 sh(또는 bash) 실행 </li>
<li>-it는 옵션인데 이걸 써줘야 지속적으로 실행이 된다고 보면 됨 (i:interactive, t:tty)</li>
</ul>
<h3 id="호스트와-컨테이너의-파일시스템-연결">호스트와 컨테이너의 파일시스템 연결</h3>
<p><img src="https://velog.velcdn.com/images/developer_kim/post/a963994e-3da9-4161-8a81-ddad51eea270/image.png" alt=""></p>
<p>이렇게 내 컴퓨터의 index.html과 container 내부와 index.html이 동기화(?) 된다면 container이 사라져도 문제 없음
docker run -p:8888:80 -v ~/Desktop/htdocs:/usr/local/apache2/htdocs/ httpd
(-v: volume,
내 컴퓨터의 /Desktop/htdocs와 /usr/local/apache2/htdocs 연결했다는 뜻, 즉 내 컴퓨터의 htdocs의 index.html파일을 변경해도 container의 index.html이 변경되어 반영됨)</p>
<p>출처: 생활코딩 docker 입문수업</p>
]]></description>
        </item>
    </channel>
</rss>