<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>생각을 개발하자, 박진형</title>
    <description></description>
    <link>http://imjinbro.github.io/</link>
    <atom:link href="http://imjinbro.github.io/rss" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 30 Oct 2018 00:36:03 +0900</pubDate>
    <lastBuildDate>Tue, 30 Oct 2018 00:36:03 +0900</lastBuildDate>
    <generator>Jekyll v3.7.4</generator>
    
      <item>
        <title>[TIL - 1029] Jackson을 사용하면서, 쿼리플랜의 중요성, Spring AOP로 트랜잭션 처리할 때 조심해야할 것</title>
        <description>&lt;h2 id=&quot;feature-개발-진행하면서-알게된-것들&quot;&gt;feature 개발 진행하면서 알게된 것들&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;책, 영상, 자료를 먼저 보고 파악한 내용이 아닌 실제 필요한 기능 개발을 하면서 알게된 것들 : 정말 소중한 경험을 하면서 얻게된 것들을 당분간 남길 것 같음&lt;/li&gt;
  &lt;li&gt;Jackson json 파싱 기준(예제)
    &lt;ul&gt;
      &lt;li&gt;자바빈 규약을 지켜야함 : NoArgsConstructor, setter/getter&lt;/li&gt;
      &lt;li&gt;[] 일 경우 array로 할지, List로 할지는 마음대로 하면 됨&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{
  &quot;id&quot;: 123,
  &quot;name&quot;: &quot;Pankaj&quot;,
  &quot;permanent&quot;: true,
  &quot;address&quot;: {
    &quot;street&quot;: &quot;Albany Dr&quot;,
    &quot;city&quot;: &quot;San Jose&quot;,
    &quot;zipcode&quot;: 95129
  },
  &quot;phoneNumbers&quot;: [
    123456,
    987654
  ],
  &quot;role&quot;: &quot;Manager&quot;,
  &quot;cities&quot;: [
    &quot;Los Angeles&quot;,
    &quot;New York&quot;
  ],
  &quot;properties&quot;: {
    &quot;age&quot;: &quot;29 years&quot;,
    &quot;salary&quot;: &quot;1000 USD&quot;
  }
}

@Data

public class Employee {

    private Long id;
    private String name;
    private boolean permanent;
    private Address address;
    private long[] phoneNumbers;
    private String role;
    private List&amp;lt;String&amp;gt; cities;
    private Map&amp;lt;String, String&amp;gt; properties;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Jackson 데이터가 없을 경우
    &lt;ul&gt;
      &lt;li&gt;null이 아니라 size가 0&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{
  &quot;DoTest&quot;: [    
  
  ]
}

public class DoTest {

    private List&amp;lt;SubTest&amp;gt; subTests;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;@Transactional 롤백 : RuntimeException에 대해서만 자동 rollback을 해주고, Unchecked Exception에 대해서는 설정해줘야함&lt;/li&gt;
  &lt;li&gt;쿼리 플랜 : 쿼리를 기능되게끔 짰다고 해서 그만인 것이 아니라 쿼리는 어떻게 해라라고 짜주지 않기 때문에 대신 짜주는 옵티마이져가 어떤 계획을 가지는지 확인해야함
    &lt;ul&gt;
      &lt;li&gt;풀스캔을 하고 있지 않은지, 잘못된 인덱스를 선택해서 검색하는 것은 아닌지 확인해야함&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://www.mysqlkorea.com/sub.html?mcode=manual&amp;amp;scode=01&amp;amp;m_no=21444&amp;amp;cat1=7&amp;amp;cat2=217&amp;amp;cat3=227&amp;amp;lang=k&quot;&gt;참고자료&lt;/a&gt; 남겨뒀다가 시간날 때 봐야지&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; EXPLAIN SELECT * FROM group WHERE xxx_id = 1;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Tue, 30 Oct 2018 00:35:00 +0900</pubDate>
        <link>http://imjinbro.github.io/2018/10/30/TIL</link>
        <guid isPermaLink="true">http://imjinbro.github.io/2018/10/30/TIL</guid>
        
        <category>TIL</category>
        
        <category>spring-aop</category>
        
        <category>jackson</category>
        
        <category>database</category>
        
        
      </item>
    
      <item>
        <title>[TIL - 1025] 오늘은 개발보단 일에 대한 이야기, @RestController redirect하기, Options HTTP 메소드</title>
        <description>&lt;h2 id=&quot;working&quot;&gt;working&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;프로젝트에 투입되기 전 배경지식을 얼른 캐치하는 것이 좋음 : 기획 배경, 사용 플로우(직접 사용해보기), API/테이블 목록, 정의, ERD 파악하기&lt;/li&gt;
  &lt;li&gt;다른 분의 코드를 보니깐 딱 든 생각은 컨벤션의 중요성과 문서화의 중요성(혹은 주석이라도 남기기)임 : 후임자가 코드를 보는데 아무런 설명이 없다면 생산성에 엄청난 악영향을 끼치게 됨
    &lt;ul&gt;
      &lt;li&gt;API의 사용처, 객체의 역할, 메소드 각각에 대한 주석 등이 굉장히 생산성에 영향을 미친다는 것을 알게됨&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;스프링-mvc&quot;&gt;스프링 MVC&lt;/h2&gt;
&lt;h3 id=&quot;restcontroller-redirect&quot;&gt;@RestController redirect&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;@Controller와 달리 redirect를 시키기위해서 HttpServletRequest(JavaEE)를 인자로 받아서 redirect 시켜줘야함&lt;/li&gt;
  &lt;li&gt;직접적인 JavaEE API 직접적인 사용을 피하고 Spring MVC가 제공 API를 사용하기 : RestTemplate
    &lt;ul&gt;
      &lt;li&gt;HttpStatus.MOVED_PERMANETLY : 301, redirect 상태코드&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@GetMapping(&quot;/test&quot;)
public ResponseEntity&amp;lt;String&amp;gt; test() {
    HttpHeaders headers = new HttpHeaders();
    headers.setLocation(Uri.create(&quot;/test2&quot;));
    return new ResponseEntity(headers, HttpStatus.MOVED_PERMANETLY);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;qualifier&quot;&gt;@Qualifier&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;동일 타입 빈 객체 중 특정 이름으로 생성되어있는 빈을 주입받을 때 사용하는 어노테이션 : 동일 타입 인스턴스 2개가 등록되어있는 경우&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;http&quot;&gt;HTTP&lt;/h2&gt;
&lt;h3 id=&quot;request-header-referer&quot;&gt;Request Header Referer&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;쉽게 말하면 현재의 전 링크 : 요청에 대한 응답을 구성할 때 다른 리소스를 요청해야할 때가 있음 다른 리소스를 요청하면 그 리소스는 request를 받아 요청을 처리하는데, 그때 header에 Referer로 이전에 요청한 URL가 기록&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Referer: https://www.daum.net
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;options-헤더&quot;&gt;Options 헤더&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;요청 URI에서 사용할 수 있는 메소드(HTTP Method)에 무엇이 있는지 요청
    &lt;ul&gt;
      &lt;li&gt;아래 예제는 모질라에서 제공 : 응답 헤더 Allow로 요청 가능한 메소드 목록이 넘어옴&lt;/li&gt;
      &lt;li&gt;굳이 아는 API에 대해 요청을 할 때 Options로 체크할 필요가 있을까?&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X OPTIONS http://example.org -i

HTTP/1.1 200 OK
Allow: OPTIONS, GET, HEAD, POST
Cache-Control: max-age=604800
Date: Thu, 13 Oct 2016 11:45:00 GMT
Expires: Thu, 20 Oct 2016 11:45:00 GMT
Server: EOS (lax004/2813)
x-ec-custom-error: 1
Content-Length: 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Fri, 26 Oct 2018 00:33:00 +0900</pubDate>
        <link>http://imjinbro.github.io/2018/10/26/TIL</link>
        <guid isPermaLink="true">http://imjinbro.github.io/2018/10/26/TIL</guid>
        
        <category>TIL</category>
        
        <category>spring-mvc</category>
        
        <category>work</category>
        
        <category>http</category>
        
        
      </item>
    
      <item>
        <title>[TIL - 1024] MySQL 데이터타입, 정규화(1)</title>
        <description>&lt;h2 id=&quot;mysql&quot;&gt;MySQL&lt;/h2&gt;
&lt;h3 id=&quot;데이터-타입&quot;&gt;데이터 타입&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;성능을 위해서 꼭 맞는 데이터를 고르기 : 공간 낭비(읽어오는 시간, 공간까지도 낭비)&lt;/li&gt;
  &lt;li&gt;숫자
    &lt;ul&gt;
      &lt;li&gt;unsigned : 양수(+)만&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;타입&lt;/th&gt;
      &lt;th&gt;크기&lt;/th&gt;
      &lt;th&gt;참고&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;BIT(N)&lt;/td&gt;
      &lt;td&gt;1 ~ 64bit까지 지정&lt;/td&gt;
      &lt;td&gt;크게 잡고 작은 수를 넣을 경우 0으로 채워짐&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;TINYINT&lt;/td&gt;
      &lt;td&gt;1byte&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;SMALLINT&lt;/td&gt;
      &lt;td&gt;2byte&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;INT&lt;/td&gt;
      &lt;td&gt;4byte&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;BIGINT&lt;/td&gt;
      &lt;td&gt;8byte&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;FLOAT&lt;/td&gt;
      &lt;td&gt;4byte&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;DOUBLE&lt;/td&gt;
      &lt;td&gt;8byte&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;DECIMAL&lt;/td&gt;
      &lt;td&gt;지정 시 : (M, N), Mbyte(정확한 소수점을 저장할 때 사용)&lt;/td&gt;
      &lt;td&gt;M 길이로 N개 남은 수부터는 소수점으로,&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;ul&gt;
  &lt;li&gt;문자&lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;타입&lt;/th&gt;
      &lt;th&gt;크기&lt;/th&gt;
      &lt;th&gt;참고&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;CHAR(N)&lt;/td&gt;
      &lt;td&gt;Nbyte 고정&lt;/td&gt;
      &lt;td&gt;크기만큼의 데이터가 아니라면 공백으로 채움&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;VARCHAR(N)&lt;/td&gt;
      &lt;td&gt;가변 길이&lt;/td&gt;
      &lt;td&gt;데이터 크기만큼 사용&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;TEXT&lt;/td&gt;
      &lt;td&gt;최대 65535byte&lt;/td&gt;
      &lt;td&gt;TINY(255byte), MEDIUM(16777215byte), LONGTEXT(4294…..;;)도 있음&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;ul&gt;
  &lt;li&gt;시간&lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;타입&lt;/th&gt;
      &lt;th&gt;참고&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;DATE&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;TIME&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;DATETIME&lt;/td&gt;
      &lt;td&gt;DATE + TIME&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;YEAR&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;TIMESTAMP&lt;/td&gt;
      &lt;td&gt;수정에 맞춰 자동으로 데이터 변경&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;ul&gt;
  &lt;li&gt;boolean 타입 저장하기 : tinyint(1) - 1비트로도 충분히 표현가능하지만 mysql에서는 1바이트를 요구&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;키-종류&quot;&gt;키 종류&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;슈퍼키 : 고유하게 식별되는 애트리뷰트 집합(후보키 + 일반 애트리뷰트 == 슈퍼키)&lt;/li&gt;
  &lt;li&gt;후보키 : 슈퍼키 부분 집합, 하나라도 제거되면 슈퍼키가 아닌 것(슈퍼키 - X == 일반키 라면 후보키)
    &lt;ul&gt;
      &lt;li&gt;여기서 하나를 선택해서 PK(기본키)로 사용함&lt;/li&gt;
      &lt;li&gt;여기서 하나를 선택하지않고 임의적으로 만든 키를 사용할 수 있음 : 인공키(아무런 의미없지만 식별가능하도록 유일하면서 NOT NULL인)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;정규화&quot;&gt;정규화&lt;/h3&gt;
&lt;h4 id=&quot;잘-설계된-테이블&quot;&gt;잘 설계된 테이블&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;다른 개체의 속성값을 가져오는 것은 FK를 통해 참조를 한다
    &lt;ul&gt;
      &lt;li&gt;CRUD가 자유롭지 못함 - 디펜던시를 깊게 가져 코드 변경을 자유롭게 하지 못하는 코드와 같음&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;한 테이블에 서로 다른 정보를 저장하는 것은 좋지않음 : 역할에 따라 객체 분리하듯 데이터도 구분(관심사끼리 분리라는 표현을 쓰더라)되는 것끼리 따로 저장하는 것이 좋음&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;정규화-1&quot;&gt;정규화&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;분해를 잘하는 것 : 문제점을 줄일 수 있도록 테이블을 설계&lt;/li&gt;
  &lt;li&gt;함수적 종속성 : 생각해본 내용을 옮기자면 X의 값으로 Y를 식별해낼 수는 있지만(함수적 종속성을 가짐), Y는 X를 식별해낼 수 없음(X가 무엇인지 결정할 수 없음)
    &lt;ul&gt;
      &lt;li&gt;한 쪽은 유일하고, 한 쪽은 같은 데이터가 있을 수도 있고 아닐 수도 있음&lt;/li&gt;
      &lt;li&gt;위의 상황을 X는 함수적으로 Y를 결정한다라고 함, Y가 달라지면 X는 무조건 달라짐&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;정규형 모델 : 조금 더 알아보자
    &lt;ol&gt;
      &lt;li&gt;1NF(1차 정규화 - 기본) : 테이블에는 키(PK)가 있어야함, 애트리뷰트는 원자성을 가져야함(주소와 같이 쪼갤 수 있는 애트리뷰트를 가지면 안됨, 하나의 로우에 여러 값을 저장X)&lt;/li&gt;
      &lt;li&gt;2NF&lt;/li&gt;
      &lt;li&gt;3NF&lt;/li&gt;
      &lt;li&gt;BCNF&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;정규화의-한계&quot;&gt;정규화의 한계&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;무조건적으로 정규형으로 맞출 수 없는 것이 실무에서는 FK JOIN으로 인한 성능 저하를 막고 한 번에 테이블의 값을 가져오기위해서 한 곳에 몰아서 데이터를 저장하기도 함
    &lt;ul&gt;
      &lt;li&gt;테이블의 한계를 자바 코드에 그대로 가져와서 고통을 받기보다 JPA를 사용하여 프로세스 메모리 상에서는 객체를 분리하여 사용할 것 : &lt;a href=&quot;https://imjinbro.github.io/2018/09/01/TIL&quot;&gt;한번 다뤘던 주제 - 블로그 다시 읽어보기&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 25 Oct 2018 01:14:00 +0900</pubDate>
        <link>http://imjinbro.github.io/2018/10/25/TIL</link>
        <guid isPermaLink="true">http://imjinbro.github.io/2018/10/25/TIL</guid>
        
        <category>TIL</category>
        
        <category>database</category>
        
        
      </item>
    
      <item>
        <title>[TIL - 1023] 문제 해결 방법 - 팩토리 메소드 패턴</title>
        <description>&lt;h2 id=&quot;java&quot;&gt;java&lt;/h2&gt;
&lt;h3 id=&quot;팩토리메소드-패턴&quot;&gt;팩토리메소드 패턴&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;객체를 만드는 공장을 생성해두는 것
    &lt;ul&gt;
      &lt;li&gt;왜? 특정 조건에 의해 생성되는 인스턴스(같은 상위클래스의 하위클래스)가 다를 때 구체적인 클래스로 인스턴스 생성하는 코드 작성하지않고 생성 권한을 위임 받은 아이에게 요청하면 결합도를 낮출 수 있기 때문(&lt;strong&gt;구체적인 클래스를 명시해서 직접 생성하기보다 맞는 조건이 있으면 생성, 없으면 예외 발생이 되도록&lt;/strong&gt; 할 수도 있음)&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;조금 더 나아가면&lt;/strong&gt; 싱글턴일 때 팩토리 혹은 인스턴스 관리자에게 인스턴스를 특정 조건값을 주고 가져오게 할 수도 있음 : 여기에 더 추가하자면 인스턴스들에게 물어봐서 특정 조건값에 너희 부합하냐라고 묻는 메소드를 요청해서 맞을 때 가져오도록 코드를 짜면 switch 혹은 if ~ else 의 떡칠을 막을 수 있다고 생각이 듦&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;예제 코드
    &lt;ul&gt;
      &lt;li&gt;검색해서 본 예제 코드에서는 팩토리를 abstract로 선언해두고 extends해서 여러 팩토리를 만들고 하는데, 굳이 지금은 적용할 필요를 느끼지 못하여 1 depth를 유지함 뿐만 아니라 abstract 보다 interface로 선언해두는 것이 더 낫지 않을까? 어떤 타입의 인스턴스를 생성하는 능력을 가지고 있는 팩토리라고 생각한다면? 또 팩토리는 상태값이 없을테니 상태 필드도 없을텐데&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public class ObjectFactory {

    public static UpperObject of(int value) {
        switch (value) {
            case 2:
                return new ExtensionObjectOne();
            break;

            case 1:
                return new ExtensionObjectTwo();
            break;

            default:
                throw new IllegalArgumentException();
        }
    }
}

interface UpperObject {

}

class ExtensionObjectOne implements UpperObject {

}

class ExtensionObjectTwo implements UpperObject {

}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Wed, 24 Oct 2018 00:49:00 +0900</pubDate>
        <link>http://imjinbro.github.io/2018/10/24/TIL</link>
        <guid isPermaLink="true">http://imjinbro.github.io/2018/10/24/TIL</guid>
        
        <category>TIL</category>
        
        <category>solution</category>
        
        
      </item>
    
      <item>
        <title>[TIL - 1021] Spock가 뭐길래, 인덱스(1), int(11)이 뭘까?</title>
        <description>&lt;h2 id=&quot;test&quot;&gt;test&lt;/h2&gt;
&lt;h3 id=&quot;spock-사용해보기&quot;&gt;spock 사용해보기&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;기존에 자바 코드(+spring)를 테스트할 때는 JUnit(unit test), Mockito(integration test)을 사용해서 테스트를 했는데, 워크샵에서 groovy로 테스트 코드를 작성하는 것을 보고 무엇인지 보았더니 Spock 였음&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* build.gradle Spock 추가 : mvnrepo(Core Module) : 스프링 환경에서 테스트 하는 것이 아니므로 Core만 */
dependencies {
    testCompile group: 'org.spockframework', name: 'spock-core', version: '1.1-groovy-2.4'
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;junit과 비교했을 때 &lt;a href=&quot;http://spockframework.org/spock/docs/1.2/index.html&quot;&gt;Spock&lt;/a&gt;는 어떤 특징을 가지는지 알아보았음
    &lt;ul&gt;
      &lt;li&gt;POJO 테스트&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* 테스트 대상 코드 */
public class Person {

    private static NameRule rule = BasicRule.of();
    private String name;

    public Person(String name) {
        if (!rule.isValid(name)) {
            throw new RuntimeException(&quot;올바르지않은 이름 설정&quot;);
        }
        this.name = name;
    }
}


/* Spock : 디펜던시 추가 후 테스트 클래스 생성할 때 테스트 프레임워크 선택할 수 있음 */
def &quot;기본 룰 - 3자 미만&quot;() {
    given:
    def invalidName = &quot;te&quot;
    
    when:
    new Person(invalidName)

    then
    def exception = thrown(RuntimeException.class)
    exception.message == &quot;블라블라&quot;
}

/* 여러가지 한꺼번에 테스트하기 */
def &quot;기본룰 테스트&quot;() {
    expect:
    new Person(name)

    where:
    name | _
    &quot;jinbro&quot; | _
    &quot;te&quot; | _
    &quot;power&quot; | _
    &quot;qw&quot; | _
}


#######
Condition failed with Exception:

new Person(invalidName)
|          |
|          te
java.lang.RuntimeException: 올바르지않은 이름 설정


Condition failed with Exception:

new Person(invalidName)
|          |
|          qw
java.lang.RuntimeException: 올바르지않은 이름 설정
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;사용해보니
    &lt;ul&gt;
      &lt;li&gt;조금 더 테스트하도록 유도하는 점(블록 없이는 실행안됨 - 로그만 찍어보기가 아니라 결과 관련 블록 있어야)이 있음&lt;/li&gt;
      &lt;li&gt;where 블록을 통해서 여러 케이스를 하나의 메소드로 묶어 테스트 할 수 있음 : 테스트 코드가 줄어듦 - JUnit의 경우 첫번쨰 실패 케이스만 알 수 있음&lt;/li&gt;
      &lt;li&gt;Mock 테스트도 가능함 : Mock() 함수를 통해서&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;mysql&quot;&gt;MySQL&lt;/h2&gt;
&lt;h3 id=&quot;인덱스1---레코드를-저장하는-방식&quot;&gt;인덱스(1) - 레코드를 저장하는 방식&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;검색 속도를 올리기 위한 레코드 저장 방식 : 검색(Select)속도를 올리는 대신 Insert, Update, Delete 속도는 느려짐
    &lt;ul&gt;
      &lt;li&gt;인덱스를 재편집 해야하기 때문에 : B+Tree 구조로 정렬해둔 상태&lt;/li&gt;
      &lt;li&gt;자주 사용되는 컬럼에 대해 인덱스를 걸어둠 : 검색 속도를 높여야할 필요성이 있는 데이터의 경우 불가피하게 선택할 수 밖에 없음&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;인덱스-종류&quot;&gt;인덱스 종류&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Clustered Index : PK를 인덱스(자동 생성), PK를 기준으로 실제 데이터 위치까지도 변경됨, PK를 기준으로 검색하여 빠른 속도로 검색
    &lt;ul&gt;
      &lt;li&gt;인덱스의 Key가 PK&lt;/li&gt;
      &lt;li&gt;레코드의 위치를 Value로 가지고 있음 : PK로 검색하면 빠르게 데이터 위치를 찾을 수 있음&lt;/li&gt;
      &lt;li&gt;BTree 구조&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql&amp;gt; show index from employee\G;
*************************** 1. row ***************************
        Table: employee
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 2
     Sub_part: NULL
       Packed: NULL
         Null:
   Index_type: BTREE
      Comment:
Index_comment:
1 row in set (0.00 sec)

ERROR:
No query specified
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Secondary Index(Non Clustered Index) : 해당 인덱스를 만들 때에는 데이터 정렬 자체도 변경되지않고(실제 데이터 위치 변경없음), 해당 컬럼 기준 B+Tree만 하나 더 만드는 것
    &lt;ul&gt;
      &lt;li&gt;PK를 Value로 가지고 있음 : PK를 찾아 Clustered Index로 다시 가서 레코드 위치를 찾음&lt;/li&gt;
      &lt;li&gt;BTree 구조&lt;/li&gt;
      &lt;li&gt;풀스캔해서 찾는 것보다 트리구조로 되어있는 상태에서 검색하는 것이 더 빠름&lt;/li&gt;
      &lt;li&gt;FK는 자동으로 인덱스 생성&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql &amp;gt; create index idx_employee_createdtime on employee (created_time);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Cardinality(인덱스 선정 기준 중 하나) : 사전의 뜻으로는 농도, 카디널리티가 높다는 뜻은 걸러낼 수 있는 데이터가 많다는 것
    &lt;ul&gt;
      &lt;li&gt;sex(성별 컬럼)를 인덱스로 잡을 경우 남/여 50%만 걸러낼 수 있으므로 성능상 이점을 가져갈 수 없음&lt;/li&gt;
      &lt;li&gt;반대로 단순하게 auto_increment 설정된 int 타입의 Primary Key에 대한 인덱스가 자동생성되었는데, 각각 다 다르고 걸러내기가 쉬움(카디널리티가 높음)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;index는 내일 데이터 bulk insert 해두고 테스트를 해봐야겠음&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;궁금했던-것---int11에서-11은-무엇을-의미할까&quot;&gt;궁금했던 것 - int(11)에서 (11)은 무엇을 의미할까?&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;디스플레이 옵션인데, 디스플레이할 때 비는 자리만큼 0을 채우도록(zerofill) 하는 옵션
    &lt;ul&gt;
      &lt;li&gt;디스플레이 적용하기위해서는 컬럼 지정 시 zerofill로 선언해야함&lt;/li&gt;
      &lt;li&gt;int(11)을 사용하는 이유는? int가 4byte인데 unsigned 표현할 수 있는 데이터 범위가 21억… 10자리가 max size + 1&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql &amp;gt; create table user ( id int(11) unsigned zerofill not null auto_increment, name varchar(16) not null, primary key (id) );
.
.
.
select * from user;
+-------------+------+
| id          | name |
+-------------+------+
| 00000000001 | a    |
| 00000000002 | b    |
| 00000000003 | c    |
| 00000000004 | d    |
| 00000000005 | e    |
+-------------+------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Mon, 22 Oct 2018 01:26:00 +0900</pubDate>
        <link>http://imjinbro.github.io/2018/10/22/TIL</link>
        <guid isPermaLink="true">http://imjinbro.github.io/2018/10/22/TIL</guid>
        
        <category>TIL</category>
        
        <category>test</category>
        
        <category>database</category>
        
        
      </item>
    
      <item>
        <title>[TIL - 1020] 병렬처리 API, MySQL 엔진/스토리지 엔진, replication 개념, 롤백하려면 어디에 저장?</title>
        <description>&lt;h2 id=&quot;java&quot;&gt;java&lt;/h2&gt;
&lt;h3 id=&quot;병렬로-연산하기&quot;&gt;병렬로 연산하기&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;ExecutorService API
    &lt;ul&gt;
      &lt;li&gt;쓰레드풀에 일정 개수의 쓰레드를 만들어두고 처리하는 방식의 API : limit 개수만큼 동시에 처리함&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ExecutorService executor = Executors.newFixedThreadPool(5);
List&amp;lt;Future&amp;lt;String&amp;gt;&amp;gt; results = new ArrayList&amp;lt;&amp;gt;();
for (int i = 0; i &amp;lt; 30; i++) {
    results.add(executor.submit() -&amp;gt; {
        Thread.sleep(5000);
        return Thread.getCurrrentName() + &quot;, end time : &quot; + LocalDateTime.now();
    });    
}

for (Future&amp;lt;String&amp;gt; result : results) {
    System.out.println(result.get());
}

executor.shutdown();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Stream API(java8)
    &lt;ul&gt;
      &lt;li&gt;하나의 task를 여러개 task로 쪼개고, 처리한 후 하나로 합치는 형태로 처리 : ForkJoin Framework(Pool) - ForkJoinPool은 ExecutorService 구현체&lt;/li&gt;
      &lt;li&gt;노는 CPU가 없도록 하는 알고리즘이 적용되어있음 : 각각이 내부적으로 queue가 생성되고 task를 처리함, 자신의 task가 모두 처리된 경우 다른 task를 가지고 올 수 있음&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Stream.iterate(1L, i -&amp;gt; i + 1)
        .limit(limit)
        .parallel()
        .reduce(0L, Long::sum);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;병렬처리와-순차처리-비교-주의해야할-점&quot;&gt;병렬처리와 순차처리 비교, 주의해야할 점&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;task가 &lt;strong&gt;독립적이지 않다면&lt;/strong&gt; 오히려 성능 저하될 가능성(각각이 서로에 영향을 미치는 경우) : 아래의 예의 경우 전 연산이 현재 연산 결과에 영향을 미칠 수 있음(연관된)&lt;/li&gt;
  &lt;li&gt;특정 메소드를 사용할 때만 사용할 것 : iterate()의 경우 boxing 객체 생성(primitive -&amp;gt; object) -&amp;gt; 연산을 위해 unboxing() 해야
    &lt;ul&gt;
      &lt;li&gt;아래의 예제코드의 iterate가 순차처리 메소드 : 하나씩 어떤 처리를 하는 것(무한스트림 생성)&lt;/li&gt;
      &lt;li&gt;Boxing된 객체를 unboxing해서 연산하도록 처리하는 것이 비효율적이라는 것도 알아갑니다! : iterate가 아닌 IntStream/LongStream과 같은 API 사용하기&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;내부적으로 queue를 만들어내서 task를 처리 : 그만큼 비용이 든다는 이야기 같음 - 무작정 사용하는 것이 사용해서 얻는 성능 이점보다 잃는 것이 많을 수 있다는 위험&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;long start = System.currentTimeMillis();
long result = Stream.iterate(1L, i -&amp;gt; i + 1)
        .limit(limit)
        //parallel()
        .reduce(0L, Long::sum);

System.out.println(((System.currentTimeMillis() - start) / 1000) + &quot;초&quot;);
return result;

병렬처리 : 20초
순차처리 : 1초
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;mysql&quot;&gt;mysql&lt;/h2&gt;
&lt;h3 id=&quot;용어-정리&quot;&gt;용어 정리&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;데이터베이스(schema) : 테이블 컨테이너(단지 담는 역할)
    &lt;ul&gt;
      &lt;li&gt;MySQL에서는 schema와 database는 동의어 : MsSQL(sql-server)에서는 schema가 database 보다 하위 컨테이너&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;쿼리 종류
    &lt;ol&gt;
      &lt;li&gt;DDL : 데이터베이스/테이블/스토어드 프로시져 생성, 변경 작업 쿼리(CREATE, ALTER)&lt;/li&gt;
      &lt;li&gt;DML : 데이터 조작 쿼리 - SELECT, UPDATE, DELETE, INSERT&lt;/li&gt;
      &lt;li&gt;DCL : 권한 관련 - GRANT&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;엔진&quot;&gt;엔진&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;MySQL 엔진 : 연결을 맞이하고 파싱된 쿼리를 최적의 방법으로 실행되기위해 계획하는 역할(하나의 종류 밖에 없음)
    &lt;ul&gt;
      &lt;li&gt;생각하는 담당&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;스토리지 엔진(핸들러) : 데이터를 저장하고 저장된 데이터를 찾아오는 역할(여러개를 동시에 사용할 수 있고 여러 종류가 있으며, INNODB가 기본 스토리지 엔진)
    &lt;ul&gt;
      &lt;li&gt;SELECT, INSERT, UPDATE, DELETE 실질적인 데이터 관련 작업은 여기서 담당&lt;/li&gt;
      &lt;li&gt;InnoDB : PK를 기준으로 데이터 클러스터링(저장) - 순서대로 저장, PK를 기준으로 검색은 빠름(클러스터링 인덱스 - 그래서 이런 이름이었군…)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# 테이블 생성 시 스토리지 엔진 지정 가능
&amp;gt; CREATE TABLE test (....) ENGINE=INNODB;

# 기본 스토리지 엔진 조회
&amp;gt; SELECT engine, support FROM information_schema.engines WHERE support='DEFAULT';
+---------+
| support |
+---------+
| InnoDB  |
+---------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;replication&quot;&gt;replication&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;시스템 안정성을 위한 복제 작업을 뜻함 : 메인으로 사용하고 있는 master 데이터베이스가 장애를 일으켰을 때 서비스가 중단되는 것을 막기위해 미리 복제해두었다가 서비스를 계속할 수 있도록 하는 것&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;역할에 따른 권한 제한
    &lt;ol&gt;
      &lt;li&gt;master : insert, update, delete&lt;/li&gt;
      &lt;li&gt;slave : read-only&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;운영 : 물론 정해져 있는대로 구성하는 것은 아니라 운영 상황에 맞게 조금씩 변형시킬 수 있음
    &lt;ol&gt;
      &lt;li&gt;active-active : master 만을 가지고 서비스를 할 수도 있지만 active-active 상태로 만들어 읽기 작업은 slave 데이터베이스에 수정 및 삭제 작업은 master가 하도록 하여 부하 분산(전제 조건은 sync 되어야 한다는 것)&lt;/li&gt;
      &lt;li&gt;active-stand by : slave 데이터베이스를 오로지 백업용으로만 사용&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;구축 어떻게 되지? : 바이너리 로그를 활성화해두면 DML(데이터 변경 쿼리), DDL(스키마 변경 쿼리)을 남기고 slave에서 로그를 참조하여 replication 작업을 수행함
    &lt;ul&gt;
      &lt;li&gt;slave 데이터베이스는 master에 접속하여 로그를 요청하고 받아온 로그를 기록한 후 복제(실행)&lt;/li&gt;
      &lt;li&gt;로그를 쓰는 것도 자원 소모입니다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;em&gt;구축해보기 : AWS 환경에서 해보기&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;트랜잭션-roll-back&quot;&gt;트랜잭션 roll-back&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;롤백이 되면 트랜잭션 처리 이전의 상태로 돌아가야하는데, InnoDB는 메모리영역에 UPDATE, DELETE 되기 전의 상태를 저장해둠 : UNDO 로그 영역(메모리)&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 21 Oct 2018 01:58:00 +0900</pubDate>
        <link>http://imjinbro.github.io/2018/10/21/TIL</link>
        <guid isPermaLink="true">http://imjinbro.github.io/2018/10/21/TIL</guid>
        
        <category>TIL</category>
        
        <category>java</category>
        
        <category>database</category>
        
        
      </item>
    
      <item>
        <title>[TIL - 1019] 오늘의회고, upsert 쿼리, git tag/config, api 구조</title>
        <description>&lt;h2 id=&quot;오늘의-회고&quot;&gt;오늘의 회고&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;드디어 시스템 파악하기 시작! 모르는 것은 모른다고 말하고 배우는 자세를 취하면 아무리 실력 없더라도 안좋게 보지는 않을까 생각함. 
그리고 입사해서 느낀 것은 글로 정리하는건 역시나 중요하다는 것 사내 위키에 시스템에 대한 히스토리 정리, 설명이 잘 되어 있다보니 파악하기가 수월하였음
명패에 쓴 “기본으로 돌아가자” 문구처럼 모르겠으면 거기서 헤매기보다 처음부터 훑어보면서 어디를 모르는지 체크부터 하도록 해야겠다.
오늘 공부 못한만큼 내일 많이 해야지~~~&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;데이터베이스&quot;&gt;데이터베이스&lt;/h2&gt;
&lt;h3 id=&quot;upsert&quot;&gt;upsert&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;데이터베이스에 저장되어있는 데이터가 있을 경우(unique key값 기준) update, 없을 경우 insert 하도록 sql을 짜서 데이터 중복되지 않도록 하는 것을 말함
    &lt;ul&gt;
      &lt;li&gt;조회한 데이터를 메모리로 가져와서 필터링한 결과 있을 경우/없을 경우를 나눠서 쿼리를 또 다시 날리는 것과 일종의 프로시져처럼 하나의 쿼리로 조건문을 만들어 사용하는 것 중 어느 것이 나을까? : 성능 상의 이점과 유지보수 관점의 문제인가(너무 민감하게 받아들이는 것인가)&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html&quot;&gt;MySQL upsert 쿼리 관련 docs&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;같은 쿼리를 2번 실행했을 때의 결과 : 존재한다면 같은 쿼리라도 @update.com으로 update 하기를 선언한 쿼리&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql&amp;gt; insert into student (name, email) values ('jinbro', 'jinbro@test.com') on duplicate key update name='jinbro', email='jinbro@update.com';
Query OK, 1 row affected (0.01 sec)

mysql&amp;gt; select * from student;
+--------+-----------------+
| name   | email           |
+--------+-----------------+
| jinbro | jinbro@test.com |
+--------+-----------------+
1 row in set (0.00 sec)

mysql&amp;gt; insert into student (name, email) values ('jinbro', 'jinbro@test.com') on duplicate key update name='jinbro', email='jinbro@update.com';
Query OK, 2 rows affected (0.01 sec)

mysql&amp;gt; select * from student;                                                                
+--------+-------------------+
| name   | email             |
+--------+-------------------+
| jinbro | jinbro@update.com |
+--------+-------------------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;git&quot;&gt;git&lt;/h2&gt;
&lt;h3 id=&quot;tag&quot;&gt;tag&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;커밋을 참조하기 쉽게 이름을 붙이는 것 : 특정 커밋에 특정한 정보를 달아주는 것, release 커밋에 대해 tag를 활용&lt;/li&gt;
  &lt;li&gt;종류
    &lt;ol&gt;
      &lt;li&gt;light-weight tag : 간단하게 이름만 붙임&lt;/li&gt;
      &lt;li&gt;annotated tag : 이름, 설명, 서명, 이메일, 태그 생성 날짜 정보를 포함시킬 수 있음&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;만들어보기
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://bit.ly/2CsXsW2&quot;&gt;특정 저장소에만 정보 설정하기&lt;/a&gt; : git config (옵션없이 하면 로컬 config)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# light-weight tag
&amp;gt; git tag ${태그이름}


# annotated tag 
&amp;gt; git tag -a ${태그이름} # m 옵션을 추가해서 바로 설명을 추가할 수 있음


# tag list
&amp;gt; git tag -n
version-0.0.1   first commit
version-0.0.2   두번째 베타버젼
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;api-구조&quot;&gt;API 구조&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;업무에 대해서 전달해주시는 과정에서 core API와 core 주변에 그려진 API에 대한 설명을 듣고 알게된 점을 적어봄&lt;/li&gt;
  &lt;li&gt;core API와 주변 API : core API는 말 그대로 핵심 기능 요청 - 응답 받을 수 있는 API이고, core 주변에 딸려 있는 API는 core API의 구성요소를 aggregation 하여 만들어진 편의성에 초점을 둔 API&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 20 Oct 2018 03:09:00 +0900</pubDate>
        <link>http://imjinbro.github.io/2018/10/20/TIL</link>
        <guid isPermaLink="true">http://imjinbro.github.io/2018/10/20/TIL</guid>
        
        <category>TIL</category>
        
        <category>database</category>
        
        <category>git</category>
        
        <category>api</category>
        
        
      </item>
    
      <item>
        <title>[TIL - 1018] git command, APM이란, aws 리소스 알아보기</title>
        <description>&lt;h2 id=&quot;git&quot;&gt;git&lt;/h2&gt;
&lt;h3 id=&quot;git-flowoperation&quot;&gt;git flow(+operation)&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;fork flow : master, develop, feature, release, hotfix 브랜치로 구성하고, 저장소는 upstream, origin, local으로 구성함
    &lt;ul&gt;
      &lt;li&gt;브랜치 : master가 현재 운영, develop은 기능 개발 시 출발점이 되는 브랜치, feature는 각 기능 개발 때 사용되는 브랜치(develop에서 branch 생성), release는 다음 release될 브랜치, hotfix는 긴급하게 수정해야하는 상황이 발생했을 때 master로부터 브랜치를 따서 수정 후 merge 배포를 진행함(&lt;strong&gt;절대적인 것은 아님!&lt;/strong&gt; - 각 팀의 운영 노하우에 따라 조금씩 수정될 수 있음)&lt;/li&gt;
      &lt;li&gt;저장소 : upstream을 prod로 사용하고 origin은 개발자 개인 repo로 upstream을 fork한 repo, local은 개발자의 로컬 저장소&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;./files/2018-10-18-TIL/fork-flow.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;command&quot;&gt;command&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;cherry-pick : 특정 브랜치와 merge 하는 것이 아니라 특정 브랜치들의 변경사항은 각각 놔두면서 흡수하는 것 - 새로운 커밋(들)을 만들어냄(내용은 복사본, pick한 커밋만큼 생성)
    &lt;ul&gt;
      &lt;li&gt;next-release 작업이 진행되고 있는 상황에서(dev까지 완료되었건 feature에 있건 간에) master에 긴급 수정한 내용이 생겼을 때 next-release에도 반영해야한다면 cherry-pick을! : release 브랜치에서 새로운 커밋 생성&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* master */
4c01e372f5f7e7ff727f3f5422fae19f0154d7ad (HEAD -&amp;gt; master) prod hotfix
bb237d418692237ebd09bf09178675b8e067fb9e prod commit

&amp;gt; git cherry-pick 4c01e37

/* release branch */
97594e7ccb7b20f375ed109cf0f107f9ee96dc9c (HEAD -&amp;gt; release) prod hotfix
c869dada3813365f36ff4c034fbd244fe2c57324 next-release commit
bb237d418692237ebd09bf09178675b8e067fb9e prod commit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;interactive rebase(squash) : 여러 커밋을 하나의 커밋으로 만드는 작업을 할 때 사용 - 단 원격저장소(hub 목적)에 push한 커밋가지고는 하지말기!(reset 보다 revert를 사용하는 것이 더 나은 이유와 같음)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;infra&quot;&gt;infra&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;APM : Application Performance Management(성능 관리, 모니터링툴) - pinpoint, new relic 등이 있음
    &lt;ul&gt;
      &lt;li&gt;3계층(tier) 구조 : 프론트 / 서버 / 데이터베이스, 지금은 3계층 이상으로 N계층으로 더 세분화해서 나눔(MSA) - 도메인 별로 더 쪼개서 관리하기 쉽도록, 관리해야할 대상이 많아져 몇군데만 보는 것이 아니라 다 들여다보고 대응할 수 있어야해서 APM을 사용하게 됨&lt;/li&gt;
      &lt;li&gt;tier와 layer 차이 : 외부로 분리해내는 것과 내부적으로 계층을 나눈 것&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;aws-리소스&quot;&gt;AWS 리소스&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;AMI : Amazon machine Image - 인스턴스를 이미지화 하여 복제(scale out)가 쉬움, AWS는 트래픽에 따라 오토스케일링이 편하다는 점!&lt;/li&gt;
  &lt;li&gt;access key ID/secret key : API로 리소스 사용가능(써드파티툴로 제어가능) - 주로 마스터 계정의 액세스키가 아닌 IAM 계정(제한된 권한)의 액세스키를 발급하여 사용&lt;/li&gt;
  &lt;li&gt;cloud watch : EC2 인스턴스를 비롯한 모니터링 가능한 서비스의 인스턴스에 attach 시키면 됨, 알람 수치를 설정할 수 있음, 뿐만 아니라 오토스케일링(out, in)&lt;/li&gt;
  &lt;li&gt;aws-cli : cli에서 aws 리소스를 제어할 수 있음 - 단 access-key가 있어야함(발급 받으면 됨)&lt;/li&gt;
  &lt;li&gt;s3 : &lt;strong&gt;HTTP로&lt;/strong&gt; 파일 업로드, 다운로드 가능 - 동적인 처리없이 정적으로 파일만 주고 받는 프로그램을 만든다면 S3를 사용하는 것이 더 효율적
    &lt;ul&gt;
      &lt;li&gt;업로드 후 curl로 다운로드 테스트&lt;/li&gt;
      &lt;li&gt;버킷에 권한 설정 가능 : AWS에서 제공해주는 기능으로 버킷에 대한 정책(공개 여부, 공개 범위 등) json 데이터를 만들기 쉽고 적용하기도 쉬움&lt;/li&gt;
      &lt;li&gt;metadata 설정으로 캐시 설정 가능, 라이프 사이클 설정 가능, 버져닝 가능(동시에 라이프 사이클 설정은 안됨)&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;&lt;em&gt;해봐야할 것&lt;/em&gt;&lt;/strong&gt; : spring cloud로 S3 파일 업로드 해보기&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;cloud front(캐시 서버 - 엣지 로케이션) : HTTP 메소드로 동적인 작업일 경우(POST, PUT, DELETE 등) origin으로, 그 외엔 파일 있을 경우 캐시된 파일을 내려주고 origin으로
    &lt;ul&gt;
      &lt;li&gt;cloud front에 복사된 파일이 없을 경우 origin으로 가게 되어있음 : 임의 갱신할 때 이용할 수 있는 특징(요청 URL 변경하기)&lt;/li&gt;
      &lt;li&gt;deploy : 엣지 로케이션에 배치된(생성된) 단위&lt;/li&gt;
      &lt;li&gt;단순하게 가까워서 얻는 이점도 있음&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://pyrasis.com/book/TheArtOfAmazonWebServices/Chapter12/03&quot;&gt;ec2 - cloud front(custom origin) 연동 : HTTP 통신&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;rds
    &lt;ul&gt;
      &lt;li&gt;탄력적으로 관리 가능 : 스케일링 가능, replica 서비스 제공 등&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;&lt;em&gt;해봐야할 것&lt;/em&gt;&lt;/strong&gt; : master/slave(Replication) 구성해보기&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;네트워크&quot;&gt;네트워크&lt;/h2&gt;
&lt;h3 id=&quot;http-헤더&quot;&gt;HTTP 헤더&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;referer : 어디에서 요청을 했는지 나타내는 값을 Request 헤더에 넣어서 보냄&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 19 Oct 2018 00:01:00 +0900</pubDate>
        <link>http://imjinbro.github.io/2018/10/19/TIL</link>
        <guid isPermaLink="true">http://imjinbro.github.io/2018/10/19/TIL</guid>
        
        <category>TIL</category>
        
        <category>git</category>
        
        <category>infra</category>
        
        <category>aws</category>
        
        
      </item>
    
      <item>
        <title>[TIL - 1017] 트랜잭션 격리수준, mysql 설치/계정 설정, stored procedure, operation process</title>
        <description>&lt;h2 id=&quot;데이터베이스&quot;&gt;데이터베이스&lt;/h2&gt;
&lt;h3 id=&quot;트랜잭션-격리-수준lock-정책&quot;&gt;트랜잭션 격리 수준(Lock 정책)&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;멀티쓰레드 환경에서 트랜잭션이 지켜야하는 트랜잭션 간의 간섭 금지(Isolation)와 속도 트레이드오프 발생 : 격리 수준 특징을 알아야 도메인 특징에 따라 알맞는 격리 수준을 골라 트레이드오프 상황을 벗어날 수 있을 것이라 생각됨
    &lt;ul&gt;
      &lt;li&gt;데이터베이스마다 다르기 때문에 어떤 격리 수준이 있는지는 알아봐야함&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;명칭&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;설명&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;발생할 수 있는 문제점&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;read uncommited&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;커밋되지 않은 데이터 변경까지도 다른 트랜잭션에서 읽기 가능&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;phantom read, non-repeatable read, dirty read&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;read commited&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;커밋된 데이터 변경을 읽을 수 있음&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;phantom read, non-repeatable read&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;read repeatable&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;조회한 데이터에 대해 Lock이 걸리고 수정할 수 없는 상태&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;phantom read&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;serializable&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;하나의 트랜잭션이 처리될 동안 완전한 Lock - 다른 트랜잭션 처리 대기&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;-&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;ul&gt;
  &lt;li&gt;phantom read : 같은 범위에 대한 검색을 했는데 다른 트랜잭션의 작업으로 인해 다른 개수(삭제, 추가)가 검색됨&lt;/li&gt;
  &lt;li&gt;non-repeatable read : 같은 데이터 임에도 불구하고 다른 트랜잭션의 작업으로 인해 변경된 데이터 값이 읽힘&lt;/li&gt;
  &lt;li&gt;dirty read : 커밋되지않은 데이터가 읽히다보니 해당 데이터를 변경한 트랜잭션에 의해 커밋되지않았을 때 쓰레기 값이 되었지만 그대로 저장되는 문제&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;mysql-설치-후-계정-생성&quot;&gt;mysql 설치 후 계정 생성&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;설치 이후에는 root 계정만 존재하므로 사용자 계정을 생성해서 사용할 것 : 호스트 종류(localhost, @ &amp;lt;- 외부 접근), 접근 제어(예를 들어 특정 스키마만 접근, select 권한만) 등 생각하고 유저 생성
    &lt;ul&gt;
      &lt;li&gt;mysql 5.7 부터 password가 아닌 authentication_string : user 테이블 조회 시&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;stored-procedure&quot;&gt;stored procedure&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;여러 쿼리를 하나의 프로시져로 선언해두고 요청이 들어왔을 때 실행함 : 말 그대로 절차를 저장해둠
    &lt;ul&gt;
      &lt;li&gt;네트워크에서 주고 받아야할 데이터가 줄어듬 : 쿼리 데이터 주고 받지 않아도 됨 - procedure 호출&lt;/li&gt;
      &lt;li&gt;특징에 대해서도 더 알아보기 : 어떤 점 때문에 사용하고 어떤 점 때문에 사용하기를 꺼리는지까지&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;오늘은 개념까지만…(잘자고 출근해야지!) 내일은 mysql에서 procedure 만들어두고 spring에서 procedure 호출해보는 것까지 해보면 좋겠..!
    &lt;ul&gt;
      &lt;li&gt;mssql(sql-server)에서는 프로시져 권장이라는 말이 있던데 이 부분도 찾아보기&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;운영&quot;&gt;운영&lt;/h2&gt;
&lt;h3 id=&quot;프로세스&quot;&gt;프로세스&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;운영 프로세스에 대한 이해없이 업무를 할 수 없을 것 같다는 생각이 들어 프로세스를 찾아보고 정리해보았음
    &lt;ul&gt;
      &lt;li&gt;아직까지는 직접 겪어본 바에 비춰 적기보다 그동안 어렴풋이 알고 있었던 개념과 검색과 시니어분께 여쭤 얻은 답을 기반으로 정리함(제대로 느끼는 그 날이 얼른 오길)&lt;/li&gt;
      &lt;li&gt;회사에 따라 아래 프로세스를 다 가져가는 경우가 있는 반면 통합해서 진행하는 것으로 보여짐&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;환경&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;설명&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;local&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;개발자 개인 개발 환경 - 공통된 개발 환경과 코드컨벤션과 같은 약속이 되어있어야함(개발 후 통합했을 때에 대한 대비 및 원활한 팀 운영)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;development(dev)&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;개발한 소스코드를 서버 환경과 같은 환경에 모아 테스트하는 환경, prod 서버 환경보다는 간소화(기능 위주의 테스트)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;integration&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;컴포넌트 간의 의존성을 가지고 있을 때 한 곳으로 모아 테스트하는 환경&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;qa&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;QA 엔지니어가 테스트하는 환경 - 항목을 짜두고 테스트&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;staging&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;운영 환경으로 들어가기 전 최종적으로 거의 운영 환경과 동일하게 구성하여 테스트 하는 환경&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;production(prod)&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;실제 서비스 운영 환경&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
</description>
        <pubDate>Thu, 18 Oct 2018 01:07:00 +0900</pubDate>
        <link>http://imjinbro.github.io/2018/10/18/TIL</link>
        <guid isPermaLink="true">http://imjinbro.github.io/2018/10/18/TIL</guid>
        
        <category>TIL</category>
        
        <category>database</category>
        
        <category>operation</category>
        
        
      </item>
    
      <item>
        <title>[TIL - 1015] 절차지향과 객체지향, IaaS/PaaS 개념</title>
        <description>&lt;h2 id=&quot;절차지향-vs-객체지향-프로그래밍&quot;&gt;절차지향 vs 객체지향 프로그래밍&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;입사 첫날 운 좋게도 객체지향의 사실과 오해 저자이자 배민찬 개발자이신 조영호님의 특강을 들을 수 있었다. 절차지향과 객체지향적인 설계와 코드를 비교해가며 각각의 특징과 장단점에 대해 들을 수 있는 시간이었다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;절차지향&quot;&gt;절차지향&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;데이터를 관리하는 클래스와 로직을 처리하는 클래스가 분리되어 있음 : 객체는 단지 데이터를 getter/setter 하는 용도로 밖에 사용되지않음&lt;/li&gt;
  &lt;li&gt;중앙 집중형 코드가 완성됨 : 역할에 따라 로직을 처리하지않고, 데이터를 가진 객체들이 한 곳에서 모여서 절차지향적으로 처리되다보니 변경사항이 생겼을 때 유연하지못함&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;객체지향&quot;&gt;객체지향&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;데이터(상태값)와 로직 처리를 클래스로 구분하지않고 역할을 기준으로 분리함 : 역할을 수행(로직)함에 따라 상태값(데이터)이 변경됨
    &lt;ul&gt;
      &lt;li&gt;각자 맡은 바가 있기 때문에 한 곳에서 처리하지않고 각각에게 위임을 하는 코드가 완성됨&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;RDBMS와 결합해서 코드를 작성하게 될텐데 서로 다른 패러다임으로 인해 Mapper를 사용하게됨 : JPA(대표 구현체 - Hibernate)
    &lt;ul&gt;
      &lt;li&gt;무조건적으로 객체지향이 좋은 것이 아니라 상황에 따라 절차지향만으로도 개발할 수 있음. 다만 변경에 유연한 개발을 위해 객체지향이 필요할 뿐&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;iaas-paas&quot;&gt;IaaS, PaaS&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;IaaS : Infrastructure-as-a-service, 인프라 제공 서비스, AWS/Microsoft Azure가 대표적인 서비스&lt;/li&gt;
  &lt;li&gt;PaaS : Platform-as-a-service, IaaS 포함 개발 툴/기능/배포까지 제공하는 서비스, Heroku가 대표적인 서비스&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 16 Oct 2018 00:16:00 +0900</pubDate>
        <link>http://imjinbro.github.io/2018/10/16/TIL</link>
        <guid isPermaLink="true">http://imjinbro.github.io/2018/10/16/TIL</guid>
        
        <category>TIL</category>
        
        <category>oop</category>
        
        
      </item>
    
  </channel>
</rss>
