<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>H!GHR</title>
    <link>https://jjjayyy.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 19 Jun 2026 21:16:15 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>H!GHR</managingEditor>
    <image>
      <title>H!GHR</title>
      <url>https://tistory1.daumcdn.net/tistory/2867587/attach/ed34b01458e9452a9640d03b7088be77</url>
      <link>https://jjjayyy.tistory.com</link>
    </image>
    <item>
      <title>[디자인패턴] 어댑터 (Adapter Pattern)</title>
      <link>https://jjjayyy.tistory.com/109</link>
      <description>&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;생성패턴 (Creational Pattern)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;구조패턴 (&lt;span style=&quot;color: #000000;&quot;&gt;Structural Pattern)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;&lt;b&gt;행위패턴 (Behavioral Pattern)&lt;/b&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- 추상 팩토리 (Abstract Factory)&lt;br /&gt;- 팩토리 메소드 (Factory Method)&lt;br /&gt;- 프로토타입 (Prototype)&lt;br /&gt;- 빌더 (Builder)&lt;br /&gt;- 싱글톤 (Singleton)&lt;/td&gt;
&lt;td&gt;- &lt;span style=&quot;color: #ee2323;&quot;&gt;어댑터 (Adapter)&lt;/span&gt;&lt;br /&gt;- 컴포지트 (Composite)&lt;br /&gt;- 브리지 (Bridge)&lt;br /&gt;- 데코레이터 (Decorator)&lt;br /&gt;- 플라이웨이트 (Flyweight)&amp;nbsp;&lt;br /&gt;- 프록시 (Proxy)&lt;br /&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;퍼사드 (Facade)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;- 책임 연쇄 (Chain of Responsibility)&lt;br /&gt;- 커맨드 (Command)&lt;br /&gt;- 인터프리터 (Interpreter)&lt;br /&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이터레이터 (Iterator)&amp;nbsp;&lt;/span&gt;&lt;br /&gt;- 미디에이터 (Mediator)&lt;br /&gt;- 비지터 (Visitor)&lt;br /&gt;- 템플릿 메소드 (Template Method)&lt;br /&gt;- 스테이트 (State)&lt;br /&gt;- 옵저버 (Observer)&lt;br /&gt;- 메멘토 (Memento)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;구조패턴 (Structural Pattern)&lt;br /&gt;&amp;gt; 클래스나 객체를 조합해 더 큰 구조를 만드는 패턴&lt;br /&gt;&amp;gt; 객체들을 묶어서 새로운 기능 제공&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Adapter 패턴?&lt;/b&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이미 만들어진 것을 필요한 것으로 사용할 수 있도록 해주는 패턴&lt;/li&gt;
&lt;li&gt;ex) 220v -&amp;gt; 110v 호환어댑터 / C타입충전기 -&amp;gt; 8핀충전기 어댑터&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Adapter 패턴구조&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;588&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0NMbM/btrBaQ2x6C0/heqq5nqKoJMM22JNkFqkc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0NMbM/btrBaQ2x6C0/heqq5nqKoJMM22JNkFqkc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0NMbM/btrBaQ2x6C0/heqq5nqKoJMM22JNkFqkc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0NMbM%2FbtrBaQ2x6C0%2Fheqq5nqKoJMM22JNkFqkc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;588&quot; height=&quot;272&quot; data-origin-width=&quot;588&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Target : 필요한 메소드 결정 (ex. 아이폰 충전중)&lt;/li&gt;
&lt;li&gt;Client : Target 역할의 메소드 사용 (ex. 아이폰 본체)&lt;/li&gt;
&lt;li&gt;Adaptee : 이미 만들어져 있는 것, 기존 제공되는 구현 (ex. 아이폰 바꾸기 전 갤럭시 충전기)&lt;/li&gt;
&lt;li&gt;Adapter : Adaptee를 이용해 필요한 것 구현 (ex. 갤럭시 -&amp;gt; 아이폰 호환 충전어댑터)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Adapter 패턴이 필요한 상황&lt;/b&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이미 존재하고 있는 것과 비슷하게 새로 구현이 필요할 경우 (기존 API는 충분한 검증이 된 것으로 안정성 up)&lt;/li&gt;
&lt;li&gt;기존 소스 수정이 필요할 경우, 의존하는 API들 테스트도 다시 해야하기 때문에 어댑터 패턴으로 side-effect 최소화&lt;/li&gt;
&lt;li&gt;구 버전과 신 버전의 호환이 필요할 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;적용 예제&lt;/b&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 일반 배송만 있다가 빠른 배송이 추가 되었다!!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qP4OF/btrBdbkeH6z/JJhkXT9B2UYifTaLmjGqJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qP4OF/btrBdbkeH6z/JJhkXT9B2UYifTaLmjGqJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qP4OF/btrBdbkeH6z/JJhkXT9B2UYifTaLmjGqJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqP4OF%2FbtrBdbkeH6z%2FJJhkXT9B2UYifTaLmjGqJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;472&quot; height=&quot;382&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;382&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1651584735758&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - jjjayyy/Design_Pattern_Sample_With_Springboot&quot; data-og-description=&quot;Contribute to jjjayyy/Design_Pattern_Sample_With_Springboot development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot; data-og-url=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bfhMir/hyOgssNjxH/wshK8xV0Kj3SCDwyU1CUy1/img.png?width=1200&amp;amp;height=600&amp;amp;face=950_121_1053_233&quot;&gt;&lt;a href=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bfhMir/hyOgssNjxH/wshK8xV0Kj3SCDwyU1CUy1/img.png?width=1200&amp;amp;height=600&amp;amp;face=950_121_1053_233');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - jjjayyy/Design_Pattern_Sample_With_Springboot&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to jjjayyy/Design_Pattern_Sample_With_Springboot development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>JAVA/디자인패턴</category>
      <author>H!GHR</author>
      <guid isPermaLink="true">https://jjjayyy.tistory.com/109</guid>
      <comments>https://jjjayyy.tistory.com/109#entry109comment</comments>
      <pubDate>Tue, 3 May 2022 22:33:02 +0900</pubDate>
    </item>
    <item>
      <title>[디자인패턴] 싱글톤 (Singleton Pattern)</title>
      <link>https://jjjayyy.tistory.com/108</link>
      <description>&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;생성패턴 (Creational Pattern)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;구조패턴 (&lt;span style=&quot;color: #000000;&quot;&gt;Structural Pattern)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;&lt;b&gt;행위패턴 (Behavioral Pattern)&lt;/b&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- 추상 팩토리 (Abstract Factory)&lt;br /&gt;- 팩토리 메소드 (Factory Method)&lt;br /&gt;- 프로토타입 (Prototype)&lt;br /&gt;- 빌더 (Builder)&lt;br /&gt;- &lt;span style=&quot;color: #ee2323;&quot;&gt;싱글톤 (Singleton)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;- 어댑터 (Adapter)&lt;br /&gt;- 컴포지트 (Composite)&lt;br /&gt;- 브리지 (Bridge)&lt;br /&gt;- 데코레이터 (Decorator)&lt;br /&gt;- 플라이웨이트 (Flyweight)&amp;nbsp;&lt;br /&gt;- 프록시 (Proxy)&lt;br /&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;퍼사드 (Facade)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;- 책임 연쇄 (Chain of Responsibility)&lt;br /&gt;- 커맨드 (Command)&lt;br /&gt;- 인터프리터 (Interpreter)&lt;br /&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이터레이터 (Iterator)&amp;nbsp;&lt;/span&gt;&lt;br /&gt;- 미디에이터 (Mediator)&lt;br /&gt;- 비지터 (Visitor)&lt;br /&gt;- 템플릿 메소드 (Template Method)&lt;br /&gt;- 스테이트 (State)&lt;br /&gt;- 옵저버 (Observer)&lt;br /&gt;- 메멘토 (Memento)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;생성패턴 (Creational Pattern)&lt;br /&gt;&amp;gt; 객체 생성에 관련된 패턴&lt;br /&gt;&amp;gt; 객체 생성과 조합을 캡슐화해 유연성 제공&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Singleton 패턴?&lt;/b&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인스턴스가 하나만 생성됨을 보증하는 패턴&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;적용 예제&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;싱글톤은 클래스 로드와 초기화를 알아야 적용하기 쉽다.&lt;/p&gt;
&lt;figure id=&quot;og_1648557511956&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;클래스는 언제 로딩되고 초기화되는가? (feat. 싱글톤)&quot; data-og-description=&quot;클래스는 언제 로딩되고 초기화되는가?&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@skyepodium/%ED%81%B4%EB%9E%98%EC%8A%A4%EB%8A%94-%EC%96%B8%EC%A0%9C-%EB%A1%9C%EB%94%A9%EB%90%98%EA%B3%A0-%EC%B4%88%EA%B8%B0%ED%99%94%EB%90%98%EB%8A%94%EA%B0%80&quot; data-og-url=&quot;https://velog.io/@skyepodium/클래스는-언제-로딩되고-초기화되는가&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ojgmX/hyNSaZK3m0/hPa0b5XiLRvjDhPPqWTdt0/img.png?width=768&amp;amp;height=179&amp;amp;face=0_0_768_179,https://scrap.kakaocdn.net/dn/bRbi8L/hyNQ2I4h44/gsw0XkOtYemwuB2HzE05kK/img.png?width=2302&amp;amp;height=536&amp;amp;face=0_0_2302_536,https://scrap.kakaocdn.net/dn/2OvIu/hyNRbMKZTm/KhNpfSzHW9NyO2xpgHgr11/img.png?width=2362&amp;amp;height=1110&amp;amp;face=0_0_2362_1110&quot;&gt;&lt;a href=&quot;https://velog.io/@skyepodium/%ED%81%B4%EB%9E%98%EC%8A%A4%EB%8A%94-%EC%96%B8%EC%A0%9C-%EB%A1%9C%EB%94%A9%EB%90%98%EA%B3%A0-%EC%B4%88%EA%B8%B0%ED%99%94%EB%90%98%EB%8A%94%EA%B0%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@skyepodium/%ED%81%B4%EB%9E%98%EC%8A%A4%EB%8A%94-%EC%96%B8%EC%A0%9C-%EB%A1%9C%EB%94%A9%EB%90%98%EA%B3%A0-%EC%B4%88%EA%B8%B0%ED%99%94%EB%90%98%EB%8A%94%EA%B0%80&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ojgmX/hyNSaZK3m0/hPa0b5XiLRvjDhPPqWTdt0/img.png?width=768&amp;amp;height=179&amp;amp;face=0_0_768_179,https://scrap.kakaocdn.net/dn/bRbi8L/hyNQ2I4h44/gsw0XkOtYemwuB2HzE05kK/img.png?width=2302&amp;amp;height=536&amp;amp;face=0_0_2302_536,https://scrap.kakaocdn.net/dn/2OvIu/hyNRbMKZTm/KhNpfSzHW9NyO2xpgHgr11/img.png?width=2362&amp;amp;height=1110&amp;amp;face=0_0_2362_1110');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;클래스는 언제 로딩되고 초기화되는가? (feat. 싱글톤)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;클래스는 언제 로딩되고 초기화되는가?&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Eager Initialization&lt;/p&gt;
&lt;pre id=&quot;code_1648556751091&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class EagerSingleton {
    private static EagerSingleton instance = new EagerSingleton();

    // private constructor
    private EagerSingleton() {
    }

    public static EagerSingleton getInstance() {
        return instance;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;간단하게 싱글톤 메소드 생성&lt;/li&gt;
&lt;li&gt;클라이언트에서 사용하지 않아도 생성됨&lt;/li&gt;
&lt;li&gt;getInstance() 메소드 말고 다른 static 메소드 추가해서 호출하면 EagerSingleton 클래스 로드 되면서 인스턴스 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Lazy Initialization&lt;/p&gt;
&lt;pre id=&quot;code_1648561709452&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class LazyInitializedSingleton {

    private static LazyInitializedSingleton instance;

    private LazyInitializedSingleton(){}

    public static LazyInitializedSingleton getInstance(){
        if(instance == null){
            instance = new LazyInitializedSingleton();
        }
        return instance;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Eager&amp;nbsp;Initialization 단점 보완&lt;/li&gt;
&lt;li&gt;멀티 쓰레드 환경에서 각 쓰레드마다 instance == null일 경우 쓰레드마다 생성됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Thread-Safe Singleton&lt;/p&gt;
&lt;pre id=&quot;code_1648562001276&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class ThreadSafeSingleton {

    private static ThreadSafeSingleton instance;

    private ThreadSafeSingleton(){}

    public static synchronized ThreadSafeSingleton getInstance(){
        if(instance == null){
            instance = new ThreadSafeSingleton();
        }
        return instance;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인스턴스 생성하는 메소드에 synchronized 추가&lt;/li&gt;
&lt;li&gt;하나의 쓰레드만 접근 가능하므로 비효율&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Double-Checked Locking&lt;/p&gt;
&lt;pre id=&quot;code_1648563082342&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static ThreadSafeSingleton getInstanceUsingDoubleLocking(){
    if(instance == null){
        synchronized (ThreadSafeSingleton.class) {
            if(instance == null){
                instance = new ThreadSafeSingleton();
            }
        }
    }
    return instance;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;synchronized 앞뒤로 인스턴스 체크 (쓰레드 관련된 부분이라 volatile 키워드를 알면 좋을듯 싶다)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Bill pugh Solution&lt;/p&gt;
&lt;pre id=&quot;code_1648563643900&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class BillPughSingleton {

    private BillPughSingleton(){}

    private static class SingletonHelper{
        private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }

    public static BillPughSingleton getInstance(){
        return SingletonHelper.INSTANCE;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Lazy Loading 가능&lt;/li&gt;
&lt;li&gt;BillPughSingleton 클래스가 로드되더라도 static SingletonHelper 클래스는 로드되지 않음&lt;/li&gt;
&lt;li&gt;쓰레드 세이프 (클래스 로드되는 시점이 다른 것을 활용한 방법으로 jvm에게 인스턴스 생성 맡기는 느낌)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. Relection을 활용한 싱글톤 망가뜨리기&lt;/p&gt;
&lt;pre id=&quot;code_1648564823011&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    public static void main(String[] args) {
        EagerInitializedSingleton instanceOne = EagerInitializedSingleton.getInstance();
        EagerInitializedSingleton instanceTwo = null;
        try {
            Constructor[] constructors = EagerInitializedSingleton.class.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                //Below code will destroy the singleton pattern
                constructor.setAccessible(true);
                instanceTwo = (EagerInitializedSingleton) constructor.newInstance();
                break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(instanceOne.hashCode());
        System.out.println(instanceTwo.hashCode());
    }&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;constructor.setAccessible(true)를 통해서 싱글톤을 망가뜨리고 해당 싱글톤의 private 생성자 메소드 접근 가능&lt;/li&gt;
&lt;li&gt;싱글톤 클래스 생성자도 접근 가능해졌으므로 여러 인스턴스 생성가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. Enum Singleton&lt;/p&gt;
&lt;pre id=&quot;code_1648565113505&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public enum EnumSingleton {
    INSTANCE;
    public void someMethod(String param) {
        // some class member
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;enum이니깐 스레드 세이프&lt;/li&gt;
&lt;li&gt;직렬화/역직렬화 고민할 필요 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;reference&lt;/u&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1648565225511&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;All About the Singleton - DZone Java&quot; data-og-description=&quot;This guide to the Singleton design pattern will help narrow down some appropriate scopes and uses, such as serialization and eager and lazy loading.&quot; data-og-host=&quot;dzone.com&quot; data-og-source-url=&quot;https://dzone.com/articles/all-about-the-singleton&quot; data-og-url=&quot;https://dzone.com/articles/all-about-the-singleton&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cF8DPW/hyNR7INyke/NVkaVsye9HPaoAJ17D7Sp1/img.jpg?width=1024&amp;amp;height=640&amp;amp;face=0_0_1024_640,https://scrap.kakaocdn.net/dn/bYdxFb/hyNRbF27Jk/Ne7EeKGhewDRZMhJi1HEKk/img.jpg?width=1024&amp;amp;height=640&amp;amp;face=0_0_1024_640&quot;&gt;&lt;a href=&quot;https://dzone.com/articles/all-about-the-singleton&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dzone.com/articles/all-about-the-singleton&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cF8DPW/hyNR7INyke/NVkaVsye9HPaoAJ17D7Sp1/img.jpg?width=1024&amp;amp;height=640&amp;amp;face=0_0_1024_640,https://scrap.kakaocdn.net/dn/bYdxFb/hyNRbF27Jk/Ne7EeKGhewDRZMhJi1HEKk/img.jpg?width=1024&amp;amp;height=640&amp;amp;face=0_0_1024_640');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;All About the Singleton - DZone Java&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This guide to the Singleton design pattern will help narrow down some appropriate scopes and uses, such as serialization and eager and lazy loading.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;dzone.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;​&lt;/p&gt;
&lt;figure id=&quot;og_1648565233654&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;디자인패턴 - 싱글톤 패턴&quot; data-og-description=&quot;개요 싱글톤 패턴의 다양한 구현 방법을 알아본다. Thread Safe 한 싱글톤 패턴의 구현도 포함한다. volatile 과 memory consistency 도 조금 알아본다. 순서요약 Eager Initialization (Early Loading) Static Block Initiali&quot; data-og-host=&quot;yaboong.github.io&quot; data-og-source-url=&quot;https://yaboong.github.io/design-pattern/2018/09/28/thread-safe-singleton-patterns/&quot; data-og-url=&quot;https://yaboong.github.io/design-pattern/2018/09/28/thread-safe-singleton-patterns/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/zbfSd/hyNQW9YMn3/D6N70BEqpYWOB00JKZNdHk/img.png?width=492&amp;amp;height=417&amp;amp;face=0_0_492_417&quot;&gt;&lt;a href=&quot;https://yaboong.github.io/design-pattern/2018/09/28/thread-safe-singleton-patterns/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yaboong.github.io/design-pattern/2018/09/28/thread-safe-singleton-patterns/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/zbfSd/hyNQW9YMn3/D6N70BEqpYWOB00JKZNdHk/img.png?width=492&amp;amp;height=417&amp;amp;face=0_0_492_417');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;디자인패턴 - 싱글톤 패턴&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;개요 싱글톤 패턴의 다양한 구현 방법을 알아본다. Thread Safe 한 싱글톤 패턴의 구현도 포함한다. volatile 과 memory consistency 도 조금 알아본다. 순서요약 Eager Initialization (Early Loading) Static Block Initiali&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yaboong.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>JAVA/디자인패턴</category>
      <author>H!GHR</author>
      <guid isPermaLink="true">https://jjjayyy.tistory.com/108</guid>
      <comments>https://jjjayyy.tistory.com/108#entry108comment</comments>
      <pubDate>Fri, 25 Mar 2022 01:49:19 +0900</pubDate>
    </item>
    <item>
      <title>[디자인패턴] 퍼사드 (Facade Pattern)</title>
      <link>https://jjjayyy.tistory.com/107</link>
      <description>&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;생성패턴 (Creational Pattern)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;구조패턴 (&lt;span style=&quot;color: #000000;&quot;&gt;Structural Pattern)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;b&gt;행위패턴 (Behavioral Pattern)&lt;/b&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- 추상 팩토리 (Abstract Factory)&lt;br /&gt;- 팩토리 메소드 (Factory Method)&lt;br /&gt;- 프로토타입 (Prototype)&lt;br /&gt;- 빌더 (Builder)&lt;br /&gt;- 싱글톤 (Singleton)&lt;/td&gt;
&lt;td&gt;- 어댑터 (Adapter)&lt;br /&gt;- 컴포지트 (Composite)&lt;br /&gt;- 브리지 (Bridge)&lt;br /&gt;- 데코레이터 (Decorator)&lt;br /&gt;- 플라이웨이트 (Flyweight)&amp;nbsp;&lt;br /&gt;- 프록시 (Proxy)&lt;br /&gt;- &lt;span style=&quot;color: #ee2323;&quot;&gt;퍼사드 (Facade)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;- 책임 연쇄 (Chain of Responsibility)&lt;br /&gt;- 커맨드 (Command)&lt;br /&gt;- 인터프리터 (Interpreter)&lt;br /&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이터레이터 (Iterator)&amp;nbsp;&lt;/span&gt;&lt;br /&gt;- 미디에이터 (Mediator)&lt;br /&gt;- 비지터 (Visitor)&lt;br /&gt;- 템플릿 메소드 (Template Method)&lt;br /&gt;- 스테이트 (State)&lt;br /&gt;- 옵저버 (Observer)&lt;br /&gt;- 메멘토 (Memento)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;구조패턴 (Structural Pattern)&lt;br /&gt;&amp;gt; 클래스나 객체를 조합해 더 큰 구조를 만드는 패턴&lt;br /&gt;&amp;gt; 객체들을 묶어서 새로운 기능 제공&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Facade 패턴?&lt;/b&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;facade는 프랑스어로 건물의 정면이라는 뜻&lt;/li&gt;
&lt;li&gt;시스템 내부의 순서 등 상관없이 외부에서는 단순한 API만 호출&lt;/li&gt;
&lt;li&gt;외부와 결합이 줄어들어 재사용이 쉬워짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MSgi3/btrw64b9iwt/gRv5lSjOi7kdADOAobky30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MSgi3/btrw64b9iwt/gRv5lSjOi7kdADOAobky30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MSgi3/btrw64b9iwt/gRv5lSjOi7kdADOAobky30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMSgi3%2Fbtrw64b9iwt%2FgRv5lSjOi7kdADOAobky30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;400&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;Facade &lt;/span&gt;&lt;/b&gt;패턴 구조&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x9NVF/btrwZWZ8YDz/22F4SfkOLjdRd2h560j6B1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x9NVF/btrwZWZ8YDz/22F4SfkOLjdRd2h560j6B1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x9NVF/btrwZWZ8YDz/22F4SfkOLjdRd2h560j6B1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx9NVF%2FbtrwZWZ8YDz%2F22F4SfkOLjdRd2h560j6B1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;524&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;524&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;적용 예제&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 메뉴 -&amp;gt; 결제 -&amp;gt; 주문접수 순서로 흘러가는 로직을 DeliveryMaker 하나로 묶어 해결&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;487&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kWhWz/btrwZ0IQDT1/55H5HOULVCCrz1tjrAUpKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kWhWz/btrwZ0IQDT1/55H5HOULVCCrz1tjrAUpKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kWhWz/btrwZ0IQDT1/55H5HOULVCCrz1tjrAUpKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkWhWz%2FbtrwZ0IQDT1%2F55H5HOULVCCrz1tjrAUpKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;716&quot; height=&quot;487&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;487&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;a href=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot;&gt;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1648048478453&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - jjjayyy/Design_Pattern_Sample_With_Springboot&quot; data-og-description=&quot;Contribute to jjjayyy/Design_Pattern_Sample_With_Springboot development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot; data-og-url=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bmwgs5/hyNNoenL15/1KBlWAvT3cwJWwbIpyeI1K/img.png?width=1200&amp;amp;height=600&amp;amp;face=950_121_1053_233&quot;&gt;&lt;a href=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bmwgs5/hyNNoenL15/1KBlWAvT3cwJWwbIpyeI1K/img.png?width=1200&amp;amp;height=600&amp;amp;face=950_121_1053_233');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - jjjayyy/Design_Pattern_Sample_With_Springboot&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to jjjayyy/Design_Pattern_Sample_With_Springboot development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;reference by &lt;a href=&quot;https://refactoring.guru/design-patterns/facade&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://refactoring.guru/design-patterns/facade&lt;/a&gt;&lt;/p&gt;</description>
      <category>JAVA/디자인패턴</category>
      <author>H!GHR</author>
      <guid isPermaLink="true">https://jjjayyy.tistory.com/107</guid>
      <comments>https://jjjayyy.tistory.com/107#entry107comment</comments>
      <pubDate>Thu, 24 Mar 2022 00:24:57 +0900</pubDate>
    </item>
    <item>
      <title>[디자인패턴] 이터레이터 (Iterator Pattern)</title>
      <link>https://jjjayyy.tistory.com/106</link>
      <description>&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 100px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.4496%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;생성패턴 (Creational Pattern)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.217%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;구조패턴 (&lt;span style=&quot;color: #000000;&quot;&gt;Structural Pattern)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;b&gt;행위패턴 (Behavioral Pattern)&lt;/b&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 80px;&quot;&gt;
&lt;td style=&quot;width: 33.4496%; height: 80px;&quot;&gt;- 추상 팩토리 (Abstract Factory)&lt;br /&gt;- 팩토리 메소드 (Factory Method)&lt;br /&gt;- 프로토타입 (Prototype)&lt;br /&gt;- 빌더 (Builder)&lt;br /&gt;- 싱글톤 (Singleton)&lt;/td&gt;
&lt;td style=&quot;width: 33.217%; height: 80px;&quot;&gt;- 어댑터 (Adapter)&lt;br /&gt;- 컴포지트 (Composite)&lt;br /&gt;- 브리지 (Bridge)&lt;br /&gt;- 데코레이터 (Decorator)&lt;br /&gt;- 플라이웨이트 (Flyweight)&amp;nbsp;&lt;br /&gt;- 프록시 (Proxy)&lt;br /&gt;- 퍼사드 (Facade)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 80px;&quot;&gt;- 책임 연쇄 (Chain of Responsibility)&lt;br /&gt;- 커맨드 (Command)&lt;br /&gt;- 인터프리터 (Interpreter)&lt;br /&gt;- &lt;span style=&quot;color: #ee2323;&quot;&gt;이터레이터 (Iterator)&amp;nbsp;&lt;/span&gt;&lt;br /&gt;- 미디에이터 (Mediator)&lt;br /&gt;- 비지터 (Visitor)&lt;br /&gt;- 템플릿 메소드 (Template Method)&lt;br /&gt;- 스테이트 (State)&lt;br /&gt;- 옵저버 (Observer)&lt;br /&gt;- 메멘토 (Memento)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;행위패턴 (Behavioral Pattern)&lt;br /&gt;&amp;gt; 객체나 클래스 사이의 상호작용 방법이나 책임 분배 방법을 정의하는 패턴&lt;br /&gt;&amp;gt; 객체 사이의 결합도 최소화에 중점&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Iterator 패턴?&lt;/b&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컬렉션 구현 방법을 숨길 수 있음&lt;/li&gt;
&lt;li&gt;컬렉션 내 모든 항목 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;b&gt;Iterator&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;패턴 구조&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;275&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DbhLR/btrvhOCkI89/q6S18dU5jMqmdYayYOGx2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DbhLR/btrvhOCkI89/q6S18dU5jMqmdYayYOGx2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DbhLR/btrvhOCkI89/q6S18dU5jMqmdYayYOGx2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDbhLR%2FbtrvhOCkI89%2Fq6S18dU5jMqmdYayYOGx2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;275&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;275&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Aggregate : Iterator 역할을 만들어내는 인터페이스 정의&lt;/li&gt;
&lt;li&gt;Iterator : 요소를 순서대로 검색해가는 인터페이스 정의&lt;/li&gt;
&lt;li&gt;ConcreteAggregate : Aggregate가 정의한 인터페이스를 구현&lt;/li&gt;
&lt;li&gt;ConcreteIterator : Iterator가 정의한 인터페이스를 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Iterator 패턴이 필요한 상황&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1647437831676&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;        int[] arr = {1,2,3,4,5};
        List&amp;lt;Integer&amp;gt; list = Arrays.stream(arr).boxed().collect(Collectors.toList());
        
        for(int i = 0; i &amp;lt; arr.length; i++) { System.out.println(arr[i]); }
        
        for(int i = 0; i &amp;lt; list.size(); i++) { System.out.println(list.get(i)); }&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다른 자료구조(위의 예제로는 배열, 리스트)를 하나씩 조회해보고 싶으면 각자 다른 루프를 돌려야 함&lt;/li&gt;
&lt;li&gt;이터레이터 패턴을 적용하면 반복되는 자료구조는 다형적으로 사용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;적용 예제&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;819&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kFvT6/btrvasM8BZ4/OBPnwepgx07OkjlskJwY1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kFvT6/btrvasM8BZ4/OBPnwepgx07OkjlskJwY1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kFvT6/btrvasM8BZ4/OBPnwepgx07OkjlskJwY1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkFvT6%2FbtrvasM8BZ4%2FOBPnwepgx07OkjlskJwY1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;819&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;819&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 치킨 메뉴와 피자 메뉴를 하나씩 확인하는 예제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647436618669&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - jjjayyy/Design_Pattern_Sample_With_Springboot&quot; data-og-description=&quot;Contribute to jjjayyy/Design_Pattern_Sample_With_Springboot development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot; data-og-url=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/uQaMn/hyNI91DaDn/KVHvyMCvTVJhmPBV1xNZoK/img.png?width=1200&amp;amp;height=600&amp;amp;face=950_121_1053_233&quot;&gt;&lt;a href=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/jjjayyy/Design_Pattern_Sample_With_Springboot&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/uQaMn/hyNI91DaDn/KVHvyMCvTVJhmPBV1xNZoK/img.png?width=1200&amp;amp;height=600&amp;amp;face=950_121_1053_233');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - jjjayyy/Design_Pattern_Sample_With_Springboot&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to jjjayyy/Design_Pattern_Sample_With_Springboot development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>JAVA/디자인패턴</category>
      <category>Design Pattern</category>
      <category>iterator</category>
      <category>java</category>
      <category>디자인패턴</category>
      <category>이터레이터</category>
      <category>자바</category>
      <author>H!GHR</author>
      <guid isPermaLink="true">https://jjjayyy.tistory.com/106</guid>
      <comments>https://jjjayyy.tistory.com/106#entry106comment</comments>
      <pubDate>Mon, 7 Mar 2022 02:14:14 +0900</pubDate>
    </item>
    <item>
      <title>2021 상반기 회고 (1~6월)</title>
      <link>https://jjjayyy.tistory.com/105</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #e0f2f7;&quot;&gt;코딩테스트 알고리즘 준비&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 알고리즘 공부에 대해 회의적이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서 큰 도움이 되는거 같지도 않고... 문제를 풀기위해 학습하는 느낌이 강했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이직을 위한 1차 관문이 일반적으로 코딩테스트이기에 준비는 해야했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학업을 위한 공부와 문제풀기를 위한 공부는 따로 있다고 생각해서,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A-Z까지 모든 알고리즘을 정석으로 공부하기 보다는 코딩테스트 통과를 목적으로 준비했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;1) 어떤 문제를 풀어야할까 ?&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알고리즘을 연구해 코딩계에 내 이름이 박힌 알고리즘을 만들고 싶진 않아서 효율적으로 풀거만 알아보기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글링하다가 찾은 &lt;a href=&quot;https://www.youtube.com/watch?v=ukkLCl9yBvE&amp;amp;ab_channel=%EB%8F%99%EB%B9%88%EB%82%98%20&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;동빈나님 유튜브&lt;/a&gt;에 어느정도 가이드라인이 있어서 참고해 방향을 잡았는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그간 코딩테스트를 풀면서 버벅이던 부분과 같은 부분이어서 집중 보완하기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;탐색 / DFS / BFS 등 전체를 탐색해 가장 효율적인 루트 하나를 찾아내는 문제가 바로 그것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;2) 어떻게 풀어야할까 ?&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://leetcode.com/interview/?gclid=CjwKCAjwjJmIBhA4EiwAQdCbxoho-x7ZFjcBLxdIlhVbFD6TUT3RUtbKTvIIn4k1bc0nplvgOWYgiBoCTyIQAvD_BwE&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;leetcode&lt;/a&gt; / &lt;a href=&quot;https://www.hackerrank.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;hackerrank&lt;/a&gt; / &lt;a href=&quot;https://www.codility.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;codility&lt;/a&gt; / &lt;a href=&quot;https://programmers.co.kr/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;프로그래머스&lt;/a&gt; / &lt;a href=&quot;https://www.acmicpc.net/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;백준&lt;/a&gt; 등등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러군데 문제를 살펴봤는데, 주로 푼건 프로그래머스와 백준이었던거 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 프로그래머스 고득점 kit와 백준 단계별 풀기를 활용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하루에 한문제씩 출근하자마자 30분 시간을 정해서 풀고 타임오버될때까지 안풀리면 찾아보고 풀고 끝!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한문제를 오래 고민하여 완벽하게 이해하는거보다 여러 문제 푸는 방식 익히는게 더 좋을거 같다고 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오래잡고 있어봐야 재미도 없고 푸는 목적은 코딩테스트 통과이기 때문에 딱 통과할 정도의 투자를 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/timer-25-the-minimalist-t/gmdbcklinofignhfmibchnmgjcocccbh?hl=ko&quot;&gt;https://chrome.google.com/webstore/detail/timer-25-the-minimalist-t/gmdbcklinofignhfmibchnmgjcocccbh?hl=ko&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1627825592970&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Timer 25: 미니멀리스트 타이머&quot; data-og-description=&quot;최소 25 분 타이머. 간단하고 안정적이며 사용하기 쉽습니다.&quot; data-og-host=&quot;chrome.google.com&quot; data-og-source-url=&quot;https://chrome.google.com/webstore/detail/timer-25-the-minimalist-t/gmdbcklinofignhfmibchnmgjcocccbh?hl=ko&quot; data-og-url=&quot;https://chrome.google.com/webstore/detail/timer-25-the-minimalist-t/gmdbcklinofignhfmibchnmgjcocccbh&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dvTm3q/hyK4LwoiHu/tlRyKDzFtwA6xTvoRk8nGK/img.jpg?width=128&amp;amp;height=128&amp;amp;face=0_0_128_128&quot;&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/timer-25-the-minimalist-t/gmdbcklinofignhfmibchnmgjcocccbh?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://chrome.google.com/webstore/detail/timer-25-the-minimalist-t/gmdbcklinofignhfmibchnmgjcocccbh?hl=ko&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dvTm3q/hyK4LwoiHu/tlRyKDzFtwA6xTvoRk8nGK/img.jpg?width=128&amp;amp;height=128&amp;amp;face=0_0_128_128');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Timer 25: 미니멀리스트 타이머&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;최소 25 분 타이머. 간단하고 안정적이며 사용하기 쉽습니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;chrome.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;30분 동안 문제를 잡고 있으려면 타이머가 있어야하는데 크롬 확장프로그램 중 요거를 활용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확장프로그램에 남은 시간도 나오고 종료되면 알람도 띄워주기때문에 나름 쏠쏠하게 사용 가능했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지방 파견 전까지는 꾸준히 1일1문제를 이어오고 있었고, 종종 실전 코테도 보곤했는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나름의 성과라면 프로그래머스에서 한번씩 기업 코테를 보게 해주는데 카카오뱅크 코테 1차 패스정도려나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 2차는 손도 못댔다...(JPA는 해본적이 없어서...ㅠ)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 JPA도 많은 곳에서 활용하는거 같아서 JPA강좌도 인프런에서 구매해뒀다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/ORM-JPA-Basic&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/ORM-JPA-Basic&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1628000690246&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의&quot; data-og-description=&quot;JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., 본 강의는 자바 백엔&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/ORM-JPA-Basic&quot; data-og-url=&quot;https://www.inflearn.com/course/ORM-JPA-Basic&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cCrmNL/hyK7sCiy01/YWQNcdeBEd7av70dcOLhvk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/Zv8tS/hyK6qe2ycu/pkQaFA00gBEizdxdQd1hc0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/hSSMa/hyK7qdpQLW/x8RK0DVcSNBuN4Re53cKxK/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/ORM-JPA-Basic&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/ORM-JPA-Basic&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cCrmNL/hyK7sCiy01/YWQNcdeBEd7av70dcOLhvk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/Zv8tS/hyK6qe2ycu/pkQaFA00gBEizdxdQd1hc0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/hSSMa/hyK7qdpQLW/x8RK0DVcSNBuN4Re53cKxK/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., 본 강의는 자바 백엔&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하반기에는 해당 강좌 시리즈를 주루룩 한번 보고 개인프로젝트를 JPA로 해보고 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 일하는 곳에서는 JPA는 사용하지 않아서 볼때마다 늘 새롭고 짜릿하겠지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한편으론 mybatis를 쓸 때와 JPA를 쓸 때의 장단점이 눈에 보여서 나름 재미도 있을듯 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하반기 회고에는 재밌는 JPA 프로젝트도 올릴 수 있길 바래본다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #e0f2f7;&quot;&gt;공유와 문서화&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상반기에는 상대적으로 여유가 많았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 여유 시간이 있을 때 리펙토링과 소스정리를 해놔야 미래의 내가 바쁠 때 지금의 나에게 고마워할 것이기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;속도 개선을 위한 리펙토링과 개발 편의를 위한 소스정리를 해나갔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리펙토링을 하면서 이런저런 호기심이 생겨(특히 대량데이터 관련) 테스트도 혼자해보다가 사내 wiki가 떠올랐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 팀 중 한 분이 정말 열심히 관리해주셔서 그런지 더 쓰고 싶어진거도 있었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발은 공유와 문서화도 필요하다고 생각해서 나름 테스트해본 것과 삽질한 것 등등 모두 wiki에 올렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(물론 변수명 등등 바꿔서 내 블로그에도 올렸다!)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삽질한거에 대한 정리와 API의 문서화는 바빠도 나중에 짬내서 정리하는게 좋겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 삽질을 하며 시간 낭비를 하지 않을 수 있고 (심지어 예전에 했던 삽질을 또 하는 경우도 봤다ㅋㅋㅋ...그건 나였고...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업데이트 된 API의 기능을 직접 소스 분석하며 찾지 않아도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일하다보면 최신판이 아닌 API 레퍼런스를 종종 보게되는데, 업데이트 된 내용을 몰랐다가 나중에 다른 사람 소스보고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 메소드도 있었구나... 하며 사용한 적이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아는 사람만 보이는 아만보 메소드들을 만들지 않으려면 문서화하는 습관을 들여야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #e0f2f7;&quot;&gt;지방 파견&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공공기관 프로젝트에 투입되어 얼떨결에 지방까지 파견을 가게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔루션은 자사제품이 있는 SI라는 말을 뒤로하고 '회바회!(회사바이회사) 팀바팀!(팀바이팀)'을 외치며 호기롭게 들어갔는데...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;338&quot; width=&quot;486&quot; height=&quot;274&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cl9Lxw/btra8ndsuy0/zaIxDDPGftXKb3D8uMpRxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cl9Lxw/btra8ndsuy0/zaIxDDPGftXKb3D8uMpRxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cl9Lxw/btra8ndsuy0/zaIxDDPGftXKb3D8uMpRxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcl9Lxw%2Fbtra8ndsuy0%2FzaIxDDPGftXKb3D8uMpRxK%2Fimg.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;338&quot; width=&quot;486&quot; height=&quot;274&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 말을 들을걸 그랬나보다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출장 개념으로 며칠 다녀오는건 작은 환기가 되어줄 수 있지만, 몇 달 상주는 개인적인 계획도 틀어지고 심신을 지치게 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SI도 업체 파견 개념이라 자사 서비스가 있는 곳을 원했던건데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차라리 이럴거면 수도권 내 파견이 보장되는 SI로 옮기는게 더 나은 선택이 아닐까 하는 생각도 든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게다가 폐쇄망 업체라 개발자의 생명인 구글링도 못하고 기존 라이브러리만 가져다가 써야하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 회고에도 쓴거 같은데 폐쇄망인 업체는 개인적으로 맞지 않는듯 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하반기 회고에는 지방 상주의 투덜거림보다는 재밌는 개인프로젝트에 대한 얘기가 가득하길 바라며 이만 마쳐야겠다!&lt;/p&gt;</description>
      <category>월간 미생</category>
      <author>H!GHR</author>
      <guid isPermaLink="true">https://jjjayyy.tistory.com/105</guid>
      <comments>https://jjjayyy.tistory.com/105#entry105comment</comments>
      <pubDate>Wed, 4 Aug 2021 00:54:14 +0900</pubDate>
    </item>
    <item>
      <title>문자열 연결 (String Concatenation)</title>
      <link>https://jjjayyy.tistory.com/104</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;들어가며&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;회사에서 여유있을때 소스 리팩토링 좀 해보려고 한번씩 쭉 보고 있는데, 문자열 연결하는 부분이 거의 String.format으로 되어있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;특별히 이렇게 쓴 이유가 있을까??&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 방식이 다른 방법보다 속도나 성능면에서 우수한걸까??&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;라는 궁금증으로 시작해 찾아보게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;문자열 연결 방법 및 테스트&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. (+)연산자 (string + string)&lt;br /&gt;2. StringBuilder&lt;br /&gt;3. String.format&lt;br /&gt;(concat, join 등등 여러 방법이 있지만 주로 사용하는 것들 세가지 정도만 테스트해봤다.)&lt;/p&gt;
&lt;pre id=&quot;code_1620910715215&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    @Test
    public void 문자열_연결_테스트() {
        final int COUNT = 1000000;
        String header = &quot;앞쪽에 붙일 문자열...&quot;;
        String footer = &quot;...뒤에 붙일 문자열&quot;;
        String result;
        long startTime;
         
        startTime = System.currentTimeMillis();
        for(int i = 0; i &amp;lt; COUNT; i++) {
            result = header + &quot;중간내용&quot; + footer + &quot;_&quot; + i;
        }
        System.out.println(&quot;(+)연산자 : &quot; + (System.currentTimeMillis() - startTime) + &quot;ms&quot;);
         
        startTime = System.currentTimeMillis();
        StringBuilder stringBuilder = new StringBuilder();
        for(int i = 0; i &amp;lt; COUNT; i++) {
            stringBuilder.setLength(0);
            stringBuilder.append(header)
                         .append(&quot;중간내용&quot;)
                         .append(footer)
                         .append(&quot;_&quot;)
                         .append(i);
            result = stringBuilder.toString();
        }
        System.out.println(&quot;StringBuilder : &quot; + (System.currentTimeMillis() - startTime) + &quot;ms&quot;);
         
        startTime = System.currentTimeMillis();
        for(int i = 0; i &amp;lt; COUNT; i++) {
            result = String.format(&quot;%s%s%s%s%s&quot;, header, &quot;중간내용&quot;, footer, &quot;_&quot;, i);
        }
        System.out.println(&quot;String.format : &quot; + (System.currentTimeMillis() - startTime) + &quot;ms&quot;);
     }
 
 
// (+)연산자 : 126ms
// StringBuilder : 56ms
// String.format : 1367ms&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1,000,000건 기준으로 StringBuilder가 56ms로 가장 빨랐지만 연결할 문자열이 많아질 경우 가독성은 좋아보이지 않는다.&lt;br /&gt;건수가 많지 않을 경우, 속도차이는 미미했지만 String.format이 좀 더 느린 것을 볼 수 있다.&lt;br /&gt;(ex. 100건 기준&amp;nbsp;&lt;br /&gt;(+)연산자&amp;nbsp;:&amp;nbsp;0ms &lt;br /&gt;StringBuilder&amp;nbsp;:&amp;nbsp;0ms &lt;br /&gt;String.format : 4ms)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;결론&lt;/blockquote&gt;
&lt;pre id=&quot;code_1620911207689&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//String.format 내부의 parse 메서드
    private static Pattern fsPattern = Pattern.compile(formatSpecifier);

    /**
     * Finds format specifiers in the format string.
     */
    private FormatString[] parse(String s) {
        ArrayList&amp;lt;FormatString&amp;gt; al = new ArrayList&amp;lt;&amp;gt;();
        Matcher m = fsPattern.matcher(s);
        for (int i = 0, len = s.length(); i &amp;lt; len; ) {
            if (m.find(i)) {
            ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;String.format은 첫번째 인자로 정규식을 받기 때문에 Pattern / Matcher 클래스를 생성해준다.&lt;br /&gt;&lt;br /&gt;이후 정규식을 검증하는 과정을 거치는데 단순 문자열 연결일 경우 정규식 검증을 위한 클래스 생성과 검증 비용은 불필요하다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 포멧이 필요한게 아니라 단순 문자열 연결일 경우에는 +연산자, StringBuilder를 사용하는 것이 좋다고 생각하며, 건수가 많지 않을 것으로 생각되면 +연산자를 사용해 가독성까지 챙기는게 좋다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://kylewbanks.com/blog/java-string-concatenation-vs-stringbuilder-vs-string-format-performance&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kylewbanks.com/blog/java-string-concatenation-vs-stringbuilder-vs-string-format-performance&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://redfin.engineering/java-string-concatenation-which-way-is-best-8f590a7d22a8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://redfin.engineering/java-string-concatenation-which-way-is-best-8f590a7d22a8&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JAVA</category>
      <author>H!GHR</author>
      <guid isPermaLink="true">https://jjjayyy.tistory.com/104</guid>
      <comments>https://jjjayyy.tistory.com/104#entry104comment</comments>
      <pubDate>Thu, 13 May 2021 22:28:51 +0900</pubDate>
    </item>
    <item>
      <title>Date, Calendar 대신 LocalDate</title>
      <link>https://jjjayyy.tistory.com/103</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Date, Calendar 클래스의 문제점&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://d2.naver.com/helloworld/645609&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Naver D2 - JAVA의 날짜와 시간 API&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;예전에 본 글이지만 정리할 생각은 따로 없었는데, 사내 개발 자료 공유 차원에서 wiki에 정리하다보니 블로그 생각도 나서 간만에 글을 쓰게 되었다.&lt;/p&gt;
&lt;p&gt;(위 글의 요약에 불과하며 직접 들어가서 보는걸 추천합니다!)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;1)&amp;nbsp;불변&amp;nbsp;객체가&amp;nbsp;아니다&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;set&amp;nbsp;메서드가&amp;nbsp;있어서&amp;nbsp;악의적으로&amp;nbsp;값&amp;nbsp;변경시&amp;nbsp;기존&amp;nbsp;사용하는&amp;nbsp;date&amp;nbsp;값의&amp;nbsp;side&amp;nbsp;effect가&amp;nbsp;있을&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2)&amp;nbsp;int&amp;nbsp;상수&amp;nbsp;필드&amp;nbsp;남용&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;calendar.add(Calendar.SECOND, 2);&lt;/blockquote&gt;
&lt;p&gt;첫번째 파라미터에 Calendar.JUNE 등 엉뚱한 상수가 들어가도 컴파일 시점에서 확인이 어렵다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3) 헷갈리는 월 지정&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;calendar.set(2021, 5, 3);&lt;/blockquote&gt;
&lt;p&gt;1월 = 0으로 표현되어 예제의 값은 Calendar.JUNE과 같다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4) 일관성 없는 요일 상수&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;어떤 메서드에서는 일요일 = 0, 어떤 메서드에서는 일요일 = 1&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5) Date와 Calendar의 역할 분담&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;날짜 계산은 Date 클래스만으로 부족해 Calendar 객체를 생성해야하는데 생성 비용도 비싸고 번거롭다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;6) java.util.Date 하위 클래스 문제&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;LocalDate의 사용&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;LocalDate로 년월일 구하고 파싱하고 등등은 다른 분들이 깔끔하게 정리해주신게 많다!&lt;/p&gt;
&lt;p&gt;그래서 나는 주로 사용하였던 localdate 예시 몇가지만 올리고 마무리해야겠다.&lt;/p&gt;
&lt;pre id=&quot;code_1620049952512&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Test
public void 현재날짜_스트링포멧_적용() throws Exception {
    String nowYearMonth = LocalDate.now().format(DateTimeFormatter.ofPattern(&quot;yyyyMM&quot;));        // yyyyMMdd로 포멧 변환시 일자까지 변환 가능
    assertThat(nowYearMonth, is(&quot;202105&quot;));                                                     // Test Pass (테스트 현재 날짜 : 20210503)
}
 
@Test
public void 스트링날짜_localdate형식으로_파싱() throws Exception {
    String dateStr = &quot;20210503&quot;;
     
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(&quot;yyyyMMdd&quot;);
    LocalDate parsedDate = LocalDate.parse(dateStr, formatter);
     
    assertThat(parsedDate, is(LocalDate.now()));                                                // Test Pass (테스트 현재 날짜 : 20210503)
}
 
 
@Test
public void 만나이_계산() throws Exception {
    String birthDate = &quot;19891111&quot;;
    String standardYm = &quot;202105&quot;;
     
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(&quot;yyyyMMdd&quot;);
    LocalDate parsedBirthDate = LocalDate.parse(birthDate, formatter);
    LocalDate parsedStandardYm = LocalDate.parse(standardYm + &quot;01&quot;, formatter);
     
    // parsedStandardYm.with(TemporalAdjusters.lastDayOfMonth() : 기준월의 마지막날짜 기준으로 하기 위함 (기대값 : 20210531)
    int age = parsedBirthDate.until(parsedStandardYm.with(TemporalAdjusters.lastDayOfMonth())).getYears();
     
    assertThat(age, is(31));                                                                    // Test Pass
}
 
 
@Test
public void 기간_계산() throws Exception {
    String targetDt = &quot;20210503&quot;;                // 목표일자            
    String standardDt = &quot;20200503&quot;;             // 기준일자
     
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(&quot;yyyyMMdd&quot;);
    LocalDate targetLocalDt = LocalDate.parse(targetDt, formatter);
    LocalDate standardLocalDt = LocalDate.parse(standardDt, formatter);
     
    //ChronoUnit.DAYS.between(일수 차이), ChronoUnit.YEARS.between(년수 차이) 필요에 따라 변경 가능
    int workPeriod = (int) ChronoUnit.MONTHS.between(standardLocalDt, targetLocalDt);
     
    assertThat(workPeriod, is(12));                                                // Test Pass
}
 
 
@Test
public void 날짜_영문_표시() throws Exception {
    String engMonthShortName = LocalDate.of(2021, 01, 01).getMonth().getDisplayName(TextStyle.SHORT, Locale.US);
    String engDayShortName = LocalDate.of(2021, 01, 01).getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.US);
     
    String engMonthFullName = LocalDate.of(2021, 01, 01).getMonth().getDisplayName(TextStyle.FULL, Locale.US);
    String engDayFullName = LocalDate.of(2021, 01, 01).getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.US);
     
    assertThat(engMonthShortName, is(&quot;Jan&quot;));                                                   // Test Pass
    assertThat(engDayShortName, is(&quot;Fri&quot;));                                                     // Test Pass
     
    assertThat(engMonthFullName, is(&quot;January&quot;));                                                // Test Pass
    assertThat(engDayFullName, is(&quot;Friday&quot;));                                                   // Test Pass
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>JAVA</category>
      <author>H!GHR</author>
      <guid isPermaLink="true">https://jjjayyy.tistory.com/103</guid>
      <comments>https://jjjayyy.tistory.com/103#entry103comment</comments>
      <pubDate>Mon, 3 May 2021 23:02:26 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 알고리즘 연습 문제 : 카펫(자바/JAVA)</title>
      <link>https://jjjayyy.tistory.com/102</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/42842?language=java&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/42842?language=java&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1608084723211&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 카펫&quot; data-og-description=&quot;Leo는 카펫을 사러 갔다가 아래 그림과 같이 중앙에는 노란색으로 칠해져 있고 테두리 1줄은 갈색으로 칠해져 있는 격자 모양 카펫을 봤습니다. Leo는 집으로 돌아와서 아까 본 카펫의 노란색과 &quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/42842?language=java&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/42842?language=java&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mxPbC/hyIAI2CyMt/MPkJkxLfaxzdhNBSVGOGUK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/fqbaB/hyIAMxbLI5/urZnj0IMaqJBbOiS3uXN00/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/QCNfG/hyIAVHEY5S/l56eBwB7cNDhfFh4JRWhd1/img.png?width=843&amp;amp;height=636&amp;amp;face=0_0_843_636&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/42842?language=java&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/42842?language=java&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mxPbC/hyIAI2CyMt/MPkJkxLfaxzdhNBSVGOGUK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/fqbaB/hyIAMxbLI5/urZnj0IMaqJBbOiS3uXN00/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/QCNfG/hyIAVHEY5S/l56eBwB7cNDhfFh4JRWhd1/img.png?width=843&amp;amp;height=636&amp;amp;face=0_0_843_636');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size18&quot;&gt;코딩테스트 연습 - 카펫&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size18&quot;&gt;Leo는 카펫을 사러 갔다가 아래 그림과 같이 중앙에는 노란색으로 칠해져 있고 테두리 1줄은 갈색으로 칠해져 있는 격자 모양 카펫을 봤습니다. Leo는 집으로 돌아와서 아까 본 카펫의 노란색과&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size18&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;pre id=&quot;code_1608086233627&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;   public static int[] solution(int brown, int yellow) {
   	 int sum = brown + yellow;
         int heigth = 0;

         for(int i = 1; i &amp;lt; sum; i++) {
             if(sum % i == 0) {
                 if(sum / i &amp;lt; i) {
                     break;
                 }
                 heigth = i;
             }
         }
         
         int[] result = {sum / heigth, heigth};
         
         return result;
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;처음 생각은 이랬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1) 사각형 넓이 = 가로 x 세로&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2) 주어진 사각형 넓이 = brown + yellow&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3) brown + yellow = x * y&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4) x와 y는 최대값이어야된다고 생각했다. (brown = 24 / yellow = 24 / 기대값 = [8, 6])&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;테스트 케이스는 무난하게 돌았지만 결과적으론 실패&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;전체 사각형 개수는 맞지만 색깔별 개수가 달라져서 실패가 되는듯 싶었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그래서 다시 블록을 만들면서 개수를 확인하기로 했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1608087784300&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    public static int[] solution(int brown, int yellow) {

        int width = 0;
        int height = 0;

        for(int i = 1; i &amp;lt;= yellow; i++) {
            if(yellow == 1) {
                height = i + 2;
                width = (brown + yellow) / height;
                break;
            }

            if(yellow % i == 0) {
                if(brown == i * 2 + (yellow / i + 2) * 2) {
                    height = i + 2;
                    width = yellow / height;
                    break;
                }
            }
        }

        int[] result = {width , height};

        return result;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;yellow를 기준으로 brown 개수를 구하고 맞으면 가로 세로 길이를 구했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;for loop의 i는 yellow의 세로길이라고 생각하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;brown의 가로개수는 (yellow 가로길이 + 2) * 2&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;brown의 세로개수는 (yellow 세로길이(위 코드 기준 i) + 2) * 2&lt;/p&gt;</description>
      <category>기초CS/알고리즘</category>
      <author>H!GHR</author>
      <guid isPermaLink="true">https://jjjayyy.tistory.com/102</guid>
      <comments>https://jjjayyy.tistory.com/102#entry102comment</comments>
      <pubDate>Wed, 16 Dec 2020 12:16:26 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 알고리즘 연습 문제 : 괄호 변환(자바/JAVA)</title>
      <link>https://jjjayyy.tistory.com/101</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/60058?language=java&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/60058?language=java&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1607611037570&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 괄호 변환&quot; data-og-description=&quot;카카오에 신입 개발자로 입사한 콘은 선배 개발자로부터 개발역량 강화를 위해 다른 개발자가 작성한 소스 코드를 분석하여 문제점을 발견하고 수정하라는 업무 과제를 받았습니다. 소스를 컴&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/60058?language=java&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/60058?language=java&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b1FzCK/hyIwCWpVU6/RcFeR9bk2aVeK6KYwXJFd0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/eN4l28/hyIwtyptIO/SiK2WL8kkQjbtl6gXDUSF1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/60058?language=java&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/60058?language=java&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b1FzCK/hyIwCWpVU6/RcFeR9bk2aVeK6KYwXJFd0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/eN4l28/hyIwtyptIO/SiK2WL8kkQjbtl6gXDUSF1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 괄호 변환&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;카카오에 신입 개발자로 입사한 콘은 선배 개발자로부터 개발역량 강화를 위해 다른 개발자가 작성한 소스 코드를 분석하여 문제점을 발견하고 수정하라는 업무 과제를 받았습니다. 소스를 컴&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;pre id=&quot;code_1607611914284&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    public static String solution(String p) {
        if(&quot;&quot;.equals(p)) {
            return p;
        }

        String u = &quot;&quot;;
        String v = &quot;&quot;;
        StringBuilder builder = new StringBuilder();

        char startBracket = p.charAt(0);
        int bracketCnt = 0;
        boolean isCorrectWord = startBracket == '(';

        for(int i = 0; i &amp;lt; p.length(); i++) {
            bracketCnt = startBracket == p.charAt(i) ? bracketCnt + 1 : bracketCnt - 1;

            if(bracketCnt &amp;lt; 0) {
                u = p.substring(0, i);
                v = p.substring(i, p.length());
                break;
            }
        }

        if(isCorrectWord) {
            if(&quot;&quot;.equals(v)) {
                return p;
            } else {
                builder.append(u);
                builder.append(solution(v));
            }
        } else {
            builder.append(&quot;(&quot;);
            builder.append(solution(v));
            builder.append(&quot;)&quot;);

            if(u.length() &amp;gt; 0)	{
                String tempStr = u.substring(1,u.length()-1);
                int index = 0;
                StringBuilder tempBuilder = new StringBuilder(u.substring(1,u.length()-1));
                if(tempStr.charAt(0) == ')') {
                    for(int i = 0; i &amp;lt; tempStr.length(); i++) {
                        if(tempStr.charAt(i) == '(') {
                            index = i;
                        }
                    }
                    tempStr = tempStr.substring(index, tempStr.length());

                    for(int i = 0; i &amp;lt; index; i++) {
                        tempStr += &quot;)&quot;;
                    }
                }

                if(tempBuilder.charAt(0) == ')') {
                    tempBuilder.reverse();
                }
                builder.append(tempStr);
            }
        }
        return  builder.toString();
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;처음 생각한 코드는 이렇다&lt;/p&gt;
&lt;p&gt;테스트는 통과했지만 채점에서 죽죽 붉은줄이 뜬다...&lt;/p&gt;
&lt;p&gt;여기저기 구글링을 해본 결과&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;4-4. u의 첫 번째와 마지막 문자를 제거하고, 나머지 문자열의 괄호 방향을 뒤집어서 뒤에 붙입니다.&lt;/blockquote&gt;
&lt;p&gt;요문장에서 reverse로 하면 12번부터 주르륵 틀린다고 나올거란거다&lt;/p&gt;
&lt;p&gt;문장 그대로 뒤집어서 뒤에 붙여야한다&lt;/p&gt;
&lt;p&gt;그리고 올바른 문장을 확인하는 부분이 너무 부실해서 이것도 문자열 u에 대해 확인하는 메소드로 수정했다.&lt;/p&gt;
&lt;pre id=&quot;code_1607613151133&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    public String solution(String p) {
        if(&quot;&quot;.equals(p)) {
            return &quot;&quot;;
        }

        String u = &quot;&quot;;
        String v = &quot;&quot;;
        StringBuilder builder = new StringBuilder();

        char startBracket = p.charAt(0);
        int bracketCnt = 0;

        for(int i = 0; i &amp;lt; p.length(); i++) {
            bracketCnt = startBracket == p.charAt(i) ? bracketCnt + 1 : bracketCnt - 1;

            if(bracketCnt == 0) {
                u = p.substring(0, i+1);
                v = p.substring(i+1, p.length());
                break;
            }
        }

        if(isCorrect(u)) {
            builder.append(u);
            builder.append(solution(v));
        } else {
            builder.append(&quot;(&quot;);
            builder.append(solution(v));
            builder.append(&quot;)&quot;);

            String tempStr = u.substring(1,u.length()-1);
            tempStr = reverse(tempStr);

            builder.append(tempStr);
        }

        return  builder.toString();
    }
    
    private static boolean isCorrect (String str) {
    	int bracketCnt = 0;
    	
    	for(int i = 0; i &amp;lt; str.length(); i++) {
    		bracketCnt = str.charAt(i) == '(' ? bracketCnt + 1 : bracketCnt - 1;
    		
    		if(bracketCnt &amp;lt; 0) 	return false;
    		
    	}
    	return true;
    }    
    
    private static String reverse (String str) {
    	StringBuilder builder = new StringBuilder();
    	for(int i = 0; i &amp;lt; str.length(); i++) {
    		if(str.charAt(i) == ')') {
    			builder.append('(');
    		} else {
    			builder.append(')');
    		}    		
    	}
    	return builder.toString(); 
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ps. )()()()( &amp;lt;- 요 테스트를 추가해서 디버깅해본게 나름 도움이 되었다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기초CS/알고리즘</category>
      <author>H!GHR</author>
      <guid isPermaLink="true">https://jjjayyy.tistory.com/101</guid>
      <comments>https://jjjayyy.tistory.com/101#entry101comment</comments>
      <pubDate>Fri, 11 Dec 2020 00:13:49 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 알고리즘 연습 문제 : 키패드 누르기(자바/JAVA)</title>
      <link>https://jjjayyy.tistory.com/100</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/67256?language=java&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/67256?language=java&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1607232242001&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 키패드 누르기&quot; data-og-description=&quot;[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] &amp;quot;right&amp;quot; &amp;quot;LRLLLRLLRRL&amp;quot; [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] &amp;quot;left&amp;quot; &amp;quot;LRLLRRLLLRR&amp;quot; [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] &amp;quot;right&amp;quot; &amp;quot;LLRLLRLLRL&amp;quot;&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/67256?language=java&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/67256?language=java&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cLrH0c/hyItWGp5pm/KHLFYa2sGLL41X2x0JcKY1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bwWgRu/hyIsoLiL9c/D4tl5PARA22kXp550KlGok/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/KtyMH/hyItQMW2Wl/LV1fnhLa1jY5EftQ1j0dQ1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/67256?language=java&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/67256?language=java&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cLrH0c/hyItWGp5pm/KHLFYa2sGLL41X2x0JcKY1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bwWgRu/hyIsoLiL9c/D4tl5PARA22kXp550KlGok/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/KtyMH/hyItQMW2Wl/LV1fnhLa1jY5EftQ1j0dQ1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 키패드 누르기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] &quot;right&quot; &quot;LRLLLRLLRRL&quot; [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] &quot;left&quot; &quot;LRLLRRLLLRR&quot; [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] &quot;right&quot; &quot;LLRLLRLLRL&quot;&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;pre id=&quot;code_1607232302454&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;
import java.util.List;

class Solution {
    public String solution(int[] numbers, String hand) {
        
        List&amp;lt;Integer&amp;gt; leftPushList = Arrays.asList(1,4,7); 
    	List&amp;lt;Integer&amp;gt; rightPushList = Arrays.asList(3,6,9);
    	List&amp;lt;Integer&amp;gt; anyPushList = Arrays.asList(2,5,8,0);
    	StringBuilder builder = new StringBuilder();
    	
    	// * : 10
    	// # : 12
    	int nowLeftFinger =  10;
    	int nowRightFinger = 12;
    	
    	for(int num : numbers) {
    		if(leftPushList.contains(num)) {
    			builder.append(&quot;L&quot;);
    			nowLeftFinger = num;
    		}
    		
    		if(rightPushList.contains(num)) {
    			builder.append(&quot;R&quot;);
    			nowRightFinger = num;
    		}
    		
    		if(anyPushList.contains(num)) {
    			if(num == 0) {
    				num = 11;
    			}
    			
    			int leftTemp = Math.abs(nowLeftFinger - num);
    			int rightTemp = Math.abs(nowRightFinger - num);
    			
    			int distanceByLeftFinger = leftTemp / 3 + leftTemp % 3;
    			int distanceByRightFinger = rightTemp / 3 + rightTemp % 3;
    			
    			if(distanceByLeftFinger &amp;gt; distanceByRightFinger) {
    				nowRightFinger = num;
    				builder.append(&quot;R&quot;);
    			} else if (distanceByLeftFinger &amp;lt; distanceByRightFinger) {
    				nowLeftFinger = num;
    				builder.append(&quot;L&quot;);
    			} else {    				
    				if(hand.equals(&quot;left&quot;)) {
        				nowLeftFinger = num;
        				builder.append(&quot;L&quot;);
    				} else {
        				nowRightFinger = num;
        				builder.append(&quot;R&quot;);    					
    				}
    			}
    		}
    	}
        return builder.toString();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;키패드를 하나의 표로 생각해서 문제를 해결했다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 35.6295%; height: 223px;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 63px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 63px; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 63px; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 63px; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 63px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 63px; text-align: center;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 63px; text-align: center;&quot;&gt;5&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 63px; text-align: center;&quot;&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 63px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 63px; text-align: center;&quot;&gt;7&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 63px; text-align: center;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 63px; text-align: center;&quot;&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 64px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 64px; text-align: center;&quot;&gt;*&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 64px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 64px; text-align: center;&quot;&gt;#&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;맨 아래 행은 *, 0, # 이라서 계산이 어려우니 10, 11, 12로 거리계산 전에 치환해줬다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;1행부터 보면 아래로 갈수록 +3씩 되는 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;따라서 +3 혹은 -3은 한칸의 행 움직임이 된다.&lt;/p&gt;
&lt;p&gt;예를들면, 9번 -&amp;gt; 3번으로 이동시&lt;/p&gt;
&lt;p&gt;9 - 3 = 6&lt;/p&gt;
&lt;p&gt;6 / 3 = 2&lt;/p&gt;
&lt;p&gt;아래로 2칸 이동이라는 결과가 나온다.&lt;/p&gt;
&lt;p&gt;3번 -&amp;gt; 9번 이동시에는 음수가 되는데 어디로 이동했는지는 알 필요없으니 절대값으로 음수 양수 구분을 없애준다.&lt;/p&gt;
&lt;p&gt;그럼 열에 대한 구분은 어떻게 해야할까?&lt;/p&gt;
&lt;p&gt;열은 나머지로 구하면 된다.&lt;/p&gt;
&lt;p&gt;같은 행 숫자의 차이는 +3 / -3 이므로 3으로 나누면 나머지는 항상 0이 된다.&lt;/p&gt;
&lt;p&gt;다른 열로 이동하면 나머지는 1, 두번이동하면 나머지는 2가 된다.&lt;/p&gt;
&lt;p&gt;예를들어 9번 -&amp;gt; 2번으로 이동시 9 - 2 = 7 % 3 = 1... 옆으로 한칸 이동했다고 나온다.&lt;/p&gt;
&lt;p&gt;행과 열의 거리를 계산했으니 이를 비교해 가운데 라인의 숫자(2,5,8,0)를 어떤 손꾸락으로 누를지만 구분해주면 끝!&lt;/p&gt;</description>
      <category>기초CS/알고리즘</category>
      <category>java</category>
      <category>알고리즘</category>
      <category>연습문제</category>
      <category>자바</category>
      <category>카카오인턴</category>
      <category>키패드</category>
      <category>프로그래머스</category>
      <author>H!GHR</author>
      <guid isPermaLink="true">https://jjjayyy.tistory.com/100</guid>
      <comments>https://jjjayyy.tistory.com/100#entry100comment</comments>
      <pubDate>Sun, 6 Dec 2020 16:29:20 +0900</pubDate>
    </item>
  </channel>
</rss>