<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>내 두 번째 뇌</title>
    <link>https://second-brain.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Mon, 9 Mar 2026 17:28:11 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>뇌주인</managingEditor>
    <item>
      <title>벨로그로 이전!</title>
      <link>https://second-brain.tistory.com/60</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;현재 벨로그에 계속 글들을 포스팅하고 있으니, 많이 찾아와 주시면 감사하겠습니다,&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@twodf78/posts&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@twodf78/posts&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1754673645650&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;twodf78 (내 두 번째 뇌) / 작성글 - velog&quot; data-og-description=&quot;&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@twodf78/posts&quot; data-og-url=&quot;https://velog.io/@twodf78/posts&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://velog.io/@twodf78/posts&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@twodf78/posts&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;twodf78 (내 두 번째 뇌) / 작성글 - velog&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;br /&gt;기존보다 더욱 복잡한 문제들을 해결하는 과정을 더욱 직관적으로 설명드릴 수 있게 노력하고 있습니다!&lt;br /&gt;백엔드 개발을 희망하시거나, 현업분들께 조금이나마 도움이 되셨으면 좋겠습니다!&lt;br /&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;br /&gt;&lt;br /&gt;나중에 기회되면 벨로그에만 새로 쓴 글들도 정리해서 티스토리에도 올려보도록 하겠습니다!&lt;/p&gt;</description>
      <category>개발 공부</category>
      <category>벨로그</category>
      <category>블로그 이전</category>
      <author>뇌주인</author>
      <guid isPermaLink="true">https://second-brain.tistory.com/60</guid>
      <comments>https://second-brain.tistory.com/60#entry60comment</comments>
      <pubDate>Sat, 9 Aug 2025 02:25:39 +0900</pubDate>
    </item>
    <item>
      <title>Spring Boot: JPA 적용기 - entity 구현</title>
      <link>https://second-brain.tistory.com/58</link>
      <description>&lt;h1&gt;#0. 개요&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 mybatis 로 되어있는 코드를 JPA 로 점진적 변환
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;간단한 CRUD 등 코드에 너무 많은 시간 소요하지 않기 위함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;JDBC (Java Database Connectivity)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DB에 접근하기 위한 자바 표준 인터페이스&lt;/li&gt;
&lt;li&gt;복잡함. 예외처리, connection 사용 후 반환을 개발자가 직접해야함&lt;/li&gt;
&lt;li&gt;SQL mapper, ORM 은 위 과정들을 추상화시켜 제공하는 방식.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SQL mapper
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체와 SQL 문 질의 결과를 매핑.&lt;/li&gt;
&lt;li&gt;SQL 문을 직접 작성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ORM
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체와 RDB 데이터 매핑&lt;/li&gt;
&lt;li&gt;JPA
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ORM 기술에 대한 표준 API&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;개발자의 SQL 중심 개발 &amp;rarr; 객체 중심 개발&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;JPQL (java persistence query language)
&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;hibernate
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JPA의 구현체&lt;/li&gt;
&lt;li&gt;JPA 자체는 인터페이스와 같다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;#1. entity 작성&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@Table(name = &quot;테이블 명&quot;, schema = &quot;##schema##&quot;)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스키마는 멀티테넌트이기에, token 에 따라 다르게끔 설정&lt;/li&gt;
&lt;li&gt;entity 마다 테이블명 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 기본 컬럼&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@Comment
&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;@Column
&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;length
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본값 255로 되어있음&lt;/li&gt;
&lt;li&gt;varchar 등의 길이 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;precision
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;numeric 앞자리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;scale
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;numeric 뒷자리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) PK&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@Id
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PK 인 거를 명시&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;@GeneratedValue(strategy = GenerationType.*IDENTITY*)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;autoIncrement PK 보장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3) 조인컬럼&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@JoinColumn
&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;/ul&gt;
&lt;/li&gt;
&lt;li&gt;여기는 조인이 되는 객체가 FK의 주인 객체
&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;FK를 가지고 있는 쪽에서 명시
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@ManyToOne 이랑 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;@OneToOne
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1대1 관계&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;@ManyToOne
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;FK 를 가지고 있는 쪽&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;@OneToMany
&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;얘를 FK로 참조하고 있는 entity 의 리스트를 가지고 있음
&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;양쪽으로 가고 싶을 때 추가
&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;여기나 @OneToOne 쪽에만 mappedBy를 쓸 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;위 조인 컬럼에서 사용할 수 있는 옵션&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;mappedBy
&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주인 쪽은 mappedBy 지정 X&lt;/li&gt;
&lt;/ul&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;주인 아닌 쪽이 mappedBy 로 주인 지정&lt;/li&gt;
&lt;/ul&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;/li&gt;
&lt;li&gt;FK를 참조 당하는 쪽에서의 세팅&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;optional- 연관 관계의 필수 여부
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;false
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;inner join&lt;/li&gt;
&lt;li&gt;관계가 반드시 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;true - 기본값
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;outer join&lt;/li&gt;
&lt;li&gt;관계가 선택적인지를 지정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;fetch- 연관 관계의 대상을 가져올 때 어떻게 가져올 지
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;FetchType.LAZY (지연로딩)
&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;모든 연관관계는 우선 이걸로 적용 (fetch join)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;FetchType.FETCH
&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;/li&gt;
&lt;li&gt;cascade - 부모 엔티티에 대한 작업이 자식 엔티티에도 적용.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PERSIST: 부모 엔티티가 저장될 때, 자식 엔티티도 함께 저장.&lt;/li&gt;
&lt;li&gt;MERGE: 부모 엔티티가 병합될 때, 자식 엔티티도 함께 병합.&lt;/li&gt;
&lt;li&gt;REMOVE: 부모 엔티티가 삭제될 때, 자식 엔티티도 함께 삭제.&lt;/li&gt;
&lt;li&gt;REFRESH: 부모 엔티티가 새로고침될 때, 자식 엔티티도 함께 새로고침.&lt;/li&gt;
&lt;li&gt;DETACH: 부모 엔티티가 영속성 컨텍스트에서 분리될 때, 자식 엔티티도 함께 분리.&lt;/li&gt;
&lt;li&gt;ALL: 모든 작업이 자식 엔티티에 전파.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;orphanRemoval
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;true
&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;/li&gt;
&lt;li&gt;예시:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;@OneToMany(mappedBy = &quot;vbrItem&quot;, cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
@Builder.Default
private List&amp;lt;VbrSelItem&amp;gt; vbrSelItemList = new ArrayList&amp;lt;&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;insertable
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 필드가 INSERT SQL 문에 포함될 지 여부 지정&lt;/li&gt;
&lt;li&gt;true&lt;/li&gt;
&lt;li&gt;false&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;updatable
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 필드가 UPDATE SQL 문에 포함될 지 여부 지정&lt;/li&gt;
&lt;li&gt;true&lt;/li&gt;
&lt;li&gt;false&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;만약 조인 컬럼과 FK 컬럼을 따로 entity 에서 구현할 경우, 한 쪽은 위 두 옵션을 false 로 설정해야함.&lt;/li&gt;
&lt;li&gt;예시:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = &quot;tmplt_sectn_sbt_id&quot;, insertable = false, updatable = false)
private VtmTmpltSectn vtmTmpltSectn;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4) 양방향 관계&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://colevelup.tistory.com/41&quot;&gt;https://colevelup.tistory.com/41&lt;/a&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;연결되는 각 객체에서, 서로로 향하는 단방향 관계 2개라고 보는 것이 타당.&lt;/li&gt;
&lt;li&gt;1대1인 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@OneToOne 2개&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1대다 인 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@ManyToOne
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;FK를 가지는 쪽&lt;/li&gt;
&lt;li&gt;Fetch 전략 등 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;@OneToMany
&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;mappedBy를 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;객체의 단방향 관계
&lt;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;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;메모리 사용량 저하&lt;/li&gt;
&lt;li&gt;성능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;entity 작성 과정:
1. 테이블과 똑같이 속성 구현 (column, comment, length 설정)
2. FK를 가지는 쪽 테이블에서 ManyToOne 컬럼 설정.
	2-1. FK의 주인 테이블의 엔티티 타입으로 속성추가
	2-2. cascade, fetch, optional 전략 설정
	2-3. JoinColumn 어노테이션 추가하여 FK 명시
3. 기저 데이터 쪽에서 OneToMany 컬럼 설정.
	3-1. 만약 단방향 관계만 유지하고 싶으면 컬럼 설정 X
	3-2. mappedBy 로 연관관계 주인 컬럼 설정
	3-3. 연관관계 주인은 ManyToOne 컬럼이 걸린 속성명 (보통 OneToMany 속성의 클래스명과 동일)
	3-4. cascade, fetch, orpanRemoval 전략 설정
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Spring Boot/JPA</category>
      <category>Entity</category>
      <category>Java</category>
      <category>JPA</category>
      <category>springboot</category>
      <category>양방향관계</category>
      <author>뇌주인</author>
      <guid isPermaLink="true">https://second-brain.tistory.com/58</guid>
      <comments>https://second-brain.tistory.com/58#entry58comment</comments>
      <pubDate>Tue, 24 Sep 2024 21:10:11 +0900</pubDate>
    </item>
    <item>
      <title>Spring Boot: mongoDB &amp;rarr; PostgreSQL 마이그레이션: Conversing 이슈 해결</title>
      <link>https://second-brain.tistory.com/57</link>
      <description>&lt;h1&gt;#1. 개요&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;영업보고 기능을 Java Spring Boot - PostgreSQL 환경에서 구현 완료함.&lt;/li&gt;
&lt;li&gt;기존 내부적으로 서비스하던 Node / MongoDB 환경에서 구현 된 영업보고 기능 내의 데이터를 PostgreSQL 환경으로 마이그레이션을 진행해야함.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터가 너무 많아서, API 서버 상에서 데이터가 담긴 mongoDB 를 연결하여 PostgreSQL 로 로직을 통해 마이그레이션을 구현함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;그 과정 속에서 Conversion 이슈가 아래와 같이 발생했고, 해결함.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;#2. 문제 및 해결&lt;/h1&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;Exception : org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47)
&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;Conversion 이슈
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;mongodb 에서 넘어오는 데이터가 스키마랑 달리 안 맞는 이슈 존재.&lt;/li&gt;
&lt;li&gt;데이터 훑어본 결과, string 으로 명시된 데이터가 데이터 상에는 숫자로 저장 되는 경우가 존재.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;@Nullable
public static Object invokeConverter(GenericConverter converter, @Nullable Object source,
		TypeDescriptor sourceType, TypeDescriptor targetType) {

	try {
		return converter.convert(source, sourceType, targetType);
	}
	catch (ConversionFailedException ex) {
		throw ex;
	}
	catch (Throwable ex) {
		throw new ConversionFailedException(sourceType, targetType, source, ex);
	}
}
&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;위 라이브러리 코드에서 ConversionFailedException 오류 발생
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;즉 sourceType 과 targetType 이 안 맞아서 생기는 오류&lt;/li&gt;
&lt;li&gt;invokeConverter 메서드는 주어진 변환기(GenericConverter)를 통해 소스 데이터를 목표 타입으로 변환하려고 시도
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GenericConverter는 일반적으로 스프링 프레임워크에서 제공하는 인터페이스로, 커스텀 변환기 로직이 여기에 구현될 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;따라서 다 string 으로 받고, double 로 따로 전환을 해주는 것으로 변경.&lt;/li&gt;
&lt;li&gt;Converter 코드&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;@Component
public class NumberToStringConverter implements Converter&amp;lt;Object, String&amp;gt; {

	@Override
	public String convert(Object source) {
		if (source instanceof Number) {
			return String.valueOf(source);  // 숫자를 문자열로 변환
		}
		return source.toString();  // 이미 문자열인 경우 그대로 반환
	}
}

&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;MongoConfig 상 Converter 등록&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;aspectj&quot;&gt;&lt;code&gt;@Bean
public MongoCustomConversions customConversions() {
	return new MongoCustomConversions(List.of(new NumberToStringConverter()));
}
&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;string &amp;rarr; 숫자 변환 코드&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;processing&quot;&gt;&lt;code&gt;public static boolean isNumeric(String str) {
	return str != null &amp;amp;&amp;amp; str.matches(&quot;-?\\\\d+(\\\\.\\\\d+)?&quot;);
}

public static Double strToDouble(String strValue) {
	if (!isNumeric(strValue)) {
		return 0.0;
	}

	try {
		return new BigDecimal(strValue).doubleValue(); // 정확도 유지
	} catch (NumberFormatException ex) {
		return 0.0;
	}
}

public static BigDecimal strToBigDecimal(String strValue) {
	if (!isNumeric(strValue)) {
		return BigDecimal.ZERO; // null 대신 0을 반환하여 값이 사라지지 않도록 처리
	}

	try {
		return new BigDecimal(strValue); // 직접 BigDecimal로 변환
	} catch (NumberFormatException ex) {
		return BigDecimal.ZERO; // 변환 실패 시 0으로 대체
	}
}
&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 크기를 넘어가는 숫자들은 0으로 반환 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;디버깅을 해보니, string 으로 변경된 큰 숫자는 8.007441165E9 이런식의 string 값 처리가 됨. 그래서 bigDecimal 로 변경하는 과정에서 Numeric 으로 인식을 못함.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;큰 숫자들의 string 값을 isNumeric() 함수의 적용했을 때 숫자로 판단을 하지 않는 것이 원인.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;따라서 isNumeric 메서드를 아래와 같이 고쳐줌.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;processing&quot;&gt;&lt;code&gt;public static boolean isNumeric(String str) {
	return str != null &amp;amp;&amp;amp; str.matches(&quot;-?\\\\d+(\\\\.\\\\d+)?([eE]-?\\\\d+)?&quot;);
}

&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Spring Boot</category>
      <category>Java</category>
      <category>MongoDB</category>
      <category>postgresql</category>
      <category>springboot</category>
      <category>마이그레이션</category>
      <author>뇌주인</author>
      <guid isPermaLink="true">https://second-brain.tistory.com/57</guid>
      <comments>https://second-brain.tistory.com/57#entry57comment</comments>
      <pubDate>Tue, 24 Sep 2024 19:49:30 +0900</pubDate>
    </item>
    <item>
      <title>38일차 TIL: MOM(메시지 지향 미들웨어)</title>
      <link>https://second-brain.tistory.com/56</link>
      <description>&lt;h1&gt;#1. 오늘의 학습 키워드&lt;/h1&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MOM&lt;/b&gt;에 대해&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비동기 기반의 i/o 방식을 제공하는 Spring WebFlux 에 대해서 알아봤었다.
&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://second-brain.tistory.com/34&quot;&gt;https://second-brain.tistory.com/34&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;메시지 브로커로 RabbitMQ, Kafka 등 익히 들어본 기술이 떠오른다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;메시지 브로커에 대해서 알아보기 전에, 우선 메시지 지향 미들웨어 (MoM) 에 대해서 알아보자&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;#2. 공부한 내용&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. MOM&lt;/h2&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&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;Message Oriented Middleware
&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;메시지 기반의 비동기형 메시지를 전달하는 방식의 미들웨어
&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;메시지 전달 방식은 Queue, Broadcast, Multicast 등이 있다.&lt;/li&gt;
&lt;li&gt;MOM 은 크게 두가지로 구성된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Publisher
&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;Subscriber
&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;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 장점&lt;/h3&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;/ul&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;확장성
&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;유연성
&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;h3 data-ke-size=&quot;size23&quot;&gt;2) 단점&lt;/h3&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;/ul&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;MOM을 위한 별도의 인프라 및 유지보수 비용이 발생한다.&lt;/li&gt;
&lt;/ul&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;h3 data-ke-size=&quot;size23&quot;&gt;3) WebFlux 와 비교&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Spring WebFlux 는 웹 애플리케이션 서버 자체가 비동기 방식으로 작동하도록 지원을 한다면, MOM 은 어플리케이션 간의 데이터 교환을 비동기 방식으로 지원한다는 것에서 차이가 있다.
&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;즉, MOM 은 메시지 전송과 수신에 대한 구현을 모두 해야 한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;반면 Spring Webflux 는 비동기형 웹 서버 개발을 지원하므로, 요청에 대한 처리하는 측만 구현하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&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;a href=&quot;https://www.itworld.co.kr/news/107527&quot;&gt;https://www.itworld.co.kr/news/107527&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@spamdong/메세지-지향-미들웨어MOM&quot;&gt;https://velog.io/@spamdong/메세지-지향-미들웨어MOM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;#3. 오늘의 회고&lt;/h1&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;MOM 은 메시지 지향 미들웨어로서, 어플리케이션 간에 메시지를 안전하게 교환할 수 있도록 지원하는 기술이다.
&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;분산시스템인 MSA 구조에서 MOM 은 유용히 쓰일 수 있는 소프트웨어로 보여진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발 공부</category>
      <category>message-oriented middleware</category>
      <category>MOM</category>
      <category>MSA</category>
      <category>springwebflux</category>
      <category>webflux</category>
      <category>메시지지향미들웨어</category>
      <author>뇌주인</author>
      <guid isPermaLink="true">https://second-brain.tistory.com/56</guid>
      <comments>https://second-brain.tistory.com/56#entry56comment</comments>
      <pubDate>Sat, 11 May 2024 13:54:32 +0900</pubDate>
    </item>
    <item>
      <title>37일차 TIL: 디자인 패턴</title>
      <link>https://second-brain.tistory.com/55</link>
      <description>&lt;h1&gt;#1. 오늘의 학습 키워드&lt;/h1&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;디자인 패턴&lt;/b&gt;에 대해&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전에 아키텍처 패턴에 대해서 공부를 했었다.
&lt;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;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;디자인 패턴
&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;#2. 공부한 내용&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 디자인 패턴&lt;/h2&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&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;디자인 패턴은 객체 지향의 4대 특성과 설계 원칙 (SOLID) 를 기반으로 구현 되어있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체 지향 4대 특성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캡슐화 (encapsulation)
&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;상속 (inheritance)
&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;추상화 (abstraction)
&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;다형성 (polymorphism)
&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;/li&gt;
&lt;li&gt;SOLID
&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://second-brain.tistory.com/38&quot;&gt;https://second-brain.tistory.com/38&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SRP
&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;OCP
&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;LSP
&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;ISP
&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;DIP
&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;/li&gt;
&lt;/ul&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;디자인 패턴은 OOP 4대 원칙을 SOLID 를 기반하여 사용해서, 제작된 올바른 가이드라인 정도로 볼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) GoF&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;디자인 패턴 중에 유명한 GoF 디자인 패턴들이 있다.&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;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;빌더
&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;팩토리 메서드
&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;프로토타입
&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;싱글톤 패턴
&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;/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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;호환성 없는 클래스를 사용하기 위해 Wrapper를 제공하는 패턴&lt;/li&gt;
&lt;/ul&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;컴포지트
&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;데코레이터
&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;퍼사드
&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;플라이웨이트
&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;프록시
&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;/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;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;커맨드
&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;인터프리터
&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;반복자
&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;중재자
&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;메멘토
&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;옵저버
&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;상태
&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;전략
&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;템플릿 메서드
&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;방문자
&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;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&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;a href=&quot;https://www.itworld.co.kr/news/107527&quot;&gt;https://www.itworld.co.kr/news/107527&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://m.blog.naver.com/wook2124/222103003848&quot;&gt;https://m.blog.naver.com/wook2124/222103003848&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://m.blog.naver.com/wook2124/222103410288&quot;&gt;https://m.blog.naver.com/wook2124/222103410288&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발 공부</category>
      <category>GOF</category>
      <category>SOLID</category>
      <category>디자인패턴</category>
      <author>뇌주인</author>
      <guid isPermaLink="true">https://second-brain.tistory.com/55</guid>
      <comments>https://second-brain.tistory.com/55#entry55comment</comments>
      <pubDate>Fri, 10 May 2024 17:55:31 +0900</pubDate>
    </item>
    <item>
      <title>99클럽 36일차 TIL: jenkins</title>
      <link>https://second-brain.tistory.com/54</link>
      <description>&lt;h1&gt;#1. 오늘의 학습 키워드&lt;/h1&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;jenkins&lt;/b&gt;에 대해&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;저번 포스트 때 DevOps 와 CI, CD 등에 대한 개념에 대해 알아보았다.
&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://second-brain.tistory.com/53&quot;&gt;https://second-brain.tistory.com/53&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;CI
&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;CD
&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;CI/CD 는 개발자들의 새로 구현한 코드들이 사용자가 사용 가능한 서비스까지 전달하는 과정을 지속 가능한 상태와 자동화 된 과정으로 유지시키는 것이다.&lt;/li&gt;
&lt;/ul&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;jenkins&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;#2. 공부한 내용&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Jenkins&lt;/h2&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;- 배포, 테스트, 도커 빌드 등 CI/CD 환경을 구축하기 위한 간단한 방법을 제공한다.
&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;자바 Runtime에서 동작한다.&lt;/li&gt;
&lt;li&gt;빌드, 배포, 테스트, 도커 빌드, 암호화, 파이프라인 등 원래 각자 수행해야 돼서 복잡했던 작업들을 하나의 플러그인으로 모듈화 시켜서 Jenkins 하나로 CI / CD 환경을 구축하고, 자동화 시킬 수 있게 도와준다.&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;1400 가지 정도의 플러그인을 가지고 있고 이 플러그인을 아래와 같이 5가지 영역으로 나눌 수 있다.
&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;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;따라서 Jenkins 에서 CI / CD 측면은 Jenkins 가 제공할 수 있는 자동화 프로세스 중 한 가지일 뿐이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) Jenkins 파이프라인&lt;/h3&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;CI/ CD 파이프라인을 Jenkins 에 구현하기 위한 일련의 플러스인들의 집합 및 구성&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;Pipeline Syntax&lt;/li&gt;
&lt;li&gt;선언적이 더 쉽다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pipeline DSL ( Domain Specific Language ) 로 작성된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;파이프라인 Section 구성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Agent Section
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Jenkins는 많은 일을 해야하기 때문에, 여러 slave node를 생성하여 일을 할당 시킬 수 있다.&lt;/li&gt;
&lt;li&gt;node를 생성하는 것과 일을 할당하는 작업을 담당&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Post Section
&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;Stage Section 에서의 작업이 끝난 후의 결과에 따라서 Post Section에 작업이 실행됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Stage Section
&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;일련의 Stage를 정의하는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Steps Section
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;한 Stage 내의 단계로 일련의 스탭을 보여준다.&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;/li&gt;
&lt;li&gt;Pipeline &amp;rarr; Agent &amp;rarr; Stages &amp;rarr; steps 순으로 작업 세분화가 이뤄진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&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;a href=&quot;https://velog.io/@bbkyoo/Jenkins&quot;&gt;https://velog.io/@bbkyoo/Jenkins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.itworld.co.kr/news/107527&quot;&gt;https://www.itworld.co.kr/news/107527&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;#3. 오늘의 회고&lt;/h1&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;Jenkins 는 CI, CD를 지원하는 자동화 도구로 널리 사용된다.&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다양한 플러그인 제공 &amp;rarr; 다양한 개발환경, 툴 지원&lt;/li&gt;
&lt;/ul&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;개방성
&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;API 통신 가능하여, 다른 도구 및 시스템과 통합 용이.&lt;/li&gt;
&lt;/ul&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;Jenkins에 대한 지식은 널리 퍼져있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;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;Pipeline 구성을 위한 별도의 언어를 알아야한다.&lt;/li&gt;
&lt;/ul&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;Jenkins 는 서버 리소스를 많이 요구할 수 있다.&lt;/li&gt;
&lt;/ul&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발 공부</category>
      <category>99일지</category>
      <category>99클럽</category>
      <category>ci/cd</category>
      <category>jenkins</category>
      <category>til</category>
      <category>개발자스터디</category>
      <category>젠킨스</category>
      <category>코딩테스트</category>
      <category>파이프라인</category>
      <category>항해</category>
      <author>뇌주인</author>
      <guid isPermaLink="true">https://second-brain.tistory.com/54</guid>
      <comments>https://second-brain.tistory.com/54#entry54comment</comments>
      <pubDate>Thu, 9 May 2024 12:54:55 +0900</pubDate>
    </item>
    <item>
      <title>99클럽 35일차 TIL: DevOps</title>
      <link>https://second-brain.tistory.com/53</link>
      <description>&lt;h1&gt;#1. 오늘의 학습 키워드&lt;/h1&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DevOps&lt;/b&gt;에 대해&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개인 프로젝트 때 AWS Ec2 서비스를 사용하여 서버를 배포한 적이 있다.&lt;/li&gt;
&lt;li&gt;또한 현재 회사에서는 쿠버네티스를 사용하고 있다.&lt;/li&gt;
&lt;li&gt;코드는 github action 을 통해 배포를 하고 있다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;develop 브랜치에 머지 될 때마다 자동으로 dev 서버에 배포되는 방식&lt;/li&gt;
&lt;/ul&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;DevOps 에 대해 알아보자&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;#2. 공부한 내용&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. DevOps&lt;/h2&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&gt;- DevOps는 서비스를 빠른 속도로 제공할 수 있도록 도와주는 방식, 도구의 조합
&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;Development + Operation 의 약자.&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;개발팀과 운영팀이 DevOps 모델 하에서는 때로 단일팀으로 병합된다.
&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;일부 DevOps 모델에서는 품질 보증팀과 보안팀도 개발 운영과 긴밀하게 통합된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 중 팀이 보안에 초점을 두는 경우, DevSecOps로도 불린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;전 포스트 때 다뤘던 애자일 방법론과 지속적인 통합 (CI) 등 개념과도 관련이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 장점&lt;/h3&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;/ul&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;안정성
&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;확장
&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;협업 강화
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DevOps 모델 하에는 개발팀과 운영팀 간 긴말한 협력이 요구된다.&lt;/li&gt;
&lt;/ul&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;h3 data-ke-size=&quot;size23&quot;&gt;2) 방식&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CI
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Continuous Integration, 지속적인 통합&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;/li&gt;
&lt;li&gt;CD
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Continuous Delivery, 지속적인 전달&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;/li&gt;
&lt;li&gt;MSA
&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;a href=&quot;https://second-brain.tistory.com/43&quot;&gt;https://second-brain.tistory.com/43&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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 data-ke-style=&quot;style1&quot; /&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;a href=&quot;https://aws.amazon.com/ko/devops/what-is-devops/&quot;&gt;https://aws.amazon.com/ko/devops/what-is-devops/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://m.blog.naver.com/acornedu/221519913222&quot;&gt;https://m.blog.naver.com/acornedu/221519913222&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/ko/devops/continuous-delivery/&quot;&gt;https://aws.amazon.com/ko/devops/continuous-delivery/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;#3. 오늘의 회고&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DevOps 를 개념적으로 접근했을 때 알 수 있다시피, DevOps 엔지니어는 개발과 운영 둘 다 가능해야한다.
&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;소프트웨어 프로덕트 개발은 더 이상 비즈니스를 지원하는 것에 그치지 않고, 비즈니스 자체의 구성 요소가 되었다.
&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;DevOps 는 안정적이고 신속한 전달을 통해 고객의 니즈를 빠르게 충족시킬 수 있고, 따라서 요즘 DevOps 가 선택 받는 개발 및 인프라 관리 프로세스가 되겠다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발 공부</category>
      <category>99일지</category>
      <category>99클럽</category>
      <category>CD</category>
      <category>CI</category>
      <category>DevOps</category>
      <category>til</category>
      <category>개발자스터디</category>
      <category>코딩테스트</category>
      <category>항해</category>
      <author>뇌주인</author>
      <guid isPermaLink="true">https://second-brain.tistory.com/53</guid>
      <comments>https://second-brain.tistory.com/53#entry53comment</comments>
      <pubDate>Wed, 8 May 2024 17:04:51 +0900</pubDate>
    </item>
    <item>
      <title>99클럽 34일차 TIL: 개발 방법론 - Agile</title>
      <link>https://second-brain.tistory.com/52</link>
      <description>&lt;h1&gt;#1. 오늘의 학습 키워드&lt;/h1&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Agile&lt;/b&gt;에 대해&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개발 스타트업에서 일하다보면 자주 등장하는 용어들이 있다.
&lt;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;그중에서 현재 사용중인 개발 방법론인 Agile 애자일에 대해서는 한 번 정리를 하고 넘어가는 것이 좋겠다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;#2. 공부한 내용&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. &lt;b&gt;Agile&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&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;애자일 자체의 의미는 &amp;ldquo;민첩함, 기민함&amp;rdquo;
&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;일정한 주기를 반복하면서 개발 과정을 진행한다.
&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;절차와 도구보다 고객과의 상호작용에 초점을 맞춘 방법론&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 스크럼&lt;/h3&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;li&gt;보통 스크럼 팀은 아래와 같이 구성된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PO
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;product owner&lt;/li&gt;
&lt;li&gt;제품 책임자&lt;/li&gt;
&lt;li&gt;요구사항이 담긴 백로그를 작성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SM
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;scrum master&lt;/li&gt;
&lt;li&gt;스크럼 마스터&lt;/li&gt;
&lt;li&gt;스크럼 팀원을 주관하는 것이 아닌 데일리 스크럼 회의 주관하는 주체&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DT
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;devolopment team&lt;/li&gt;
&lt;li&gt;개발팀&lt;/li&gt;
&lt;li&gt;PO와 SM 제외 모든 팀원&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;스프린트
&lt;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;보통 2주에서 1달 정도이다.
&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;/li&gt;
&lt;li&gt;프로세스
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&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;li&gt;스프린트 회고&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) XP&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;eXtreme Programming 의 약자
&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;스크럼과 어떤 짧은 주기의 개발기간과 개발 내용을 반복적으로 수행하는 측면에서는 동일하다.
&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;차이는 아래와 같다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;XP가 좀 더 빠른 개발 주기를 가지고 있으며&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;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&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;a href=&quot;https://m.blog.naver.com/acornedu/221519913222&quot;&gt;https://m.blog.naver.com/acornedu/221519913222&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://m.blog.naver.com/wook2124/222102993732&quot;&gt;https://m.blog.naver.com/wook2124/222102993732&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.codestates.com/blog/content/애자일방법론-워터폴방법론&quot;&gt;https://www.codestates.com/blog/content/애자일방법론-워터폴방법론&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://brunch.co.kr/@haerrrrry/43&quot;&gt;https://brunch.co.kr/@haerrrrry/43&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://it-license.tistory.com/37&quot;&gt;https://it-license.tistory.com/37&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;#3. 오늘의 회고&lt;/h1&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;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;/ul&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;품질 향상
&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;협업 강화
&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;/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;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;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발 공부</category>
      <category>99일지</category>
      <category>99클럽</category>
      <category>Agile</category>
      <category>til</category>
      <category>XP</category>
      <category>개발방법론</category>
      <category>개발자스터디</category>
      <category>애자일</category>
      <category>코딩테스트</category>
      <category>항해</category>
      <author>뇌주인</author>
      <guid isPermaLink="true">https://second-brain.tistory.com/52</guid>
      <comments>https://second-brain.tistory.com/52#entry52comment</comments>
      <pubDate>Tue, 7 May 2024 17:38:48 +0900</pubDate>
    </item>
    <item>
      <title>99클럽 33일차 TIL: 클라이언트 사이드 캐시</title>
      <link>https://second-brain.tistory.com/51</link>
      <description>&lt;h1&gt;#1. 오늘의 학습 키워드&lt;/h1&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;클라이언트 사이드 캐시&lt;/b&gt; 에 대해&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;cache 의 종류와 redis 의 선정 및 CDN 의 개념의 대해 알아보았다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;cache 종류 비교 및 선정
&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://second-brain.tistory.com/9&quot;&gt;https://second-brain.tistory.com/9&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;redis 적용
&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://second-brain.tistory.com/10&quot;&gt;https://second-brain.tistory.com/10&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CDN
&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://second-brain.tistory.com/50&quot;&gt;https://second-brain.tistory.com/50&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이번 포스트에서는 다른 측면에서의 캐시인 클라이언트 사이드 캐시에 대해서 알아보자&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;#2. 공부한 내용&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 클라이언트 사이드 캐싱&lt;/h2&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&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;웹 페이지를 접근할 때, 서버 데이터의 서브셋을 클라이언트 측 로컬 디스크나 메모리에 저장을 한다.
&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;이때 데이터 서브셋 내 데이터들은 자주 접근하지만, 드물게 변경 되는 데이터 위주로 구성해야 성능을 많이 높일 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 클라이언트 사이드 캐싱 관련 HTTP 헤더&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클라이언트 측에서 캐싱을 수행할 수 있도록, 서버에서는 response HTTP 헤더에 여러 정보를 담아서 전송한다.&lt;/li&gt;
&lt;li&gt;Cache-Control
&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;Expires
&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;Last-Modified
&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;If-Modified-Since
&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;클라이언트는 Last-Modified 로 받은 정보를 해당 헤더에 넣어서 전송&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;서버는 해당 헤더내의 시간 정보와, 실제로 요청된 리소스의 최신화된 마지막 수정 시간을 비교하여 변경 여부를 판단&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ETag
&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;If-None-Math
&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;클라이언트는 ETag 로 받은 정보를 해당 헤더에 넣어서 전송&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;서버는 해당 헤더내의 정보와, 실제로 요청된 리소스의 최신화된 ETag값을 비교하여 변경 여부를 판단&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) 장점&lt;/h3&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;latency 가 줄어든다.&lt;/li&gt;
&lt;/ul&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;오프라인 지원
&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;h3 data-ke-size=&quot;size23&quot;&gt;3) 단점&lt;/h3&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;/ul&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 data-ke-style=&quot;style1&quot; /&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;a href=&quot;https://kim-gpt.tistory.com/entry/클라이언트-단-캐시-Client-side-Caching&quot;&gt;https://kim-gpt.tistory.com/entry/클라이언트-단-캐시-Client-side-Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/garimoo/클라이언트-사이드-캐싱-71a3ca7727ff&quot;&gt;https://medium.com/garimoo/클라이언트-사이드-캐싱-71a3ca7727ff&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;#3. 오늘의 회고&lt;/h1&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;그러나 빨라진 속도 만큼 tradeoff 로 고려할 것도 많아진다.
&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;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발 공부</category>
      <category>99일지</category>
      <category>99클럽</category>
      <category>cache</category>
      <category>client-side cache</category>
      <category>til</category>
      <category>개발자스터디</category>
      <category>캐시</category>
      <category>코딩테스트</category>
      <category>클라이언트사이드캐시</category>
      <category>항해</category>
      <author>뇌주인</author>
      <guid isPermaLink="true">https://second-brain.tistory.com/51</guid>
      <comments>https://second-brain.tistory.com/51#entry51comment</comments>
      <pubDate>Mon, 6 May 2024 12:34:40 +0900</pubDate>
    </item>
    <item>
      <title>99클럽 32일차 TIL: CDN</title>
      <link>https://second-brain.tistory.com/50</link>
      <description>&lt;h1&gt;#1. 오늘의 학습 키워드&lt;/h1&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CDN&lt;/b&gt; 에 대해&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전에 개발 중인 API 서버에 cache 를 도입하려 Spring 에서 사용 가능한 cache 종류들을 비교하고, 적용하는 글을 포스팅한 적이 있었다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;cache 종류 비교 및 선정
&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://second-brain.tistory.com/9&quot;&gt;https://second-brain.tistory.com/9&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;redis 적용
&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://second-brain.tistory.com/10&quot;&gt;https://second-brain.tistory.com/10&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;우선, CDN에 관해 알아보자&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;#2. 공부한 내용&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. CDN&lt;/h2&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&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;Contents Delivery Network의 약자
&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;즉 쉽게 말하면, 전세계 곳곳에 사용자가, 똑같은 서비스를 이용하기 위해 같은 위치에 있는 서버를 접근하는 것이 아니라, 각자에게 지리적 위치로 좀 더 가까운 서버로 접근하여 빠르게 컨텐츠를 전달 받기 위해 CDN 이 존재한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CDN은 전세계적으로 분산 된 네트워크다.&lt;/li&gt;
&lt;li&gt;본래 단일 서버에서 제공되는 컨텐츠들은, CDN 전체에 복제가 된다.
&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;해당 방식을 통해, CDN 은 클라이언트의 컨텐츠로의 접근 속도를 향상시킬 뿐만 아니라, 서버 측으로 몰리는 트래픽을 감소 시켜, 양측 모두에게 성능을 향상 시켜준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;실제로 우리는 CDN과 빈번히 상호 작용을 한다.&lt;/li&gt;
&lt;li&gt;그러나 원래 서버의 정보와 CDN 의 정보가 동일하여, 사용자로 하여금 자신의 요청이 원본 서버로 접근하는 지, CDN으로 접근하는 지 모르게 하려면 서버와 CDN 간 동기화 작업은 매번 일어나야된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) CDN 작동 방식&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;CDN 은 콘텐츠의 복제본을 여러 위치(PoP, Point Of Presence) 에 저장&lt;/li&gt;
&lt;li&gt;사용자는 지리적으로 가장 가까운 PoP 의 캐싱 서버로 요청.&lt;/li&gt;
&lt;li&gt;CDN은 웹 사이트의 페이지를 지리적으로 서로 다른 위치에 분산 되어있는 서버 네트워크에 복사하여, 페이지 컨텐츠를 캐싱한다.&lt;/li&gt;
&lt;li&gt;사용자는 CDN의 일부인 웹 페이지를 요청할 때, CDN은 원본 서버에서 사용자에 가장 지리적으로 가까운 CDN 의 서버로 요청을 보내고, 캐시된 컨텐츠를 사용자에게 전달.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) 장점&lt;/h3&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;/ul&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;보안 강화
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CDN은 보안 기능을 제공하여, 여러 보안 위협으로부터 웹 사이트를 보호할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&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;a href=&quot;https://www.phonesreview.co.uk/2017/09/01/content-delivery-network-cdn-works/&quot;&gt;https://www.phonesreview.co.uk/2017/09/01/content-delivery-network-cdn-works/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://akku-dev.tistory.com/21#google_vignette&quot;&gt;https://akku-dev.tistory.com/21#google_vignette&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.naver.com/wasgosu-2010/222235080499&quot;&gt;https://blog.naver.com/wasgosu-2010/222235080499&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;#3. 오늘의 회고&lt;/h1&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;CDN은 지리적 위치에 따라 사용자에게 더 빠르게 컨텐츠를 전달하기 위한 분산 서버 시스템이다.&lt;/li&gt;
&lt;li&gt;실생활에서 우리는 우리도 모른채 항상 CDN과 상호작용을 하고 있었다.&lt;/li&gt;
&lt;li&gt;그만큼 효과적으로 우리의 콘텐츠로의 빠른 접근의 니즈를 만족 시키는 우수한 캐싱 기법이라고 볼 수 있겠다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발 공부</category>
      <category>99일지</category>
      <category>99클럽</category>
      <category>cache</category>
      <category>CDN</category>
      <category>til</category>
      <category>개발자스터디</category>
      <category>캐시</category>
      <category>캐싱</category>
      <category>코딩테스트</category>
      <category>항해</category>
      <author>뇌주인</author>
      <guid isPermaLink="true">https://second-brain.tistory.com/50</guid>
      <comments>https://second-brain.tistory.com/50#entry50comment</comments>
      <pubDate>Sun, 5 May 2024 14:17:00 +0900</pubDate>
    </item>
  </channel>
</rss>