<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>sang-eun.log</title>
        <link>https://velog.io/</link>
        <description>꾸준히</description>
        <lastBuildDate>Tue, 04 Oct 2022 00:04:04 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>sang-eun.log</title>
            <url>https://images.velog.io/profiles/sang-eun/thumbnails/1578116857.336.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. sang-eun.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/sang-eun" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[netty 공부]]></title>
            <link>https://velog.io/@sang-eun/netty-%EA%B3%B5%EB%B6%80</link>
            <guid>https://velog.io/@sang-eun/netty-%EA%B3%B5%EB%B6%80</guid>
            <pubDate>Tue, 04 Oct 2022 00:04:04 GMT</pubDate>
            <description><![CDATA[<h1 id="netty는-어떻게-동작하는가">netty는 어떻게 동작하는가?</h1>
<p>Bootstrap에서 bossGroup과 workerGroup을 받는다. 둘다 eventLoop이고 자체 selector를 가지고 있다. bossGroup은 </p>
<h2 id="bootstrap">BootStrap</h2>
<p>네트워크 레이어를 구성하는 컨테이너. bossGroup과 workerGroup을 받는다.
생성자가 빌더패턴으로 되어있음</p>
<h2 id="eventloop">EventLoop</h2>
<ul>
<li>NioEventLoop = socketChannel + selector</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sang-eun/post/6d19ac5a-dace-49e4-9b36-51987641a2d1/image.png" alt=""></p>
<h3 id="작동순서">작동순서</h3>
<ul>
<li>BossNioEventLoop에서 
accept event, client와 커넥션 맺기 -&gt; socketChannel 생성 -&gt; socketChannel이랑 selector를 nioEventLooop에다가 등록하기.  -&gt; runAllTask</li>
<li>worker NioEventLoop 스레드에서 
socketChannel에서 event를 poll해와서 selector에다가 등록 -&gt; 커넥션이 맺어지면 read write 기능 처리 -&gt; runAllTasks</li>
</ul>
<h3 id="등록-순서">등록 순서</h3>
<p>channel -&gt; selector -&gt; eventLoop</p>
<h3 id="질문">질문</h3>
<ul>
<li><p>eventLoop는 왜 group별로 나누어져있는가?
여러 개의 eventLoop를 묶은 이유?</p>
</li>
<li><p>nioEventLoop는 selector를 가지고 있고, selector에다가 socketChannel을 등록한다고 하는데 대체 socketChannel은 어디있는가?</p>
</li>
</ul>
<h3 id="selector">selector</h3>
<p>IO multiplexing에 사용</p>
<ul>
<li><p>IO multiplexing이란?
가장 자주 쓰이는 모델로, 싱글 스레드에서 listen과 블록을 여러 리소스들에 대해 동시에 진행한다 (polling -cpu 자원 낭비- 또는 멀티스레딩을 한다는 의미는 아님) 그리고 하나라도 자원이 준비되면 리턴한다.</p>
</li>
<li><p>netty에서는 selector도 선택 가능
<img src="https://velog.velcdn.com/images/sang-eun/post/64b66734-bb56-4802-b4c6-ca3637491391/image.png" alt="">
java 시스템변수로 지정 가능
selector 커스텀을 고민해볼 수도 있을까?
디폴트는 KQueueSelectorImpl ( for mac os)</p>
</li>
</ul>
<h1 id="코드-보고">코드 보고</h1>
<h2 id="nioeventloopgroup">NioEventLoopGroup</h2>
<p><img src="https://velog.velcdn.com/images/sang-eun/post/debfe682-0e11-4629-92cf-94dbda4fb74f/image.png" alt=""></p>
<p>EventExecutor은 interface인데??</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[카프카]]></title>
            <link>https://velog.io/@sang-eun/%EC%B9%B4%ED%94%84%EC%B9%B4</link>
            <guid>https://velog.io/@sang-eun/%EC%B9%B4%ED%94%84%EC%B9%B4</guid>
            <pubDate>Sat, 18 Jul 2020 11:00:36 GMT</pubDate>
            <description><![CDATA[<h2 id="카프카-커넥트">카프카 커넥트</h2>
<h3 id="필요한-이유">필요한 이유</h3>
<p>카프카와 다른 시스템을 연결을 더 편리하게 하기 위해서이다. 예를 들어서 카프카 커넥트가 없다면 실패한 데이터를 추적한다거나, 데이터 분산처리, 작업을 배포하는 등의 작업을 직접 구현하여야 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[기타등등 두근두근 면접준비]]></title>
            <link>https://velog.io/@sang-eun/%EA%B8%B0%ED%83%80%EB%93%B1%EB%93%B1-%EB%91%90%EA%B7%BC%EB%91%90%EA%B7%BC-%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84</link>
            <guid>https://velog.io/@sang-eun/%EA%B8%B0%ED%83%80%EB%93%B1%EB%93%B1-%EB%91%90%EA%B7%BC%EB%91%90%EA%B7%BC-%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84</guid>
            <pubDate>Mon, 18 May 2020 01:34:22 GMT</pubDate>
            <description><![CDATA[<h1 id="스프링">스프링</h1>
<h2 id="스프링-부트-vs-스프링-mvc">스프링 부트 vs 스프링 MVC</h2>
<ul>
<li>스프링 부트<ul>
<li>내장 톰캣</li>
<li>자동 환경 구성: 트랜잭션 등 자주 사용하는 몇몇 라이브러리들을 자동적으로 설정해줌. 미리 구성된 스타터 패키지 제공</li>
</ul>
</li>
</ul>
<p><a href="http://dveamer.github.io/backend/SpringBootAutoConfiguration.html">http://dveamer.github.io/backend/SpringBootAutoConfiguration.html</a></p>
<h2 id="빈">빈</h2>
<h3 id="빈이란">빈이란?</h3>
<h3 id="빈-스코프">빈 스코프</h3>
<h2 id="필터-vs-인터셉터">필터 vs 인터셉터</h2>
<h3 id="필터">필터</h3>
<ul>
<li>dispatcherServlet 전에 실행</li>
<li>예외가 발생하면 was단에서 처리를 해 주어야 ex. 에러 페이지 만들기</li>
</ul>
<h3 id="인터셉터">인터셉터</h3>
<ul>
<li>dispatcherServlet후에 실행</li>
<li>후에 실행되므로, 필터보다 더 많은 정보(httpServletResponse/Request, 실행될 컨트롤러, 발생한 예외 등)을 전달받을 수 있음</li>
<li>예외가 발생하면 스프링 단의 예외처리 방법을 사용할 수 있음</li>
</ul>
<h1 id="코틀린">코틀린</h1>
<h2 id="코틀린-특징">코틀린 특징</h2>
<ul>
<li>엄격한 null check</li>
<li>함수형, 객체지향 프로그래밍 모두 가능</li>
<li>기본적으로 immutable이어서 스레드 세이프함</li>
<li>data 클래스: equals, hashcode, tostring, getter/setter 자동생성으로 롬복기능 일부 대신가능</li>
</ul>
<h1 id="프로그래밍-패러다임">프로그래밍 패러다임</h1>
<h2 id="명령형-프로그래밍">명령형 프로그래밍</h2>
<ul>
<li>알고리즘을 명시</li>
<li>데이터들이 mutable함<h2 id="선언형-프로그래밍">선언형 프로그래밍</h2>
</li>
<li>알고리즘이 아닌 목표를 명시</li>
<li>데이터 중심적으로, 데이터를 변경하면서 프로그램을 진행하지않으므로  데이터들이 immutable함</li>
<li>외부 상태를 변경하지 않도록 인자가 같으면 언제나 같은 값을 반환하는 순수함수 사용</li>
<li>매개변수 또는 반환값으로 함수를 사용하는 고차함수를 사용(순수함수들의 집합으로 로직을 만들 수 있음)</li>
<li>전달되는 그 함수를 람다라고 함. 람다는 일급함수.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JPA]]></title>
            <link>https://velog.io/@sang-eun/JPA</link>
            <guid>https://velog.io/@sang-eun/JPA</guid>
            <pubDate>Sun, 17 May 2020 17:24:36 GMT</pubDate>
            <description><![CDATA[<p>면접직전이라 JAVA ORM표준 JPA프로그래밍을 이틀만에 급 읽어서 정리; 집중안돼서 너무 힘들었지만 평소에 알고싶었던 개념들이라 지금이라도 정리해서 다행이다..</p>
<h1 id="기본-내부구조">기본 내부구조</h1>
<h2 id="orm이란">ORM이란?</h2>
<ul>
<li>데이터베이스와 자바 간 패러다임의 불일치를 해결하기 위한 도구. 개발자들이 비즈니스 로직에 집중할 수 있게 도와준다.</li>
<li>패러다임 불일치 해결<ul>
<li>반복되는 SQL 자동 생성</li>
<li>자바에서의 상속을 데이터베이스와 매핑해서 객체지향적인 구조를 유지할 수 있게 도와줌</li>
</ul>
</li>
</ul>
<h2 id="jpa의-장점">JPA의 장점?</h2>
<ul>
<li>패러다임의 불일치 해결</li>
<li>연관된 객체 탐색을 보다 간편하게 해줌</li>
<li>동등성 관리에 도움(근데 캐시와 프록시가 끼어드니 더 복잡하게 만드는 것 같아서 참조보다는 값을 통한 비교가 나을 수도 있음)</li>
<li>1차 캐시(영속성 컨텍스트)를 통한 도움<ul>
<li>내부적인 트랜잭션 관리 가능</li>
<li>데이터베이스에 다녀오지 않아도 이미 영속성 컨텍스트에서 가지고 있는 데이터는 곧바로 가져올 수 있음</li>
</ul>
</li>
</ul>
<h2 id="그래도-mybatis를-사용하는-이유">그래도 Mybatis를 사용하는 이유?</h2>
<ul>
<li>지연 로딩같은게 JPA의 장점일 수 있는데, 사실 사용할 객체라면 한번에 join으로 로딩해오는 것이 더 빠를 수 있음</li>
<li>어쩌피 현업에서 매우 단순한 쿼리는 잘 사용하지 않아서 성능도 고려하면 대부분의 쿼리는 개발자가 직접 생성해야 함</li>
<li>제대로 이해하지 못하고 사용하면 추상화되어있기 때문에 문제를 파악하기 어려움 ex)N+1문제</li>
</ul>
<h2 id="그래도-jpa가">그래도 JPA가...</h2>
<ul>
<li>mybatis에서 리턴받은 데이터베이스 오브젝트를 일일히 xml을 통해 자바의 객체와 매핑하는 것이 너무 불편; 패러다임의 불일치 극복 비용이 너무 많이 든다..</li>
</ul>
<h2 id="엔티티-매니저">엔티티 매니저</h2>
<ul>
<li>엔티티와 관련된 모든 일을 처리(CRUD).</li>
<li>서버 요청당 하나일 수도(OSIV), 트랜잭션당 하나일 수도 있고 다양함.</li>
<li>가장 근본적인 원칙은 앤티티 매니저 팩토리는 스레드 세이프하지만 엔티티 메니저는 스레드 간에 공유가 안됨</li>
</ul>
<h2 id="영속-컨텍스트">영속 컨텍스트</h2>
<ul>
<li>1차 캐시 관리</li>
<li>내부에 있는 엔티티들은 모두 식별자를 가지고 있음 -&gt; 따라서 Identity전략(mysql에서 사용)트랜잭션에서 write을 할 경우, 식별자를 알아야지 영속 컨텍스트에 넣을 수 있으므로 쓰기 지연이 발생하지 않음 </li>
</ul>
<h2 id="엔티티의-생명주기">엔티티의 생명주기</h2>
<ul>
<li>비영속: 순수한 자바 객체 상태</li>
<li>영속: 영속성 컨텍스트에 들어간 자바 객체. <ul>
<li>객체의 변경이 추적되어 자동적으로 데이터베이스에 반영된다.</li>
<li>1차 캐시</li>
<li>동일성 보장</li>
<li>트랜잭션 쓰기 지연: flush전에는 데이터베이스에 직접 락을 걸지 않으므로 장점</li>
<li>지연 로딩</li>
</ul>
</li>
<li>준영속: 트랜잭션의 종료 또는 명시적인 영속성 컨텍스트 종료 등으로 영속성이 끊어진 상태. 거의 비영속 상태인데 차이는 식별자 값을 가진 것</li>
<li>삭제</li>
</ul>
<h2 id="관련-어노테이션">관련 어노테이션</h2>
<h3 id="persistencecontext">@PersistenceContext</h3>
<ul>
<li>순수 자바 어플리케이션과는 달리, 스프링에서는 EntityManager를 알아서 관리해주기에, 직접 EntityManagerFactory에서 주입받지 않더라도 주입받을 수 있음</li>
</ul>
<h3 id="repository">@Repository</h3>
<ul>
<li>해당 클래스가 빈으로 등록</li>
<li>JPA전용 에러가 발생하였을 때 추상화된 스프링의 DB에러로 한번 더 감싸서 나옴</li>
</ul>
<h1 id="객체의-연관관계">객체의 연관관계</h1>
<h2 id="다대일-양방향">다대일 양방향</h2>
<ul>
<li>member * - 1 team일 경우</li>
<li>member가 foreign key를 관리할 수 있도록 설정하는 것이 편리. -&gt; @ManyToOne</li>
<li>team는 member의 외래키를 이용해서 List&lt; member &gt;를 생성하는 것이므로, 연관관계의 실제 주인인 member의 team속성을 넣어줌-&gt; @ManyToOne(mappedBy=&quot;team&quot;)<ul>
<li>왜넣어주지? 싶었는데 List&lt; member &gt;이 많을 경우 ex) 학교 팀 멤버들, 동네 팀 멤버들... 이렇게 있을 때 구분해주기 위해서인듯 </li>
</ul>
</li>
<li>주의사항<ul>
<li>한쪽에만 데이터를 넣거나 삭제하면 다른 쪽에는 반영되지 않기 때문에, 양쪽에 넣어주는 함수 만들어 사용하면 편함(단, 영속성 전이를 사용하면 양쪽에 반영할 수 있음)</li>
<li>순환참조</li>
</ul>
</li>
</ul>
<h2 id="상속관계">상속관계</h2>
<ul>
<li><p>부모, 자식들을 각자 다른 테이블로 만듬</p>
<ul>
<li>장<ul>
<li>테이블이 정규화됨</li>
<li>효율적인 데이터 사용</li>
</ul>
</li>
<li>단<ul>
<li>많은 조인이 들어감</li>
<li>insert할때 부모, 자식 두번 들어감</li>
</ul>
</li>
</ul>
</li>
<li><p>부모, 자식에서 필요한 칼럼들을 모아서 하나의 테이블로 만듬</p>
<ul>
<li>장<ul>
<li>성능을 높일 수 있음</li>
<li>조회 쿼리 단순</li>
</ul>
</li>
<li>단<ul>
<li>칼럼들이 nullable해짐</li>
<li>저장공간 낭비</li>
</ul>
</li>
</ul>
</li>
<li><p>부모에서 필요한 칼럼들을 모두 자식 테이블에 넣음</p>
<ul>
<li>장<ul>
<li>메모리 공간 절약 + 부모 테이블에 조인할 필요성 없음</li>
</ul>
</li>
<li>단<ul>
<li>자식들을 한꺼번에 모아서 처리하기 불편함</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="식별관계-vs-비식별관계">식별관계 vs 비식별관계</h2>
<ul>
<li>식별관계: 부모 테이블의 기본 키를 받아서 자식 테이블의 기본키 + 외래키로 사용하는 방식</li>
<li>비식별관계: 부모 테이블의 기본 키를 자식 키에서 외래키로 사용하는 것</li>
</ul>
<h1 id="로딩">로딩</h1>
<h2 id="지연-로딩">지연 로딩</h2>
<ul>
<li>한번에 모든 데이터들을 가져오는 것은 매우 비효율적이어서 정말 사용할 때 가져오는 방식</li>
<li>JPA에서는 바이트 코드를 로딩할때 조작하는 로드타임 위빙 방식과 프록시 방식을 사용</li>
</ul>
<h2 id="프록시-방식">프록시 방식</h2>
<ul>
<li>객체를 getReference로 조회하면 엔티티 그대로의 객체가 오는 것이 아니라, 프록시로 한번 더 감싸진 객체가 온다. (영속성 컨텍스트에 존재하면 이미 로딩되었다는 것이므로 불필요하게 프록시로 감싸져있는게 아닌 실제 엔티티를 가져옴) </li>
<li>getReference로 얻은 프록시 객체는 식별자를 가지고 있기에 AcessType이 프로퍼티인 경우에는 getId를 해도 엔티티가 초기화되지 않음(?어떻게.....? Mysql은 디비에 넣어야지 식별자를 알 수 있을텐데... 임시식별자인가?)</li>
<li>실제 데이터를 얻기 위해 get메서드를 사용할 때 초기화를 진행한다.</li>
<li>영속성 컨텍스트의 범위에서 벗어나 있는 경우(ex 컨트롤러단, 영속성 컨텍스트 종료)에 해당 속성에 접근하려고 하면 LazyInitializationException이 뜬다.</li>
</ul>
<h1 id="spring-data-jpa">Spring Data JPA</h1>
<h2 id="사용-이유">사용 이유</h2>
<ul>
<li>별다른 구현 클래스 없이 인터페이스만 만들어놓으면 네이밍 규칙만 맞추면 자동으로 쿼리를 생성해준다 (JpaRepository를 상속받아야 함)</li>
<li>이미 몇가지 findAll같은 인터페이스는 이미 JpaRepository에 들어있음</li>
</ul>
<h1 id="트랜잭션">트랜잭션</h1>
<h2 id="영속성-컨텍스트">영속성 컨텍스트</h2>
<ul>
<li>트랜잭션이 같으면 같은 영속성 컨텍스트를 사용</li>
</ul>
<h2 id="준영속-상태의-지연-로딩-문제">준영속 상태의 지연 로딩 문제</h2>
<p>컨트롤러에서 추가적으로 엔티티를 초기화할 필요가 있을수도 있음. 하지만 컨트롤러는 트랜잭션의 범위를 이미 넘어가서 엔티티가 비영속 상태이고, 더이상 초기화가 불가능해짐.</p>
<ul>
<li>해결방법1: 페치 전략을 즉시로딩으로 수정<ul>
<li>단: N+1문제가 발생, 불필요한 엔티티를 로딩해둠</li>
</ul>
</li>
<li>해결방법2: OSIV를 사용<ul>
<li>이전 OSIV: 필터 또는 인터셉터에서 트랜잭션을 시작해 요청당 하나의 영속성 컨텍스트를 사용 -&gt; 컨트롤러에서 뷰에 보여지기 위해 임시로 엔티티의 데이터를 수정하면, 영속성 컨텍스트 내부에 있으므로 결과적으로 요청을 반환할 때 DB에 반영되는 문제<ul>
<li>해결책: 엔티티를 읽기 전용으로 전달(getter만 있는 인터페이스 타입으로 전달. 매번 인터페이스를 작성해야 한다는 불편함), DTO로 전달, wrapper로 전달 다 비슷한 단점</li>
</ul>
</li>
<li>현재 OSIV: 필터 또는 인터셉터에서 영속성 컨텍스트를 만들어 영속성 컨텍스트는 요청 전체로 유지를 하되, 트랜잭션은 서비스 계층만으로 국한시킴. -&gt; 서비스 호출이 끝나고 컨트롤러에서 데이터를 수정하여도, flush는 이미 하였으니 디비에는 반영되지 않을 것. flush를 명시적으로 호출하여도 트랜잭션의 범위 밖이라서 데이터 변경 불가 에러 발생(그런가보다..)
하지만 service -&gt; 컨트롤러에서 수정 -&gt; service하면 결국 flush하니 디비에 반영되는디...? -&gt; 그러지 마라....</li>
</ul>
</li>
</ul>
<h2 id="롤백-문제">롤백 문제</h2>
<p>트랜잭션이 롤백되어도, 영속성 상태의 객체는 이미 수정되어서 남아있음. 따라서 명시적으로 em.clear같이 초기화를 해줘야 함
-&gt; 그런데 스프링에서는 내부적으로 롤백발생하면 알아서 초기화해줌</p>
<h1 id="추가적인-문제들">추가적인 문제들</h1>
<h2 id="엔티티-동등성">엔티티 동등성</h2>
<ul>
<li>영속성 컨텍스트가 같으면 같은 엔티티는 같은 참조를 가짐</li>
<li>반면 영속성 컨텍스트가 다를 때는 엔티티의 동일성 비교(==)는 실패하므로, 되도록이면 미스하지 않도록 동등성 비교(equals)쓰는게 좋음</li>
</ul>
<h2 id="프록시-객체-동등성">프록시 객체 동등성</h2>
<ul>
<li>getReference하고 find하면? -&gt; 영속성 컨텍스트에서는 find에다가 이미 찾아놓은 프록시 객체 돌려줌</li>
<li>find -&gt; getReferenct하면? -&gt; 영속성 컨텍스트에서는 getReference에다가 이미 로딩해놓은 엔티티 객체 돌려줌</li>
<li>동등성 지켜짐 </li>
<li>심화문제있는데 나중에 657 이해해보자</li>
</ul>
<h2 id="성능-최적화">성능 최적화</h2>
<h3 id="n1문제">N+1문제</h3>
<p>지연 로딩으로 인해 객체들을 찾아오고, 가지고있는 외부참조 속성들을 하나씩 초기화하게 되면 요청이 매 객체마다 날라가는 문제 발생</p>
<h1 id="락">락</h1>
<h2 id="낙관적-락">낙관적 락</h2>
<ul>
<li>트랜잭션 대부분이 충돌이 발생하지 않는다고 가정</li>
<li>JPA가 제공하는 버전 관리 기능 이용</li>
<li>동시에 두 데이터를 트랜잭션에서 변경할 때, 최초 커밋만 인정하도록 구현</li>
<li>Version사용: 트랜잭션이 데이터를 변경하거나, 심지어는 조회만 했을 때(경우에 따라 다르게 설정가능) 버전을 하나씩 높임. 칼럼으로 하나 둬서 JPA가 관리. 만약 커밋을 할 때 내가 가지고 있는 버전과 다르면 다른 트랜잭션에서 이미 접근했다는 의미이므로 에러를 발생시키고 반영하지 않음.<ul>
<li>NONE: 데이터 변경시 버전 높여서 두번의 갱신으로 인해 데이터가 유실되는 것을 방지</li>
<li>OPTIMISTIC: 조회시 버전을 높여서 다른 트랜잭션들의 non repeatable read를 방지</li>
</ul>
</li>
</ul>
<h2 id="비관적-락">비관적 락</h2>
<ul>
<li>트랜잭션의 충돌이 발생한다고 가정하고 우선 락을 검</li>
<li>데이터베이스가 제공하는 락 기능 사용(ex. for update)</li>
</ul>
<h1 id="2차-캐시">2차 캐시</h1>
<ul>
<li>2차 캐시를 추가로 둘 수 있음. </li>
<li>1차 캐시에서 없으면 2차 캐시를 한번 더 찾아서 네트워크 비용을 줄일 수 있도록 함</li>
<li>동시성을 극대화하기 위해 객체를 그대로 반환하지 않고 복사본을 반환</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[트랜잭션]]></title>
            <link>https://velog.io/@sang-eun/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98</link>
            <guid>https://velog.io/@sang-eun/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98</guid>
            <pubDate>Fri, 15 May 2020 12:28:02 GMT</pubDate>
            <description><![CDATA[<h2 id="스프링의-트랜잭션">스프링의 트랜잭션</h2>
<h3 id="기능">기능</h3>
<ul>
<li><p>트랜잭션 추상화</p>
<ul>
<li>서비스의 종류나 환경이 변화되더라도 트랜잭션을 사용하는 코드는 그대로 유지 가능</li>
</ul>
</li>
<li><p>트랜잭션 동기화</p>
</li>
</ul>
<h3 id="트랜잭션-경계설정방법">트랜잭션 경계설정방법</h3>
<ul>
<li>PlatformTransactionManager의 구현체들을 사용</li>
<li>getTransaction -&gt; commit or rollback 메서드 사용</li>
</ul>
<ol>
<li>코드를 이용한 트랜잭션 경계설정</li>
<li>선언적 트랜잭션 경계설정: 데코레이터를 이용한 트랜잭션 프록시 빈 사용<ul>
<li>@Transactional</li>
</ul>
</li>
</ol>
<h3 id="transactional-동작방법">@Transactional 동작방법</h3>
<p>프록시 기반으로 다이나믹 프록시나 CGLib를 통해서 구현되거나, 타깃 오브젝트를 직접 조작하는 방식의 AspectJ방식이 있습니다. 스프링 boot는 디폴트로 CGLib를 사용</p>
<ul>
<li>다이나믹 프록시는 인터페이스에 적용하는 프록시이기 때문에 인터페이스가 필요</li>
<li>CGLib는 클래스를 상속해서 프록시를 만들기 때문에 final 클래스는 불가</li>
<li>AspectJ는 프록시를 타깃 오브젝트 앞에 두지 않고, 타깃 오브젝트 자체를 직접 조작</li>
</ul>
<p><a href="http://wonwoo.ml/index.php/post/1708">http://wonwoo.ml/index.php/post/1708</a></p>
<h2 id="트랜잭션-속성">트랜잭션 속성</h2>
<h3 id="트랜잭션-전파">트랜잭션 전파</h3>
<p>새로운 트랜잭션이 시작될 경우, 이것을 기존의 트랜잭션에 참여시키는 방법을 결정</p>
<ul>
<li>required: 디폴트. 기존의 트랜잭션이 있으면 참여하고 없으면 새로 시작</li>
<li>requires_new: 매번 새로운 트랜잭션</li>
<li>nested: 부모의 트랜잭션에 참여하지만, 자신이 에러가 발생할 경우에는 부모에 영향을 끼치지 않는다. 로그작업같은데 쓰임. 내부적으로 savepoint를 사용</li>
</ul>
<h3 id="트랜잭션-격리수준">트랜잭션 격리수준</h3>
<ul>
<li>read_uncommitted: dirty read(트랜잭션 작업이 완료되지 않았는데도 다른 트랜잭션에서 볼 수 있는 현상) 발생. 다른 트랜잭션의 커밋하지 않은 데이터들을 읽을 수 있음</li>
<li>read_committed: 다른 트랜잭션의 커밋한 데이터를 읽을 수 있음. 다시 읽었을 때 데이터가 달라질 수 있는 문제 발생</li>
<li>repeatable_read: 하나의 트랜잭션이 일관적인 데이터를 볼 수 있도록 함. 단, 다른 트랜잭션에서의 삽입의 경우에는 새로운 데이터가 추가될 수 있음.</li>
<li>serializable: 읽기에는 shared_lock, 쓰기에는 exclusive_lock을 걸어서 극도의 일관성을 보장.</li>
</ul>
<h3 id="그-외">그 외</h3>
<ul>
<li>timeout</li>
<li>read_only</li>
<li>rollback_for</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[ORM]]></title>
            <link>https://velog.io/@sang-eun/ORM</link>
            <guid>https://velog.io/@sang-eun/ORM</guid>
            <pubDate>Fri, 15 May 2020 12:25:37 GMT</pubDate>
            <description><![CDATA[<h2 id="orm이란">ORM이란?</h2>
<p>오브젝트와 RDB 사이에 존재하는 패러다임의 불일치 때문에 요구되는 불편한 작업들(sql 작성, 자바 객체에서의 상속 - DB에서는 외래키로, 다형성, 레퍼런스, 오브젝트 합성)을 대신 해결해준다. DB와 자바 객체의 자동 매핑, SQL자동생성 등이 존재.</p>
<h2 id="jpa-vs-mybatis">JPA vs Mybatis</h2>
<ul>
<li>mybatis<ul>
<li>단<ul>
<li>SQL을 직접 작성하고, 결과를 따로 xml에 매핑해서 자바 객체에 담아주는 작업이 번거롭다.<ul>
<li>장</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="jdbc---mybatis---jpa">JDBC -&gt; Mybatis -&gt; JPA</h2>
<ul>
<li><p>mybatis</p>
<ul>
<li>자바오브젝트만을 이용해 데이터 로직 작성 가능(이전에는 ResultSet으로 담아옴)</li>
<li>SQL을 별도의 파일로 분리 가능</li>
</ul>
</li>
<li><p>JPA</p>
<ul>
<li>데이터베이스의 오프젝트와 자바의 객체 간 매핑을 자동적으로 해줌</li>
<li>기본적인 SQL을 작성할 필요가 없음</li>
</ul>
</li>
</ul>
<h1 id="jpa">JPA</h1>
<h2 id="entitymanager">EntityManager</h2>
<ul>
<li>DAO에서 주입받아서 사용해야 함</li>
<li>@PersistenceContext EntityManager em;</li>
<li>트랜잭션마다 한번 만들어지고, 종료되면 함께 제거되어야하는데 어떻게 이 코드로? 이 코드는 마치 DAO에서 한번 주입받고 계속 쓰는 것 같음</li>
<li>=&gt; 저 EntityManager은 실제 EntityManager이 아니라 프록시임. 각 트랜잭션마다 다른 EntityManager을 보장</li>
</ul>
<h2 id="바이트코드-향상-기법">바이트코드 향상 기법</h2>
<ul>
<li>바이트코드를 직접 조작해서 지연 로딩, 엔티티 값 변화 추적, 최적화와 그룹 페칭 등의 고급 기능 적용 가능</li>
<li>방법<ul>
<li>바이트 코드를 빌드 중에 변경: JPA가 제공하는 바이트코드 컴파일러가 필요하다는 단점이 있음</li>
<li>바이트 코드를 로딩하면서 다이내믹하게 바이트코드를 변경해 기능 추가(로드타임 위빙)</li>
<li>지연로딩을 위해 프록시를 사용</li>
</ul>
</li>
</ul>
<h2 id="hibernate">Hibernate</h2>
<ul>
<li>JPA의 구현체</li>
<li>JPA의 EntityMangerFactory처럼 핵심 역할을 하는 SessionFactory존재</li>
<li>TransactionManager존재</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[bean]]></title>
            <link>https://velog.io/@sang-eun/bean</link>
            <guid>https://velog.io/@sang-eun/bean</guid>
            <pubDate>Mon, 11 May 2020 16:37:55 GMT</pubDate>
            <description><![CDATA[<h2 id="bean이란">bean이란?</h2>
<ul>
<li>스프링은 이전에 프레임워크와 의존성이 매우 높았던 EJB대신 POJO객체를 쓰는 것을 강조한다.</li>
<li>POJO란 프레임워크에 독립적인 객체를 의미한다. </li>
<li>IOC컨테이너, 즉 application context에서 beanFactory 인터페이스들을 확장해 bean들의 라이프사이클을 관리한다.</li>
</ul>
<h2 id="bean의-메타정보">bean의 메타정보</h2>
<ul>
<li>빈 아이디: 빈 오브젝트를 구분할 수 있는 식별자</li>
<li>클래스 or 클래스 이름: 빈으로 만들 POJO클래스 또는 서비스 클래스 정보</li>
<li>스코프: 빈의 생성 방식과 존재 범위</li>
<li>프로퍼티 값 또는 참조: DI에 사용할 프로퍼티 이름과 값 또는 참조하는 빈의 이름</li>
<li>생성자 파라미터 값 또는 참조: DI에 사용할 생성자 파라미터 이름과 값 또는 참조할 빈의 이름</li>
<li>지연된 로딩 여부, 우선 빈 여부, autowiring여부, 부모 빈 정보, 빈팩토리 이름 등</li>
</ul>
<h2 id="bean-scope란">bean scope란?</h2>
<ul>
<li>singleton: 한번만 생성해서 캐시해두고 계속해서 사용(디폴트)<ul>
<li>상태가 없을 때</li>
<li>이뮤터블 할 때</li>
<li>상태가 있어도 생성하는 비용이 매우 클 때</li>
</ul>
</li>
<li>prototype: 사용할때마다 계속 생성<ul>
<li>뮤터블해서 동기화 비용을 생각할 바에는 객체를 새로 만들 때</li>
</ul>
</li>
<li>request: 한 http request안에는 하나의 객체만 존재</li>
<li>session: 한 http session안에는 하나의 객체만 존재</li>
<li>global session: 한 global session안에는 하나의 객체만 존재</li>
</ul>
<h2 id="singleton-vs-prototype">singleton vs prototype</h2>
<ul>
<li>싱글톤<ul>
<li>ioc컨테이너가 빈의 초기화 및 라이프사이클 관리</li>
</ul>
</li>
<li>prototype<ul>
<li>ioc컨테이너는 빈을 초기화하고 di를 해주지만, 거기서부터는 di받은 빈이 담당한다. 즉, di받은 빈이 제거되면 그때 해당 빈도 제거됨</li>
<li>사용자의 요청별로 필요한 오브젝트(ex DTO)를 new로 안만들고 ioc에서 DL받을 필요가 있을 때 사용
ex) DTO 내부에서 DB에 접근할 필요가 있어서 DAO를 주입받아야 할 때</li>
<li>왜 DI를 안하고 DL을?: DI를 할 경우에는 컨트롤러에서 DTO를 di받을텐데, 이렇게 하면 컨트롤러의 빈스코프가 싱글톤이기 때문에 해당 DTO의 빈스코프가 프로토타입이어도 요청마다 제거되지 않음. 따라서 컨트롤러에 들어와서 지역변수에다가 DL을 하면 요청이 끝나면 제거됨.</li>
</ul>
</li>
</ul>
<h2 id="다른-요청-스코프-세션-스코프들은-왜-dl">다른 요청 스코프, 세션 스코프들은 왜 DL?</h2>
<ul>
<li>DI로 할 경우에는 맨처음에 객체를 초기화할 때, 에러가 발생할 것&lt;- 요청 스코프는 요청이 들어오면 객체를 생성하기 때문. 따라서 나중에 주입할 수 있는 DL로 찾아오는게 옳다.</li>
</ul>
<h2 id="요청-스코프와-프로토타입의-차이">요청 스코프와 프로토타입의 차이</h2>
<ul>
<li>그러면 매 요청마다 새로 생성되니 같은 것 아닌가?</li>
<li>ㄴㄴ 보통 평범하게 사용하면 매 요청마다 새로 생성하겠지만, getBean을 여러번 하면 요청 스코프는 요청 안에서는 매번 똑같은 객체를 얻을 수 있지만, 프로토타입의 경우에는 매번 다른 객체를 얻음 </li>
</ul>
<p>수정자 주입, 생성자 주입
application Context 두개</p>
<h2 id="dl방식">DL방식</h2>
<ul>
<li>ServiceLocatorFactoryBean, 메소드 주입 등등..</li>
<li>@Inject Provider&lt; T &gt;사용하는 방식이 제일 많이 쓰임</li>
</ul>
<h2 id="세션-스코프-동작방식">세션 스코프 동작방식</h2>
<p>스코프 프록시 오브젝트 사용 - 어떤 오브젝트를 가져올지는 알아서 추상화가 됨</p>
<h2 id="bean을-가져오는-순서">bean을 가져오는 순서</h2>
<ul>
<li>빈의 메타 정보를 기록해 둔 beanDefinition을 등록 applicaionContext에 등록</li>
<li>applicaionContext내부에서 빈을 생성</li>
<li>applicationContext에서 빈을 가져와서 사용</li>
</ul>
<h2 id="webapplicaioncontext">WebApplicaionContext</h2>
<ul>
<li>ApplicationContext구현체중 WebApplicationContext가 웹 서비스에서 가장 편하게 사용 가능</li>
<li>main메소드 역할을 하는 서블릿을 만들어두고, 어플리케이션 컨텍스트를 생성한 뒤, 요청이 서블릿으로 들어올 때마다 getBean으로 빈을 가져와 정해진 메소드를 실행하는 방식이었는데(스프링의 덜 추상화된 api를 사용하니 프레임워크에 종속적으로 됨), webApplicationContext를 사용하면 DispatcherServlet이 중간 역할을 대신해준다. 요청이 들어오면 기존에 생성한 어플리케이션 컨텍스트에서 빈을 찾아와 이를 실행시켜주는 역할</li>
<li>이 DispatcherServlet가 들어온 모든 요청에 대해 filter를 처리하고 알맞은 핸들러에 요청을 전달하기 때문에 프론트 컨트롤러라고도 함</li>
</ul>
<h2 id="bean-스캔-방식">bean 스캔 방식</h2>
<ul>
<li>스테레오타입 어노테이션이 붙어 있을 경우 빈으로 인식: 클래스에 붙어서 해당 클래스가 컴포넌트 스캐닝의 대상이고 스프링을 통해 관리될 것이라고 명시하는 어노테이션</li>
</ul>
<h2 id="bean등록-방법">bean등록 방법</h2>
<ul>
<li>configuration + bean: bean이 싱글톤일 경우 싱글톤으로 동작</li>
<li>bean: 매 요청마다 새로운 객체를 리턴</li>
<li>component: 클래스에 붙이는 스테리오타입 어노테이션</li>
</ul>
<h2 id="autowired">autowired</h2>
<h3 id="방식">방식</h3>
<ul>
<li>생성자: <ul>
<li>장 <ul>
<li>수정자 메소드가 많아질 일이 없다</li>
<li>순환 참조를 미리 알 수 있다.</li>
</ul>
</li>
<li>단<ul>
<li>일부 프로퍼티는 쪽 DI하지 않고 선택적으로 DI할 수 있도록 하지 못한다(아니 할 수 있잖아????)</li>
</ul>
</li>
</ul>
</li>
<li>수정자</li>
<li>필드<h3 id="관련-anotation">관련 anotation</h3>
</li>
<li>resource: 빈의 이름과 타입으로 찾음</li>
<li>autowired: 빈의 이름과 타입으로 찾음<ul>
<li>resource와의 차이: 생성자에도 부여 가능</li>
</ul>
</li>
<li>qualifier: 빈에게 한정자 값을 주고 이 한정자를 가진 빈을 autowired할 수 있게 한다.</li>
<li>value: 해당되는 값을 넣어줌</li>
</ul>
<h2 id="컨테이너-위치">컨테이너 위치</h2>
<h3 id="webapplication-레벨에-컨테이너-존재">WebApplication 레벨에 컨테이너 존재</h3>
<ul>
<li>프론트 컨트롤러 서블릿의 어플리케이션 컨텍스트를 자식으로, 웹 어플리케이션에 어플리케이션 컨텍스트를 부모로 두는 구조</li>
<li>하나로 합쳐도 되지만, 스프링을 사용하지 않는 기술들은 서블릿을 거쳐갈 필요가 없기에 곧바로 루트 어플리케이션 컨텍스트에 접근하라고 둠</li>
</ul>
<p><img src="https://images.velog.io/images/sang-eun/post/a00c14d5-e089-4bd6-b9e6-5169f77b02c1/image.png" alt=""></p>
<h1 id="주입-방식">주입 방식</h1>
<h2 id="생성자-주입">생성자 주입</h2>
<ul>
<li>어플리케이션을 실행하면 객체를 생성하기 위해 DI를 받는데, 여기서 순환참조를 확인할 수 있음.<h2 id="필드-주입-새터-주입">필드 주입, 새터 주입</h2>
</li>
<li>객체를 메모리에 올린 다음에 DI를 하므로, 어플리케이션을 실행해도 에러를 발견할 수 없음</li>
<li>필드를 final로 지정할 수 없음</li>
</ul>
<p><a href="https://coding-start.tistory.com/250">https://coding-start.tistory.com/250</a></p>
<h2 id="mvc패턴이란">MVC패턴이란?</h2>
<p>모델, 뷰 컨트롤러로 이뤄진 패턴으로, 두가지 구현 방식이 존재</p>
<ul>
<li>모델이 뷰를 옵저버로 관리</li>
<li></li>
</ul>
<h2 id="spring-mvc-vs-spring-boot">spring mvc vs spring boot</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[이펙티브 자바]]></title>
            <link>https://velog.io/@sang-eun/%EC%9D%B4%ED%8E%99%ED%8B%B0%EB%B8%8C-%EC%9E%90%EB%B0%94</link>
            <guid>https://velog.io/@sang-eun/%EC%9D%B4%ED%8E%99%ED%8B%B0%EB%B8%8C-%EC%9E%90%EB%B0%94</guid>
            <pubDate>Mon, 11 May 2020 06:32:13 GMT</pubDate>
            <description><![CDATA[<h2 id="정적-메서드">정적 메서드</h2>
<ul>
<li>생성자에 이름을 가질 수 있음 </li>
<li>인스턴스를 새로 생성하지 않아도 됨 <ul>
<li>immutable이기 때문에 객체를 만들어놓고(캐싱해놓고) 재활용 가능<ul>
<li>싱글턴        </li>
</ul>
</li>
<li><h2 id="싱글턴-방식">싱글턴 방식</h2>
</li>
</ul>
</li>
<li>인스턴스를 하나만 만들고 재활용하는 방식</li>
</ul>
<h2 id="중첩-클래스">중첩 클래스</h2>
<h3 id="종류">종류</h3>
<ul>
<li>정적 멤버 클래스: 바깥 클래스의 private멤버에도 접근할 수 있음(일반 클래스와 비교) </li>
<li>inner class<ul>
<li>비정적 멤버 클래스</li>
<li>익명 클래스</li>
<li>지역 클래스</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring]]></title>
            <link>https://velog.io/@sang-eun/Spring</link>
            <guid>https://velog.io/@sang-eun/Spring</guid>
            <pubDate>Wed, 06 May 2020 05:58:23 GMT</pubDate>
            <description><![CDATA[<h3 id="spring을-사용하는-이유">Spring을 사용하는 이유</h3>
<ul>
<li>객체지향적인 프로그래밍을 위해서</li>
<li>aop, ioc, di, psa를 사용하여 훨씬 간단한 프로그래밍 가능</li>
</ul>
<h3 id="어떻게-객체지향적인-프로그래밍을">어떻게 객체지향적인 프로그래밍을?</h3>
<ul>
<li>aop는 분산된 책임을 한 곳에 집중시키므로 srp원칙을 지킬 수 있음</li>
<li>ioc는 객체의 생성과 라이프사이클 관리를 프레임워크에 맡기는 방식이므로, 의존성을 줄일 수 있음</li>
<li>psa를 이용해서는 환경에 구애받지 않는 프로그래밍을 할 수 있으므로 의존성을 줄일 수 있다.</li>
</ul>
<h1 id="aop">AOP</h1>
<h3 id="aop란">AOP란?</h3>
<p>분산되어있는 횡단관심사들을 핵심로직들과 분리해 한곳에 모아서 개발하는 기법</p>
<h3 id="어떻게-구현하는가">어떻게 구현하는가?</h3>
<p>프록시 기반으로 다이나믹 프록시나 CGLib를 통해서 구현되거나, 타깃 오브젝트를 직접 조작하는 방식의 AspectJ방식이 있습니다. Spring AOP에서는 다이나믹 프록시나 cglib사용</p>
<ul>
<li>다이나믹 프록시는 인터페이스에 적용하는 프록시이기 때문에 인터페이스가 필요</li>
<li>CGLib는 클래스를 상속해서 프록시를 만들기 때문에 final 클래스는 불가. 런타임 위빙, 하지만 나중에 캐싱해서 사용하기는 함</li>
<li>AspectJ는 프록시를 타깃 오브젝트 앞에 두지 않고, 타깃 오브젝트 자체를 직접 조작. 클래스 or 클래스로드 타임 위빙을 하기 때문에 좀더 빠르다.</li>
</ul>
<h1 id="ioc">IOC</h1>
<h3 id="ioc란">IOC란?</h3>
<ul>
<li>프로그램의 흐름을 프레임워크에 위임하는 방식</li>
<li>구체적으로 이야기하면 객체의 라이프사이클을 프레임워크에서 관리</li>
<li>방법으로 DI와 DL을 사용함</li>
</ul>
<h3 id="di란">DI란?</h3>
<ul>
<li>객체를 주입받는 방식 </li>
<li>DI사용 이유: 의존 객체를 매번 직접 생성하면 메모리 낭비도 있고, 객체 수정을 하면 산탄총 수술을 해야 함</li>
<li>테스트에도 편리(테스트시에는 테스트를 위한 클래스를 주입해줄수도 있음)</li>
<li>setter, 생성자, 필드 주입 방식</li>
</ul>
<h3 id="어느-주입-방식이-가장-좋은가">어느 주입 방식이 가장 좋은가?</h3>
<ul>
<li>생성자 주입 방식</li>
<li>immutable한 객체를 만들 수 있고, 객체 생성시점에서 순환참조 여부를 알 수 있다. (왜? -&gt; 컨테이너가 빈을 생성하는 시점에 객체생성을하는데, 그때 순환참조가 생기기 때문. 필드주입 같은 경우에는 객체생성시점에 필드주입을 하지는 않는듯.)</li>
</ul>
<p><a href="https://yaboong.github.io/spring/2019/08/29/why-field-injection-is-bad/">https://yaboong.github.io/spring/2019/08/29/why-field-injection-is-bad/</a></p>
<h3 id="dl이란">DL이란?</h3>
<p>IOC컨테이너를 참조해 얻고자하는 객체를 검색하는 것</p>
<h1 id="psa">PSA</h1>
<h3 id="psa란">PSA란?</h3>
<ul>
<li>환경에 구애받지 않고 프로그래밍을 할 수 있는 추상화 기법</li>
<li>예: PlatformTransactionManager은 구현체가 변경되더라도 동일한 인터페이스로 프로그래밍 가능</li>
</ul>
<h1 id="final-static">final, static</h1>
<h3 id="final">final</h3>
<p>객체마다 하나씩 가지고, 값을 바꿀 수 없음</p>
<h3 id="static-final">static final</h3>
<p>클래스에 하나뿐이고, 값을 바꿀 수 없는 엄연한 상수</p>
<h3 id="static-변수는-어디에-올라가는가">static 변수는 어디에 올라가는가?</h3>
<ul>
<li>method area에 정적으로 클래스 정보를 올릴 때 올라감</li>
<li>heap 영역에 동적으로 생성되는 객체들은 GC의 영향을 받지만, method area에 들어간 클래스 정보들은 프로그램이 끝날때까지 계속 유지되므로 남발하면 안됨</li>
</ul>
<h1 id="jpa">JPA</h1>
<h3 id="jpa란">JPA란?</h3>
<p>자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스</p>
<h3 id="hibernate란">Hibernate란?</h3>
<p>JPA의 구현체</p>
<h3 id="spring-data-jpa란">Spring Data JPA란?</h3>
<ul>
<li>JPA를 쓰기 편하게 만들어놓은 모듈</li>
<li>Repository라는 추상화 인터페이스가 핵심</li>
<li>Repository에 적합하게 함수명을 만들면 자동으로 쿼리를 만들어준다.</li>
</ul>
<h1 id="orm">ORM</h1>
<ul>
<li>객체와 관계형 데이터를 자동으로 매핑시키는 것</li>
<li>Sequelize, JPA 등 써봄</li>
<li>장: 비즈니스 로직에 집중 가능, 추상화로 인해 DB의 구현에 덜 의지하게 됨</li>
<li>단: 프로시저가 많은 경우에는 도입이 까다로움 </li>
</ul>
<h1 id="스프링-트랜잭션">스프링 트랜잭션</h1>
]]></description>
        </item>
        <item>
            <title><![CDATA[QR코드 에러]]></title>
            <link>https://velog.io/@sang-eun/QR%EC%BD%94%EB%93%9C-%EC%97%90%EB%9F%AC</link>
            <guid>https://velog.io/@sang-eun/QR%EC%BD%94%EB%93%9C-%EC%97%90%EB%9F%AC</guid>
            <pubDate>Sat, 07 Mar 2020 18:15:41 GMT</pubDate>
            <description><![CDATA[<p>QR코드를 일반 script 에서 type=&quot;module&quot;로 바꾸니 문제가 생겼다.</p>
<p><img src="https://images.velog.io/images/sang-eun/post/0eeb3ed0-4c60-458d-8386-47fef846ace0/image.png" alt=""></p>
<p>갑자기 undefined에서 값을 불러오려고 한다는 것이다.</p>
<p>에러난 부분의 코드는 아래와 같다. </p>
<pre><code class="language-javascript">if (this._android &amp;&amp; this._android &lt;= 2.1) {
            var factor = 1 / window.devicePixelRatio;
            var drawImage = CanvasRenderingContext2D.prototype.drawImage;
            CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
                if ((&quot;nodeName&quot; in image) &amp;&amp; /img/i.test(image.nodeName)) {
                    for (var i = arguments.length - 1; i &gt;= 1; i--) {
                        arguments[i] = arguments[i] * factor;
                    }
                } else if (typeof dw == &quot;undefined&quot;) {
                    arguments[1] *= factor;
                    arguments[2] *= factor;
                    arguments[3] *= factor;
                    arguments[4] *= factor;
                }

                drawImage.apply(this, arguments);
            };
        }</code></pre>
<p>  왜 갑자기 이전에는 window에 잘 바인딩되던 this가 이번에는 undefined로 바인딩 되어 에러가 발생한 것이다.</p>
<p>  자세히 알아보니 <code>모듈 방식은 strict모드를 사용한다는 것</code>을 알게 되었고
  strict모드에서는 전역에서 this가 window로 바인딩되지 않는다는 것을 깨달았다.</p>
<p>  즉, 순서대로 생각하면 이 <code>new QRCode()</code>를 실행하는 곳은 모듈이었기 때문에 this는 undefined로 바인딩된다. 여기서 생성자를 호출해 QRCode 인스턴스를 생성했다면, 그 인스턴스는 호출한 곳의 this에 바인딩되고, 그 인스턴스의 this도 undefined가 된다.</p>
<pre><code class="language-javascript">  const printCode = (url) =&gt; {
    const qrCode = new QRCode(&quot;qrcode&quot;, qrOption);

    qrCode.makeCode(url);
};</code></pre>
<p>그러면 해결책은</p>
<ol>
<li>인스턴스의 this를 window로 바인딩</li>
<li>strict모드를 취소</li>
<li>코드를 수정</li>
</ol>
<p>이렇게 세가지 방법이 있을 수 있다.
하지만 1번의 경우, new를 통해 객체의 인스턴스를 생성하는 작업에 call함수를 통해 this를 바인딩하는 것은 불가능했다.
또한 2번도 찾아본 결과 불가능했다.
결국 this에러가 발생하는 코드를 window로 직접 수정해보기로 하였고, 일단 한 줄만 수정해서 해결이 되었다. </p>
<p>하지만 현재 상황에서만 잘 동작하지, 다른 상황에서는 어떻게 동작할지 모르므로 코드를 직접 읽고 이해해서 고치거나, 모듈 방식이 아니라 script방식을 그대로 사용하는 것이 좋을 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오브젝트 4~ 정리]]></title>
            <link>https://velog.io/@sang-eun/%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-4-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@sang-eun/%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-4-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 24 Feb 2020 01:37:52 GMT</pubDate>
            <description><![CDATA[<h1 id="설계-품질과-트레이드오프">설계 품질과 트레이드오프</h1>
<h2 id="객체지향-설계-방법">객체지향 설계 방법</h2>
<ul>
<li>상태를 분할의 중심축으로 삼기</li>
<li>책임을 분할의 중심축으로 삼기
두가지 방법이 있다. 물론 후자가 더 적합한 방법이다. 객체의 데이터(상태)는 구현에 속한다. 구현을 중심으로 삼으면 인터페이스에 구현의 세부사항이 들어가고, 캡슐화의 원칙이 무너진다. 결과적으로 상태가 변경되면 인터페이스가 변경되고, 인터페이스에 의존하는 모든 객체들이 변경된다.</li>
</ul>
<p>반대로 책임은 인터페이스에 속하므로, 안정적으로 캡슐화가 가능하고 구현의 파장이 외부로 벗어나지 않는다.</p>
<h2 id="객체지향-평가-방법">객체지향 평가 방법</h2>
<p>객체지향적인 설계인지 평가하는 방법에는 세 가지가 존재한다.</p>
<ul>
<li>캡슐화</li>
<li>응집도</li>
<li>결합도</li>
</ul>
<h3 id="캡슐화">캡슐화</h3>
<p>캡슐화는 품질의 가장 중요한 척도로서, 응집도와 결합도에도 영향을 끼친다. 
객체의 상태와 행동을 객체 안에 모으는 것을 캡슐화라고 한다. 변경될 가능성이 높은 구현은 내부에 두고, 안정적인 인터페이스를 통해 외부와 통신하는 것을 말한다.</p>
<h3 id="응집도-결합도">응집도, 결합도</h3>
<p>응집도란 모듈에 포함된 내부 요소들이 연관되어있는 정도를 나타낸다. 
구체적으로 말하면, 변경이 발생할 때 모듈 내부 전체가 함께 변경된다면 응집도가 높은 것이다. </p>
<h3 id="결합도">결합도</h3>
<p>결합도란 다른 모듈에 대해 얼마나 많은 지식을 가지고 있는지를 나타낸다.
한 모듈이 변경될 때 외부의 다른 모듈이 변경된다면 결합도가 높은 것이다. 
내부를 변경했을 때 외부 모듈에 영향을 끼치는 것 또한 결합도가 높다고 할 수 있다. 반면, 내부를 변경할 때는 외부에 영향을 끼치지 않고, 퍼블릭 인터페이스를 바꿔야지만 다른 모듈에 영향을 끼치는 경우를 결합도가 높다고 한다.  </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오브젝트 1~3 정리]]></title>
            <link>https://velog.io/@sang-eun/%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-13-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@sang-eun/%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-13-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 23 Feb 2020 10:27:52 GMT</pubDate>
            <description><![CDATA[<h1 id="1-객체-설계">1. 객체, 설계</h1>
<h2 id="객체지향의-목적">객체지향의 목적</h2>
<ul>
<li>책임을 분산시킨다.</li>
<li>응집도를 높이고 결합도를 낮춘다.</li>
<li>결합도를 낮추는 방법으로 캡슐화, 책임분산, 데이터와 프로세스의 통합이 있다.</li>
</ul>
<h3 id="결합도">결합도</h3>
<p>객체 사이의 의존성이 과한 경우 결합도(coupling)이 높다고 말한다. 
의존성이 있을 경우, 어떤 객체가 변경될 때 그 객체에게 의존하는 다른 객체도 함께 변경될 수 있다는 사실이 내포되어 있다. </p>
<h3 id="캡슐화">캡슐화</h3>
<p>결합도를 낮추는 방법으로(객체의 자율성을 높이는 방식으로) <code>캡슐화</code>가 있다. 객체 내부에 세부적인 사항을 감추는 것을 캡슐화라고 한다. 즉, 외부에 존재하는 프로세스를 내부로 감추는 것이다. 간단한 예시로 티켓을 판매하는 프로세스를 들 수 있다. Theather에서 필드로 가지는 TicketSeller를 통해 티켓을 꺼내고, Audience의 돈을 꺼낼 수도 있다. 하지만 이러한 일련의 과정을 TicketSeller의 sellTo 메서드에 넣어서 캡슐화를 할 수 있다. 이러면 Theather은 TicketSeller의 sellTo 메서드만 호출하면 되지, Audience가 무슨 함수를 가지고 있는지, TicketSeller은 어떤 방식으로 Ticket을 판매하는지 몰라도 된다.
이를 Theather은 오직 TicketSeller의 <code>인터페이스</code>에만 의존한다고 한다. 이처럼 객체를 <code>인터페이스</code>와 <code>구현(implementation)</code>으로 나누고 인터페이스만을 공개하는 것은 객체 사이의 결합도를 낮춘다.</p>
<h3 id="데이터와-프로세스">데이터와 프로세스</h3>
<p>데이터: 객체 안의 필드
프로세스: 데이터를 다루는 행위</p>
<p>예를 들어서 티켓을 사는 것은 프로세스고, 티켓은 데이터이다. 티켓 구매 프로세스를 객체 바깥에서 한다면, 이는 책임을 다른 객체에게 넘기는 것이고 결합도가 높아진다.</p>
<h1 id="2-객체지향-프로그래밍">2. 객체지향 프로그래밍</h1>
<h2 id="도메인">도메인</h2>
<p>도메인이란, 문제를 해결하기 위해 사용자가 프로그램을 사용하는 분야를 뜻한다. 예를 들어 영화를 쉽고 빠르게 예매하려는 문제가 있다. 이를 위해 영화 예매 분야(도메인)을 이용할 수 있다.</p>
<p>도메인의 구조를 정하고, 이와 유사하게 클래스의 구조를 정해야 한다. 그 다음 설계 과정을 거친 뒤 코드를 짜기 시작한다.</p>
<h2 id="필드와-메서드">필드와 메서드</h2>
<p>필드는 private으로, 메서드는 public으로 두어야 한다. 그를 통해 외부에서는 객체의 속성에 직접 접근할 수 없도록 막고, 적절한 public 메서드를 통해서만 내부 상태를 변경할 수 있게 해야 한다.
이처럼 클래스의 내부와 외부를 구분해야 객체의 자율성이 보장된다. 즉, 캡슐화를 넘어서 접근 제어를 통해 <code>내부(구현)</code>과 <code>외부(인터페이스)</code>를 구분해야 객체의 자율성을 지킬 수 있다. 이를 <code>구현 은닉</code>이라고도 한다.</p>
<h2 id="다형성">다형성</h2>
<p>객체들 사이의 상호작용을 <code>협력</code>이라고 한다. 객체지향에서의 협력은 객체들 사이의 <code>요청</code>과 <code>응답</code>으로 이루어진다. 요청의 방법은 <code>메시지</code>를 보내는 것 뿐이다. 도착한 메시지를 처리하는 방법을 <code>메서드</code>라고 한다. 즉, 객체에게 <code>인터페이스</code>를 통해 메시지를 보내면, 객체 내부에서는 메서드를 선택해서 처리한다. 여기서 어떤 메서드로 처리할지 컴파일 시점이 아니라 실행 시점에 결정하는 것을 <code>동적 바인딩</code>이라고 한다. 이와 같이 메시지와 메서드가 구분되어 있을 때, <code>다형성</code>이 성립한다.  (다형성은 동적 바인딩을 통해 구현된다.)</p>
<h2 id="의존성">의존성</h2>
<p>어떤 클래스가 다른 클래스에 접근할 수 있는 경로를 가지거나, 해당 클래스의 객체의 메서드를 호출할 경우 두 클래스 사이에 의존성이 존재한다고 말한다.
코드의 의존성과 실행 시점의 의존성은 다를 수 있다. DiscountPolicy라는 추상 클래스가 존재하고, 이 클래스를 상속받는 PercentDiscountPolicy가 있다. 코드 상에서 DiscountPolicy에게 의존할 수 있지만, 실행 시점에는 PercentDiscountPolicy에 의존할 수 있다. 이처럼 코드의 의존성과 실행 시점의 의존성이 다를 경우 확장성은 높아지지만, 코드를 이해하기는 어려워진다.</p>
<p>어떻게 이처럼 시점에 따라 의존성이 다를 수 있을까? 오직 calculateDiscountAmount라는 메시지를 받을 수만 있다면 객체가 어떤 클래스의 인스턴스인지는 상관하지 않기 때문이다. 이렇게 인터페이스에 의존하는 방식을 <code>업캐스팅</code>이라고 한다.</p>
<h2 id="상속과-합성">상속과 합성</h2>
<h3 id="상속">상속</h3>
<p>상속은 코드를 재사용할 수 있다는 장점을 가진다. 하지만 단점이 있다.</p>
<ul>
<li>캡슐화를 위반한다.</li>
<li>설계를 유연하지 못하게 한다.</li>
</ul>
<p>캡슐화를 위반하는 이유는, 상속을 위해서 부모 클래스의 내부 구조를 잘 알고있어야 하기 때문이다. 즉, 부모 클래스의 구현이 자식 클래스에게 노출되기 때문에 캡슐화가 약화된다. 캡슐화가 약화되면 부모 클래스가 변경될 때, 자식 클래스도 변경될 가능성이 높아진다.</p>
<p>설계를 유연하지 못하게 하는 이유는, 컴파일 시점에 어떤 객체가 사용될지 결정되기 때문이다. 따라서 실행 시점에 객체의 종류를 변경하는 것이 불가능하다.</p>
<h3 id="합성">합성</h3>
<p>합성은 객체 간에 인터페이스를 통해 정의된 메시지를 통해서만 통신하는 것을 뜻한다. 실제적인 구현은 객체 내부에 담겨지므로 캡슐화를 이룰 수 있고, 인터페이스에만 의존하니 실행 시점에 객체를 변경할 수 있어 설계가 유연해진다.</p>
<h1 id="3-역할-책임-협력">3. 역할, 책임, 협력</h1>
<h2 id="협력">협력</h2>
<p>객체들이 애플리케이션의 기능을 구현하기 위해 수행하는 상호작용을 <code>협력</code>이라고 한다. 협력의 유일한 방법은 메시지 전송 뿐이다. 메시지를 수신하면 메서드를 실행해 요청에 응답한다.</p>
<p>협력은 객체의 행동을 결정하고, 행동은 객체의 상태를 결정한다. 예를 들어서 영화 예매라는 협력을 위해 Movie는 요금을 계산하는 행동을 한다. 이 행동을 위해 Movie는 기본 요금인 fee와 할인 정책인 discountPolicy라는 상태를 가진다. 
즉, 협력은 객체의 행동과 상태를 결정하는데 필요한 <code>문맥</code>을 제공한다.</p>
<h2 id="책임">책임</h2>
<p>협력에 참여하기 위해 객체가 수행하는 행동을 <code>책임</code>이라고 한다. 책임은 객체가 유지해야하는 정보와 수행할 수 있는 행동에 대해 개략적으로 서술한 문장이다. 책임은 메시지보다 개념적으로 크고 추상적이다. 객체에게 얼마나 적절한 책임을 할당하느냐가 설계의 전체적인 품질을 결정한다.</p>
<h3 id="정보-전문가-패턴">정보 전문가 패턴</h3>
<p>책임을 객체에게 나누기 위한 하나의 방법이다. 협력이라는 문맥을 정의하고, 그를 하나의 책임으로 본다. 그 다음 더 작은 책임과 책임을 맡을 수 있는 적절한 정보 전문가를 찾아내가는 방식을 말한다.
이렇게 책임을 찾아나가면서, 인터페이스와 오퍼레이션의 목록을 구할 수 있다. 이러한 책임에 초점을 맞춘 설계 방식을 책임 주도 설계라고 한다.</p>
<p>책임을 할당할 때는 두 가지 요소를 고려해야 한다.</p>
<ul>
<li>메시지가 객체를 결정하게 한다.<ul>
<li>최소한의 인터페이스만 가지게 된다.</li>
<li>어떻게가 아니라 무슨 메시지를 처리할지 고려하게 되므로 추상적인 인터페이스를 가질 수 있게 된다.</li>
</ul>
</li>
<li>행동이 상태를 결정한다.<ul>
<li>객체의 상태를 고민하고 행동을 결정하면, 상태가 외부에 노출되게 되어 캡슐화를 낮춘다.</li>
</ul>
</li>
</ul>
<h3 id="의문점">의문점</h3>
<p>정보 전문가 패턴은 객체의 상태(정보)를 고려하고, 책임에 맞는 객체를 선택하는 방법이다. 그렇다면 상태가 객체를 결정하지 메시지가 객체를 결정하는 방법이 아니지 않나?</p>
<h2 id="역할">역할</h2>
<p>객체가 어떤 특정한 협력 안에서 수행하는 책임의 집합을 <code>역할</code>이라고 한다. 책임을 통해 객체를 결정할 때, 하나의 책임을 여러 객체들이 수행할 수 있을 경우 이는 역할이 된다. 역할을 구현하는 가장 일반적인 방법은 인터페이스 또는 추상 클래스이다. 이 둘은 책임의 집합을 서술해 놓은 것인데, 추상 클래스는 그 일부를 구현해 둔 것이고 인터페이스는 책임의 집합만을 나열해 둔 것이다.</p>
<p>여러 시나리오를 고려해보고, 협력을 지속적으로 정제해 보면 그 협력들이 거의 유사한 구조를 보이게 된다. 그때 협력들을 합치면서 두 객체를 역할로 포괄할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[시스템 설계]]></title>
            <link>https://velog.io/@sang-eun/%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%84%A4%EA%B3%84</link>
            <guid>https://velog.io/@sang-eun/%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%84%A4%EA%B3%84</guid>
            <pubDate>Wed, 19 Feb 2020 06:12:48 GMT</pubDate>
            <description><![CDATA[<p>시스템 설계는 대용량 서비스를 빠르게 제공하기 위해 도입된다. 현재 우리 서비스와 같은 경우에는 하루에 1000명 정도의 사용자를 예측하고 있으므로 큰 필요성이 없지만</p>
<ul>
<li>예상 사용자를 늘릴 경우</li>
<li>좀더 빠른 서비스 제공을 목표로 할 경우</li>
</ul>
<p>이렇게 두 가지의 경우를 추구한다면 생각해 볼 필요가 있다.</p>
<h2 id="시스템-설계도">시스템 설계도</h2>
<p><img src="https://images.velog.io/images/sang-eun/post/02333346-fb03-4297-82e0-4ed3b49ec4c4/image.png" alt=""></p>
<h3 id="reverse-proxy">reverse proxy</h3>
<ul>
<li>로드밸런싱</li>
<li>ssl termination</li>
<li>ip blocking</li>
<li>logging</li>
</ul>
<p>이를 위해 nginx, apache 등을 많이 사용한다.
하지만 이러한 기능들 중 로깅, ssl과 같은 부분은 톰캣에서 사용할 수 있을 것이라 결론이 나왔다.</p>
<h3 id="was">WAS</h3>
<p>실제 비즈니스 로직이 들어가는 부분이다. 여러 개의 WAS로 이루어질 수 있다.</p>
<h3 id="queue">Queue</h3>
<p>비동기 방식에 주로 사용된다. 응답을 기다리지 않고 바로 리턴을 하는 방식이다. 큐 뒤에 다수의 Worker를 둬서, 대용량 처리에 유리하다. 아래와 같은 방식들로 요청이 들어오면 비동기적으로 다른 business component들(은행, 다른 서비스들 등..) 에게 알린다. </p>
<p>만약 payment측에서 결제 승인 웹훅을 merchant로부터 받는 방식이었다면, 웹훅이 많아질 때를 고려해 queue에 넣는 방식을 생각할 수 있다. 하지만 지금은 payment에서 웹훅을 merchant로 보내는 방식이므로, 도입한다면 merchant에 Queue를 도입하게 된다. 하지만 이 프로젝트는 payment가 메인이므로 우선순위를 낮추었다.<br><img src="https://images.velog.io/images/sang-eun/post/8dac843a-7997-46c5-b89c-f5c0388796bd/image.png" alt=""></p>
<h3 id="data-grid">Data grid</h3>
<p>session과 같은 공유 정보와 캐시 영역으로 사용된다.</p>
<h3 id="dbms">DBMS</h3>
<p>Primary Secondary 계층으로 여러 개의 db들을 둘 수 있다.
CRUD는 Primary DB에서 수행하고 Primary DB의 데이타를 Staging DB로 고속 복사한후 Staging DB에서 N개의 Secondary DB로 데이타를 복사한다. Read는 Secondary DB에서 수행할 수 있다. 대부분의 서비스들은 read 요청이 많으므로 성능 향상을 낼 수 있다.</p>
<p>샤딩, 파티셔닝과 같은 솔루션도 고려해볼 수 있다.</p>
<h3 id="object-store">Object Store</h3>
<p>S3와 같이 이미지를 저장해 둘 때 사용하는 저장소이다. </p>
<p>하지만 우리 서비스와 같은 경우에는 이미지를 처리할 일이 없으므로 크게 고려하지 않았다.</p>
<h3 id="cdn">CDN</h3>
<p>자바스크립트 파일과 css, 이미지같은 잘 변화되지 않는 파일들은 불필요하게 서버에서 받을 필요가 없다. 그보다는 사용자에게 가까운 곳에 위치한 캐시 서버에서 전달을 받는 편이 빠르다. </p>
<p>CDN은 우리 프로젝트에서 충분히 도입할 수 있다고 생각했기에, 후에 더 알아볼 예정이다.</p>
<p>참고: <a href="https://bcho.tistory.com/661">https://bcho.tistory.com/661</a>
<a href="https://www.slideshare.net/Byungwook/3-34910563">https://www.slideshare.net/Byungwook/3-34910563</a>
<a href="https://cdn.hosting.kr/cdn%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94/">https://cdn.hosting.kr/cdn%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[spring의 특징]]></title>
            <link>https://velog.io/@sang-eun/spring%EC%9D%98-%ED%8A%B9%EC%A7%95</link>
            <guid>https://velog.io/@sang-eun/spring%EC%9D%98-%ED%8A%B9%EC%A7%95</guid>
            <pubDate>Mon, 10 Feb 2020 13:23:38 GMT</pubDate>
            <description><![CDATA[<h2 id="spring의-장점">Spring의 장점</h2>
<ul>
<li>유연성<ul>
<li>aop, di를 통해 기능을 조립하는 것이 가능하다.</li>
<li>psa</li>
</ul>
</li>
<li>실용적인 javaEE 사용과 빠른 스펙의 반영</li>
<li>pojo기반의 개발을 많이 하여 테스트에 용이하다.</li>
<li>어노테이션을 사용하여 편리한 개발이 가능</li>
</ul>
<h2 id="aop">AOP</h2>
<p>AOP(Aspect Oriented Programming)는 관점 지향 프로그래밍이다. 코드에서 반복되어 사용하는 부분을 부분적으로 나누어서 모듈화하는 것을 말한다. 
간단히 말하면 코드에 흩어져 있는 횡단 관심사들을 aspect로 모듈화 한 것이다. </p>
<h3 id="예-로깅을-하는-aspect">예) 로깅을 하는 aspect</h3>
<pre><code class="language-java">package com.example.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAspect {
    Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Around(&quot;execution(* com.example.aop.*.*(..))&quot;)
    public Object logging(ProceedingJoinPoint pjp) throws Throwable {
        logger.info(&quot;start - &quot; + pjp.getSignature().getDeclaringTypeName() + &quot; / &quot; + pjp.getSignature().getName());
        Object result = pjp.proceed();
        logger.info(&quot;finished - &quot; + pjp.getSignature().getDeclaringTypeName() + &quot; / &quot; + pjp.getSignature().getName());

        return result;
    }
}</code></pre>
<p>실제로 실행해 보았을 때, Aspect를 적용할 컴포넌트가 존재하지 않을 경우 에러가 발생한다.</p>
<p>@Aspect만으로는 빈으로 등록되지 않으므로 빈으로 등록하기 위한 Component가 필요하다.</p>
<h3 id="관련된-어노테이션">관련된 어노테이션</h3>
<p>@EnableAspectJAutoProxy: @Aspect를 적용한 컴포넌트들을 사용할 수 있도록 설정하는 역할
@Aspect: aspect로 정의하여 AspectJAutoProxy가 사용할 수 있도록 한다.
@Around: 메소드 실행 전후 공통 로직을 적용할 때
@Before: 메소드 실행 전 공통 로직을 적용할 때
@After: 메소드 실행 후 공통 로직을 적용할 때
@Component: bean을 생성하는 역할</p>
<h3 id="excution">excution</h3>
<p>Aop가 적용될 위치를 정할 때 사용하는 pointCut의 일종이다. Advice(무엇을 할 지 정의한 부분, 여기서는 로깅)를 적용할 메서드를 등록할 때 많이 쓰인다.
표현식은 이와 같다.</p>
<pre><code>execution([수식어] 리턴타입 [클래스이름].이름(파라미터)</code></pre><p>수식어 : public, private 등 수식어를 명시합니다. (생략 가능)
리턴타입 : 리턴 타입을 명시합니다.
클래스이름 및 이름 : 클래스이름과 메서드 이름을 명시합니다. (클래스 이름은 풀 패키지명으로 명시해야합니다. 생략도 가능)
파라미터 : 메서드의 파라미터를 명시합니다.
&quot; * &quot; : 모든 값을 표현합니다.
&quot; .. &quot; : 0개 이상을 의미합니다.</p>
<h3 id="내부-작동방식">내부 작동방식</h3>
<p>Dynamic proxy로 동작한다. 
dynamic proxy가 프록시 패턴인지 데코레이터 패턴인지에 대해서는 생각해볼 가치가 있는데, 데코레이터 패턴에 가깝다고 볼 수 있다.</p>
<p><a href="http://toby.epril.com/?p=841">http://toby.epril.com/?p=841</a></p>
<p>출처: <a href="https://engkimbs.tistory.com/746">https://engkimbs.tistory.com/746</a> [새로비]
<a href="https://jeong-pro.tistory.com/171">https://jeong-pro.tistory.com/171</a>
<a href="https://icarus8050.tistory.com/8">https://icarus8050.tistory.com/8</a></p>
<h2 id="psa">PSA</h2>
<p>PSA란 
<code>환경의 변화와 관계없이 일관된 방식의 기술로의 접근 환경을 제공하려는 추상화 구조</code> 를 뜻한다. </p>
<p>Java EJB가 환경에 너무 의존적이기 때문에 조금만 변화하여도 코드를 변경해야 했고, 테스트도 어려운 단점이 있었다. 따라서 이와 반대되는 POJO라는 명칭을 사용하게 되었고,  </p>
<h2 id="di">DI</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[[코드스피츠] 객체지향1]]></title>
            <link>https://velog.io/@sang-eun/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%94%BC%EC%B8%A0-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A51</link>
            <guid>https://velog.io/@sang-eun/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%94%BC%EC%B8%A0-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A51</guid>
            <pubDate>Sun, 02 Feb 2020 14:38:47 GMT</pubDate>
            <description><![CDATA[<h3 id="함수지향-vs-객체지향">함수지향 vs 객체지향</h3>
<h4 id="함수지향">함수지향</h4>
<ul>
<li>끝없는 복사본</li>
<li>상태 변화에 안전: 계속 복사하니 기존의 값은 안전함. 3 + 1을 한다면 새로 연산된 4는 불변성을 통해서 안전하지만, 예전의 3의 문제가 해결되는 것도 아니고 3과 1은 그대로 존재한다. 안전하게 상태를 보관했다고 보기는 어려움.</li>
<li>연산을 기반으로 로직을 전개 </li>
</ul>
<h3 id="객체지향">객체지향</h3>
<ul>
<li>하나의 원본: 값이 mutable함</li>
<li>상태 변화를 내부에서 책임짐: 이게 매우 어려운 점</li>
<li>메세지를 기반으로 로직을 전개</li>
</ul>
<h3 id="polymophism다형성">polymophism(다형성)</h3>
<p>다형성이 갖춰지면 객체지향 언어라고 할 수 있다.</p>
<p>대체가능성(substitution): 확장된 객체는 원본으로 대체 가능
내적일관성(internal identy): 어때한 경우에도 태어났을 때의 원본 클래스를 유지하려고하는 속성(생성 시점의 타입이 내부에 일관성 있게 참조됨)</p>
<h4 id="자바스크립트에서-내적일관성-구현방식">자바스크립트에서 내적일관성 구현방식</h4>
<h5 id="프로토타입-체인">프로토타입 체인</h5>
<p>worker hardworker class(function)
__ proto__ --&gt;  hardworker prototype (constructor(함수의 프로토타입이므로 가지게 됨, 자기 자신을 가리키고 있음), __ proto__(객체이므로 얘도 가짐), 클래스의 메소드들)</p>
<p>즉, </p>
<pre><code>class HardWorker extends Worker
const worker = new HardWorker();</code></pre><p>에서 worker은 __ proto__를 가지는데, 이는 자신의 원본인 hardworker의 프로토타입을 가리킨다. hardworker의 프로토타입 또한 객체이므로 __ proto__를 가지고, 함수(function)의 프로토타입이므로 constructor을 가진다. 이는 자기 자신을 가리키고 있다. HardWorker은 Worker을 상속받았으므로, __ proto__는 Worker의 프로토타입을 가리킨다. </p>
<p>따라서 프로토타입 체이닝이란, 해당 객체의 __ proto__를 확인해서 원본의 프로토타입을 확인하고, 그 원본의 __ proto__를 확인하는 방식을 반복하며 진행된다. 이를 통해 constructor로 직접 원본을 확인하거나, 원본이 가진 메서드를 확인해 대체가능성과 내적일관성을 구현할 수 있다.</p>
<h5 id="구현방법">구현방법</h5>
<p>먼저 그 객체의 메서드들에서 존재하는지 확인하고, 그 다음 __ proto__를 통해 부모를 확인하고 계속해서 위로 올라가며 메서드가 존재하는지 확인한다. 따라서 부모와 자식이 같은 함수를 가지고 있을 경우, 자식의 메서드가 호출되는 것이다.</p>
<h4 id="자바스크립트에서-대체가능성-구현방식">자바스크립트에서 대체가능성 구현방식</h4>
<p><code>A instanceof B</code> 일 경우, 객체 A의 __ proto__를 확인하면, 원본의 constructor을 알 수 있으므로, B의 constructor와 이가 같은지 확인한다. 같지 않을 경우에는 프로토타입 체이닝을 통해 부모의 constructor을 확인한다.</p>
<h3 id="객체지향에-맞는-객체">객체지향에 맞는 객체</h3>
<h4 id="요건">요건</h4>
<ul>
<li>은닉: 모든 데이터는 private이어야 한다. 상태를 외부에 보여주지 않으려면 private이 필수이다. 이렇게 되면 객체가 값으로 사용되는 일이 많아지게 되고, 객체지향이 아니게 된다. </li>
<li>캡슐화: 은닉이 변수에 대한 것이라면, 캡슐화는 메서드에 대한 것이다.(구체적인 메서드가 아니라 추상적인 메서드를 만들어야 한다.) setter와 getter로 private변수를 사용하면 제대로 된 캠슐화가 이뤄지지 않은 것이다. 
ex) setAge를 피하는 방법
age필드를 그대로 노출 -&gt; setAge를 왜 하는 것인가? -&gt; 어디에 왜 쓰는지 생각해보아야 한다. -&gt; 나이에 따라서 컨텐츠를 구분할려고 하는 것이다 -&gt; setAdult, setChild로 추상화해야 외부에서 내 상태를 관리하지 않고 내부에서 내 상태를 관리할 수 있다.</li>
</ul>
<h4 id="이유">이유</h4>
<p>변화에 대한 격리를 위해</p>
<h3 id="solid원칙">SOLID원칙</h3>
<ul>
<li>SPR: 단일 책임 원칙(이 코드를 고쳐야 하는 이유는 하나뿐인 것, 이를 지키지 못하면 shotgun surgery(산탄총 수술)이 일어난다.)</li>
<li>OCP: 개방 폐쇄 원칙(extends나 implements를 하게 만들고, 기존에 있는 것들은 수정하지 않도록 만드는 것)</li>
<li>리스코프 치환 원칙: 추상층의 정의가 너무 구체적이면 구상층의 구현에서 모순이 발생함. 업캐스팅이 안전해야 하는데 추상클래스 구현이 너무 구체적이면 구현이 안되는 경우를 막아야 함</li>
<li>ISP(Interface Segergation): 인터페이스 분리 (한 객체가 너무 비대해졌을 경우 소유를 사용하거나 위임을 사용하여 분리할 수 있다. 소유 방식은 사용처에 따라 객체를 하나씩 생성, 위임방식은 인터페이스를 구현한 메서드들을 오버라이드하기 때문에 인터페이스를 건드린다고 메서드에 영향이 가지 않는다.) ??????? 에바</li>
<li>DIP: 의존성 역전 법칙: 다운캐스팅금지(의존성은 부모쪽으로만 흘러가야 함, 만약 instanceof C일때.. 이런 코드가 들어가있으면 다운캐스팅을 하고 있는 것, 즉 자식쪽에 의존하고 있는 것이므로 코드를 잘못 짜고 있는 것이다.)</li>
</ul>
<p>고차원의 모듈은 저차원의 모듈에 의존하면 안된다. 이 두 모듈 모두 추상화된 것에 의존해야 한다.????
DI: 의존성 주입
IOC: 제어 역전
DRY(Don&#39;t Repeat Yourself): 중복 방지
Hollywood Principle: 의존성 부패방지(부모클래스는 서브클래스에 정의된 연산에 대한 호출을 할 수 있지만 그 반대방향은 일어나면 안 된다. 이렇게 어떤 대상에게 질의를 하게 되면 은닉, 캡슐화를 잊게 된다)
Law of demeter: 어떠한 객체에 대해 최소한의 지식만 알아야 함, 의존성의 부패를 막기 위해 </p>
<ul>
<li>최소한의 지식
classA.methodA의 경우<ul>
<li>classA의 필드 객체</li>
<li>methodA가 생성한 객체</li>
<li>methodA의 인자로 넘어온 객체</li>
</ul>
</li>
</ul>
<h3 id="메세지">메세지</h3>
<h4 id="srp">SRP</h4>
<p>단일 책임 원칙을 준수하는 객체에게 그 이상의 업무를 부여하면</p>
<ul>
<li>만능 객체가 되려 한다</li>
<li>다른 객체한테 의뢰한다.</li>
</ul>
<p>다른 객체에게 의뢰하는 것 = 다른 객체에게 메세지를 보내는 것</p>
<ul>
<li>메세지: 의뢰할 내용</li>
<li>오퍼레이션: 메세지를 수신할 객체가 제공하는 서비스</li>
<li>메소드: 오퍼레이션이 연결될 실제 처리기
오퍼레이션이 호출되면 그때에 따라 다른 메소드가 호출되는 것을 동적 바인딩이라고 한다.</li>
</ul>
<p>오퍼레이션과 메소드를 분리해서 상황에 따라 원하는 메소드를 호출하기 위해 추상클래스나 인터페이스를 상속시킨다.(OCP)</p>
<h3 id="의존성">의존성</h3>
<p>의존성이 있으면 의존되는 관계에 있는 객체들의 영향을 그대로 받는다. =&gt; 격리성을 높여야
너무 의존성이 없으면 만능 객체가 태어나게 됨. 너무 의존성이 크면 한 객체가 수정되거나 추가되면 다른 객체들이 전부 영향을 가지게 된다. 따라서 적당한 의존성을 가져야 한다.</p>
<h4 id="의존성-만드는-방법">의존성 만드는 방법</h4>
<p>객체의 생명 주기 전체에 걸친 의존성</p>
<ul>
<li>상속: 매우 강력해서 부모 객체가 바뀌면 수정될 것을 각오해야 한다.</li>
<li><blockquote>
<p>연관: 필드에 객체를 저장해놓는 것.(소유) </p>
</blockquote>
</li>
</ul>
<p>각 오퍼레이션 실행 시 임시적인 의존성
-&gt; 의존: 오퍼레이션 실행 시에만 연결이 되고, 메서드 호출이 되면 의존성이 생기고 호출이 끝나면 의존성이 사라지는 약한 의존성을 가진다.</p>
<p>연관에서 의존으로 바꾸기 위해서는 상태를 저장해놓는 방식을 포기해야 한다. 그러면 함수형 아니냐, 따라서 쉽게 바꾸지 못함</p>
<h4 id="높은-의존성-단점">높은 의존성 단점</h4>
<ul>
<li>수정 여파 규모증가</li>
<li>수정하기 어려운 구조 생성</li>
<li>순환 의존성</li>
</ul>
<h3 id="의존성-역전">의존성 역전</h3>
<p>어떠한 경우에도 다운캐스팅은 금지하고 다형성 사용하는 것. DIP와 OCP는 깊은 연관을 가지고 있다. 부모쪽에 의존성을 가지면, 새로운 자식이 추가되어도 기존의 코드는 수정되지 않아 OCP가 이뤄진다고 볼 수 있기 때문이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접] 예상질문]]></title>
            <link>https://velog.io/@sang-eun/%EB%A9%B4%EC%A0%91-%EC%98%88%EC%83%81%EC%A7%88%EB%AC%B8</link>
            <guid>https://velog.io/@sang-eun/%EB%A9%B4%EC%A0%91-%EC%98%88%EC%83%81%EC%A7%88%EB%AC%B8</guid>
            <pubDate>Tue, 14 Jan 2020 10:34:35 GMT</pubDate>
            <description><![CDATA[<h3 id="자기소개-해주세요">자기소개 해주세요</h3>
<h3 id="자신있는-분야가-뭐에요">자신있는 분야가 뭐에요?</h3>
<h3 id="지원동기가-뭐에요">지원동기가 뭐에요?</h3>
<h3 id="가장-도전적이었던-프로젝트-설명해주세요">가장 도전적이었던 프로젝트 설명해주세요</h3>
<h3 id="어떤-부분이-제일-힘들었어요">어떤 부분이 제일 힘들었어요?</h3>
<h3 id="webflux가-뭐에요">webflux가 뭐에요?</h3>
<h3 id="webflux왜-사용했어요">webflux왜 사용했어요?</h3>
<h3 id="mysql왜-사용했어요">mysql왜 사용했어요?</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[Mysql utf8mb4설정]]></title>
            <link>https://velog.io/@sang-eun/Mysql-utf8mb4%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@sang-eun/Mysql-utf8mb4%EC%84%A4%EC%A0%95</guid>
            <pubDate>Wed, 08 Jan 2020 14:35:23 GMT</pubDate>
            <description><![CDATA[<p>우리 프로젝트에서 db에 이모지가 들어가야 한다는 사실을 깨달았고, 이모지가 지원되는 utf8mb4로 이동해야 한다는 것을 발견했다. </p>
<p>기본적인 내용은 아래의 블로그를 따라가면 된다. 하지만 내가 고생했던 부분과 팁을 첨부해 글을 적어 놓으려고 한다. 참고로 mysql 5.6이상만 utf8mb4를 지원한다. 우리는 다행히 5.6.6을 사용하고 있었다. </p>
<p><a href="https://mathiasbynens.be/notes/mysql-utf8mb4">How to support full Unicode in MySQL databases</a></p>
<h2 id="1-amazon-rds-파라미터-설정">1. amazon rds 파라미터 설정</h2>
<p>기존에 디폴트 파라미터 그룹을 사용했다면, 새로운 amazon rds 파라미터 그룹을 생성하여 거기에 설정해 준다.</p>
<p>설정은 각 블로그마다 달랐지만, 기본적으로는 character_set과 collation과 관련 파라미터를 모두 utf8mb4, utf8mb4_unicode_ci로 설정하면 된다.</p>
<p>블로그에 있는 글을 참고하면 </p>
<p><a href="http://jinolog.com/programming/mysql/2011/03/21/character-set-and-collation.html">http://jinolog.com/programming/mysql/2011/03/21/character-set-and-collation.html</a></p>
<blockquote>
<p>문자셋(Character set)은 각 문자가 컴퓨터에 저장될 때 어떠한 &#39;코드&#39;로 저장될지에 대한 규칙의 집합을 의미하며 콜레이션(Collation)은 특정 문자 셋에 의해 데이터베이스에 저장된 값들을 비교 검색하거나 정렬 등의 작업을 위해 문자들을 서로 &#39;비교&#39; 할때 사용하는 규칙들의 집합을 의미한다.</p>
</blockquote>
<p>이라고 한다.</p>
<p>만든 파라미터 그룹을 해당 디비에 적용한 다음 재부팅 반드시 잊지말자! 재부팅을 안할 시 해당 설정이 제대로 안먹는 경우도 발생한다.</p>
<h2 id="2-로컬에서-설정">(2. 로컬에서 설정)</h2>
<p>먼저 아마존의 파라미터 그룹 설정이 잘 적용되었는지 확인한다.</p>
<pre><code>show variables like&#39;char%&#39;</code></pre><p>잘 적용되지 않았을 경우에는 해당 파라미터에 대해 set &#39;Variable_name&#39;=utf8mb4를 이용해 적용한다.</p>
<h2 id="3-기존-db-설정">3. 기존 DB 설정</h2>
<p>만약 디비를 새로 생성하는 것이라면 괜찮지만, 기존 디비에서 설정을 바꿔야 할 경우에는 추가적인 작업이 필요하다. 맨 처음 블로그를 보면 일일히 모든 디비, 칼럼, 테이블을 이렇게 설정하라고 나와 있다. 디비정도는 괜찮지만, 테이블, 칼럼에 대해서는 너무 노가다인게 사실이다.</p>
<h3 id="for-each-database">For each database:</h3>
<p>ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;</p>
<h3 id="for-each-table">For each table:</h3>
<p>ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;</p>
<h3 id="for-each-column">For each column:</h3>
<p>ALTER TABLE table_name CHANGE column_name column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
(Don’t blindly copy-paste this! The exact statement depends on the column type, maximum length, and other properties. The above line is just an example for a <code>VARCHAR</code> column.)</p>
<p>따라서 아래의 쿼리문을 이용하면 테이블의 설정을 간편하게 바꿀 수 있다.</p>
<pre><code>SELECT CONCAT(&#39;ALTER TABLE &#39;, TABLE_NAME, &#39; CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8_unicode_ci;&#39;)
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = &#39;my_database_name&#39; AND TABLE_TYPE != &#39;VIEW&#39;;</code></pre><p>하지만 칼럼에 대해서는 답이 없다. 해당 칼럼마다 특성이 다르기 때문에 일반적인 쿼리문을 작성하기 어렵기 때문이다. 따라서 일일히 위처럼 해준다...</p>
<p>지금까지 적용한 속성들을 다 확인하기 위한 쿼리문이다.</p>
<pre><code>##디비 설정 확인
select * from information_schema.SCHEMATA S;
## 해당 테이블에 대한 칼럼 설정 확인
SELECT character_set_name FROM information_schema.`COLUMNS` WHERE table_name = &#39;posts&#39;;
## 모든 테이블에 대한 칼럼 설정 확인
    SHOW VARIABLES WHERE Variable_name LIKE &#39;character\_set\_%&#39; OR Variable_name LIKE &#39;collation%&#39;;</code></pre><h2 id="참고">참고</h2>
<p>하지만 datagrip에서 이모지가 들어간 row를 넣으려고 하면 ?로 변환된다.. mysql의 설정이 안먹어서 그런 줄 알았는데 그냥 datagrip이 utf8mb4를 지원하지 않는 것 같아 별도의 datagrip gui설정이 필요한 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[코드스피츠] ES6+ 기초편 2]]></title>
            <link>https://velog.io/@sang-eun/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%94%BC%EC%B8%A0-ES6-%EA%B8%B0%EC%B4%88%ED%8E%B8-2</link>
            <guid>https://velog.io/@sang-eun/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%94%BC%EC%B8%A0-ES6-%EA%B8%B0%EC%B4%88%ED%8E%B8-2</guid>
            <pubDate>Tue, 07 Jan 2020 03:47:39 GMT</pubDate>
            <description><![CDATA[<h1 id="흐름에-따른-레코드의-종류">흐름에 따른 레코드의 종류</h1>
<p>식은 하나의 값으로, 일반 문은 실행 단위(레코드)로 등록되고 flow를 따른다.</p>
<p>flow control를 할 수 있는 문들을 이용하면, 레코드를 선택하거나 레코드를 순환할 수 있게 된다. 이런 문들을 completion record로 바뀐다.</p>
<h1 id="직접-flow-control">직접 flow control</h1>
<h3 id="label">label</h3>
<p>문이 아니라 record에 달아주는 태그같은 것이므로 자체로는 문, 레코드가 될 수 없고 별다른 문이 없으면 에러가 난다. 
레이블의 이름은 같은 스코프에 두개 등장할 수 없고 이는 컴파일 타임에 에러가 잡힌다.</p>
<h4 id="스코프">스코프</h4>
<p>스코프의 종류: 블록 스코프, 함수 스코프</p>
<p>label 스코프를 만들 수 있다. a:{}는 중문과는 또 다르다. 
같은 함수 스코프 내에는 똑같은 이름의 레이블을 선언할 수 없다. 하지만 레이블 스코프 내에는 같은 이름의 레이블을 또 만들 수 있다.</p>
<h4 id="스코프-범위">스코프 범위</h4>
<p>일반적으로 레이블 스코프가 지정되지 않을 경우 다른 lablel이 등장하기 전 까지
auto label일 경우 레이블 스코프가 자동적으로 지정된다. iteration, switch위에 label을 작성하게 되면 그 문이 끝날 때까지로 레이블이 자동적으로 한정된다.</p>
<p>특정한 경우, label안에서는 그걸 빠져나오기 위한 flow control이 가능해지고(위로 이동하는 것은 불가능), break, 루프의 경우 switch도 가능해진다.</p>
<ul>
<li>label 스코프를 선언한다.</li>
<li>iteration label이 된다.</li>
<li>switch label이 된다.</li>
</ul>
<h4 id="for문에서-어떻게-break를-사용할-수-있는가">for문에서 어떻게 break를 사용할 수 있는가?</h4>
<p>보통 label문에서는 break 뒤에 label이름을 적는데, for문 위에 auto label이 생성되고, break를 쓰면 뒤에 자동으로 break &quot;auto label name&quot;이 되어 작동한다.</p>
<h1 id="switch">switch</h1>
<h3 id="구성요소">구성요소</h3>
<p>switch + (식) + {}
하지만 if문이나 for문 뒤의 중괄호는 단문이 나와도 되어서 생략될 수 있었던 반면, switch문의 중괄호는 생략되면 안된다. 
이유: switch문 중괄호는 special label block을 만들어주는 역할을 하기 때문이다. 이를 통해 컴파일 타임에 해석되는 정적인 레이블을 만드는 것이 아니라, 동적으로 해석할 수 있는 케이스 레이블을 사용할 수 있다.</p>
<h3 id="case-label-평가방식">case label 평가방식</h3>
<p>자바에서는 switch문이 나오면 케이스와 문에 대한 맵을 생성하여서 default문을 앞에 두어도 해당되는 케이스만 수행된다. -&gt; case label에 식이 들어가면 안 된다.
반면 자바스크립트는 case label에 식이 들어가도 런타임으로 평가가 가능하다. </p>
<h3 id="평가방식">평가방식</h3>
<p>값에 대한 평가, 값을 true를 통해 무력화시키고 case를 통해 평가(책임 연쇄 패턴) </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[코드스피츠] ES6+ 기초편 1]]></title>
            <link>https://velog.io/@sang-eun/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%94%BC%EC%B8%A0-ES6-%EA%B8%B0%EC%B4%88%ED%8E%B8</link>
            <guid>https://velog.io/@sang-eun/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%94%BC%EC%B8%A0-ES6-%EA%B8%B0%EC%B4%88%ED%8E%B8</guid>
            <pubDate>Sun, 05 Jan 2020 10:50:48 GMT</pubDate>
            <description><![CDATA[<h1 id="프로그램이란">프로그램이란?</h1>
<h3 id="컴파일-프로그램">컴파일 프로그램</h3>
<p>컴파일 언어 프로그램의 생명주기는 Language Code(Lint Time) -&gt; Machine Language(Compile Time) -&gt; File -&gt; Load -&gt; Run(Run time) -&gt; Terminate 이다. Load되어 컴퓨터에 올라간 것을 프로그램이라고 한다.</p>
<h3 id="스크립트-프로그램">스크립트 프로그램</h3>
<p>스크립트 언어 프로그램의 생명주기는 Language Code -&gt; File -&gt; Load -&gt; Machine Language -&gt; Run -&gt; Terminate 이다. 일반 프로그램과는 달리 컴파일이 되지 않고 로드된 후에 컴파일을 하고 실행된다.
자바스크립트도 스크립트 언어이기 때문에 코드를 브라우저에 로딩하고 로드가 끝난 다음에 컴파일을 하고 실행한다.</p>
<h1 id="런타임">런타임?</h1>
<h3 id="메모리">메모리</h3>
<p>코드는 명령부분과 데이터부분으로 나눠져서 메모리에 적재된다.</p>
<h3 id="cpu">CPU</h3>
<p>CPU는 4가지로 구성된다.</p>
<ul>
<li>외부 입출력 인터페이스(캐시 레이어, 외부 버스): 메모리로부터 명령을 전달받고, 캐싱하거나 자신의 CPU에 맞는 명령으로 해석한다. </li>
<li>제어유닛: 디코딩을 한다. 추상적인 명령을 CPU가 알 수 있는 명령으로 디코딩한다.</li>
<li>연산유닛: 제어유닛과 데이터유닛에서 명령과 값을 받아와 연산한다.</li>
<li>데이터유닛: 메모리의 데이터부분을 받아와서 연산유닛에 넘긴다.</li>
</ul>
<p>그래서 런타임이란?
Load (메모리에 적재)
-&gt; Run</p>
<ul>
<li>instruction fetch(외부 버스에서 자신의 CPU가 이해할 수 있도록 명령을 바꿔준다.) &amp; decoding (제어유닛에서 연산유닛이 알 수 있도록 디코딩)</li>
<li>Execution: 연산 유닛의 결과를 데이터유닛에 전달하고, 이것은 메모리에 전달된다.</li>
</ul>
<h1 id="load-run은-어떻게-진행">Load-&gt;Run은 어떻게 진행?</h1>
<h3 id="컴파일-프로그램-1">컴파일 프로그램</h3>
<p>컴파일러는 어떻게 메모리에 적재되지 않아서(로드가 되지 않음) 물리적인 메모리를 갖고있지도 않은 상태에서 코드를 검증하지? </p>
<ul>
<li>컴파일러가 language code를 해석할 때 가상 메모리 상에서 테스트를 해본 것이다. 코드가 검증되면 V테이블을 이용해 가상 메모리를 진짜 메모리와 매핑한다.</li>
</ul>
<p>essential definition loading (프로그램 실행에 반드시 필요한 것들을 컴파일할 때 메모리에 적재)
-&gt; v table mapping (로딩하고 실행하기 전에 가상 메모리와 진짜 메모리를 매핑)
-&gt; run 
-&gt; runtime definition loading
-&gt; run</p>
<p>이처럼 컴파일 시점에서 확정되는게 아니라 런타임에서 정의되기도 한다.</p>
<h3 id="스크립트-프로그램-1">스크립트 프로그램</h3>
<ol>
<li>기본이 되는 함수들이나 클래스가 정의된다.</li>
<li>런타임에서도 위를 이용해 커스텀 함수들이나 클래스가 정의된다.</li>
</ol>
<p>따라서 스태틱과 런타임이란 상대적인 것이다. 1번이 정의되어야만 2번이 정의될 수 있으므로 2번에게 1번은 static이 된다. </p>
<h1 id="프로그램이-작동하는-방식">프로그램이 작동하는 방식</h1>
<h3 id="참조의-참조를-왜-쓰는가">참조의 참조를 왜 쓰는가?</h3>
<p>메모리, 주소, 포인터, 변수, 디스패치(주소로부터 값을 얻는 행위)가 존재한다.</p>
<p>A의 메모리 참조를 가지고 있는 B를 직접참조한 C가 있다. 여기서 B가 다른 메모리를 참조하더라도, C는 계속해서 자신은 B를 가지고 있다고 생각하고, 여기서 에러가 발생한다. 이처럼 참조를 복사하면 큰 문제가 일어난다. </p>
<p>함수형 프로그래밍에서는 참조를 사용하지 말도록 한다. 객체지향 프로그래밍에서는 직접참조하지 않도록 더블 디스패치로 해결한다. </p>
<h1 id="자바스크립트의-특성">자바스크립트의 특성</h1>
<h3 id="자바스크립트를-구성하는-텍스트-요소">자바스크립트를 구성하는 텍스트 요소</h3>
<ul>
<li>control character: 제어문자</li>
<li>white space: 공백문자</li>
<li>line terminators: 개행문자</li>
<li>comments: 주석</li>
<li>keyword: 예약어(변수나 식별자로 사용할 수 없음)</li>
<li>literal: 더 이상 나눌 수 없는 객체나 값의 표현</li>
</ul>
<h3 id="자바스크립트-언어를-구성하는-요소">자바스크립트 언어를 구성하는 요소</h3>
<ul>
<li>statememt: 문<ul>
<li>처리될때 처리를 위한 힌트로 사용하고 결과는 메모리에 남지 않는 것</li>
<li>종류: 공문(&quot; ;&quot;), 식문, 제어문, 선언문(메모리 상에 변수를 할당하는 일. 주소, 타입, 크기를 v테이블에 기록해놓는다.)</li>
<li>종류: 단문, 중문({}) ex) if의 구성요소는 if+(식)+문이어서 단문일 경우도 중문으로 묶지 않아도 실행된다.</li>
</ul>
</li>
<li>expression: 식<ul>
<li>값식, 연산식, 호출식(함수 호출을 하면 값이 나옴) </li>
<li>결과로 값이 나온다.</li>
<li>식을 문으로 인정한다.</li>
</ul>
</li>
<li>identifier: 식별자<ul>
<li>기본형, 참조형</li>
</ul>
</li>
</ul>
<h3 id="흐름이란">흐름이란?</h3>
<p>명령이 순서대로 실행되는 과정을 흐름이라고 한다. 원래 메모리에 적재되는 명령어를 수행하는 동안 간섭하지 못한다. 하지만 제어문을 이용해 flow control을 할 수 있다. 함수나 클래스를 이용해 sub flow도 만들 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[C++ 알고리즘] map]]></title>
            <link>https://velog.io/@sang-eun/C-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-map</link>
            <guid>https://velog.io/@sang-eun/C-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-map</guid>
            <pubDate>Sun, 05 Jan 2020 05:44:11 GMT</pubDate>
            <description><![CDATA[<h3 id="include">include</h3>
<p><code>#include &lt;map&gt;</code></p>
<h3 id="유용한-방식">유용한 방식</h3>
<h4 id="넣고-빼기">넣고 빼기</h4>
<pre><code>map&lt;int, int&gt; m;
m[4] = 4;
m.insert({4,4});
cout &lt;&lt; m[4] &lt;&lt; endl;</code></pre><p>하지만 <code>m[4]</code>와 같은 식으로 접근할 경우 원소가 없으면 0을 리턴에 원소가 실제로 존재하지 않는지 확실히 알 수 없다. 따라서 m.find(4)와 같이 접근해야 원소가 있는지 없는지 확실히 알 수 있다.</p>
<pre><code>if (m.find(5) == m.end())</code></pre><p>find는 원소가 없을 시 마지막 원소를 리턴한다.</p>
<h4 id="삭제">삭제</h4>
<pre><code>//m : [{4,4}]
m.erase(4);
//m : []</code></pre><h4 id="순회">순회</h4>
<p>map에는 pair을 넣기에 pair와 똑같은 방식으로 값에 접근한다.</p>
<pre><code>for (map&lt;int, int&gt;::iterator i = m.begin(); i != m.end(); i++)
    {
        cout &lt;&lt; i-&gt;first &lt;&lt; i-&gt;second;
    }</code></pre><p>auto를 사용하면 포인터 참조를 하지 않아도 된다.</p>
<pre><code>for (auto i = m.begin(); i != m.end(); i++)
    {
        cout &lt;&lt; i.first &lt;&lt; i.second;
    }</code></pre>]]></description>
        </item>
    </channel>
</rss>