<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>구름</title>
    <link>https://cherishvert.tistory.com/</link>
    <description> 몰입하는 개발자  </description>
    <language>ko</language>
    <pubDate>Fri, 14 Aug 2026 16:22:37 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>lheunoia</managingEditor>
    <image>
      <title>구름</title>
      <url>https://tistory1.daumcdn.net/tistory/4431861/attach/3c1a6456514a4b179fb1c0c646312fcb</url>
      <link>https://cherishvert.tistory.com</link>
    </image>
    <item>
      <title>SSR VS CSR 차이점</title>
      <link>https://cherishvert.tistory.com/112</link>
      <description>&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-filename=&quot;스크린샷 2024-01-21 오후 7.14.18.png&quot; data-origin-width=&quot;1340&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnBSka/btsDJkT271U/AmApk9hLoEXzshyPMq7kwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnBSka/btsDJkT271U/AmApk9hLoEXzshyPMq7kwk/img.png&quot; data-alt=&quot;SSR vs CSR&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnBSka/btsDJkT271U/AmApk9hLoEXzshyPMq7kwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnBSka%2FbtsDJkT271U%2FAmApk9hLoEXzshyPMq7kwk%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;1340&quot; height=&quot;520&quot; data-filename=&quot;스크린샷 2024-01-21 오후 7.14.18.png&quot; data-origin-width=&quot;1340&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSR vs CSR&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;br /&gt;&lt;br /&gt;&lt;br /&gt;안녕하세요 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 &lt;b&gt;SSR&lt;/b&gt;(Server Side Rendering)과 &lt;b&gt;CSR&lt;/b&gt;(Client Side Rendering)의 차이점에 대해 알아 보겠습니다.  &lt;br /&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  SSR (Server Side Rendering)&lt;br /&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-21 오후 7.12.04.png&quot; data-origin-width=&quot;1472&quot; data-origin-height=&quot;664&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Rlyzu/btsDLsQ4j3V/7NyDi3v5QbeDdCTWRSIq61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Rlyzu/btsDLsQ4j3V/7NyDi3v5QbeDdCTWRSIq61/img.png&quot; data-alt=&quot;SSR&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Rlyzu/btsDLsQ4j3V/7NyDi3v5QbeDdCTWRSIq61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRlyzu%2FbtsDLsQ4j3V%2F7NyDi3v5QbeDdCTWRSIq61%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;710&quot; height=&quot;320&quot; data-filename=&quot;스크린샷 2024-01-21 오후 7.12.04.png&quot; data-origin-width=&quot;1472&quot; data-origin-height=&quot;664&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSR&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;서버 사이드 렌더링(SSR)이란, UI  로직이 담긴 &lt;span class=&quot;half-line-yellow&quot;&gt;HTML 파일을 서버 측에서 렌더링&lt;/span&gt;하는 방식을 말합니다. 서버에서  렌더링이 완료된 HTML 파일을 전달받기 때문에 사용자는 곧바로 웹 사이트를 볼 수 있습니다. 그러나 사용자와의 인터렉션을 요구하는 자바스크립트 파일이 브라우저상에 다운로드되기 전까지 사용자는 어떠한 행위도 수행할 수 없어, TTV(Time To View)와 TTI(Time To Interaction) 사이의 공백 시간이 존재하게 됩니다.&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  CSR (Client Side Rendering)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-21 오후 7.11.55.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2lYYY/btsDJCz8Gdf/RbMkTHH1JrNm0zKeU4dOK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2lYYY/btsDJCz8Gdf/RbMkTHH1JrNm0zKeU4dOK0/img.png&quot; data-alt=&quot;CSR&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2lYYY/btsDJCz8Gdf/RbMkTHH1JrNm0zKeU4dOK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2lYYY%2FbtsDJCz8Gdf%2FRbMkTHH1JrNm0zKeU4dOK0%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;714&quot; height=&quot;323&quot; data-filename=&quot;스크린샷 2024-01-21 오후 7.11.55.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;666&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CSR&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;클라이언트 사이드 렌더링(CSR)이란, 서버로부터 &lt;span class=&quot;half-line-yellow&quot;&gt;비어 있는 HTML 파일을 전달 받아 클라이언트 측에서 렌더링&lt;/span&gt;하고 자바스크립트 파일을 Hydration 하는 방식을 말합니다. HTML 파일을 렌더링하기까지 사용자가 화면을 볼 수 없다는 단점이 있지만 화면을 볼 수 있는 동시에 인터렉션을 수행할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  Hydration&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;HTML 파일과 자바스크립트 코드를 연결하는 과정 혹은 각 DOM 요소에 이벤트 리스너를 연결하는 과정&lt;/p&gt;
&lt;/div&gt;
&lt;/div&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇듯, SSR과 CSR 방식은 &lt;span class=&quot;half-line-yellow&quot;&gt;어느 곳에서 HTML 파일을 렌더링하는 지&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  SSR 장단점&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;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버로부터 pre-rendering된 HTML 파일을 전달받기 때문에 &lt;span class=&quot;half-line-yellow&quot;&gt;검색 엔진 최적화(SEO)&lt;/span&gt;에 용이&lt;/li&gt;
&lt;li&gt;초기 로딩 &lt;span class=&quot;half-line-yellow&quot;&gt;속도가 빠름&lt;/span&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;span class=&quot;half-line-yellow&quot;&gt;공백이 존재&lt;/span&gt;하여 사용자가 불편함 호소&lt;/li&gt;
&lt;li&gt;페이지 이동 시, 서버 측에서 HTML 파일을 다시 렌더링하기 때문에 초기 로딩 속도를 제외한 &lt;span class=&quot;half-line-yellow&quot;&gt;나머지 로딩 속도는 느림&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;CSR 방식보다 &lt;span class=&quot;half-line-yellow&quot;&gt;서버의 부하가 큼&lt;/span&gt;&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;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  SEO (검색 엔진 최적화)&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;웹 사이트를 검색 엔진에 잘 노출되도록 하는 작업&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;HTML 문서의 &lt;span class=&quot;full-line-grey&quot;&gt;head&lt;/span&gt; 태그와 &lt;span class=&quot;full-line-grey&quot;&gt;meta&lt;/span&gt; 태그에 등록된 데이터를 통해 검색 엔진에 노출될 수 있다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  CSR 장단점&lt;br /&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;페이지 이동 시, 필요한 데이터만 전달받아 렌더링하기 때문에 초기 로딩 시간을 제외한 &lt;span class=&quot;half-line-yellow&quot;&gt;나머지 로딩 시간이 빠름&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;사용자는 페이지를 볼 수 있는 &lt;span class=&quot;half-line-yellow&quot;&gt;동시에 인터렉션이 가능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;서버는 비어 있는 HTML 파일만 전달하기 때문에 &lt;span class=&quot;half-line-yellow&quot;&gt;서버의 부하가 적음&lt;/span&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;서버로부터 비어있는 HTML 파일을 전달받기 때문에 &lt;span class=&quot;half-line-yellow&quot;&gt;검색 엔진 최적화(SEO)에 취약&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;초기에는 비어있는 HTML 파일에 자바스크립트 파일을 적용하여 페이지를 렌더링하기 때문에 &lt;span class=&quot;half-line-yellow&quot;&gt;초기 로딩 속도가 느림&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  SSR, CSR. 언제 사용하면 좋을까?&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;SSR&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;li&gt;랜딩 페이지나 블로그와 같이 검색 엔진에 노출되어야 하는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CSR&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;li&gt;프로필 페이지와 같이 검색 엔진에 노출될 필요가 없는 경우&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Next.js</category>
      <category>csr</category>
      <category>SSR</category>
      <category>SSR CSR 차이</category>
      <category>서버사이드렌더링</category>
      <category>클라이언트사이드렌더링</category>
      <author>lheunoia</author>
      <guid isPermaLink="true">https://cherishvert.tistory.com/112</guid>
      <comments>https://cherishvert.tistory.com/112#entry112comment</comments>
      <pubDate>Sun, 21 Jan 2024 19:19:39 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 두 큐 합 같게 만들기 C++ (Lv.2)</title>
      <link>https://cherishvert.tistory.com/111</link>
      <description>&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/118667&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/118667&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1684133394328&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/118667&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cKNQHK/hySCSOAoA0/cIpgdiKMK3p9WZvHk1j85K/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/b6yEHM/hySCP5m2mc/4Yk5hic6be1hqU8MSL21sK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/118667&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/118667&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cKNQHK/hySCSOAoA0/cIpgdiKMK3p9WZvHk1j85K/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/b6yEHM/hySCP5m2mc/4Yk5hic6be1hqU8MSL21sK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;b&gt;2022 KAKAO TECH INTERNSHIP&lt;/b&gt; 문제였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글쓴이는 &lt;b&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;&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;&amp;nbsp;&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;  문제 풀이&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 두 큐의 모든 원소를 담을 v 벡터 선언&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. v 벡터에서 가리킬 queue1, queue2의 &lt;span class=&quot;half-line-yellow&quot;&gt;각 시작 지점과 끝 지점 선언&lt;/span&gt; (queue1의 시작 지점: s1, queue1의 끝 지점: e1)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. queue1, queue2의 각 모든 원소의 합을 담을 변수는 long long 타입으로 선언 (&lt;span style=&quot;text-align: left;&quot;&gt;산술 오버플로우 발생 가능성)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;4. &lt;span class=&quot;half-line-yellow&quot;&gt;sum1과 sum2를 비교&lt;/span&gt;하면서 원소를 더하거나 빼 나가기 ⭐️&lt;/span&gt;&lt;span style=&quot;text-align: left;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;5. &lt;b&gt;answer &amp;lt;= size*2&lt;/b&gt;인 동안에 두 큐의 합이 같으면 answer 반환&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &amp;zwj;  C++ 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1684133440203&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;

int solution(vector&amp;lt;int&amp;gt; queue1, vector&amp;lt;int&amp;gt; queue2) {
    int answer = 0;
    vector&amp;lt;int&amp;gt; v;
    
    int s1 = 0;
    int e1 = queue1.size() - 1;
    int s2 = queue1.size();
    int e2 = queue1.size()*2 - 1;
    
    int size = queue1.size() * 2;
    long long sum1 = 0, sum2 = 0;
        
    for (int q1: queue1) {
        sum1 += q1;
        v.push_back(q1);
    }
    
    for (int q2: queue2) {
        sum2 += q2;
        v.push_back(q2);
    }

    // 위치가 원래대로 돌아오면 각 큐의 원소 합을 같게 만들 수 없음
    while (answer &amp;lt;= size * 2) {
        if (sum1 &amp;lt; sum2) {
            sum1 += v[(++e1) % size];
            sum2 -= v[(s2++) % size];
        } else if (sum1 &amp;gt; sum2) {
            sum1 -= v[(s1++) % size];
            sum2 += v[(++e2) % size];
        } else return answer; // 두 큐의 합이 같으면 answer 반환
        
        answer++;
    }
    
    return -1;
}&lt;/code&gt;&lt;/pre&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-filename=&quot;스크린샷 2023-05-15 오후 3.51.02.png&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;364&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zzh95/btsf2H5h6m3/WBSjRBwvqB2z8tBlpk7c91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zzh95/btsf2H5h6m3/WBSjRBwvqB2z8tBlpk7c91/img.png&quot; data-alt=&quot;프로그래머스 - 결과 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zzh95/btsf2H5h6m3/WBSjRBwvqB2z8tBlpk7c91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzzh95%2Fbtsf2H5h6m3%2FWBSjRBwvqB2z8tBlpk7c91%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;541&quot; height=&quot;364&quot; data-filename=&quot;스크린샷 2023-05-15 오후 3.51.02.png&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;364&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로그래머스 - 결과 화면&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>2022 kakao tech internship</category>
      <category>C++</category>
      <category>level2</category>
      <category>프로그래머스 2022 kakao tech internship 두 큐 합 같게 만들기</category>
      <category>프로그래머스 두 큐 합 같게 만들기</category>
      <category>프로그래머스 두 큐 합 같게 만들기 c++</category>
      <author>lheunoia</author>
      <guid isPermaLink="true">https://cherishvert.tistory.com/111</guid>
      <comments>https://cherishvert.tistory.com/111#entry111comment</comments>
      <pubDate>Mon, 15 May 2023 16:02:44 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] [1차] 비밀지도 C++ (Lv.1)</title>
      <link>https://cherishvert.tistory.com/110</link>
      <description>&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/17681&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/17681&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1684132137209&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/17681&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dhfaOi/hySCRINT7I/dyaylYk1U6WuO2XDy1gQgk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/geGYc/hySC0Mv4aY/kWHOFwTvCqCVrueWiJlMDk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/17681&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/17681&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dhfaOi/hySCRINT7I/dyaylYk1U6WuO2XDy1gQgk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/geGYc/hySC0Mv4aY/kWHOFwTvCqCVrueWiJlMDk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;b&gt;2018 KAKAO BLIND RECRUITMENT&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;&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;&amp;nbsp;&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;  문제 풀이&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 두 지도의 각 가로열을 &lt;span class=&quot;half-line-yellow&quot;&gt;or 연산&lt;/span&gt; (지도 중 어느 하나라도 1이면 전체 지도에서도 1이므로)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 1의 결과값을 소인수분해&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2로 나누어 떨어지면 tmp += &quot; &quot;&lt;/li&gt;
&lt;li&gt;2로 나누어 떨어지지 않으면 tmp += &quot;#&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. tmp 값 뒤집기&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &amp;zwj;  C++ 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1684132196989&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

vector&amp;lt;string&amp;gt; solution(int n, vector&amp;lt;int&amp;gt; arr1, vector&amp;lt;int&amp;gt; arr2) {
    vector&amp;lt;string&amp;gt; answer;
    
    for (int i=0; i&amp;lt;n; i++) {
        int num = arr1[i] | arr2[i];
        string tmp = &quot;&quot;;
        
        while (tmp.length() != n) {
            if (num % 2 == 0) tmp += &quot; &quot;;
            else tmp += &quot;#&quot;;
            
            num /= 2;
        }
        
        reverse(tmp.begin(), tmp.end());
        answer.push_back(tmp);
    }
    
    return answer;
}&lt;/code&gt;&lt;/pre&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-filename=&quot;스크린샷 2023-05-15 오후 3.30.06.png&quot; data-origin-width=&quot;568&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byeJPz/btsf2lVHQqm/jFSeNofq7SqBc6rPGyI1s1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byeJPz/btsf2lVHQqm/jFSeNofq7SqBc6rPGyI1s1/img.png&quot; data-alt=&quot;프로그래머스 - 결과 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byeJPz/btsf2lVHQqm/jFSeNofq7SqBc6rPGyI1s1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyeJPz%2Fbtsf2lVHQqm%2FjFSeNofq7SqBc6rPGyI1s1%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;541&quot; height=&quot;324&quot; data-filename=&quot;스크린샷 2023-05-15 오후 3.30.06.png&quot; data-origin-width=&quot;568&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로그래머스 - 결과 화면&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>2018 KAKAO BLIND RECRUITMENT</category>
      <category>C++</category>
      <category>level1</category>
      <category>프로그래머스 2018 kakao blind recruitment 비밀지도</category>
      <category>프로그래머스 비밀지도</category>
      <category>프로그래머스 비밀지도 C++</category>
      <author>lheunoia</author>
      <guid isPermaLink="true">https://cherishvert.tistory.com/110</guid>
      <comments>https://cherishvert.tistory.com/110#entry110comment</comments>
      <pubDate>Mon, 15 May 2023 15:47:48 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 메뉴 리뉴얼 C++ (Lv.2)</title>
      <link>https://cherishvert.tistory.com/109</link>
      <description>&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72411&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/72411&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1683782577896&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72411&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/1u7FR/hySz9Dbm30/SevtjoXMa5hwS9kdcrTelk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/G5jzy/hySAgI3P6h/YL2he20Fw93nK6Q1clqrR1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72411&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72411&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/1u7FR/hySz9Dbm30/SevtjoXMa5hwS9kdcrTelk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/G5jzy/hySAgI3P6h/YL2he20Fw93nK6Q1clqrR1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;b&gt;2021 KAKAO BLIND RECRUITMENT&lt;/b&gt; 문제였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글쓴이는 DFS로 풀이했습니다.&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;&amp;nbsp;&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;  문제 풀이&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. orders 벡터의 각 단품메뉴에 대해서 course 요소만큼의 코스요리의 메뉴 구성의 &lt;span class=&quot;half-line-yellow&quot;&gt;주문 횟수를 dfs를 통해 combination 맵에 누적&lt;/span&gt; ⭐️&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. combination 맵에서 가장 많이 주문된 수를 maxCount 변수에 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. maxCount가 2보다 크다면, combination 맵에서 maxCount와 같은 값을 가진 &lt;span class=&quot;half-line-yellow&quot;&gt;키를 answer 벡터에 삽입&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. for문이 종료된 후 answer 벡터 오름차순 정렬&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &amp;zwj;  C++ 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1683782628361&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;map&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

map&amp;lt;string, int&amp;gt; combination;

bool cmp(pair&amp;lt;string, int&amp;gt; &amp;amp;a, pair&amp;lt;string, int&amp;gt; &amp;amp;b) {
    return a.second &amp;gt; b.second;
}

// 각 order에 대해 조합의 수가 len인 단품메뉴 조합의 주문 개수 카운트
void dfs(string &amp;amp;order, int &amp;amp;len, string tmp, int idx) {
    if (tmp.length() == len) {
        combination[tmp]++; // 해당 조합의 주문 수++
        return;
    }
    
    for (int i=idx; i&amp;lt;order.length(); i++) {
        dfs(order, len, tmp + order[i], i + 1);
    }
}

vector&amp;lt;string&amp;gt; solution(vector&amp;lt;string&amp;gt; orders, vector&amp;lt;int&amp;gt; course) {
    vector&amp;lt;string&amp;gt; answer;
    
    for (int len: course) {
        for (string order: orders) {
            sort(order.begin(), order.end());
            dfs(order, len, &quot;&quot;, 0);   
        }
        
        int maxCount = 0; // 가장 많이 주문된 수
        for (auto it: combination) {
            maxCount = max(maxCount, it.second);
        }
        
        for (auto it: combination) {
            if (maxCount &amp;lt; 2) break;
            else if (combination[it.first] == maxCount) answer.push_back(it.first);
        }
        
        combination.clear(); // 다음 단품메뉴의 개수의 연산을 위해 clear
    }
    
    sort(answer.begin(), answer.end());
    return answer;
}&lt;/code&gt;&lt;/pre&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-filename=&quot;스크린샷 2023-05-09 오전 1.01.25.png&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;441&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EpX7s/btseQs83ieF/TSJUgaqmIqFdxgNVrSMZdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EpX7s/btseQs83ieF/TSJUgaqmIqFdxgNVrSMZdk/img.png&quot; data-alt=&quot;프로그래머스 - 결과 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EpX7s/btseQs83ieF/TSJUgaqmIqFdxgNVrSMZdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEpX7s%2FbtseQs83ieF%2FTSJUgaqmIqFdxgNVrSMZdk%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;576&quot; height=&quot;403&quot; data-filename=&quot;스크린샷 2023-05-09 오전 1.01.25.png&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;441&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로그래머스 - 결과 화면&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>2021 KAKAO BLIND RECRUITMENT</category>
      <category>C++</category>
      <category>dfs</category>
      <category>level2</category>
      <category>프로그래머스 2021 kakao blind recruitment 메뉴 리뉴얼</category>
      <category>프로그래머스 메뉴 리뉴얼</category>
      <category>프로그래머스 메뉴 리뉴얼 c++</category>
      <author>lheunoia</author>
      <guid isPermaLink="true">https://cherishvert.tistory.com/109</guid>
      <comments>https://cherishvert.tistory.com/109#entry109comment</comments>
      <pubDate>Thu, 11 May 2023 14:38:48 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 순위 검색 C++ (Lv.2)</title>
      <link>https://cherishvert.tistory.com/108</link>
      <description>&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72412&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/72412&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1683561610549&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72412&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Mo0SN/hySysCq9XA/mW64XzYPachcifcVtKl050/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/nZBDU/hySyiNm4Uw/jpmPnzTopMxg65yzSk47H1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72412&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72412&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Mo0SN/hySysCq9XA/mW64XzYPachcifcVtKl050/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/nZBDU/hySyiNm4Uw/jpmPnzTopMxg65yzSk47H1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;b&gt;2021 KAKAO BLIND RECRUITMENT&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;&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;&amp;nbsp;&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;  문제 풀이&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. info 배열의 각 원소의 값을 &lt;span class=&quot;half-line-yellow&quot;&gt;stringstream으로 공백을 제거&lt;/span&gt;하고 코딩테스트 점수를 제외한 값은 tmp[i][0]에 삽입&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;  tmp 벡터는 [['java', '-'], ['backend', '-'], ['junior', '-'], ['pizza', '-']] 와 같은 형태&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;scores 맵에&lt;/span&gt; &lt;span class=&quot;half-line-yellow&quot;&gt;tmp 벡터에서 발생할 수 있는 모든 query를 키로 하여&lt;/span&gt; 코딩테스트 점수를 저장 ⭐️&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. scores 맵의 각 키에 대해 코딩테스트 점수를 오름차순 정렬&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. query 벡터의 각 문의조건에 대해 &quot;and&quot;를 제외한 [조건]을 &lt;b&gt;key&lt;/b&gt; 변수에 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. &lt;span class=&quot;half-line-yellow&quot;&gt;lower_bound 함수를 사용&lt;/span&gt;하여 scores[&lt;b&gt;key&lt;/b&gt;]에서 코딩테스트 점수가 score 이상인 사람의 수를 찾아서 answer 벡터에 삽입&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;&amp;nbsp;&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; &amp;zwj;  C++ 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1683561669383&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;sstream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;map&amp;gt;

using namespace std;

map&amp;lt;string, vector&amp;lt;int&amp;gt;&amp;gt; scores; // 각 query에 대한 코딩테스트 점수를 담은 객체

// 각 info에 대해 가능한 모든 query에 코딩테스트 점수 저장
void storeScore(vector&amp;lt;vector&amp;lt;string&amp;gt;&amp;gt; &amp;amp;tmp, int score) {
    string c1, c2, c3, c4;
    
    for (int i=0; i&amp;lt;2; i++) {
        c1 = tmp[0][i];
        for (int j=0; j&amp;lt;2; j++) {
            c2 = tmp[1][j];
            for (int k=0; k&amp;lt;2; k++) {
                c3 = tmp[2][k];
                for (int l=0; l&amp;lt;2; l++) {
                    c4 = tmp[3][l];
                    scores[c1 + c2 + c3 + c4].push_back(score);
                }
            }
        }
    }
}

vector&amp;lt;int&amp;gt; solution(vector&amp;lt;string&amp;gt; info, vector&amp;lt;string&amp;gt; query) {
    vector&amp;lt;int&amp;gt; answer;
    vector&amp;lt;vector&amp;lt;string&amp;gt;&amp;gt; tmp(4, vector&amp;lt;string&amp;gt;(2, &quot;-&quot;));
    
    for (int i=0; i&amp;lt;info.size(); i++) {
        string s;
        int idx = 0, score = 0;
        
        stringstream ss(info[i]);
        
        while (ss &amp;gt;&amp;gt; s) {
            if (idx &amp;lt; 4) tmp[idx++][0] = s;
            else score = stoi(s);
        }
        
        storeScore(tmp, score);
    }
    
    // 코딩테스트 점수 오름차순 정렬
    for (auto it: scores) {
        sort(scores[it.first].begin(), scores[it.first].end());
    }
    
    for (string q: query) {
        string s, key = &quot;&quot;;
        int idx = 0, score = 0;
        
        stringstream ss(q);
        
        while (ss &amp;gt;&amp;gt; s) {
            if (s == &quot;and&quot;) continue;
            
            if (idx &amp;lt; 4) {
                key += s;
                idx++;
            } else {
                score = stoi(s);
            }
        }
        
        auto it = lower_bound(scores[key].begin(), scores[key].end(), score);
        answer.push_back(scores[key].size() - (it - scores[key].begin()));
    }
    
    return answer;
}&lt;/code&gt;&lt;/pre&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-filename=&quot;스크린샷 2023-05-09 오전 1.01.25.png&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;441&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EINjT/btseqwLG7B3/JH6OqHCQLuEVLoogzMZJKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EINjT/btseqwLG7B3/JH6OqHCQLuEVLoogzMZJKk/img.png&quot; data-alt=&quot;프로그래머스 - 결과 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EINjT/btseqwLG7B3/JH6OqHCQLuEVLoogzMZJKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEINjT%2FbtseqwLG7B3%2FJH6OqHCQLuEVLoogzMZJKk%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;614&quot; height=&quot;430&quot; data-filename=&quot;스크린샷 2023-05-09 오전 1.01.25.png&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;441&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로그래머스 - 결과 화면&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>2021 KAKAO BLIND RECRUITMENT</category>
      <category>C++</category>
      <category>level2</category>
      <category>프로그래머스 2021 kakao blind recruitment 순위 검색</category>
      <category>프로그래머스 순위 검색</category>
      <category>프로그래머스 순위 검색 c++</category>
      <author>lheunoia</author>
      <guid isPermaLink="true">https://cherishvert.tistory.com/108</guid>
      <comments>https://cherishvert.tistory.com/108#entry108comment</comments>
      <pubDate>Tue, 9 May 2023 01:18:30 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] 웹 어플리케이션 배포하기 (EC2)</title>
      <link>https://cherishvert.tistory.com/107</link>
      <description>&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;AWS&lt;/b&gt; 배포를 위해 &lt;b&gt;EC2&lt;/b&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  EC2 생성하기&lt;/b&gt;&lt;/h2&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;1.&amp;nbsp; AWS 사이트 접속 후 회원가입&lt;/b&gt;&lt;/h4&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://ap-northeast-2.console.aws.amazon.com/console/home?region=ap-northeast-2&quot;&gt;https://ap-northeast-2.console.aws.amazon.com/console/home?region=ap-northeast-2&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1683025241097&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;https://ap-northeast-2.console.aws.amazon.com/console/home?region=ap-northeast-2&quot; data-og-description=&quot;&quot; data-og-host=&quot;ap-northeast-2.console.aws.amazon.com&quot; data-og-source-url=&quot;https://ap-northeast-2.console.aws.amazon.com/console/home?region=ap-northeast-2&quot; data-og-url=&quot;https://ap-northeast-2.console.aws.amazon.com/console/home?region=ap-northeast-2&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://ap-northeast-2.console.aws.amazon.com/console/home?region=ap-northeast-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ap-northeast-2.console.aws.amazon.com/console/home?region=ap-northeast-2&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;https://ap-northeast-2.console.aws.amazon.com/console/home?region=ap-northeast-2&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;ap-northeast-2.console.aws.amazon.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;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;&lt;b&gt;2. 지역 &amp;gt; 아시아 태평양(서울)으로 변경&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-05-02 오후 8.01.22.png&quot; data-origin-width=&quot;2660&quot; data-origin-height=&quot;922&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l4x3I/btsdH24UKj7/GkVa6TudrC3s27KN0E23T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l4x3I/btsdH24UKj7/GkVa6TudrC3s27KN0E23T0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l4x3I/btsdH24UKj7/GkVa6TudrC3s27KN0E23T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl4x3I%2FbtsdH24UKj7%2FGkVa6TudrC3s27KN0E23T0%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;2660&quot; height=&quot;922&quot; data-filename=&quot;스크린샷 2023-05-02 오후 8.01.22.png&quot; data-origin-width=&quot;2660&quot; data-origin-height=&quot;922&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;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;&lt;b&gt;3.&amp;nbsp;EC2&amp;nbsp;&amp;gt;&amp;nbsp;인스턴스&amp;nbsp;시작&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-05-02 오후 8.04.52.png&quot; data-origin-width=&quot;2068&quot; data-origin-height=&quot;1380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVsq2H/btsdJgawzF1/A7cfyL043CWe0igVXkXGT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVsq2H/btsdJgawzF1/A7cfyL043CWe0igVXkXGT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVsq2H/btsdJgawzF1/A7cfyL043CWe0igVXkXGT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVsq2H%2FbtsdJgawzF1%2FA7cfyL043CWe0igVXkXGT0%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;796&quot; height=&quot;531&quot; data-filename=&quot;스크린샷 2023-05-02 오후 8.04.52.png&quot; data-origin-width=&quot;2068&quot; data-origin-height=&quot;1380&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;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;&lt;b&gt;4. 서버 선택&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 프로젝트에서는 &lt;b&gt;Ubuntu&lt;/b&gt; 서버를 선택했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&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;br /&gt;&lt;b&gt;5. 인스턴스 유형 선택 &lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'프리티어 사용 가능'&lt;/b&gt;이라고 쓰여 있는 인스턴스는 무료로 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&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;br /&gt;&lt;b&gt;6. HTTP, HTTPS 허용&lt;/b&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-05-02 오후 8.07.08.png&quot; data-origin-width=&quot;1554&quot; data-origin-height=&quot;1298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rrn2l/btsdBNae3aa/KjE6cbZleGXNKhjvNkVOH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rrn2l/btsdBNae3aa/KjE6cbZleGXNKhjvNkVOH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rrn2l/btsdBNae3aa/KjE6cbZleGXNKhjvNkVOH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frrn2l%2FbtsdBNae3aa%2FKjE6cbZleGXNKhjvNkVOH0%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;639&quot; height=&quot;534&quot; data-filename=&quot;스크린샷 2023-05-02 오후 8.07.08.png&quot; data-origin-width=&quot;1554&quot; data-origin-height=&quot;1298&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크 설정에서 &lt;b&gt;HTTP&lt;/b&gt;와 &lt;b&gt;HTTPS&lt;/b&gt; 트래픽을 허용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IP가 0.0.0.0 이면 모든 IP에서 접근 가능합니다. &lt;b&gt;SSH&lt;/b&gt;(개발 환경 터미널)는 집의 IP로 변경하여 해커들이 접근하지 못하도록 방지하는 것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&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;br /&gt;&lt;b&gt;7. 키 페어 생성&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;인스턴스 키 페어는 &lt;b&gt;.pem&lt;/b&gt; 형태로, 이 파일이 있어야 EC2 인스턴스에 접근이 가능합니다.&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-filename=&quot;스크린샷 2023-05-02 오후 8.42.39.png&quot; data-origin-width=&quot;1552&quot; data-origin-height=&quot;344&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czyfcj/btsdHO6LNtt/klgyk8nK77kOhB5D54zjck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czyfcj/btsdHO6LNtt/klgyk8nK77kOhB5D54zjck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czyfcj/btsdHO6LNtt/klgyk8nK77kOhB5D54zjck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fczyfcj%2FbtsdHO6LNtt%2Fklgyk8nK77kOhB5D54zjck%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;788&quot; height=&quot;175&quot; data-filename=&quot;스크린샷 2023-05-02 오후 8.42.39.png&quot; data-origin-width=&quot;1552&quot; data-origin-height=&quot;344&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;&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;size18&quot;&gt;&lt;b&gt;⭐️ 키 페어 파일을 프로젝트에 추가하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다운로드된 키 페어 파일을 프로젝트의 &lt;b&gt;루트 경로&lt;/b&gt;에 추가 후 깃허브에 노출되지 않도록 &lt;i&gt;.gitignore&lt;/i&gt;에 &lt;b&gt;키 페어 이름.pem&lt;/b&gt;을 추가합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&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;8. 인스턴스 시작&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-05-02 오후 8.26.34.png&quot; data-origin-width=&quot;2260&quot; data-origin-height=&quot;292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rKqp0/btsdGdzEPj0/An2QFRvMfTyoaobw5DrP1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rKqp0/btsdGdzEPj0/An2QFRvMfTyoaobw5DrP1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rKqp0/btsdGdzEPj0/An2QFRvMfTyoaobw5DrP1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrKqp0%2FbtsdGdzEPj0%2FAn2QFRvMfTyoaobw5DrP1K%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;2260&quot; height=&quot;292&quot; data-filename=&quot;스크린샷 2023-05-02 오후 8.26.34.png&quot; data-origin-width=&quot;2260&quot; data-origin-height=&quot;292&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스 상태가  &lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;실행 중&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  EC2 인스턴스에 프로젝트 연결하기&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;&lt;b&gt;1. EC2 서버에 접속&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-05-02 오후 8.26.34.png&quot; data-origin-width=&quot;2260&quot; data-origin-height=&quot;292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bW4v21/btsdIplkjIE/v49nf7E8KxVxg7PGCJtB21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bW4v21/btsdIplkjIE/v49nf7E8KxVxg7PGCJtB21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bW4v21/btsdIplkjIE/v49nf7E8KxVxg7PGCJtB21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbW4v21%2FbtsdIplkjIE%2Fv49nf7E8KxVxg7PGCJtB21%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;2260&quot; height=&quot;292&quot; data-filename=&quot;스크린샷 2023-05-02 오후 8.26.34.png&quot; data-origin-width=&quot;2260&quot; data-origin-height=&quot;292&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결하려는 인스턴스를 선택하고 [연결] 버튼을 클릭합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-05-02 오후 8.25.51.png&quot; data-origin-width=&quot;1676&quot; data-origin-height=&quot;1122&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYJ2wP/btsdFgDcDJ3/G5ysBkD49rclxVGYFf6mX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYJ2wP/btsdFgDcDJ3/G5ysBkD49rclxVGYFf6mX0/img.png&quot; data-alt=&quot;SSH 클라이언트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYJ2wP/btsdFgDcDJ3/G5ysBkD49rclxVGYFf6mX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYJ2wP%2FbtsdFgDcDJ3%2FG5ysBkD49rclxVGYFf6mX0%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;656&quot; height=&quot;439&quot; data-filename=&quot;스크린샷 2023-05-02 오후 8.25.51.png&quot; data-origin-width=&quot;1676&quot; data-origin-height=&quot;1122&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSH 클라이언트&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;[SSH 클라이언트] 탭을 클릭한 후 하단의 &lt;b&gt;ssh&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;개발 환경 플랫폼(글쓴이의 경우 VScode)으로 돌아가서 터미널에 접속합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키 페어 파일이 들어있는 경로(루트 경로)에서 위에서 복사한 텍스트를 붙여넣기 하고 &lt;i&gt;Enter&lt;/i&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;Are you sure you want to continue connecting (yes/no/[fingerprint])?&lt;/b&gt;&amp;nbsp; 문장이 나오는데 이 때 &lt;b&gt;yes&lt;/b&gt;를 입력합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;Enter&lt;/i&gt; 키를 누르면 원격의 EC2 서버에 접속할 수 있게 됩니다.&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;&lt;b&gt;2. EC2 서버에 해당 프로젝트의 깃허브 주소 연결&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EC2 서버에 정상적으로 접속되면 터미널의 경로가 로컬이 아닌 &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;ubuntu@&lt;/b&gt;&lt;/span&gt;&amp;nbsp;경로가 됩니다. (선택한 서버에 따라 다릅니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1683029088785&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git clone https://github.com/&amp;lt;사용자명&amp;gt;/&amp;lt;레포지토리명&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 인스턴스에 연결하려는 프로젝트의 깃허브 레포지토리 주소를 &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;ubuntu@&lt;/b&gt;&lt;/span&gt;&amp;nbsp;경로에 클론합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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;br /&gt;&lt;b&gt;3.  EC2 서버에 의존성 패키치 설치하기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;+ 깃허브 레포지토리에 변경사항이 있으면 &lt;span class=&quot;full-line-grey&quot;&gt;git pull&lt;/span&gt; 명령어를 수행합니다.&lt;/span&gt;&amp;nbsp;(EC2 서버에서는 깃허브의 변경사항을 알지 못하기 때문)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt; &lt;br /&gt;&lt;b&gt;root@&lt;/b&gt; 경로에서는 &lt;span class=&quot;full-line-grey&quot;&gt;git pull&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ubuntu@&lt;/span&gt;&lt;/b&gt;&amp;nbsp;경로에서는 &lt;span class=&quot;full-line-grey&quot;&gt;sudo git pull&lt;/span&gt;&lt;/blockquote&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;pre id=&quot;code_1683029448245&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd back&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포하려는 서버의 루트 폴더로 이동합니다. (백엔드 서버를 배포하려면 &lt;b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;node 버전 확인&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1683029612111&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;node -v&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 경로에 &lt;span class=&quot;full-line-grey&quot;&gt;node&lt;/span&gt;가 없다면 &lt;span class=&quot;full-line-grey&quot;&gt;node&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ubuntu@&lt;/span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;/span&gt; 경로에 node 설치하기&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1683029640059&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install -y build-essential
sudo apt-get install curl
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash --
sudo apt-get install -y nodejs&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어들을 순차적으로 입력하여&lt;b&gt; &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ubuntu@&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&amp;nbsp;경로에 &lt;span class=&quot;full-line-grey&quot;&gt;node&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;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683029695626&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;node -v
npm -v&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;node&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ubuntu@&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;경로에 의존성 패키지 설치하기&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1683029745125&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm i&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어를 실행하여 back 폴더의 &lt;span class=&quot;full-line-grey&quot;&gt;package.json&lt;/span&gt;에 포함된 의존성 패키지들을 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ubuntu@&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&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;&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;&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;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; &amp;zwj;  EC2 서버에서&amp;nbsp;&lt;/b&gt;&lt;b&gt;프론트 서버 실행하기&lt;/b&gt;&lt;/h2&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: #333333; text-align: start;&quot;&gt;1. 백엔드 url 수정&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;인스턴스의 IPv4는 주기적으로 변하기 때문에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ubuntu@&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;서버에 연결할 때 필요한 주소가 고정적이지 않습니다. (탄력적 IP를 사용하면 유료로 고정적인 IP를 사용할 수 있습니다.) 프론트 서버를 배포하기 전에  개발 시 사용하던 &lt;b&gt;백엔드 url&lt;/b&gt; ➡️&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt; back 인스턴스의 IP&lt;/b&gt;로 변경해야 합니다. (백엔드 서버를 배포하기 전에도 front 인스턴스 IP를 origin url에 추가해주어야 합니다.)&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;2. 포트 번호 80으로 수정&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1683095984074&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;scripts&quot;: {
    &quot;dev&quot;: &quot;next dev -p 3060&quot;,
    &quot;build&quot;: &quot;ANALYZE=true NODE_ENV=production next build&quot;,
    &quot;start&quot;: &quot;NODE_ENV=production next start -p 80&quot;
  },&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;포트번호를 &lt;b&gt;3060 ➡️ 80&lt;/b&gt;으로 변경합니다. (80: EC2 생성 당시 네트워크 설정에서 허용한 포트 번호)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경 사항을 깃허브에 push  합니다.&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;3. 프론트 원격 서버 접속&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1683038250834&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd front&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;로컬 경로(C:)&lt;/b&gt;에서 &lt;b&gt;front 인스턴스의 주소&lt;/b&gt;를 입력하여 프론트 원격 서버로 접속합니다. 프론트 서버를 실행해야 하기 때문에 &lt;b&gt;프론트 루트 폴더&lt;/b&gt; 경로로 이동합니다. &lt;span class=&quot;full-line-grey&quot;&gt;git pull&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 프론트 서버 실행&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1683030272630&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm run build
npm run start&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ubuntu 서버에서 프론트 서버를 실행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;해당 인스턴스의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;IPv4 주소:허용된 포트 번호&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;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;  CI/CD 툴이나 docker를 사용하면 여러 개의 명령어를 한번에 실행할 수 있습니다. &lt;s&gt;(더 찾아보기)&lt;/s&gt;&lt;/blockquote&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;b&gt; &amp;zwj;  EC2 서버에서&amp;nbsp;&lt;/b&gt;백엔드 서버 실행하기&lt;/b&gt;&lt;/h2&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;1. mysql 설치&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1683038471575&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wget -c https://repo.mysql.com//mysql-apt-config_0.8.13-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.13-1_all.deb
sudo apt update
sudo apt-get install mysql-server&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ubuntu@&lt;/span&gt;&lt;/b&gt;&amp;nbsp;경로의 back 폴더에서 &lt;b&gt;mysql&lt;/b&gt;을 설치합니다. (암호는 &lt;b&gt;strong&lt;/b&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. root 경로에서 mysql 암호 설정&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1683039652937&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mysql_secure_installation&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;sudo su&lt;/span&gt;를 입력하여 &lt;b&gt;root@ &lt;/b&gt;경로로 전환한 뒤, 위 명령어를 입력해 줍니다. (반드시 &lt;b&gt;root@&lt;/b&gt; 경로에서 진행)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암호는 &lt;b&gt;strong&lt;/b&gt;으로 설정하고 나머지 응답에는 &lt;b&gt;y&lt;/b&gt;(yes)를 입력합니다.&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;pre id=&quot;code_1683039813250&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mysql -uroot -p&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;root@&lt;/b&gt; 경로에서 위 명령어를 입력하면 비밀번호를 입력하라는 문구가 뜹니다. 위에서 설정한 비밀번호를 입력하면 &lt;b&gt;mysql&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;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683040670151&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '설정한 암호'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;mysql&lt;/b&gt; 경로에서 위 명령어를 입력하여 실제 암호를 &lt;b&gt;설정한 암호&lt;/b&gt;로 변경해 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;mysql&lt;/b&gt; 경로에서 빠져 나오는 명령어는 &lt;span class=&quot;full-line-grey&quot;&gt;exit;&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 실행 전 몇 가지 설정&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;app.js 파일 수정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1683099389371&quot; class=&quot;less&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 1.
app.use(cors({
  origin: ['http://localhost:3060', 'http://52.79.157.220'], // front IP 추가
  credentials: true
}));

// 2.
app.listen(80, () =&amp;gt; { // 3065 -&amp;gt; 80(허용된 포트 번호)으로 변경
  console.log('서버 실행 중!');
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;full-line-grey&quot;&gt;app.js&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;파일의 cors 설정에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;origin url&lt;/b&gt;에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;front 인스턴스의 IP 주소&lt;/b&gt;를 추가하여 cors 에러를 방지합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 백엔드 서버의 포트 번호를 인스턴스에서 허용된 포트 번호로 변경해 줍니다. 허용된 포트 번호는 EC2를 생성할 때&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;네트워크 설정&lt;/b&gt;&lt;span&gt;&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;서버 실행 명령어 추가&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1683040170481&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;scripts&quot;: {
  &quot;dev&quot;: &quot;nodemon app&quot;, // 개발 모드
  &quot;start&quot;: &quot;node app&quot; // 배포 모드
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;back/package.json&lt;/span&gt; 파일의 &lt;span class=&quot;full-line-grey&quot;&gt;scripts&lt;/span&gt;에 배포 모드 실행 명령어를 추가합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(변경 사항이 있으므로 변경 사항을 깃허브에 push하고&amp;nbsp;&lt;span class=&quot;full-line-grey&quot;&gt;git pull&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span class=&quot;full-line-grey&quot;&gt;.env&lt;/span&gt; 파일 추가&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1683040400039&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vim .env&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;환경 변수가 작성된 &lt;span class=&quot;full-line-grey&quot;&gt;.env&lt;/span&gt; 파일은 깃허브에 업로드되지 않기 때문에 &lt;b&gt;root@&lt;/b&gt; 경로에 따로 추가해주어야 합니다. &lt;span class=&quot;full-line-grey&quot;&gt;back/.env&lt;/span&gt;와 동일하게 입력 후 &lt;span class=&quot;full-line-grey&quot;&gt;:wq&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;DB 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1683040762199&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npx sequelize db:create&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어를 입력하여 데이터베이스를 생성합니다. &lt;b&gt;Database &amp;lt;DB 이름&amp;gt; created.&lt;/b&gt; 문구가 뜨면 성공적으로 생성이 된 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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. 백엔드 서버 실행&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1683041123375&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm start&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어를 입력하여 백엔드 서버를 실행합니다. (&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ubuntu@&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;/span&gt; 경로에서는 80 포트를 허용하지 않기 때문에 &lt;span class=&quot;full-line-grey&quot;&gt;sudo npm start&lt;/span&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 인스턴스의 &lt;b&gt;IPv4 주소:허용된 포트 번호&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  background process 사용하기: pm2&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;node&lt;/span&gt;는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;foreground process&lt;/b&gt;이기 때문에 터미널이 종료되면 원격 서버도 함께 종료됩니다. 만약 실수로 원격으로 접속해 놓은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;full-line-grey&quot;&gt;shell&lt;/span&gt;을 끄면(&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ubuntu@&lt;/span&gt;&lt;/b&gt;&amp;nbsp;경로에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;full-line-grey&quot;&gt;exit;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;명령어를 입력했거나 개발 환경 창을 종료한 경우) 로컬 경로(&lt;b&gt;C:&lt;/b&gt;)로 돌아가고 원격에 접속해 있던&amp;nbsp;&lt;span class=&quot;full-line-grey&quot;&gt;shell&lt;/span&gt;이 종료되기 때문에 원격 서버도 함께 종료됩니다. 하루종일 원격 서버에 접속해 두긴 어렵기 때문에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;background process&lt;/b&gt;를 사용하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;full-line-grey&quot;&gt;shell&lt;/span&gt;의 종료 여부와 관계없이 원격 서버를 계속 실행할 수 있습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;background process&lt;/b&gt;를 사용하는 방법 중 하나는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;full-line-grey&quot;&gt;pm2&lt;/span&gt;&lt;span&gt;&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;백엔드 서버에서 pm2 사용하기&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. pm2 설치&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1683092170205&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm i pm2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ubuntu@&lt;/span&gt;&lt;/b&gt; 경로의 back 폴더에서&amp;nbsp;&lt;span class=&quot;full-line-grey&quot;&gt;pm2&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 서버 실행 명령어 수정&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;half-line-yellow&quot;&gt;back/package.json&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1683092354101&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;scripts&quot;: {
  &quot;dev&quot;: &quot;nodemon app&quot;,
  &quot;start&quot;: &quot;pm2 start app.js&quot; // 이렇게 수정
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;start 명령어를 위와 같이 수정합니다.&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. pm2로 서버 실행&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1683092461284&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo npm start // 서버 실행
sudo npx pm2 monit // 서버 모니터링&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ubuntu@&lt;/span&gt;&lt;/b&gt; 경로에서 위 명령어를 순차적으로 입력하여 &lt;span class=&quot;full-line-grey&quot;&gt;pm2&lt;/span&gt;로 실행되는지 확인합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;해당 인스턴스의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;IPv4 주소:허용된 포트 번호&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;+ node 보안 관련 설정하기 (권장)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;node&lt;/span&gt;의 배포 모드에서 보안을 위한 몇 가지 설정이 필요합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- morgan 설정&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- hpp, helmet 패키지 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683097583184&quot; class=&quot;coffeescript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm i pm2 helmet hpp&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;로컬 경로(C:)&lt;/b&gt;의 back 폴더 경로에서 필요한 패키지들을 설치합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;half-line-yellow&quot;&gt;&lt;b&gt;back/app.js&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1683097583184&quot; class=&quot;php&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (process.env.NODE_ENV === 'production') {
  app.use(morgan('combined')); // 자세한 로그 확인 (ex. 접속자의 IP)
  app.use(hpp()); // 보안을 위한 패키지
  app.use(helmet()); // 보안을 위한 패키지
} else {
  app.use(morgan('dev'));
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;app.js&lt;/span&gt;의 코드의 일부분입니다. 위와 같이 수정합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1683097583184&quot; class=&quot;properties&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo git pull
sudo npm i&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;변경 사항들을 깃허브에 push 하고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;ubuntu@&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;경로에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;full-line-grey&quot;&gt;sudo git pull&lt;/span&gt;&amp;nbsp;합니다. 새로운 패키지들을 설치했기 때문에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;full-line-grey&quot;&gt;sudo npm i&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;명령어로 의존성 패키지들을 설치합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;  Aborting error 발생 ➡️&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;full-line-grey&quot;&gt;git reset --hard&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;프론트 서버에서 pm2 사용하기&lt;/b&gt;&lt;/h3&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. pm2 설치&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1683096393523&quot; class=&quot;coffeescript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm i pm2&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ubuntu@&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;경로의 front 폴더에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;full-line-grey&quot;&gt;pm2&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. pm2로 서버 실행&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1683096449926&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm run build (프론트 소스코드 변경될 때마다 실행)
npx pm2 start npm -- start&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 명령어를 통해 &lt;span class=&quot;full-line-grey&quot;&gt;pm2&lt;/span&gt;로 &lt;span class=&quot;full-line-grey&quot;&gt;npm start&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;  pm2 명령어 (&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;ubuntu@&lt;/b&gt;&lt;/span&gt; 경로에서는 명령어 앞에 &lt;span class=&quot;full-line-grey&quot;&gt;sudo&lt;/span&gt; 붙이기)&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;full-line-grey&quot;&gt;npx pm2 logs&lt;/span&gt; 로그 보기&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;full-line-grey&quot;&gt;npx pm2 logs --error&lt;/span&gt; 에러 로그 보기&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;full-line-grey&quot;&gt;npx pm2 list&lt;/span&gt; 실행 중인 서버 리스트 보기&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;full-line-grey&quot;&gt;npx pm2 reload all&lt;/span&gt; 모든 서버 재시작&lt;/blockquote&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  도메인 연결하기&lt;/b&gt;&lt;/h2&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-filename=&quot;스크린샷 2023-05-03 오후 6.07.57.png&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;328&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzuL9P/btsdQI5Pn89/NkIhf0kWEJSCBPbuZWkXi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzuL9P/btsdQI5Pn89/NkIhf0kWEJSCBPbuZWkXi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzuL9P/btsdQI5Pn89/NkIhf0kWEJSCBPbuZWkXi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzuL9P%2FbtsdQI5Pn89%2FNkIhf0kWEJSCBPbuZWkXi1%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;641&quot; height=&quot;288&quot; data-filename=&quot;스크린샷 2023-05-03 오후 6.07.57.png&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;328&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;프론트 서버와 백엔드 서버의 인스턴스 IP 주소가 다르면 새로고침 시 로그인이 유지되지 않는 이슈가 발생하는데요. 개발자 도구의 네트워크 탭을 보면 요청 도메인과 응답 헤더의 도메인이 다릅니다. 이러한 경우에는 2가지 해결 방법이 있습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 동일한 도메인으로 설정 (유료)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://domain.gabia.com/?utm_source=google&amp;amp;utm_medium=performanceMax&amp;amp;utm_campaign=%25EB%258F%2584%25EB%25A9%2594%25EC%259D%25B8&amp;amp;utm_term=%25EB%258F%2584%25EB%25A9%2594%25EC%259D%25B8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;가비아&lt;/a&gt;와 같은 사이트에서 도메인을 구매하고 AWS에서 별도의 세팅을 통해 도메인 설정을 해줍니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 하나의 인스턴스로 관리 (무료)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;두 서버를 하나의 서버에서 사용하여 쿠키가 공유되도록 합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Web</category>
      <category>AWS</category>
      <category>AWS EC2</category>
      <category>AWS 배포</category>
      <category>EC2</category>
      <category>EC2 생성</category>
      <category>react aws</category>
      <category>react aws 배포</category>
      <category>react ec2</category>
      <author>lheunoia</author>
      <guid isPermaLink="true">https://cherishvert.tistory.com/107</guid>
      <comments>https://cherishvert.tistory.com/107#entry107comment</comments>
      <pubDate>Wed, 3 May 2023 00:43:24 +0900</pubDate>
    </item>
    <item>
      <title>[HTTP] Cache-Control로 웹 서비스 캐시 다루기</title>
      <link>https://cherishvert.tistory.com/106</link>
      <description>&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;웹 어플리케이션에서는 네트워크 요청을 통해 필요한 리소스들을 받아옵니다. 만약 다음 요청에서 응답받을 리소스가 이전 요청에서 응답받은 리소스와 동일할 경우, 동일한 리소스에 대한 네트워크 요청은 응답 시간을 지연시킬 뿐더러 불필요한 네트워크 요청으로 서버의 자원을 낭비하게 됩니다. 이러한 경우에 &lt;b&gt;HTTP 캐싱&lt;/b&gt;을 활용하면 이전에 가져온 리소스들을 재사용함으로써 웹 어플리케이션의 성능을 현저하게 향상시킬 수 있습니다. HTTP 캐시를 효율적으로 관리하기 위해서는 &lt;span class=&quot;full-line-grey&quot;&gt;Cach-Control&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;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;  리소스(Resource)&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;HTTP 요청 대상&lt;/b&gt;으로, 텍스트, 이미지, 파일 등 식별 가능한 모든 자원을 말한다.&lt;/blockquote&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; ️ Cache-Control&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 브라우저가 지금껏 요청한 적이 없는 리소스를 서버에서 가져오려고 할 때, 서버와 브라우저는 완전한 HTTP 요청/응답을 주고 받습니다. 이후 HTTP 응답에 포함된 &lt;span class=&quot;full-line-grey&quot;&gt;Cache-Control&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 class=&quot;full-line-grey&quot;&gt;Cache-Control&lt;/span&gt; 헤더 필드는 브라우저 및 공유 캐시(ex. proxies, CDNs)의 &lt;b&gt;캐싱&lt;/b&gt;을 제어하는 &lt;b&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; &amp;zwj;♀️ &lt;/b&gt;&lt;b&gt;Response Directives&lt;/b&gt;&lt;/h2&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;max-age&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;max-age&lt;/span&gt;는 브라우저에 캐시되는 유효 기간을 나타냅니다. &lt;span class=&quot;full-line-grey&quot;&gt;max-age=N&lt;/span&gt;은 응답이 생성된 후 N초까지 응답이 fresh 상태임을 의미합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;캐시의 유효 기간이 지나기 전: 재사용&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_스크린샷 2023-05-02 오후 2.17.10.png&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H8UyP/btsdGAHbJXx/Jyqz5FczyOkTZp64kRKwsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H8UyP/btsdGAHbJXx/Jyqz5FczyOkTZp64kRKwsK/img.png&quot; data-alt=&quot;max-age=59&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H8UyP/btsdGAHbJXx/Jyqz5FczyOkTZp64kRKwsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH8UyP%2FbtsdGAHbJXx%2FJyqz5FczyOkTZp64kRKwsK%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;441&quot; height=&quot;430&quot; data-filename=&quot;edited_스크린샷 2023-05-02 오후 2.17.10.png&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;430&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;max-age=59&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;Cache-Control&lt;/span&gt; 응답 헤더 값이 &lt;span class=&quot;full-line-grey&quot;&gt;max-age=59&lt;/span&gt;이기 때문에 응답이 생성된 후 59초까지는 캐시된 응답을 &lt;b&gt;재사용&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;캐시의 유효 기간이 지난 후: 재검증&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-05-02 오후 2.26.49.png&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crBXW0/btsdEDEn42u/0lKUJnZ34ssJErUouCIUrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crBXW0/btsdEDEn42u/0lKUJnZ34ssJErUouCIUrk/img.png&quot; data-alt=&quot;304 Not Modified&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crBXW0/btsdEDEn42u/0lKUJnZ34ssJErUouCIUrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrBXW0%2FbtsdEDEn42u%2F0lKUJnZ34ssJErUouCIUrk%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;645&quot; height=&quot;195&quot; data-filename=&quot;스크린샷 2023-05-02 오후 2.26.49.png&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;284&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;304 Not Modified&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;캐시의 유효 기간이 지나면 브라우저는 서버에 캐시가 유효한 지에 대한 &lt;b&gt;재검증&lt;/b&gt; 요청을 보냅니다. 재검증 결과 브라우저의 캐시가 유효하다면 서버는&lt;span style=&quot;color: #333333; text-align: justify;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;[304 Not Modified]&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #333333; text-align: justify;&quot;&gt;응답을 내려줍니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;[304 Not Modified]&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: justify;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;응답은 HTTP 본문을 포함하지 않기 때문에 빠른 응답을 받을 수 있습니다.&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;&amp;nbsp;&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-05-02 오후 2.31.52.png&quot; data-origin-width=&quot;622&quot; data-origin-height=&quot;100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdiuWn/btsdBN1u74Y/kP51et9eWfWBCSzGs1nf41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdiuWn/btsdBN1u74Y/kP51et9eWfWBCSzGs1nf41/img.png&quot; data-alt=&quot;304 Not Modified&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdiuWn/btsdBN1u74Y/kP51et9eWfWBCSzGs1nf41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdiuWn%2FbtsdBN1u74Y%2FkP51et9eWfWBCSzGs1nf41%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;610&quot; height=&quot;98&quot; data-filename=&quot;스크린샷 2023-05-02 오후 2.31.52.png&quot; data-origin-width=&quot;622&quot; data-origin-height=&quot;100&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;304 Not Modified&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;5.5KB 리소스의 캐시 검증을 위해 &lt;b&gt;206B&lt;/b&gt; 사이즈만이 네트워크의 통신에 사용되었음을 알 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;재검증 결과 브라우저의 캐시가 유효하지 않다면&amp;nbsp;&lt;b&gt;[200 OK]&lt;/b&gt;&amp;nbsp;또는 적합한 상태 코드를 본문과 함께 내려줍니다. 추가로 HTTP 요청을 보내지 않고도 최신값을 내려받을 수 있기 때문에 효율적입니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;s-maxage&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;s-maxage&lt;/span&gt;는 &lt;i&gt;CDN&lt;/i&gt;(클라이언트와 서버의 중간 서버)에 캐시되는 유효 기간을 나타냅니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;max-age&lt;/span&gt;와 유사하지만 &lt;span class=&quot;full-line-grey&quot;&gt;s-maxage&lt;/span&gt;는 공유 캐시에만 적용되며 &lt;span class=&quot;full-line-grey&quot;&gt;max-age&lt;/span&gt;가 존재하는 경우 &lt;span class=&quot;full-line-grey&quot;&gt;max-age&lt;/span&gt;를 무시합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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-filename=&quot;스크린샷 2023-05-02 오후 3.19.22.png&quot; data-origin-width=&quot;1422&quot; data-origin-height=&quot;758&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvSICB/btsdBM9wQmh/deoqAGKtKP10tFlymYI9z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvSICB/btsdBM9wQmh/deoqAGKtKP10tFlymYI9z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvSICB/btsdBM9wQmh/deoqAGKtKP10tFlymYI9z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvSICB%2FbtsdBM9wQmh%2FdeoqAGKtKP10tFlymYI9z0%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;691&quot; height=&quot;368&quot; data-filename=&quot;스크린샷 2023-05-02 오후 3.19.22.png&quot; data-origin-width=&quot;1422&quot; data-origin-height=&quot;758&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;no-cache&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;no-cache&lt;/span&gt;는 응답이 &lt;b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;no-store&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;no-store&lt;/span&gt;은 어떤 종류의 캐시(private 또는 shared)도 이 &lt;b&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;&amp;nbsp;&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;span class=&quot;full-line-grey&quot;&gt;private&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;private&lt;/span&gt;은 응답이 &lt;b&gt;개인 캐시&lt;/b&gt;(ex. 브라우저의 로컬 캐시)에만 저장될 수 있음을 나타냅니다.&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;blockquote data-ke-style=&quot;style3&quot;&gt;  개인화된 콘텐츠, 특히 로그인 후 수신된 응답과 쿠키를 통해 관리되는 세션에 대해 &lt;span class=&quot;full-line-grey&quot;&gt;private&lt;/span&gt;을 추가해야 합니다. 이를 잊은 경우&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;해당 응답이 공유 캐시에 저장되어 여러 사용자로 인해 재사용될 수 있으며, 이로 인해 개인 정보가 유출될 수 있습니다.&lt;/blockquote&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;public&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;public&lt;/span&gt;은 응답이 &lt;b&gt;공유 캐시&lt;/b&gt;에 저장될 수 있음을 나타냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;  인증 헤더 필드에 있는 요청에 대한 응답은 공유 캐시에 저장해서는 안 됩니다. &lt;span class=&quot;full-line-grey&quot;&gt;public&lt;/span&gt;은 이러한 응답을 공유 캐시에 저장되도록 합니다.&lt;/blockquote&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;size18&quot;&gt;&lt;b&gt;  예제&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1682956947993&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Cache-Control: public, max-age=604800&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;  &lt;span class=&quot;full-line-grey&quot;&gt;s-maxage&lt;/span&gt; 또는 &lt;span class=&quot;full-line-grey&quot;&gt;must-revalidate&lt;/span&gt;는 위의 규정을 해제합니다. 요청에 인증 헤더가 없거나 이미 응답에서 &lt;span class=&quot;full-line-grey&quot;&gt;s-maxage&lt;/span&gt; 또는 &lt;span class=&quot;full-line-grey&quot;&gt;must-revalidate&lt;/span&gt;를 사용하고 있다면 &lt;span class=&quot;full-line-grey&quot;&gt;public&lt;/span&gt;을 사용할 필요가 없습니다.&lt;/blockquote&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;must-revalidate&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;must-revalidate&lt;/span&gt;는 응답을 캐시에 저장할 수 있으며 캐시가 신선한 동안 응답을 재사용할 수 있음을 나타냅니다. 응답이 오래된 경우, 재사용하기 전에 원본 서버에서 유효성을 검사해야 합니다. 일반적으로 &lt;span class=&quot;full-line-grey&quot;&gt;max-age&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  예제&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1683008978872&quot; class=&quot;lasso&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Cache-Control: max-age=604800, must-revalidate&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;  &lt;i&gt;HTTP&lt;/i&gt;는 원본 서버와의 연결이 끊어졌을 때 캐시에서 오래된 응답을 재사용하는 것을 허용합니다. &lt;span class=&quot;full-line-grey&quot;&gt;must-revalidate&lt;/span&gt;는 이러한 해프닝을 방지하는 방법입니다. 저장된 응답이 원본 서버로 재검증되거나 504(Gateway Timeout) 응답이 생성됩니다.&lt;/blockquote&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;stale-while-revalidate&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;stale-while-revalidate&lt;/span&gt;는 캐시에 대한 유효성을 재검증하는 동안 &lt;b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  예제&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1682957251041&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Cache-Control: max-age=604800, stale-while-revalidate=86400&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fdfdfd; color: #000000; text-align: start;&quot;&gt;위의 예제에서는 응답이 7일(604800s) 동안 신선합니다. 7일 후에는 오래되지만 백그라운드에서 응답을 재검증하는 경우 다음 날(86400s) 어떤 요청에 대해서든 캐시가 재사용될 수 있습니다 . 유효성 재확인은 캐시를 다시 &lt;b&gt;최신 상태로 만들어 클라이언트에게 해당 기간 동안 항상 최신 상태&lt;/b&gt;인 것처럼 보이게 하여&amp;nbsp;재확인으로 인한 대기 시간 페널티를 효과적으로 숨깁니다. 해당 기간 동안 요청이 발생하지 않으면 캐시가 오래되어 다음 요청이 정상적으로 재검증됩니다.&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>Web</category>
      <category>Cache-Control</category>
      <category>http cache-control</category>
      <category>max-age</category>
      <category>must-revalidate</category>
      <category>s-maxage</category>
      <category>stale-while-revalidate</category>
      <author>lheunoia</author>
      <guid isPermaLink="true">https://cherishvert.tistory.com/106</guid>
      <comments>https://cherishvert.tistory.com/106#entry106comment</comments>
      <pubDate>Tue, 2 May 2023 01:15:07 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 크레인 인형뽑기 게임 C++ (Lv.1)</title>
      <link>https://cherishvert.tistory.com/105</link>
      <description>&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/64061&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/64061&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1682950677461&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/64061&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fA19p/hySsiOgvu1/W4JfLopYtFZBkWJLbGBdBK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/zP986/hySsfYiPei/kzkHOUotkZKryvLjLPOze0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/64061&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/64061&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fA19p/hySsiOgvu1/W4JfLopYtFZBkWJLbGBdBK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/zP986/hySsfYiPei/kzkHOUotkZKryvLjLPOze0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;b&gt;2019 카카오 개발자 겨울 인턴십&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;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  문제 풀이&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 각 위치에서 가장 위에 있는 인형의 좌표를 담을 doll 벡터 선언&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;vector&amp;lt;pair&amp;lt;int, int&amp;gt;&amp;gt; doll(board[0].size() + 1, {-1, -1}); ⬅️ 위치는 1부터 시작하므로 board[0].size() + 1&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 각 위치에서 &lt;span class=&quot;half-line-yellow&quot;&gt;가장 위에 있는 인형의 좌표&lt;/span&gt; 담기 (빈 칸이 아니면 인형이 들어있는 칸) ⭐️&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. moves 벡터의 각 위치에 대해 가장 위에 있는 인형과 바구니에 담긴 인형(stack.top())이 같은 모양의 인형이면 &lt;b&gt;answer += 2&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 각 위치의 가장 위에 있는 인형의 좌표를 &lt;span class=&quot;half-line-yellow&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;&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;&amp;nbsp;&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; &amp;zwj;  C++ 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1682950721865&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;stack&amp;gt;

using namespace std;

int solution(vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; board, vector&amp;lt;int&amp;gt; moves) {
    int answer = 0;
    stack&amp;lt;int&amp;gt; s;
    vector&amp;lt;pair&amp;lt;int, int&amp;gt;&amp;gt; doll(board[0].size() + 1, {-1, -1});
    
    // 각 위치에서 가장 위에 있는 인형의 좌표 담기
    for (int i=0; i&amp;lt;board[0].size(); i++) {
        for (int j=0; j&amp;lt;board.size(); j++) {
            if (board[j][i] != 0) {
                doll[i + 1] = {j, i};
                break;
            }        
        }
    }
    
    for (int m: moves) {
        // 인형이 없는 곳에서는 아무런 일도 일어나지 않음
        if (doll[m].first == -1) continue;
        
        // 바구니에 담긴 인형과 같은 모양의 인형이면 두 인형은 터트려짐
        if (!s.empty() &amp;amp;&amp;amp; s.top() == board[doll[m].first][doll[m].second]) {
            answer += 2;
            s.pop();
        } else {
            s.push(board[doll[m].first][doll[m].second]);
        }
        
        // 가장 아래 칸이 아니면 아래 칸의 인형의 좌표 담기
        if (doll[m].first &amp;lt; board.size() - 1) doll[m] = {doll[m].first + 1, doll[m].second};
        else doll[m] = {-1, -1}; // 가장 아래 칸이면 더 이상 집을 인형이 없음
    }
    
    return answer;
}&lt;/code&gt;&lt;/pre&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-filename=&quot;스크린샷 2023-05-01 오후 11.19.10.png&quot; data-origin-width=&quot;617&quot; data-origin-height=&quot;403&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2uGOB/btsdhB12Mrj/scawY8SSV7FiYq0AytgUtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2uGOB/btsdhB12Mrj/scawY8SSV7FiYq0AytgUtK/img.png&quot; data-alt=&quot;프로그래머스 - 결과 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2uGOB/btsdhB12Mrj/scawY8SSV7FiYq0AytgUtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2uGOB%2FbtsdhB12Mrj%2FscawY8SSV7FiYq0AytgUtK%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;553&quot; height=&quot;361&quot; data-filename=&quot;스크린샷 2023-05-01 오후 11.19.10.png&quot; data-origin-width=&quot;617&quot; data-origin-height=&quot;403&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로그래머스 - 결과 화면&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>2019 카카오 개발자 겨울 인턴십</category>
      <category>C++</category>
      <category>프로그래머스 2019 카카오 개발자 겨울 인턴십 크레인 인형뽑기 게임</category>
      <category>프로그래머스 2019 카카오 개발자 겨울 인턴십 크레인 인형뽑기 게임 c++</category>
      <category>프로그래머스 크레인 인형뽑기 게임</category>
      <category>프로그래머스 크레인 인형뽑기 게임 c++</category>
      <author>lheunoia</author>
      <guid isPermaLink="true">https://cherishvert.tistory.com/105</guid>
      <comments>https://cherishvert.tistory.com/105#entry105comment</comments>
      <pubDate>Mon, 1 May 2023 23:37:52 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 키패드 누르기 C++ (Lv.1)</title>
      <link>https://cherishvert.tistory.com/104</link>
      <description>&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/67256&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/67256&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1682949272704&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/67256&quot; data-og-url=&quot;https://progra mmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/EaFx9/hyStMNICP2/YhYpLy84jzoiFqoc2U2uk1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/fEKTM/hySsavWS54/2XtkKXfn8HkbN6SR6lKNWk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/67256&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/67256&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/EaFx9/hyStMNICP2/YhYpLy84jzoiFqoc2U2uk1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/fEKTM/hySsavWS54/2XtkKXfn8HkbN6SR6lKNWk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;b&gt;2020 카카오 인턴십&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;&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;&amp;nbsp;&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;  문제 풀이&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⭐️ * ➡️ 10, 0 ➡️ 11, # ➡️ 12로 생각하기&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;1. 맨 처음 왼손 엄지손가락 위치를 10, 오른손 엄지손가락 위치를 12로 초기화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 누를 번호 &lt;b&gt;1, 4, 7&lt;/b&gt; ➡️ 왼손 엄지손가락으로  입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 누를 번호 &lt;b&gt;3, 6, 9&lt;/b&gt; ➡️ 오른손 엄지손가락으로 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 누를 번호 &lt;b&gt;2, 5, 8, 0&lt;/b&gt; ➡️ 왼손 엄지손가락과의 거리와 오른손 엄지손가락과의 거리 비교&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;zwj;♀️ &lt;span class=&quot;half-line-yellow&quot;&gt;거리가&amp;nbsp;다르다면 누를 번호와 더 가까운&lt;/span&gt; 엄지손가락을 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  거리 계산: | (엄지손가락 위치 - 누를 번호) / 3 | + | (엄지손가락 위치 - 누를 번호) % 3 |&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;  &lt;span class=&quot;half-line-yellow&quot;&gt;거리가&amp;nbsp;같다면 hand에 따라&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;&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;&amp;nbsp;&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; &amp;zwj;  C++ 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1682949342719&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;

string solution(vector&amp;lt;int&amp;gt; numbers, string hand) {
    string answer = &quot;&quot;;
    int lefthand = 10;
    int righthand = 12;
    
    for (int number: numbers) {
        if (number == 1 || number == 4 || number == 7) {
            answer += 'L';
            lefthand = number;
        }
        
        else if (number == 3 || number == 6 || number == 9) {
            answer += 'R';
            righthand = number;
        }
        
        else {
            if (number == 0) number = 11;
            
            int leftDistance = abs((lefthand - number) / 3) + abs((lefthand - number) % 3);
            int rightDistance = abs((righthand - number) / 3) + abs((righthand - number) % 3);
            
            if (leftDistance &amp;lt; rightDistance) {
                answer += 'L';
                lefthand = number;
            } else if (leftDistance == rightDistance) {
                if (hand == &quot;left&quot;) {
                    answer += 'L';
                    lefthand = number;
                } else {
                    answer += 'R';
                    righthand = number;
                }
            } else {
                answer += 'R';
                righthand = number;
            }
        }
    }
    
    return answer;
}&lt;/code&gt;&lt;/pre&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-filename=&quot;스크린샷 2023-05-01 오후 10.56.08.png&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;341&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byQvcz/btsdBM8meTc/wYZkhJkYwIiRbb0bSKQAAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byQvcz/btsdBM8meTc/wYZkhJkYwIiRbb0bSKQAAk/img.png&quot; data-alt=&quot;프로그래머스 - 결과 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byQvcz/btsdBM8meTc/wYZkhJkYwIiRbb0bSKQAAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyQvcz%2FbtsdBM8meTc%2FwYZkhJkYwIiRbb0bSKQAAk%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;522&quot; height=&quot;328&quot; data-filename=&quot;스크린샷 2023-05-01 오후 10.56.08.png&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;341&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로그래머스 - 결과 화면&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;&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>2020 카카오 인턴십</category>
      <category>C++</category>
      <category>level1</category>
      <category>프로그래머스 2020 카카오 인턴십 키패드 누르기</category>
      <category>프로그래머스 2020 카카오 인턴십 키패드 누르기 c++</category>
      <category>프로그래머스 키패드 누르기</category>
      <category>프로그래머스 키패드 누르기 c++</category>
      <author>lheunoia</author>
      <guid isPermaLink="true">https://cherishvert.tistory.com/104</guid>
      <comments>https://cherishvert.tistory.com/104#entry104comment</comments>
      <pubDate>Mon, 1 May 2023 23:14:39 +0900</pubDate>
    </item>
    <item>
      <title>[Next.js] SSR 페이지에서 session pre-fetch 하기 (next-auth)</title>
      <link>https://cherishvert.tistory.com/103</link>
      <description>&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Groom_Logo_White.png&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;142&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baKXjo/btsdhAah22m/mDkKzvZQG8dKrKBPfaaIDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baKXjo/btsdhAah22m/mDkKzvZQG8dKrKBPfaaIDk/img.png&quot; data-alt=&quot;Groom Blog Logo&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baKXjo/btsdhAah22m/mDkKzvZQG8dKrKBPfaaIDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaKXjo%2FbtsdhAah22m%2FmDkKzvZQG8dKrKBPfaaIDk%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;354&quot; height=&quot;157&quot; data-filename=&quot;Groom_Logo_White.png&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;142&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Groom Blog Logo&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;현재(2023.04.30) &lt;i&gt;Next.js&lt;/i&gt; 프레임워크를 사용하여 블로그를 개발 중에 있습니다. 블로그에서의 사용자 인증은 &lt;i&gt;next-auth&lt;/i&gt; 라이브러리로 구현했습니다. &lt;i&gt;next-auth&lt;/i&gt; 라이브러리에서 제공하는 &lt;span class=&quot;full-line-grey&quot;&gt;NextAuth&lt;/span&gt;는 로그인 시 &lt;span class=&quot;full-line-grey&quot;&gt;signIn&lt;/span&gt; 메소드를 통해 사용자의 정보를 &lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;에 저장하기 때문에 사용자의 정보를 가져오거나 로그인/로그아웃 상태를 판별할 때&amp;nbsp;&lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;을 사용하면 편리합니다. 이번 포스트에서는 &lt;i&gt;Next.js&lt;/i&gt; 페이지에 적용한 렌더링 방식과 그 렌더링 방식에서&amp;nbsp;&lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;을 &lt;b&gt;pre-fetch&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  Why SSG -&amp;gt; SSR?&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; 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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-04-30 오후 10.23.10.png&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1nN9x/btsdduCgqRg/l9XK5pFBzgueWDicHnSXy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1nN9x/btsdduCgqRg/l9XK5pFBzgueWDicHnSXy1/img.png&quot; data-alt=&quot;Next.js 공식 문서 &amp;amp;gt; Pages&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1nN9x/btsdduCgqRg/l9XK5pFBzgueWDicHnSXy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1nN9x%2FbtsdduCgqRg%2Fl9XK5pFBzgueWDicHnSXy1%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;676&quot; height=&quot;141&quot; data-filename=&quot;스크린샷 2023-04-30 오후 10.23.10.png&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Next.js 공식 문서 &amp;gt; Pages&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;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;Next.js&lt;/i&gt;&lt;span style=&quot;color: #333333; text-align: justify;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;공식 문서에서는 &quot;성능 상의 이유로 서버 측 렌더링을 통한 정적 생성 방식을 사용하는 것을 권장한다. 정적으로 생성된 페이지는 성능 향상을 위해 별도의 구성 없이 &lt;i&gt;CDN&lt;/i&gt;에 의해 캐시될 수 있으나 &lt;i&gt;Server-side Rendering&lt;/i&gt; 방식이 유일한 옵션일 수 있다.&quot;고 설명합니다. 글쓴이의 경우, 개발 중인 공유 블로그의 성향과 기존 방식(SSG)의 제약 사항때문에 &lt;b&gt;SSR&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 공유 블로그의 성향&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;개발 중인 블로그는 개인 블로그가 아닌, &lt;i&gt;velog&lt;/i&gt;와 같이 여러 사람이 함께 사용할 수 있도록 만든 블로그입니다. 여러 사용자들이 함께 사용하는 블로그이니 만큼 페이지마다 &lt;b&gt;데이터의 변화가 잦고&lt;/b&gt;, 블로그의 특성상 &lt;b&gt;검색 엔진 최적화(SEO)&lt;/b&gt;를 요구합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 기존 방식(SSG)의 문제점&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;getStaticProps&lt;/span&gt; 함수의 &lt;span class=&quot;full-line-grey&quot;&gt;context&lt;/span&gt; 파라미터에는 &lt;span class=&quot;full-line-grey&quot;&gt;req&lt;/span&gt; 속성이 존재하지 않기 때문에 &lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;을 pre-fetch 할 수 없습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;을 pre-fetch하지 못해 발생하는 문제는 아래와 같습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;1. 페이지 재요청마다 사용자 관련 데이터를 포함한 컴포넌트가 깜빡인다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ➡️&amp;nbsp; 사용자의 경험을 감소시킨다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;2. 페이지 재요청마다 &lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;을 서버에 요청힌다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ➡️ 불필요한 리소스 요청으로 서버의 성능을 저하시킨다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-05-01 오전 12.45.27.png&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H1JQZ/btsdeZO09M7/CFPVsfYEQPpQ5yR4StVBDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H1JQZ/btsdeZO09M7/CFPVsfYEQPpQ5yR4StVBDK/img.png&quot; data-alt=&quot;session API&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H1JQZ/btsdeZO09M7/CFPVsfYEQPpQ5yR4StVBDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH1JQZ%2FbtsdeZO09M7%2FCFPVsfYEQPpQ5yR4StVBDK%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;508&quot; height=&quot;142&quot; data-filename=&quot;스크린샷 2023-05-01 오전 12.45.27.png&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;222&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;session API&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  SSR 방식에서 session pre-fetch 하기&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;getServerSideProps&lt;/span&gt; 함수의 &lt;span class=&quot;full-line-grey&quot;&gt;context&lt;/span&gt; 파라미터에는 &lt;span class=&quot;full-line-grey&quot;&gt;req&lt;/span&gt; 속성이 존재하기 때문에 &lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;을 &lt;b&gt;pre-fetch&lt;/b&gt; 할 수 있습니다!  &lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. &amp;nbsp;getSession 메소드로 session pre-fetch&lt;/b&gt;&lt;/h3&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;span class=&quot;half-line-yellow&quot;&gt;&lt;b&gt;pages/index.tsx&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1682871066049&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { GetServerSideProps } from 'next';
import { getSession } from 'next-auth/react';
import { dehydrate, QueryClient } from '@tanstack/react-query';

import getUserWithEmail from '../apis/user/getUserWithEmail';

const Home = () =&amp;gt; {
	// 생략...
};

// Home 컴포넌트보다 먼저 실행
export const getServerSideProps: GetServerSideProps = async (context) =&amp;gt; {
  const session = await getSession(context);
  const email = session ? session.user.email : null;

  const queryClient = new QueryClient();
  context.res.setHeader('Cache-Control', 'public, max-age=59');

  // 유저 정보를 캐시
  await queryClient.prefetchQuery(['user', email], () =&amp;gt; getUserWithEmail(email));

  return {
    props: {
      session,
      dehydratedState: dehydrate(queryClient),
    },
  };
};&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;next-auth/react&lt;/i&gt; 라이브러리의 &lt;span class=&quot;full-line-grey&quot;&gt;getSession&lt;/span&gt; 메소드를 통해 &lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;을 응답받고, &lt;span class=&quot;full-line-grey&quot;&gt;session.user.email&lt;/span&gt;을 query key로 하여 유저 정보를 캐시합니다. (Home 컴포넌트를 포함한 자식 컴포넌트에서 &lt;span class=&quot;full-line-grey&quot;&gt;StaleTime&lt;/span&gt; 이내에 동일한 쿼리를 참조했을 경우, 캐시된 유저 정보를 응답받기 위해) 응답받은 &lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;과 &lt;span class=&quot;full-line-grey&quot;&gt;queryClient&lt;/span&gt;를 반환하여 &lt;b&gt;최상위 페이지(_app.ts) props&lt;/b&gt;로 전달합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; 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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 자식 컴포넌트에 session 내려주기&lt;/b&gt;&lt;/h3&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;span class=&quot;half-line-yellow&quot;&gt;&lt;b&gt;pages/_app.tsx&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1682871490093&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useEffect, useState } from 'react';
import Head from 'next/head';
import { SessionProvider } from 'next-auth/react';
import { RecoilRoot } from 'recoil';
import { QueryClientProvider, QueryClient, Hydrate } from '@tanstack/react-query';

const App = ({ Component, pageProps: { session, ...pageProps } }) =&amp;gt; {
  const [queryClient] = useState(() =&amp;gt; new QueryClient());
	
  // 콘솔에 session이 잘 찍히는지 확인해 보세요.
  console.log('session', session);

  return (
    &amp;lt;&amp;gt;
      &amp;lt;SessionProvider session={session}&amp;gt; // Component 컴포넌트에 session 내려줌
        &amp;lt;QueryClientProvider client={queryClient}&amp;gt;
          &amp;lt;Hydrate state={pageProps.dehydratedState}&amp;gt;
            &amp;lt;RecoilRoot&amp;gt;
                &amp;lt;Head&amp;gt;
                  &amp;lt;title&amp;gt;Groom&amp;lt;/title&amp;gt;
                &amp;lt;/Head&amp;gt;
                &amp;lt;Component {...pageProps} /&amp;gt; // pre-fetch된 session 사용 가능
            &amp;lt;/RecoilRoot&amp;gt;
          &amp;lt;/Hydrate&amp;gt;
        &amp;lt;/QueryClientProvider&amp;gt;
      &amp;lt;/SessionProvider&amp;gt;
    &amp;lt;/&amp;gt;
  );
};

export default App;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지 컴포넌트에서 전달한 &lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;을 &lt;span class=&quot;full-line-grey&quot;&gt;SessionProvider&lt;/span&gt; 컴포넌트의 &lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt; 속성에 전달합니다. 그러면 &lt;span class=&quot;full-line-grey&quot;&gt;SessionProvider&lt;/span&gt;로 감싼 &lt;span class=&quot;full-line-grey&quot;&gt;Component&lt;/span&gt; 컴포넌트 중 &lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;을 전달한 컴포넌트를 포함한 하위 컴포넌트에서 pre-fetch된 &lt;span class=&quot;full-line-grey&quot;&gt;session&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. useSession 훅으로 session 사용하기&lt;/b&gt;&lt;/h3&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;span class=&quot;half-line-yellow&quot;&gt;&lt;b&gt;components/main/UserProfile.tsx&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1682872332074&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useEffect } from 'react';
import { useSession, signOut } from 'next-auth/react';\

import { useGetUser, useGetUserWithEmail } from '../../hooks/query/user';
import SkeletonUserProfile from '../skeleton/SkeletonUserProfile';
import * as S from '../../styles/ts/components/main/UserProfile';

const UserProfile = () =&amp;gt; {
  const { data: session } = useSession(); // pre-fetch된 session
  
  // 캐시된 유저 정보가 존재하므로 서버에 요청하지 않음
  const { data: user, isLoading } = session ? useGetUserWithEmail(session.user.email) : useGetUser();

  useEffect(() =&amp;gt; {
    if (session?.user === null) {
      alert('세션이 만료되었습니다.');
      signOut({ redirect: false });
    }
  }, [session]);

  return (
   &amp;lt;S.UserProfileWrapper&amp;gt;
      {isLoading ? ( // 캐시된 유저 정보가 있으므로 isLoading: false
        &amp;lt;SkeletonUserProfile /&amp;gt;
      ) : (
        // 생략...
      )}
    &amp;lt;/S.UserProfileWrapper&amp;gt;
  );
};

export default UserProfile;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;을 전달한 컴포넌트를 포함한 하위 컴포넌트에서 &lt;span class=&quot;full-line-grey&quot;&gt;useSession&lt;/span&gt; 훅을 사용하면 &lt;b&gt;pre-fetch&lt;/b&gt;된 &lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;을 사용할 수 있습니다. &lt;i&gt;index.tsx&lt;/i&gt;에서 &lt;span class=&quot;full-line-grey&quot;&gt;getUserWithEmail&lt;/span&gt; 함수를 호출하여 유저 정보를 캐시해 놓았고, ['user', email] 쿼리 키의 &lt;span class=&quot;full-line-grey&quot;&gt;staleTime&lt;/span&gt;을 &lt;i&gt;infinity&lt;/i&gt;로 설정해 두었기 때문에 index 페이지를 재요청해도(새로고침해도) 유저 정보를 새로 불러오지 않고, 캐시한 데이터를 재사용합니다.&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;&amp;nbsp;&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;4. 결과&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;기존 방식 (SSG) - &lt;/b&gt;&lt;b&gt;페이지 재요청 시 서버에 유저 정보 요청&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면-기록-2023-05-01-오후-3.15.43.gif&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;1076&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d7WooT/btsdlKKCBin/spcvCOLTwCi39EjLydzIwk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d7WooT/btsdlKKCBin/spcvCOLTwCi39EjLydzIwk/img.gif&quot; data-alt=&quot;SSG&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d7WooT/btsdlKKCBin/spcvCOLTwCi39EjLydzIwk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/d7WooT/btsdlKKCBin/spcvCOLTwCi39EjLydzIwk/img.gif&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;705&quot; height=&quot;396&quot; data-filename=&quot;화면-기록-2023-05-01-오후-3.15.43.gif&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;1076&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSG&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;수정한 방식 (SSR) - 페이지 재요청 시 캐시된 유저 정보 재사용&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면-기록-2023-05-01-오후-3.08.12.gif&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;1076&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CpT0t/btsdgSCuzWb/hf8WTyhEPznQRGw9EZ8Be1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CpT0t/btsdgSCuzWb/hf8WTyhEPznQRGw9EZ8Be1/img.gif&quot; data-alt=&quot;SSR&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CpT0t/btsdgSCuzWb/hf8WTyhEPznQRGw9EZ8Be1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/CpT0t/btsdgSCuzWb/hf8WTyhEPznQRGw9EZ8Be1/img.gif&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;714&quot; height=&quot;401&quot; data-filename=&quot;화면-기록-2023-05-01-오후-3.08.12.gif&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;1076&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSR&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  React Query 사용하지 않는 경우&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;+ session 속성 재정의하기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;react-query&lt;/i&gt; 라이브러리를 사용하지 않는다면 오로지 &lt;span class=&quot;full-line-grey&quot;&gt;session&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-05-01 오후 2.31.32.png&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vOAjY/btsdefSoY7A/KAcAo7rUkfVDKKydmCpIJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vOAjY/btsdefSoY7A/KAcAo7rUkfVDKKydmCpIJK/img.png&quot; data-alt=&quot;session 객체&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vOAjY/btsdefSoY7A/KAcAo7rUkfVDKKydmCpIJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvOAjY%2FbtsdefSoY7A%2FKAcAo7rUkfVDKKydmCpIJK%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;672&quot; height=&quot;168&quot; data-filename=&quot;스크린샷 2023-05-01 오후 2.31.32.png&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;session 객체&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 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;기존 &lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;의 user 객체에는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;full-line-grey&quot;&gt;email&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;&lt;span class=&quot;full-line-grey&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;속성만 존재하기 때문에 &lt;i&gt;User&lt;/i&gt; 모델에 정의되어 있는 속성을 사용하려면 몇 가지 설정을 해주어야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;1. interface 키워드를 통해 Session 객체 확장&lt;/span&gt;&lt;/b&gt;&lt;/h3&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;span class=&quot;half-line-yellow&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;@types/next-auth.d.ts&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1682919544471&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import NextAuth from 'next-auth';
import { PostItem, UserType } from '../types';

// session.user 속성 재정의
declare module 'next-auth' {
  interface Session {
    user: {
      id: number;
      email: string;
      name: string;
      imageUrl: string;
      posts: PostItem[];
      neighbors: UserType[];
    };
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;i&gt;@types&lt;/i&gt; 폴더 안에 &lt;i&gt;next-auth.d.ts&lt;/i&gt; 이름의 파일을 생성한 후 위와 같이 코드를 작성합니다. &lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;User 모델의 속성 중 사용하려는 속성을 작성하여 &lt;span class=&quot;full-line-grey&quot;&gt;Session&lt;/span&gt;의 &lt;span class=&quot;full-line-grey&quot;&gt;user&lt;/span&gt; 객체를 선언적으로 확장합니다. (&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span class=&quot;full-line-grey&quot;&gt;interface&lt;/span&gt;의 선언적 확장은 &lt;a href=&quot;https://cherishvert.tistory.com/46&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기&lt;/a&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 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;&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;span class=&quot;half-line-yellow&quot;&gt;&lt;b&gt;pages/api/auth/[...nextauth].ts&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1682919991215&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import NextAuth from 'next-auth';
import prisma from '../../../lib/prisma';

export default NextAuth({
  providers: [
    // 생략...
  ],
  callbacks: {
    async session({ session }) {
    // 데이터베이스에서 유저의 정보 가져오기
      const user = await prisma.user.findUnique({
        where: { email: session.user?.email },
        select: {
          id: true,
          email: true,
          name: true,
          imageUrl: true,
          posts: {
            select: {
              id: true,
              title: true,
              category: {
                select: {
                  name: true,
                },
              },
              isPublic: true,
              allowComments: true,
            },
          },
          neighbors: {
            select: {
              id: true,
            },
          },
        },
      });

      session.user = user;
      return session;
    },
  },
  secret: process.env.NEXTAUTH_SECRET,
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 &lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt; 콜백 함수를 추가하면 &lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt; 콜백 함수가 호출될 때마다 select한 속성을 포함한 유저의 정보를 가져옵니다.&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;  &lt;b&gt;session 콜백 함수가 호출되는 경우&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/session endpoint 호출&lt;/li&gt;
&lt;li&gt;useSession 사용 (only Client Side)&lt;/li&gt;
&lt;li&gt;getSession 사용 (only Client Side)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 재정의된 속성이 추가된 session.user&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-05-01 오후 2.37.18.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;392&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BbeJu/btsdemYhsQO/xQuqMfxWAAnEDRKMM1rKmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BbeJu/btsdemYhsQO/xQuqMfxWAAnEDRKMM1rKmk/img.png&quot; data-alt=&quot;재정의된 session.user&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BbeJu/btsdemYhsQO/xQuqMfxWAAnEDRKMM1rKmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBbeJu%2FbtsdemYhsQO%2FxQuqMfxWAAnEDRKMM1rKmk%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;574&quot; height=&quot;225&quot; data-filename=&quot;스크린샷 2023-05-01 오후 2.37.18.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;392&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;재정의된 session.user&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 class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;을 콘솔에 출력하여 재정의된 속성이 추가되어 잘 나타나는지 확인해 보세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 &lt;span class=&quot;full-line-grey&quot;&gt;session&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  개선할 점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSR 방식에서&amp;nbsp;&lt;span class=&quot;full-line-grey&quot;&gt;session&lt;/span&gt;을 pre-fetch하여 기존의 문제점들을 해결했으나 속도가 느린 이슈가 존재합니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;SSG 방식에서의 index.json 로드&lt;/b&gt;&lt;/h4&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-filename=&quot;스크린샷 2023-05-01 오후 3.21.15.png&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nX2cK/btsddZI4poi/b6IMIPbnCMhUNeUakoRGP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nX2cK/btsddZI4poi/b6IMIPbnCMhUNeUakoRGP1/img.png&quot; data-alt=&quot;SSG - index.json&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nX2cK/btsddZI4poi/b6IMIPbnCMhUNeUakoRGP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnX2cK%2FbtsddZI4poi%2Fb6IMIPbnCMhUNeUakoRGP1%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;425&quot; height=&quot;357&quot; data-filename=&quot;스크린샷 2023-05-01 오후 3.21.15.png&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSG - index.json&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&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;SSR &lt;b&gt;방식에서의 index.json 로드&lt;/b&gt;&lt;/b&gt;&lt;/h4&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-filename=&quot;스크린샷 2023-05-01 오후 3.27.38.png&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;658&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnDPm6/btsdwtH237G/NS2yfk5ZtEDIV41HHJubr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnDPm6/btsdwtH237G/NS2yfk5ZtEDIV41HHJubr0/img.png&quot; data-alt=&quot;SSR - index.json&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnDPm6/btsdwtH237G/NS2yfk5ZtEDIV41HHJubr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnDPm6%2FbtsdwtH237G%2FNS2yfk5ZtEDIV41HHJubr0%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;422&quot; height=&quot;355&quot; data-filename=&quot;스크린샷 2023-05-01 오후 3.27.38.png&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;658&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSR - index.json&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;&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;i&gt;Waiting for server response&lt;/i&gt;를 비교해보면 SSG 방식이 SSR 방식보다 &lt;b&gt;약 416배&lt;/b&gt; 빠른 것을 알 수 있습니다. SSR 방식에서는 &lt;span class=&quot;full-line-grey&quot;&gt;Cache-Control&lt;/span&gt; 속성을 설정하여 캐시의 유효 기간을 설정할 수 있는데요. 현재는 &lt;b&gt;max-age=59&lt;/b&gt;로 설정해 두었기 때문에 59초 이내의 요청에 대해서는 캐시된 HTML 파일을 재사용합니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;59초 이내 요청의 경우&lt;/b&gt;&lt;/h4&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-filename=&quot;스크린샷 2023-05-01 오후 3.33.42.png&quot; data-origin-width=&quot;1086&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lsAHO/btsdpzhJqbz/zqBkzFEBw6kC5vN7wy7Gnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lsAHO/btsdpzhJqbz/zqBkzFEBw6kC5vN7wy7Gnk/img.png&quot; data-alt=&quot;SSR - from disk cache&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lsAHO/btsdpzhJqbz/zqBkzFEBw6kC5vN7wy7Gnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlsAHO%2FbtsdpzhJqbz%2FzqBkzFEBw6kC5vN7wy7Gnk%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;641&quot; height=&quot;378&quot; data-filename=&quot;스크린샷 2023-05-01 오후 3.33.42.png&quot; data-origin-width=&quot;1086&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSR - from disk cache&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-05-01 오후 3.34.07.png&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nWcjG/btsdemqskms/Y0HdtxQh9F3BUGOhDKkYg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nWcjG/btsdemqskms/Y0HdtxQh9F3BUGOhDKkYg0/img.png&quot; data-alt=&quot;SSR - from disk cache&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nWcjG/btsdemqskms/Y0HdtxQh9F3BUGOhDKkYg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnWcjG%2Fbtsdemqskms%2FY0HdtxQh9F3BUGOhDKkYg0%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;540&quot; height=&quot;175&quot; data-filename=&quot;스크린샷 2023-05-01 오후 3.34.07.png&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSR - from disk cache&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;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;59초 내에 페이지를 재요청하면 &lt;b&gt;memory&lt;/b&gt; 또는 &lt;b&gt;disk&lt;/b&gt;에 캐시된 데이터를 곧바로 내려주기 때문에 훨씬 빠른 응답을 받을 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;다음 포스터에서는 &lt;span class=&quot;full-line-grey&quot;&gt;Cache-Control&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Next.js</category>
      <category>Cache-Control</category>
      <category>cache-control max-age</category>
      <category>next.js</category>
      <category>next.js session</category>
      <category>next.js session pre-fetch</category>
      <category>Session</category>
      <category>session pre-fetch</category>
      <category>SSR session</category>
      <category>SSR session pre-fetch</category>
      <author>lheunoia</author>
      <guid isPermaLink="true">https://cherishvert.tistory.com/103</guid>
      <comments>https://cherishvert.tistory.com/103#entry103comment</comments>
      <pubDate>Mon, 1 May 2023 01:41:48 +0900</pubDate>
    </item>
  </channel>
</rss>