<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>화투의 개발 블로그</title>
    <link>https://hsp1116.tistory.com/</link>
    <description>박현식 (화투) / 28세  / 웹개발자</description>
    <language>ko</language>
    <pubDate>Fri, 17 Apr 2026 04:49:15 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>HwaToo</managingEditor>
    <item>
      <title>규칙 2 . Builder Pattern</title>
      <link>https://hsp1116.tistory.com/65</link>
      <description>&lt;h2&gt;2장 객체의 생성과 삭제&lt;/h2&gt;
&lt;h3&gt;규칙 2. 생성자 인자가 많을 때는 Builder 패턴 적용 또한 고려하자.&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;static factory method와 constructor는 둘 다 선택적 인자가 많은 경우에 적응하기 힘들다는 공통적인 단점을 가지고 있다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;1. 점층적 생성자 패턴(telescoping constructor pattern)&lt;/h4&gt;
&lt;p&gt;선택적 인자가 10여개가 넘을 시, 보통 &lt;strong&gt;점층적 생성자 패턴(telescoping constructor pattern)&lt;/strong&gt;을 적용한다.&lt;/p&gt;&lt;p&gt;필수 인자 생성자 정의 후, 추가적으로 선택적 인자를 받는 생성자를 추가하여 해당 생성자를 호출하는 방식으로 대표적인 예는 다음과 같다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot; lang=&quot;java&quot;&gt;public class NutritionFacts{
  private final int servingSize;
  private final int servings;
  private final int calories;
  private final int fat;
  private final int sodium;
  private final int carbohydrate;
  
  public NutritionFacts(int servingSie, int servings){
    this(servingSize, servings, 0);
  }
  
  public NutritionFacts(int servingSie, int servings, int calories){
    this(servingSize, servings, calories, 0);
  }
  
  public NutritionFacts(int servingSie, int servings, int calories, int fat){
    this(servingSize, servings, calories, fat, 0);
  }
  
  public NutritionFacts(int servingSie, int servings, int calories, int fat, int sodium){
    this(servingSize, servings, calories, fat, sodium, 0);
  }
  
  public NutritionFacts(int servingSie, int servings, int calories, int fat, int sodium, int carbohydrate){
    this.servingSize = servingSize;
    this.servings = servings;
    this.calories = calories;
    this.fat = fat;
    this.sodium = sodium;
    this.carbohydrate = carbohydrate;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;del&gt;정말 그지같다.&lt;/del&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;코드만 봐도 알 수 있다싶이, 점층적 생성자 패턴은 인자수가 증가 할 수록 작성하기도, 읽기도 어려운 코드가 된다.&lt;/p&gt;&lt;p&gt;특히 코드만 봐서 해당 인자가 어떤 인자인지 알 기가 힘들다. (인자의 순서를 하나씩 세어봐야 한다.)&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;2. 자바빈 패턴(JavaBeans Pattern)&lt;/h4&gt;
&lt;p&gt;두번째 방법으로는 자바빈 규약에 따르는 클래스를 생성 한 뒤, setter 메서드로 각 값들을 설정해 주는 방법이 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot; lang=&quot;java&quot;&gt;public class NutritionFacts{
  private final int servingSize;
  private final int servings;
  private final int calories;
  private final int fat;
  private final int sodium;
  private final int carbohydrate;
  
  public NutritionFacts(){}

  //Setter Method
  public void setServingSize(int servingSize){ this.servingSize = servingSize; }
  public void setServings(int servings){ this.servings = servings; }
  public void setCalories(int calories){ this.calories = caloires; }
  public void setFat(int fat){ this.fat = fat; }
  public void setSodium(int sodium){ this.sodium = sodium; }
  public void setCarbohydrate(int carbohydrate){ this.arbohydrate = arbohydrate; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;자바빈 패턴은 점층적 생성자 패턴에 있던 문제는 없지만, 1회의 함수 호출로 객체 생성을 마칠 수 없으므로 객체 일관성이 깨질 수 있다.&lt;/p&gt;&lt;p&gt;또한 자바빈 패턴은 immutable 클래스를 만들 수 없다는 단점이 있다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;3. 빌더 패턴 (Builder Pattern)&lt;/h4&gt;
&lt;p&gt;빌더 패턴은 점층적 생성자 패턴의 안전성과 자바빈 패턴의 가독성을 결합한 대안이다.&lt;/p&gt;&lt;p&gt;객체를 생성하는 빌더 클래스(builder class)를 만들고, 이 생성자에 필수 인자를 전달하여 빌더 객채(builder object)를 만든다.&lt;/p&gt;&lt;p&gt;그 후 빌더 객체에 정의된 setter method를 호출하여 선택적 인자들을 추가하고 build 메서드를 호출하여 immutable 객체를 만든다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot; lang=&quot;java&quot;&gt;public class NutritionFacts{
  private final int servingSize;
  private final int servings;
  private final int calories;
  private final int fat;
  private final int sodium;
  private final int carbohydrate;
  
  private NutritionFacts(Builder builder){
    this.servingSize = builder.servingSize;
    this.servings = builder.servings;
    this.calories = builder.calories;
    this.fat = builder.fat;
    this.sodium = builder.sodium;
    this.carbohydrate = builder.carbohydrate;
  }
  
  //builder class
  public static class Builder {
    //필수 인자
    private final int servingsize;
    private final int servings;
    //선택적 인자(초기화)
    private final int calories = 0;
    private final int fat = 0;
    private final int sodium = 0;
    private final int carbohydrate = 0;
   
    public Builder(int servingSize, int servings){
      this.servingSize = servingSize;
      this.servings = servings;
    }
    
    public Builder calories(int calories){
      this.calories = calories;
      return this;
    }
    
    public Builder fat(int fat){
      this.fat = fat;
      return this;
    }
    
    public Builder sodium(int sodium){
      this.sodium = sodium;
      return this;
    }
    
    public Builder carbohydrate(int carbohydrate){
      this.carbohydrate = carbohydrate;
      return this;
    }
    
    public NutritionFacts build(){
      return new NutritionFacts(this);
    }
  }  
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;&lt;p&gt;해당 코드는 모든 인자가 final로 immutable한 NutritionFacts 객체이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;위에서 작성한 빌더 패턴은 객체 자신을 반환하므로 다음과 같이 chaining하여 사용 할 수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot; lang=&quot;java&quot;&gt;NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h5&gt;빌더 패턴의 장점&lt;/h5&gt;
&lt;p&gt;또한 빌더패턴을 적용하면서 얻을 수 있는 장점은 다음과 같다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;불변식(invariant)을 적용 할 수 있다.&lt;/p&gt;&lt;p&gt;build 메서드, 혹은 build가 호출 되기 전에 불변식에 위반되었는지 검사 할 수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot; lang=&quot;java&quot;&gt;public NutritionFacts build(){
  if(/*불변식 검사*/){
    throw new IllegalArgumentExcepiton();
  }
  return new NutritionFacts(this);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot; lang=&quot;java&quot;&gt;public Builder carbohydrate(int carbohydrate){
  if(/*불변식 검사*/){
    throw new IllegalArgumentExcepiton();
  }
  this.carbohydrate = carbohydrate;
  return this;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;객체를 생성 할 때 여러 개의 가변인자(varargs, ex : String…)를  인자로 받을 수 있다.&lt;/p&gt;&lt;p&gt;가변인자는 생성자 및 메서드에 하나만 사용 가능하다. 하지만 빌더 패턴을 적용하면 각 선택적 인자의 setter 메서드에 가변 인자를 적용 할 수 있다.&lt;/p&gt;&lt;p&gt;(기본적으로 메서드 시그니쳐의 마지막 인자에만 지정한다.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;빌더 패턴은 유연하다.&lt;/p&gt;&lt;p&gt;하나의 빌더 객체로 여러 객체를 만들 수 있다.&lt;/p&gt;&lt;p&gt;기존에 사용했던 빌더 객체에서 setter 메서드로 값만 바꾼 후 build 하면 다른 객체가 생성된다.&lt;/p&gt;&lt;p&gt;또한 빌더 객체는 어떤 필드의 값은 자동으로 채우도록 할 수 있다.(예 : 자동으로 증가하는 일련 번호 등.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;인자가 설정된 빌더는 훌륭한 추상적 팩토리이다.&lt;/p&gt;&lt;p&gt;클라이언트는 빌더를 다른 메서드에 넘겨서 하나 이상의 객체를 만들도록 할 수 있다.&lt;/p&gt;&lt;p&gt;다음과 같은 제네릭을 적용한 인터페이스면 어떤 객체를 만드는 빌더냐에 관계 없이 모든 빌더에 적용 할 수 있다.&lt;/p&gt;&lt;p&gt;(빌더 객체를 인자로 받는 모든 메서드에 전달 할 수 있다.)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot; lang=&quot;java&quot;&gt;public interface Builder&amp;lt;T&amp;gt; {
  public T build();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;&lt;p&gt; 빌더 객체의 인자를 제한 할 경우, 보통 한정적 와일드카드 자료형을 통해 인자의 자료형을 제안한다.&lt;/p&gt;&lt;p&gt;ex ) Tree buildTree(Builder&amp;lt;? extends Node&amp;gt; nodeBuilder){ … }&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;

&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h5&gt;빌더 패턴의 단점&lt;/h5&gt;
&lt;p&gt;객체를 생성 하려면 우선 빌더 객체를 생성해야한다는 단점이 있다.&lt;/p&gt;&lt;p&gt;실무에서는 빌더 객체 생성에 의한 오버헤드의 문제는 없겠지만, 성능이 중요한 상황에선 그렇지 않을 수 도 있다.&lt;/p&gt;&lt;p&gt;또한 점층적 생성자 패턴에 비해 만흔 코드를 요구하기 때문에 인자가 충분히 많은 상황에서 이용해야 한다.&lt;/p&gt;</description>
      <category>Effective Java/2장. 객체의 생성과 삭제</category>
      <author>HwaToo</author>
      <guid isPermaLink="true">https://hsp1116.tistory.com/65</guid>
      <comments>https://hsp1116.tistory.com/65#entry65comment</comments>
      <pubDate>Sun, 14 Jan 2018 20:25:59 +0900</pubDate>
    </item>
    <item>
      <title>규칙 1 . Static Factory Method</title>
      <link>https://hsp1116.tistory.com/64</link>
      <description>&lt;article class=&quot;markdown-body&quot;&gt;
&lt;h1&gt;Effective Java&lt;/h1&gt;
&lt;h2&gt;2장 객체의 생성과 삭제&lt;/h2&gt;
&lt;h3&gt;규칙 1.  생성자 뿐만 아니라 정적 팩터리 메서드의 사용도 고려하자.&lt;/h3&gt;
&lt;p&gt;객체를 생성할때 일반적으로 public으로 선언되어있는 생성자를 사용한다. &lt;/p&gt;
&lt;p&gt;하지만 생성자 외에 static factory method(정적 팩토리 메서드)를 사용해서 객체를 생성 할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;정적 팩토리 메서드의 장점&lt;/h4&gt;
&lt;ol start=&quot;&quot;&gt;
&lt;li&gt;&lt;p&gt;생성자와 달리 static factory method에는 &lt;strong&gt;이름이 존재한다. &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;해당 메서드가 어떤 객체를 생성하는지 알 수 있어 가독성을 높일수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;생성자와 달리 호출 될 때마다 &lt;strong&gt;새로운 객체를 생성할 필요가 없다.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이뮤터블 클래스일 경우 이미 만든 객체를 활용할 뿐만 아니라 객체를 캐시하여 재사용 하여 객체를 불필요하기 생성하는 것을 피할 수 있다.&lt;/li&gt;
&lt;li&gt;특정시점에 객체가 얼마나 존재하는지 제어할수 있다.(instance-controlled class). 이를 통해 싱글턴 패턴 클래스, 객체 생성이 불가능한 클래스 생성 등을 만들수 있다. 또한 이뮤터블 클래스일 경우 같은 객체가 존재하지 않도록 할 수 있다.&lt;/li&gt;

&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;생성자와 달리 자료형의 &lt;strong&gt;하위 자료형 객체를 반환 할 수 있다.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;반환되는 객체의 클래스를 유영하게 결정 할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;구현 세부 사항을 감출수 있으므로 간결한 API가 가능하며 이는 인터페이스 기반 프레임 워크에 적합하다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;대표적인 예 : JDK 1.5에 도입된 EnumSet -&lt;/p&gt;
&lt;p&gt;EnumSet은 public 생성자가 없으며 정적 팩토리 메서드만 가지고있다.&lt;/p&gt;
&lt;p&gt;EnumSet은 정적 팩토리 매서드로 두가지 구현체 중 하나를 반환한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;RegularEnumSet : enum 상수들이 64개 이하일경우, enum의 갯수를 long 변수 하나만 사용해 표현한다.&lt;/li&gt;
&lt;li&gt;JumboEnumSet : enum상수들이 64개 이상일 경우, enum의 갯수를 long형 배열을 사용해 표현한다.&lt;/li&gt;

&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service Provider Framework : 정적 팩토리 메서드가 작성된 시기에 반환될 구현체 클래스가 존재하지 않아도 무방하다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;대표적인 예 :  JDBC&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service Provider Framework는 세가지 핵심 컴포넌트로 구성된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Service Interface : 서비스 제공자가 구현한다. (JDBC : Connection)&lt;/li&gt;
&lt;li&gt;Provider Registration API : 구현체를 서비스에 등록하여 클라이언트가 사용 가능하도록한다. (JDBC : DriverManger.registDriver)&lt;/li&gt;
&lt;li&gt;Service Access API : 클라이언트에게 서비스 구현체를 제공한다.(DriverManger.getConnection)&lt;/li&gt;
&lt;li&gt;Service Provider Interface : 선택적이며, 서비스 제공자가 구현한다. 서비스 구현체의 객체를 생성하기 위한 인터페이스이다. 이가 없으면 자바의 리플렉션등으로 객체가 생성된다.(JDBC : Driver)&lt;/li&gt;

&lt;/ul&gt;
&lt;/li&gt;

&lt;/ul&gt;
&lt;/li&gt;

&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;형인자 자료형(parameterized type) 객체를 만들 때 편리하다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;형인자 자료형 클래스의 생성자를 호출할 때는, 문맥상 형인자가 명백하더라도 반드시 인자로 형인자를 전달해야한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot; lang=&quot;java&quot;&gt;Map&amp;lt;String, List&amp;lt;String&amp;gt;&amp;gt; m = new HashMap&amp;lt;String, List&amp;lt;String&amp;gt;&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이처럼 형인자가 늘어남에 따라 길고 복잡한 코드가 만들어진다. 하지만 정적 팩토리 메서드로 컴파일러가 형인자를 유추하도록 할 수 있다. 이를 자료형 유추(type interface)라고 부른다. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot; lang=&quot;java&quot;&gt;public static &amp;lt;K, V&amp;gt; HashMap&amp;lt;K, V&amp;gt; newInstance(){
  return new HashMap&amp;lt;K, V&amp;gt;();
}
Map&amp;lt;String, List&amp;lt;String&amp;gt;&amp;gt; m = HashMap.newInstance();
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;

&lt;/ol&gt;
&lt;blockquote&gt;&lt;p&gt;JDK 1.7 이후부터는 생성자를 이용해서도 형인자 유추가 가능하다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;정적 팩토리 메서드의 단점&lt;/h4&gt;
&lt;ol start=&quot;&quot;&gt;
&lt;li&gt;정적 팩토리 메서드만 있는 클래스는 public이나 protected로 선언된 생성자가 없으므로 하위 클래스를 만들 수 없다.&lt;/li&gt;
&lt;li&gt;정적 팩토리 메서드가 다른 정적 메서드와 확연히 구분되지 않는다.&lt;/li&gt;

&lt;/ol&gt;
&lt;h4&gt;요약&lt;/h4&gt;
&lt;p&gt;정적 팩터리 메서드와 public 생성자는 용도가 서로 다르다. 그 차이점과 장단점을 이해하고 정적 팩토리 메서드가 효과적인 경우가 많으니 무조건 public 생성자만 만드는 것은 삼가자.&lt;/p&gt;
&lt;/article&gt;</description>
      <category>Effective Java/2장. 객체의 생성과 삭제</category>
      <author>HwaToo</author>
      <guid isPermaLink="true">https://hsp1116.tistory.com/64</guid>
      <comments>https://hsp1116.tistory.com/64#entry64comment</comments>
      <pubDate>Wed, 3 Jan 2018 23:24:40 +0900</pubDate>
    </item>
    <item>
      <title>엘라스틱서치 정리</title>
      <link>https://hsp1116.tistory.com/62</link>
      <description>&lt;h1&gt;Elasticsearch&lt;/h1&gt;&lt;h2 style=&quot;margin: 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/h2&gt;&lt;h2 style=&quot;margin: 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;Elasticsearch와 RDBMS의 데이터구조 비교&lt;/h2&gt;&lt;table class=&quot;confluenceTable&quot; style=&quot;border-collapse: collapse; margin: 10px 0px 0px; overflow-x: auto; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th class=&quot;confluenceTh&quot; style=&quot;border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; text-align: left; min-width: 8px; white-space: pre-wrap; background-color: rgb(240, 240, 240); color: rgb(0, 0, 0);&quot;&gt;Elasticsearch&lt;/th&gt;&lt;th class=&quot;confluenceTh&quot; style=&quot;border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; text-align: left; min-width: 8px; white-space: pre-wrap; background-color: rgb(240, 240, 240); color: rgb(0, 0, 0);&quot;&gt;RDBMS&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;인덱스&lt;/td&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;데이터베이스&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;타입&lt;/td&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;테이블&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;도큐먼트&lt;/td&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;로우&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;confluenceTd&quot; colspan=&quot;1&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;필드&lt;/td&gt;&lt;td class=&quot;confluenceTd&quot; colspan=&quot;1&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;컬럼&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;confluenceTd&quot; colspan=&quot;1&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;매핑&lt;/td&gt;&lt;td class=&quot;confluenceTd&quot; colspan=&quot;1&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;스키마&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;span data-mce-style=&quot;color: #000000; font-size: 20.0px;&quot; style=&quot;color: rgb(0, 0, 0); font-size: 20px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;span data-mce-style=&quot;color: #000000; font-size: 20.0px;&quot; style=&quot;color: rgb(0, 0, 0); font-size: 20px;&quot;&gt;클러스터&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;엘라스틱서치의 가장 큰 시스템 단위.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;하나의 클러스터는 하나 이상의 노드로 구성.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;여러대의 서버가 하나의 클러스터로 구성할 수 있으며, 그 반대도 가능하다.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;span data-mce-style=&quot;color: #000000;&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;h2 style=&quot;margin: 30px 0px 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;&lt;span data-mce-style=&quot;color: #000000;&quot;&gt;노드&lt;/span&gt;&lt;/h2&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;데이터를 색인하고 검색을 수행하는 단위 프로세스&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;각 노드는 1개 이상의 데이터 원본과 복사본을 가지고 다른 위치에 나누어 저장한다.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;노드가 종료되거나 실행에 실패할 경우 다른 노드로 데이터를 이동한다.&lt;/p&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;마스터노드 : 클러스터 상태 관리&lt;/li&gt;&lt;li&gt;데이터노드 : 데이터/입출력, 검색 수행&lt;/li&gt;&lt;li&gt;클라이언트 노드 : 색인 및 검색을 위한 명령, 결과 전달&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;margin: 30px 0px 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;샤드와 복사본(Shard and Replica)&lt;/h2&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;샤드는 데이터 검색을 위해 구분되는 최소 단위.&lt;/li&gt;&lt;li&gt;색인된 데이터는 여러개의 샤드로 분할되어 저장된다. (분산처리)&lt;/li&gt;&lt;li&gt;기본적으로 인덱스당 5개의 샤드와 5개의 레플리카로 분리.&lt;/li&gt;&lt;li&gt;샤드와 레플리카를 설정할 때 말고 사용자가 직접 샤드에 접근할 일은 없다.&lt;/li&gt;&lt;li&gt;생성된 인덱스의 샤드 설정은 변경 불가능하다.&lt;/li&gt;&lt;/ul&gt;&lt;h2 style=&quot;margin: 30px 0px 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;&lt;span data-mce-style=&quot;color: #000000;&quot;&gt;최초 샤드 (Primary Shard)&lt;/span&gt;&lt;/h2&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;데이터가 색인되어 저장되는 공간.&lt;/li&gt;&lt;li&gt;최초 샤드에 데이터가 색인되면 동일한 수 만큼 레플리카를 생성.&lt;/li&gt;&lt;li&gt;최초 샤드가 유실되는 경우 레플리카를 최초 샤드로 승격.&lt;/li&gt;&lt;li&gt;최초 샤드와 레플리카는 서로 다른 노드에 저장한다&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;margin: 30px 0px 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;REST API&lt;/h2&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;엘라스틱서치는 기본적으로 REST API으로 데이터를 처리한다.&lt;/li&gt;&lt;li&gt;REST API를 용하기 위한 주소는 다음과 같다.&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;http://host:port/{INDEX}/{TYPE}/{DOCUMENTID}&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 style=&quot;margin: 30px 0px 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;&lt;span data-mce-style=&quot;color: #000000;&quot;&gt;검색&lt;/span&gt;&lt;/h2&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;검색 기능은 query 명령어를 이용해 수행한다.&lt;/li&gt;&lt;li&gt;타입 및 인덱스의 범위로 질의가 가능하다.&lt;/li&gt;&lt;li&gt;여러개의 인덱스를 묶어서 멀티 인덱스의 범위로 질의 또한 가능하다.&lt;/li&gt;&lt;li&gt;URI를 통한 검색 시&amp;nbsp;&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;&lt;a href=&quot;http://hostport/&quot; data-mce-href=&quot;http://hostport/&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;http://host:port/{INDEX}/{TYPE}/&lt;/a&gt;_search?q=&lt;/li&gt;&lt;li&gt;q 매개변수에 값을 입력한다.&lt;/li&gt;&lt;li&gt;hit : 검색 결과, took : 실행 소요 시간&lt;/li&gt;&lt;li&gt;Multi tanancy&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;&lt;a href=&quot;http://hostport/&quot; data-mce-href=&quot;http://hostport/&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;http://host:port/{INDEX1},&lt;/a&gt;&lt;a href=&quot;http://hostport/&quot; data-mce-href=&quot;http://hostport/&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;{INDEX2}&lt;/a&gt;&lt;a href=&quot;http://hostport/&quot; data-mce-href=&quot;http://hostport/&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;/&lt;/a&gt;_search?q=&lt;/li&gt;&lt;li&gt;여러 인덱스를 동시에 검색한다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;REQUEST BODY 검색&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;JSON을 통해 질의한다.&lt;/li&gt;&lt;li&gt;QueryDSL 사용&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 style=&quot;margin: 30px 0px 0px; font-size: 24px; font-weight: normal; line-height: 1.25; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;SEARCH TYPE&lt;/h1&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;검색을 수행하는 방법을 지정.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;query_then_fetch : 전체 샤드의 검색이 모두 수행된 후 결과 출력. 전체 취합된 결과를 size 매개변수에서 지정한 수만큼 출력.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;query_and_fetch : 샤드별로 검색되는대로 결과 출력. size * 샤드의 갯수만큼 출력.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;dfs_query_then_fetch : 검색방식은 query_then_fetch와 같으나 정확한 스코어링을 위해 검색어들을 사전 처리.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;dfs_query_and_fetch : 검색방식은 query_and_fetch와 같으나 정확한 스코어링을 위해 검색어들을 사전 처리한다.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;count : 검색된 도큐먼트를 배제하고 전체 hits수만 출력.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;scan : 검색 결과를 바로 보여주지 않고 저장했다가&amp;nbsp;&lt;em&gt;_scroll_ id를&amp;nbsp;&lt;/em&gt;사용해 나중에 결과 출력&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;margin: 30px 0px 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;쿼리와 필터&lt;/h2&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;Elasticsearch의 검색 방법은 크게 쿼리와 필터로 나뉜다.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;쿼리와 필터는 모두 QueryDSL로 작성한다.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;table class=&quot;confluenceTable&quot; style=&quot;border-collapse: collapse; margin: 10px 0px 0px; overflow-x: auto; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th class=&quot;confluenceTh&quot; style=&quot;border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; text-align: left; min-width: 8px; white-space: pre-wrap; background-color: rgb(240, 240, 240); color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/th&gt;&lt;th class=&quot;confluenceTh&quot; style=&quot;border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; text-align: left; min-width: 8px; white-space: pre-wrap; background-color: rgb(240, 240, 240); color: rgb(0, 0, 0);&quot;&gt;쿼리(Query)&lt;/th&gt;&lt;th class=&quot;confluenceTh&quot; style=&quot;border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; text-align: left; min-width: 8px; white-space: pre-wrap; background-color: rgb(240, 240, 240); color: rgb(0, 0, 0);&quot;&gt;필터(Filter)&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;검색 대상(일반적)&lt;/td&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;Full Text(전문 검색)&lt;/td&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;Bianry(Y/N)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;점수 계산&lt;/td&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;O&lt;/td&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;X&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;캐싱&lt;/td&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;X&lt;/td&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;O&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;응답속도(상대적)&lt;/td&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;느림&lt;/td&gt;&lt;td class=&quot;confluenceTd&quot; style=&quot;white-space: pre-wrap; border: 1px solid rgb(221, 221, 221); padding: 7px 10px; vertical-align: top; min-width: 8px;&quot;&gt;빠름&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;margin: 30px 0px 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;형태소 분석 과정&lt;/h2&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;대문자는 모두 소문자로 변환한다.&lt;/li&gt;&lt;li&gt;중복된는 단어는 제거한다.&lt;/li&gt;&lt;li&gt;분석 과정을 거치고 거장도니 토큰을 term이라고 한다.&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;img class=&quot;confluence-embedded-image&quot; title=&quot;팀_El Dorado (Payment, 간편결제) &gt; Elasticsearch &gt; image2017-11-29 19:16:36.png&quot; width=&quot;600&quot; src=&quot;https://wiki.coupang.net/download/attachments/87781095/image2017-11-29%2019%3A16%3A36.png?version=1&amp;amp;modificationDate=1511950597000&amp;amp;api=v2&quot; data-image-src=&quot;/download/attachments/87781095/image2017-11-29%2019%3A16%3A36.png?version=1&amp;amp;modificationDate=1511950597000&amp;amp;api=v2&quot; data-unresolved-comment-count=&quot;0&quot; data-linked-resource-id=&quot;87781098&quot; data-linked-resource-version=&quot;1&quot; data-linked-resource-type=&quot;attachment&quot; data-linked-resource-default-alias=&quot;image2017-11-29 19:16:36.png&quot; data-base-url=&quot;https://wiki.coupang.net&quot; data-linked-resource-content-type=&quot;image/png&quot; data-linked-resource-container-id=&quot;87781095&quot; data-linked-resource-container-version=&quot;6&quot; data-location=&quot;팀_El Dorado (Payment, 간편결제) &gt; Elasticsearch &gt; image2017-11-29 19:16:36.png&quot; data-image-height=&quot;374&quot; data-image-width=&quot;1190&quot; data-mce-src=&quot;https://wiki.coupang.net/download/attachments/87781095/image2017-11-29%2019%3A16%3A36.png?version=1&amp;amp;modificationDate=1511950597000&amp;amp;api=v2&quot; style=&quot;cursor: move; max-width: none; margin-left: 2px; margin-right: 2px; vertical-align: text-bottom;&quot;&gt;&lt;/p&gt;&lt;h1 style=&quot;margin: 30px 0px 0px; font-size: 24px; font-weight: normal; line-height: 1.25; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;Query&lt;/h1&gt;&lt;h2 style=&quot;margin: 10px 0px 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;term 쿼리&lt;/h2&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;term 옵션을 사용.&lt;/li&gt;&lt;li&gt;질의문이 저장된 term과 정확히 일치하는 내용을 찾는다.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;font color=&quot;#333333&quot; face=&quot;Arial, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;&lt;table class=&quot;txc-table&quot; width=&quot;864&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; style=&quot;border:none;border-collapse:collapse;;font-family:&quot; 맑은=&quot;&quot; 고딕&quot;,=&quot;&quot; sans-serif;font-size:13px&quot;=&quot;&quot;&gt;&lt;table class=&quot;txc-table&quot; width=&quot;864&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; style=&quot;border:none;border-collapse:collapse;;font-family:&quot; 맑은=&quot;&quot; 고딕&quot;,=&quot;&quot; sans-serif;font-size:13px&quot;=&quot;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;width:864;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-top:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;




&lt;/p&gt;&lt;style type=&quot;text/css&quot;&gt;
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px 'Helvetica Neue'; color: #454545}
span.s1 {font: 12.0px '.Apple SD Gothic NeoI'}
span.Apple-tab-span {white-space:pre}
&lt;/style&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;


&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;{&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&quot;query&quot; : {&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&quot;term&quot; : {&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&quot;message&quot; : &quot;&lt;span class=&quot;s1&quot;&gt;취소&lt;/span&gt;&quot;&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;}&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;}&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;&lt;span style=&quot;color: rgb(69, 69, 69); font-family: &amp;quot;Helvetica Neue&amp;quot;; font-size: 12px;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;tbody&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;margin: 30px 0px 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;terms 쿼리&lt;/h2&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;terms 옵션으로 2개 이상의 텀을 같이 검색한다.&lt;/li&gt;&lt;li&gt;terms 쿼리의 값은 항상 배열 형식으로 입력한다.&lt;/li&gt;&lt;li&gt;minimum_shuld_match 옵션으로 최소 일치 수도 지정 가능하다.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;font color=&quot;#333333&quot; face=&quot;Arial, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;&lt;table class=&quot;txc-table&quot; width=&quot;864&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; style=&quot;border:none;border-collapse:collapse;;font-family:&quot; 맑은=&quot;&quot; 고딕&quot;,=&quot;&quot; sans-serif;font-size:13px&quot;=&quot;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;width:864;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-top:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;




&lt;/p&gt;&lt;style type=&quot;text/css&quot;&gt;
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px 'Helvetica Neue'; color: #454545}
span.s1 {font: 12.0px '.Apple SD Gothic NeoI'}
span.Apple-tab-span {white-space:pre}
&lt;/style&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;


&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;{&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&quot;query&quot; : {&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&quot;terms&quot; : {&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&quot;message&quot; : [&quot;&lt;span class=&quot;s1&quot;&gt;인증&lt;/span&gt;&quot;, &quot;&lt;span class=&quot;s1&quot;&gt;취소&lt;/span&gt;&quot;],&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&quot;minimum_shuld_match&quot; : 2&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;}&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;}&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;&lt;span style=&quot;color: rgb(69, 69, 69); font-family: &amp;quot;Helvetica Neue&amp;quot;; font-size: 12px;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;span style=&quot;font-size: 20px; color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;match 쿼리, mutlti match 쿼리&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;match 옵션을 사용한다.&lt;/li&gt;&lt;li&gt;질의문 또한 형태소 분석을 거친 뒤 사용한다.&lt;/li&gt;&lt;li&gt;multi_match옵션을 사용하면 여러 필드에서 검색 가능하다.&lt;/li&gt;&lt;li&gt;analyzer 옵션으로 원하는 형태소 분석 적용을 가능하다.&lt;/li&gt;&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;&lt;strong&gt;한글은 엘라스틱서치에서 기본 지원하지 않아 은전한닢(&lt;a href=&quot;http://eunjeon.blogspot.kr/&quot; data-mce-href=&quot;http://eunjeon.blogspot.kr/&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;http://eunjeon.blogspot.kr&lt;/a&gt;)이라는 커스텀 형태소 분석기를 이용한다.&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;&lt;font color=&quot;#333333&quot; face=&quot;Arial, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 14px;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;&lt;table class=&quot;txc-table&quot; width=&quot;864&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; style=&quot;border:none;border-collapse:collapse;;font-family:&quot; 맑은=&quot;&quot; 고딕&quot;,=&quot;&quot; sans-serif;font-size:13px&quot;=&quot;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;width:864;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-top:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;




&lt;/p&gt;&lt;style type=&quot;text/css&quot;&gt;
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px 'Helvetica Neue'; color: #454545}
span.s1 {font: 12.0px '.Apple SD Gothic NeoI'}
span.Apple-tab-span {white-space:pre}
&lt;/style&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;


&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;{&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&quot;query&quot; : {&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&quot;match&quot; : {&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&quot;message&quot; : {&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&quot;query&quot; : &quot;&lt;span class=&quot;s1&quot;&gt;인증을&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;취소합니다&lt;/span&gt;.&quot;&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;}&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;}&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p class=&quot;p1&quot; style=&quot;margin-left: 2em;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot;&gt;	&lt;/span&gt;}&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;
&lt;/p&gt;&lt;p style=&quot;margin-left: 2em;&quot;&gt;&lt;span style=&quot;color: rgb(69, 69, 69); font-family: &amp;quot;Helvetica Neue&amp;quot;; font-size: 12px;&quot;&gt;}&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;span style=&quot;font-size: 20px; color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;span style=&quot;font-size: 20px; color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;span style=&quot;font-size: 20px; color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;bool 쿼리&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;내부의 질의로 다른 질의를 포함시켜 사용한다.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;쿼리를 조건문인 bool 조합으로 적용하여 최종 검색 결과를 나타낸다&lt;/p&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;must : AND 조건&lt;/li&gt;&lt;li&gt;must_not : NOT 조건&lt;/li&gt;&lt;li&gt;shuld : 해당할 필요는 없으니 해당 될 경우 더 높은 점수를 가진다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 style=&quot;margin: 30px 0px 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;fuzzy 쿼리&amp;nbsp;&lt;/h2&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;편집거리 알고리즘(르벤슈타인 알고리즘)을 기반으로 유사 단어 검색 지원.&lt;/li&gt;&lt;li&gt;숫자, 날짜 형식을 대상으로 범위 검색으로 응용 가능.&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1 style=&quot;margin: 30px 0px 0px; font-size: 24px; font-weight: normal; line-height: 1.25; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;Filter&lt;/h1&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;스코어를 계산하지 않아 쿼리에 비해 월등히 빠름.&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;결과가 메모리에 캐싱됨(_cache 옵션으로 캐싱 여부 설정 가능)&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;margin: 30px 0px 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;&lt;strong&gt;은전한닢 (한글 형태소 분석기)&lt;/strong&gt;&lt;/h2&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;strong&gt;&lt;a href=&quot;http://eunjeon.blogspot.kr/&quot; data-mce-href=&quot;http://eunjeon.blogspot.kr/&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;http://eunjeon.blogspot.kr/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;품사태그표&lt;strong&gt;&amp;nbsp;:&amp;nbsp;&lt;a href=&quot;https://docs.google.com/spreadsheets/d/1-9blXKjtjeKZqsf4NzHeYJCrr49-nXeRF6D80udfcwY/edit#gid=589544265&quot; data-mce-href=&quot;https://docs.google.com/spreadsheets/d/1-9blXKjtjeKZqsf4NzHeYJCrr49-nXeRF6D80udfcwY/edit#gid=589544265&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;https://docs.google.com/spreadsheets/d/1-9blXKjtjeKZqsf4NzHeYJCrr49-nXeRF6D80udfcwY/edit#gid=589544265&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;margin: 30px 0px 0px; font-size: 20px; font-weight: normal; line-height: 1.5; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;&lt;strong&gt;엘라스틱서치 점수 측정 방법&lt;/strong&gt;&lt;/h2&gt;&lt;ul data-mce-style=&quot;margin-left: 30.0px;&quot; style=&quot;margin: 10px 0px 0px 30px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;Term frequency: 문서(필드) 안에 term이 자주 출현할수록 고득점&lt;/li&gt;&lt;li&gt;Inverse document frequency: 색인된 모든 문서(필드)에 term이 적게 존재할수록 고득점&lt;/li&gt;&lt;li&gt;Length norm: 문서(필드)가 짧을수록 고득점&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;strong&gt;&lt;a href=&quot;http://www.popit.kr/bm25-elasticsearch-5-0%EC%97%90%EC%84%9C-%EA%B2%80%EC%83%89%ED%95%98%EB%8A%94-%EC%83%88%EB%A1%9C%EC%9A%B4-%EB%B0%A9%EB%B2%95/&quot; data-mce-href=&quot;http://www.popit.kr/bm25-elasticsearch-5-0%EC%97%90%EC%84%9C-%EA%B2%80%EC%83%89%ED%95%98%EB%8A%94-%EC%83%88%EB%A1%9C%EC%9A%B4-%EB%B0%A9%EB%B2%95/&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;http://www.popit.kr/bm25-elasticsearch-5-0%EC%97%90%EC%84%9C-%EA%B2%80%EC%83%89%ED%95%98%EB%8A%94-%EC%83%88%EB%A1%9C%EC%9A%B4-%EB%B0%A9%EB%B2%95/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;a href=&quot;https://www.slideshare.net/seunghyuneom/elastic-search-52724188&quot; data-mce-href=&quot;https://www.slideshare.net/seunghyuneom/elastic-search-52724188&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;https://www.slideshare.net/seunghyuneom/elastic-search-52724188&lt;/a&gt;&lt;/p&gt;</description>
      <author>HwaToo</author>
      <guid isPermaLink="true">https://hsp1116.tistory.com/62</guid>
      <comments>https://hsp1116.tistory.com/62#entry62comment</comments>
      <pubDate>Wed, 13 Dec 2017 14:15:52 +0900</pubDate>
    </item>
    <item>
      <title>Deview 2017 1일차 정리</title>
      <link>https://hsp1116.tistory.com/61</link>
      <description>&lt;h1 style=&quot;margin: 0px; font-size: 24px; font-weight: normal; line-height: 1.25; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;책 읽어주는 딥러닝&lt;/h1&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;a href=&quot;https://www.slideshare.net/carpedm20/deview-2017-80824162&quot; data-mce-href=&quot;https://www.slideshare.net/carpedm20/deview-2017-80824162&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;https://www.slideshare.net/carpedm20/deview-2017-80824162&lt;/a&gt;&lt;/p&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;Data&lt;br /&gt;&lt;ol style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;&amp;nbsp;한국어 음성 데이터는 공개된 데이터가 없어서 직접 만들어야 한다.&lt;/li&gt;&lt;li&gt;Google Speech API, Text Similarity를 통해 자동화&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;Model : Tacotron, Deep voice 2&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;Tacotron&lt;ol style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;Encoder -&lt;ol style=&quot;margin: 0px; list-style-type: lower-alpha;&quot;&gt;&lt;li&gt;Character Embeddings : 해당 텍스트를 가장 잘 나타내는 숫자를 생성&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;Decoder -&lt;ol style=&quot;margin: 0px; list-style-type: lower-alpha;&quot;&gt;&lt;li&gt;음성을 생성 할 수 있는 스팩트로그램을 생성&lt;/li&gt;&lt;li&gt;스팩트로그램 : 음성이 되기 직전의 숫자&lt;/li&gt;&lt;li&gt;Attention&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;Vocoder - 스팩트로그램을 음성으로 변환&lt;ol style=&quot;margin: 0px; list-style-type: lower-alpha;&quot;&gt;&lt;li&gt;Griffin-Lim : 스팩트로그램을 음성으로 만들어주는 알고리즘&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;Attention -&lt;ol style=&quot;margin: 0px; list-style-type: lower-alpha;&quot;&gt;&lt;li data-mce-style=&quot;list-style-type: none; background-image: none;&quot; style=&quot;list-style-type: none; background-image: none;&quot;&gt;&lt;ol style=&quot;margin: 0px; list-style-type: lower-roman;&quot;&gt;&lt;li&gt;텍스트의 어디에 집중할 것인가를 계산,&lt;/li&gt;&lt;li&gt;스팩트그램을 만드는 RNN에 Atteintion을 전달&lt;/li&gt;&lt;li&gt;Attention의 중요성 :일반화&lt;/li&gt;&lt;li&gt;&amp;nbsp;학습하지 않았던 문장도 얼마나 잘 말할 수 있는가?&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p data-mce-style=&quot;margin-left: 1.125in;&quot; style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 1.125in; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;Tacotron : Enbedding, Bidirectinal RNN&lt;/p&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li data-mce-style=&quot;list-style-type: none; background-image: none;&quot; style=&quot;list-style-type: none; background-image: none;&quot;&gt;&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;Deep Voice 2&lt;/li&gt;&lt;/ul&gt;&lt;ol data-mce-style=&quot;margin-left: 0.375in;&quot; style=&quot;margin: 0px 0px 0px 0.375in;&quot;&gt;&lt;li&gt;Multi Speaker Tacotron : 여러 목소리를 트레이닝 한다.&lt;/li&gt;&lt;li&gt;Speaker Embedding&lt;/li&gt;&lt;ol data-mce-style=&quot;margin-left: 0.375in;&quot; style=&quot;margin: 0px 0px 0px 0.375in; list-style-type: lower-alpha;&quot;&gt;&lt;li&gt;캐릭터 임베딩 뿐만 아니라 발화자를 잘 나타내는 숫자를 생성&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Multi Speaker Attention&lt;/li&gt;&lt;ol data-mce-style=&quot;margin-left: 0.375in;&quot; style=&quot;margin: 0px 0px 0px 0.375in; list-style-type: lower-alpha;&quot;&gt;&lt;li&gt;어텐션을 임의의 어텐션으로 교체하여 커스터마이징 할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;Code&amp;nbsp;&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;&lt;span data-mce-style=&quot;color: #3b3835;&quot; style=&quot;color: rgb(59, 56, 53);&quot;&gt;&lt;a href=&quot;https://github.com/devsisters/multi-speaker-tacotron-tensorflow&quot; data-mce-href=&quot;https://github.com/devsisters/multi-speaker-tacotron-tensorflow&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;https://github.com/devsisters/multi-speaker-tacotron-tensorflow&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1 style=&quot;margin: 30px 0px 0px; font-size: 24px; font-weight: normal; line-height: 1.25; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;그런&amp;nbsp;REST API로 괜찮은가&lt;/h1&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;a href=&quot;http://slides.com/eungjun/rest#/&quot; data-mce-href=&quot;http://slides.com/eungjun/rest#/&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;http://slides.com/eungjun/rest#/&lt;/a&gt;&lt;/p&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;2000년에 REST에 대해 논문을 발표한&amp;nbsp;Roy T. Fielding가 현재 대부분의 REST API는 제약 조건을 따르지 않는다고 한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;REST API :&amp;nbsp;REST 아키텍쳐 스타일을 따르는 API&lt;br /&gt;&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;REST를 구성하는 스타일&amp;nbsp;&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;client-server&lt;/li&gt;&lt;li&gt;stateless&lt;/li&gt;&lt;li&gt;cache&lt;/li&gt;&lt;li&gt;&lt;strong&gt;uniform interface&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;layered system&lt;/li&gt;&lt;li&gt;code-on-demand (optional)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;REST API의 제약 조건은 현재 http를 통해서 대부분 만족한다.&amp;nbsp;다만&amp;nbsp;Uniform interface는 만족하지 못하는 경우가 많다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;uniform interface중에서 특히&amp;nbsp;&lt;span data-mce-style=&quot;color: #000000;&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;strong&gt;Self-descriptive&lt;/strong&gt;&lt;span data-mce-style=&quot;color: #000000;&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;와&amp;nbsp;&lt;/span&gt;&lt;span data-mce-style=&quot;color: #000000;&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;strong&gt;HATEOAS&lt;/strong&gt;&lt;/span&gt;&lt;span data-mce-style=&quot;color: #000000;&quot; style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 잘 만족하지 못한다.&lt;/span&gt;&lt;br /&gt;&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;Self-descriptive - 메시지는 스스로에 대해 명세할 수 있어야한다. (헤더 / 미디터타입 등)&lt;/li&gt;&lt;li&gt;HATEOAS - 애플리케이션의 상태는 hyperlink에 의헤 명세되어야한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;독립적 진화&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;서버와 클라이언트가 각각 독립적으로 진화한다&lt;/li&gt;&lt;li&gt;서버의 기능이 변경되어도 클라이언트는 업데이트 할 필요가 없다.&lt;/li&gt;&lt;li&gt;대표적인 예시 : 웹브라우저&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;즉 REST API란 하이퍼텍스트를 포함한 self-descriptive한 메시지의 uniform interface를 통해 리소스에 접근하는 API.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Self-descriptive를 지키는 방법&lt;br /&gt;1. 미디어타입 정의&lt;br /&gt;2. Profile&lt;/li&gt;&lt;/ul&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;HATEOAS&lt;br /&gt;1. data로 링크 등 다음 상태를 전달한다.&lt;br /&gt;2. HTTP 헤더를 통해 상태를 전달한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 class=&quot;notranslate slideshow-title-text&quot; style=&quot;margin: 30px 0px 0px; font-size: 24px; font-weight: normal; line-height: 1.25; border-bottom-color: rgb(46, 61, 84); font-family: Arial, sans-serif;&quot;&gt;&lt;span class=&quot;j-title-breadcrumb&quot;&gt;오픈소스 데이터베이스, 은행 서비스에 첫발을 내밀다.&lt;/span&gt;&lt;/h1&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;span class=&quot;j-title-breadcrumb&quot;&gt;&lt;a href=&quot;https://www.slideshare.net/deview/135-80845610&quot; data-mce-href=&quot;https://www.slideshare.net/deview/135-80845610&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;https://www.slideshare.net/deview/135-80845610&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;MySQL의 Replication을 통한 데이터 이중화&amp;nbsp;&lt;br /&gt;&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;Async Replication&amp;nbsp;&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;master의 데이터를 async로 slave에 replication한다. (mysql의 replication은 async로 동작한다.)&lt;/li&gt;&lt;li&gt;비동기 replication 으로 master 장애시 데이터 유실 위험이 있다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Lossless Replication&amp;nbsp;&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;slave 어딘가에 반드시 변경 이력이 남아있다.&lt;/li&gt;&lt;li&gt;Binary log를 전 slave에 전송, 단 하나의 slave에서라도 ack가 온다면 storage commit.&amp;nbsp;&lt;/li&gt;&lt;li&gt;slave중 최소 하나는 로그를 가지고있다&lt;/li&gt;&lt;li&gt;master 장애 시 slave중 어딘가에 있을 로그를 통해 데이터를 복구한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;MHA (Master High Availability)&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;30초 이내로 데이터 유실 없이 복구&lt;/li&gt;&lt;li&gt;3초마다 DB 헬스체크, 3회 실패시 장애 인지후 페일오버.&lt;/li&gt;&lt;li&gt;Lossless Replication을 통한 relay log로 데이터 복구.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul style=&quot;margin: 10px 0px 0px; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;li&gt;Domain Failover&amp;nbsp;&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;VIP failover가 아닌 Domain Failover를 채택.&lt;/li&gt;&lt;li&gt;서비스 도메인(master) 장애시 slave로 DNS를 설정하여 장애 대응.&lt;/li&gt;&lt;li&gt;서비스 도메인의 TTL은 0로 설정한다.&lt;/li&gt;&lt;li&gt;DNS는 캐싱하지 않는다.&lt;/li&gt;&lt;li&gt;서비스는 커넥션풀로 동작한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Scale-out&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;데이터 특성에 따라 파티셔닝.&lt;/li&gt;&lt;li&gt;static : 데이터 변경이 거의 없는 static 데이터는 캐시를 이용한다.&lt;/li&gt;&lt;li&gt;dynamic, historical : 변경이 잦은 사용자 데이터 혹은 로그 데이터는 DB를 통해 확장한다.&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;SERVICE : innoDB only, Range Partitoning한다.&lt;/li&gt;&lt;li&gt;ARCHIVE : 장기보관 데이터, tokuDB에&amp;nbsp;&amp;nbsp;Range Partitoning한다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;tokuDB ? :&amp;nbsp;&lt;a href=&quot;http://gywn.net/2014/05/fractal-index-in-tokudb/&quot; data-mce-href=&quot;http://gywn.net/2014/05/fractal-index-in-tokudb/&quot; style=&quot;color: rgb(50, 108, 166) !important;&quot;&gt;http://gywn.net/2014/05/fractal-index-in-tokudb/&lt;/a&gt;&lt;ul style=&quot;margin: 0px;&quot;&gt;&lt;li&gt;Fractal Index : 피벗에 버퍼를 두어 IOPS를 줄임.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;span class=&quot;j-title-breadcrumb&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;span class=&quot;j-title-breadcrumb&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 10px; margin-right: 0px; margin-left: 0px; word-wrap: break-word; color: rgb(51, 51, 51); font-family: Arial, sans-serif; font-size: 14px;&quot;&gt;&lt;span class=&quot;j-title-breadcrumb&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>deview</category>
      <category>Deview 2017</category>
      <author>HwaToo</author>
      <guid isPermaLink="true">https://hsp1116.tistory.com/61</guid>
      <comments>https://hsp1116.tistory.com/61#entry61comment</comments>
      <pubDate>Wed, 18 Oct 2017 15:43:18 +0900</pubDate>
    </item>
    <item>
      <title>Java 8 - 람다 표현식</title>
      <link>https://hsp1116.tistory.com/59</link>
      <description>&lt;p&gt;





&lt;!--StartFragment--&gt;



&lt;!--EndFragment--&gt;&lt;/p&gt;&lt;div style=&quot;direction:ltr;border-width:100%&quot;&gt;

&lt;div style=&quot;direction:ltr;margin-top:0in;margin-left:0in;width:7.4812in&quot;&gt;

&lt;div style=&quot;direction:ltr;margin-top:0in;margin-left:0in;width:7.4812in&quot;&gt;

&lt;p style=&quot;margin-top: 0in; margin-right: 0in; margin-bottom: 0in; font-family: &amp;quot;Malgun Gothic&amp;quot;; font-size: 11pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 0in; margin-right: 0in; margin-bottom: 0in; font-family: &amp;quot;Malgun Gothic&amp;quot;; font-size: 11pt;&quot;&gt;&lt;b style=&quot;font-size: 11pt;&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;람다 표현식이란?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot;&gt;&lt;span lang=&quot;ko-KR&quot;&gt;자바 &lt;/span&gt;&lt;span lang=&quot;en-US&quot;&gt;8에 추가된 함수형 프로그래밍 요소&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;객체지향이
객체의 필드에 데이터를 저장하고 그를 다루는데에 반해,&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;함수형
프로그래밍은 선언적이어서 statement보다 선언, 혹은 표현식을 사용한다.&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot;&gt;&lt;span lang=&quot;ko-KR&quot;&gt;자바&lt;/span&gt;&lt;span lang=&quot;en-US&quot;&gt;8의 람다식은 다음과 같은 형태를 가진다&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot;&gt;&lt;span lang=&quot;en-US&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;parameters -&amp;gt; expression body&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;ex ) Comparator comparator = (a, b) -&amp;gt; a.compareTo(b)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin-top:3pt;margin-bottom:11pt;font-family:Georgia&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-top:3pt;margin-bottom:11pt;font-family:Georgia&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;람다 표현식의 특징&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;ol style=&quot;list-style-type: decimal;&quot;&gt;&lt;li&gt;&lt;p style=&quot;margin-top: 0in; margin-right: 0in; margin-bottom: 0in; font-family: &amp;quot;Malgun Gothic&amp;quot;; font-size: 11pt;&quot; lang=&quot;en-US&quot;&gt;타입 선언이 선택적이다 .&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;margin-top: 0in; margin-right: 0in; margin-bottom: 0in; font-family: &amp;quot;Malgun Gothic&amp;quot;; font-size: 11pt;&quot; lang=&quot;en-US&quot;&gt;싱글 파라미터의 경우 괄호가 필요 없다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;margin-top: 0in; margin-right: 0in; margin-bottom: 0in; font-family: &amp;quot;Malgun Gothic&amp;quot;; font-size: 11pt;&quot; lang=&quot;en-US&quot;&gt;중괄호 선택 : 한문장일 경우 중괄호가 필요 없다&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;margin-top: 0in; margin-right: 0in; margin-bottom: 0in; font-family: &amp;quot;Malgun Gothic&amp;quot;; font-size: 11pt;&quot; lang=&quot;en-US&quot;&gt;return 키워드 선택 : 한문장일 경우 생략 가능하다, 다만&amp;nbsp;중괄호를 포함한 경우 무조건 return 포함해야한다.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;람다식을
이용하려면 오버라이드 할 메서드가 포함된 함수형 인터페이스가 필요하다.&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;함수형 인터페이스는 함수를 하나만 가지는 인터페이스에,&amp;nbsp;함수형 인터페이스&amp;nbsp;어노테이션(@FunctionalInterface)를 붙여 명시한다.&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;자바
API에 내장된 대표적인 함수형 인터페이스로는 Runable이나 Comparator가 있다.&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;Java 8 이전 방식과 람다 표현식&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;b&gt;1. 클래스 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;&lt;span style=&quot;color:#fbde2d&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;MyRunnable&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;implements&lt;/span&gt; &lt;span style=&quot;color:#ff6400;font-style:italic&quot;&gt;Runnable&lt;/span&gt; {
    &lt;span style=&quot;color:#fbde2d&quot;&gt;@Override&lt;/span&gt;
    &lt;span style=&quot;color:#fbde2d&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;run&lt;/span&gt;() {
        &lt;span style=&quot;color:#fbde2d&quot;&gt;System&lt;/span&gt;&lt;span style=&quot;color:#fbde2d&quot;&gt;.&lt;/span&gt;out&lt;span style=&quot;color:#fbde2d&quot;&gt;.&lt;/span&gt;println(&lt;span style=&quot;color:#61ce3c&quot;&gt;&quot;I have implemented Runnable&quot;&lt;/span&gt;);
    }
 
    &lt;span style=&quot;color:#fbde2d&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;main&lt;/span&gt;(&lt;span style=&quot;color:#fbde2d&quot;&gt;String&lt;/span&gt; args[]) {
        &lt;span style=&quot;color:#fbde2d&quot;&gt;MyRunnable&lt;/span&gt; runnable &lt;span style=&quot;color:#fbde2d&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;MyRunnable&lt;/span&gt;();
        runnable&lt;span style=&quot;color:#fbde2d&quot;&gt;.&lt;/span&gt;run();
    }
}
&lt;/pre&gt;&lt;b&gt;2. 익명 클래스&lt;/b&gt;&lt;p&gt;&lt;/p&gt;
&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;&lt;span style=&quot;color:#fbde2d&quot;&gt;Runnable&lt;/span&gt; runnable = &lt;span style=&quot;color:#fbde2d&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;Runnable&lt;/span&gt;() {
  @&lt;span style=&quot;color:#fbde2d&quot;&gt;Override&lt;/span&gt;
  &lt;span style=&quot;color:#fbde2d&quot;&gt;public &lt;/span&gt;&lt;span style=&quot;color:#fbde2d&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;run&lt;/span&gt;() {
    &lt;span style=&quot;color:#fbde2d&quot;&gt;System&lt;/span&gt;.&lt;span style=&quot;color:#fbde2d&quot;&gt;out&lt;/span&gt;.println(&lt;span style=&quot;color:#61ce3c&quot;&gt;&quot;I have implemented Runnable&quot;&lt;/span&gt;);
  }
};
runnable.run();
&lt;/pre&gt;
&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;b&gt;3.&amp;nbsp;람다식
사용&lt;/b&gt;&lt;/p&gt;
&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;&lt;span style=&quot;color:#d8fa3c&quot;&gt;Runnable&lt;/span&gt; runnable &lt;span style=&quot;color:#fbde2d&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#d8fa3c&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#d8fa3c&quot;&gt;System&lt;/span&gt;&lt;span style=&quot;color:#fbde2d&quot;&gt;.&lt;/span&gt;out&lt;span style=&quot;color:#fbde2d&quot;&gt;.&lt;/span&gt;println(&lt;span style=&quot;color:#61ce3c&quot;&gt;&quot;I have implemented Runnable&quot;&lt;/span&gt;);
runnable&lt;span style=&quot;color:#fbde2d&quot;&gt;.&lt;/span&gt;run&lt;span style=&quot;color:#d8fa3c&quot;&gt;()&lt;/span&gt;;
&lt;/pre&gt;
&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;함수형
인터페이스&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;람다를
사용하기 위해선 추상메서드를 하나만 가지는 함수형 인터페이스가 필요하다.&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;함수형
메서드의 추상 메서드 시그너처를 함수 디스크립터라고 한다.&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;자바8에는
java.util.function에 Predicate, Consumer, Function 등, 그 외 여러 인터페이스가 이미 구현되어있다.&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;대표적인
함수형 인터페이스&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;div style=&quot;direction:ltr&quot;&gt;

&lt;br /&gt;&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; valign=&quot;top&quot; style=&quot;direction:ltr;
 border-collapse:collapse;border-style:solid;border-color:#A3A3A3;border-width:
 1pt&quot; title=&quot;&quot; summary=&quot;&quot;&gt;
 &lt;tbody&gt;&lt;tr&gt;
  &lt;td style=&quot;border-style: solid; border-color: rgb(163, 163, 163); border-width: 1pt; vertical-align: top; width: 1.5638in; padding: 2pt 3pt; height: 22px; background-color: rgb(189, 189, 189);&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;b&gt;함수형 인터페이스&lt;/b&gt;&lt;/p&gt;
  &lt;/td&gt;
  &lt;td style=&quot;border-style: solid; border-color: rgb(163, 163, 163); border-width: 1pt; vertical-align: top; width: 1.2993in; padding: 2pt 3pt; height: 22px; background-color: rgb(189, 189, 189);&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;b&gt;함수 디스크립터&lt;/b&gt;&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.5638in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;Predicate&amp;lt;T&amp;gt;&lt;/p&gt;
  &lt;/td&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.2298in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;T-&amp;gt;boolean&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.5638in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;Consumer&amp;lt;T&amp;gt;&lt;/p&gt;
  &lt;/td&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.2298in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;T-&amp;gt;void&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td style=&quot;border-style: solid; border-color: rgb(163, 163, 163); border-width: 1pt; vertical-align: top; width: 1.5638in; padding: 2pt 3pt; height: 22px;&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;Function&amp;lt;T, R&amp;gt;&lt;/p&gt;
  &lt;/td&gt;
  &lt;td style=&quot;border-style: solid; border-color: rgb(163, 163, 163); border-width: 1pt; vertical-align: top; width: 1.2298in; padding: 2pt 3pt; height: 22px;&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;T-&amp;gt;R&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.5638in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;Supplier&amp;lt;T&amp;gt;&lt;/p&gt;
  &lt;/td&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.2298in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;()-&amp;gt;T&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.5638in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;UnaryOperator&amp;lt;T&amp;gt;&lt;/p&gt;
  &lt;/td&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.2298in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;T-&amp;gt;T&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.5819in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;BinaryOperator&amp;lt;T&amp;gt;&lt;/p&gt;
  &lt;/td&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.2125in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;(T, T)-&amp;gt;T&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.5638in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;BiPredicate&amp;lt;L, R&amp;gt;&lt;/p&gt;
  &lt;/td&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.2548in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;(L, R)-&amp;gt;boolean&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.5638in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;BiConsumer&amp;lt;L, R&amp;gt;&lt;/p&gt;
  &lt;/td&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.2298in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;(L, R)-&amp;gt;void&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.5833in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;BiFunction&amp;lt;T, U, R&amp;gt;&lt;/p&gt;
  &lt;/td&gt;
  &lt;td style=&quot;border-style:solid;border-color:#A3A3A3;border-width:1pt;
  vertical-align:top;width:1.2104in;padding:2.0pt 3.0pt 2.0pt 3.0pt&quot;&gt;
  &lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;(T, U,)-&amp;gt;R&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p style=&quot;margin-top: 0px; margin-bottom: 0px; vertical-align: middle;&quot;&gt;&lt;span style=&quot;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;margin-top: 0px; margin-bottom: 0px; vertical-align: middle;&quot;&gt;&lt;span style=&quot;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot;&gt;autoboxing에 대한 리소스를
     줄이기 위해 각 함수형 인터페이스엔 기본형 특화 인터페이스가 존재하며,&amp;nbsp;인터페이스 네임 서두에 자료형을 붙인 형태이다.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;margin-top: 0px; margin-bottom: 0px; vertical-align: middle;&quot;&gt;&lt;span style=&quot;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot;&gt;Function같은 경우 파라미터와
     반환형을 명시하기 위해 ToIntFunction, DoubleToIntFunction등이 존재한다.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul type=&quot;disc&quot; style=&quot;margin-left:.375in;direction:ltr;unicode-bidi:embed;
 margin-top:0in;margin-bottom:0in&quot;&gt;
 &lt;/ul&gt;&lt;ul type=&quot;disc&quot; style=&quot;margin-left:.375in;direction:ltr;unicode-bidi:embed;
 margin-top:0in;margin-bottom:0in&quot;&gt;
&lt;/ul&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;형식
검사&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;컴파일러는
람다가 사용되는 컨텍스트를 기반으로 람다의 형식을 추론한다.&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;어떤 컨텍스트에서 기대되는 람다 표현식의 형식을 대상 형식이라고 부른다.&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;형식을
검사하는 순서는 다음과 같다.&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;ol style=&quot;list-style-type: decimal;&quot;&gt;&lt;li&gt;&lt;p style=&quot;margin-top: 0in; margin-right: 0in; margin-bottom: 0in; font-family: &amp;quot;Malgun Gothic&amp;quot;; font-size: 11pt;&quot; lang=&quot;en-US&quot;&gt;람다 선언부 확인(람다가 매서드 파라미터로 사용시 매서드 선언부 확인)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;margin-top: 0in; margin-right: 0in; margin-bottom: 0in; font-family: &amp;quot;Malgun Gothic&amp;quot;; font-size: 11pt;&quot; lang=&quot;en-US&quot;&gt;선언부에서 대상형식 확인.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;margin-top: 0in; margin-right: 0in; margin-bottom: 0in; font-family: &amp;quot;Malgun Gothic&amp;quot;; font-size: 11pt;&quot; lang=&quot;en-US&quot;&gt;대상형식이 함수형 인터페이스인지 확인.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;margin-top: 0in; margin-right: 0in; margin-bottom: 0in; font-family: &amp;quot;Malgun Gothic&amp;quot;; font-size: 11pt;&quot; lang=&quot;en-US&quot;&gt;대상형식의 추상 메서드 확인.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;margin-top: 0in; margin-right: 0in; margin-bottom: 0in; font-family: &amp;quot;Malgun Gothic&amp;quot;; font-size: 11pt;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;추상메서드의 함수 디스크립터와 람다의 시그니처를 비교하여 형식 검사를 완료한다.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;형식
추론&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;자바
컴파일러는 콘텍스트를 통해 람다 표현식과 관련된 함수형 인터페이스를 추론한다..&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;즉
형식 검사를 통해 함수 디스크립터를 알 수 있으므로, 컴파일러는 람다의 시그니처 또한 추론 할 수 있다.&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;람다의
시그니쳐 추론을 통해 람다 표현식의 파라미터 형식에 접근 할 수 있으므로 파라미터의 형식이 생략 가능하다.&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;(앞서 정리한&amp;nbsp;특징 중 '1. 타입 선언이 선택적이다'에 해당한다.)&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin-top: 0in; margin-right: 0in; margin-bottom: 0in; font-family: &amp;quot;Malgun Gothic&amp;quot;; font-size: 11pt;&quot; lang=&quot;en-US&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;람다
표현식의 유효 범위&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;람다표현식은 java에서 정의된 명명규칙인&amp;nbsp;name conflicts와 shadowing 규칙이 똑같이 적용된다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;즉
람다 파라미터나 람다 표현식 내에 람다가 선언되는 지역의 지역변수와 똑같은 이름의 변수를 선언 할 수 없다.&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;this키워드
또한 람다표현식 내에서 사용할 경우, 람다 표현식이 선언되는 메서드의 this 파라미터를 의미한다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;외부
유효범위의 변수 접근&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;람다
표현식 외부에 있는 변수를 람다가 사용할 경우, 해당 변수를 자유 변수라 부른다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;람다가
자유변수를 capture하기 위해서&lt;/p&gt;&lt;p style=&quot;margin:0in;font-family:&amp;quot;Malgun Gothic&amp;quot;;font-size:11.0pt&quot; lang=&quot;en-US&quot;&gt;자유
변수는 final이거나 변하지 않는 effectivley final 변수여야 한다.&lt;/p&gt;

&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참조 :&amp;nbsp;&lt;a href=&quot;https://dzone.com/articles/a-little-lambda-tutorial&quot; style=&quot;font-family: &amp;quot;Malgun Gothic&amp;quot;; font-size: 14.6667px;&quot;&gt;https://dzone.com/articles/a-little-lambda-tutorial&lt;/a&gt;, 카이호스트만 코어 자바 8&lt;/p&gt;</description>
      <category>JAVA/Java</category>
      <author>HwaToo</author>
      <guid isPermaLink="true">https://hsp1116.tistory.com/59</guid>
      <comments>https://hsp1116.tistory.com/59#entry59comment</comments>
      <pubDate>Sun, 18 Jun 2017 20:58:43 +0900</pubDate>
    </item>
    <item>
      <title>비동기 흐름 제어를 위한 모듈  - async</title>
      <link>https://hsp1116.tistory.com/58</link>
      <description>&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;Async&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;node.js의 장점으로 꼽는 점 중 하나가 non-Blocking으로써 비동기적으로 작동한다는 점이다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그렇기 때문에 node.js의 대부분의 기능들은&amp;nbsp;콜백 패턴을 이용한 비동기 처리를 사용는데, 이러한 점 때문에 실제 개발에 콜백 지옥으로 인해 난관을 겪곤 한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;콜백 지옥이란 콜백 패턴을 이용하는 함수에, 연달아 추가 기능을 사용할 경우 콜백이 계속해서 중첩되는 상태를 말한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;&lt;p&gt;task1(a, &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt;(err, result1){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;task2(b, &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt;(err, result2){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;task3(c, &lt;span style=&quot;color: rgb(251, 222, 45);&quot;&gt;function&lt;/span&gt;(err, result3){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;task4(d, &lt;span style=&quot;color: rgb(251, 222, 45);&quot;&gt;function&lt;/span&gt;(err, result4){
&lt;span style=&quot;color:#aeaeae&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//함수 실행&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
});
&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위 예제는 err에 대한 처리와 각 파라미터에 대한 알고리즘을 베재한 코드이다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;4중첩이지만 실제 코드를 node.js로 코딩할땐 흔히 4중첩이상은 흔히 볼 수 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이러한 콜백 지옥을 해결하기 위해서 다양한 모듈이 있다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;자바스크립트의 Promise 패턴을 이용한 방법(대부분의 모듈은 Promise를 지원한다.), 혹은 Async나 Step이라는 모듈로 흐름을 제어하는 방법이다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;여기서는 Async모듈을 사용하는 방법을 정리하고자 한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;async :&amp;nbsp;&lt;a href=&quot;https://github.com/caolan/async&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://github.com/caolan/async&lt;/a&gt;&lt;/p&gt;&lt;p&gt;docs :&amp;nbsp;&lt;a href=&quot;http://caolan.github.io/async/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://caolan.github.io/async/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;설치 : npm install async --save&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;async 모듈의 메소드는 크게 콜렉션, 흐름제어, 유틸&amp;nbsp;3종류로 나뉘어진다. 주로 사용하는건 콜렉션과 흐름제어이고, 이 포스팅 자체는 흐름제어가 주제이므로 이를 주로 다루겠다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;흐름 제어 메서드&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;async의 흐름 제어 메서드는 정말 다양한 종류가 있지만, 내가 주로 사용한 메서드는 다음과 같다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;- 순차 실행 : series, waterfall&lt;/p&gt;&lt;p&gt;- 병렬 실행 : parallels&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;순차 실행&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;순차 실행은 이름 그대로 메서드들을 순차적으로 실행하는 메서드이다. 여기엔 인자를 전달하지 않고 순차적으로만 실행하는 메서드인 series와,&amp;nbsp;&lt;/p&gt;&lt;p&gt;다음 메서드에 인자를 전달할 수 있는 waterfall 메서드가 있다.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;1. series&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;시리즈 메서드는 다음과 같은 형태를 가진다.&lt;/p&gt;&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;&lt;p&gt;async.series([task1,task2,task3], &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt;(err, results){
&lt;span style=&quot;color:#aeaeae&quot;&gt;// series 완료 콜백&lt;/span&gt;
});
&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;첫번째 파라미터는 실행할 함수들을 순서대로 배열에 넣어 삽입한다, 두번째 메서드는 이 serise가 완료되었을때 실행되는 콜백 함수를 넣는데,&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 콜백에는&amp;nbsp;실행 메서드들 중 실패하는 경우 err에 인자를 전달하며 그 뒤 테스크들의 실행을 중단하고 콜백 함수를 호출한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;모두 성공할 경우 콜백 함수의&amp;nbsp;results에&amp;nbsp;배열에 있는 각 테스크들의 실행 결과를 배열로 전달받는다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;배열에 들어가는 메서드들은 callback을 인자로 가지는&amp;nbsp;함수 형태로 만들어야 한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;task1&lt;/span&gt;(callback){
&lt;span style=&quot;color:#aeaeae&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//실패시&lt;/span&gt;
&lt;span style=&quot;color:#fbde2d&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt;(err){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;callback(err);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;span style=&quot;color:#aeaeae&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//성공시&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;callback(&lt;span style=&quot;color:#d8fa3c&quot;&gt;null&lt;/span&gt;, &lt;span style=&quot;color:#61ce3c&quot;&gt;'성공1'&lt;/span&gt;);
}
&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;성공 시에는 callback인자를 함수로 호출하는데, 첫 인자를 null로 전달하면 되고&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;실패 시에는 첫 null에 err를 전달하면 된다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;async.series([
    &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt; (callback) {
        &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt; (err) {
            callback(&lt;span style=&quot;color:#61ce3c&quot;&gt;'실패1'&lt;/span&gt;);
        }
        callback(&lt;span style=&quot;color:#d8fa3c&quot;&gt;null&lt;/span&gt;, &lt;span style=&quot;color:#61ce3c&quot;&gt;'성공1'&lt;/span&gt;);
    }, 
    &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt; (callback) {
        &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt; (err) {
            callback(&lt;span style=&quot;color:#61ce3c&quot;&gt;'실패2'&lt;/span&gt;);
        }
        callback(&lt;span style=&quot;color:#d8fa3c&quot;&gt;null&lt;/span&gt;, &lt;span style=&quot;color:#61ce3c&quot;&gt;'성공2'&lt;/span&gt;);
    },
    &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt; (callback) {
        &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt; (err) {
            callback(&lt;span style=&quot;color:#61ce3c&quot;&gt;'실패3'&lt;/span&gt;);
        }
        callback(&lt;span style=&quot;color:#d8fa3c&quot;&gt;null&lt;/span&gt;, &lt;span style=&quot;color:#61ce3c&quot;&gt;'성공3'&lt;/span&gt;);
    }],
    &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt;(err, results) {
        &lt;span style=&quot;color:#aeaeae&quot;&gt;// serise 완료 콜백&lt;/span&gt;
        &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt;(err){
            &lt;span style=&quot;color:#aeaeae&quot;&gt;//err시 err난 테스크에서 전달한 err값을 전달받는다&lt;/span&gt;
            &lt;span style=&quot;color:#ff6400&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#8da6ce&quot;&gt;.log&lt;/span&gt;(err);
        }
        &lt;span style=&quot;color:#aeaeae&quot;&gt;//모두 성공시, 성공 값들을 전달받는다&lt;/span&gt;
        &lt;span style=&quot;color:#aeaeae&quot;&gt;//예) ['성공1','성공2','성공3']&lt;/span&gt;
        &lt;span style=&quot;color:#ff6400&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#8da6ce&quot;&gt;.log&lt;/span&gt;(reuslts);
});
&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;2. waterfall&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;serise와 waterfall은 둘다 순차 실행이지만&lt;/p&gt;&lt;p&gt;serise는 테스크들이 독립적으로 실행되어 모든&amp;nbsp;결과를 모아&amp;nbsp;배열로 콜백에 전달하는 반면에,&amp;nbsp;&lt;/p&gt;&lt;p&gt;waterfall은 각 테스크들의 값을 다음 인자로 전달한다는&amp;nbsp;점에서 다르다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background: rgb(12, 16, 33); color: rgb(248, 248, 248);&quot;&gt;&lt;p&gt;async.waterfall([task1,task2,task3], &lt;span style=&quot;color: rgb(251, 222, 45);&quot;&gt;function&lt;/span&gt;(err, result){
&lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;// waterfall 완료 콜백&lt;/span&gt;
});&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;메서드의 형태는 searise와 얼핏 비슷하나, task에서 다음 콜백을 호출 할 때 인자를 전달 할 수 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;&lt;p&gt;&lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;task1&lt;/span&gt;(callback){
    &lt;span style=&quot;color:#aeaeae&quot;&gt;//실패 시&lt;/span&gt;
    &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt;(err){
        callback(err);
    }
    &lt;span style=&quot;color:#aeaeae&quot;&gt;//성공 시&lt;/span&gt;
    callback(&lt;span style=&quot;color:#d8fa3c&quot;&gt;null&lt;/span&gt;, &lt;span style=&quot;color:#61ce3c&quot;&gt;'성공'&lt;/span&gt;, &lt;span style=&quot;color:#61ce3c&quot;&gt;'1'&lt;/span&gt;);
}

&lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;task2&lt;/span&gt;(arg1, arg2, callback){
    &lt;span style=&quot;color:#aeaeae&quot;&gt;//실패 시&lt;/span&gt;
    &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt;(err){
        callback(err);
    }
    &lt;span style=&quot;color:#aeaeae&quot;&gt;//성공 시&lt;/span&gt;
    callback(&lt;span style=&quot;color:#d8fa3c&quot;&gt;null&lt;/span&gt;,&lt;span style=&quot;color:#61ce3c&quot;&gt;'성공2'&lt;/span&gt;);
}
&lt;/p&gt;&lt;/pre&gt;
&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;&lt;p&gt;async.waterfall([
    &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt; (callback) {
        &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt; (err) {
            callback(&lt;span style=&quot;color:#61ce3c&quot;&gt;'실패1'&lt;/span&gt;);
        }
        callback(&lt;span style=&quot;color:#d8fa3c&quot;&gt;null&lt;/span&gt;, &lt;span style=&quot;color:#61ce3c&quot;&gt;'성공'&lt;/span&gt;,&lt;span style=&quot;color:#61ce3c&quot;&gt;'1'&lt;/span&gt;);
    }, 
    &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt; (arg1, arg2, callback) {
        &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt; (err) {
            callback(&lt;span style=&quot;color:#61ce3c&quot;&gt;'실패2'&lt;/span&gt;);
        }
        &lt;span style=&quot;color:#aeaeae&quot;&gt;//arg1 : '성공', arg2 : 1&lt;/span&gt;
        &lt;span style=&quot;color:#ff6400&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#8da6ce&quot;&gt;.log&lt;/span&gt;(arg1, arg2);
        callback(&lt;span style=&quot;color:#d8fa3c&quot;&gt;null&lt;/span&gt;, &lt;span style=&quot;color:#61ce3c&quot;&gt;'성공2'&lt;/span&gt;);
    },
    &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt; (arg1, callback) {
        &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt; (err) {
            callback(&lt;span style=&quot;color:#61ce3c&quot;&gt;'실패3'&lt;/span&gt;);
        }
        &lt;span style=&quot;color:#aeaeae&quot;&gt;//arg1 : '성공2'&lt;/span&gt;
        &lt;span style=&quot;color:#ff6400&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#8da6ce&quot;&gt;.log&lt;/span&gt;(arg1);
        callback(&lt;span style=&quot;color:#d8fa3c&quot;&gt;null&lt;/span&gt;, &lt;span style=&quot;color:#61ce3c&quot;&gt;'성공3'&lt;/span&gt;);
    }],
    &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt;(err, result) {
        &lt;span style=&quot;color:#aeaeae&quot;&gt;// waterfall 완료 콜백&lt;/span&gt;
        &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt;(err){
            &lt;span style=&quot;color:#aeaeae&quot;&gt;//err시 err난 테스크에서 전달한 err값을 전달받는다&lt;/span&gt;
            &lt;span style=&quot;color:#ff6400&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#8da6ce&quot;&gt;.log&lt;/span&gt;(err);
        }
        &lt;span style=&quot;color:#aeaeae&quot;&gt;//모두 성공시, 마지막에 결과 값을 전달 받는다.&lt;/span&gt;
        &lt;span style=&quot;color:#aeaeae&quot;&gt;//result : '성공3'&lt;/span&gt;
        &lt;span style=&quot;color:#ff6400&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#8da6ce&quot;&gt;.log&lt;/span&gt;(reuslt);
});
&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24px; font-weight: bold;&quot;&gt;병렬 실행&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;parallel&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 13.3333px;&quot;&gt;parallel도 앞서 본 메서드들과 같이 task의 배열과 콜백을 인자로 받는다. 다만 순차 실행이 아닌 전달 받은 task들을 병렬, 즉 동시에 실행한다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 13.3333px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 13.3333px;&quot;&gt;그리고 모든 테스크들이 전부 다 끝난 다음에서야 콜백 함수가 실행된다.&lt;/span&gt;&lt;/p&gt;&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;async.parallel([task1,task2,task3], &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt;(err, results){
&lt;span style=&quot;color:#aeaeae&quot;&gt;// parallel 완료 콜백&lt;/span&gt;
});
&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;동시 실행이기 때문에 각 task들은 serise와 같이 독립적으로 실행되며, results에는 모든 함수의 결과가 저장된다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;메서드의 형태는 serise와 비슷하다.&lt;/p&gt;&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;async.parallel([
    &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt; (callback) {
        &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt; (err) {
            callback(&lt;span style=&quot;color:#61ce3c&quot;&gt;'실패1'&lt;/span&gt;);
        }
        callback(&lt;span style=&quot;color:#d8fa3c&quot;&gt;null&lt;/span&gt;, &lt;span style=&quot;color:#61ce3c&quot;&gt;'성공1'&lt;/span&gt;);
    }, 
    &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt; (callback) {
        &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt; (err) {
            callback(&lt;span style=&quot;color:#61ce3c&quot;&gt;'실패2'&lt;/span&gt;);
        }
        callback(&lt;span style=&quot;color:#d8fa3c&quot;&gt;null&lt;/span&gt;, &lt;span style=&quot;color:#61ce3c&quot;&gt;'성공2'&lt;/span&gt;);
    },
    &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt; (callback) {
        &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt; (err) {
            callback(&lt;span style=&quot;color:#61ce3c&quot;&gt;'실패3'&lt;/span&gt;);
        }
        callback(&lt;span style=&quot;color:#d8fa3c&quot;&gt;null&lt;/span&gt;, &lt;span style=&quot;color:#61ce3c&quot;&gt;'성공3'&lt;/span&gt;);
    }],
    &lt;span style=&quot;color:#fbde2d&quot;&gt;function&lt;/span&gt;(err, results) {
        &lt;span style=&quot;color:#aeaeae&quot;&gt;// parallel 완료 콜백&lt;/span&gt;
        &lt;span style=&quot;color:#fbde2d&quot;&gt;if&lt;/span&gt;(err){
            &lt;span style=&quot;color:#aeaeae&quot;&gt;//err시 err난 테스크에서 전달한 err값을 전달받는다&lt;/span&gt;
            &lt;span style=&quot;color:#ff6400&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#8da6ce&quot;&gt;.log&lt;/span&gt;(err);
        }
        &lt;span style=&quot;color:#aeaeae&quot;&gt;//모두 성공시, 성공 값들을 전달받는다&lt;/span&gt;
        &lt;span style=&quot;color:#aeaeae&quot;&gt;//예) ['성공1','성공2','성공3']&lt;/span&gt;
        &lt;span style=&quot;color:#ff6400&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;color:#8da6ce&quot;&gt;.log&lt;/span&gt;(reuslts);
});

&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;node.js를 이용한 프로젝트를 진행하면서 비동기 처리에 따른 콜백 지옥을 벗어나고자 많은 고민이 있었다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;async 모듈, 그리고 promise&amp;nbsp;만으로도 대부분의&amp;nbsp;콜백 지옥을 해소 할 수 있다고 하므로&amp;nbsp;반복해서 숙지하도록 노력해야겠다.&lt;/p&gt;</description>
      <category>Javascript/node.js</category>
      <category>async</category>
      <category>express</category>
      <category>node.js</category>
      <category>노드</category>
      <category>비동기</category>
      <author>HwaToo</author>
      <guid isPermaLink="true">https://hsp1116.tistory.com/58</guid>
      <comments>https://hsp1116.tistory.com/58#entry58comment</comments>
      <pubDate>Sun, 18 Sep 2016 19:19:53 +0900</pubDate>
    </item>
    <item>
      <title>백준 - 10218 Maze</title>
      <link>https://hsp1116.tistory.com/57</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10218&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;[문제 링크]&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;발상적으로 좀 어려웠던 문제다. 최단거리를&amp;nbsp;구하는 것이기 때문에&amp;nbsp;BFS로 전체 경우를 계산에 풀 면 되는데.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;처음엔 구슬들을 모두 벡터로 처리해 복잡해져서&amp;nbsp;고전했다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;좌표가 겹치게 되는 구슬은 어차피 이후 행적은 모두 동일하기 때문에 그냥 SET으로 중복되는부분은 제거하는 방식으로 풀면 된다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;queue&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;set&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#fbde2d&quot;&gt;using&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;namespace&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;std&lt;/span&gt;;
&lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt; t, n, m;
&lt;span style=&quot;color:#fbde2d&quot;&gt;char&lt;/span&gt; maze[&lt;span style=&quot;color:#d8fa3c&quot;&gt;11&lt;/span&gt;][&lt;span style=&quot;color:#d8fa3c&quot;&gt;11&lt;/span&gt;];
&lt;span style=&quot;color:#fbde2d&quot;&gt;typedef&lt;/span&gt; pair&amp;lt;&lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt;&amp;gt; coordi;
&lt;span style=&quot;color:#fbde2d&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;char&lt;/span&gt; nextAc[&lt;span style=&quot;color:#d8fa3c&quot;&gt;4&lt;/span&gt;] = { 'L','R','U','D' }, reAc[&lt;span style=&quot;color:#d8fa3c&quot;&gt;4&lt;/span&gt;] = { 'R','L','D','U' };
&lt;span style=&quot;color:#fbde2d&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt; relPos[&lt;span style=&quot;color:#d8fa3c&quot;&gt;4&lt;/span&gt;][&lt;span style=&quot;color:#d8fa3c&quot;&gt;2&lt;/span&gt;] = { { -1,0 },{ 1,0 },{ 0,-1 },{ 0,1 } };
coordi exitPos;
&lt;span style=&quot;color:#fbde2d&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;Info&lt;/span&gt; {
public:
    set&amp;lt;coordi &amp;gt; pos;
    string ret;
    &lt;span style=&quot;color:#ff6400&quot;&gt;Info&lt;/span&gt;() { ret = &quot;&quot;; }
    &lt;span style=&quot;color:#ff6400&quot;&gt;Info&lt;/span&gt;(set&amp;lt;coordi &amp;gt; nSet, string nRet) {
        pos = nSet;
        ret = nRet;
    }
};
Info* &lt;span style=&quot;color:#ff6400&quot;&gt;Maze&lt;/span&gt;(Info in) {
    queue&amp;lt;Info&amp;gt; q;
    q.&lt;span style=&quot;color:#8da6ce&quot;&gt;push&lt;/span&gt;(in);
    &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//BFS&lt;/span&gt;
    while (!q.&lt;span style=&quot;color:#8da6ce&quot;&gt;empty&lt;/span&gt;()) {
        Info cur = q.&lt;span style=&quot;color:#8da6ce&quot;&gt;front&lt;/span&gt;(); q.&lt;span style=&quot;color:#8da6ce&quot;&gt;pop&lt;/span&gt;();
        char curAc = ' ';
        if (cur.ret.&lt;span style=&quot;color:#8da6ce&quot;&gt;length&lt;/span&gt;() != 0) curAc = cur.ret[cur.ret.&lt;span style=&quot;color:#8da6ce&quot;&gt;length&lt;/span&gt;() - 1];
        for (int i = 0; i&amp;lt;4; i++) {
            set&amp;lt;coordi&amp;gt; nextSet;
           &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt; //가지치기. 
&lt;/span&gt;            if (nextAc[i] != curAc &amp;amp;&amp;amp; curAc != reAc[i]) {
                for (set&amp;lt;coordi&amp;gt;::iterator it = cur.pos.&lt;span style=&quot;color:#8da6ce&quot;&gt;begin&lt;/span&gt;(); it != cur.pos.&lt;span style=&quot;color:#8da6ce&quot;&gt;end&lt;/span&gt;(); it++) {
                    int px = (*it).first, py = (*it).second;
                    bool flag = true;
                    &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//다음 이동이 벽이기 전까지 이동. 혹은 현재 위치가 출구일때 까지&lt;/span&gt;
                    while (maze[py + relPos[i][1]][px + relPos[i][0]] != '#') {
                        px += relPos[i][0];
                        py += relPos[i][1];
                        if(maze[py][px] == 'O') flag = false;
                    }
                    if(flag) nextSet.&lt;span style=&quot;color:#8da6ce&quot;&gt;insert&lt;/span&gt;(&lt;span style=&quot;color:#8da6ce&quot;&gt;make_pair&lt;/span&gt;(px, py));
                }
               &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt; //다음 값이 현재 값과 일치하면 continue&lt;/span&gt;
                if (nextSet == cur.pos) continue;
               &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt; //set의 사이즈가 0이면 모두 탈출 -&amp;gt; 결과 객체 반환 &lt;/span&gt;
                if(nextSet.&lt;span style=&quot;color:#8da6ce&quot;&gt;size&lt;/span&gt;() == 0){
                    return new Info(nextSet, cur.ret + nextAc[i]);
                }
               &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt; //현재 액션의 길이가 10이 넘어서면 NULL 반환 &lt;/span&gt;
                else if ((cur.ret + nextAc[i]).&lt;span style=&quot;color:#8da6ce&quot;&gt;length&lt;/span&gt;() &amp;gt; 10) return NULL;
                q.&lt;span style=&quot;color:#8da6ce&quot;&gt;push&lt;/span&gt;(&lt;span style=&quot;color:#8da6ce&quot;&gt;Info&lt;/span&gt;(nextSet, cur.ret + nextAc[i])); 
            
            }
        }   
    }
    return NULL;
}
&lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;main&lt;/span&gt;() {
    cin &amp;gt;&amp;gt; t;
    while (t--) {
        Info in;
        cin &amp;gt;&amp;gt; n &amp;gt;&amp;gt; m;
        for (int y = 0; y&amp;lt;n; y++) {
            for (int x = 0; x&amp;lt;m; x++) {
                cin &amp;gt;&amp;gt; maze[y][x];
                if (maze[y][x] == '.') in.pos.&lt;span style=&quot;color:#8da6ce&quot;&gt;insert&lt;/span&gt;(&lt;span style=&quot;color:#8da6ce&quot;&gt;make_pair&lt;/span&gt;(x, y));
                else if (maze[y][x] == 'O') {
                    exitPos = make_pair(x, y);
                }
            }
        }
        Info* retInfo = Maze(in);
        if (retInfo == NULL) cout &amp;lt;&amp;lt; &quot;XHAE&quot; &amp;lt;&amp;lt; endl;
        else cout &amp;lt;&amp;lt; retInfo-&amp;gt;ret &amp;lt;&amp;lt; endl;
    }
}
&lt;/pre&gt;</description>
      <category>Algorithm/Problems</category>
      <category>ACM-ICPC</category>
      <category>algorithm</category>
      <category>coder's high</category>
      <category>백준</category>
      <category>백준온라인저지</category>
      <category>알고리즘</category>
      <category>코더스하이</category>
      <author>HwaToo</author>
      <guid isPermaLink="true">https://hsp1116.tistory.com/57</guid>
      <comments>https://hsp1116.tistory.com/57#entry57comment</comments>
      <pubDate>Mon, 20 Jun 2016 18:16:52 +0900</pubDate>
    </item>
    <item>
      <title>백준 - 10217 KCM Travel</title>
      <link>https://hsp1116.tistory.com/56</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10217&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;[문제 링크]&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그래프 문제이다. 최단거리를 구하는 문제이기 때문에 다익스트라를 이용해서 풀 수 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;다만 가중치만 존재하는 것이 아니라 금액도 같이 주어지기 때문에 DP를 이용해서 풀어야한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;특정 공항에 도착했을때 남은 금액과 가중치가 모두 다르기 때문이다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;cstdio&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;utility&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;queue&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;cstring&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;define&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;MAXV&lt;/span&gt; 987654321
&lt;span style=&quot;color:#fbde2d&quot;&gt;using&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;namespace&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;std&lt;/span&gt;;
&lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt; t, n, m, k,cache[&lt;span style=&quot;color:#d8fa3c&quot;&gt;102&lt;/span&gt;][&lt;span style=&quot;color:#d8fa3c&quot;&gt;10002&lt;/span&gt;];
&lt;span style=&quot;color:#fbde2d&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;Info&lt;/span&gt; {
public:
    int v, x, d;
    &lt;span style=&quot;color:#ff6400&quot;&gt;Info&lt;/span&gt;(int v, int x, int d) :v(v), x(x), d(d) {
    }
};
&lt;span style=&quot;color:#fbde2d&quot;&gt;struct&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;cmp&lt;/span&gt; {
    bool operator()(Info x, Info y) {
        return x.d &amp;gt; y.d;
    }
};
vector&amp;lt;Info&amp;gt; adj[&lt;span style=&quot;color:#d8fa3c&quot;&gt;102&lt;/span&gt;];
&lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;kcmTravel&lt;/span&gt;() {
    int ret = MAXV;
    priority_queue&amp;lt;Info, vector&amp;lt;Info&amp;gt;, cmp&amp;gt; pq;
    &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//memoization reset &lt;/span&gt;
    memset(cache, -1, sizeof(cache));
    cache[1][0] = 0;
    pq.&lt;span style=&quot;color:#8da6ce&quot;&gt;push&lt;/span&gt;(&lt;span style=&quot;color:#8da6ce&quot;&gt;Info&lt;/span&gt;(1, 0, 0));
    while (!pq.&lt;span style=&quot;color:#8da6ce&quot;&gt;empty&lt;/span&gt;()) {
        Info cur = pq.&lt;span style=&quot;color:#8da6ce&quot;&gt;top&lt;/span&gt;(); pq.&lt;span style=&quot;color:#8da6ce&quot;&gt;pop&lt;/span&gt;();
        &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//현재 저장된 가중치보다 크거나 비용이 초과하면  continue &lt;/span&gt;
        if (cur.d &amp;gt; cache[cur.v][cur.x] || cur.x &amp;gt; m) continue;
        &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//인접리스트 체크 &lt;/span&gt;
        for (int i = 0; i &amp;lt; adj[cur.v].&lt;span style=&quot;color:#8da6ce&quot;&gt;size&lt;/span&gt;(); i++) {
            Info tmp = adj[cur.v][i];
            int acCost = tmp.x + cur.x;
            if ((cache[tmp.v][acCost] == -1 || cache[tmp.v][acCost] &amp;gt; cur.d + tmp.d)&amp;amp;&amp;amp; cur.x + tmp.x &amp;lt;= m) {
                cache[tmp.v][acCost] = cur.d + tmp.d;
                pq.&lt;span style=&quot;color:#8da6ce&quot;&gt;push&lt;/span&gt;(&lt;span style=&quot;color:#8da6ce&quot;&gt;Info&lt;/span&gt;(tmp.v, acCost, cur.d + tmp.d));
            }
        }
    }
   &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt; //도착지의 최소 비용을 구한다. &lt;/span&gt;
    for (int i = 0; i &amp;lt;= m; i++) {
        if (cache[n][i] != -1 &amp;amp;&amp;amp; ret&amp;gt;cache[n][i])
            ret = cache[n][i];
    }
    return ret;
}
&lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;main&lt;/span&gt;() {
    scanf(&quot;%d&quot;, &amp;amp;t);
    while (t--) {
        &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//인접리스트 초기화 &lt;/span&gt;
        for (int i = 0; i &amp;lt;= 101; i++) adj[i].&lt;span style=&quot;color:#8da6ce&quot;&gt;clear&lt;/span&gt;();
        int u, v, x, d;
        &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//input &lt;/span&gt;
        scanf(&quot;%d %d %d&quot;, &amp;amp;n, &amp;amp;m, &amp;amp;k);
        for (int i = 0; i&amp;lt;k; i++) {
            scanf(&quot;%d %d %d %d&quot;, &amp;amp;u, &amp;amp;v, &amp;amp;x, &amp;amp;d);
            adj[u].&lt;span style=&quot;color:#8da6ce&quot;&gt;push_back&lt;/span&gt;(&lt;span style=&quot;color:#8da6ce&quot;&gt;Info&lt;/span&gt;(v, x, d));
        }
        int tmp = kcmTravel();
        printf(tmp == MAXV ? &quot;Poor KCM\n&quot; : &quot;%d\n&quot;, tmp);
    }
}
&lt;/pre&gt;</description>
      <category>Algorithm/Problems</category>
      <category>ACM-ICPC</category>
      <category>algorithm</category>
      <category>boj</category>
      <category>coder's high</category>
      <category>백준</category>
      <category>백준온라인저지</category>
      <category>알고리즘</category>
      <category>코더스하이</category>
      <author>HwaToo</author>
      <guid isPermaLink="true">https://hsp1116.tistory.com/56</guid>
      <comments>https://hsp1116.tistory.com/56#entry56comment</comments>
      <pubDate>Mon, 20 Jun 2016 18:12:20 +0900</pubDate>
    </item>
    <item>
      <title>백준 - 10216 Count Circle Groups</title>
      <link>https://hsp1116.tistory.com/55</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10216&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;[문제 링크]&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;도달 할 수 있는 진영을 그래프의 형태로 만들고 그래프의 갯수를 세면 된다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;서로 연결되지 않은 진영이 있기 때문에 모두 연결하다보면 다수의 그래프를 취한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이를 BFS든 DFS든 완전탐색을 해나가며 탐색한 그래프의 갯수를 세면 답을 구할 수 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;cstdio&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;utility&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;define&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;createCamp&lt;/span&gt;(x,y,r) make_pair(make_pair(x,y),r);
&lt;span style=&quot;color:#fbde2d&quot;&gt;using&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;namespace&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;std&lt;/span&gt;;
&lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt; t, n, x, y, r;
&lt;span style=&quot;color:#fbde2d&quot;&gt;typedef&lt;/span&gt; pair&amp;lt;pair&amp;lt;&lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt;&amp;gt;, &lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt;&amp;gt; Camp;
vector&amp;lt;&lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt;&amp;gt; adj[&lt;span style=&quot;color:#d8fa3c&quot;&gt;3001&lt;/span&gt;];
Camp c[&lt;span style=&quot;color:#d8fa3c&quot;&gt;3001&lt;/span&gt;];

&lt;span style=&quot;color:#aeaeae&quot;&gt;//인접 여부 &lt;/span&gt;
&lt;span style=&quot;color:#fbde2d&quot;&gt;bool&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;groupOk&lt;/span&gt;(Camp a, Camp b) {
    int distance = (a.first.first - b.first.first)*(a.first.first - b.first.first)
        + (a.first.second - b.first.second)*(a.first.second - b.first.second);
    return distance &amp;lt;= (a.second + b.second)*(a.second + b.second);
}
&lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;countCirclegroup&lt;/span&gt;() {
    int ret = 0;
    bool visited[3001] = { false, };
    //인접리스트 초기화 
    for (int i = 0; i&amp;lt;n; i++) {
        for (int j = 0; j&amp;lt;n; j++) {
            if (&lt;span style=&quot;color:#8da6ce&quot;&gt;groupOk&lt;/span&gt;(c[i], c[j])) {
                adj[i].&lt;span style=&quot;color:#8da6ce&quot;&gt;push_back&lt;/span&gt;(j);
                adj[j].&lt;span style=&quot;color:#8da6ce&quot;&gt;push_back&lt;/span&gt;(i);
            }
        }
    }
    //탐색 
    vector&amp;lt;int&amp;gt; v;
    for (int i = 0; i&amp;lt;n; i++) {
        if (visited[i]) continue;
        visited[i] = true;
        v.&lt;span style=&quot;color:#8da6ce&quot;&gt;push_back&lt;/span&gt;(i);
        while (!v.&lt;span style=&quot;color:#8da6ce&quot;&gt;empty&lt;/span&gt;()) {
            int cur = v.&lt;span style=&quot;color:#8da6ce&quot;&gt;back&lt;/span&gt;(); v.&lt;span style=&quot;color:#8da6ce&quot;&gt;pop_back&lt;/span&gt;();
            for (int j = 0; j&amp;lt;adj[cur].&lt;span style=&quot;color:#8da6ce&quot;&gt;size&lt;/span&gt;(); j++) {
                int tmp = adj[cur][j];
                if (!visited[tmp]) {
                    visited[tmp] = true;
                    v.&lt;span style=&quot;color:#8da6ce&quot;&gt;push_back&lt;/span&gt;(tmp);
                }
            }
        }
        ret++;
    }
    return ret;
}
&lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;main&lt;/span&gt;() {
    scanf(&quot;%d&quot;, &amp;amp;t);
    while (t--) {
        scanf(&quot;%d&quot;, &amp;amp;n);
        for (int i = 0; i&amp;lt;n; i++) {
            adj[i].&lt;span style=&quot;color:#8da6ce&quot;&gt;clear&lt;/span&gt;();
            scanf(&quot;%d %d %d&quot;, &amp;amp;x, &amp;amp;y, &amp;amp;r);
            c[i] = createCamp(x, y, r);
        }
        printf(&quot;%d\n&quot;, countCirclegroup());
    }
}
&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Algorithm/Problems</category>
      <category>ACM-ICPC</category>
      <category>algorithm</category>
      <category>boj</category>
      <category>coder's high</category>
      <category>백준</category>
      <category>백준온라인저지</category>
      <category>알고리즘</category>
      <author>HwaToo</author>
      <guid isPermaLink="true">https://hsp1116.tistory.com/55</guid>
      <comments>https://hsp1116.tistory.com/55#entry55comment</comments>
      <pubDate>Mon, 20 Jun 2016 18:08:14 +0900</pubDate>
    </item>
    <item>
      <title>백준 - 10215 Colored Bead Work</title>
      <link>https://hsp1116.tistory.com/54</link>
      <description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10215&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;[문제 링크]&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;처음엔 완전 탐색으로 풀었는데 이 문제는 비트마스킹 DP로 풀어야 한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;여기서 주어진 칸의 갯수는 4X4로 16개이며, unsigned int형으로 비트마스킹 하면 각각 칸에 대해서 4가지(00,01,10,11) 상태를 표현이 가능하다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 각 경우에 대해 주어진 조건에 맞춰 확률을 모두 계산해 더해주면 된다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;(비트마스킹의 시프트로 해결해도 되고, 배열과 비트마스크를 바꿔가며 해결해도 된다. 밑의 코드는 두가지 경우를 모두 사용해보았다. 입맛에 맞게 사용하면 되지만 비트마스킹만을 사용하는게 더 빠른 속도로 통과된다.)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background:#0c1021;color:#f8f8f8&quot;&gt;#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;cstdio&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;utility&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;map&amp;gt;&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color:#61ce3c&quot;&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#aeaeae&quot;&gt;//반복문 매크로&lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;define&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;FOR&lt;/span&gt;(k,a,b) for(int k = a; k&amp;lt;b; k++)
#&lt;span style=&quot;color:#fbde2d&quot;&gt;define&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;M_FOR&lt;/span&gt;(k,a,b) for(int k = a; k &amp;gt;= b; k--)
#&lt;span style=&quot;color:#fbde2d&quot;&gt;define&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;D_FOR&lt;/span&gt;(a,b,c,d) for(int i = a; i&amp;lt;b; i++) for(int j = c; j&amp;lt;d; j++)
&lt;span style=&quot;color:#aeaeae&quot;&gt;//구슬 비트 &lt;/span&gt;
#&lt;span style=&quot;color:#fbde2d&quot;&gt;define&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;W_BIT&lt;/span&gt; (8*i+2*j)
using namespace std;
&lt;span style=&quot;color:#aeaeae&quot;&gt;//memoization &lt;/span&gt;
map&amp;lt;&lt;span style=&quot;color:#fbde2d&quot;&gt;unsigned&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color:#fbde2d&quot;&gt;double&lt;/span&gt;&amp;gt; cache[&lt;span style=&quot;color:#d8fa3c&quot;&gt;17&lt;/span&gt;];
&lt;span style=&quot;color:#fbde2d&quot;&gt;typedef&lt;/span&gt; pair&amp;lt;&lt;span style=&quot;color:#fbde2d&quot;&gt;unsigned&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt;, &lt;span style=&quot;color:#fbde2d&quot;&gt;double&lt;/span&gt;&amp;gt; dishStat;
&lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt; T, actCount;
&lt;span style=&quot;color:#fbde2d&quot;&gt;unsigned&lt;/span&gt; &lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt; dish;
&lt;span style=&quot;color:#fbde2d&quot;&gt;char&lt;/span&gt; act[&lt;span style=&quot;color:#d8fa3c&quot;&gt;17&lt;/span&gt;];

&lt;span style=&quot;color:#aeaeae&quot;&gt;//bitmask -&amp;gt; vector &lt;/span&gt;
vector&amp;lt;vector&amp;lt;&lt;span style=&quot;color:#fbde2d&quot;&gt;char&lt;/span&gt;&amp;gt; &amp;gt; &lt;span style=&quot;color:#ff6400&quot;&gt;getStatVector&lt;/span&gt;(unsigned int dish) {
    vector&amp;lt; vector&amp;lt;char&amp;gt; &amp;gt; ret;
    ret.&lt;span style=&quot;color:#8da6ce&quot;&gt;resize&lt;/span&gt;(4);
    D_FOR(0, 4, 0, 4) {
        if (dish&amp;amp;(1 &amp;lt;&amp;lt; W_BIT)) ret[i].&lt;span style=&quot;color:#8da6ce&quot;&gt;push_back&lt;/span&gt;('W');
        else if (dish&amp;amp;(1 &amp;lt;&amp;lt; (W_BIT+1))) ret[i].&lt;span style=&quot;color:#8da6ce&quot;&gt;push_back&lt;/span&gt;('G');
        else ret[i].&lt;span style=&quot;color:#8da6ce&quot;&gt;push_back&lt;/span&gt;('E');
    }
    return ret;
}
  
&lt;span style=&quot;color:#fbde2d&quot;&gt;double&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;getProb&lt;/span&gt;(int curAct, unsigned int curDish) {
    &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//기저사례 1 : 모든 액션 실행.&lt;/span&gt;
    if(curAct == actCount) return curDish==dish? 1:0;
    &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//기저사례 2 : DP &lt;/span&gt;
    if (cache[curAct].&lt;span style=&quot;color:#8da6ce&quot;&gt;find&lt;/span&gt;(curDish) != cache[curAct].&lt;span style=&quot;color:#8da6ce&quot;&gt;end&lt;/span&gt;())
        return cache[curAct][curDish];
    vector&amp;lt;vector&amp;lt;char&amp;gt; &amp;gt; ret = getStatVector(curDish);
        &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//구슬일 경우&lt;/span&gt;
        if (act[curAct] == 'W' || act[curAct] == 'G') {
            int centNum = 0, curBead = act[curAct] == 'W' ? 0 : 1;
            D_FOR(1, 3, 1, 3) if (ret[i][j] == 'E')  centNum++;
            &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//중앙 공간이 3개 비었을 경우, 대각선 100% &lt;/span&gt;
            if (centNum == 3) {
                if (ret[1][1] != 'E') cache[curAct][curDish] += getProb(curAct + 1, curDish | (1 &amp;lt;&amp;lt; (20 + curBead)));
                else if (ret[1][2] != 'E') cache[curAct][curDish] += getProb(curAct + 1, curDish | (1 &amp;lt;&amp;lt; (18 + curBead)));
                else if (ret[2][1] != 'E') cache[curAct][curDish] += getProb(curAct + 1, curDish | (1 &amp;lt;&amp;lt; (12 + curBead)));
                else if (ret[2][2] != 'E') cache[curAct][curDish] += getProb(curAct + 1, curDish | (1 &amp;lt;&amp;lt; (10 + curBead)));
            }
            &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//중앙 공간이 1,2,4개 남았을경우, 1/centNum&lt;/span&gt; 
            else if (centNum &amp;lt;= 4 &amp;amp;&amp;amp; centNum &amp;gt; 0) {
                D_FOR(1, 3, 1, 3) {
                    if (ret[i][j] == 'E')
                        cache[curAct][curDish] += getProb(curAct + 1, curDish | (1 &amp;lt;&amp;lt; (W_BIT + curBead))) / centNum;
                }
            }
            &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//중앙이 꽉찼을 경우, 1/나머지공간 &lt;/span&gt;
            else {
                D_FOR(0, 4, 0, 4) if (ret[i][j] == 'E') centNum++;
                D_FOR(0, 4, 0, 4) {
                    if (ret[i][j] == 'E')
                        cache[curAct][curDish] += (&lt;span style=&quot;color:#8da6ce&quot;&gt;getProb&lt;/span&gt;(curAct + 1, curDish | (1 &amp;lt;&amp;lt; (W_BIT + curBead)))) / centNum;
                }
  
            }
        }
        &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//나머지 액션 &lt;/span&gt;
        else {
            unsigned int nextDish = curDish;
            if (act[curAct] == 'L') {
                FOR(k,0, 4) D_FOR(0, 4, 1, 4) { 
                    &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt;//직전 -1~-2비트가 00이면 오른쪽으로 2bit shift &lt;/span&gt;
                    if (!(nextDish &amp;amp;(3 &amp;lt;&amp;lt; (W_BIT - 2)))) {
                        nextDish = ((nextDish &amp;amp; (3 &amp;lt;&amp;lt; (W_BIT))) &amp;gt;&amp;gt; 2) | (nextDish&amp;amp;~(3 &amp;lt;&amp;lt; (W_BIT)));
                    }
                }
                cache[curAct][curDish] += getProb(curAct + 1, nextDish);
            }
            else if (act[curAct] == 'R') {
                FOR(k,0, 4) FOR(i,0,4) M_FOR(j,2,0) {
                   &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt; //이후 1~2비트가 00이면 왼쪽으로 2bit shift &lt;/span&gt;
                    if (!(nextDish &amp;amp;(3 &amp;lt;&amp;lt; (W_BIT + 2)))) {
                        nextDish = ((nextDish &amp;amp; (3 &amp;lt;&amp;lt; (W_BIT))) &amp;lt;&amp;lt; 2) | (nextDish&amp;amp;~(3 &amp;lt;&amp;lt; (W_BIT)));
                    }
                }
                cache[curAct][curDish] += getProb(curAct + 1, nextDish);
            }
            else if (act[curAct] == 'T') {
                FOR(k,0, 4) D_FOR(1,4,0,4) {
                   &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt; //이전 -7~-8비트가 00이면 오른쪽으로 8bit shift&lt;/span&gt;
                    if (!(nextDish &amp;amp;(3 &amp;lt;&amp;lt; (W_BIT - 8)))) {
                        nextDish = ((nextDish &amp;amp; (3 &amp;lt;&amp;lt; (W_BIT))) &amp;gt;&amp;gt; 8) | (nextDish&amp;amp;~(3 &amp;lt;&amp;lt; (W_BIT)));
                    }
                }
                cache[curAct][curDish] += getProb(curAct + 1, nextDish);
            }
              
            else if (act[curAct] == 'B') {
                FOR(k,0, 4) M_FOR(i,2,0) FOR(j,0,4){
                   &lt;span style=&quot;color: rgb(174, 174, 174);&quot;&gt; //이후 7~8비트가 00이면 왼쪽으로 8bit shift &lt;/span&gt;
                    if (!(nextDish &amp;amp;(3 &amp;lt;&amp;lt; (W_BIT + 8)))) {
                        nextDish = ((nextDish &amp;amp; (3 &amp;lt;&amp;lt; (W_BIT))) &amp;lt;&amp;lt; 8) | (nextDish&amp;amp;~(3 &amp;lt;&amp;lt; (W_BIT)));
                    }
                }
                cache[curAct][curDish] += getProb(curAct + 1, nextDish);
            }
        }    
   return cache[curAct][curDish];
}
 
&lt;span style=&quot;color:#fbde2d&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#ff6400&quot;&gt;main&lt;/span&gt;() {
    cin &amp;gt;&amp;gt; T;
    while (T--) {
        dish = 0;
        cin &amp;gt;&amp;gt; actCount;
        FOR(k, 0, actCount) cin &amp;gt;&amp;gt; act[k];
        D_FOR(0, 4, 0, 4) {
            char tmp;
            cin &amp;gt;&amp;gt; tmp;
            if (tmp == 'W') dish |= 1 &amp;lt;&amp;lt; W_BIT;
            if (tmp == 'G') dish |= 1 &amp;lt;&amp;lt; (W_BIT+1);
        }
        cache[actCount][dish] = 1.0;
        printf(&quot;%.9lf\n&quot;, getProb(0, 0));
        FOR(k, 0, 17)cache[k].&lt;span style=&quot;color:#8da6ce&quot;&gt;clear&lt;/span&gt;();
    }
}
&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Algorithm/Problems</category>
      <category>ACM-ICPC</category>
      <category>algorithm</category>
      <category>boj</category>
      <category>coder's high</category>
      <category>백준</category>
      <category>백준온라인저지</category>
      <category>알고리즘</category>
      <category>코더스하이</category>
      <author>HwaToo</author>
      <guid isPermaLink="true">https://hsp1116.tistory.com/54</guid>
      <comments>https://hsp1116.tistory.com/54#entry54comment</comments>
      <pubDate>Mon, 20 Jun 2016 18:03:59 +0900</pubDate>
    </item>
  </channel>
</rss>