<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>코딩 요리사의 레시피</title>
    <link>https://pugyu.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 2 Jul 2026 23:18:52 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>devyu</managingEditor>
    <image>
      <title>코딩 요리사의 레시피</title>
      <url>https://tistory1.daumcdn.net/tistory/2893179/attach/9640145e49b74eab9aa19906201ea1cc</url>
      <link>https://pugyu.tistory.com</link>
    </image>
    <item>
      <title>[Effective Java 공부하기] 6. 불필요한 객체 생성을 피하라</title>
      <link>https://pugyu.tistory.com/119</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;불필요한 객체 생성을 피하라&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;자바는 기본적으로 사용하지 않는 불필요한 객체를 청소해주는 GC(Garbage Collectotion) 기능이 존재한다만 소스적으로 불변의 객체를 반복적으로 생성하는 것을 최대한 지양해야 한다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Boolean 인스턴스를 생성
Boolean b1 = new Boolean(true);

// Boolean 팩터리 메서드를 사용(만들어진 인스턴스를 참조)
Boolean b2 = Boolean.valueOf(true);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;위와 같은 불변 객체라면 &lt;code&gt;new Boolean(true)&lt;/code&gt; 생성자를 통해 불필요한 객체의 인스턴스를 반복 생성하는 것보다 팩터리 메서드를 사용하여 이미 만들어진 객체의 인스턴스를 재활용하는 것이 더 현명한 선택이 될 수 있을 것 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dGLNq3/btrx4RYyjb7/ElC4jKumg6pZMmVoALtDHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dGLNq3/btrx4RYyjb7/ElC4jKumg6pZMmVoALtDHk/img.png&quot; data-alt=&quot;java.lang.Boolean&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dGLNq3/btrx4RYyjb7/ElC4jKumg6pZMmVoALtDHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdGLNq3%2Fbtrx4RYyjb7%2FElC4jKumg6pZMmVoALtDHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;624&quot; height=&quot;410&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;java.lang.Boolean&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;실제로 자바9 이후로 &lt;code&gt;new Boolean()&lt;/code&gt; 생성자를 통한 Boolean 객체의 인스턴스 추가생성은 &lt;code&gt;deprecated&lt;/code&gt; 되어 사용을 자제하라는 공식내용이 있다.&lt;/p&gt;
&lt;p&gt;또 다른 예로는 정규표현식을 활용하여 문자열을 체크할 때 주로 사용하는 방식이다. 문자열이 이메일 형식인지 정규표현식을 통해 검증을 하면&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static boolean isEmailPattern(String text) {
    return text.matches(&amp;quot;^[a-z0-9_+.-]+@([a-z0-9-]+\\.)+[a-z0-9]{2,4}$&amp;quot;);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;보통 위와 같이 유틸클래스에 정적메서드를 만들어서 사용한다. 실제 나도 회사내부 유틸클래스에서 위와 동일한 코드를 작성한 기억이 있다. 그럼 &lt;code&gt;matches&lt;/code&gt; 메서드를 타고 내부로 들어가 보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/obH0h/btrx1xMG3xW/aEE6LeAp88ScrmuEw86KZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/obH0h/btrx1xMG3xW/aEE6LeAp88ScrmuEw86KZk/img.png&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;117&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;40.2&quot; style=&quot;width: 39.7347%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/obH0h/btrx1xMG3xW/aEE6LeAp88ScrmuEw86KZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FobH0h%2Fbtrx1xMG3xW%2FaEE6LeAp88ScrmuEw86KZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;480&quot; height=&quot;117&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rmwb1/btrx5uuT1jn/YfQNFzczTWH1fCtTtaedf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rmwb1/btrx5uuT1jn/YfQNFzczTWH1fCtTtaedf1/img.png&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;88&quot; data-is-animation=&quot;false&quot; style=&quot;width: 59.1025%;&quot; data-widthpercent=&quot;59.8&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rmwb1/btrx5uuT1jn/YfQNFzczTWH1fCtTtaedf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frmwb1%2Fbtrx5uuT1jn%2FYfQNFzczTWH1fCtTtaedf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;88&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;java.util.regex.Pattern&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Pattern 팩터리 메서드 내부에서의 동작을 확인하면 regex 패턴을 매개변수로 넘겨 생성자를 통한 Pattern 객체의 인스턴스를 생성한다. 이렇게 생성된 인스턴스는 매번 새롭게 생성되고 곧바로 GC의 대상이 되어 제거된다. (사실 자바의 GC가 일처리가 굉장히 대단해서 왠만한 경우가 아니고서는 큰 성능차이가 없겠지만 알고 쓰는것과 모르는 것은 차이가 많이 나니깐..)&lt;/p&gt;
&lt;p&gt;성능을 개선하기 위해서는 불변 객체(Pattern class) 인스턴스를 생성하는것을 정적인 방식으로 딱 한번만 초기화하고 그 다음부터는 재활용 하는 것이다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 초기화
private static final Pattern EMAIL_PATTERN = Pattern.compile(&amp;quot;^[a-z0-9_+.-]+@([a-z0-9-]+\\.)+[a-z0-9]{2,4}$&amp;quot;);


EMAIL_PATTERN.matcher(text3).matches()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;로컬 환경에서 인스턴스를 반복 생성하는 방식과 재활용하는 후자 방식의 속도를 체감하고 싶어서 eamil 정규표현식을 1천만번 루프시켰더니 약, 3배 가까이 시간이 절감되는 것을 확인할 수 있었다.&lt;/p&gt;</description>
      <category>Java</category>
      <author>devyu</author>
      <guid isPermaLink="true">https://pugyu.tistory.com/119</guid>
      <comments>https://pugyu.tistory.com/119#entry119comment</comments>
      <pubDate>Fri, 1 Apr 2022 01:39:22 +0900</pubDate>
    </item>
    <item>
      <title>[Effective Java 공부하기] 4. 인스턴스화를 막으려거든 private 생성자를 사용하라</title>
      <link>https://pugyu.tistory.com/117</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스화를 막으려거든 private 생성자를 사용하라&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;static method와 static field가 존재하는 유틸리티 클래스를 따로 만들어서 사용하곤 한다. 이런 유틸리티 클래스는 인스턴스를 만들어서 사용하려는 목적이 아니기 때문에 인스턴스화를 막아주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스는 생성자를 따로 명시해주지 않았다면 컴파일러에 의하여 접근제어자 &lt;code&gt;public&lt;/code&gt;을 지닌 기본 생성자가 추가된다. 기본 생성자에 의하여 외부에서 클래스의 인스턴스화 시킬 수 있으니 인스턴스를 막으려거든 기본 생성자를 &lt;code&gt;private&lt;/code&gt; 접근제어자로 변경하자.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;public class JsonUtils {
    // 외부에서 인스턴스화 되는것을 막는다.
    private JsonUtils() {
    }

}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Java</category>
      <author>devyu</author>
      <guid isPermaLink="true">https://pugyu.tistory.com/117</guid>
      <comments>https://pugyu.tistory.com/117#entry117comment</comments>
      <pubDate>Thu, 31 Mar 2022 00:46:38 +0900</pubDate>
    </item>
    <item>
      <title>[Effective Java 공부하기] 2. 생성자에 매개변수가 많다면 빌더를 고려하라</title>
      <link>https://pugyu.tistory.com/115</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자에 매갭변수가 많다면 빌더를 고려하라&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스의 인스턴스를 생성하기 위해서 생성자를 이용하는 것이 일반적이다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;Student student = new Student(1L, &quot;장규민&quot;, 10);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자의 매개변수가 예시처럼 간단할 때는 생성자를 통한 인스턴스 생성 방법은 좋은 선택이 될 수 있지만 10개가 넘는 생성자 매개변수가 존재하고 매개변수의 타입마저 연달아 늘어서 있다면 코드를 작성할 때 휴먼에러로 이러질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히, 매개변수의 타입이 같아서 개발자가 실수한다면 컴파일 시, 오류를 잡아내지 못하기에 한참동안 방황할 수도 있을 것 같다.&lt;/p&gt;
&lt;pre class=&quot;lsl&quot;&gt;&lt;code&gt;// 매개변수가 많아져 눈에 들어오지 않는다.
Student student = new Student(1L, &quot;장규민&quot;, 10, 179, 71, 100, 234, &quot;01099700790&quot;, 12034, 634, 1234, 623, 1234, 523, 524); &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 원하는 속성의 값만 초기화 하기 위해 점층적 생성자 패턴을 사용하여 생성자 매개변수를 줄일수도 있다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;// 초기화를 원하는 속성을 점층적 생성자 패턴
public Student(Long studentId, String name, int height, int weight) {
        this.studentId = studentId;
        this.name = name;
        this.height = height;
        this.weight = weight;
    }


Student student = new Student(1L, &quot;장규민&quot;, 179, 71);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이마저의 매개변수도 길어질 여지는 충분히 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;JavaBeans Pattern&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자 방법의 첫번째 대안으로는 자바빈즈 패턴(JavaBeans pattern)이 있다. 우리가 익숙하게 사용하는 &lt;code&gt;Getter&lt;/code&gt;, &lt;code&gt;Setter&lt;/code&gt; 메서드를 통해 인스턴스 속성에 접근하고 변경할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public class Student {

    private Long studentId;
    private String name;
    private int age;
    private int height;
    private int weight;
    private String phoneNo;

    public Student() {
    }    

    public Long getStudentId() {
        return studentId;
    }

    public void setStudentId(Long studentId) {
        this.studentId = studentId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public String getPhoneNo() {
        return phoneNo;
    }

    public void setPhoneNo(String phoneNo) {
        this.phoneNo = phoneNo;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;Student s = new Student();
s.setStudentId(1L);
s.setName(&quot;장규민&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매개변수가 길게 나열된 생성자 패턴보다는 &lt;code&gt;Setter&lt;/code&gt; 메서드를 통해 필요한 속성에 직접 값을 설정할 수 있으므로 직관적으로 보인다. 하지만 Effective Java 에서는 하나의 객체를 만드는데 여러개의 메서드가 호출되어야 하고 객체가 완전히 생성되기 전까지 일관성(consistency)가 무너진 상태로 놓이기에 큰 단점이 될 수 있다고 한다. 이 말은 즉슨 메서드의 호출을 이용한 객체 속성의 설정은 소스 이곳저곳에서 사용될 우려가 있어 런타임 오류 시, 디버깅이 매우 힘든다는 것이다. 때문에 실제로 운영되는 서비스에서는 &lt;code&gt;Setter&lt;/code&gt; 메서드의 사용을 최대한 자제하기도 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Builder Pattern&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;점측적 생성자 패턴의 안전성 + 자바빈즈 패턴의 가독성&lt;/li&gt;
&lt;li&gt;불변의 클래스&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public class Student {

    private Long studentId;
    private String name;
    private int age;
    private int height;
    private int weight;
    private String phoneNo;

    public Student(Builder builder) {
        studentId = builder.studentId;
        name = builder.name;
        age = builder.age;
        height = builder.height;
        weight = builder.weight;
        phoneNo = builder.phoneNo;
    }

    public static class Builder {

        private Long studentId;
        private String name;
        private int age = 0;
        private int height = 0;
        private int weight = 0;
        private String phoneNo = null;

        public Builder studentId(Long studentId) {
            this.studentId = studentId;
            return this;
        }

        public Builder name(String name) {
            this.name = name;
            return this;
        }

        public Builder age(int age) {
            this.age = age;
            return this;
        }

        public Builder height(int height) {
            this.height = height;
            return this;
        }

        public Builder weight(int weight) {
            this.weight = weight;
            return this;
        }

        public Builder phoneNo(String phoneNo) {
            this.phoneNo = phoneNo;
            return this;
        }

        public Student builder() {
            return new Student(this);
        }

    }
}

public class Main {
    public static void main(String[] args) {
        // 플루언트(fluent) API 또는 메서드 연쇄(method chaining)
        new Student.Builder()
                .studentId(1L)
                .name(&quot;장규민&quot;)
                .height(182)
                .weight(120)
                .builder();

    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Java</category>
      <author>devyu</author>
      <guid isPermaLink="true">https://pugyu.tistory.com/115</guid>
      <comments>https://pugyu.tistory.com/115#entry115comment</comments>
      <pubDate>Tue, 29 Mar 2022 00:12:15 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] 정규표현식 정리하기();</title>
      <link>https://pugyu.tistory.com/109</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;정규표현식(Regular Expression)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 특정한 규칙을 가진 문자열의 집합을 표현하기 위해 쓰이는 형식언어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 780px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;기호&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px; text-align: center;&quot;&gt;설명&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;예시패턴&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px; text-align: center;&quot;&gt;매칭문자열&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;^&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;문자열 행의 시작&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;-&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;$&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;문자열&amp;nbsp;행의 끝&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;-&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;.&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;임의의 문자 한 개를 의미(줄바꿈 제외)&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9;&quot;&gt;[ab].&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9;&quot;&gt;&quot;ac&quot;, &quot;ad&quot;, &quot;bb&quot;, &quot;bz&quot;, etc..&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;*&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;앞 표현식의 문자가 없거나 한개 이상을 의미&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;(car)[0-9]*&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&quot;car&quot;, &quot;car051&quot;, &quot;car421&quot;, etc...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;+&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;앞 표현식의 문자가 한개 이상을 의미&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9;&quot;&gt;(car)[0-9]*&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&quot;car0&quot;, &quot;car111&quot;, etc...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; text-align: center; height: 20px;&quot;&gt;?&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;앞 표현식의 문자가 없거나 한개를 의미&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9;&quot;&gt;(car)[0-9]?&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px; text-align: left;&quot;&gt;&quot;car&quot;, &quot;car1&quot;, &quot;car4&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;[ ]&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;대괄호는 검증문자 1개를 의미&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px; text-align: left;&quot;&gt;a, b, c, d 중 문자 1개&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9;&quot;&gt;[abcd]&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px; text-align: left;&quot;&gt;b, c 를 제외한 문자 1개&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;[^bc]&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&quot;a&quot;, &quot;d&quot;, &quot;e&quot;, &quot;z&quot;, &quot;0&quot;, &quot;한&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px; text-align: left;&quot;&gt;a부터 c까지의 문자, e부터 g까지의 문자 1개&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9;&quot;&gt;[a-ce-g]&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;e&quot;, &quot;f&quot;, &quot;g&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px; text-align: left;&quot;&gt;b부터 e까지의 문자, 1부터 4까지의 문자 1개&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;[b-e1-2]&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&quot;b&quot;, &quot;c&quot;, &quot;d&quot;, &quot;e&quot;, &quot;1&quot;, &quot;2&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;{ }&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;중괄호는 횟수 또는 범위를 의미&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;[0-9]{1,3}&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&quot;023&quot;, &quot;1&quot;, &quot;46&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;( )&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;소괄호안의 문자는 그 자체의 의미&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;(423)&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&quot;423&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;|&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;패턴 안에서 or 연산을 의미&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;(123|456|789)&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&quot;123&quot;, &quot;456&quot;, &quot;789&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;\&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;정규표현식 확장 문자&lt;br /&gt;\ 다음에 일반문자가 오면 특수 문자로 취급&lt;br /&gt;\ 다음에 특수문자가 오면 문자 자체로 취급&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;\b&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;단어의 경계&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;\B&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;단어의 경계가 아닌 것&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;\A&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;입력의 시작 부분&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;\G&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;이전 매치의 끝&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;\Z&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;입력의 끝이지만 종결자가 있는 경우&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;\z&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;입력의 끝&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;\S&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;white space가 아닌 문자&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;\s&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;white space&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;\W&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;한개의 알파벳 or 숫자가 아닌 문자, [^\w]&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;\w&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;한개의 알파벳이나 숫자, [a-zA-Z0-9]&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;\D&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;한개의 숫자가 아닌 문자, [^0-9]&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;\d&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;한개의 숫자, [0-9]&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 7.42246%; height: 20px; text-align: center;&quot;&gt;(?i)&lt;/td&gt;
&lt;td style=&quot;width: 42.1319%; height: 20px;&quot;&gt;대소문자를 구분하지 않음&lt;/td&gt;
&lt;td style=&quot;width: 13.0622%; text-align: center; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 26.4728%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <author>devyu</author>
      <guid isPermaLink="true">https://pugyu.tistory.com/109</guid>
      <comments>https://pugyu.tistory.com/109#entry109comment</comments>
      <pubDate>Tue, 29 Jun 2021 22:36:53 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 제네릭 타입 정리하기();</title>
      <link>https://pugyu.tistory.com/108</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;API document을 보다가 제네릭 타입 표현이 많아 이번 기회에 다시 한번 제네릭을 정리하기로 결심하고 오랜만에&lt;br /&gt;자바 책을 다시 펼치게 되었다는...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;제네릭은 Java 5에서 처음 등장하였으며,&lt;b&gt;클래스와 인터페이스, 메소드를 정의할 때, 타입을 파라미터로 사용하고, 파라미터는 코드 작성 시 구체적인 타입으로 대체되어 동적인 코드를 생성하도록 도와주는 기술이다.&lt;/b&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;제네릭 클래스, 제네릭 인터페이스&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;텍스트로 보면 곧바로 와닿지 않는다. 바로 코드를 보자.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;@Getter
public class Height&amp;lt;T&amp;gt; {
    private T t;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위 클래스는 간단한 &lt;code&gt;Height&lt;/code&gt; 클래스이며, 클래스명 뒤에 제네릭 클래스를 의미하는 &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; 부호가 붙어있다. 해당하는 부호 사이에 타입 파라미터를 나타내는 &lt;code&gt;T&lt;/code&gt; 문자열이 있으며 일반적으로 대문자 알파벳 한 글자로 표현하곤 한다.&lt;/p&gt;
&lt;p&gt;타입 파라미터는 &lt;code&gt;Height&lt;/code&gt; 클래스를 실제 코드로 사용할 때, 구체적인 타입을 지정해서 구체화 한다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public class GenericMain {

    public static void main(String[] args) {

    // 타입 파라미터 Integer
        Height&amp;lt;Integer&amp;gt; heightA = new Height&amp;lt;&amp;gt;();

        // 타입 파라미터 Double
        Height&amp;lt;Double&amp;gt; heightB = new Height&amp;lt;&amp;gt;();

    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;변수명 heightA는 타입 파라미터를 &lt;code&gt;Integer&lt;/code&gt;로 지정하였고, 변수명 heightB는 타입 파라미터를 &lt;code&gt;Double&lt;/code&gt;로 지정하였다. 각 각의 타입 파라미터는 &lt;code&gt;Height&lt;/code&gt; 객체의 임의의 타입파라미터 &lt;code&gt;T&lt;/code&gt;와 매핑되어, 정수형, 실수형 객체 인스턴스가 생성된다.&lt;/p&gt;
&lt;p&gt;제네릭을 통해 하나의 클래스로 동적인 타입을 가지는 객체를 생성하는 것은 장점이 많다.&lt;/p&gt;
&lt;p&gt;예를 들어, 제네릭 타입이 아닌 모든 객체의 최상위 객체인 &lt;code&gt;java.lang.Object&lt;/code&gt; 을 통해 정수형과 실수형 데이터를 받는다고 가정해보자.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;@Getter
public class HeightV2 {
    private Object o;
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public class GenericMain {

    public static void main(String[] args) {

        HeightV2 heightC = new HeightV2();
        // 정수형, 자동타입변환
        heightC.setValue(178);
    // 강제타입변환
        Integer a = (Integer) heightC.getValue();


        HeightV2 heightD = new HeightV2();
        // 실수형, 자동타입변환
        heightD.setValue(180.4);
    // 강제타입변환
        double b = (double) heightD.getValue();

    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;setter 메소드를 통해 정수형, 실수형 데이터를 넣을 땐, Object 타입으로 자동타입변환이 이루어지며, getter 메소드를 통해 데이터를 가져올 때는 강제타입변환이 필요하다. 이 과정은 시스템 자원을 낭비하는 코딩이 될 수 있다.(물론 미미하겠지만..)&lt;/p&gt;
&lt;p&gt;위와 같은 상황에서 제네릭 타입을 사용하면,&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;Height&amp;lt;Integer&amp;gt; heightA = new Height&amp;lt;&amp;gt;();
heightA.setT(178);
Integer t = heightA.getT();

Height&amp;lt;Double&amp;gt; heightB = new Height&amp;lt;&amp;gt;();
heightB.setT(180.4);
Double d = heightB.getT();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;저장할 때와 불러올 때 모두 자동타입변환 및 강제타입변환이 발생하지 않는다.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;제네릭 메소드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;제네릭 메소드는 리턴타입 앞에 &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; 기호를 추가하고, 타입파리머터 및 리턴 타입, 매개 타입을 타입 파라미터의 타입으로 기술하여 사용한다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public static &amp;lt;T&amp;gt; Height&amp;lt;T&amp;gt; makeHeight(T t) {
    Height&amp;lt;T&amp;gt; height = new Height&amp;lt;&amp;gt;();
    height.setT(t);
    return height;
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public static void main(String[] args) {
    Height&amp;lt;Integer&amp;gt; heightE = makeHeight(178);
    Height&amp;lt;Double&amp;gt; heightF = makeHeight(180.4);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;매개값을 보고 구체적인 타입을 추정하여 제네릭 메소드를 호출할 수 있다.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;제한된 타입 파라미터&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;제네릭 타입에 타입 파라미터를 제한할 수 있다. 타입 파라미터를 제한하기 위해서는 타입 파라미터 뒤에 &lt;code&gt;extends&lt;/code&gt; 키워드를 통해 상위 타입을 명시한다.&lt;/p&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;public class A extends B{
    ...
}

public class B {
    ...
}

public class C {
    ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;B 클래스를 상속한 A 클래스, B 클래스, C 클래스&lt;/p&gt;
&lt;pre class=&quot;gradle&quot;&gt;&lt;code&gt;public static &amp;lt;T extends B&amp;gt; void makeAlphabet(T t) {
    if (t instanceof A) {
        System.out.println(&quot;Type A&quot;);
    } else if (t instanceof B) {
        System.out.println(&quot;Type B&quot;);
    } else if (t instanceof C) {
        System.out.println(&quot;Type C&quot;);
    } else {
        System.out.println(&quot;no matching&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;haxe&quot;&gt;&lt;code&gt;makeAlphabet(new A()); // 허용
makeAlphabet(new B()); // 허용
makeAlphabet(new C()); // 허용되지 않음&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;instanceof&lt;/code&gt; 연산자를 사용하여 매개타입을 알아보는 메소드가 있다. 이를 통하여 타입 파라미터의 제한을 확인해 보자.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;T extends B&amp;gt;&lt;/code&gt; 타입 파라미터를 통하여, 타입 파라미터는 B 타입을 최상위 타입으로 제한할 것이라는 것을 명시해주었다. 따라서 B 클래스를 상속한 A 클래스, B 클래스는 해당 메소드를 호출할 수 있지만, C 클래스의 경우, 제한된 타입 파라미터로 인식되어 컴파일 에러가 발생한다.&lt;/p&gt;</description>
      <category>Java</category>
      <author>devyu</author>
      <guid isPermaLink="true">https://pugyu.tistory.com/108</guid>
      <comments>https://pugyu.tistory.com/108#entry108comment</comments>
      <pubDate>Sun, 25 Apr 2021 23:44:25 +0900</pubDate>
    </item>
    <item>
      <title>[HTTP] HTTP 응답 상태코드 정리하기();</title>
      <link>https://pugyu.tistory.com/107</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;HTTP 응답의 상태코드 정리를 간단하게 해보자&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbvUqI/btq2QVhUrgu/mVIkLqpOK4UB6s7vrFdjL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbvUqI/btq2QVhUrgu/mVIkLqpOK4UB6s7vrFdjL0/img.png&quot; data-alt=&quot;크롬 개발자도구 Network 탭을 통해 요청과 응답을 확인할 수 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbvUqI/btq2QVhUrgu/mVIkLqpOK4UB6s7vrFdjL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbvUqI%2Fbtq2QVhUrgu%2FmVIkLqpOK4UB6s7vrFdjL0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크롬 개발자도구 Network 탭을 통해 요청과 응답을 확인할 수 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;모든 HTTP 요청에는 HTTP 응답이 있다. 그 응답 속에는 항상 상태코드(Status Code)가 있는데, 이를 통해 요청을 준 클라이언트에게 서버단의 처리 결과를 알려줄 수 있다.&lt;/p&gt;
&lt;p&gt;개발자로서 항상 200번 대의 응답을 만나는 것은 아니니 400, 500 번대 응답도 알아두는게 도움이 될 것 같다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3&gt;HTTP 상태코드 100 ~ 1xx&lt;/h3&gt;
&lt;p&gt;100번 대의 상태코드는 정보성 상태를 의미하며 HTTP/1.1에서 첫 도입되었다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;구간&lt;/td&gt;
&lt;td style=&quot;width: 10.1163%; text-align: center;&quot;&gt;상태코드&lt;/td&gt;
&lt;td style=&quot;width: 25.9302%; text-align: center;&quot;&gt;사유구절&lt;/td&gt;
&lt;td style=&quot;width: 38.9535%; text-align: center;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot; rowspan=&quot;2&quot;&gt;100 ~ 1xx&lt;/td&gt;
&lt;td style=&quot;width: 10.1163%;&quot;&gt;100&lt;/td&gt;
&lt;td style=&quot;width: 25.9302%;&quot;&gt;Continue&lt;/td&gt;
&lt;td style=&quot;width: 38.9535%;&quot;&gt;클라이언트의 요청의 일부가 받아들여졌으며, 클라이언트는 계속해서 요청의 나머지를 계속 이어서 보내야함을 의미하는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 10.1163%;&quot;&gt;101&lt;/td&gt;
&lt;td style=&quot;width: 25.9302%;&quot;&gt;Switching Protocols&lt;/td&gt;
&lt;td style=&quot;width: 38.9535%;&quot;&gt;서버가 프로토콜을 바꾸었음을 나타내는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;100번 상태코드는 클라이언트가 본문을 서버에게 보낼 때, 그 이전에 서버에서 본문을 받아들일 것이지 확인하고자 할 때 사용되며 &lt;code&gt;100 Continue&lt;/code&gt;로 응답한다. 클라이언트는 측에서 해당 응답을 받으려면 Expect 요청 헤더에 &lt;code&gt;100-continue&lt;/code&gt; 값을 포함하여 보내야만 한다.&lt;/p&gt;
&lt;p&gt;서버는 &lt;code&gt;100-continue&lt;/code&gt; 값이 담긴 Expect 헤더가 포함된 요청을 받는다면, 100 Continue 혹은 400번 대의 에러코드로 응답해야만 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HTTP 상태코드 200 ~ 2xx&lt;/h3&gt;
&lt;p&gt;200번 대의 상태코드는 '성공' 을 의미하며, HTTP 통신에서 가장 흔하게 볼 수 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 152px;&quot; border=&quot;1&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 12.5969%; height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;구간&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.1551%; height: 19px; text-align: center;&quot;&gt;상태코드&lt;/td&gt;
&lt;td style=&quot;width: 26.938%; height: 19px; text-align: center;&quot;&gt;사유구절&lt;/td&gt;
&lt;td style=&quot;width: 50.31%; height: 19px; text-align: center;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 12.5969%; height: 133px;&quot; rowspan=&quot;7&quot;&gt;200 ~ 299&lt;/td&gt;
&lt;td style=&quot;width: 10.1551%; height: 19px;&quot;&gt;200&lt;/td&gt;
&lt;td style=&quot;width: 26.938%; height: 19px;&quot;&gt;OK&lt;/td&gt;
&lt;td style=&quot;width: 50.31%; height: 19px;&quot;&gt;요청을 정상적으로 처리하였고 본문에 요청된 리소스를 포함하고 있는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 10.1551%; height: 19px;&quot;&gt;201&lt;/td&gt;
&lt;td style=&quot;width: 26.938%; height: 19px;&quot;&gt;Created&lt;/td&gt;
&lt;td style=&quot;width: 50.31%; height: 19px;&quot;&gt;서버에 개체를 생성하라는 요청을 위한 성공 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 10.1551%; height: 19px;&quot;&gt;202&lt;/td&gt;
&lt;td style=&quot;width: 26.938%; height: 19px;&quot;&gt;Accepted&lt;/td&gt;
&lt;td style=&quot;width: 50.31%; height: 19px;&quot;&gt;서버는 클라이언트의 요청에 대하여 수용하였으나, 아직 그 어떤 동작도 수행하지 않은 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 10.1551%; height: 19px;&quot;&gt;203&lt;/td&gt;
&lt;td style=&quot;width: 26.938%; height: 19px;&quot;&gt;Non-Autohritative Information&lt;/td&gt;
&lt;td style=&quot;width: 50.31%; height: 19px;&quot;&gt;헤더에 들어있는 정보가 리소스 사본에서 왔으며, 리소스에 대한 메타 정보를 검증하지 못한 경우 응답하는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 10.1551%; height: 19px;&quot;&gt;204&lt;/td&gt;
&lt;td style=&quot;width: 26.938%; height: 19px;&quot;&gt;No Content&lt;/td&gt;
&lt;td style=&quot;width: 50.31%; height: 19px;&quot;&gt;요청을 정상적으로 처리하였고 본문을 포함하지 않는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 10.1551%; height: 19px;&quot;&gt;205&lt;/td&gt;
&lt;td style=&quot;width: 26.938%; height: 19px;&quot;&gt;Reset Content&lt;/td&gt;
&lt;td style=&quot;width: 50.31%; height: 19px;&quot;&gt;브라우저에게 현재 페이지에 있는 HTML 폼에 채워진 모든 값을 비우라는 것을 알려주기 위한 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 10.1551%; height: 19px;&quot;&gt;206&lt;/td&gt;
&lt;td style=&quot;width: 26.938%; height: 19px;&quot;&gt;Paritail Content&lt;/td&gt;
&lt;td style=&quot;width: 50.31%; height: 19px;&quot;&gt;클라이언트의 요청에 대하여 부분 혹은 범위적인 성공을 나타내는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HTTP 상태코드 300 ~ 3xx&lt;/h3&gt;
&lt;p&gt;300번 대의 상태코드는 '리다이렉션' 에 대한 코드이며, 클라이언트의 요청에 대하여 원하는 리소스가 다른 위치에 있다는 것을 전달하거나 해당 리소스의 대안 응답을 제공한다.&lt;/p&gt;
&lt;p&gt;리다이렉션 상태코드와 Location 헤더를 사용하여 브라우저에게 새 위치로 재 요청을 보내도록 할 수 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 152px;&quot; border=&quot;1&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 11.7441%; height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;구간&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 9.76759%; height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;상태코드&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;사유구절&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 58.4883%; height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;설명&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 11.7441%; height: 133px;&quot; rowspan=&quot;7&quot;&gt;300 - 3xx&lt;/td&gt;
&lt;td style=&quot;width: 9.76759%; height: 19px;&quot;&gt;300&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;Multiple Cohoices&lt;/td&gt;
&lt;td style=&quot;width: 58.4883%; height: 19px;&quot;&gt;클라이언트가 동시에 여러 리소스를 가리키는 URL을 요청한 경우, 그 리소스의 목록과 함께 반환하는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 9.76759%; height: 19px;&quot;&gt;301&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;Moved Permanently&lt;/td&gt;
&lt;td style=&quot;width: 58.4883%; height: 19px;&quot;&gt;요청한 URL이 옮겨졌을 때 사용되는 상태.&lt;br /&gt;Location 헤더에 현재 리소스가 존재하고 있는 URL을 포함해야 함.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 9.76759%; height: 19px;&quot;&gt;302&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;Found&lt;/td&gt;
&lt;td style=&quot;width: 58.4883%; height: 19px;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;요청한 URL이 옮겨졌을 때 사용되는 상태.&lt;br /&gt;&lt;/span&gt;Location 헤더의 URL은 임시로 이동되는 목적으로 사용되며 이후의 요청에서는 원래의 URL을 사용해야 함.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 9.76759%; height: 19px;&quot;&gt;303&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;See Other&lt;/td&gt;
&lt;td style=&quot;width: 58.4883%; height: 19px;&quot;&gt;클라이언트에게 리소스를 다른 URL에서 가져올 것을 말하고자 할 때 사용되는 상태.&lt;br /&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Location 헤더에 현재 리소스가 존재하고 있는 URL을 포함해야 함.&lt;/span&gt;&lt;br /&gt;303 상태코드의 주 목적은 POST 요청에 대한 응답이며 GET 요청으로 리다이렉트 시킨다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 9.76759%; height: 19px;&quot;&gt;304&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;Not Modified&lt;/td&gt;
&lt;td style=&quot;width: 58.4883%; height: 19px;&quot;&gt;클라이언트는 If-Modified-Since 헤더를 사용하여 조건부 요청을 할 수 있다. 조건부 헤더의 정보를 바탕으로 서버의 리소스가 수정된 사항이 없을 경우 반환하는 상태.&lt;br /&gt;304 상태는 리소스 수정이 없기때문에 응답 본문이 존재하지 않는다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 9.76759%; height: 19px;&quot;&gt;305&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;Use Proxy&lt;/td&gt;
&lt;td style=&quot;width: 58.4883%; height: 19px;&quot;&gt;리소스가 반드시 프록시를 통해서 접근되어야 함을 나타내기 위해 사용되는 상태.&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 9.76759%; height: 19px;&quot;&gt;307&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;Temporary Redirect&lt;/td&gt;
&lt;td style=&quot;width: 58.4883%; height: 19px;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;요청한 URL이 옮겨졌을 때 사용되는 상태.&lt;br /&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Location 헤더의 URL은 임시로 이동되는 목적으로 사용되며 이후의 요청에서는 원래의 URL을 사용해야 함.&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HTTP 상태코드 400 ~ 4xx&lt;/h3&gt;
&lt;p&gt;400번 대의 상태코드는 '클라이언트 요청에 대한 에러' 를 설명하는 코드이다. 클라이언트의 요청을 서버가 처리할 수 없을 경우 발생하며 대게 브라우저를 통해 처리된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 361px;&quot; border=&quot;1&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 12.6745%; height: 19px; text-align: center;&quot;&gt;구간&lt;/td&gt;
&lt;td style=&quot;width: 14.651%; height: 19px; text-align: center;&quot;&gt;상태코드&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;사유구절&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;설명&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 12.6745%; height: 342px;&quot; rowspan=&quot;18&quot;&gt;400 ~ 4xx&lt;/td&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;400&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;Bad Request&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;클라이언트의 요청이 잘못된 것을 알려주는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;401&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;Unauthorized&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;인증이 되지 않은 클라이언트에게 인증을 요구하기 위한 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;402&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;Payment Required&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;현재 사용되지 않는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;403&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;Forbidden&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;서버에서 클라이언트의 요청을 거부하고자 할 때 사용되는 상태. 인증은 되었으나 허가되지 게시물에 접근하고자 할 때 발생 할 수 있음.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;404&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;Not Found&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;존재하지 않는 URL에 접근할 때 응답하는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;405&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;Method Not Allowed&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;요청한 URL에 대하여 지원하지 않는 메서드의 요청을 받았을 때 사용하는 상태.&lt;br /&gt;Allow 헤더를 포함하여 클라이언트가 인지할 수 있도록 한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;406&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;Not Acceptable&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;클라이언트가 요청한 URL에 대한 리소스 중 클라이언트가 받아들일 수 있는 것이 없는 경우 사용되는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;407&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;Proxy Authentication Required&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;접근하는 리소스에 대한 인증을 요구하는 프락시 서버를 위해 사용되는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;408&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;Request Timeout&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;클라이언트의 요청을 완수하기에 시간이 너무 많이 걸리는 경우, 서버는 408 상태를 응답하면서 연결을 끊을 수 있음.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;409&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;Conflict&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;클라이언트의 요청이 리소스의 충돌을 일으킬 염려가 있을 때 사용되는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;410&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;Gone&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;404 상태와 비슷하나 한 때, 서버가 해당 리소스를 갖고 있었을 경우 응답하는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;411&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;Length Required&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;서버가 클라이언트의 요청에 Content-Length 헤더가 있을 것을 요구할 때 사용하는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;412&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Precondition Failed&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;클라이언트가 조건부 요청을 하였을 경우, 그 중 하나가 실패했을 때 사용하는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;413&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Request Entity Too Large&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;서버가 처리할 수 있는 한계를 넘은 크기의 요청을 클라이언트가 보냈을 경우 사용하는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;414&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Request URI Too Long&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;서버가 처리할 수 있는 한계를 넘은 길이의 요청 URL이 포함된 요청을 클라이언트가 보냈을 경우 사용하는 상태&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;415&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Unsupported Media Type&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;서버가 이해하지 못한 내용 유형의 헤더 및 본분을 클라이언트가 요청하였을 경우 응답하는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;416&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Requested Range Not Satisfiable&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;리소스의 특정 범위를 요청하였으나, 그 범위가 잘못되었을 경우 사용되는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 14.651%; height: 19px;&quot;&gt;417&lt;/td&gt;
&lt;td style=&quot;width: 29.0698%; height: 19px;&quot;&gt;Expectation Failed&lt;/td&gt;
&lt;td style=&quot;width: 43.6047%; height: 19px;&quot;&gt;요청에 포함된 Expect 요청 헤더에 서버가 만족시킬 수 없는 기대가 담겨있는 경우 사용되는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HTTP 상태코드 500 ~ 5xx&lt;/h3&gt;
&lt;p&gt;500번 대의 상태코드는 '서버 자체 에러' 를 의미한다. 클라이언트 측에서 올바른 요청을 보냈음에도 서버가 처리를 할 수 없는 상태&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 153px;&quot; border=&quot;1&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 16.2791%; text-align: center; height: 19px;&quot;&gt;구간&lt;/td&gt;
&lt;td style=&quot;width: 15.1162%; text-align: center; height: 19px;&quot;&gt;상태코드&lt;/td&gt;
&lt;td style=&quot;width: 26.9768%; text-align: center; height: 19px;&quot;&gt;사유구절&lt;/td&gt;
&lt;td style=&quot;width: 41.6279%; text-align: center; height: 19px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 39px;&quot;&gt;
&lt;td style=&quot;width: 16.2791%; text-align: center; height: 134px;&quot; rowspan=&quot;6&quot;&gt;500 ~ 5xx&lt;/td&gt;
&lt;td style=&quot;width: 15.1162%; text-align: center; height: 39px;&quot;&gt;500&lt;/td&gt;
&lt;td style=&quot;width: 26.9768%; height: 39px;&quot;&gt;Internal Server Error&lt;/td&gt;
&lt;td style=&quot;width: 41.6279%; height: 39px;&quot;&gt;서버가 요청을 처리할 수 없게 만드는 에러가 발생한 경우 응답하는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 15.1162%; text-align: center; height: 19px;&quot;&gt;501&lt;/td&gt;
&lt;td style=&quot;width: 26.9768%; height: 19px;&quot;&gt;Not Implemented&lt;/td&gt;
&lt;td style=&quot;width: 41.6279%; height: 19px;&quot;&gt;클라이언트가 서버의 능력을 넘은 요청을 했을 때 사용하는 상태(서버가 지원하지 않는 메서드로 요청)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 15.1162%; text-align: center; height: 19px;&quot;&gt;502&lt;/td&gt;
&lt;td style=&quot;width: 26.9768%; height: 19px;&quot;&gt;Bad Gateway&lt;/td&gt;
&lt;td style=&quot;width: 41.6279%; height: 19px;&quot;&gt;프록시나 게이트웨이로부터 잘못된 응답을 받았을 경우 사용되는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 15.1162%; text-align: center; height: 19px;&quot;&gt;503&lt;/td&gt;
&lt;td style=&quot;width: 26.9768%; height: 19px;&quot;&gt;Service Unavailable&lt;/td&gt;
&lt;td style=&quot;width: 41.6279%; height: 19px;&quot;&gt;현재 서버에서 요청을 처리해줄 수 없는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 15.1162%; text-align: center; height: 19px;&quot;&gt;504&lt;/td&gt;
&lt;td style=&quot;width: 26.9768%; height: 19px;&quot;&gt;Gateway Timeout&lt;/td&gt;
&lt;td style=&quot;width: 41.6279%; height: 19px;&quot;&gt;프록시나 게이트웨이로부터 응답을 기다리다 발생한 타임아웃에 대한 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 15.1162%; text-align: center; height: 19px;&quot;&gt;505&lt;/td&gt;
&lt;td style=&quot;width: 26.9768%; height: 19px;&quot;&gt;HTTP Version Not Supported&lt;/td&gt;
&lt;td style=&quot;width: 41.6279%; height: 19px;&quot;&gt;서버가 지원할 수 없거나 지원하지 않으려고 하는 버전의 프로토콜로 된 요청을 받았을 때 사용하는 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>HTTP</category>
      <category>HTTP</category>
      <category>상태코드</category>
      <author>devyu</author>
      <guid isPermaLink="true">https://pugyu.tistory.com/107</guid>
      <comments>https://pugyu.tistory.com/107#entry107comment</comments>
      <pubDate>Mon, 19 Apr 2021 00:02:23 +0900</pubDate>
    </item>
    <item>
      <title>[git] 커맨드라인을 통한 깃(git) 명령어 정리</title>
      <link>https://pugyu.tistory.com/95</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;해당 포스팅은 생활코딩의 egoing님 Git 강의를 듣고 정리한 자료이다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;Git의 핵심 목적&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;버전관리&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;백업&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;협업&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;1. 버전관리&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;파일이 변경되었을때 변경사항들을 버전으로 만들어서 관리하는것.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dErisr/btqDg46EqIE/JkixbVi5wVYkfYFDVqAC5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dErisr/btqDg46EqIE/JkixbVi5wVYkfYFDVqAC5k/img.png&quot; data-alt=&quot;버전관리 사이클&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dErisr/btqDg46EqIE/JkixbVi5wVYkfYFDVqAC5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdErisr%2FbtqDg46EqIE%2FJkixbVi5wVYkfYFDVqAC5k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;버전관리 사이클&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;init&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;현재 디렉토리를 git을 통해 버전관리를 요청한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;버전이 저장되는 저장소(repository)를 생성하는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586415205609&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;status&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;git을 통해 관리하고 있는 디렉토리의 상태를 묻는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586415788774&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;add&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;working-directory의 수정사항을 버전으로 만들기 위해 staging-area로 올리는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586415951856&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// [파일이름]을 staging-area 올린다.
git add [파일이름]

// 모든 수정된 file을 staging-area에 올린다.
git add .
&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;commit&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;staging-area에 올라와 있는 수정사항을 저장소(repository)로 보내서 버전으로 만드는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586416073180&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git commit

// -m : 커맨드라인에서 직접 commit 메시지 적기
git commit -m &quot;commit message&quot;

// -am : add &amp;amp; commit 메시지 적기
// -am 설정은 Untracked 파일에는 사용할 수 없기 때문에 최초 1번의 add 명령어로 
// staging-area에 올려서 tracked 상태가 되어야 한다.
// 추적되지 않은 파일이 추적되는 것을 막을수 있다.
git commit -am &quot;commit message&quot;

// --ammend : 마지막 commit 메시지 수정하기
git commit --ammend&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;log&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;commit 내역을 확인하기 위한 명령어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586416377506&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git log

// -p : commit 상세 내용 보기
git log -p

// --oneline : commit 내역 한줄로 보기
git log --oneline

// --all : 모든 branch의 로그 보기
git log --all

// --graph : 그래프 형식으로 로그 보기
git log --graph&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;diff&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;difference의 약자로 수정된 working-directory의 수정된 차이점을 보여주는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;마지막 commit 버전과 working-directory의 차이점을 통해서 commit하기 전에 최종적으로 검토할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586417115839&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git diff&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;checkout&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;commit 버전을 만든 시점으로 돌아가는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586427837462&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// commit ID값 입력
git checkout b322b7a993d1a98ac132319667509097e7674cd6

// 해당하는 branch로 이동
git checkout [branch 이름]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;442&quot; height=&quot;275&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QLIbM/btqDibEpCoM/lBVRjCFfELNQ8Q5z5uc6TK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QLIbM/btqDibEpCoM/lBVRjCFfELNQ8Q5z5uc6TK/img.png&quot; data-alt=&quot;자동으로 생성되는 commit ID값&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QLIbM/btqDibEpCoM/lBVRjCFfELNQ8Q5z5uc6TK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQLIbM%2FbtqDibEpCoM%2FlBVRjCFfELNQ8Q5z5uc6TK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;442&quot; height=&quot;275&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;자동으로 생성되는 commit ID값&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;reset&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;commit ID값을 통해 해당하는 버전으로 리셋하는 명령어(선택한 버전이 되겠다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;선택된 버전 이후의 commit 버전은 모두 사라진다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586429090869&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git reset --hard 3a1489b8f528bd3b4dd7593a61156b005a5aab5e&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;staging-area에 올라오기 전 working-directory에 존재하는 변경사항을 마지막 버전으로 되돌리는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586450971802&quot; class=&quot;java&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git reset --hard&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;revert&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;선택한 commit 버전의 &lt;b&gt;전 버전&lt;/b&gt;으로 되돌리는 명렁어(선택한 버전의 이전 버전으로 되돌리겠다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;reset의 경우 선택한 버전이 되서 그 이후의 커밋 버전을 지우지만 &lt;b&gt;revert&lt;/b&gt;는 선택한 버전의 이전 버전을 복사해서 새로운 커밋 버전으로 생성하는 개념이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586431989464&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git revert 28a3d81b47044ca203affd2082c929b235f44cb2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYMs3G/btqDjd9HNtt/PZTpRB3Ttf8ClAKKzll1I1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYMs3G/btqDjd9HNtt/PZTpRB3Ttf8ClAKKzll1I1/img.png&quot; data-alt=&quot;3개의 커밋 내역&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYMs3G/btqDjd9HNtt/PZTpRB3Ttf8ClAKKzll1I1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYMs3G%2FbtqDjd9HNtt%2FPZTpRB3Ttf8ClAKKzll1I1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;3개의 커밋 내역&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;git log를 통해 확인한 commit 내역이다. 위 내역에서 커밋 메시지 &quot;R3&quot;를 &lt;b&gt;revert&lt;/b&gt; 한다면 해당 커밋의 이전의 커밋으로, 즉 커밋 메시지 &quot;Message 3&quot;의 상태로 되돌아 간다. &lt;b&gt;revert&lt;/b&gt;는 코드의 상태가 되돌아가지만 커밋 메시지 &quot;R3&quot;에 대한 내역은 사라지지 않고 새롭게 커밋을 생성하는 개념이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;만약 커밋 메시지 &quot;Message 2&quot; 로 가기 위해서는 바로 &lt;b&gt;revert&lt;/b&gt; Message 3를 해야할 것 같지만, 역순으로 작업을 해야한다. 즉, &lt;b&gt;revert &lt;/b&gt;R3 를 하고 &lt;b&gt;revert&lt;/b&gt; Message 3를 해야 Message 2로 돌아갈 수 있는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;2. Branch &amp;amp; Conflict&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;branch&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;브랜치 목록을 확인하는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;기본은 master 브랜치 위에서 작업을 하게된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586450679514&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// branch 목록 보기
git branch

// branch 생성
git branch [생성할 branch 이름]&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;checkout&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;해당 브랜치로 이동하는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586451389632&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// HEAD 브랜치 이동
git checkout [branch 이름]

// commit 값으로 이동(detacted)
git checkout [commit ID값]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;저장소를 생성하면 기본적으로 &lt;b&gt;HEAD&lt;/b&gt;가 만들어지고 기본적으로 master branch를 가리킨다. checkout은 &lt;b&gt;HEAD&lt;/b&gt;의 값을 바꾸는 기능이다.&amp;nbsp; 만약 checkout 명령어를 통해 브랜치가 아닌 commit ID값을 입력하면 브랜치로부터 떨어져있다는 detacted되 있다고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;merge&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;브랜치를 병합하기 위한 명령어&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;병합을 하기 위해서 우선 master branch 상태가 되어야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586452227108&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 병합하기전 master branch 이여야 한다.
git checkout master

git merge [병합할 branch 이름]&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;충돌(conflict)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;같은 라인에서 각각의 수정이 있는 파일을 병합(merge)하였을 경우 발생하는 충돌.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBnEbg/btqDkAwkRY8/f2BQnQlJK23AwCYtB82kL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBnEbg/btqDkAwkRY8/f2BQnQlJK23AwCYtB82kL1/img.png&quot; data-alt=&quot;충돌 발생 로그&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBnEbg/btqDkAwkRY8/f2BQnQlJK23AwCYtB82kL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBnEbg%2FbtqDkAwkRY8%2Ff2BQnQlJK23AwCYtB82kL1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;충돌 발생 로그&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;241&quot; height=&quot;282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2LMkH/btqDkyL6wSg/7YRU9UlJJKl9Cmc2PgItwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2LMkH/btqDkyL6wSg/7YRU9UlJJKl9Cmc2PgItwK/img.png&quot; data-alt=&quot;merge 이후 충동이 일어난 파일의 내부&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2LMkH/btqDkyL6wSg/7YRU9UlJJKl9Cmc2PgItwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2LMkH%2FbtqDkyL6wSg%2F7YRU9UlJJKl9Cmc2PgItwK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;241&quot; height=&quot;282&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;merge 이후 충동이 일어난 파일의 내부&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;'&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;' 에서 '=====' 사이의 내용은 HEAD, 즉 현재 브랜치의 내용을 나타내고, &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;'=====' 에서 '&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;' 사이의 내용은 w3 브랜치의 내용을 나타낸다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;git은 같은 라인에서 브런치 각각의 수정을 자동으로 병합할 수 없으므로 사용자에게 보기를 주고 선택하도록 하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;3. backup&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;remote&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;지역저장소(Local Repository)의 파일을 원격저장소(Remote Repository)와 연결하는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586512915610&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// origin은 원격저장소 별칭으로 origin을 기본으로 한다.
git remote origin [원격저장소에 생성한 주소 URL]

// 연결된 원격 저장소 확인
git remote -v&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;clone&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;원격저장소(Remote Repository)의 파일을 복제해서 지역지역소(Local Repository)를 만드는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;원격저장소의 이름을 딴 폴더가 생성되고 폴더 안에서 프로젝트가 git을 통해 관리된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586519074545&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git clone [원격저장소에 생성한 주소 URL]&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;push&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;지역저장소(Local Repository)에 존재하는 commit된 파일들을 원격저장소(Remote Repository)에 밀어넣는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586519358328&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;pull&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;원격저장소(Remote Repository)의 파일을 지역저장소(Local Repository)에 당겨오는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586519488911&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;4. collaboration&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;fetch&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;원격저장소만 업데이트하는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;merge 명령어를 통해 업데이트 된 파일과 병합해야 한다. 신중하게 파일을 pull하고 싶을때 사용된다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;즉, pull = fetch + merge&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586521505174&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git fetch

// 가장 최신의 커밋을 병합해주는 명령어
git merge FETCH_HEAD&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p style=&quot;font-size: 1.25em;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;cherry-pick&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;해당하는 commit 버전이 생성된 당시의 변화만을 가져와서 병합하는 명령어&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;버전이 생성되었을때의 변화를 합쳐서 새로운 버전을 만들어내는 것&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1586540791590&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git cherry-pick [commit ID값]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git</category>
      <category>Git</category>
      <author>devyu</author>
      <guid isPermaLink="true">https://pugyu.tistory.com/95</guid>
      <comments>https://pugyu.tistory.com/95#entry95comment</comments>
      <pubDate>Fri, 10 Apr 2020 02:34:49 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] 페치조인(fetch join)이란?</title>
      <link>https://pugyu.tistory.com/94</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;페치조인(fetch join)&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;기존 SQL의 조인이 아님&lt;/li&gt;
&lt;li&gt;JPQL의 성능 튜닝을 위해 제공되는 조인&lt;/li&gt;
&lt;li&gt;연관된 엔티티 or&amp;nbsp; 컬렉션을 SQL 한번에 함께 조회하는 기능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;간단한 예제를 보자.&lt;/p&gt;
&lt;pre id=&quot;code_1585849466703&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Entity
@Getter
public class Member {
    @Id @GeneratedValue
    private Long id;
    private String username;
    private int age;
    
    // 양방향 연관 필드
    // 연관관계 주인
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = &quot;TEAM_ID&quot;)
    private Team team;
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1585849555507&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Entity
@Getter
public class Team {

    @Id @GeneratedValue
    private Long id;

    private String name;

    // 양방향 연관 필드
    @OneToMany(mappedBy = &quot;team&quot;)
    private List&amp;lt;Member&amp;gt; memList = new ArrayList&amp;lt;Member&amp;gt;();

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;위 두개의 엔티티는 회원과 팀을 나타내고 있으면서 N : 1 양방향 매핑으로 동작하고 있다. 연관관계의 주인은 N쪽인 회원 엔티티로 선정하였고 &lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;FetchType.Lazy&lt;/span&gt;&lt;/b&gt;를 통해 조회과정에서 &lt;b&gt;지연로딩 전략&lt;/b&gt;을 선택하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;페치조인을 적용해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1585849781809&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// JPQL
select m from Memeber m join fetch m.team

// 실제 데이터베이스에 전송되는 SQL
SELECT M.*, T.* FROM MEMBER M INNER JOIN TEAM T ON M.TEAM_ID = T.ID&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;JPQL에서 &lt;b&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;join fetch&lt;/span&gt; &lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 사용하면 실제 SQL에서는 두 테이블을 조인한 테이블을 조회할 수 있다. 데이터베이스로 전송되는 실제 SQL을 자세히 보면 &lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;FetchType.EAGER&lt;/span&gt;&lt;/b&gt;를 사용한&amp;nbsp;&lt;b&gt;즉시로딩 전략&lt;/b&gt;으로 조회한 것 SQL이 같다는 것을 알 수 있다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(엔티티에서 지연로딩 전략으로 세팅을 해도 JPQL에서 페치조인으로 날리는 것이 우선순위)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;즉시로딩 전략은 묵시적인 방식이라서 원하지 않는 타이밍에도 항상 연관필드를 조인을 하고 결과를 반환한다. 물론 조인을 하고나서 데이터를 처리하는 것이 훨씬 효율적인 구성이 있을텐데 그때 바로 JPQL 페치조인을 사용하는 것이다. JPQL 페치조인은 명시적으로 동적인 타이밍에 원하는 객체그래프를 탐색할 수 있어 유용하다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>JPA</category>
      <category>JPA</category>
      <category>페치조인</category>
      <author>devyu</author>
      <guid isPermaLink="true">https://pugyu.tistory.com/94</guid>
      <comments>https://pugyu.tistory.com/94#entry94comment</comments>
      <pubDate>Fri, 3 Apr 2020 04:09:25 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] 경로표현식(묵시적 내부조인과 명시적 내부조인)</title>
      <link>https://pugyu.tistory.com/93</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;경로표현식&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;' &lt;b&gt;.&lt;/b&gt; '&lt;/span&gt; 을 찍어서 객체 그래프를 탐색 하는것&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;상태필드&lt;/b&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;단순히 값을 저장하기 위한 필드(ex. username)&lt;/li&gt;
&lt;li&gt;경로 탐색의 끝. 더 이상의 탐색할 것이 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1585847796171&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String query = &quot;select m.username from Member12 m&quot;;
List&amp;lt;String&amp;gt; resultList = em.createQuery(query, String.class).getResultList();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSThrF/btqC8H4yeGV/Jc8JgtqFm0KamzQ1PryXS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSThrF/btqC8H4yeGV/Jc8JgtqFm0KamzQ1PryXS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSThrF/btqC8H4yeGV/Jc8JgtqFm0KamzQ1PryXS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSThrF%2FbtqC8H4yeGV%2FJc8JgtqFm0KamzQ1PryXS1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;JPQL을 통해 데이터베이스로 날라간 실제 SQL을 보면 상태필드 조회는 기존의 JPQL과 같음을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;연관필드&lt;/b&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;단일값 연관필드 : @ManyToOne, @OneToOne 대상이 엔티티일 경우&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;묵시적 내부조인 발생&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;추가 탐색 가능(ex. m.team.name)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;컬렉션 값 연관필드 : @OneToMany, @ManyToMany 대상이 컬렉션일 경우
&lt;ul&gt;
&lt;li&gt;묵시적 내부조인 발생&lt;/li&gt;
&lt;li&gt;추가 탐색 불가능(컬렉션 리스트 중에서 특정 하나만 가져오지 못한다는 것을 생각하자. 기껏해야 size 정도만 가져올 수 있다.)&lt;/li&gt;
&lt;li&gt;단, 명시적인 조인을 사용하면 컬렉션 값 연관필드 추가 탐색이 가능하다.
&lt;ul&gt;
&lt;li&gt;select m from Team t join t.members m&lt;/li&gt;
&lt;li&gt;FROM 절에서 명시적 조인을 통해 별칭을 얻으면 별칭을 통해 탐색 가능&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1585847924458&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String query = &quot;select m.team from Member12 m&quot;;
List&amp;lt;Team12&amp;gt; resultList = em.createQuery(query, Team12.class).getResultList();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAfwL7/btqC8HQYQdv/nPxLk4t5U4uLg74O6Oc0U1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAfwL7/btqC8HQYQdv/nPxLk4t5U4uLg74O6Oc0U1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAfwL7/btqC8HQYQdv/nPxLk4t5U4uLg74O6Oc0U1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAfwL7%2FbtqC8HQYQdv%2FnPxLk4t5U4uLg74O6Oc0U1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;JPQL을 통해 연관필드를 조회하면 실제 SQL에서는 내부적으로 연관 테이블을 조인한다. &lt;b&gt;묵시적 내부조인&lt;/b&gt;이 발생한 것을 확인할 수 있다. (&lt;u&gt;묵시적 내부조인은 쿼리를 성능 튜닝하기 굉장히 까다롭기 때문에 실무에서는 사용을 자제해야 한다고 한다.)&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;실무에서는 묵시적 내부조인을 쓰지말고 명시적 내부조인을 사용하는 것이 바람직하다.&lt;/p&gt;</description>
      <category>JPA</category>
      <category>JPA</category>
      <author>devyu</author>
      <guid isPermaLink="true">https://pugyu.tistory.com/93</guid>
      <comments>https://pugyu.tistory.com/93#entry93comment</comments>
      <pubDate>Fri, 3 Apr 2020 02:38:36 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] JPA 쿼리 지원 방식(JPQL)</title>
      <link>https://pugyu.tistory.com/92</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;JPA 쿼리 지원 방식&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;JPA는 데이터베이스에 데이터를 주고받기 위한 다양한 쿼리 방식을 지원한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;JPQL&lt;/span&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;가장 단순한 조회 방법&lt;/span&gt;
&lt;ul style=&quot;list-style-type: square;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;EntityManager.find()&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;객체 그래프 탐색(a.getB().getC())&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;테이블이 아닌 매핑된 엔티티를 대상으로 검색(SQL은 테이블을 대상으로 검색)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어를 제공&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;ANSI 표준 SQL을 지원하는 문법 모두 적용이 가능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;SQL을 추상화해서 특정 데이터베이스에 의존하지 않는다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;단순 String 값으로 쿼리가 쓰이기 때문에 동적 쿼리를 만들기 어렵다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Criteria&lt;/span&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;쿼리를 String 문자가 아닌 자바 코드로 작성하기 때문에 컴파일 오류를 찾기 쉬움&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;동적 쿼리를 짜기 수월하지만 코드의 가독성이 매우 떨어져 유지보수가 어려움&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;사용 빈도가 굉장히 낮음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;QueryDSL&lt;/span&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;오픈소스&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;쿼리를 String 문자가 아닌 자바 코드로 작성하기 때문에 컴파일 오류를 찾기 쉬움&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;동적쿼리 작성이 수월하고 코드가 직관적이고 쉽다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;실무에서 많이 사용되는 방식&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;네이티브 SQL&lt;/span&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;JPA가 직접 SQL을 사용하는 기능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;JPQL로 해결할 수 없는 특정 데이터베이스에 의존적인 기능을 사용할 때 쓰임&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;JPQL(Java Persistence Query Language)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;JPQL은 객체지향 쿼리 언어이므로 테이블을 대상으로 쿼리 하는 것이 아닌 엔티티 객체를 대상으로 쿼리 한다, 또한 SQL을 추상화해서 특정 데이터베이스에 종속되지 않고 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1585501659979&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select m from Member as m where m.name = &quot;devyu&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Member는 테이블이 아닌 엔티티 객체이며 대소문자를 구분함을 유의하자.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;별칭은 꼭 사용되어야 하고 as는 생략이 가능하다. ANSI SQL에 따른 표준 함수들도 사용할 수 있다.(ex, SUM, AVG, MAX, MIN, COUNT 등)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;TypeQuery와 Query&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;TypeQuery는 반환 타입이 명확할 때 사용되고 Query는 반환타입이 명확하지 않을 때 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1585502427862&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// TypedQuery 타입 정보를 받을 수 있을 때(Member.class 명시)
TypedQuery&amp;lt;Member&amp;gt; createQuery = em.createQuery(&quot;select m from Member m&quot;, Member.class);
// TypedQuery 타입 정보를 받을 수 있을 때(Integer.class 명시)
TypedQuery&amp;lt;Integer&amp;gt; createQuery2 = em.createQuery(&quot;select m.age from Member m&quot;, Integer.class);

// Query 타입 정보를 받을 수 없을 때(반환값이 int와 String)
Query createQuery = em.createQuery(&quot;select m.age, m.username from Member m&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;조회 API&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;query.getResultList();&lt;/span&gt;
&lt;ul style=&quot;list-style-type: square;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;결과가 하나 이상일 때, 리스트 반환&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;결과가 없다면 빈 리스트&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;query.getSingleResult();&lt;/span&gt;
&lt;ul style=&quot;list-style-type: square;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;결과가 단 하나뿐일 때, 단일 객체 반환&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;결과가 없다면&lt;/span&gt; &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;javax.persistence.NoResultException&lt;/b&gt;&lt;/span&gt; 발생&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;결과가 둘 이상이라면&lt;/span&gt; &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;javax.persistence.NonUniqueResultException&lt;/b&gt;&lt;/span&gt; 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;파라미터 바인딩&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;이름 기준 바인딩&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1585503425993&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;em.createQuery(&quot;select m from Member11 m where m.username=:username&quot;)
              .setParameter(&quot;username&quot;, &quot;devyu&quot;)
              .getSingleResult();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;바인딩하려는 위치에 ' &lt;b&gt;: &lt;/b&gt;' 를 사용하고 바인딩 이름을 적는다. setParameter() 메서드에 바인딩 이름과 실제 적용될 값을 파라미터로 넘겨준다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;위치 기준 바인딩&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1585503625293&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;em.createQuery(&quot;select m from Member11 m where m.username=?1&quot;)
              .setParameter(1, &quot;devyu&quot;)
              .getSingleResult();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;바인딩하려는 위치에 '&amp;nbsp;&lt;b&gt;?&lt;/b&gt; ' 를 사용하고 바인딩 순서를 적는다. setParameter() 메서드에 바인딩 순서와 실제 적용될 값을 파라미터로 넘겨준다. 위치에 민감하기 때문에 사용을 실수가 나올 수 있는 바인딩 방법이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;프로젝션&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;프로젝션이란 SELECT절에 조회할 대상을 지정하는 것이며 프로젝션의 대상은 엔티티, 임베디드 타입, 스칼라 타입(숫자, 문자 등 기본 데이터를 의미)이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1585504200740&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Entity
public class Member{

	@Id @GeneratedValue
	@Column(name =  &quot;MEMBER_ID&quot;)
	private Long id;
	private String username;
	private int age;
    
	@Embedded
	private Address address;

	@ManyToOne
	@JoinColumn(name = &quot;TEAM_ID&quot;)
	private Team team;
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1585504038445&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 엔티티 프로젝션
select m from Member m

// 엔티티 프로젝션
select m.team from Member m

// 임베디드 타입 프로젝션
select m.address from Member m

// 스칼라 타입 프로젝션
select m.username, m.age from Member m&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;SELECT를 통해 조회된 엔티티는 영속성 컨텍스트 속에서 관리된다. 엔티티 타입으로 데이터를 받고 조작할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;그런데 숫자, 문자 등 여러 타입이 겹친 스칼라 타입 프로젝션의 경우 어떤 타입으로 데이터를 전달받을까?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Object[] 타입으로 받기&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1585506833399&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 단순 값 받기 Object[]
List&amp;lt;Object[]&amp;gt; resultList = em.createQuery(&quot;select m.age, m.username from Member m&quot;)
		.getResultList();
// age
System.out.println(resultList.get(0)[0]);
// username
System.out.println(resultList.get(0)[1]);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;new 명령어를 통한 DTO로 받기&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1585506971496&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MemberDTO {

	private int age;
	private String username;
	
    // 생성자 순서 중요
	public MemberDTO(int age, String username) {
		this.age = age;
		this.username = username;
	}
	
    // getter, setter...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1585507061555&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;List&amp;lt;MemberDTO&amp;gt; resultList = 
	em.createQuery(&quot;select new 패키지경로.MemberDTO(m.age, m.username) from Member m&quot;, MemberDTO.class)
	.getResultList();

// age
System.out.println(resultList2.get(0).getAge());
// username
System.out.println(resultList2.get(0).getUsername());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;패키지 명을 포함한 전체 클래스명을 new 명령어를 통해 DTO 생성하여 값을 넣는 방법. 순서와 타입이 일치하는 생성자가 필수적으로 존재해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;페이징&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;JPA에서 페이징 API는 굉장히 간단하게 구현할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1585537148754&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;List&amp;lt;Member&amp;gt; resultList = 
	em.createQuery(&quot;select m from Member m order by m.age desc&quot;, Member.class)
	.setFirstResult(1)
	.setMaxResults(10)
	.getResultList();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;setFirstResult()&lt;/b&gt; 메서드에 파라미터로 조회 시작 위치를 넣어주고 &lt;b&gt;setMaxResults()&lt;/b&gt; 메서드의 파라미터로 조회할 데이터의 수를 넣어주기만 하면 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;사용하는 데이터베이스 방언 종류에 따라 페이징 관련 쿼리가 다르게 전달된다. 예를 들어 MySQL의 경우 limit와 offset을 이용한 쿼리가 나가고 Oracle의 경우 ROWNUM을 이용한 3중 뎁스로 쿼리가 나간다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n8pYD/btqC0J9G7I9/IZ2v5IlWltWoXkUFZlxylK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n8pYD/btqC0J9G7I9/IZ2v5IlWltWoXkUFZlxylK/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 51.7846%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n8pYD/btqC0J9G7I9/IZ2v5IlWltWoXkUFZlxylK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn8pYD%2FbtqC0J9G7I9%2FIZ2v5IlWltWoXkUFZlxylK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cV1OVO/btqC2tSTeZq/Oi82l250qPzlBJ9m2nNQik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cV1OVO/btqC2tSTeZq/Oi82l250qPzlBJ9m2nNQik/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 47.0526%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cV1OVO/btqC2tSTeZq/Oi82l250qPzlBJ9m2nNQik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcV1OVO%2FbtqC2tSTeZq%2FOi82l250qPzlBJ9m2nNQik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;JPA 방언으로 지정된 데이터베이스의 종류에 따라 (MySQL(좌), Oracle(우)) 같은 코드임에도 다르게 나간다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;조인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;내부조인(대괄호 생략가능)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1585540546408&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select m from Member m [inner] join m.team t&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;외부조인(대괄호 생략가능)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1585540570249&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select m from Member m left [outer] join m.team t&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;ON절 활용 조인&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;조인 대상 필터링&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;연관관계가 없는 엔티티 외부 조인 가능&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1585540891671&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 회원과 팀을 조인하면서 팀이름이 'IT사업부'인 팀만 조인

// JPQL(연관관계 O)
select m, t from Member m left join m.team t on t.name = 'IT사업부'

// SQL
select m.*, t.* from Member m left join Team on m.team_id = t.id and t.name = 'IT사업부'

// 회원의 이름과 팀의 이름이 같은 대상 외부 조인

// JPQL(연관관계 X)
select m, t from Member m left join Team t on t.name = 'IT사업부'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;서브쿼리&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1585543169541&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 나이가 평균보다 많은 회원 조회
select m from Member m where m.age = (select avg(m2.age) from Member m2)

// 한 건이라도 주문한 회원 조회
select m from Member m where (select count(o) from Order o where m = o.member) &amp;gt; 0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;JPA 표준 스펙은 WHERE절과 HAVING절에만 서브쿼리 사용가능하지만 Hibernate는 SELECT절까지 서브쿼리를 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;FROM절의 서브쿼리는 JPQL에서 불가능함.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;JPQL 타입 표현&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;문자&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;'Hello' &lt;/span&gt;
&lt;ul style=&quot;list-style-type: square;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;single quartation 안쪽에 문자열을 표현&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;'She''s'&lt;/span&gt;
&lt;ul style=&quot;list-style-type: square;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;single quartation 안쪽 문자열에 single quartation이 사용된다면 한개 더 사용해서 이스케이프 문자를 만든다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;숫자&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;10L&lt;/span&gt;
&lt;ul style=&quot;list-style-type: square;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;long형&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;10D&lt;/span&gt;
&lt;ul style=&quot;list-style-type: square;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;double형&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;10F&lt;/span&gt;
&lt;ul style=&quot;list-style-type: square;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;float형&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;ENUM&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;square&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;xyz.devyu.MemberType.Admin&lt;/span&gt;
&lt;ul style=&quot;list-style-type: square;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666;&quot;&gt;자바 패키지명을 포함해서 넣어야 한다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>JPA</category>
      <category>JPA</category>
      <author>devyu</author>
      <guid isPermaLink="true">https://pugyu.tistory.com/92</guid>
      <comments>https://pugyu.tistory.com/92#entry92comment</comments>
      <pubDate>Mon, 30 Mar 2020 02:43:14 +0900</pubDate>
    </item>
  </channel>
</rss>