<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발개굴 </title>
    <link>https://j-su2.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 17 Apr 2026 08:23:34 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>개발개굴 </managingEditor>
    <image>
      <title>개발개굴 </title>
      <url>https://tistory1.daumcdn.net/tistory/5320611/attach/1d66379c18fe4bab8fbe0eae2761be5d</url>
      <link>https://j-su2.tistory.com</link>
    </image>
    <item>
      <title>[JPA] 영속성 컨텍스트</title>
      <link>https://j-su2.tistory.com/141</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;JPA(Java Persistence API)를 이해하는 데 있어 가장 중요한 개념은 영속성 컨텍스트(Persistence Context)입니다. 영속성 컨텍스트는 엔티티의 생명주기를 관리하고 데이터베이스 접근을 최적화하는 핵심적인 역할을 수행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 영속성 컨텍스트를 통해 JPA의 내부 동작을 이해하기 위해 작성되었습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 엔티티 매니저 팩토리와 엔티티 매니저&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JPA 애플리케이션은 데이터베이스와의 연결을 관리하고 엔티티를 조작하기 위해 엔티티 매니저 팩토리와 엔티티 매니저를 사용합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;782&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IvD2D/btsPhGjocmV/tx0EcKaFbp1JFFhlEPvbkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IvD2D/btsPhGjocmV/tx0EcKaFbp1JFFhlEPvbkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IvD2D/btsPhGjocmV/tx0EcKaFbp1JFFhlEPvbkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIvD2D%2FbtsPhGjocmV%2Ftx0EcKaFbp1JFFhlEPvbkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;681&quot; height=&quot;424&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;782&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1752401807403&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 엔티티 매니저 생성 (영속성 컨텍스트 생성)
EntityManager em = emf.createEntityManager();

// 트랜잭션 시작
EntityTransaction transaction = em.getTransaction();
transaction.begin();

// ...엔티티 조작...

// 트랜잭션 커밋
transaction.commit();&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;EntityManagerFactory&lt;/b&gt;는&amp;nbsp;애플리케이션 실행 시점에 단 하나만 생성되는 객체&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;데이터베이스 연결 정보, JPA 설정 등을 바탕으로 &lt;b&gt;EntityManagerFactory&lt;/b&gt;에 의해 &lt;b&gt;EntityManager&lt;/b&gt;가 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;b&gt;EntityManager&lt;/b&gt;는 실제 엔티티를 저장/조회/수정/삭제 하는데 사용되며, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;i&gt;&lt;b&gt;영속성 컨텍스트에 접근하는 통로 역할&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; &lt;br /&gt;(&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;내부적으로 데이터베이스 커넥션을 사용하여 데이터베이스에 접근)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 영속성 컨텍스트와 엔티티의 생명 주기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;엔티티를 영구적으로 저장하는 환경&lt;/b&gt;이라는 논리적인 개념으로, EntityManager가 생성될 때 함께 생성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영속성 컨텍스트 내에서 4가지 상태를 가지는 엔티티를 관리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1246&quot; data-origin-height=&quot;842&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baGQkJ/btsPgVPaVMh/aVfbzccLA6slR1RZlkNU50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baGQkJ/btsPgVPaVMh/aVfbzccLA6slR1RZlkNU50/img.png&quot; data-alt=&quot;엔티티의 생명주기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baGQkJ/btsPgVPaVMh/aVfbzccLA6slR1RZlkNU50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaGQkJ%2FbtsPgVPaVMh%2FaVfbzccLA6slR1RZlkNU50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;629&quot; height=&quot;425&quot; data-origin-width=&quot;1246&quot; data-origin-height=&quot;842&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;엔티티의 생명주기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.1. 비영속 (New/Transient)&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1752401268635&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 객체를 생성
Member member = new Member();&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;영속성 컨텍스트와 전혀 관계가 없는 새로운 상태&lt;/li&gt;
&lt;li&gt;객체를 생성했지만 아직 EntityManager에 저장되지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.2. 영속 (Managed)&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1752401658500&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 객체를 영속화
em.persist(member);&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;영속성 컨텍스트에 관리되는 상태&lt;/li&gt;
&lt;li&gt;persist()를 통해 영속 상태로 전환되거나, 데이터베이스에서 조회되어 영속성 컨텍스트에 로드&lt;/li&gt;
&lt;li&gt;영속 상태의 엔티티는 1차 캐시에 저장되며, &lt;b&gt;Dirty Checking(&lt;/b&gt;&lt;b&gt;변경 감지)&lt;/b&gt;의 대상&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;** Spring Data JPA의 save() 메서드는 새로운 엔티티라면 내부적으로 em.persist()를 호출&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.3. 준영속 (Detached)&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1752401751846&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 영속성 컨텍스트에서 분리
em.detach(member);&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;영속성 컨텍스트에 저장되었다가 분리된 상태&lt;/li&gt;
&lt;li&gt;detach()를 호출하거나, 트랜잭션이 종료되면 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.4. 삭제 (Removed)&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1752401760254&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 삭제 상태로 전환
em.remove(member);&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;영속성 컨텍스트에서 삭제된 상태&lt;/li&gt;
&lt;li&gt;remove()를 호출하여 삭제 상태로 전환&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 영속성 컨텍스트의 이점&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3.1. 1차 캐시&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영속성 컨텍스트 내부에 존재하는 캐시 공간&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;580&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzp573/btsPg7BM1ZU/iNSKwU2ObcDtIkLp1vE76K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzp573/btsPg7BM1ZU/iNSKwU2ObcDtIkLp1vE76K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzp573/btsPg7BM1ZU/iNSKwU2ObcDtIkLp1vE76K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbzp573%2FbtsPg7BM1ZU%2FiNSKwU2ObcDtIkLp1vE76K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;747&quot; height=&quot;357&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;580&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1752403631659&quot; class=&quot;reasonml&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;// 1차 캐시에 저장됨
em.persist(member);

// 1차 캐시에서 조회
Member findMember = em.find(Member.class, &quot;member1&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;persist()를 통해 영속성 컨텍스트에 저장된 객체를 다시 조회하면 DB가 아닌 컨텍스트에서 조회&lt;/li&gt;
&lt;li&gt;만약, 1차 캐시에 없다면 DB에서 조회 후 1차 캐시에 저장 (이때, 바로 영속 상태가 됨)&lt;/li&gt;
&lt;li&gt;동일한 트랜잭션 내에서 엔티티의 동일성을 보장하며, 반복적인 읽기 작업의 성능 향상&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3.2. Dirty Checking(&lt;b&gt;변경 감지)&lt;/b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1340&quot; data-origin-height=&quot;802&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHHzqO/btsPgTjtIwC/ua0RyeBvjMp5khwubvmkak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHHzqO/btsPgTjtIwC/ua0RyeBvjMp5khwubvmkak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHHzqO/btsPgTjtIwC/ua0RyeBvjMp5khwubvmkak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHHzqO%2FbtsPgTjtIwC%2Fua0RyeBvjMp5khwubvmkak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;743&quot; height=&quot;445&quot; data-origin-width=&quot;1340&quot; data-origin-height=&quot;802&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1752404194106&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 영속 엔티티 조회
Member memberA = em.find(Member.class, &quot;memberA&quot;);

// 영속 엔티티 데이터 수정
memberA.setUsername(&quot;hi&quot;);
memberA.setAge(10);

// 자동으로 UPDATE 쿼리를 실행합니다.&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1차 캐시 안의 영속 상태 엔티티와 스탭샷을 비교하여 변경을 감지하여, JPA가 자동으로 변경된 내용을 감지하여 데이터베이스에 반영&lt;/li&gt;
&lt;li&gt;JPA는 flush()를 통해 transaction.commit() 호출 시점에 변경 감지, 쓰기 지연 SQL 저장소에 등록, 저장소의 쿼리를 데이터베이스에 전송하게 되는데, 이러한&amp;nbsp;&lt;b&gt;트랜잭션을 지원하는 쓰기 지연 (Transcation Wirte-Behind)&lt;/b&gt;을 통해 모든 쿼리들을 데이터베이스에 한 번에 전송하는 배치 처리로 성능 향상과 데이터 정합성을 유지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3.2.1. @Transactional(readOnly = true)와 Dirty Checking&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@Transactional(readOnly = true)는 단순히 읽기 전용 설정이나, Master/Slave 데이터베이스 환경에서 읽기 전용 DB로의 읽기 작업 분산 처리 외에도, JPA의 영속성 컨텍스트 동작에 관여하여 성능을 최적화하는 역할을 합니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1752404738119&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Transactional(readOnly = true)
public void updateMember(Member member) {
    member.setName(&quot;Changed Name&quot;);
    // 트랜잭션 커밋 시점에도 UPDATE 쿼리 발생 X
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;트랜잭션에 readOnly를 true로 적용하면, JPA는 해당 트랜잭션이 &lt;b&gt;읽기 전용임을 인지하고&amp;nbsp;&lt;/b&gt;&lt;b&gt;Dirty Checking를 수행하지 않음&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;스냅샷 저장 생략&lt;/b&gt;과 &lt;b&gt;변경 감지 로직 건너뛰기&lt;/b&gt;를 통해 불필요한 스냅샷 비교 및 메모리 사용을 줄여 성능을 향상&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[참고]&lt;br /&gt;&lt;a href=&quot;https://www.inflearn.com/course/ORM-JPA-Basic&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.inflearn.com/course/ORM-JPA-Basic&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1752406305352&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;자바 ORM 표준 JPA 프로그래밍 - 기본편 강의 | 김영한 - 인프런&quot; data-og-description=&quot;김영한 | JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., 실무에서도&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/ORM-JPA-Basic&quot; data-og-url=&quot;https://www.inflearn.com/course/ORM-JPA-Basic&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/DY0hL/hyZjimHxVB/1xm0wCVXxPJH1iyg7Qvqm1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/bvxjeJ/hyZjrKP8lC/zTC59I8qhCd0F4VatJ1Gnk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/blXxBw/hyZjgCpV2j/EzOCH7XHXW3pcDFcI2broK/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/ORM-JPA-Basic&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/ORM-JPA-Basic&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/DY0hL/hyZjimHxVB/1xm0wCVXxPJH1iyg7Qvqm1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/bvxjeJ/hyZjrKP8lC/zTC59I8qhCd0F4VatJ1Gnk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/blXxBw/hyZjgCpV2j/EzOCH7XHXW3pcDFcI2broK/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;자바 ORM 표준 JPA 프로그래밍 - 기본편 강의 | 김영한 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;김영한 | JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., 실무에서도&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JPA</category>
      <category>1차 캐시</category>
      <category>Dirty Checking</category>
      <category>JPA</category>
      <category>더티 체킹</category>
      <category>영속성 컨텍스트</category>
      <author>개발개굴 </author>
      <guid isPermaLink="true">https://j-su2.tistory.com/141</guid>
      <comments>https://j-su2.tistory.com/141#entry141comment</comments>
      <pubDate>Sun, 13 Jul 2025 20:33:05 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] 비동기 환경에서 ThreadLocal 관리</title>
      <link>https://j-su2.tistory.com/140</link>
      <description>&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;해당 포스팅은 비동기로 동작하는 스프링 프로젝트 환경에서 &lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;안전한 Context 전파 전략을 도입하기 위한 &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;ThreadLocal과 InheritableThreadLocal 고찰&lt;/b&gt;&lt;/span&gt;에 대한 내용입니다.&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;1. 문제 배경&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시스템에서 사용자 요청 시 &lt;b&gt;고객 정보를 ThreadLocal에 저장하고, 요청 처리 전체 과정에서 일관되게 유지&lt;/b&gt;하고자 함&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;하지만, &lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;비동기 작업 또는 스레드 풀 환경에서는&amp;nbsp;&lt;/span&gt;&lt;b&gt;ThreadLocal의 한계&lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;로 인해 고객 정보가 전파되지 않거나, 누수/섞임 등의 문제가 발생 가능.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span data-token-index=&quot;0&quot;&gt;2. InheritableThreadLocal 도입 고려 및 문제 분석&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;InheritableThreadLocal&lt;/span&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;/span&gt;&lt;span data-token-index=&quot;2&quot;&gt;은 자식 스레드가 생성될 때 부모 스레드의 값을 자동으로 복사한다는 장점을 가지고 있습니다.&lt;/span&gt;&lt;span data-token-index=&quot;2&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span data-token-index=&quot;0&quot;&gt;2.1. InheritableThreadLocal의 내부 구조&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1748167056660&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class AccountContext {
    public static final InheritableThreadLocal&amp;lt;AccountInfo&amp;gt; accountThreadLocal = new InheritableThreadLocal&amp;lt;&amp;gt;();
}

Thread-Main.inheritableThreadLocals
↳ key: accountThreadLocal &amp;rarr; value: AccountInfo@0x123
Thread-Sub.inheritableThreadLocals
↳ key: accountThreadLocal &amp;rarr; value: AccountInfo@0x123&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;userThreadLocal은 static으로 전역 1개&lt;/li&gt;
&lt;li&gt;각 스레드는 자신의 ThreadLocalMap을 가짐&lt;/li&gt;
&lt;li&gt;ThreadLocalMap의 key는 동일한 userThreadLocal 인스턴스&lt;/li&gt;
&lt;li&gt;이 구조로 인해, 같은 키로 다른 스레드의 값을 구분해서 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span data-token-index=&quot;0&quot;&gt;2.2. 문제점 및 한계&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1) 값은 복사되지만 참조가 공유됨&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;mainThread &amp;rarr; subThread로 전파 시, 값은 복사되지만 &lt;b&gt;같은 객체 참조&lt;/b&gt;를 가짐.&lt;/li&gt;
&lt;li&gt;즉, 자식 스레드에서 객체 내부 값을 변경하면, 부모에게도 영향을 미침.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;ThreadLocalMap
- mainThread : AccountInfo@0x123
- subThread : AccountInfo@0x123
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2) 객체 자체를 새로 생성하면 부모/자식 값이 분리&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자식 스레드에서 new AccountInfo(...)로 새로운 객체를 set하면 부모와는 다른 값으로 분리됨.&lt;/li&gt;
&lt;li&gt;그러나 이를 위해선 개발자가 &lt;b&gt;명시적으로 객체를 새로 생성&lt;/b&gt;해야 하며, 자동 전파의 의미가 퇴색됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3) 메모리 관리 문제&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ThreadLocalMap은 각 스레드마다 존재&lt;/li&gt;
&lt;li&gt;mainThread에서 ThreadLocal.remove() 해도 자식 스레드의 값은 여전히 남아 있음.&lt;/li&gt;
&lt;li&gt;자식 스레드에서 직접 remove하지 않으면 메모리 누수 위험 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4) 스레드 풀 환경에서는 값이 전파되지 않음&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;InheritableThreadLocal은 &lt;b&gt;스레드 생성 시점에만 값 복사&lt;/b&gt;됨.&lt;/li&gt;
&lt;li&gt;스레드 풀은 기존 스레드를 재사용하기 때문에, 새로 생성되지 않으면 값이 전파되지 않음.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반적으로 비동기 동작을 위해서 스레드 풀을 만들어서 사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. InheritableThreadLocal 보완 시도 및 한계&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3.1. 불변 객체 사용&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내부 상태가 바뀌지 않도록 설계
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이미 값이 복사되어 들어 있으면 새로 생성 불가능하도록 처리&lt;/li&gt;
&lt;li&gt;setter 모두 제거, final 필드 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3.2. 전파 시 수동 복사&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자식 스레드 생성 시, 수동으로 복사된 객체를 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3.3. 명시적 remove() 처리&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자식 스레드가 종료되기 전에 ThreadLocal.remove() 호출로 메모리 누수 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 해당 방법들은 결국 라이프 사이클을 직접 관리할 수 없으니, 아래와 같은 한계가 여전히 남아있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자동 전파의 의미가 퇴색됨&lt;/li&gt;
&lt;li&gt;의도치 않은 값의 복사에 대해선 명시적 remove 처리가 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 스레드 풀 사용 환경에서 InheritableThreadLocal 사용 말고 다른 방법을 찾아보았습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 결론: TaskDecorator + 일반 ThreadLocal&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4.1. TaskDecorator를 활용하여 ThreadLocal값을 유지&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반 ThreadLocal 사용&lt;/li&gt;
&lt;li&gt;TaskDecorator를 통해 부모 스레드의 값을 수동으로 복사&lt;/li&gt;
&lt;li&gt;작업 종료 후 finally에서 remove()를 수행하여 GC 유도&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public class AccountContextTaskDecorator implements TaskDecorator {
    @Override
    public Runnable decorate(Runnable runnable) {
        AccountInfo context = AccountContext.get(); // ThreadLocal에서 값 복사
        return () -&amp;gt; {
            try {
                AccountContext.set(context); // 복사한 값 설정
                runnable.run();              // 원래 작업 실행
            } finally {
                AccountContext.clear();      // 누수 방지를 위해 remove()
            }
        };
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4.2. ThreadPool이 해당 TaskDecorator를 사용하도록 등록&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1748168496759&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
public class AsyncConfig {

    @Bean(name = &quot;asyncExecutor&quot;)
    public ThreadPoolTaskExecutor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);                  // 기본 쓰레드 수
        executor.setMaxPoolSize(8);                   // 최대 쓰레드 수
        executor.setQueueCapacity(100);                // 대기 큐 크기
        executor.setThreadNamePrefix(&quot;async-thread-&quot;); // 쓰레드 이름 prefix
        executor.setTaskDecorator(new AccountContextTaskDecorator()); // 커스텀 TaskDecorator 등록
        executor.initialize();
        return executor;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로, 아래와 같이 &lt;b&gt;안전하게 고객 정보를 관리&lt;/b&gt;할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;명확하게 Context 생명주기를 관리&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비동기 환경에서도 사용자 정보를 안전하게 전파 가능&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;GC 누수를 방지&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span data-token-index=&quot;0&quot;&gt;5. 테스트 코드&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;해당 코드는 위와 같은 결과를 도출하기 위해 진행한 테스트 코드입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748167813763&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class AccountContextTest {
    static class AccountInfo {
        private String name;
        public AccountInfo(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    private static final InheritableThreadLocal&amp;lt;AccountInfo&amp;gt; accountThreadLocal = new InheritableThreadLocal&amp;lt;&amp;gt;();
    @DisplayName(&quot;자식이 필드를 변경하면 부모의 필드도 같이 변경됨&quot;)
    @Test
    void testInheritableThreadLocal_change_field_same() throws InterruptedException {
        // mainThread에서 값 셋팅
        AccountInfo accountInfo = new AccountInfo(&quot;main&quot;);
        accountThreadLocal.set(accountInfo);
        System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] main이 설정 =&amp;gt; &quot; + accountThreadLocal.get().getName());
        // subThread에서 필드 값 변경
        Thread sub = new Thread(() -&amp;gt; {
            AccountInfo inherited = accountThreadLocal.get();// 부모로부터 참조 복사됨
            System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] main에서 물려받음 =&amp;gt; &quot; + accountThreadLocal.get().getName());
            inherited.setName(&quot;sub&quot;);
            System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] sub가 변경함 =&amp;gt; &quot; + accountThreadLocal.get().getName());
        });
        sub.start();
        sub.join();// subThread 종료 대기// mainThread에서 다시 값 조회 (자식이 변경한 값 확인)
        System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] main도 변경됨 =&amp;gt; &quot; + accountThreadLocal.get().getName());
        // 결과: 변경되어 있어야 함
        assertThat(accountThreadLocal.get().getName()).isEqualTo(&quot;sub&quot;);
    }
    @DisplayName(&quot;자식이 객체를 변경하면 자식만 변경됨&quot;)
    @Test
    void testInheritableThreadLocal_change_object_diff() throws InterruptedException {
        // mainThread에서 값 셋팅
        AccountInfo accountInfo = new AccountInfo(&quot;main&quot;);
        accountThreadLocal.set(accountInfo);
        System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] main이 설정 =&amp;gt; &quot; + accountThreadLocal.get().getName());
        // subThread에서 객체 변경
        Thread sub = new Thread(() -&amp;gt; {
            System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] main에서 물려받음 =&amp;gt; &quot; + accountThreadLocal.get().getName());
            AccountInfo subAccountInfo = new AccountInfo(&quot;sub&quot;);
            accountThreadLocal.set(subAccountInfo);
            System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] sub에 새로운거 넣음 =&amp;gt; &quot; + accountThreadLocal.get().getName());
        });
        sub.start();
        sub.join();
        // mainThread에서 확인
        System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] main은 그대로 =&amp;gt; &quot; + accountThreadLocal.get().getName());
        // 결과: 변경X
        assertThat(accountThreadLocal.get().getName()).isEqualTo(&quot;main&quot;);
    }
/**
     * accountThreadLocal과 스레드 풀
     *@throwsInterruptedException     */
    @DisplayName(&quot;스레드 전파 후 main스레드 먼저 종료시 ThreadLocal값이 살아있음&quot;)
    @Test
    void testInheritableThreadLocal_main_terminate_sub_alive() throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(1);
        // MainThread에서 설정
        accountThreadLocal.set(new AccountInfo(&quot;main&quot;));
        System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] set name = main&quot;);
        // 비동기 실행 (InheritableThreadLocal은 스레드 생성 시만 복사되므로 주의)
        executor.submit(() -&amp;gt; {
            // 이 쓰레드는 풀에서 재사용되므로 InheritableThreadLocal이 null일 수 있음
            AccountInfo accountInfo = accountThreadLocal.get();
            System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] inherited? &quot; + (accountInfo != null ? accountInfo.getName() : &quot;null&quot;));
            try {
                try {
                    Thread.sleep(3000);// 오래 걸리는 작업
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] 작업 완료, 읽은 값 = &quot; + accountThreadLocal.get().getName());
            } finally {
                // 꼭 정리해줘야 함!
                accountThreadLocal.remove();
                System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] ThreadLocal 정리 완료, 읽은 값 = &quot; + accountThreadLocal.get());
            }
        });
        // main은 바로 응답 (remove)
        System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] 작업 완료, 읽은 값 = &quot; + accountThreadLocal.get().getName());
        accountThreadLocal.remove();
        System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] remove 완료&quot;);
        System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] remove 완료, 읽은 값 = &quot; + accountThreadLocal.get());
        // main 대기
        Thread.sleep(4000);
        executor.shutdown();
    }
    @DisplayName(&quot;스레드 풀에서 꺼내온 스레드는 값이 복사 안됨&quot;)
    @Test
    void testInheritableThreadLocal_pool_no_inherit() throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(1);
        // MainThread에서 설정
        accountThreadLocal.set(new AccountInfo(&quot;main&quot;));
        System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] set name = main&quot;);
        // 2번 실행 -&amp;gt; 1번은 새로 생성, 2번은 꺼내와서 사용
        for(int i=0;i&amp;lt;2;i++) {
            int cnt = i;
            executor.submit(() -&amp;gt; {
                try {
                    AccountInfo accountInfo = accountThreadLocal.get();
                    if (cnt == 0) {
                        System.out.print(&quot;첫번째는 새로 생성됨 =&amp;gt; &quot;);
                    } else {
                        System.out.print(&quot;두번째는 풀에서 꺼내옴 =&amp;gt; &quot;);
                    }
                    System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] inherited? &quot; + (accountInfo != null ? accountInfo.getName() : &quot;null&quot;));
                } finally {
                    accountThreadLocal.remove();
                }
            });
        }
        accountThreadLocal.remove();
        Thread.sleep(1000);
        executor.shutdown();
    }
    @DisplayName(&quot;스레드 풀 사용 시 TaskDecorator로 복사 후 실행, finally에서 remove 확인&quot;)
    @Test
    void testInheritableThreadLocal_sub_finally_remove() throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(1);
        accountThreadLocal.set(new AccountInfo(&quot;main&quot;));
        System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] 셋팅된 값 = &quot; + accountThreadLocal.get().getName());
        Runnable originalTask = () -&amp;gt; {
            try {
                System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] 복사된 값 = &quot; + accountThreadLocal.get().getName());
            } finally {
                // 꼭 remove 해줘야 메모리 누수 방지됨
                accountThreadLocal.remove();
                System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] remove 완료, 읽은 값 = &quot; + accountThreadLocal.get());
            }
        };
		// TaskDecorator처럼 context 전달
        Runnable decoratedTask = () -&amp;gt; {
            AccountInfo parentContext = accountThreadLocal.get();
            accountThreadLocal.set(parentContext);// 상속처럼 복사
            originalTask.run();
        };
		// 실행
        executor.submit(decoratedTask).get();
		// Main context도 정리
        accountThreadLocal.remove();
        System.out.println(&quot;[&quot; + Thread.currentThread().getName() + &quot;] remove 완료, 읽은 값 = &quot; + accountThreadLocal.get());
        assertThat(accountThreadLocal.get()).isNull();
        executor.shutdown();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[참고]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://mangkyu.tistory.com/333&quot;&gt;[Java] 스레드 로컬(ThreadLocal)과 상속 가능한 스레드 로컬( InheritableThreadLocal)에 대하여&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ThreadLocal의 내부 동작 방식은 java.lang 소스코드를 참고하여 분석&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>async</category>
      <category>inheritablethreadlocal</category>
      <category>taskdecorator</category>
      <category>thread</category>
      <category>ThreadLocal</category>
      <category>threadpool</category>
      <category>멀티 스레드</category>
      <category>비동기</category>
      <category>스레드 풀</category>
      <category>스프링</category>
      <author>개발개굴 </author>
      <guid isPermaLink="true">https://j-su2.tistory.com/140</guid>
      <comments>https://j-su2.tistory.com/140#entry140comment</comments>
      <pubDate>Sun, 25 May 2025 19:24:52 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] Feign Client란?</title>
      <link>https://j-su2.tistory.com/139</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 진행하다 Spring 서버에서 외부 API와 통신하는 서버 to 서버 통신을 하게되는 경우가 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 경우에 사용할 수 있는 Feign Client에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Feign Client 란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Feign Client를 한마디로 정리하자면 Netflix에서 개발된 Http Client Binder입니다. Spring Boot 환경에서 다른 서버의 Api를 호출하기 위해 사용하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 단순하기 때문에 비즈니스 로직에 더 집중할 수 있게 도와줍니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HTTP API를 균일하게 바인딩하여 복잡성을 줄임&lt;/li&gt;
&lt;li&gt;RestTemplate방식과 WebClient방식보다 단순&lt;/li&gt;
&lt;li&gt;웹 서비스 클라이언트를 쉽게 작성할 수 있음
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Interface를 작성하고 Annotaion을 선언하면 끝&lt;/li&gt;
&lt;li&gt;Jpa가 실제 쿼리를 작성하지 않고 Interface만 지정하여 쿼리 실행 구현체를 자동으로 만드는것과 유사함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 장점들로 인해 비즈니스 로직에 더 집중할 수 있게 도와줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7; text-align: left;&quot;&gt;OkHttp&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Feign에서 제공하는 Http Client 중 1개
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비동기 / Non-Blocking 사용하기 위해 설정&lt;/li&gt;
&lt;li&gt;기본 설정은 HttpUrlConnection&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Rest Api, Http 통신을 간편하게 구현할 수 있도록 다양한 기능을 제공해주는 라이브러리&lt;/li&gt;
&lt;li&gt;HTTP 요청과 응답을 생성하고 처리하는 기본 기능을 제공
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;헤더, 바디 등의 세부 사항을 수동으로 제어할 수 있음&lt;/li&gt;
&lt;li&gt;요청 및 응답에 대한 세밀한 제어가 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Java와 같은 JVM 기반 시스템에서 동작&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Feign Client 예시 코드&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 Feign Client를 활용해 외부 API를 호출하는 로직을 작성해보겠습니다. 테스트를 위해선 Json 무료 가상 Rest API 서버인 JSONPlaceholder를 사용하겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GET &lt;a href=&quot;https://jsonplaceholder.typicode.com/users/1&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://jsonplaceholder.typicode.com/users/1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;401&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kKWbv/btszKz7tiOX/ckZsOhP5nywryAsNNrcpf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kKWbv/btszKz7tiOX/ckZsOhP5nywryAsNNrcpf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kKWbv/btszKz7tiOX/ckZsOhP5nywryAsNNrcpf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkKWbv%2FbtszKz7tiOX%2FckZsOhP5nywryAsNNrcpf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;504&quot; height=&quot;401&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;401&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://jsonplaceholder.typicode.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://jsonplaceholder.typicode.com/&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698579114977&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;JSONPlaceholder - Free Fake REST API&quot; data-og-description=&quot;{JSON} Placeholder Free fake API for testing and prototyping. Powered by JSON Server + LowDB. Tested with XV. Serving ~2 billion requests each month.&quot; data-og-host=&quot;jsonplaceholder.typicode.com&quot; data-og-source-url=&quot;https://jsonplaceholder.typicode.com/&quot; data-og-url=&quot;https://jsonplaceholder.typicode.com/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://jsonplaceholder.typicode.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jsonplaceholder.typicode.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;JSONPlaceholder - Free Fake REST API&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;{JSON} Placeholder Free fake API for testing and prototyping. Powered by JSON Server + LowDB. Tested with XV. Serving ~2 billion requests each month.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jsonplaceholder.typicode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 build.gradle파일을 통해 Dependency를 설정해야합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;의존성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1698577923808&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ext {
	set('springCloudVersion', &quot;2021.0.5&quot;)
}

dependencies {
	implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
    	implementation 'io.github.openfeign:feign-okhttp'
}

dependencyManagement {
	imports {
		mavenBom &quot;org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}&quot;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;예시 코드&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Client Interface와 FallbackFacory Class를 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FallbackFacory란?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Feign에서 제공하는 기능 중 하나로, 서비스 간 통신 중에 에러가 발생할 때 대체 동작을 정의하기 위해 사용&lt;/li&gt;
&lt;li&gt;예외가 발생하면 해당 인터페이스의 백엔드 구현 대신 FallbackFactory에 정의된 메소드 호출&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1698987677476&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.demofeign.api.test.feign;

import org.springframework.http.MediaType;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.Map;

@FeignClient(name = &quot;testApi&quot;, url = &quot;https://jsonplaceholder.typicode.com&quot;, fallbackFactory = ApiClientFallbackFactory.class)
public interface ApiClient {

    @GetMapping(value = &quot;/users/{userNo}&quot;, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    Map getTestData(@PathVariable String userNo);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1698987851048&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.demofeign.api.test.feign;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;

import java.util.Map;

@Slf4j
@Component
public class ApiClientFallbackFactory implements FallbackFactory&amp;lt;ApiClient&amp;gt; {
    @Override
    public ApiClient create(Throwable cause) {
        return new ApiClient() {
            @Override
            public Map getTestData(String userNo) {
                log.error(&quot;testData Fallback reason was: &quot; + cause.getMessage(), cause);
                return null;
            }
        };
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 ApiClient를 호출하는 TestService를 생성합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1698988034778&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.demofeign.api.test.service;

import com.example.demofeign.api.test.feign.ApiClient;
import com.example.demofeign.api.test.model.response.ApiResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class TestService {

    private final ApiClient apiClient;
    private final ObjectMapper objectMapper;

    public ApiResponse getTestData(String userNo) {
        Map testData = apiClient.getTestData(userNo);
        ApiResponse apiResponse = objectMapper.convertValue(testData, ApiResponse.class);
        log.info(&quot;TestData: {}&quot;, apiResponse);
        return apiResponse;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 TestService를 호출 테스트해볼 TestController를 생성합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1698988065768&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.demofeign.api.test.controller;

import com.example.demofeign.api.test.model.response.ApiResponse;
import com.example.demofeign.api.test.service.TestService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
@RequestMapping(&quot;/api&quot;)
public class TestController {
    private final TestService testService;

    @GetMapping(&quot;/test/{userNo}&quot;)
    public ResponseEntity&amp;lt;ApiResponse&amp;gt; test(@PathVariable String userNo) {
        return ResponseEntity.ok(testService.getTestData(userNo));
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Postman으로 호출결과를 확인하면, 위에 링크와 같이 데이터를 가져온것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dCAqAA/btszH6ZbNEA/GGIWTDl7vcuTXyL5q3J7Dk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dCAqAA/btszH6ZbNEA/GGIWTDl7vcuTXyL5q3J7Dk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dCAqAA/btszH6ZbNEA/GGIWTDl7vcuTXyL5q3J7Dk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdCAqAA%2FbtszH6ZbNEA%2FGGIWTDl7vcuTXyL5q3J7Dk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;822&quot; height=&quot;609&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 예제 소스 링크입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/Jisue/Spring-Boot---Feign-Client&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/Jisue/Spring-Boot---Feign-Client&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698987485253&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - Jisue/Spring-Boot---Feign-Client: Feign Client를 정리해보자&quot; data-og-description=&quot;Feign Client를 정리해보자. Contribute to Jisue/Spring-Boot---Feign-Client development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/Jisue/Spring-Boot---Feign-Client&quot; data-og-url=&quot;https://github.com/Jisue/Spring-Boot---Feign-Client&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/9sRt4/hyUnMGz6Pg/wH45CtCZfovDpAkITvNv51/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/Jisue/Spring-Boot---Feign-Client&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/Jisue/Spring-Boot---Feign-Client&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/9sRt4/hyUnMGz6Pg/wH45CtCZfovDpAkITvNv51/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - Jisue/Spring-Boot---Feign-Client: Feign Client를 정리해보자&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Feign Client를 정리해보자. Contribute to Jisue/Spring-Boot---Feign-Client development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[참고]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://techblog.woowahan.com/2630/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://techblog.woowahan.com/2630/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698577421506&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;우아한 feign 적용기 | 우아한형제들 기술블로그&quot; data-og-description=&quot;{{item.name}} 안녕하세요. 저는 비즈인프라개발팀에서 개발하고 있는 고정섭입니다. 이 글에서는 배달의민족 광고시스템 백엔드에서 feign 을 적용하면서 겪었던 것들에 대해서 공유 하고자 합니다&quot; data-og-host=&quot;techblog.woowahan.com&quot; data-og-source-url=&quot;https://techblog.woowahan.com/2630/&quot; data-og-url=&quot;https://techblog.woowahan.com/2630/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/clbgBY/hyUkdxFBuc/6TBUub4s6R7JWPkhguMsa0/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856,https://scrap.kakaocdn.net/dn/lLEdu/hyUnQnbHKM/dPQ6Yn5g2J41EpStN6MtL0/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856&quot;&gt;&lt;a href=&quot;https://techblog.woowahan.com/2630/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://techblog.woowahan.com/2630/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/clbgBY/hyUkdxFBuc/6TBUub4s6R7JWPkhguMsa0/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856,https://scrap.kakaocdn.net/dn/lLEdu/hyUnQnbHKM/dPQ6Yn5g2J41EpStN6MtL0/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;우아한 feign 적용기 | 우아한형제들 기술블로그&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;{{item.name}} 안녕하세요. 저는 비즈인프라개발팀에서 개발하고 있는 고정섭입니다. 이 글에서는 배달의민족 광고시스템 백엔드에서 feign 을 적용하면서 겪었던 것들에 대해서 공유 하고자 합니다&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;techblog.woowahan.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kdhyo98.tistory.com/33#google_vignette&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kdhyo98.tistory.com/33#google_vignette&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698577425697&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[SPRING] feign은 뭘까?&quot; data-og-description=&quot;  서론 다른 서버와 통신을 하기 위한 API 를 설계 및 개발을 하면서 알게 된 feign에 대해서 정리하기 위해 작성하게 되었다. 그 전까지는 spring에서 다른 서버를 호출해본 적이 없었기 때문에 어&quot; data-og-host=&quot;kdhyo98.tistory.com&quot; data-og-source-url=&quot;https://kdhyo98.tistory.com/33#google_vignette&quot; data-og-url=&quot;https://kdhyo98.tistory.com/33&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/xekHi/hyUkcyKwwa/zNjjxmdaOvDHtaK68FUKy1/img.png?width=800&amp;amp;height=271&amp;amp;face=0_0_800_271,https://scrap.kakaocdn.net/dn/caDv4b/hyUj7EcerX/s15t8eeaXlAmifyYNZuk30/img.png?width=800&amp;amp;height=271&amp;amp;face=0_0_800_271,https://scrap.kakaocdn.net/dn/fo2RZ/hyUnN43GRb/7RgYZAujwlFWurAnOoury0/img.png?width=1582&amp;amp;height=536&amp;amp;face=0_0_1582_536&quot;&gt;&lt;a href=&quot;https://kdhyo98.tistory.com/33#google_vignette&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kdhyo98.tistory.com/33#google_vignette&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/xekHi/hyUkcyKwwa/zNjjxmdaOvDHtaK68FUKy1/img.png?width=800&amp;amp;height=271&amp;amp;face=0_0_800_271,https://scrap.kakaocdn.net/dn/caDv4b/hyUj7EcerX/s15t8eeaXlAmifyYNZuk30/img.png?width=800&amp;amp;height=271&amp;amp;face=0_0_800_271,https://scrap.kakaocdn.net/dn/fo2RZ/hyUnN43GRb/7RgYZAujwlFWurAnOoury0/img.png?width=1582&amp;amp;height=536&amp;amp;face=0_0_1582_536');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[SPRING] feign은 뭘까?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;  서론 다른 서버와 통신을 하기 위한 API 를 설계 및 개발을 하면서 알게 된 feign에 대해서 정리하기 위해 작성하게 되었다. 그 전까지는 spring에서 다른 서버를 호출해본 적이 없었기 때문에 어&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kdhyo98.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>API 연동</category>
      <category>Feign Client</category>
      <category>Http Client</category>
      <category>java</category>
      <category>spring boot</category>
      <author>개발개굴 </author>
      <guid isPermaLink="true">https://j-su2.tistory.com/139</guid>
      <comments>https://j-su2.tistory.com/139#entry139comment</comments>
      <pubDate>Fri, 3 Nov 2023 14:09:28 +0900</pubDate>
    </item>
    <item>
      <title>[네트워크] TCP 연결/해제 과정(3 way handshake &amp;amp; 4 way handshake)</title>
      <link>https://j-su2.tistory.com/138</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;TCP가 데이터를 전송할때, 신뢰성을 보장하기 위한 연결 성립과 연결 해제 과정에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://j-su2.tistory.com/15&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://j-su2.tistory.com/15&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698560446264&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[네트워크] TCP와 UDP&quot; data-og-description=&quot;TCP와 UDP는 전송 계층에서 통신 활성화를 위해 사용되는 프로토콜입니다. TCP : 신뢰성, 연결 지향적 UDP : 비신뢰성, 비연결성, 실시간 프로토콜이란? 통신 규약으로 컴퓨터 내부에서, 또는 컴퓨터 &quot; data-og-host=&quot;j-su2.tistory.com&quot; data-og-source-url=&quot;https://j-su2.tistory.com/15&quot; data-og-url=&quot;https://j-su2.tistory.com/15&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bPNmCX/hyUj6L0RDr/TPSPVnvVKMH7tRQ7hxEeFk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cf5ALP/hyUkbs0mBp/nyNLdQ9hnsTykda5bor1Kk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://j-su2.tistory.com/15&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://j-su2.tistory.com/15&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bPNmCX/hyUj6L0RDr/TPSPVnvVKMH7tRQ7hxEeFk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cf5ALP/hyUkbs0mBp/nyNLdQ9hnsTykda5bor1Kk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[네트워크] TCP와 UDP&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;TCP와 UDP는 전송 계층에서 통신 활성화를 위해 사용되는 프로토콜입니다. TCP : 신뢰성, 연결 지향적 UDP : 비신뢰성, 비연결성, 실시간 프로토콜이란? 통신 규약으로 컴퓨터 내부에서, 또는 컴퓨터&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;j-su2.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3 way handshake&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP는 연결을 위해서 3번의 과정을 진행합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;692&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sT246/btszoiytUpk/xe739GbEFFqgXs4dTmVBf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sT246/btszoiytUpk/xe739GbEFFqgXs4dTmVBf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sT246/btszoiytUpk/xe739GbEFFqgXs4dTmVBf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsT246%2FbtszoiytUpk%2Fxe739GbEFFqgXs4dTmVBf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;888&quot; height=&quot;692&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;692&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클라이언트가 서버에게 SYN 패킷을 보냄 (sequence: X)&lt;/li&gt;
&lt;li&gt;서버가 SYN(X)을 받고, 클라이언트로 받았다는 신호인 ACK와 SYN패킷을 보냄 (sequence: Y / ACK: X+1)&lt;/li&gt;
&lt;li&gt;클라이언트는 서버의 응답인 ACK(X+1)와 SYN(Y) 패킷을 받고, ACK(Y+1)를 서버로 보냄&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;*ACK: Acknowledgment(승인), 요청을 확인했다는 응답&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;*SYN: Synchronize(동시성) Sequence Number, 연결이 이루어지도록 요청하는 의미&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4 way handshake&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP는 모든 통신이 끝난후 연결 해제를 위해 4번의 과정을 진행합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-10-29 오후 3.46.25.png&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cokypl/btszkma22zi/KFFy53gpptkrgp84iMkHX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cokypl/btszkma22zi/KFFy53gpptkrgp84iMkHX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cokypl/btszkma22zi/KFFy53gpptkrgp84iMkHX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcokypl%2Fbtszkma22zi%2FKFFy53gpptkrgp84iMkHX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;844&quot; height=&quot;678&quot; data-filename=&quot;스크린샷 2023-10-29 오후 3.46.25.png&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클라이언트는 서버에게 연결을 종료한다는 FIN 플래그를 보냄&lt;/li&gt;
&lt;li&gt;서버는 FIN을 받고, 확인했다는 ACK를 클라이언트에게 보냄 (이때 모든 데이터를 보내기 위해 CLOSE_WAIT 상태가 됨)&lt;/li&gt;
&lt;li&gt;데이터를 모두 보내고, 서버는 연결이 종료되었다는 FIN 플래그를 클라이언트에게 보냄&lt;/li&gt;
&lt;li&gt;클라이언트는 FIN을 받고, 확인했다는 ACK를 서버에게 보냄(아직 서버로부터 받지 못한 데이터가 있을 수 있어 TIME_WAIT상태)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버는 ACK를 받을 이후 소켓을 닫음 (CLOESED)&lt;/li&gt;
&lt;li&gt;TIME_WAIT 시간이 끝나면 클라이언트도 닫음 (CLOSED)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[참고]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@leeesangheee/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC.-TCP-3-way-Handshake&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@leeesangheee/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC.-TCP-3-way-Handshake&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698562071107&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;네트워크. TCP 3-way Handshake&quot; data-og-description=&quot;TCP 3-way Handshake&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@leeesangheee/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC.-TCP-3-way-Handshake&quot; data-og-url=&quot;https://velog.io/@leeesangheee/네트워크.-TCP-3-way-Handshake&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ZOZmJ/hyUls2hTYL/nYPAq4jjNRQPweDJelqCeK/img.png?width=600&amp;amp;height=330&amp;amp;face=0_0_600_330,https://scrap.kakaocdn.net/dn/ffW5S/hyUnOv4Vku/Roj9AeV2mlI2M3kTpnqx0K/img.png?width=600&amp;amp;height=330&amp;amp;face=0_0_600_330,https://scrap.kakaocdn.net/dn/xwM5K/hyUnRfgr0V/q0aJejxfEZsiYj0ZCAYLYk/img.jpg?width=482&amp;amp;height=512&amp;amp;face=0_0_482_512&quot;&gt;&lt;a href=&quot;https://velog.io/@leeesangheee/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC.-TCP-3-way-Handshake&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@leeesangheee/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC.-TCP-3-way-Handshake&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ZOZmJ/hyUls2hTYL/nYPAq4jjNRQPweDJelqCeK/img.png?width=600&amp;amp;height=330&amp;amp;face=0_0_600_330,https://scrap.kakaocdn.net/dn/ffW5S/hyUnOv4Vku/Roj9AeV2mlI2M3kTpnqx0K/img.png?width=600&amp;amp;height=330&amp;amp;face=0_0_600_330,https://scrap.kakaocdn.net/dn/xwM5K/hyUnRfgr0V/q0aJejxfEZsiYj0ZCAYLYk/img.jpg?width=482&amp;amp;height=512&amp;amp;face=0_0_482_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;네트워크. TCP 3-way Handshake&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;TCP 3-way Handshake&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Network/TCP%203%20way%20handshake%20%26%204%20way%20handshake.md#tcp-3-way-handshake--4-way-handshake&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Network/TCP%203%20way%20handshake%20%26%204%20way%20handshake.md#tcp-3-way-handshake--4-way-handshake&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CS/Network</category>
      <category>3 way handshake</category>
      <category>4 way handshake</category>
      <category>TCP 연결</category>
      <category>TCP 해제</category>
      <category>신뢰성 연결</category>
      <author>개발개굴 </author>
      <guid isPermaLink="true">https://j-su2.tistory.com/138</guid>
      <comments>https://j-su2.tistory.com/138#entry138comment</comments>
      <pubDate>Sun, 29 Oct 2023 15:56:54 +0900</pubDate>
    </item>
    <item>
      <title>[네트워크] OSI 7 계층</title>
      <link>https://j-su2.tistory.com/7</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;OSI 7 계층이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크 통신이 일어나는 과정을 7단계로 나눈 것으로, 국제표준화기구(ISO)에서 네트워트 간의 호환을 위해서 만든 개방형 시스템 상호 연결 모델의 표준인 네트워크 모델&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실제 인터넷에서 사용되는&amp;nbsp;&lt;b&gt;TCP/IP 는 OSI 참조 모델을 기반으로 상업적이고 실무적으로 이용될 수 있도록 단순화&lt;br /&gt;&lt;a href=&quot;https://j-su2.tistory.com/134&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://j-su2.tistory.com/134&lt;/a&gt;&lt;br /&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1698145807525&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[네트워크] TCP/IP 4계층&quot; data-og-description=&quot;TCP/IP(Transmission Control Protocal / Internet Protocal)란? 현재 수많은 프로그램들이 인터넷으로 통신하는데 있어 가장 기반이 되는 프로토콜로 실제 대다수 프로그램은 TCP와 IP로 통신하고 있습니다. 즉, &quot; data-og-host=&quot;j-su2.tistory.com&quot; data-og-source-url=&quot;https://j-su2.tistory.com/134&quot; data-og-url=&quot;https://j-su2.tistory.com/134&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bhtRVB/hyUklgOJ2B/JYcD0gJZ6W3KlZ4EvJKoz1/img.png?width=800&amp;amp;height=536&amp;amp;face=0_0_800_536,https://scrap.kakaocdn.net/dn/WieoJ/hyUgHMBgbh/dAouux72vLR7vMPnOoVetK/img.png?width=800&amp;amp;height=536&amp;amp;face=0_0_800_536,https://scrap.kakaocdn.net/dn/boAwoZ/hyUgQ3PYxY/TXYFNKysFAymyRKgrPQaX1/img.png?width=882&amp;amp;height=592&amp;amp;face=0_0_882_592&quot;&gt;&lt;a href=&quot;https://j-su2.tistory.com/134&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://j-su2.tistory.com/134&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bhtRVB/hyUklgOJ2B/JYcD0gJZ6W3KlZ4EvJKoz1/img.png?width=800&amp;amp;height=536&amp;amp;face=0_0_800_536,https://scrap.kakaocdn.net/dn/WieoJ/hyUgHMBgbh/dAouux72vLR7vMPnOoVetK/img.png?width=800&amp;amp;height=536&amp;amp;face=0_0_800_536,https://scrap.kakaocdn.net/dn/boAwoZ/hyUgQ3PYxY/TXYFNKysFAymyRKgrPQaX1/img.png?width=882&amp;amp;height=592&amp;amp;face=0_0_882_592');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[네트워크] TCP/IP 4계층&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;TCP/IP(Transmission Control Protocal / Internet Protocal)란? 현재 수많은 프로그램들이 인터넷으로 통신하는데 있어 가장 기반이 되는 프로토콜로 실제 대다수 프로그램은 TCP와 IP로 통신하고 있습니다. 즉,&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;j-su2.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물리 &amp;rarr; 데이터 링크 &amp;rarr; 네트워크 &amp;rarr; 전송 &amp;rarr; 세션 &amp;rarr; 표현 &amp;rarr; 응용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;탄생 배경&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크 간의 호환을 위해 탄생한 모델&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;초기 여러 정보 통신 업체 장비들은 자신의 업체 장비들끼리만 연결되어 호환성이 없었음&lt;/li&gt;
&lt;li&gt;따라서 모든 시스템의 상호 연결에 있어 문제가 없도록 표준을 정한것이 OSI 7 계층&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;흐름을 한눈에 알아보기 쉽고, 이해하기 쉬움&lt;/li&gt;
&lt;li&gt;7계층중 특정한 곳에 이상이 생기면 다른 단계의 장비 및 소프트웨어를 건들이지 않고도 이상이 생긴 단계만 고칠 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;작동 원리&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;774&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZb0hU/btsy9MffILk/kdKxiDpW5K9I6S4vOpo6Ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZb0hU/btsy9MffILk/kdKxiDpW5K9I6S4vOpo6Ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZb0hU/btsy9MffILk/kdKxiDpW5K9I6S4vOpo6Ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZb0hU%2Fbtsy9MffILk%2FkdKxiDpW5K9I6S4vOpo6Ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1102&quot; height=&quot;774&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;774&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;송신
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;7계층 -&amp;gt; 1계층 송신(전송)시, 각각의 층마다 인식할 수 있는 헤더를 붙여 캡슐화&lt;/li&gt;
&lt;li&gt;출발지에서 데이터가 전송될 때 헤더가 추가 &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(단, 2계층에서만 오류제어를 위해 꼬리부분에 추가됨&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;물리계층에서 1, 0 의 신호가 되어 전송매체(동축케이블, 광섬유 등)을 통해 전송&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;수신
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1계층 -&amp;gt; 7계층 수신시 헤더를 제거해 디캡슐화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1계층 - 물리계층(Physical Layer)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 전기적, 기계적, 기능적인 특성을 이용해서 통신 케이블로 데이터를 전송하는 역할&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 단위: 0과1의 비트(BIT)&lt;/li&gt;
&lt;li&gt;단지 데이터를 전기적인 신호로 변환해서 전달(데이터가 무엇인지, 어떤 에러가 잇는지 신경쓰지 않음)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;구성 요소&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리피터: 신호를 증폭해 재전송하는 장치&lt;/li&gt;
&lt;li&gt;케이블&lt;/li&gt;
&lt;li&gt;허브: 여러 PC를 브로드캐스트를 위한 연결 장치&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2계층 - 데이터 링크계층(DataLink Layer)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물리 계층을 통해 송신/수신되는 정보의 오류와 흐름을 관리하여 &lt;span style=&quot;color: #009a87;&quot;&gt;*안전한 정보&lt;/span&gt;의 전달을 수행할 수 있도록 도와주는 역할&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 단위: 프레임(Frame)&lt;/li&gt;
&lt;li&gt;Mac 주소를 이용해 통신&lt;/li&gt;
&lt;li&gt;Point-To-Point 전송&lt;/li&gt;
&lt;li&gt;Frame에 MAC 주소를 부여하고 에러검출, 재선송, 흐름 제어&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주소 할당: 물리계층의 신호를 네트워크 상의 장치에 안착할수 있게함&lt;/li&gt;
&lt;li&gt;오류 감지: 오류가 포함되면 해당 데이터를 파기&lt;/li&gt;
&lt;li&gt;순서 제어: 프레임의 순서적 전송&lt;/li&gt;
&lt;li&gt;프레임 동기화: 프레임의 시작과 끝을 구별하기 위한 동기화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87; text-align: start;&quot;&gt;*안전한 정보: 오류나 재전송하는 기능이 존재해 신뢰성 있는 전송을 보장&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;구성 요소&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;브릿지, 스위치: 연결된 포트로만 프레임을 전송&lt;/li&gt;
&lt;li&gt;이더넷: LAN(근거리 통신망) 구축을 위해 장치를 연결하는 네트워킹 프로토콜&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3계층 - 네트워크 계층(Network Layer)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 개의 노드를 거칠 때마다 경로를 찾아주는 역할&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 길이의 데이터를 목적지까지 가장 안전하고 빠르게 전달하는 기능을 담당(최적의 경로를 설정)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 단위: 패킷(Packet/Datagram)&lt;/li&gt;
&lt;li&gt;전송 계층이 요구하는 서비스 품질을 제공하기 위한 기능적, 절차적 수단을 제공&lt;/li&gt;
&lt;li&gt;라우터를 통해 이동할 경로(Route)를 선택하여 주소(IP)를 지정하고, 해당 경로에 따라 패킷을 전달&lt;/li&gt;
&lt;li&gt;라우팅, 흐름 제어, 오류 제어, 세그먼테이션 등을 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;구성 요소&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;라우터 : 경로 설정&lt;/li&gt;
&lt;li&gt;IP : 주소 부여&lt;/li&gt;
&lt;li&gt;L3 스위치&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4계층 - 전송 계층(Transport Layer)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP, UDP 프로토콜을 통해 통신을 활성화해 양 끝단의 사용자들 간의 신뢰성있는 데이터를 주고 받게 해주는 역할&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 단위: 세그먼트(Segment)&lt;/li&gt;
&lt;li&gt;포트를 열어두고, 프로그램들이 전송을 할 수 있도록 제공&lt;/li&gt;
&lt;li&gt;신뢰성 있고 효율적인 데이터 전송
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오류검출 및 복구, 흐름제어와 중복검사 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;데이터 전송을 위해 Port번호 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;구성 요소&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TCP 프로토콜&lt;/li&gt;
&lt;li&gt;UDP 프로토콜&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://j-su2.tistory.com/15&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://j-su2.tistory.com/15&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698243360556&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[네트워크] TCP와 UDP&quot; data-og-description=&quot;TCP와 UDP는 전송 계층에서 통신 활성화를 위해 사용되는 프로토콜입니다. TCP : 신뢰성, 연결 지향적 UDP : 비신뢰성, 비연결성, 실시간 프로토콜이란? 통신 규약으로 컴퓨터 내부에서, 또는 컴퓨터 &quot; data-og-host=&quot;j-su2.tistory.com&quot; data-og-source-url=&quot;https://j-su2.tistory.com/15&quot; data-og-url=&quot;https://j-su2.tistory.com/15&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bp1eyo/hyUkevwPOy/hikg4sjcUkQcQKVGHy4bb0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/j23uh/hyUkkvI780/BgyamNgkmQ4pq1Z5tq9dkk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://j-su2.tistory.com/15&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://j-su2.tistory.com/15&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bp1eyo/hyUkevwPOy/hikg4sjcUkQcQKVGHy4bb0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/j23uh/hyUkkvI780/BgyamNgkmQ4pq1Z5tq9dkk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[네트워크] TCP와 UDP&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;TCP와 UDP는 전송 계층에서 통신 활성화를 위해 사용되는 프로토콜입니다. TCP : 신뢰성, 연결 지향적 UDP : 비신뢰성, 비연결성, 실시간 프로토콜이란? 통신 규약으로 컴퓨터 내부에서, 또는 컴퓨터&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;j-su2.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://j-su2.tistory.com/138&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://j-su2.tistory.com/138&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698562663020&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[네트워크] TCP 연결/해제 과정(3 way handshake &amp;amp; 4 way handshake)&quot; data-og-description=&quot;TCP가 데이터를 전송할때, 신뢰성을 보장하기 위한 연결 성립과 연결 해제 과정에 대해 알아보겠습니다. https://j-su2.tistory.com/15 [네트워크] TCP와 UDP TCP와 UDP는 전송 계층에서 통신 활성화를 위해 &quot; data-og-host=&quot;j-su2.tistory.com&quot; data-og-source-url=&quot;https://j-su2.tistory.com/138&quot; data-og-url=&quot;https://j-su2.tistory.com/138&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bu3UnL/hyUkjkgeAj/97BN6b18pnbCe4gKQyxfPk/img.png?width=800&amp;amp;height=623&amp;amp;face=0_0_800_623,https://scrap.kakaocdn.net/dn/b7yJMB/hyUnXft37p/s6ztZnaSp0cEqKDVeST9Q0/img.png?width=800&amp;amp;height=623&amp;amp;face=0_0_800_623,https://scrap.kakaocdn.net/dn/1qn8s/hyUnSebDRt/aF9E5JnqXBvJsSUqW5tjF1/img.png?width=888&amp;amp;height=692&amp;amp;face=0_0_888_692&quot;&gt;&lt;a href=&quot;https://j-su2.tistory.com/138&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://j-su2.tistory.com/138&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bu3UnL/hyUkjkgeAj/97BN6b18pnbCe4gKQyxfPk/img.png?width=800&amp;amp;height=623&amp;amp;face=0_0_800_623,https://scrap.kakaocdn.net/dn/b7yJMB/hyUnXft37p/s6ztZnaSp0cEqKDVeST9Q0/img.png?width=800&amp;amp;height=623&amp;amp;face=0_0_800_623,https://scrap.kakaocdn.net/dn/1qn8s/hyUnSebDRt/aF9E5JnqXBvJsSUqW5tjF1/img.png?width=888&amp;amp;height=692&amp;amp;face=0_0_888_692');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[네트워크] TCP 연결/해제 과정(3 way handshake &amp;amp; 4 way handshake)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;TCP가 데이터를 전송할때, 신뢰성을 보장하기 위한 연결 성립과 연결 해제 과정에 대해 알아보겠습니다. https://j-su2.tistory.com/15 [네트워크] TCP와 UDP TCP와 UDP는 전송 계층에서 통신 활성화를 위해&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;j-su2.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5계층 - 세션 계층(Session Layer)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;양 끝 단의 응용 프로세스가 통신을 관리하기 위한 방법을 제공하는 역할&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터가 통신하기 위한 논리적 연결을 담당&lt;/li&gt;
&lt;li&gt;TCP/IP 세션을 만들고 없애는 책임을 지니고 있음
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IP 데이터의 배달을 처리, TCP는 패킷을 추적하고 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;구성 요소&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API&lt;/li&gt;
&lt;li&gt;Socket&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6계층 - 표현 계층(Presentation Layer)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 표현에 대한 독립성을 제공하고 암호화하는 역할&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전송 데이터의 표현방식 결정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;코드 간의 번역을 담당하여 사용자 시스템에서 데이터의 형식상 차이를 다루는 부담을 응용 계층으로 부터 덜어줌&lt;/li&gt;
&lt;li&gt;데이터 변환, 압축, 암호화 등&lt;/li&gt;
&lt;li&gt;인코딩이나 암호화 등의 동작이 이루어짐&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;기능 3가지
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;송신자에서 온 데이터를 해석하기 위한 응용계층 데이터 부호화, 변화&lt;/li&gt;
&lt;li&gt;수신자에게 데이터 압축을 풀수 있는 방식으로 데이터 압축&lt;/li&gt;
&lt;li&gt;데이터 암호화/복호화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;구성 요소&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JPEG&lt;/li&gt;
&lt;li&gt;MPEG&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7계층 - 응용 계층(Application Layer)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 목적지로 응용 프로세스와 직접 관계하여 일반적인 응용 서비스를 수행하는 역할&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자와 가장 가까운 계층&lt;/li&gt;
&lt;li&gt;사용자 인터페이스(UI), 전자우편, 데이터베이스 관리 등의 서비스 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;구성 요소&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HTTP 프로토콜&lt;/li&gt;
&lt;li&gt;FTP 프로토콜&lt;/li&gt;
&lt;li&gt;DNS&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[참고]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@cgotjh/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-OSI-7-%EA%B3%84%EC%B8%B5-OSI-7-LAYER-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-%EA%B0%81-%EA%B3%84%EC%B8%B5-%EC%84%A4%EB%AA%85&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@cgotjh/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-OSI-7-%EA%B3%84%EC%B8%B5-OSI-7-LAYER-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-%EA%B0%81-%EA%B3%84%EC%B8%B5-%EC%84%A4%EB%AA%85&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1653820422004&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[네트워크] OSI 7 계층 (OSI 7 LAYER) 기본 개념, 각 계층 설명&quot; data-og-description=&quot;네트워크의 기초 OSI 7 계층&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@cgotjh/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-OSI-7-%EA%B3%84%EC%B8%B5-OSI-7-LAYER-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-%EA%B0%81-%EA%B3%84%EC%B8%B5-%EC%84%A4%EB%AA%85&quot; data-og-url=&quot;https://velog.io/@cgotjh/네트워크-OSI-7-계층-OSI-7-LAYER-기본-개념-각-계층-설명&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/VYEdb/hyOzMxPfXj/gP6waV0IxF6gPD0Iz6M7HK/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/c0IKMc/hyOzNXOqm0/cn1EOGKa1fLBTiK65KheA1/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/EQfNX/hyOzRsnyRV/8wfUWZ9DMM12oSr5zsAa7K/img.jpg?width=721&amp;amp;height=364&amp;amp;face=0_0_721_364&quot;&gt;&lt;a href=&quot;https://velog.io/@cgotjh/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-OSI-7-%EA%B3%84%EC%B8%B5-OSI-7-LAYER-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-%EA%B0%81-%EA%B3%84%EC%B8%B5-%EC%84%A4%EB%AA%85&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@cgotjh/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-OSI-7-%EA%B3%84%EC%B8%B5-OSI-7-LAYER-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-%EA%B0%81-%EA%B3%84%EC%B8%B5-%EC%84%A4%EB%AA%85&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/VYEdb/hyOzMxPfXj/gP6waV0IxF6gPD0Iz6M7HK/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/c0IKMc/hyOzNXOqm0/cn1EOGKa1fLBTiK65KheA1/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/EQfNX/hyOzRsnyRV/8wfUWZ9DMM12oSr5zsAa7K/img.jpg?width=721&amp;amp;height=364&amp;amp;face=0_0_721_364');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[네트워크] OSI 7 계층 (OSI 7 LAYER) 기본 개념, 각 계층 설명&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;네트워크의 기초 OSI 7 계층&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://onecoin-life.com/19&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://onecoin-life.com/19&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1653820426006&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[네트워크] OSI 7Layer / 7계층 개념 및 역할, 구조까지 한번에 알아보기&quot; data-og-description=&quot;목차 OSI 7 계층이란? OSI 7 계층은 네트워크에서 통신이 일어나는 과정을 7단계로 나눈 것을 말하며,&amp;nbsp;국제표준화기구(ISO, International Organization for Standardization)에서 네트워크 간의 호환을 위해 OSI..&quot; data-og-host=&quot;onecoin-life.com&quot; data-og-source-url=&quot;https://onecoin-life.com/19&quot; data-og-url=&quot;https://onecoin-life.com/19&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bktjB7/hyOzUJpMOH/VIv1ElrdIpESxk1L9b3Ye1/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/eMxZ6/hyOzRsnznO/K9pkcjvq2BLeFSEXpJOX5k/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/ciTlMN/hyOzIWvl5x/aKfuCoTFK1iubAl0lL76Bk/img.jpg?width=1920&amp;amp;height=1275&amp;amp;face=0_0_1920_1275&quot;&gt;&lt;a href=&quot;https://onecoin-life.com/19&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://onecoin-life.com/19&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bktjB7/hyOzUJpMOH/VIv1ElrdIpESxk1L9b3Ye1/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/eMxZ6/hyOzRsnznO/K9pkcjvq2BLeFSEXpJOX5k/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/ciTlMN/hyOzIWvl5x/aKfuCoTFK1iubAl0lL76Bk/img.jpg?width=1920&amp;amp;height=1275&amp;amp;face=0_0_1920_1275');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[네트워크] OSI 7Layer / 7계층 개념 및 역할, 구조까지 한번에 알아보기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차 OSI 7 계층이란? OSI 7 계층은 네트워크에서 통신이 일어나는 과정을 7단계로 나눈 것을 말하며,&amp;nbsp;국제표준화기구(ISO, International Organization for Standardization)에서 네트워크 간의 호환을 위해 OSI..&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;onecoin-life.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/WooVictory/Ready-For-Tech-Interview/blob/master/Network/OSI%207%20%EA%B3%84%EC%B8%B5.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/WooVictory/Ready-For-Tech-Interview/blob/master/Network/OSI%207%20%EA%B3%84%EC%B8%B5.md&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1653820436803&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - WooVictory/Ready-For-Tech-Interview:   신입 개발자로서 준비를 하기 위해 지식을 정리하는 공간 &quot; data-og-description=&quot;  신입 개발자로서 준비를 하기 위해 지식을 정리하는 공간  &amp;zwj; . Contribute to WooVictory/Ready-For-Tech-Interview development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/WooVictory/Ready-For-Tech-Interview/blob/master/Network/OSI%207%20%EA%B3%84%EC%B8%B5.md&quot; data-og-url=&quot;https://github.com/WooVictory/Ready-For-Tech-Interview&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cY9eQz/hyOzUvSP8d/PSCQRw0yGk41PeLKcsB4tk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/WooVictory/Ready-For-Tech-Interview/blob/master/Network/OSI%207%20%EA%B3%84%EC%B8%B5.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/WooVictory/Ready-For-Tech-Interview/blob/master/Network/OSI%207%20%EA%B3%84%EC%B8%B5.md&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cY9eQz/hyOzUvSP8d/PSCQRw0yGk41PeLKcsB4tk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - WooVictory/Ready-For-Tech-Interview:   신입 개발자로서 준비를 하기 위해 지식을 정리하는 공간&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;  신입 개발자로서 준비를 하기 위해 지식을 정리하는 공간  &amp;zwj; . Contribute to WooVictory/Ready-For-Tech-Interview development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://shlee0882.tistory.com/110&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://shlee0882.tistory.com/110&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698143950043&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;OSI 7 계층이란?, OSI 7 계층을 나눈 이유&quot; data-og-description=&quot;1. OSI 7 계층이란? OSI 7 계층은 네트워크에서 통신이 일어나는 과정을 7단계로 나눈 것을 말한다. 1.1 OSI 7 계층을 나눈이유는? 계층을 나눈 이유는 통신이 일어나는 과정이 단계별로 파악할 수 있&quot; data-og-host=&quot;shlee0882.tistory.com&quot; data-og-source-url=&quot;https://shlee0882.tistory.com/110&quot; data-og-url=&quot;https://shlee0882.tistory.com/110&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/CtS0W/hyUkmz00uy/1PPIJPnoiKXlrZNM1LkPxk/img.jpg?width=259&amp;amp;height=194&amp;amp;face=0_0_259_194,https://scrap.kakaocdn.net/dn/cxekjQ/hyUgGGUs4J/hRq5GA9zFP1Jr2RVOdc9AK/img.jpg?width=259&amp;amp;height=194&amp;amp;face=0_0_259_194,https://scrap.kakaocdn.net/dn/bWrJHW/hyUki5srA4/93SwC1iTV00NQhU8zvtug0/img.png?width=1837&amp;amp;height=915&amp;amp;face=0_0_1837_915&quot;&gt;&lt;a href=&quot;https://shlee0882.tistory.com/110&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://shlee0882.tistory.com/110&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/CtS0W/hyUkmz00uy/1PPIJPnoiKXlrZNM1LkPxk/img.jpg?width=259&amp;amp;height=194&amp;amp;face=0_0_259_194,https://scrap.kakaocdn.net/dn/cxekjQ/hyUgGGUs4J/hRq5GA9zFP1Jr2RVOdc9AK/img.jpg?width=259&amp;amp;height=194&amp;amp;face=0_0_259_194,https://scrap.kakaocdn.net/dn/bWrJHW/hyUki5srA4/93SwC1iTV00NQhU8zvtug0/img.png?width=1837&amp;amp;height=915&amp;amp;face=0_0_1837_915');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;OSI 7 계층이란?, OSI 7 계층을 나눈 이유&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. OSI 7 계층이란? OSI 7 계층은 네트워크에서 통신이 일어나는 과정을 7단계로 나눈 것을 말한다. 1.1 OSI 7 계층을 나눈이유는? 계층을 나눈 이유는 통신이 일어나는 과정이 단계별로 파악할 수 있&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;shlee0882.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://inpa.tistory.com/entry/WEB-%F0%9F%8C%90-OSI-7%EA%B3%84%EC%B8%B5-%EC%A0%95%EB%A6%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://inpa.tistory.com/entry/WEB-%F0%9F%8C%90-OSI-7%EA%B3%84%EC%B8%B5-%EC%A0%95%EB%A6%AC&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698143953562&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;  OSI 7계층 모델 - 핵심 총정리&quot; data-og-description=&quot;​OSI 7계층 OSI 7계층은 네트워크 통신이 일어나는 과정을 7단계로 나눈 것을 말한다. OSI 7계층을 나눈 이유는? 흐름을 한눈에 알아보기 쉽고 7단계 중 특정한 곳에 이상이 생기면 다른 단계의 장&quot; data-og-host=&quot;inpa.tistory.com&quot; data-og-source-url=&quot;https://inpa.tistory.com/entry/WEB-%F0%9F%8C%90-OSI-7%EA%B3%84%EC%B8%B5-%EC%A0%95%EB%A6%AC&quot; data-og-url=&quot;https://inpa.tistory.com/entry/WEB-%F0%9F%8C%90-OSI-7%EA%B3%84%EC%B8%B5-%EC%A0%95%EB%A6%AC&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dgRZXn/hyUlqB5UgL/2XCV50iM8Pe7nAFLyuMEik/img.png?width=800&amp;amp;height=476&amp;amp;face=0_0_800_476,https://scrap.kakaocdn.net/dn/cQZ6KU/hyUj7pkpFc/UvXxo4QkvO6CyjcmCZNiKk/img.png?width=800&amp;amp;height=476&amp;amp;face=0_0_800_476,https://scrap.kakaocdn.net/dn/VxMPu/hyUgNzhjIM/5X6yxr428XagQSzqKIFS20/img.png?width=1280&amp;amp;height=762&amp;amp;face=0_0_1280_762&quot;&gt;&lt;a href=&quot;https://inpa.tistory.com/entry/WEB-%F0%9F%8C%90-OSI-7%EA%B3%84%EC%B8%B5-%EC%A0%95%EB%A6%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://inpa.tistory.com/entry/WEB-%F0%9F%8C%90-OSI-7%EA%B3%84%EC%B8%B5-%EC%A0%95%EB%A6%AC&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dgRZXn/hyUlqB5UgL/2XCV50iM8Pe7nAFLyuMEik/img.png?width=800&amp;amp;height=476&amp;amp;face=0_0_800_476,https://scrap.kakaocdn.net/dn/cQZ6KU/hyUj7pkpFc/UvXxo4QkvO6CyjcmCZNiKk/img.png?width=800&amp;amp;height=476&amp;amp;face=0_0_800_476,https://scrap.kakaocdn.net/dn/VxMPu/hyUgNzhjIM/5X6yxr428XagQSzqKIFS20/img.png?width=1280&amp;amp;height=762&amp;amp;face=0_0_1280_762');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;  OSI 7계층 모델 - 핵심 총정리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;​OSI 7계층 OSI 7계층은 네트워크 통신이 일어나는 과정을 7단계로 나눈 것을 말한다. OSI 7계층을 나눈 이유는? 흐름을 한눈에 알아보기 쉽고 7단계 중 특정한 곳에 이상이 생기면 다른 단계의 장&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;inpa.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CS/Network</category>
      <author>개발개굴 </author>
      <guid isPermaLink="true">https://j-su2.tistory.com/7</guid>
      <comments>https://j-su2.tistory.com/7#entry7comment</comments>
      <pubDate>Wed, 25 Oct 2023 23:20:00 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] CI/CD란?</title>
      <link>https://j-su2.tistory.com/137</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 새로운 프로젝트에 들어가며, AWS CodePipeline을 활용해 빌드/배포 자동화 환경을 셋팅하게 되었습니다. 이참에 CI/CD 개념을 자세히 정리하고자 해당 글을 작성하게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l615w/btsjlY4rUrw/HWOcy0NnkadLZc0S8r7I21/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l615w/btsjlY4rUrw/HWOcy0NnkadLZc0S8r7I21/img.jpg&quot; data-alt=&quot;[출처: https://velog.io/@whattsup_kim/CI-CD%EB%9E%80]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l615w/btsjlY4rUrw/HWOcy0NnkadLZc0S8r7I21/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl615w%2FbtsjlY4rUrw%2FHWOcy0NnkadLZc0S8r7I21%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;746&quot; height=&quot;373&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[출처: https://velog.io/@whattsup_kim/CI-CD%EB%9E%80]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CI/CD 란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지속적 통합(Continuous Integration, CI)과 지속적 제공&amp;amp;배포(Continuous Delivery&amp;amp;Continuous Deployment, CD)의 약자로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션 개발 단계를 자동화하여 애플리케이션을 더욱 짧은 주기로 고객에게 제공하는 방법입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DevOps 엔지니어의 핵심 업무라고 불리기도 하는 CI/CD는 통합과 제공을 자동화함으로써 소프트웨어 개발팀이 코드 품질과 소프트웨어 보안을 보장하는 동시에 비즈니스 요구사항을 충족하는 데 집중할 수 있게 해줍니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CI/CD의 핵심 개념&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CI/CD는 &lt;span style=&quot;color: #009a87;&quot;&gt;*인터그레이션 헬&lt;/span&gt;을 해결하기 위한 하나의 솔루션으로 핵심 개념을 다음과 같이 세 가지로 구분할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87; text-align: start;&quot;&gt;*인터그레이션 헬(Integration Hell): 개발/운영 조직에서 새로운 코드 통합(merge) 과정에서 발생하는 여러가지 문제들로, 통합을 위한 작업으로 수 시간이 소요되며 롤백을 수행하기도 함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;CI(Continuous Integration) - 지속적인 통합&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 코드 변경 사항이 주기적으로 빌드 및 테스트를 거쳐 공유 리포지토리에 통합(merge)되는 것을 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 프로젝트에 여러명의 개발자가 협업을 하며 개발하는 상황이 있다고 가정해봅시다. 이때, 너무 오랜 주기로 merge를 한다면 충돌 코드가 많아질 수 있고, 또 너무 빈번한 merge를 하자면 귀찮다는 단점이 있습니다. 하지만, 가능한 작은 단위로 나누어 주기적인 통합이 중요하기 때문에 해당 작업을 자동화하여 지속적인 통합을 진행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;장점&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 개발자가 동시에 작업하며 발생할 수 있는 충돌 문제를 수시로 확인하고 해결할 수 있음&lt;/li&gt;
&lt;li&gt;버그를 빠르게 찾아 해결하고, 소프트웨어 품질을 개선 가능&lt;/li&gt;
&lt;li&gt;새로운 업데이트 테스트와 출시 시간을 단축시킴&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;CD(Continuous Delivery &amp;amp; Deployment) - 지속적인 서비스 제공 &amp;amp; &lt;span style=&quot;text-align: start;&quot;&gt;배포&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자의 변경 사항을 리포지토리에서 고객이 사용 가능한 프로덕션 환경까지 자동으로 릴리즈하는 것을 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;장점&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개발자는 배포보다는 개발에 더욱 신경 쓸 수 있도록 도와줌&lt;/li&gt;
&lt;li&gt;개발자가 원클릭으로 수작업 없이 빌드, 테스트, 배포까지의 자동화를 할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CI/CD 파이프라인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새 버전의 소프트웨어를 제공하기 위해 수행해야 할 일련의 단계를 뜻합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/F6nTQ/btsjmvAUyUz/7hbB5CXbIsHYApkaAZLOoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/F6nTQ/btsjmvAUyUz/7hbB5CXbIsHYApkaAZLOoK/img.png&quot; data-alt=&quot;[출처: https://www.redhat.com/ko/topics/devops/what-is-ci-cd]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/F6nTQ/btsjmvAUyUz/7hbB5CXbIsHYApkaAZLOoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FF6nTQ%2FbtsjmvAUyUz%2F7hbB5CXbIsHYApkaAZLOoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1474&quot; height=&quot;342&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[출처: https://www.redhat.com/ko/topics/devops/what-is-ci-cd]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;빌드(Build) : 애플리케이션을 컴파일하는 단계&lt;/li&gt;
&lt;li&gt;테스트(Test): 코드를 테스트하는 단계, 이 단계를 자동화하여 시간과 수고를 줄일 수 있음&lt;/li&gt;
&lt;li&gt;릴리즈(Release): 애플리케이션을 리포지토리에 제공하는 단계&lt;/li&gt;
&lt;li&gt;배포(Delpoy): 코드를 프로덕션에 배포하는 단계&lt;/li&gt;
&lt;li&gt;검증 및 컴플라이언스(Validation &amp;amp; Compliance): 빌드 검증 단계는 해당 조직의 필요에 따라 결정되며, 소프트웨어 품질을 보장할 수 있게 해줌&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;[참고]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;&lt;a href=&quot;https://walkingplow.tistory.com/78&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://walkingplow.tistory.com/78&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686461711836&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;CI/CD의 개념과 차이점&quot; data-og-description=&quot;CI/CD의 개념 CI/CD는 애플리케이션 개발 단계를 자동화해 보다 짧은 주기로 통합 및 배포하는 것을 의미합니다. 인터그레이션 헬(Integration Hell)을 해결하기 위한 솔루션으로 지속적인 통합, 지속적&quot; data-og-host=&quot;walkingplow.tistory.com&quot; data-og-source-url=&quot;https://walkingplow.tistory.com/78&quot; data-og-url=&quot;https://walkingplow.tistory.com/78&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bdyTkB/hySW51ay35/RROatgafHOZKIaO6wvFbT0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/XmcWm/hySW2QUD7F/6xih7fbhuPmtqqecmj5SSK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/C24cF/hySW5z6DU0/Scq9EKOKTAFbAKulnM1Tfk/img.png?width=1222&amp;amp;height=718&amp;amp;face=0_0_1222_718&quot;&gt;&lt;a href=&quot;https://walkingplow.tistory.com/78&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://walkingplow.tistory.com/78&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bdyTkB/hySW51ay35/RROatgafHOZKIaO6wvFbT0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/XmcWm/hySW2QUD7F/6xih7fbhuPmtqqecmj5SSK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/C24cF/hySW5z6DU0/Scq9EKOKTAFbAKulnM1Tfk/img.png?width=1222&amp;amp;height=718&amp;amp;face=0_0_1222_718');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;CI/CD의 개념과 차이점&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CI/CD의 개념 CI/CD는 애플리케이션 개발 단계를 자동화해 보다 짧은 주기로 통합 및 배포하는 것을 의미합니다. 인터그레이션 헬(Integration Hell)을 해결하기 위한 솔루션으로 지속적인 통합, 지속적&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;walkingplow.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.redhat.com/ko/topics/devops/what-is-ci-cd&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.redhat.com/ko/topics/devops/what-is-ci-cd&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686461838278&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;CI/CD(CI CD, 지속적 통합/지속적 배포): 개념, 툴, 구축, 차이&quot; data-og-description=&quot;CI/CD는 애플리케이션의 통합 및 테스트 단계부터 제공 및 배포까지 애플리케이션 라이프사이클 전체에서 지속적인 자동화와 지속적인 모니터링을 제공하는 것을 뜻합니다.&quot; data-og-host=&quot;www.redhat.com&quot; data-og-source-url=&quot;https://www.redhat.com/ko/topics/devops/what-is-ci-cd&quot; data-og-url=&quot;https://www.redhat.com/ko/topics/devops/what-is-ci-cd&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bB69Tk/hySW1EtA0o/QDYk117OlK8buK8mhcaQi1/img.png?width=300&amp;amp;height=190&amp;amp;face=0_0_300_190&quot;&gt;&lt;a href=&quot;https://www.redhat.com/ko/topics/devops/what-is-ci-cd&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.redhat.com/ko/topics/devops/what-is-ci-cd&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bB69Tk/hySW1EtA0o/QDYk117OlK8buK8mhcaQi1/img.png?width=300&amp;amp;height=190&amp;amp;face=0_0_300_190');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;CI/CD(CI CD, 지속적 통합/지속적 배포): 개념, 툴, 구축, 차이&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CI/CD는 애플리케이션의 통합 및 테스트 단계부터 제공 및 배포까지 애플리케이션 라이프사이클 전체에서 지속적인 자동화와 지속적인 모니터링을 제공하는 것을 뜻합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.redhat.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.ciokorea.com/insider/233289&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.ciokorea.com/insider/233289&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686462404039&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;'CI/CD란?' 알기 쉽게 설명한 지속적 통합과 지속적 전달&quot; data-og-description=&quot;지속적 통합(Continuous integration, CI)과 지속적 제공(Continuous delivery, CD), 줄여서 CI/CD는&quot; data-og-host=&quot;www.ciokorea.com&quot; data-og-source-url=&quot;https://www.ciokorea.com/insider/233289&quot; data-og-url=&quot;https://www.ciokorea.com/news/233289&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/vqIQD/hySWlxauEK/sYewOKZY1zuT9KVrJLkBl0/img.jpg?width=747&amp;amp;height=467&amp;amp;face=189_178_304_304,https://scrap.kakaocdn.net/dn/C1Bt5/hySW397WL9/NEHQd65aZLyiT4AyxlQOX0/img.jpg?width=747&amp;amp;height=467&amp;amp;face=189_178_304_304&quot;&gt;&lt;a href=&quot;https://www.ciokorea.com/insider/233289&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ciokorea.com/insider/233289&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/vqIQD/hySWlxauEK/sYewOKZY1zuT9KVrJLkBl0/img.jpg?width=747&amp;amp;height=467&amp;amp;face=189_178_304_304,https://scrap.kakaocdn.net/dn/C1Bt5/hySW397WL9/NEHQd65aZLyiT4AyxlQOX0/img.jpg?width=747&amp;amp;height=467&amp;amp;face=189_178_304_304');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;'CI/CD란?' 알기 쉽게 설명한 지속적 통합과 지속적 전달&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;지속적 통합(Continuous integration, CI)과 지속적 제공(Continuous delivery, CD), 줄여서 CI/CD는&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ciokorea.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jud00.tistory.com/entry/CICD%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jud00.tistory.com/entry/CICD%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686462806164&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;CI/CD란 무엇일까?&quot; data-og-description=&quot;오늘은 CI/CD에 대해서 작성해보겠습니다. 앞으로는 글을 작성하는데 편한 글씨체로 작성할 생각입니다 :) CI/CD란? CI/CD는 개발자라면 한 번쯤은 다들 들어봤을 만한 단어일 것이다. CI/CD는 애플리&quot; data-og-host=&quot;jud00.tistory.com&quot; data-og-source-url=&quot;https://jud00.tistory.com/entry/CICD%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C&quot; data-og-url=&quot;https://jud00.tistory.com/entry/CICD%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/LLm85/hySWmpiHGF/Qx966Im3Lk9DeZsMbUykH0/img.png?width=800&amp;amp;height=188&amp;amp;face=0_0_800_188,https://scrap.kakaocdn.net/dn/j2ztr/hySWYAZSBB/D9Cjtupm0I0f2OuKj2VWh0/img.png?width=800&amp;amp;height=188&amp;amp;face=0_0_800_188,https://scrap.kakaocdn.net/dn/b1YRc0/hySW06DJGG/L1o0QH3KOrvYwp5E01mvd1/img.png?width=3015&amp;amp;height=710&amp;amp;face=0_0_3015_710&quot;&gt;&lt;a href=&quot;https://jud00.tistory.com/entry/CICD%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jud00.tistory.com/entry/CICD%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/LLm85/hySWmpiHGF/Qx966Im3Lk9DeZsMbUykH0/img.png?width=800&amp;amp;height=188&amp;amp;face=0_0_800_188,https://scrap.kakaocdn.net/dn/j2ztr/hySWYAZSBB/D9Cjtupm0I0f2OuKj2VWh0/img.png?width=800&amp;amp;height=188&amp;amp;face=0_0_800_188,https://scrap.kakaocdn.net/dn/b1YRc0/hySW06DJGG/L1o0QH3KOrvYwp5E01mvd1/img.png?width=3015&amp;amp;height=710&amp;amp;face=0_0_3015_710');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;CI/CD란 무엇일까?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;오늘은 CI/CD에 대해서 작성해보겠습니다. 앞으로는 글을 작성하는데 편한 글씨체로 작성할 생각입니다 :) CI/CD란? CI/CD는 개발자라면 한 번쯤은 다들 들어봤을 만한 단어일 것이다. CI/CD는 애플리&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jud00.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@woodonggyu/Deployment-Pipeline-CICD&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@woodonggyu/Deployment-Pipeline-CICD&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686465457780&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;WHAT IS &amp;quot;CI/CD&amp;quot; ?&quot; data-og-description=&quot;본 글에서는 CI/CD 에 대한 기본적인 내용을 다룬다.&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@woodonggyu/Deployment-Pipeline-CICD&quot; data-og-url=&quot;https://velog.io/@woodonggyu/Deployment-Pipeline-CICD&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/BQs0C/hySXcsuTAQ/fW1B3AraW3QggNjnBSZDAk/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/ejwhc0/hySWrc8ZBb/KAgKSfy1bjbnYr7K0DIaV0/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460&quot;&gt;&lt;a href=&quot;https://velog.io/@woodonggyu/Deployment-Pipeline-CICD&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@woodonggyu/Deployment-Pipeline-CICD&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/BQs0C/hySXcsuTAQ/fW1B3AraW3QggNjnBSZDAk/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/ejwhc0/hySWrc8ZBb/KAgKSfy1bjbnYr7K0DIaV0/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;WHAT IS &quot;CI/CD&quot; ?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;본 글에서는 CI/CD 에 대한 기본적인 내용을 다룬다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AWS</category>
      <category>AWS</category>
      <category>CI/CD</category>
      <category>빌드/배포 자동화</category>
      <category>파이프라인</category>
      <author>개발개굴 </author>
      <guid isPermaLink="true">https://j-su2.tistory.com/137</guid>
      <comments>https://j-su2.tistory.com/137#entry137comment</comments>
      <pubDate>Sun, 11 Jun 2023 16:59:09 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래밍 패러다임] SOLID란?</title>
      <link>https://j-su2.tistory.com/128</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;객체지향 프로그래밍(OOP)이란?&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;*객체지향 프로그래밍&lt;/span&gt;&lt;/b&gt;은 객체들의 집합으로 프로그램의 상호 작용을 표현하며 데이터를 객체로 취급하여 객체 내부에 선언된 메서드를 활용하는 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;*프로그래밍 패러다임&lt;/span&gt;&lt;/b&gt;으로 추상화, 캡슐화, 상속성, 다형성이라는 특징을 가지고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333;&quot;&gt;이러한 특징들로 인해 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;*프로그래밍 패러다임이란?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://j-su2.tistory.com/127&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://j-su2.tistory.com/127&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664608884474&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[프로그래밍 패러다임] 프로그래밍 패러다임이란?&quot; data-og-description=&quot;프로그래밍 패러다임(Programming Paradigm)이란? 프로그래머에게 프로그래밍의 관점을 갖게 해주는 역할을 하는 개발 방법론입니다. 예를 들어 객체지향 프로그래밍 : 프로그래머들이 프로그램을 상&quot; data-og-host=&quot;j-su2.tistory.com&quot; data-og-source-url=&quot;https://j-su2.tistory.com/127&quot; data-og-url=&quot;https://j-su2.tistory.com/127&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/lGN4m/hyPY0OOJck/dNZga016u8R6KU48afdKQ1/img.png?width=800&amp;amp;height=492&amp;amp;face=0_0_800_492,https://scrap.kakaocdn.net/dn/dpPOWl/hyPZbJzG1D/hXjCeONtiEysJtOVQ7ZEMk/img.png?width=800&amp;amp;height=492&amp;amp;face=0_0_800_492,https://scrap.kakaocdn.net/dn/b6NJUu/hyPXFFy9hc/Y6xf1J2J0l12wccyaxoj01/img.png?width=1134&amp;amp;height=698&amp;amp;face=0_0_1134_698&quot;&gt;&lt;a href=&quot;https://j-su2.tistory.com/127&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://j-su2.tistory.com/127&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/lGN4m/hyPY0OOJck/dNZga016u8R6KU48afdKQ1/img.png?width=800&amp;amp;height=492&amp;amp;face=0_0_800_492,https://scrap.kakaocdn.net/dn/dpPOWl/hyPZbJzG1D/hXjCeONtiEysJtOVQ7ZEMk/img.png?width=800&amp;amp;height=492&amp;amp;face=0_0_800_492,https://scrap.kakaocdn.net/dn/b6NJUu/hyPXFFy9hc/Y6xf1J2J0l12wccyaxoj01/img.png?width=1134&amp;amp;height=698&amp;amp;face=0_0_1134_698');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[프로그래밍 패러다임] 프로그래밍 패러다임이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;프로그래밍 패러다임(Programming Paradigm)이란? 프로그래머에게 프로그래밍의 관점을 갖게 해주는 역할을 하는 개발 방법론입니다. 예를 들어 객체지향 프로그래밍 : 프로그래머들이 프로그램을 상&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;j-su2.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;*객체지향 프로그래밍(OOP)란?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://j-su2.tistory.com/35&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://j-su2.tistory.com/35&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664608872115&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[프로그래밍 패러다임] OOP와 FP&quot; data-og-description=&quot;OOP란? OOP는 Object Oriented Programming의 약자로 객체 지향 프로그래밍을 뜻합니다. class와 object에 기반한 프로그래밍 패러다임(디자인 패턴)으로, 관련된 데이터끼리 묶어서 class를 형성하고 그 안에&quot; data-og-host=&quot;j-su2.tistory.com&quot; data-og-source-url=&quot;https://j-su2.tistory.com/35&quot; data-og-url=&quot;https://j-su2.tistory.com/35&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hVTbn/hyPYXEx4Ns/NtmQbzey1YiMcoObyZAktK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/j3ypi/hyPY0uv2La/NH7SF9dbV5JJe4kpuyNEBK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://j-su2.tistory.com/35&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://j-su2.tistory.com/35&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hVTbn/hyPYXEx4Ns/NtmQbzey1YiMcoObyZAktK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/j3ypi/hyPY0uv2La/NH7SF9dbV5JJe4kpuyNEBK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[프로그래밍 패러다임] OOP와 FP&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;OOP란? OOP는 Object Oriented Programming의 약자로 객체 지향 프로그래밍을 뜻합니다. class와 object에 기반한 프로그래밍 패러다임(디자인 패턴)으로, 관련된 데이터끼리 묶어서 class를 형성하고 그 안에&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;j-su2.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 객체지향 프로그래밍을 설계할 때는 SOLID 원칙을 지켜주어야 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SOLID란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SOLID란 로버트 마틴이 2000년대 초반에 명명한 객체 지향 프로그래밍 및 설계의 다섯 가지 기본 원칙을 마이클 패더스가 두문자어 기억술로 소개한 것입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그래머가 시간이 지나도 유지 보수와 확장이 쉬운 시스템을 만들게 해줌&lt;/li&gt;
&lt;li&gt;애자일 소프트웨어 개발과 적응형 소프트웨어 개발의 전박적 전략의 일부&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;S는 단일 책임 원칙, O는 개방-폐쇄 원칙, L은 리스코프 치환 원칙, I는 인터페이스 분리 원칙, D는 의존 역선 원칙을 의미합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;단일 책임 원칙(SRP, Single Responsibility Principle)&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 클래스는 각각 하나의 책임만 가져야 하는 원칙입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변경이 있을 때 파급 효과가 적으면 좋음&lt;/li&gt;
&lt;li&gt;예를 들어 객체의 생성 부분과 사용 부분을 분리하는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;개방-폐쇄 원칙(OCP, Open Close Principle)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유지 보수 사항이 생긴다면 코드를 쉽게 확장할 수 있도록 하고 수정할 때는 닫혀 있어야 하는 원칙입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존의 코드는 잘 변경하지 않으면서도 확장은 쉽게 할 수 있어야 함&lt;/li&gt;
&lt;li&gt;예를 들어 다형성을 활용해 인터페이스를 구현한 새로운 클래스를 하나 만들어 새로운 기능을 구현&lt;/li&gt;
&lt;li&gt;역할과 구현의 분리&lt;/li&gt;
&lt;li&gt;객체를 생성하고, 연관관계를 맺어주는 별도의 조립/설정자가 필요함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;리스코프 치환 원칙(LSP, Liskov Substitution Principle)&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 하는 것입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부모 객체에 자식 객체를 넣어도 시스템이 문제없이 돌아가야 함&lt;/li&gt;
&lt;li&gt;다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다는 것, 다형성을 지원하기 위한 원칙, 인터페이스를 구현한 구현체를 믿고 사용하려면 LSP가 충족되어야 함&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;예를 들어 &lt;/span&gt;컴파일에 성공해도 인터페이스의 기능에 대한 규약을 지키지 않게 구현하다면 LSP를 위반!&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;인터페이스 분리 원칙(ISP, Interface Segregation Principle)&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 일반적인 인터페이스보다 구체적인 여러 개의 인터페이스를 만들어야 하는 원칙을 말합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터페이스가 명확해지고, 대체 가능성이 높아짐&lt;/li&gt;
&lt;li&gt;예를 들어 자동차는 운전/정비 기능이 있고, 사용자는 운전자/정비사로 분리해두면 정비 인터페이스를 바꿔도 운전자에는 영향을 미치지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;의존 역전 원칙(DIP, Dependency Inversion Principle)&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DIP의 핵심 원리는 &quot;추상화에 의존해야지, 구체화에 의존하면 안된다&quot; 입니다. 즉,&amp;nbsp;자신보다 변하기 쉬운 것에 의존하던 것을 추상화된 인터페이스나 상위 클래스를 두어 변하기 쉬운 것의 변화에 영향받지 않게 하는 원칙을 말합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상위 계층은 하위 계층의 변화에 대한 구현으로부터 독립해야 함&lt;/li&gt;
&lt;li&gt;구현 클래스에 의존하지 말고 인터페이스에 의존해야 함 (구현체에 의존하게 된다면 변경이 아주 어려워지게 됨)&lt;/li&gt;
&lt;li&gt;의존성 주입은 DIP를 따름&lt;/li&gt;
&lt;li&gt;역할에 의존하게 해야함&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하자면, 객체 지향의 핵심은 다형성을 통해 변경에 용이한 개발을 하는 것입니다. 하지만, 다형성 만으로는 OCP, DIP를 지킬 수 없기 때문에 스프링과 같이 객체 지향 설계를 도와주는 프레임워크를 사용해 해결할 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[출처] 면접을 위한 CS 전공지식 노트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://www.yes24.com/Product/Goods/108887922&quot;&gt;http://www.yes24.com/Product/Goods/108887922&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664609613547&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;book&quot; data-og-title=&quot;면접을 위한 CS 전공지식 노트 - YES24&quot; data-og-description=&quot;디자인 패턴, 네트워크, 운영체제, 데이터베이스, 자료 구조, 개발자 면접과 포트폴리오까지!CS 전공지식 습득과 면접 대비, 이 책 한 권이면 충분하다!개발자 면접에서 큰 비중을 차지하는 CS(Comp&quot; data-og-host=&quot;www.yes24.com&quot; data-og-source-url=&quot;http://www.yes24.com/Product/Goods/108887922&quot; data-og-url=&quot;http://www.yes24.com/Product/Goods/108887922&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/zrnMI/hyPXKGQaEX/8OoguVBzPPSDam0KpWYvjk/img.jpg?width=934&amp;amp;height=1200&amp;amp;face=0_0_934_1200,https://scrap.kakaocdn.net/dn/bN3Ndq/hyPY2MCS77/bScs6KxstRUe6KKH3Hk2l0/img.jpg?width=934&amp;amp;height=1200&amp;amp;face=0_0_934_1200,https://scrap.kakaocdn.net/dn/dIcRCz/hyPY02mbCi/kcMdWmQJ6AK8dKYMad3mZ1/img.jpg?width=934&amp;amp;height=1200&amp;amp;face=0_0_934_1200&quot;&gt;&lt;a href=&quot;http://www.yes24.com/Product/Goods/108887922&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.yes24.com/Product/Goods/108887922&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/zrnMI/hyPXKGQaEX/8OoguVBzPPSDam0KpWYvjk/img.jpg?width=934&amp;amp;height=1200&amp;amp;face=0_0_934_1200,https://scrap.kakaocdn.net/dn/bN3Ndq/hyPY2MCS77/bScs6KxstRUe6KKH3Hk2l0/img.jpg?width=934&amp;amp;height=1200&amp;amp;face=0_0_934_1200,https://scrap.kakaocdn.net/dn/dIcRCz/hyPY02mbCi/kcMdWmQJ6AK8dKYMad3mZ1/img.jpg?width=934&amp;amp;height=1200&amp;amp;face=0_0_934_1200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;면접을 위한 CS 전공지식 노트 - YES24&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;디자인 패턴, 네트워크, 운영체제, 데이터베이스, 자료 구조, 개발자 면접과 포트폴리오까지!CS 전공지식 습득과 면접 대비, 이 책 한 권이면 충분하다!개발자 면접에서 큰 비중을 차지하는 CS(Comp&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.yes24.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)&quot;&gt;https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1664609625971&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;SOLID (객체 지향 설계) - 위키백과, 우리 모두의 백과사전&quot; data-og-description=&quot;위키백과, 우리 모두의 백과사전.&quot; data-og-host=&quot;ko.wikipedia.org&quot; data-og-source-url=&quot;https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)&quot; data-og-url=&quot;https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84)&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SOLID (객체 지향 설계) - 위키백과, 우리 모두의 백과사전&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;위키백과, 우리 모두의 백과사전.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ko.wikipedia.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664610160762&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;[무료] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 인프런 | 강의&quot; data-og-description=&quot;스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., - 강의 소개 | 인프런...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/9nIPr/hyPY3rfQmp/d95ChurWAF8mgtbbRsrfm0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/GaCO2/hyPXCovUY0/4nGV7BhJnXLfgBtRjm0ZZ0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/9nIPr/hyPY3rfQmp/d95ChurWAF8mgtbbRsrfm0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/GaCO2/hyPXCovUY0/4nGV7BhJnXLfgBtRjm0ZZ0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[무료] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., - 강의 소개 | 인프런...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1684844660469&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;스프링 핵심 원리 - 기본편 - 인프런 | 강의&quot; data-og-description=&quot;스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., - 강의 소개 | 인프런&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bvNYSl/hySJaPJosh/zDrYdm1Ss8ihtRgKQSqjr1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/3pVVC/hySJahSCJ7/84APcJRnLJKtkdurQvDK5k/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/oNhB4/hySJfcpDOS/s2ZwGidvgrjkCimti7Ipm0/img.png?width=1805&amp;amp;height=1044&amp;amp;face=0_0_1805_1044&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bvNYSl/hySJaPJosh/zDrYdm1Ss8ihtRgKQSqjr1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/3pVVC/hySJahSCJ7/84APcJRnLJKtkdurQvDK5k/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/oNhB4/hySJfcpDOS/s2ZwGidvgrjkCimti7Ipm0/img.png?width=1805&amp;amp;height=1044&amp;amp;face=0_0_1805_1044');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;스프링 핵심 원리 - 기본편 - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., - 강의 소개 | 인프런&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>CS/Design Pattern</category>
      <category>SOLID란</category>
      <category>객체지향 프로그래밍 설계 원칙</category>
      <author>개발개굴 </author>
      <guid isPermaLink="true">https://j-su2.tistory.com/128</guid>
      <comments>https://j-su2.tistory.com/128#entry128comment</comments>
      <pubDate>Tue, 23 May 2023 21:56:52 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] Mockito란?</title>
      <link>https://j-su2.tistory.com/136</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;368&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZfvyk/btr3ICpugBF/nnM6ZVWqboksckcY6RjUw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZfvyk/btr3ICpugBF/nnM6ZVWqboksckcY6RjUw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZfvyk/btr3ICpugBF/nnM6ZVWqboksckcY6RjUw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZfvyk%2Fbtr3ICpugBF%2FnnM6ZVWqboksckcY6RjUw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;468&quot; height=&quot;278&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;368&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;단위 테스트란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단위 테스트는 하나의 모듈을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트입니다. 즉, 하나의 기능이 올바르게 동작하는지 독립적으로 테스트하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램을 작은 단위로 쪼개서 각 단위가 정확하게 동작하는지 검사하기 때문에 문제 발생 시 정확하게 어느 부분이 잘못되었는지 캐치할 수 있다는 장점이 있지만, 다른 객체와 데이터를 주고 받는 경우에 문제가 발생할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 Service 계층의 단위 테스트 코드를 작성할 때 보통 다른 객체들과 의존 관계를 맺고 있는 경우가 많습니다. 이때, Bean Container에 주입된 실제 객체들을 가져다 쓰는 방법이 있고, Mockito 프레임워크 등을 활용해 Mock 객체를 만들어서 쓰는 방법이 존재합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Mockito란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mockito는 &lt;span style=&quot;color: #009a87;&quot;&gt;*JUnit&lt;/span&gt; Test에서 &lt;span style=&quot;color: #009a87;&quot;&gt;*Mock&lt;/span&gt;을 위한 Java 오픈소스 테스트 프레임워크입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Spring은 여러 객체들 간의 의존성이 생기게 되는데, 이러한 특성은 단위 테스트를 작성하기 어렵게 만듭니다. 따라서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;의존성을 해결하기 위해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;개발자가 동작을 직접 제어할 수 있는 가짜 객체인 Mock을 생성하여 주입시켜주는 Mockito 라이브러리를 활용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, Mockito는 &lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;Mock 객체를 쉽게 만들고, 관리하고, 검증할 수 있는 방법을 제공하는 프레임워크&lt;/span&gt;&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;*Mock: 진짜 객체와 비슷하게 동작하지만, 프로그래머가 직접 행동을 관리하는 객체&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87; text-align: start;&quot;&gt;*JUnit: 자바 단위 테스트를 위한 프레임워크&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Mockito 시작하기&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Dependency 추가&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 부트 2.2 이상 버전의 프로젝트 생성시 spring-boot-start-test에서 자동으로 Mockito를 추가해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1678792620113&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dependencies {
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접 추가하기 위해선 mockito-core와 mockito-junit-jupiter가 필요합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;mockito-core: mockito가 제공해주는 기본적인 라이브러리&lt;/li&gt;
&lt;li&gt;mockito-junit-jupiter: junit 테스트에서 mockito를 연동해서 사용할 수 있는 junit 확장 구현체&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1678792894871&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// build.gradle
dependencies {
    testImplementation 'org.mockito:mockito-core:3.11.2'
    testImplementation 'org.mockito:mockito-junit-jupiter:3.11.2'   
}

//maven
 &amp;lt;dependency&amp;gt;       
 	&amp;lt;groupId&amp;gt;org.mockito&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;mockito-core&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;3.1.0&amp;lt;/version&amp;gt;
    &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;

&amp;lt;dependency&amp;gt;
	&amp;lt;groupId&amp;gt;org.mockito&amp;lt;/groupId&amp;gt;
	&amp;lt;artifactId&amp;gt;mockito-junit-jupiter&amp;lt;/artifactId&amp;gt;
	&amp;lt;version&amp;gt;3.1.0&amp;lt;/version&amp;gt;
	&amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;JUnit과 결합&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mockito도 테스팅 프레임워크이기 때문에 &lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;JUnit과 결합되기 위해 클래스 어노테이션을 붙이는 별도의 작업&lt;/span&gt;&lt;/b&gt;이 필요합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JUnit4: @RunWith(MockitoJUnitRunner.class)&lt;/li&gt;
&lt;li&gt;JUnit5: @ExtendWith(MockitoExtension.class)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;SpringBoot 2.2.0부터 공식적으로 JUnit5를 지원함에 따라 &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;@ExtendWith(MockitoExtension.class)를 사용해 결합하게 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678794095272&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@ExtendWith(MockitoExtension.class)
class Test {
	// 테스트 작성
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Mockito 사용하기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 테스트 작성에 앞서 Member라는 객체를 조회하기 위한 세팅을 진행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(편의성을 위해 저는 Lombok을 사용했습니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Member&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1684668726668&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.demotest.domain;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Getter
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Table(name = &quot;member&quot;)
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = &quot;member_no&quot;)
    private Long no;

    @Setter
    @Column(name = &quot;name&quot;, nullable = false)
    private String name;

}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Member Entity를 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Repository&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1684668867483&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.example.demotest.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface MemberRepository extends JpaRepository&amp;lt;Member, Long&amp;gt; {
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Member를 조회하기 위한 Repository를 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Service&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1684668890814&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.example.demotest.domain.Member;
import com.example.demotest.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class MemberService {

    private final MemberRepository memberRepository;

    public List&amp;lt;Member&amp;gt; findAllMember() {
        return memberRepository.findAll();
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Member List를 조회하는 서비스를 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 MemberService를 통해 Member List를 조회하는 Service Test 예시는 다음과 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1684668989045&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.example.demotest.domain.Member;
import com.example.demotest.repository.MemberRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.assertj.core.api.Assertions;

import java.util.ArrayList;
import java.util.List;

@ExtendWith(MockitoExtension.class)
class MemberServiceTest {

    @InjectMocks
    private MemberService memberService;

    @Mock
    private MemberRepository memberRepository;

    @Test
    @DisplayName(&quot;회원 조회 결과 Member 리스트가 반환되어야 한다.&quot;)
    void findAllMember() {
        // given
        List&amp;lt;Member&amp;gt; memberList = new ArrayList&amp;lt;&amp;gt;();
        memberList.add(new Member(
                1L,
                &quot;name1&quot;));
        memberList.add(new Member(
                2L,
                &quot;name2&quot;));


        // when
        Mockito.when(memberRepository.findAll()).thenReturn(memberList);
        List&amp;lt;Member&amp;gt; result = memberService.findAllMember();

        // then
        Assertions.assertThat(result).hasSize(2);
        Assertions.assertThat(result.get(0).getName()).isEqualTo(&quot;name1&quot;);
        Assertions.assertThat(result.get(1).getName()).isEqualTo(&quot;name2&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@Mock
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Mock객체를 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;@InjectMocks
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@Mock이 붙은 Mock객체를 @InjectMocks이 붙은 객체에 주입&lt;/li&gt;
&lt;li&gt;Service를 테스트하기 위해서 MemberRespository를 주입받아야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Mock 객체 Stubbing
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;when() -&amp;gt; memberRepository를 통해 회원 리스트를 조회 했을때&lt;/li&gt;
&lt;li&gt;thenReturn() -&amp;gt; memberList가 return 되어야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Test 진행
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Repository에서 조회한 결과와 Service를 통해 조회한 결과를 비교&lt;/li&gt;
&lt;li&gt;생성한 MemberList의 크기는 2&lt;/li&gt;
&lt;li&gt;첫번째 값의 이름은 name1&lt;/li&gt;
&lt;li&gt;두번째 값의 이름은 name2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트를 실행 결과 passed가 잘 나옵니다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1354&quot; data-origin-height=&quot;406&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8gYs9/btsgG4MBltz/3j9POCmVyvRKslwxwKs6uk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8gYs9/btsgG4MBltz/3j9POCmVyvRKslwxwKs6uk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8gYs9/btsgG4MBltz/3j9POCmVyvRKslwxwKs6uk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8gYs9%2FbtsgG4MBltz%2F3j9POCmVyvRKslwxwKs6uk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1354&quot; height=&quot;406&quot; data-origin-width=&quot;1354&quot; data-origin-height=&quot;406&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작성 코드는 아래 링크를 통해 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/Jisue/Spring-Test/tree/main/demo-test&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/Jisue/Spring-Test/tree/main/demo-test&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1684669986138&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - Jisue/Spring-Test: TDD Study&quot; data-og-description=&quot;TDD Study. Contribute to Jisue/Spring-Test development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/Jisue/Spring-Test/tree/main/demo-test&quot; data-og-url=&quot;https://github.com/Jisue/Spring-Test&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/0K8ES/hySHeYBr2r/pqTwmzWzKJiXKyLwi44kSK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/Jisue/Spring-Test/tree/main/demo-test&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/Jisue/Spring-Test/tree/main/demo-test&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/0K8ES/hySHeYBr2r/pqTwmzWzKJiXKyLwi44kSK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - Jisue/Spring-Test: TDD Study&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;TDD Study. Contribute to Jisue/Spring-Test development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[참고]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mangkyu.tistory.com/145&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://mangkyu.tistory.com/145&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678791730288&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Spring] JUnit과 Mockito 기반의 Spring 단위 테스트 코드 작성법 (3/3)&quot; data-og-description=&quot;이번에는 Spring 기반의 웹 애플리케이션에서 테스트를 작성하는 방법에 대해 알아보도록 하겠습니다. 1. Mockito 소개 및 사용법 [ Mockito란? ] Mockito는 개발자가 동작을 직접 제어할 수 있는 가짜 객&quot; data-og-host=&quot;mangkyu.tistory.com&quot; data-og-source-url=&quot;https://mangkyu.tistory.com/145&quot; data-og-url=&quot;https://mangkyu.tistory.com/145&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bJO8VF/hyRVhoLDgp/GipbfXUCWtCY5kxXIhzdd0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/pDUxs/hyRVba1zOs/PCgxGwgEYuecUjPKjK6C31/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://mangkyu.tistory.com/145&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mangkyu.tistory.com/145&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bJO8VF/hyRVhoLDgp/GipbfXUCWtCY5kxXIhzdd0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/pDUxs/hyRVba1zOs/PCgxGwgEYuecUjPKjK6C31/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Spring] JUnit과 Mockito 기반의 Spring 단위 테스트 코드 작성법 (3/3)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 Spring 기반의 웹 애플리케이션에서 테스트를 작성하는 방법에 대해 알아보도록 하겠습니다. 1. Mockito 소개 및 사용법 [ Mockito란? ] Mockito는 개발자가 동작을 직접 제어할 수 있는 가짜 객&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mangkyu.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://scshim.tistory.com/439&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://scshim.tistory.com/439&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678791944515&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Mockito란? Mockito 사용하기&quot; data-og-description=&quot;Mockito란? &amp;middot; Mock 객체를 쉽게 만들고, 관리하고, 검증할 수 있는 방법을 제공하는 프레임워크 - Mock: 진짜 객체와 비슷하게 동작하지만, 프로그래머가 직접 행동을 관리하는 객체 - 공홈 https://site.m&quot; data-og-host=&quot;scshim.tistory.com&quot; data-og-source-url=&quot;https://scshim.tistory.com/439&quot; data-og-url=&quot;https://scshim.tistory.com/439&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bWkH1Y/hyRVhWD9Xz/BK2wPyEh79YMznVRGzdejK/img.png?width=800&amp;amp;height=400&amp;amp;face=0_0_800_400,https://scrap.kakaocdn.net/dn/co9qtP/hyRVcA03Rp/Vqm14LqndEiW2JzYKdTwoK/img.png?width=800&amp;amp;height=400&amp;amp;face=0_0_800_400,https://scrap.kakaocdn.net/dn/RHGIJ/hyRVfLhfzM/C0qr3tLWarXtlM5m3zTfvK/img.png?width=885&amp;amp;height=997&amp;amp;face=0_0_885_997&quot;&gt;&lt;a href=&quot;https://scshim.tistory.com/439&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://scshim.tistory.com/439&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bWkH1Y/hyRVhWD9Xz/BK2wPyEh79YMznVRGzdejK/img.png?width=800&amp;amp;height=400&amp;amp;face=0_0_800_400,https://scrap.kakaocdn.net/dn/co9qtP/hyRVcA03Rp/Vqm14LqndEiW2JzYKdTwoK/img.png?width=800&amp;amp;height=400&amp;amp;face=0_0_800_400,https://scrap.kakaocdn.net/dn/RHGIJ/hyRVfLhfzM/C0qr3tLWarXtlM5m3zTfvK/img.png?width=885&amp;amp;height=997&amp;amp;face=0_0_885_997');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Mockito란? Mockito 사용하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Mockito란? &amp;middot; Mock 객체를 쉽게 만들고, 관리하고, 검증할 수 있는 방법을 제공하는 프레임워크 - Mock: 진짜 객체와 비슷하게 동작하지만, 프로그래머가 직접 행동을 관리하는 객체 - 공홈 https://site.m&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;scshim.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.nextree.io/mockito/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.nextree.io/mockito/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678792948896&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Mockito를 활용하여 테스트 코드 작성하기&quot; data-og-description=&quot;Mockito 란? Mockito란 Java 오픈소스 테스트 프레임워크입니다. Mockito를 사용하면 실제 객체를 모방한 가짜 객체, Mock 객체 생성이 가능해집니다. 개발자는 이 Mock 객체를 통해 테스트를 보다 간단하&quot; data-og-host=&quot;www.nextree.io&quot; data-og-source-url=&quot;https://www.nextree.io/mockito/&quot; data-og-url=&quot;https://www.nextree.io/mockito/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/blZE3m/hyRU3cZMmG/sWZp98TMJMyQmRKkFkXlF0/img.jpg?width=658&amp;amp;height=468&amp;amp;face=0_0_658_468,https://scrap.kakaocdn.net/dn/Kj1Mz/hyRWsbaC9D/mcgYgxmNrKWNTZxqhxz6Qk/img.jpg?width=658&amp;amp;height=468&amp;amp;face=0_0_658_468,https://scrap.kakaocdn.net/dn/cPd6uA/hyRWyPZMoU/wdCyBdklTV9pH3eb3l9pk0/img.jpg?width=658&amp;amp;height=468&amp;amp;face=0_0_658_468&quot;&gt;&lt;a href=&quot;https://www.nextree.io/mockito/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.nextree.io/mockito/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/blZE3m/hyRU3cZMmG/sWZp98TMJMyQmRKkFkXlF0/img.jpg?width=658&amp;amp;height=468&amp;amp;face=0_0_658_468,https://scrap.kakaocdn.net/dn/Kj1Mz/hyRWsbaC9D/mcgYgxmNrKWNTZxqhxz6Qk/img.jpg?width=658&amp;amp;height=468&amp;amp;face=0_0_658_468,https://scrap.kakaocdn.net/dn/cPd6uA/hyRWyPZMoU/wdCyBdklTV9pH3eb3l9pk0/img.jpg?width=658&amp;amp;height=468&amp;amp;face=0_0_658_468');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Mockito를 활용하여 테스트 코드 작성하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Mockito 란? Mockito란 Java 오픈소스 테스트 프레임워크입니다. Mockito를 사용하면 실제 객체를 모방한 가짜 객체, Mock 객체 생성이 가능해집니다. 개발자는 이 Mock 객체를 통해 테스트를 보다 간단하&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.nextree.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://lemontia.tistory.com/951&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://lemontia.tistory.com/951&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1684669677266&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[junit5] Mock을 이용한 단위 테스트 (@InjectMocks 과 @Mock 차이)&quot; data-og-description=&quot;Mockito를 이용하면 좀더 작은 단위까지 테스트가 가능하다. 무엇보다 데이터를 컨트롤해야하는 상황에서 DB연결없이 임의로 주고받을 수 있기 때문에 유용하다. 이번에는 그 테스트에 관한 내용&quot; data-og-host=&quot;lemontia.tistory.com&quot; data-og-source-url=&quot;https://lemontia.tistory.com/951&quot; data-og-url=&quot;https://lemontia.tistory.com/951&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/vff5c/hySHau9egc/XBsU8kiEKKtTkHAHAADnA0/img.png?width=800&amp;amp;height=113&amp;amp;face=0_0_800_113,https://scrap.kakaocdn.net/dn/boBXro/hySG2qmDzK/qsCTqpbWLh8Akjrww0qpPK/img.png?width=800&amp;amp;height=113&amp;amp;face=0_0_800_113&quot;&gt;&lt;a href=&quot;https://lemontia.tistory.com/951&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://lemontia.tistory.com/951&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/vff5c/hySHau9egc/XBsU8kiEKKtTkHAHAADnA0/img.png?width=800&amp;amp;height=113&amp;amp;face=0_0_800_113,https://scrap.kakaocdn.net/dn/boBXro/hySG2qmDzK/qsCTqpbWLh8Akjrww0qpPK/img.png?width=800&amp;amp;height=113&amp;amp;face=0_0_800_113');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[junit5] Mock을 이용한 단위 테스트 (@InjectMocks 과 @Mock 차이)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Mockito를 이용하면 좀더 작은 단위까지 테스트가 가능하다. 무엇보다 데이터를 컨트롤해야하는 상황에서 DB연결없이 임의로 주고받을 수 있기 때문에 유용하다. 이번에는 그 테스트에 관한 내용&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;lemontia.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@hellonayeon/spring-boot-service-layer-unit-testcode&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@hellonayeon/spring-boot-service-layer-unit-testcode&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1685253780452&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Spring Boot] Service 계층의 단위 테스트 코드 작성&quot; data-og-description=&quot; &quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@hellonayeon/spring-boot-service-layer-unit-testcode&quot; data-og-url=&quot;https://velog.io/@hellonayeon/spring-boot-service-layer-unit-testcode&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Rjp8S/hySNfWusAa/a8Ab6RIkkrg73QR8DT0rvk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/cVg2GY/hySNaHD7Lw/OMF63CBSwaZg9Fe1OE2b11/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960&quot;&gt;&lt;a href=&quot;https://velog.io/@hellonayeon/spring-boot-service-layer-unit-testcode&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@hellonayeon/spring-boot-service-layer-unit-testcode&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Rjp8S/hySNfWusAa/a8Ab6RIkkrg73QR8DT0rvk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/cVg2GY/hySNaHD7Lw/OMF63CBSwaZg9Fe1OE2b11/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Spring Boot] Service 계층의 단위 테스트 코드 작성&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@sussa3007/Spring-JUnit-Mockito-%EA%B8%B0%EB%B0%98-Spring-%EB%8B%A8%EC%9C%84-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@sussa3007/Spring-JUnit-Mockito-%EA%B8%B0%EB%B0%98-Spring-%EB%8B%A8%EC%9C%84-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1685254754983&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Spring] JUnit &amp;amp; Mockito 기반 Spring 단위 테스트 코드 작성&quot; data-og-description=&quot;단위테스트는 하나의 모듈을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트다.하나의 모듈이란 각 계층에서의 하나의 기능 또는 메소드로 이해할 수 있다.하나의 기능이 올바르게 동&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@sussa3007/Spring-JUnit-Mockito-%EA%B8%B0%EB%B0%98-Spring-%EB%8B%A8%EC%9C%84-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1&quot; data-og-url=&quot;https://velog.io/@sussa3007/Spring-JUnit-Mockito-기반-Spring-단위-테스트-코드-작성&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mNgBU/hySLDxWFY3/FDf8xQCzNMkYS809nwwT2K/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/btfzQ6/hySM9hGdA0/RQx1NmKWy9TOINC08OvZVk/img.jpg?width=822&amp;amp;height=822&amp;amp;face=0_0_822_822&quot;&gt;&lt;a href=&quot;https://velog.io/@sussa3007/Spring-JUnit-Mockito-%EA%B8%B0%EB%B0%98-Spring-%EB%8B%A8%EC%9C%84-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@sussa3007/Spring-JUnit-Mockito-%EA%B8%B0%EB%B0%98-Spring-%EB%8B%A8%EC%9C%84-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mNgBU/hySLDxWFY3/FDf8xQCzNMkYS809nwwT2K/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/btfzQ6/hySM9hGdA0/RQx1NmKWy9TOINC08OvZVk/img.jpg?width=822&amp;amp;height=822&amp;amp;face=0_0_822_822');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Spring] JUnit &amp;amp; Mockito 기반 Spring 단위 테스트 코드 작성&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;단위테스트는 하나의 모듈을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트다.하나의 모듈이란 각 계층에서의 하나의 기능 또는 메소드로 이해할 수 있다.하나의 기능이 올바르게 동&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>JUnit</category>
      <category>Mockito</category>
      <category>spring test</category>
      <category>TDD</category>
      <category>단위테스트</category>
      <author>개발개굴 </author>
      <guid isPermaLink="true">https://j-su2.tistory.com/136</guid>
      <comments>https://j-su2.tistory.com/136#entry136comment</comments>
      <pubDate>Sun, 21 May 2023 20:47:40 +0900</pubDate>
    </item>
    <item>
      <title>[Server] gRPC란?</title>
      <link>https://j-su2.tistory.com/135</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;gRPC(Google Remote Procedure Call&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;)&lt;/span&gt;란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gRPC&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;는&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Google에서 만든 RPC&lt;/b&gt;&lt;/span&gt;로 &lt;/span&gt;공식 홈페이지에 &lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;A high performance, open source universal RPC framework&quot;&lt;/span&gt;&lt;/b&gt;라고 정의되어 있습니다. 이를 직역하자면 &lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;고성능 오픈 소스 범용 RPC 프레임워크&quot;&lt;/span&gt;&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 gRPC등장 이전의 RPC에 대해 먼저 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;RPC(Remote Procedure Call)란?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 프로시저 호출(RPC)는 &lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;별도의 원격 제어를 위한 코딩 없이 다른 주소 공간에서 함수나 프로시저를 실행할 수 있게하는 프로세스 간 통신 기술&lt;/span&gt;&lt;/b&gt;입니다. 즉, RPC를 이용하면 개발자는 어디서든 원하는 함수를 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RPC는 &lt;span style=&quot;color: #009a87;&quot;&gt;*IPC 기법&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;중 1개로 클라이언트나 서버는 일반 메소드를 호출하는 것처럼 원격의 프로시저를 호출하여 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, &lt;span&gt;다양한 언어와 프레임워크로 개발될 수 있는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #009a87;&quot;&gt;*MSA&lt;/span&gt;&amp;nbsp;구조의 서비스처럼 Polyglot한 구조에서는 프로토콜에 맞춰서 통신하려면 복잡하고 비용이 들지만, &lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;RPC를 통해 언어에 구애받지 않고, 원격에 있는 프로시저를 호출&lt;/span&gt;&lt;/b&gt;할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-01-06 오후 5.34.23.png&quot; data-origin-width=&quot;1532&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kX64Z/btrVyWoxNZ9/GxXQKXNdLPlewHRws3EDOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kX64Z/btrVyWoxNZ9/GxXQKXNdLPlewHRws3EDOk/img.png&quot; data-alt=&quot;Polyglot한 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kX64Z/btrVyWoxNZ9/GxXQKXNdLPlewHRws3EDOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkX64Z%2FbtrVyWoxNZ9%2FGxXQKXNdLPlewHRws3EDOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1532&quot; height=&quot;656&quot; data-filename=&quot;스크린샷 2023-01-06 오후 5.34.23.png&quot; data-origin-width=&quot;1532&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Polyglot한 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;*IPC(Inter Process Communication) 기법:&lt;/span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로세스 간 정보를 교환하기 위해 통신하는 방법론을 통칭한 것 ex)소켓, RPC, REST 등&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #009a87;&quot;&gt;*MSA(Micro Service Architecture) : &lt;span style=&quot;color: #000000;&quot;&gt;서비스간의 의존성을 없애고 기능을 쪼개는 것을 중점적으로 설계한 아키텍처&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;gRPC의 특징과 구조&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 많이 사용되던 REST 방식의 경우에는, 표준이 없어 파라미터의 응답이 명시적이지 않았을 뿐 아니라 JSON형태의 데이터를 Serialization하는 비용이 발생한다는 단점이 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 REST의 문제점을 해결하기 위한 대안으로 google사에서 개발한 오픈소스 RPC 프레임워크인&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;gRPC를 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;gRPC의 특징&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;*protocol buffer&lt;/span&gt;와 RPC를 사용&lt;/li&gt;
&lt;li&gt;최신 버전의 &lt;span style=&quot;color: #009a87;&quot;&gt;*IDL&lt;/span&gt;로 proto3를 사용&lt;/li&gt;
&lt;li&gt;SSL/TLS를 사용하여 서버를 인증하고 클라이언트와 서버간에 교환되는 모든 데이터를 암호화&lt;/li&gt;
&lt;li&gt;HTTP 2.0을 사용하여 성능이 뛰어나고 확장 가능한 API를 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 특징들로 인해 gRPC를 사용하면 Proto File만 배포하여 환경과 프로그램 언어에 구애받지 않고 서로 간의 데이터 통신이 가능해집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;*IDL:&lt;/span&gt;&lt;/b&gt; 정보를 저장하는 규칙 (ex. XML, JSON, Protocol Buffer)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;*protocol buffer:&lt;/span&gt;&lt;/b&gt; 구조화된 데이터를 직렬화하여 XML을 문제점을 개선하기 위해 제안된 IDL&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;gPRC의 구조&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-01-07 오후 6.48.41.png&quot; data-origin-width=&quot;1424&quot; data-origin-height=&quot;966&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNeQ7a/btrVzJwbb1Y/wkKMerVlL3nuhCwM3vKrQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNeQ7a/btrVzJwbb1Y/wkKMerVlL3nuhCwM3vKrQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNeQ7a/btrVzJwbb1Y/wkKMerVlL3nuhCwM3vKrQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNeQ7a%2FbtrVzJwbb1Y%2FwkKMerVlL3nuhCwM3vKrQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1424&quot; height=&quot;966&quot; data-filename=&quot;스크린샷 2023-01-07 오후 6.48.41.png&quot; data-origin-width=&quot;1424&quot; data-origin-height=&quot;966&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gRPC에서 클라이언트 응용 프로그램을 서버에서 함수를 바로 호출 할 수 있어 분산 MSA를 쉽게 구현할 수 있으며, 서버 측에서는 서버 인터페이스를 구현하고 gRPC 서버를 실행하여 클라이언트 호출을 처리합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[참고]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://medium.com/naver-cloud-platform/nbp-%EA%B8%B0%EC%88%A0-%EA%B2%BD%ED%97%98-%EC%8B%9C%EB%8C%80%EC%9D%98-%ED%9D%90%EB%A6%84-grpc-%EA%B9%8A%EA%B2%8C-%ED%8C%8C%EA%B3%A0%EB%93%A4%EA%B8%B0-1-39e97cb3460&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://medium.com/naver-cloud-platform/nbp-%EA%B8%B0%EC%88%A0-%EA%B2%BD%ED%97%98-%EC%8B%9C%EB%8C%80%EC%9D%98-%ED%9D%90%EB%A6%84-grpc-%EA%B9%8A%EA%B2%8C-%ED%8C%8C%EA%B3%A0%EB%93%A4%EA%B8%B0-1-39e97cb3460&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1672903187808&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[NBP 기술&amp;amp;경험] 시대의 흐름, gRPC 깊게 파고들기 #1&quot; data-og-description=&quot;안녕하세요, 네이버 클라우드 플랫폼입니다.&quot; data-og-host=&quot;medium.com&quot; data-og-source-url=&quot;https://medium.com/naver-cloud-platform/nbp-%EA%B8%B0%EC%88%A0-%EA%B2%BD%ED%97%98-%EC%8B%9C%EB%8C%80%EC%9D%98-%ED%9D%90%EB%A6%84-grpc-%EA%B9%8A%EA%B2%8C-%ED%8C%8C%EA%B3%A0%EB%93%A4%EA%B8%B0-1-39e97cb3460&quot; data-og-url=&quot;https://medium.com/naver-cloud-platform/nbp-%EA%B8%B0%EC%88%A0-%EA%B2%BD%ED%97%98-%EC%8B%9C%EB%8C%80%EC%9D%98-%ED%9D%90%EB%A6%84-grpc-%EA%B9%8A%EA%B2%8C-%ED%8C%8C%EA%B3%A0%EB%93%A4%EA%B8%B0-1-39e97cb3460&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/1zCJ9/hyRaFJUfix/1SQe0f5RNRcLQIildjtGS1/img.png?width=966&amp;amp;height=483&amp;amp;face=0_0_966_483&quot;&gt;&lt;a href=&quot;https://medium.com/naver-cloud-platform/nbp-%EA%B8%B0%EC%88%A0-%EA%B2%BD%ED%97%98-%EC%8B%9C%EB%8C%80%EC%9D%98-%ED%9D%90%EB%A6%84-grpc-%EA%B9%8A%EA%B2%8C-%ED%8C%8C%EA%B3%A0%EB%93%A4%EA%B8%B0-1-39e97cb3460&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://medium.com/naver-cloud-platform/nbp-%EA%B8%B0%EC%88%A0-%EA%B2%BD%ED%97%98-%EC%8B%9C%EB%8C%80%EC%9D%98-%ED%9D%90%EB%A6%84-grpc-%EA%B9%8A%EA%B2%8C-%ED%8C%8C%EA%B3%A0%EB%93%A4%EA%B8%B0-1-39e97cb3460&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/1zCJ9/hyRaFJUfix/1SQe0f5RNRcLQIildjtGS1/img.png?width=966&amp;amp;height=483&amp;amp;face=0_0_966_483');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[NBP 기술&amp;amp;경험] 시대의 흐름, gRPC 깊게 파고들기 #1&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요, 네이버 클라우드 플랫폼입니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;medium.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://chacha95.github.io/2020-06-15-gRPC1/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://chacha95.github.io/2020-06-15-gRPC1/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1672903196376&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;gRPC 1 - gRPC란?&quot; data-og-description=&quot;배경지식 gRPC는 Google에서 개발한 RPC(Remote Procedure Call) 시스템입니다. 전송을 위해 TCP/IP 프로토콜과 HTTP 2.0 프로토콜을 사용하고 IDL(Interface Definition language)로 protocol buffer를 사용합니다. gRPC에 대&quot; data-og-host=&quot;chacha95.github.io&quot; data-og-source-url=&quot;https://chacha95.github.io/2020-06-15-gRPC1/&quot; data-og-url=&quot;https://chacha95.github.io/2020-06-15-gRPC1/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Spb2j/hyRaG9VOJV/N41YJAMK2ADcvUWKkkKd6K/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/kA5Mi/hyRaCfkvRm/5cflqiPHpMPmSAybpV3Ub0/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/bou3i5/hyRayKMx7q/dZUbR08UK4jNldxKQ0kZTk/img.png?width=1321&amp;amp;height=747&amp;amp;face=0_0_1321_747&quot;&gt;&lt;a href=&quot;https://chacha95.github.io/2020-06-15-gRPC1/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://chacha95.github.io/2020-06-15-gRPC1/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Spb2j/hyRaG9VOJV/N41YJAMK2ADcvUWKkkKd6K/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/kA5Mi/hyRaCfkvRm/5cflqiPHpMPmSAybpV3Ub0/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/bou3i5/hyRayKMx7q/dZUbR08UK4jNldxKQ0kZTk/img.png?width=1321&amp;amp;height=747&amp;amp;face=0_0_1321_747');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;gRPC 1 - gRPC란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;배경지식 gRPC는 Google에서 개발한 RPC(Remote Procedure Call) 시스템입니다. 전송을 위해 TCP/IP 프로토콜과 HTTP 2.0 프로토콜을 사용하고 IDL(Interface Definition language)로 protocol buffer를 사용합니다. gRPC에 대&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;chacha95.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@jakeseo_me/RPC%EB%9E%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@jakeseo_me/RPC%EB%9E%80&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1672983963291&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;RPC란?&quot; data-og-description=&quot;분산 네트워크 컴퓨터 환경에서 프로그래밍을 쉽게 할 수 있는 방법을 찾다가...Client to Server 패턴Server를 켬Client는 Server에 데이터 혹은 행동을 요청Server는 요청 받은 내용에 대한 응답을 반환Clie&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@jakeseo_me/RPC%EB%9E%80&quot; data-og-url=&quot;https://velog.io/@jakeseo_me/RPC란&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/BzFr6/hyRbD6jk0S/ZRoqu81pCBRyKQADwFVpjK/img.png?width=791&amp;amp;height=631&amp;amp;face=0_0_791_631,https://scrap.kakaocdn.net/dn/glXYo/hyRbABLkN2/NCsbrT9sKKwE6wIKOMBVA0/img.png?width=791&amp;amp;height=631&amp;amp;face=0_0_791_631,https://scrap.kakaocdn.net/dn/s3at7/hyRbHOqZvi/FskEiJPpb59xqzJCnGHau1/img.jpg?width=1280&amp;amp;height=960&amp;amp;face=0_0_1280_960&quot;&gt;&lt;a href=&quot;https://velog.io/@jakeseo_me/RPC%EB%9E%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@jakeseo_me/RPC%EB%9E%80&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/BzFr6/hyRbD6jk0S/ZRoqu81pCBRyKQADwFVpjK/img.png?width=791&amp;amp;height=631&amp;amp;face=0_0_791_631,https://scrap.kakaocdn.net/dn/glXYo/hyRbABLkN2/NCsbrT9sKKwE6wIKOMBVA0/img.png?width=791&amp;amp;height=631&amp;amp;face=0_0_791_631,https://scrap.kakaocdn.net/dn/s3at7/hyRbHOqZvi/FskEiJPpb59xqzJCnGHau1/img.jpg?width=1280&amp;amp;height=960&amp;amp;face=0_0_1280_960');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;RPC란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;분산 네트워크 컴퓨터 환경에서 프로그래밍을 쉽게 할 수 있는 방법을 찾다가...Client to Server 패턴Server를 켬Client는 Server에 데이터 혹은 행동을 요청Server는 요청 받은 내용에 대한 응답을 반환Clie&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ssungkang.tistory.com/entry/WEB-google%EC%9D%B4-%EB%A7%8C%EB%93%A0-RPC-gRPC%EB%9E%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ssungkang.tistory.com/entry/WEB-google%EC%9D%B4-%EB%A7%8C%EB%93%A0-RPC-gRPC%EB%9E%80&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1673084901810&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[WEB] google이 만든 RPC, gRPC란&quot; data-og-description=&quot;gRPC란 gRPC는 구글에서 개발한 어디서나 실행할 수 있는 오픈소스 고성능 RPC 프레임워크입니다. RPC는 Remote Procedure Call의 줄임말로 원격 프로시저 호출이라고 합니다. 이는 별도의 원격제어를 위&quot; data-og-host=&quot;ssungkang.tistory.com&quot; data-og-source-url=&quot;https://ssungkang.tistory.com/entry/WEB-google%EC%9D%B4-%EB%A7%8C%EB%93%A0-RPC-gRPC%EB%9E%80&quot; data-og-url=&quot;https://ssungkang.tistory.com/entry/WEB-google%EC%9D%B4-%EB%A7%8C%EB%93%A0-RPC-gRPC%EB%9E%80&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bO3esT/hyRcN8LbHa/KSQ0ecdzThjC1mtfuOmmEk/img.jpg?width=386&amp;amp;height=309&amp;amp;face=0_0_386_309,https://scrap.kakaocdn.net/dn/VjePB/hyRczCGaHe/PqJaFnEja3eIsrZEsE3Mp1/img.jpg?width=386&amp;amp;height=309&amp;amp;face=0_0_386_309,https://scrap.kakaocdn.net/dn/hmUPr/hyRbD7FhoP/Pak8i3dhiskuUVRNPLsg1K/img.jpg?width=1052&amp;amp;height=1248&amp;amp;face=267_380_686_838&quot;&gt;&lt;a href=&quot;https://ssungkang.tistory.com/entry/WEB-google%EC%9D%B4-%EB%A7%8C%EB%93%A0-RPC-gRPC%EB%9E%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ssungkang.tistory.com/entry/WEB-google%EC%9D%B4-%EB%A7%8C%EB%93%A0-RPC-gRPC%EB%9E%80&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bO3esT/hyRcN8LbHa/KSQ0ecdzThjC1mtfuOmmEk/img.jpg?width=386&amp;amp;height=309&amp;amp;face=0_0_386_309,https://scrap.kakaocdn.net/dn/VjePB/hyRczCGaHe/PqJaFnEja3eIsrZEsE3Mp1/img.jpg?width=386&amp;amp;height=309&amp;amp;face=0_0_386_309,https://scrap.kakaocdn.net/dn/hmUPr/hyRbD7FhoP/Pak8i3dhiskuUVRNPLsg1K/img.jpg?width=1052&amp;amp;height=1248&amp;amp;face=267_380_686_838');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[WEB] google이 만든 RPC, gRPC란&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;gRPC란 gRPC는 구글에서 개발한 어디서나 실행할 수 있는 오픈소스 고성능 RPC 프레임워크입니다. RPC는 Remote Procedure Call의 줄임말로 원격 프로시저 호출이라고 합니다. 이는 별도의 원격제어를 위&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ssungkang.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Server</category>
      <category>gRPC</category>
      <category>IPC</category>
      <category>Rest</category>
      <category>rpc</category>
      <author>개발개굴 </author>
      <guid isPermaLink="true">https://j-su2.tistory.com/135</guid>
      <comments>https://j-su2.tistory.com/135#entry135comment</comments>
      <pubDate>Sat, 7 Jan 2023 18:57:35 +0900</pubDate>
    </item>
    <item>
      <title>[네트워크] TCP/IP 4계층</title>
      <link>https://j-su2.tistory.com/134</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;TCP/IP(Transmission Control Protocal / Internet Protocal)란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 수많은 프로그램들이 인터넷으로 통신하는데 있어 가장 기반이 되는 프로토콜로 실제 대다수 프로그램은 TCP와 IP로 통신하고 있습니다. 즉, 인터넷을 통해 데이터를 보낼 때 주로 TCP와 IP를 이용해서 보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 상황에서 데이터을 보낼 때 올바르게 데이터를 전송하기 위해 TCP/IP 4계층을 통해 각 계층마다 책임이 부여되어 계층을 따라서 데이터가 보내지게 됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;OSI 7계층 VS TCP/IP 4계층&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #006dd7;&quot;&gt;OSI 7계층&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워크 통신이 일어나는 과정을 7단계로 나눈 것&lt;/li&gt;
&lt;li&gt;국제표준화기구(ISO)에서 네트워트 간의 호환을 위해서 만든 개방형 시스템 상호 연결 모델의 표준인 네트워크 모델&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;TCP/IP 4계층&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실제로 사용되는 TCP/IP는 OSI 참조 모델을 기반으로 상업적이고 실무적으로 이용될 수 있도록 단순화된 모형&lt;/li&gt;
&lt;li&gt;OSI 7계층을 4계층으로 분류하여 적용한 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;882&quot; data-origin-height=&quot;592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcr2uP/btrQb3UrkOz/0x4WB0rZwrTcZXLpoVv0EK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcr2uP/btrQb3UrkOz/0x4WB0rZwrTcZXLpoVv0EK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcr2uP/btrQb3UrkOz/0x4WB0rZwrTcZXLpoVv0EK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbcr2uP%2FbtrQb3UrkOz%2F0x4WB0rZwrTcZXLpoVv0EK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;771&quot; height=&quot;517&quot; data-origin-width=&quot;882&quot; data-origin-height=&quot;592&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;*OSI 7계층에 대한 내용은 아래 블로그를 참고하세요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://j-su2.tistory.com/7&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://j-su2.tistory.com/7&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667462351911&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[네트워크] OSI 7 계층&quot; data-og-description=&quot;OSI 7 계층이란? 네트워크 통신이 일어나는 과정을 7단계로 나눈 것으로, 국제표준화기구(ISO)에서 네트워트 간의 호환을 위해서 만든 개방형 시스템 상호 연결 모델의 표준인 네트워크 모델 실제 &quot; data-og-host=&quot;j-su2.tistory.com&quot; data-og-source-url=&quot;https://j-su2.tistory.com/7&quot; data-og-url=&quot;https://j-su2.tistory.com/7&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fGnPD/hyQqTJOYOX/iCdxjQpOWsCxjMcxaJRVI1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/KuDuP/hyQqWT5kEf/i36PwYKruBxpeJ0lKXZtCK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://j-su2.tistory.com/7&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://j-su2.tistory.com/7&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fGnPD/hyQqTJOYOX/iCdxjQpOWsCxjMcxaJRVI1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/KuDuP/hyQqWT5kEf/i36PwYKruBxpeJ0lKXZtCK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[네트워크] OSI 7 계층&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;OSI 7 계층이란? 네트워크 통신이 일어나는 과정을 7단계로 나눈 것으로, 국제표준화기구(ISO)에서 네트워트 간의 호환을 위해서 만든 개방형 시스템 상호 연결 모델의 표준인 네트워크 모델 실제&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;j-su2.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;TCP/IP 4계층&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP/IP 4계층은 장치들이 인터넷 상에서 데이터를 주고받을 때 쓰는 독립적인 프로토콜의 집합을 의미합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Application(응용): SMTP, HTTP/HTTPS, FTP, SSH&lt;/li&gt;
&lt;li&gt;Transport(전송): UDP, TCP&lt;/li&gt;
&lt;li&gt;Internet(인터넷): IPv4/IPv6, ICMP, ARP&lt;/li&gt;
&lt;li&gt;Network Access(네트워크 엑세스)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 계층을 간단하게 설명하기 앞서 TCP/IP 4계층에서 사용되는 용어들을 알아보겠습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 378px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 22.0931%; height: 21px;&quot;&gt;용어&lt;/td&gt;
&lt;td style=&quot;width: 77.9069%; height: 21px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 117px;&quot;&gt;
&lt;td style=&quot;width: 22.0931%; height: 117px; text-align: center;&quot;&gt;&lt;b&gt;캡슐화&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.9069%; height: 117px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;송신자가 수신자에게 데이터를 보낼 때 데이터가 각 계층을 지나며 각 계층의 특징들이 담긴 헤더들이 붙여지는 과정&lt;/li&gt;
&lt;li&gt;전송계층의 TCP 헤더, 네트워크 계층의 IP 주소 헤더&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 63px;&quot;&gt;
&lt;td style=&quot;width: 22.0931%; height: 63px; text-align: center;&quot;&gt;&lt;b&gt;비캡슐화&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.9069%; height: 63px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;수신자측에서 캡슐화된 데이터를 역순으로 제거하면서 응용계층까지 도달하는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 177px;&quot;&gt;
&lt;td style=&quot;width: 22.0931%; height: 177px; text-align: center;&quot;&gt;&lt;b&gt;PDU(protocal data unit)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.9069%; height: 177px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TCP/IP 4계층을 기반으로 각 계층의 데이터 단위&lt;/li&gt;
&lt;li&gt;응용: 메시지&lt;/li&gt;
&lt;li&gt;전송: 세그먼트(TCP), 데이터그램(UDP)&lt;/li&gt;
&lt;li&gt;인터넷: 패킷&lt;/li&gt;
&lt;li&gt;네트워크 엑세스: 프레임(데이터 링크), 비트(물리)&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Application 계층&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP, SMTP, FTP, SSH가 대표적이며 웹 서비스, 이메일 등 서비스를 실질적으로 사람들에게 제공하는 층입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;HTTP(Hypertext Transfer Protocal)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버와 브라우저간에 데이터를 주고 받기 위해 설계된 프로토콜&lt;/li&gt;
&lt;li&gt;지금은 브라우저 뿐만 아니라 서버와 서버간의 통신할 때도 많이 이용&lt;/li&gt;
&lt;li&gt;헤더를 통한 확장이 쉬움(다른 값 추가 쉬움)&lt;/li&gt;
&lt;li&gt;stateless함(연속적인 상태 값 X)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;SSH(Secure SHhell Protocal)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;보안되지 않은 네트워크에서 네트워크 서비스를 안전하게 운영하기 위한 암호화 네트워크 프로토콜&lt;/li&gt;
&lt;li&gt;AWS EC2 접근: ssh &amp;lt;pem&amp;gt; &amp;lt;user&amp;gt;@&amp;lt;serverIP&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;FTP(File Transfer Protocal)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;노드와 노드간의 파일을 전송하는데 사용되는 프로토콜&lt;/li&gt;
&lt;li&gt;지금은 파일을 암호화해서 전송하는 FTPS, SFTP로 대체&lt;/li&gt;
&lt;li&gt;대표적으로 FileZilla라는 SW가 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;SMTP(Simple Mail Transfer Prototal)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터넷을 통해 메일을 보낼 때 사용되는 프로토콜&lt;/li&gt;
&lt;li&gt;보통 서비스를 운영하면 메일링 서비스를 하게 되는데 node.js를 통해 메일을 보낸다면 이를 통해 보내야함(Nodemailer)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;Tansport 계층&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP와 UDP가 대표적이며 응용 계층에서 받은 메시지를 기반으로 세그먼트 또는 데이터그램으로 데이터를 쪼개고 데이터가 오류없이 순서대로 전달되도록 도움을 주는 층입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;TCP&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가상회선 패킷 교환 방식: 순서대로 도착&lt;/li&gt;
&lt;li&gt;오류검사 매커니즘이 다양함
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;재전송: 시간 초과 하면 다시 전송&lt;/li&gt;
&lt;li&gt;체크섬: 무결성을 평가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;헤더는 20~60 바이트로 가변적&lt;/li&gt;
&lt;li&gt;연결 보장 -&amp;gt; 3웨이-핸드셰이크, 4웨이-핸드셰이크&lt;/li&gt;
&lt;li&gt;브로드캐스트 지원X&lt;/li&gt;
&lt;li&gt;느림&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;UDP&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터그램 패킷 교환 방식: 순서 보장 X&lt;/li&gt;
&lt;li&gt;오류검사는 단순한 체크섬만 지원&lt;/li&gt;
&lt;li&gt;32비트(8바이트)로 고정길이&lt;/li&gt;
&lt;li&gt;연결 보장X -&amp;gt; 그냥 데이터 보내서 유지/해제 비용 X&lt;/li&gt;
&lt;li&gt;브로드캐스트 지원O&lt;/li&gt;
&lt;li&gt;빠름&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;Internet 계층&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IP, ICMP, ARP가 대표적이며 한 노드에서 다른 노드로 전송 계층에서 받은 세그먼트 또는 데이터그램을 패킷화 하여 목적지로 전송하는 계층입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;ICMP(Internet Control Message Protocal)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;노드와 노드 사이에서 통신이 잘되나를 확인할 때 쓰는 프로토콜 (데이터를 교환하는데 사용되지 않는 프로토콜)&lt;/li&gt;
&lt;li&gt;일반적으로 테스팅에 사용됨&lt;/li&gt;
&lt;li&gt;독립적인 비연결형 프로토콜&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;Network Access 계층&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;링크 계층이라고도 불리며 전선, 광섬유, 무선 등으로 데이터가 네트워크를 통해 물리적으로 전송되는 방식을 정의하는 계층입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[참고]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%A9%B4%EC%A0%91-cs-%ED%8A%B9%EA%B0%95/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%A9%B4%EC%A0%91-cs-%ED%8A%B9%EA%B0%95/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667462268902&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;CS지식의 정석 | CS면접 디자인패턴 네트워크 운영체제 데이터베이스 자료구조 개발자면접 - 인프&quot; data-og-description=&quot;국내 1위 &amp;quot;면접을 위한 CS전공지식노트&amp;quot; 저자의 디자인패턴, 네트워크, 운영체제, 데이터베이스 등 CS지식 강의! CS면접에 필요한 모든 개념과 최신 기출을 다룬다!, - 강의 소개 | 인프런...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%A9%B4%EC%A0%91-cs-%ED%8A%B9%EA%B0%95/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%A9%B4%EC%A0%91-cs-%ED%8A%B9%EA%B0%95&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bmzVic/hyQqYj1OZM/SmxhoX5tywb1Lq5ZDm97vk/img.jpg?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/boDwcv/hyQqNpg8L1/lmw0OixJ9upNEEkYWJkPkK/img.jpg?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/bc5xgU/hyQshI3GMK/blEzxUdBe9K9UqUNn9zId0/img.jpg?width=1831&amp;amp;height=810&amp;amp;face=0_0_1831_810&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%A9%B4%EC%A0%91-cs-%ED%8A%B9%EA%B0%95/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%A9%B4%EC%A0%91-cs-%ED%8A%B9%EA%B0%95/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bmzVic/hyQqYj1OZM/SmxhoX5tywb1Lq5ZDm97vk/img.jpg?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/boDwcv/hyQqNpg8L1/lmw0OixJ9upNEEkYWJkPkK/img.jpg?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/bc5xgU/hyQshI3GMK/blEzxUdBe9K9UqUNn9zId0/img.jpg?width=1831&amp;amp;height=810&amp;amp;face=0_0_1831_810');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;CS지식의 정석 | CS면접 디자인패턴 네트워크 운영체제 데이터베이스 자료구조 개발자면접 - 인프&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;국내 1위 &quot;면접을 위한 CS전공지식노트&quot; 저자의 디자인패턴, 네트워크, 운영체제, 데이터베이스 등 CS지식 강의! CS면접에 필요한 모든 개념과 최신 기출을 다룬다!, - 강의 소개 | 인프런...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hahahoho5915.tistory.com/15&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://hahahoho5915.tistory.com/15&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667462284326&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;TCP/IP 4계층(TCP/IP 4 Layer)&quot; data-og-description=&quot;TCP/IP (Transmission Control Protocol / Internet Protocol)현재 수많은 프로그램들이 인터넷으로 통신하는데 있어 가장 기반이 되는 프로토콜로 실제 대다수 프로그램은 TCP와 IP로 통신하고 있다. ARPANET이 개&quot; data-og-host=&quot;hahahoho5915.tistory.com&quot; data-og-source-url=&quot;https://hahahoho5915.tistory.com/15&quot; data-og-url=&quot;https://hahahoho5915.tistory.com/15&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ckEibl/hyQshbdzxw/zXDCT7oVKwq1q8BDRmvbVK/img.png?width=800&amp;amp;height=449&amp;amp;face=0_0_800_449,https://scrap.kakaocdn.net/dn/ulXoY/hyQqJf7HFI/wNyxyyMmeQp5gG29pqDOdK/img.png?width=800&amp;amp;height=449&amp;amp;face=0_0_800_449,https://scrap.kakaocdn.net/dn/16c4Y/hyQsdfAq9U/R9UcPeg8vHMTOEHbPOb3xK/img.png?width=830&amp;amp;height=466&amp;amp;face=0_0_830_466&quot;&gt;&lt;a href=&quot;https://hahahoho5915.tistory.com/15&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hahahoho5915.tistory.com/15&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ckEibl/hyQshbdzxw/zXDCT7oVKwq1q8BDRmvbVK/img.png?width=800&amp;amp;height=449&amp;amp;face=0_0_800_449,https://scrap.kakaocdn.net/dn/ulXoY/hyQqJf7HFI/wNyxyyMmeQp5gG29pqDOdK/img.png?width=800&amp;amp;height=449&amp;amp;face=0_0_800_449,https://scrap.kakaocdn.net/dn/16c4Y/hyQsdfAq9U/R9UcPeg8vHMTOEHbPOb3xK/img.png?width=830&amp;amp;height=466&amp;amp;face=0_0_830_466');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;TCP/IP 4계층(TCP/IP 4 Layer)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;TCP/IP (Transmission Control Protocol / Internet Protocol)현재 수많은 프로그램들이 인터넷으로 통신하는데 있어 가장 기반이 되는 프로토콜로 실제 대다수 프로그램은 TCP와 IP로 통신하고 있다. ARPANET이 개&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hahahoho5915.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@jehjong/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%9D%B8%ED%84%B0%EB%B7%B0-TCPIP-4%EA%B3%84%EC%B8%B5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@jehjong/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%9D%B8%ED%84%B0%EB%B7%B0-TCPIP-4%EA%B3%84%EC%B8%B5&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667462292059&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[개발자 인터뷰] TCP/IP 4계층&quot; data-og-description=&quot;계층 모형TCP/IP 모형은 현재의 인터넷에서 컴퓨터들이 서로 정보를 주고받는데 쓰이는 통신규약(프로토콜)의 모음으로 각 계층은 담당하는 위치마다 처리 역할을 구분해 진행함으로 서로 간의 &quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@jehjong/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%9D%B8%ED%84%B0%EB%B7%B0-TCPIP-4%EA%B3%84%EC%B8%B5&quot; data-og-url=&quot;https://velog.io/@jehjong/개발자-인터뷰-TCPIP-4계층&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mUv4Z/hyQqOhqbZr/AH8f3QfpEuptwrtt3rvTS1/img.png?width=818&amp;amp;height=546&amp;amp;face=0_0_818_546,https://scrap.kakaocdn.net/dn/vvVmM/hyQscOwqCf/ztYMixETDZ0mTPDi059dm1/img.png?width=818&amp;amp;height=546&amp;amp;face=0_0_818_546,https://scrap.kakaocdn.net/dn/bKvjoT/hyQsf5x9Zb/Ku1DD1yS1qLTLP6ddyMjP1/img.png?width=818&amp;amp;height=546&amp;amp;face=0_0_818_546&quot;&gt;&lt;a href=&quot;https://velog.io/@jehjong/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%9D%B8%ED%84%B0%EB%B7%B0-TCPIP-4%EA%B3%84%EC%B8%B5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@jehjong/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%9D%B8%ED%84%B0%EB%B7%B0-TCPIP-4%EA%B3%84%EC%B8%B5&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mUv4Z/hyQqOhqbZr/AH8f3QfpEuptwrtt3rvTS1/img.png?width=818&amp;amp;height=546&amp;amp;face=0_0_818_546,https://scrap.kakaocdn.net/dn/vvVmM/hyQscOwqCf/ztYMixETDZ0mTPDi059dm1/img.png?width=818&amp;amp;height=546&amp;amp;face=0_0_818_546,https://scrap.kakaocdn.net/dn/bKvjoT/hyQsf5x9Zb/Ku1DD1yS1qLTLP6ddyMjP1/img.png?width=818&amp;amp;height=546&amp;amp;face=0_0_818_546');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[개발자 인터뷰] TCP/IP 4계층&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;계층 모형TCP/IP 모형은 현재의 인터넷에서 컴퓨터들이 서로 정보를 주고받는데 쓰이는 통신규약(프로토콜)의 모음으로 각 계층은 담당하는 위치마다 처리 역할을 구분해 진행함으로 서로 간의&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CS/Network</category>
      <category>OSI 7계층</category>
      <category>TCP/IP 4계층</category>
      <category>네트워크</category>
      <author>개발개굴 </author>
      <guid isPermaLink="true">https://j-su2.tistory.com/134</guid>
      <comments>https://j-su2.tistory.com/134#entry134comment</comments>
      <pubDate>Thu, 3 Nov 2022 16:59:20 +0900</pubDate>
    </item>
  </channel>
</rss>