<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>라봉이의 개발 블로그</title>
    <link>https://psyhm.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sat, 30 May 2026 23:54:29 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Labhong</managingEditor>
    <image>
      <title>라봉이의 개발 블로그</title>
      <url>https://tistory1.daumcdn.net/tistory/2884159/attach/696605f098e44b17aa7c87f00b34a5ea</url>
      <link>https://psyhm.tistory.com</link>
    </image>
    <item>
      <title>스크럼 마스터(scrum master)의 업무</title>
      <link>https://psyhm.tistory.com/56</link>
      <description>&lt;h1&gt;서론&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 현재 근무하는 회사에서 백엔드 개발자로 일하고 있다. 회사에 입사하고 1년 정도 됐을 때, 팀에서 스크럼 마스터(Scrum Master) 역할을 맡을 기회가 있어서 그 역할에 자원했다. 무언가 새로운 시도를 해보고 싶었기 때문이기도 했고 팀이나 팀원 매니징에도 관심이 있었기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 스크럼 마스터 역할을 부여 받았을 땐 구체적으로 무엇을 해야하는지 전혀 감이 오지 않았다. 대학도 컴퓨터를 전공하고 일도 개발자로 시작한 나는 명시적이고 구체적인 일만 할 줄 알았지 소프트 스킬이 필요한 업무는 해보질 않았기 때문이다. 다행히 팀의 Product Owner가 간단한 가이드 문서를 만들어줬고 그걸 보면서 차근차근 시도해보기 시작했다. 그래서 그 이후로부터 약 1년 동안 백엔드 개발도 하면서 스크럼 마스터 역할을 겸임해왔다. 그 경험을 토대로 스크럼 마스터의 해야할 일을 조금이나마 정의해볼 수 있었다.&lt;/p&gt;
&lt;h1&gt;스크럼과 스크럼 마스터&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크럼 마스터가 무엇을 해야하는지 알기 전에 스크럼(Scrum)에 대해 간단히 짚고 넘어가보려고 한다. 스크럼이 무엇이길래 IT 개발할 때 그렇게 많이들 사용하는지, 그리고 스크럼 마스터는 무엇을 하는 역할인지 정리해봤다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;스크럼(Scrum)&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크럼은 &lt;b&gt;복잡한 문제를 팀이 협업하고 작업을 구조화 할 수 있도록 돕는 업무 프레임워크&lt;/b&gt;이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;스크럼(Scrum)&lt;/b&gt;은 애자일 진영에서 사용하는 업무 프레임워크이다. 말 그대로 업무 프레임워크이기 때문에 어떤 업무를 하던 적용이 가능하다. IT 서비스가 점점 더 고도화 되면서 주로 복잡한 문제를 풀어야하는 IT 쪽에서 많이 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 스크럼은 사람들의 관계와 상호 작용을 안내하는 최소한의 규칙 집합이기도 하다. 스크럼은 어떤 방법론이 아니다. 제품을 개발할 때 직면하는 문제에 대한 해결책을 사람, 팀 및 조직이 상호 작용을 통해 직접 해결해야 한다. 스크럼은 그것을 도와줄 뿐이다. 또한 스크럼은 복잡한 문제를 해결하는데 도움을 주고 내부의 문제를 드러낼 수 있도록 가이드한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;스크럼 마스터(Scrum Master)&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크럼 마스터는 &lt;b&gt;스크럼이 잘 수행되도록 보장하는 역할&lt;/b&gt;이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크럼이 업무 프레임워크라면 &lt;b&gt;스크럼 마스터(Scrum Master)&lt;/b&gt;는 이 업무 프레임워크가 팀 내에서 잘 돌아가게 만드는 역할이다. 그렇기 때문에 스크럼과 스크럼의 가치에 대해 잘 알고 있어야 하며, 스크럼이 팀에 잘 녹아들 수 있게 해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크럼 마스터가 매니징 즉 관리자의 역할을 해야하는 것으로 착각할 수도 있다. 나 또한 스크럼 마스터는 그런 줄 알았다. 하지만 &lt;b&gt;스크럼이 잘 수행되도록 보장하는 역할&lt;/b&gt;이 스크럼 마스터이기 때문에 관리자라기 보다는 팀이 스크럼 프레임워크를 통해 일을 더 잘할 수 있게 만드는 서포터에 가깝다고 생각한다. 팀을 위해 기꺼이 희생하고 섬기는 하인(servant)이 되어야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;스크럼 마스터 할 일 3가지&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 스크럼 마스터는 스크럼이 잘 수행되도록 무엇을 해야 할까? 약 1년의 경험을 토대로 나는 스크럼 마스터가 해야할 일을 3가지로 요약해볼 수 있었다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;[스크럼 실천] 스크럼 행동 패턴을 만들어 팀이 이를 잘 유지하게 만들기&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;[퍼실리테이트] 스쿼드가 목표를 달성하기 위한 모든 일들의 &amp;ldquo;협력적 참여&amp;rdquo;를 유도&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;[문제 해결] 스크럼이 진행되는 과정 중 불확실성을 찾고 장애물을 해소&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. [스크럼 실천] 스크럼 행동 패턴을 만들어 팀이 이를 잘 유지하게 만들기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 가장 중요하게 생각하는 업무이다. 스크럼이 잘 유지될 수 있도록 스크럼 이벤트를 주기적으로 챙기거나 스크럼 아티팩트(산출물)을 관리하는 업무이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크럼은 복잡한 문제를 경험주의적 접근 방법을 통해 가치 전달을 극대화한다. 그리고 이 경험주의를 위해 스크럼에서는 중요하게 여기는 세 가지 요소가 있다. 바로 투명성(Transparency), 점검(Inspection), 적응(Adaption)이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;투명성(Transparency)&lt;/b&gt;이란 업무를 수행하거나 일의 결과물을 받는 사람들에게 신규 업무 프로세스와 일이 무엇인지 잘 나타내는 것을 의미한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;점검(Inspection)&lt;/b&gt;이란 바람직하지 않는 변화와 문제점을 발견하기 위한 일련의 활동을 의미한다. 적응을 하기 위해 꼭 필요한 활동이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;적응(Adaption)&lt;/b&gt;이란 점검한 결과를 바탕으로 더 나은 변화와 문제점을 개선하기 위한 활동을 의미한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크럼이 잘 유지된다는 것은 이 세 가지가 잘 지켜진다는 것이라고 생각한다. 그리고 이 세 가지를 잘 지킬 수 있도록 도움을 주는 중요한 요소들이 있다. 위에서 말한 &lt;b&gt;3가지 아티팩트(산출물)&lt;/b&gt;와 &lt;b&gt;5가지의 이벤트&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;스크럼 아티팩트(Scrum Artifacts)&lt;/b&gt;는 프로덕트 백로그, 스프린트 백로그, 증가분(Increment)을 의미한다. 이 세 가지는 핵심 정보의 투명성을 극대화할 수 있도록 설계되어 있다. 스크럼은 아티팩트를 통해 팀이 어떤 일을 해야하는지, 우리가 어떤 것을 만들어가고 있는지를 투명하게 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 &lt;b&gt;스크럼 이벤트(Scrum Events)&lt;/b&gt;는 스프린트, 스프린트 플래닝, 데일리 스크럼, 스프린트 리뷰, 스프린트 회고를 의미한다. 주기적으로 챙겨지는 스크럼 이벤트를 통해 팀은 바람직하지 않는 변화와 문제점을 조기에 발견할 수 있다. 이 문제점이 밝혀졌을 때 우리는 문제점을 해결할 수 있는 방법을 시도해보고 적응해나가는 과정을 거쳐가며 가치 전달을 극대화 하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 스크럼 마스터는 이 3가지 아티팩트와 5가지 이벤트를 관리하면서 팀 내에 투명성, 점검, 그리고 적응이 지속적으로, 반복적으로 이루어질 수 있도록 유지해야한다. 그리고 이것은 스크럼이 유지될 수 있는 기반이 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. [퍼실리테이트] 스쿼드가 목표를 달성하기 위한 모든 일들의 &amp;ldquo;협력적 참여&amp;rdquo;를 유도&lt;/h3&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;나는 주로 스크럼 이벤트를 챙기기 위해, 또는 팀의 목표 달성을 위해 미팅을 조율하거나 그 미팅의 MC가 되어 대화를 유도한다. 그리고 미팅에 참여한 모든 사람들이 토의에 적극적으로 참여할 수 있도록 이끌어낸다. 만일 스크럼 마스터가 미팅에 직접 참여하지 않더라도 작업 관련자들끼리 커뮤니케이션을 유도하거나 미팅을 진행하게끔 유도한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 &amp;lsquo;미팅을 잡고 미팅을 주도하는게 업무가 될 수 있을까?&amp;rsquo;란 생각을 했었던 적이 있다. 하지만 팀이 목표 달성을 위해 미팅을 하고 대화를 해나갔을 때와 미팅을 하지 않고 대화를 하지 않았을 때의 퍼포먼스가 크게 다른 것을 직접 경험했다. 팀의 성과를 이끌어내기 위해선 상호 작용과 대화를 하는 것이 정말 중요하다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. [문제 해결] 스크럼이 진행되는 과정 중 불확실성을 찾고 장애물을 해소&lt;/h3&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;그리고 팀의 퍼포먼스를 꾸준히 유지하기 위해 팀 또는 팀원을 방해하는 장애물을 미리 제거할 수 있도록 노력해야 한다. 장애물은 팀원의 개인적인 문제일 수도 있고, 휴가 또는 퇴사로 인한 일시적인 팀 내 자원 부족, 또는 조직 차원의 문제일 수 있다. 스크럼 마스터는 이 장애물을 조기에 찾아 팀의 퍼포먼스가 유지될 수 있도록 직접 제거하거나 또는 다른 사람에게 도움을 받을 수 있어야 한다.&lt;/p&gt;
&lt;h1&gt;경계해야 할 것&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크럼은 &amp;lsquo;일을 위한 또다른 일이다&amp;rsquo;, &amp;lsquo;일하는데 오히려 방해된다&amp;rsquo;, &amp;lsquo;관리자들이 일을 더 많이 시키고 부려먹기 위한 것이다&amp;rsquo;라는 글들을 본 적이 있다. 아마 그들이 겪었던 스크럼은 스크럼의 가치를 생각하지 않고 생각 없이 기계적으로 스크럼을 수행했지 않았을까? 그렇기 때문에 스크럼을 위한 모든 행동들이 의미가 없었기 때문에 스크럼에 대해 부정적으로 얘기했을거라 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크럼은 우리 모두가 일을 더 잘하기 위해 수행하는 업무 프레임워크다. 스크럼을 사용한다는 것은 일을 더 잘하기 위함이다. 그렇기 때문에 스크럼 마스터, 그리고 스크럼을 사용하고 있는 모든 사람들은 &lt;b&gt;스크럼이 기계적으로 반복되지 않고 스크럼의 가치를 잘 지키며 일을 더 잘할 수 있도록 항상 생각하면서 사용해야 함&lt;/b&gt;을 잊지 말아야 한다.&lt;/p&gt;
&lt;h1&gt;마무리&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔직히 이 글을 쓰면서 나 또한 스크럼에 대해 많은 것을 알고 있다고 생각하지 않는다. 오히려 계속 배우고 있는 중이다. 스크럼에 대한 많은 글들을 보면 스크럼은 체스와 같다고 한다. 체스 규칙을 아는 것은 쉽지만 체스를 잘하는 것은 매우 어렵기 때문이다. 스크럼도 마찬가지이다. 스크럼을 더 잘 하기 위해 고민하고 계속 경험하면서 더 잘할 수 있도록 연습해야 진정한 스크럼 마스터가 될 수 있을거라 생각한다.&lt;/p&gt;</description>
      <category>스크럼(Scrum)</category>
      <category>scrum</category>
      <category>Scrum Master</category>
      <category>개발자</category>
      <category>스크럼</category>
      <category>스크럼 마스터</category>
      <category>업무</category>
      <category>역할</category>
      <category>퍼실리테이션</category>
      <category>퍼실리테이터</category>
      <category>할 일</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/56</guid>
      <comments>https://psyhm.tistory.com/56#entry56comment</comments>
      <pubDate>Thu, 22 Feb 2024 21:22:50 +0900</pubDate>
    </item>
    <item>
      <title>2023년 5년차 개발자 회고</title>
      <link>https://psyhm.tistory.com/54</link>
      <description>&lt;h1&gt;
&lt;script data-mce-fragment=&quot;1&quot;&gt;
  if (window.location.pathname.split(&quot;/&quot;)[1] === &quot;m&quot; &amp;&amp; navigator.userAgent.indexOf(&quot;Tistory&quot;) === -1 &amp;&amp; navigator.userAgent.indexOf(&quot;Android&quot;) === -1) {
    window.location.href = window.location.origin + window.location.pathname.substr(2);
  }
&lt;/script&gt;
서론&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전 직장에 근무할 땐 미팅을 하던 뭘 하던 회고를 전혀 하지 않았습니다. 그렇기 때문에 회고가 중요한지 전혀 몰랐었습니다. 이직하고 나서 다니고 있는 현 회사에서는 미팅을 진행할 때마다 회고를 진행합니다. 회고를 하고나서 느낀 점은 회고를 진행하게 되면 현재 미팅의 문제점이 무엇인지, 잘하고 있는 점이 무엇인지 객관적으로 알 수 있게 됩니다. 개선하고 유지해야 할 부분이 명확해지기 때문에 다음에는 더 나은 미팅이 될 수 있습니다. 회고는 현재보다 더 성장하기 위한 최고의 수단이라는 것을 이 회사를 다니고 나서 깨닫게 됐습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 개발자들이 자신들의 &amp;lsquo;개발자 회고&amp;rsquo;를 많이 작성하는 것 같습니다. 연차 성별 상관없이 많이들 작성하길래 언젠가 나도 한번 써봐야지 생각만 하다가 시간이 이렇게까지 흘러버렸습니다. 회고의 중요성을 깨달은 지금 이제는 더이상 미룰 수가 없어 조금 늦었지만 지금이라도 써보고자 합니다.&lt;/p&gt;
&lt;h1&gt;작년 2023년 목표&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 다니고 있는 회사는 매 분기 크루 리뷰를 작성합니다. 다면평가의 일종인데 셀프 리뷰(자기 평가)를 꼭 진행합니다. 셀프 리뷰를 작성할 땐 이번 분기의 나의 성과와 다음 분기에 성취하고 싶은 목표를 작성하게 됩니다. 이렇게 분기마다 리뷰 또는 회고를 회사 내에서 진행하다보니 자연스럽게 성과와 목표를 점검할 수 있습니다. 작년 4분기 셀프 리뷰를 합쳐보니 나의 목표는 상반기, 하반기로 나눌 수 있었습니다.&lt;/p&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&gt;[상반기]
- 제품 복잡도 개선 및 레거시 (코드, 정책) 개선하기
- 사내 백엔드 코드 구조 개선

[하반기]
- 팀이 스크럼에 잘 녹아들 수 있게 하기
- 팀이 효율적으로 제품에 기여할 수 있도록 만들기&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 맥락에서 보면 상반기는 개인이 달성할 수 있는 엔지니어로써의 목표이고 하반기는 팀이 일을 더 잘할 수 있도록 하는 매니저로써의 목표입니다. 어쩌다가 내 목표가 바뀌게 됐을까? 작년에 어떤 일들이 있었는지 한번 돌아보자 바뀌게 된 사유가 보이기 시작했습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;상반기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 다니고 있는 회사는 매트릭스 조직으로 하나의 스쿼드가 하나의 제품을 담당하고 있습니다. 그 중에 저는 리뷰 제품을 개발하고 있는데, 이 리뷰 제품은 회사의 탄생과 더불어 생긴 제품입니다. 그러다보니 정책과 코드 모두 레거시가 많은 편입니다. 게다가 제품도 점점 커지다보니 복잡도 또한 커져서 기능을 개발할 때마다 정책 사이드 이펙트가 얼마나 있을지 확인을 꼭 해야했습니다. 그러다보니 개발 시간 또한 점점 늘어났습니다. 더불어 python과 django로 이루어진 서버 코드는 특유의 pythonic함 때문에 개인적으로 개발에 불편함을 느꼈습니다. 그렇기에 좀 더 구조적이고 확장적인 형태로 코드 구조를 개선하고 싶었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 상반기의 저의 목표는 제품 레거시 개선하기와 백엔드 코드 구조 개선이었습니다. 그래서 이를 달성하기 위해 상반기에는 아래의 작업들을 진행했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;함수형 자바스크립트 스터디 진행 및 함수형으로 작업을 돕는 유틸리티 라이브러리 &lt;code&gt;pydash&lt;/code&gt; 도입&lt;/li&gt;
&lt;li&gt;백엔드 컨벤션 개선 TF 진행 및 참가&lt;/li&gt;
&lt;li&gt;제품 내 데드락 이슈 원인 쉐어링&lt;/li&gt;
&lt;li&gt;영속성 모델과 도메인 모델 분리 제안 등&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 이슈가 없었다면 연말까지 꼭 달성하고 싶은 목표였습니다. 하지만 그 목표를 유지하지 못하고 하반기에 수정할 수 밖에 없는 큰 이슈가 생겨버렸습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;하반기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 백엔드 개발 외에도 맡고 있는 역할이 하나 더 있습니다. 먼저 우리 회사 조직은 스크럼 프레임워크를 활용해 일을 하고 있습니다. 이 스크럼 프레임워크를 유지시키기 위한 &amp;lsquo;스크럼 마스터&amp;rsquo; 역할이 존재하는데, 제가 팀 내에서 이 역할을 겸임하고 있습니다. 스크럼 마스터의 역할은 명확하게 정해진 것은 아니나 제가 꼭 지키려고 하는 스크럼 마스터 업무는 아래와 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;팀 내 스크럼 업무 패턴을 유지시키기&lt;/li&gt;
&lt;li&gt;팀원의 업무를 방해하는 요소 제거&lt;/li&gt;
&lt;li&gt;업무의 불확실성을 줄일 수 있도록 팀원 간 커뮤니케이션 활성화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크럼 마스터 역할을 맡고 있는 상태에서 하반기에 진입하자 고객사와 약속해서 데드라인이 걸려있는, 꼭 배포를 해야만 하는 기능이 4~5개 있다는 것을 알게 됐습니다. 고객과의 약속을 지키지 못하는 것은 B2B SaaS에서는 치명적이기 때문에 연말까지 프로젝트들을 완수해내는 것이 필수였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상황이 이렇게 되자 스크럼 마스터였던 저는 팀이 프로젝트 기한을 지키기 위해 필요한 모든 것을 해야겠다는 생각이 들었습니다. 그렇기에 엔지니어로써의 기여보다는 스크럼 마스터로써의 기여도를 높이도록, 상반기에 세워뒀던 목표를 팀에 기여할 수 있는 목표로 재수정했습니다.&lt;/p&gt;
&lt;h1&gt;23년도 회고&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;23년도 상반기에서 하반기로 넘어가면서 목표가 변경됐지만 이를 달성하기 위해 많은 노력들이 있었습니다. 그래서 종합적으로 작년에 나는 어떤 점을 잘했고 어떤 점을 못했는지 정리해보고자 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&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;/li&gt;
&lt;li&gt;백엔드 엔지니어로서의 역할을 하면서 스크럼 마스터의 역할 또한 같이 수행했고, 맡은 역할을 잘 수행한 것&lt;/li&gt;
&lt;li&gt;연말까지 배포해야 하는 기능들을 최소한의 요구사항을 만족한 채 팀이 어떻게든 릴리즈 하도록 만든 것&lt;/li&gt;
&lt;li&gt;진행해야 하는 프로젝트의 불확실성을 밝혀내기 위해 무엇을 해야하는지 알게된 것&lt;/li&gt;
&lt;li&gt;업무를 위임하는 것을 배운 것
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내가 다 짊어지고 가려다가 무너져서 팀에 방해를 끼치지 않고 적절히 분배해서 기한 내에 업무를 처리할 수 있게 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;스크럼 마스터로서 좀 더 팀의 문제점을 해결하려고 들지 않았던 것
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위의 문제점이 이어져서, 팀의 문제점을 제 때에 해결하지 못해 맥락을 잃어버리는 경우가 많았음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;목표를 세웠음에도 이를 달성하기 위한 행동을 적극적으로 행하지 않은 것
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;머리 속으로 &amp;lsquo;해볼까? 하면 되게 좋을 것 같은데 실패하면 어쩌지?&amp;rsquo;만 생각한 것&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;다른 팀원들을 도울 수 있는 상황임에도 좀 더 적극적으로 돕지 않았던 것&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;24년도 목표&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 개선해야 하는 점의 대부분은 당장 실행하지 않았기 때문에 아쉬웠던 점들이 많았습니다. 그렇기에 2024년 목표는 &lt;b&gt;'실행'과 '성과'&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지난 2023년도는 바쁘기도 했지만 무엇보다 생각만 하고 시도해보지 않았던, 실패로부터 배워가려는 태도보단 실패부터 생각했던 한 해였던 것 같습니다. 그렇기 때문에 올해는 아이디어가 있다면 일단 뭐라도 행동하거나 시도해보고 회고를 통해 인사이트를 얻는 것이 목표입니다. 또한 그냥 시도하기보다는 시도하는 모든 것들이 성과가 될 수 있도록 측정할 수 있는 정량적, 정성적인 지표를 설정해 측정하려는 노력도 할 것입니다.&lt;/p&gt;</description>
      <category>잡다한 것들/일기</category>
      <category>23년</category>
      <category>5년차</category>
      <category>개발자</category>
      <category>개발자 회고</category>
      <category>백엔드</category>
      <category>스크럼</category>
      <category>스크럼 마스터</category>
      <category>엔지니어</category>
      <category>회고</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/54</guid>
      <comments>https://psyhm.tistory.com/54#entry54comment</comments>
      <pubDate>Sat, 10 Feb 2024 18:52:38 +0900</pubDate>
    </item>
    <item>
      <title>제품 스쿼드의 스크럼 프로세스 개선기 1부</title>
      <link>https://psyhm.tistory.com/53</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요. 현재 저는 &lt;a href=&quot;https://www.lemonbase.team/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;레몬베이스&lt;/a&gt;에서 Backend Engineer로 근무 중입니다. 회사에서 업무를 볼 때 저희는 스쿼드 단위 조직에서 스크럼 방식을 통해 IT 서비스 기능을 개발하고 있습니다. 약 1년이라는 기간 동안 저와 제 팀이 스크럼 방식을 어떻게 개선했는지에 대한 글을 회사 팀 블로그에 게시했습니다. 많은 관심 부탁드립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://medium.com/lemonbase/%EC%A0%9C%ED%92%88-%EC%8A%A4%EC%BF%BC%EB%93%9C%EC%9D%98-%EC%8A%A4%ED%81%AC%EB%9F%BC-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EA%B0%9C%EC%84%A0%EA%B8%B0-1%EB%B6%80-18197f8a0158&quot;&gt;제품 스쿼드의 스크럼 프로세스 개선기 1부&lt;/a&gt;&lt;/p&gt;</description>
      <category>개발</category>
      <category>comunication</category>
      <category>scrum</category>
      <category>Squad</category>
      <category>개선</category>
      <category>스쿼드</category>
      <category>스크럼</category>
      <category>커뮤니케이션</category>
      <category>프로세스</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/53</guid>
      <comments>https://psyhm.tistory.com/53#entry53comment</comments>
      <pubDate>Tue, 13 Dec 2022 00:10:30 +0900</pubDate>
    </item>
    <item>
      <title>django enum custom field 만들기</title>
      <link>https://psyhm.tistory.com/52</link>
      <description>&lt;h1&gt;enum 클래스&lt;/h1&gt;
&lt;p&gt;enumerate는 열거형이라고 불리며 고유한 상숫값에 연결된 기호 이름(멤버)의 집합입니다. python은 열거형을 지원하기 위해 enum 클래스가 존재합니다.&lt;/p&gt;
&lt;p&gt;아래는 열거형을 만드는 예시 코드입니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class LanguageType(Enum):
    C = &amp;#39;c&amp;#39;
    PYTHON = &amp;#39;python&amp;#39;
    JAVA = &amp;#39;JAVA&amp;#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;django와의 호환성&lt;/h2&gt;
&lt;p&gt;하지만 python의 enum 클래스는 django orm과 호환성이 좋지 못합니다. 무슨 의미인지 아래 코드를 보면 알 수 있습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class TestType(Enum):
    A_TYPE = &amp;#39;a_type&amp;#39;
    B_TYPE = &amp;#39;b_type&amp;#39;
    C_TYPE = &amp;#39;c_type&amp;#39;

class TestModel(models.Model):
    id = models.AutoField(primary_key=True)
    type = models.CharField(max_length=10)
    class Meta:
        db_table = &amp;#39;t_test_model&amp;#39;

&amp;gt;&amp;gt;&amp;gt; t_model = TestModel.objects.get(id=1)
&amp;gt;&amp;gt;&amp;gt; type(t_model.type)
&amp;lt;class &amp;#39;str&amp;#39;&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위와 같이 t_model의 type값이 &lt;strong&gt;string 타입&lt;/strong&gt;인 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;맞습니다. django orm은 Enum 타입을 그대로 데이터베이스로부터 불러올 수 없고, int나 string 같은 &lt;strong&gt;primitive&lt;/strong&gt; 타입 값을 불러오게 됩니다.&lt;/p&gt;
&lt;p&gt;그렇기 때문에 발생하는 오류가 존재합니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&amp;gt;&amp;gt;&amp;gt; t_model.type
&amp;#39;a_type&amp;#39;
&amp;gt;&amp;gt;&amp;gt; t_model.type == TestType.A_TYPE
False&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;python의 enum 비교는 같은 eum 타입만 비교할 수 있기 때문에 값이 같더라도 enum 타입이 아닌 이상 다르다고 처리해버립니다.&lt;/p&gt;
&lt;p&gt;그렇기 때문에 아래와 같이 django model 값과 enum 값을 비교하기 위해서는 enum 타입의 value 속성을 이용해 비교해야합니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&amp;gt;&amp;gt;&amp;gt; t_model.type == TestType.A_TYPE**.value**  # 명시적으로 value 값을 비교해줘야 한다.
True&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;그렇다면 모든 코드들을 value 속성을 이용해서 비교해야 하는데, 사람이 코드를 개발하는 특성 상 실수가 발생하기 쉬운 형태입니다.&lt;/p&gt;
&lt;p&gt;하지만 &lt;strong&gt;django custom field&lt;/strong&gt;를 이용한다면 이를 해결할 수 있습니다.&lt;/p&gt;
&lt;h1&gt;django custom field&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.djangoproject.com/en/4.1/howto/custom-model-fields/&quot;&gt;django 공식 문서&lt;/a&gt;를 보면 django model에 대한 field를 커스텀으로 생성할 수 있는 방법이 있습니다.&lt;/p&gt;
&lt;p&gt;field 클래스는 데이터베이스로부터 데이터를 불러올 때, 혹은 데이터를 저장할 때 변환하는 로직을 가지고 있습니다. 이를 통해 Enum 클래스로 변환하는 로직을 구현할 수 있습니다.&lt;/p&gt;
&lt;h2&gt;TextEnumField&lt;/h2&gt;
&lt;p&gt;위의 &lt;code&gt;TestType&lt;/code&gt;처럼 text 형식의 enum을 위한 custom field는 아래와 같습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class TextEnumField(models.CharField):
    def __init__(self, *args, **kwargs):
        self.enum = kwargs.pop(&amp;#39;enum&amp;#39;)
        self.__enum_value_to_key_map = {item.value: item for item in self.enum}
        if not issubclass(self.enum, Enum):
            raise TypeError(&amp;#39;enum 인자는 Enum 형식이여야 합니다.&amp;#39;)
        super().__init__(*args, **kwargs)

    def deconstruct(self):
        name, path, args, kwargs = super().deconstruct()
        kwargs[&amp;#39;enum&amp;#39;] = self.enum
        return name, path, args, kwargs

    def to_python(self, value):
        if isinstance(value, self.enum):
            return value
        if value is None:
            return None
        val = self.__enum_value_to_key_map[value]
        if val is None:
            raise Exception(&amp;#39;존재하지 않는 Enum 타입입니다.&amp;#39;)
        return val

    def from_db_value(self, value, expression, connection):
        return self.to_python(value=value)

    def get_prep_value(self, value):
        if isinstance(value, self.enum):
            return value.value
        else:
            return value

    def validate(self, value, model_instance):
        super().validate(value, model_instance)
        if not isinstance(value, self.enum):
            raise ValidationError(&amp;#39;잘못된 Enum 타입입니다.&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;IntEnumField&lt;/h2&gt;
&lt;p&gt;int 형식의 enum을 위한 custom field는 아래와 같습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class IntEnumField(models.IntegerField):
    def __init__(self, *args, **kwargs):
        self.enum = kwargs.pop(&amp;#39;enum&amp;#39;)
        self.__enum_value_to_key_map = {item.value: item for item in self.enum}
        if not issubclass(self.enum, IntEnum):
            raise TypeError(&amp;#39;enum 인자는 IntEnum 형식이여야 합니다.&amp;#39;)
        super().__init__(*args, **kwargs)

    def deconstruct(self):
        name, path, args, kwargs = super().deconstruct()
        kwargs[&amp;#39;enum&amp;#39;] = self.enum
        return name, path, args, kwargs

    def to_python(self, value):
        if isinstance(value, self.enum):
            return value
        if value is None:
            return None
        val = self.__enum_value_to_key_map[value]
        if val is None:
            raise Exception(&amp;#39;존재하지 않는 IntEnum 타입입니다.&amp;#39;)
        return val

    def from_db_value(self, value, expression, connection):
        value = self.to_python(value=value)

        if value is None:
            return None
        return value

    def get_prep_value(self, value):
        if isinstance(value, self.enum):
            return value.value
        else:
            return value

    def validate(self, value, model_instance):
        super().validate(value, model_instance)
        if not isinstance(value, self.enum):
            raise ValidationError(&amp;#39;잘못된 Choice 타입입니다.&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;※ django custom field에 대한 자세한 설명은 추후에 추가할 예정입니다.&lt;/p&gt;</description>
      <category>Python/django</category>
      <category>custom field</category>
      <category>Django</category>
      <category>enum</category>
      <category>Python</category>
      <category>장고</category>
      <category>커스텀</category>
      <category>파이썬</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/52</guid>
      <comments>https://psyhm.tistory.com/52#entry52comment</comments>
      <pubDate>Sun, 25 Sep 2022 18:08:25 +0900</pubDate>
    </item>
    <item>
      <title>prefork 기반 웹서버가 요청을 동시에 처리할 수 있는 이유</title>
      <link>https://psyhm.tistory.com/51</link>
      <description>&lt;h1&gt;서론&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 현재 재직 중인 회사에서는 웹 어플리케이션 서버를 개발하기 위해 Django 스택을 사용하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Django는 Web Server가 아니고 Web framework이기 때문에 django를 단순히 python으로 실행한다고 서버 어플리케이션이 되는게 아닙니다. 때문에 Django를 동시 다발적으로 실행해 여러 클라이언트의 요청을 받아 Django에게 요청을 넘길 수 있는 WSGI 서버를 사용해야 합니다. 그렇기 때문에 저희 회사는 Django와 Gunicorn을 같이 사용하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gunicorn은 python의 &lt;b&gt;prefork&lt;/b&gt; 방식의 웹 서버입니다. prefork란 이름 그대로 http 요청을 처리하기 위해 미리 자식 프로세스를 여러개 띄워서(fork) 동시에 처리하는 방식을 의미합니다. 따라서 gunicorn을 사용하면 django 프레임워크를 사용하는 다수의 자식 프로세스가 동시에 띄워지게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 gunicorn을 사용해보면서 아래의 궁금한 점이 생겼습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;tcp 요청을 처리하기 위해서는 ip와 port가 필요한데 각각의 &lt;b&gt;자식 프로세스들은 ip와 port를 할당받지 않고 어떻게 클라이언트와 통신&lt;/b&gt;하는지?&lt;/li&gt;
&lt;li&gt;한번에 몰려오는 &lt;b&gt;다수의 요청들을 다수의 자식 프로세스에게 어떻게 분배&lt;/b&gt;되는지?&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹서버가 클라이언트와 통신하기 위해선 ip와 port가 필요합니다. 그런데 어찌된 영문인지 자식 프로세스들을 위한 ip와 port를 따로 설정해주지 않습니다. 게다가 동시다발적으로 들어오는 요청을 자식 프로세스들이 어떻게 선점해서 처리하는지도 궁금해졌습니다. 그래서 먼저 prefork 방식이 무엇인지 알아보고 궁금증을 해결해보도록 하겠습니다.&lt;/p&gt;
&lt;h1&gt;prefork 방식&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LVJBF/btrH31QvAMH/CsqIQw7dmiqAnUy4WOfCxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LVJBF/btrH31QvAMH/CsqIQw7dmiqAnUy4WOfCxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LVJBF/btrH31QvAMH/CsqIQw7dmiqAnUy4WOfCxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLVJBF%2FbtrH31QvAMH%2FCsqIQw7dmiqAnUy4WOfCxk%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;960&quot; height=&quot;540&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;prefork 방식은 이전에 설명했듯이 클라이언트의 요청을 처리하기 전에 미리 &lt;b&gt;fork() 시스템 콜&lt;/b&gt;을 사용해 자식 프로세스 풀을 만듭니다. 그 후에 각 자식 프로세스마다 클라이언트의 요청을 배정받아 처리하는 구조입니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;fork 시스템 콜&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 프로세스를 생성하는 시스템 콜 입니다. 새롭게 생성된 자식 프로세스는 새로운 PID를 갖게되며 호출한 부모 프로세스를 그대로 복사합니다. 복사를 통해 자식 프로세스는 부모와 완전히 독립된 물리 메모리 공간을 갖습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;요청의 분배&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자식 프로세스를 미리 여러개를 만들어 놓는다면 클라이언트의 요청이 물리적인 서버로 전달된 경우 누군가는 클라이언트의 요청을 자식 프로세스로 &lt;b&gt;분배&lt;/b&gt;해야 합니다. 저는 당연하게도 부모 프로세스가 마치 load balancer 처럼 모든 클라이언트의 요청이 부모 프로세스로 전달되고 자식 프로세스에게 요청을 분배해서 전달할 줄 알았습니다.&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;요청이 어떻게 분배되는지 이해하기 위해선 &lt;b&gt;소켓(Socket) 통신&lt;/b&gt;에 대해 이해해야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;940&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnU1NE/btrH0ulALiH/wXm6HUpDcueCVx7lFja8e0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnU1NE/btrH0ulALiH/wXm6HUpDcueCVx7lFja8e0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnU1NE/btrH0ulALiH/wXm6HUpDcueCVx7lFja8e0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnU1NE%2FbtrH0ulALiH%2FwXm6HUpDcueCVx7lFja8e0%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;2048&quot; height=&quot;940&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;940&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;

&lt;h1&gt;소켓 통신&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;서버 소켓, 클라이언트 소켓&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소켓(Socket) 통신은 두 프로그램이 네트워크를 통해 서로 통신을 수행할 수 있도록 양쪽에 생성되는 링크의 단자입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvE56O/btrH32BRRe2/qzZ7kt8tuLDLaWqLK3Bk7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvE56O/btrH32BRRe2/qzZ7kt8tuLDLaWqLK3Bk7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvE56O/btrH32BRRe2/qzZ7kt8tuLDLaWqLK3Bk7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvE56O%2FbtrH32BRRe2%2FqzZ7kt8tuLDLaWqLK3Bk7K%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;700&quot; height=&quot;268&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버에서는 통신을 위해 소켓을 생성하게 됩니다. 이를 &lt;b&gt;서버 소켓(Server Socket)&lt;/b&gt;이라고 하겠습니다. 서버 프로세스가 서버 소켓을 생성할 때는 &lt;b&gt;주소(ip)&lt;/b&gt;와 &lt;b&gt;포트(port)&lt;/b&gt;를 &lt;b&gt;결합(bind)&lt;/b&gt;한 뒤에 &lt;b&gt;요청 대기(listen)&lt;/b&gt;함으로써 클라이언트의 요청을 수신할 수 있는 상태가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트도 마찬가지로 소켓을 생성해서 서버와 연결을 시도합니다. 클라이언트와 서버가 연결되면 클라이언트의 연결 정보는 시스템 내부적으로 관리되는 &lt;b&gt;요청 대기 큐(accept queue)&lt;/b&gt;에 쌓이게 되는데, 이 시점에서 서버와 클라이언트의 연결 상태는 &lt;b&gt;established&lt;/b&gt; 상태입니다. 대기 중인 연결 요청을 큐(queue)로 부터 꺼내와서 연결을 완료하기 위해서는 &lt;b&gt;수락(accept)&lt;/b&gt;을 진행해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트와 서버 간에 연결이 &lt;b&gt;수락(accept)&lt;/b&gt;되고 &lt;b&gt;수립(established)&lt;/b&gt; 상태가 되면 새로운 소켓을 생성하게 되는데 이를 &lt;b&gt;클라이언트 소켓(Client Socket)&lt;/b&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;&lt;code&gt;서버 소켓&lt;/code&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ip와 port를 사용해 클라이언트와 통신이 가능하도록 설정&lt;/li&gt;
&lt;li&gt;클라이언트와 연결 수립 후 클라이언트 소켓 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;클라이언트 소켓&lt;/code&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버와 클라이언트가 서로 연결될 때 생성됨&lt;/li&gt;
&lt;li&gt;데이터 송수신 처리를 담당&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요청 대기 큐&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버와 클라이언트가 네트워크 연결이 되면 클라이언트 연결 요청에 대한 정보는 운영체제(OS) 내부적으로 관리되는 &lt;b&gt;큐(queue)&lt;/b&gt;에 쌓이게 되는데, 이를 &lt;b&gt;요청 대기 큐(accept queue)&lt;/b&gt;라고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 요청 대기 큐에는 서버 어플리케이션에서 클라이언트와 데이터를 주고받을 수 있는 &lt;b&gt;established&lt;/b&gt; 상태인 연결 정보가 저장됩니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;accept queue, syn queue?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 내부적으로 관리되는 큐를 부르는 명칭은 명확하게 정의된 게 없지만 &lt;a href=&quot;https://blog.cloudflare.com/ko-kr/syn-packet-handling-in-the-wild-ko-kr/&quot;&gt;cloudflare 블로그&lt;/a&gt;에서 정의한대로 부르도록 하겠습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트에서 서버 소켓으로 연결이 요청될 때마다 요청 대기 큐에 연결이 쌓이게 됩니다. 자식 프로세스는 이 요청 대기 큐에서 &lt;b&gt;accept() 시스템 콜&lt;/b&gt;을 통해 클라이언트의 요청을 하나씩 꺼내오게 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;자식 프로세스가 클라이언트 요청을 처리하는 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트와의 연결을 수립하기 위한 서버 소켓, 그리고 데이터를 송수신하기 위한 클라이언트 소켓. 이 두 개의 소켓은 같은 소켓이지만 서로 다른 역할을 수행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 만약 각 자식 프로세스가 서버 소켓의 정보를 가지고 있고, 각 자식 프로세스가 서버 소켓을 이용해 클라이언트 소켓을 만들어낸다면 어떻게 될까요? 맞습니다. 자식 프로세스들은 1개의 ip와 port를 사용하면서 클라이언트와 데이터를 송수신 할 수 있게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 부모 프로세스는 서버 소켓을 생성한 뒤에 fork 시스템 콜을 사용해 자식 프로세스를 생성합니다. 이렇게 되면 자식 프로세스의 메모리 공간에 같은 서버 소켓을 가지게 됩니다. 각 자식 프로세스는 서버 소켓을 사용해 클라이언트와 연결이 accept될 수 있도록 기다리게 됩니다. 클라이언트와 연결이 수립되면 각 자식 프로세스는 클라이언트 소켓을 생성하게 되고 이를 통해 클라이언트와 통신할 수 있게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이해를 돕기 위해 위의 프로세스를 하나의 그림으로 표현했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1hB5h/btrH1bmnHA4/ksxrbmzdINNggEskaeLR6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1hB5h/btrH1bmnHA4/ksxrbmzdINNggEskaeLR6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1hB5h/btrH1bmnHA4/ksxrbmzdINNggEskaeLR6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1hB5h%2FbtrH1bmnHA4%2FksxrbmzdINNggEskaeLR6k%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;960&quot; height=&quot;540&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부모 프로세스가 서버 소켓을 생성 및 요청 대기 상태(listen)로 진입&lt;/li&gt;
&lt;li&gt;클라이언트가 서버로 요청을 보냄. 연결 정보는 요청 대기 큐에 쌓임.&lt;/li&gt;
&lt;li&gt;부모 프로세스가 fork를 통해 자식 프로세스를 생성. 자식 프로세스들은 같은 서버 소켓을 가지게 됨&lt;/li&gt;
&lt;li&gt;각 자식 프로세스의 서버 소켓이 연결을 accept하면서 요청 대기 큐에서 가져온 연결 정보를 가지고 클라이언트 소켓을 생성&lt;/li&gt;
&lt;li&gt;각 자식 프로세스는 클라이언트를 통해 요청을 분산 처리할 수 있게 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;마무리 지으면서&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서론에서 궁금했던 점이 해결됐습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자식 프로세스들은 ip와 port를 할당받지 않고 어떻게 클라이언트와 통신하는지?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자식 프로세스는 부모 프로세스가 가지고 있던 서버 소켓 정보를 복사해서 각각 가지고 있기 때문에 이를 통해서 클라이언트와 통신을 주고 받을 수 있게 됩니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한번에 몰려오는 다수의 요청은 다수의 자식 프로세스에게 어떻게 분배되는지?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다수의 요청은 요청 대기 큐에 쌓이게 되며 자식 프로세스는 각자 가지고 있는 서버 소켓을 이용해 요청 대기 큐에 있는 클라이언트 요청 정보를 꺼내와서 각자 처리할 수 있게 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;경합이 일어나지 않을까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 구조에서 의문점이 하나 들 수가 있습니다. prefork 모델에서 자식 프로세스가 여러개일 때, 각 자식 프로세스들이 요청 대기 큐에 접근해서 클라이언트의 요청을 가져올 때 &lt;b&gt;프로세스 간 경합&lt;/b&gt;이 일어나지 않을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 말하자면 &lt;b&gt;경합이 일어나지 않습니다.&lt;/b&gt; 여러 개의 자식 프로세스가 accept 시스템 콜을 호출해도 &lt;b&gt;운영체제 커널에 의해 관리&lt;/b&gt;되기 때문에 1개의 자식 프로세스만 요청 대기 큐에 접근할 수 있고 나머지는 새로운 클라이언트 요청이 오기 전까지 &lt;b&gt;block 상태에서 대기&lt;/b&gt;하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 특성을 이용해 prefork 방식은 프로세스 풀을 만들어 컴퓨팅 리소스를 아낄 뿐만 아니라, 클라이언트 요청을 각 자식 프로세스에서 분산 처리할 수 있는 환경이 만들 수 있게 됩니다.&lt;/p&gt;</description>
      <category>컴퓨터 사이언스</category>
      <category>Django</category>
      <category>Gunicorn</category>
      <category>Network</category>
      <category>prefork</category>
      <category>Python</category>
      <category>네트워크</category>
      <category>소켓</category>
      <category>소켓통신</category>
      <category>시스템콜</category>
      <category>요청분배</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/51</guid>
      <comments>https://psyhm.tistory.com/51#entry51comment</comments>
      <pubDate>Mon, 25 Jul 2022 00:42:21 +0900</pubDate>
    </item>
    <item>
      <title>클라우드 컴퓨팅의 정의</title>
      <link>https://psyhm.tistory.com/50</link>
      <description>&lt;h1&gt;클라우드 컴퓨팅의 정의&lt;/h1&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NIST(미국 국립표준 기술 연구소)에 의하면 클라우드 컴퓨팅(Cloud Computing)은 최소한의 관리나 서비스 제공자의 상호 작용으로 신속하게 프로비저닝 및 출시할 수 있는 구성 가능한 컴퓨팅 리소스(예: 네트워크, 서버, 스토리지, 애플리케이션 및 서비스)의 공유 풀에 대한 유비쿼터스하고 편리한 온디맨드 네트워크 액세스를 가능하게 하는 모델.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고: &lt;a href=&quot;https://faculty.winthrop.edu/domanm/csci411/Handouts/NIST.pdf&quot;&gt;[NIST] 클라우드 컴퓨팅 정의&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;클라우드 컴퓨팅의 5가지 특성&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;온디맨드 셀프 서비스(On-demand Self Service)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소비자는 각 서비스 제공자와 상호작용 할 필요 없이 필요에 따라 컴퓨팅 기능을 자동으로 프로비저닝 할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;광범위한 네트워크 엑세스(Broad Network Access)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능들은 네트워크를 통해 제공되며, 여러 종류의 thin 혹은 thick 클라이언트 플랫폼에서 사용을 촉진하는 표준 메커니즘을 통해 액세스할 수 있습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Thin vs Thick Client&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Thin Client&lt;/b&gt;는 주로 서버와 통신하도록 설계된 소프트웨어입니다. (예: 크롬, 사파리 웹 브라우저)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Thick Client&lt;/b&gt;는 자체 기능을 구현하는 소프트웨어입니다. 서버에 연결할 수 있지만 연결이 끊겨도 기능을 수행할 수 있습니다. (예: 게임)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;리소스 풀링(Resource Pooling)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제공자의 컴퓨팅 리소스는 멀티 테넌트(Multi-tenant) 모델을 사용해 여러 소비자에게 서비스를 제공할 수 있도록 풀링되며, 소비자의 요구에 따라 서로 다른 물리적 리소스와 가상 리소스가 동적으로 할당/재할당 됩니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;멀티 테넌트(Multi-tenant) 모델&lt;/b&gt;&lt;br /&gt;단일 소프트웨어 인스턴스로 서로 다른 여러 사용자 그룹에 서비스를 제공할 수 있는 소프트웨어 아키텍쳐를 의미. SaaS 제품이 멀티테넌트 아키텍쳐의 예입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;리소스 풀링(Pooling)&lt;/b&gt;&lt;br /&gt;서버나 스토리지 등의 자원을 미리 확보하고 이를 사용자 요청에 따라 제공한다는 개념 혹은 이를 확보해놓은 가상적인 공간을 의미합니다. (수영장 풀을 생각하면 된다.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;빠른 탄력(Rapid elasticity)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능이 탄력적으로 프로비저닝 및 릴리즈 될 수 있으며, 경우에 따라 자동적으로 수요에 따라서 신속하게 확장 및 축소될 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;측정되는 서비스(Measured Service)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드 시스템은 서비스 유형에 적합한 일정 수준의 추상화()에서 미터링 기능을 활용해 리소스 사용을 자동으로 제어하고 최적화합니다. 또한 리소스 사용량을 모니터링, 제어 및 보고할 수 있으므로 사용된 서비스의 제공자와 소비자 모두에게 투명성을 제공합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;클라우드의 서비스 모델&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;SaaS&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SaaS(&lt;b&gt;S&lt;/b&gt;oftware &lt;b&gt;a&lt;/b&gt;s &lt;b&gt;a&lt;/b&gt; &lt;b&gt;S&lt;/b&gt;ervice)는 클라우드 인프라에서 실행되는 제공자의 애플리케이션을 사용할 수 있는 기능이 소비자에게 제공됩니다. 이 애플리케이션은 웹 브라우저와 같은 thin 클라이언트로 인터페이스나 프로그램 인터페이스를 통해 다양하게 접근 가능합니다. 사용자는 애플리케이션에서 제공하는 기능 및 구성 설정을 제외하고 네트워크, 서버, 운영 체제, 스토리지 또는 개별 애플리케이션 기능을 포함한 기본 클라우드 인프라를 관리하거나 제어하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 네이버 메일, 드롭박스, 넷플릭스 OTA 등&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;PaaS&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PaaS(&lt;b&gt;P&lt;/b&gt;latform &lt;b&gt;a&lt;/b&gt;s &lt;b&gt;a&lt;/b&gt; &lt;b&gt;S&lt;/b&gt;ervice)는 사용자에게 제공되는 기능은 제공자가 지원하는 프로그래밍 언어, 라이브러리, 서비스 및 도구를 활용해 사용자가 생성하거나 취득한 애플리케이션을 클라우드 인프라에 배포하는 것입니다. 사용자는 네트워크, 서버, 운영 체제 또는 스토리지를 포함한 기본 클라우드 인프라를 관리하거나 제어하지 않지만 배포된 애플리케이션과 애플리케이션 호스팅 환경의 구성 설정을 제어할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 헤로쿠, AWS Lambda, AWS elastic Beanstalk, 도커, 쿠버네티스 등&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;IaaS&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IaaS(&lt;b&gt;I&lt;/b&gt;nfrastructure &lt;b&gt;a&lt;/b&gt;s &lt;b&gt;a&lt;/b&gt; Service)는 사용자에게 제공되는 기능은 프로세싱, 스토리지, 네트워크 및 기타 기본 컴퓨팅 리소스를 프로비저닝하여 운영 체제와 애플리케이션을 포함한 임의의 소프트웨어를 배포하고 실행할 수 있는 기능입니다. 사용자는 기본 클라우드 인프라를 관리하거나 제어하지 않지만 운영 체제, 스토리지 및 구현된 애플리케이션을 제어할 수 있으며, 선별된 네트워킹 구성 요소(예: 호스트 방화벽)에 대한 제어가 제한적일 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) AWS, Azure, IBM Cloud, Google cloud 등&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;클라우드 서비스 배포 모델&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드를 사용하는 조직 및 사용 목적에 의해 클라우드 서비스가 배포되는 모델을 4가지로 나눌 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Private Cloud&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 소비자(예: 사업부)로 구성된 단일 조직에서 독점적으로 사용하는 클라우드입니다. 조직, 제3자 또는 이들의 조합에 의해 소유, 관리 및 운영될 수 있으며, 사내 또는 외부에 존재할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Community Cloud&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공통 관심사(예: 미션, 보안 요구 사항, 정책 및 규정 준수 고려 사항)가 있는 조직의 특정 소비자 커뮤니티에서 독점적으로 사용하는 클라우드입니다. 지역사회의 하나 이상의 조직, 제3자 또는 이들의 조합에 의해 소유, 관리 및 운영될 수 있으며, 구내 또는 외부에 존재할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Public Cloud&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 대중이 공개적으로 사용할 수 있는 클라우드입니다. 기업, 학계, 정부 단체 또는 이들의 조합에 의해 소유, 관리 및 운영될 수 있습니다. 클라우드 제공자의 구내에 존재합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Hybrid Cloud&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘 이상의 개별 클라우드 인프라(프라이빗, 커뮤니티 또는 퍼블릭)로 구성되어 있지만, 데이터 및 애플리케이션 이식성(예: 클라우드 간 로드 밸런싱을 위한 클라우드 버스트)을 가능하게 하는 표준화된 또는 독점 기술에 의해 함께 결합되어 있습니다.&lt;/p&gt;</description>
      <category>컴퓨터 사이언스/용어 정리</category>
      <category>Cloud</category>
      <category>cloud service model</category>
      <category>클라우드</category>
      <category>클라우드 서비스 모델</category>
      <category>특성</category>
      <category>특징</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/50</guid>
      <comments>https://psyhm.tistory.com/50#entry50comment</comments>
      <pubDate>Fri, 22 Oct 2021 15:24:47 +0900</pubDate>
    </item>
    <item>
      <title>Node.js의 socket.io 클라이언트 파일 경로가 /socket.io/socket.io.js 인 이유</title>
      <link>https://psyhm.tistory.com/49</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Socket.io&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Socket.io란 &lt;b&gt;WebSocket&lt;/b&gt;을 기반으로 클라이언트와 서버의 양방향 통신을 가능하게 해주는 모듈입니다. Socket.io를 사용하기 위해선 서버와 클라이언트 모두 Socket.io 라이브러리가 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://socket.io/docs/v4/client-initialization/&quot;&gt;socket.io 문서&lt;/a&gt;를 보면 client에서 socket.io 라이브러리를 html script로 불러올 때 다음 코드를 작성하도록 하게 합니다.&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;script src=&quot;/socket.io/socket.io.js&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 Node.js 서버 개발 시에는 저런 파일을 정적(static)으로 제공한 적도, 저 파일을 만든 적도 없는데 사용할 수 있다는 것입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;socket.io 서버&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 작성한 코드는 웹 클라이언트에서 상대 경로에 있는 socket.io.js 파일을 서버 측에 요청하는 코드입니다. 그렇다면 Node.js 서버에서는 static 파일을 제공하는 코드를 작성해야 하는데, 먼저 &lt;a href=&quot;https://socket.io/docs/v4/server-initialization/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;socket.io 문서&lt;/a&gt;에서 제공하는 서버 측 코드를 보시면 좋을 것 같습니다.&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;// CommonJS
const httpServer = require(&quot;http&quot;).createServer();
const io = require(&quot;socket.io&quot;)(httpServer, {
  // ...
});

io.on(&quot;connection&quot;, (socket) =&amp;gt; {
  // ...
});

httpServer.listen(3000);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드는 express.js나 nest.js 웹 프레임워크를 사용하지 않는 코드입니다.&lt;br /&gt;위의 코드를 보면 알 수 있듯이, 기존 http 서버 인스턴스를 socket.io 라이브러리 인스턴스의 프로퍼티로 넣는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번엔 express.js 서버에서 사용하는 코드입니다.&lt;/p&gt;
&lt;pre class=&quot;livescript&quot;&gt;&lt;code&gt;const app = require(&quot;express&quot;)();
const httpServer = require(&quot;http&quot;).createServer(app);
const options = { /* ... */ };
const io = require(&quot;socket.io&quot;)(httpServer, options);

io.on(&quot;connection&quot;, socket =&amp;gt; { /* ... */ });

httpServer.listen(3000);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 기존 express http 서버 인스턴스를 socket.io 라이브러리 인스턴스의 프로퍼티로 넣습니다.&lt;br /&gt;이로써 우리는 &lt;b&gt;http 서버 인스턴스를 사용해 socket.io를 사용할 수 있도록 하는 것을 추측할 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;socket.io.js는 어디에 있을까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 socket.io 내부에서는 기존 http 서버 인스턴스를 어떻게 활용하길래, socket.io.js 파일을 제공할 수 있었던 건 지 알아봐야 할 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 &lt;code&gt;node_modules&lt;/code&gt; 디렉토리에 있을 것 같아 socket.io의 디렉토리를 확인해보니 서브 디렉토리 &lt;code&gt;client-dist&lt;/code&gt;에 socket.io.js 파일이 있는 것을 확인했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;269&quot; data-origin-height=&quot;180&quot; data-filename=&quot;_2021-06-24__4.10.04.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xs1Kp/btrcOjNSeJA/a34oJQLhW6q4NUdb0s3H71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xs1Kp/btrcOjNSeJA/a34oJQLhW6q4NUdb0s3H71/img.png&quot; data-alt=&quot;node_modules/에 socket.io.js 파일이 존재한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xs1Kp/btrcOjNSeJA/a34oJQLhW6q4NUdb0s3H71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxs1Kp%2FbtrcOjNSeJA%2Fa34oJQLhW6q4NUdb0s3H71%2Fimg.png&quot; data-origin-width=&quot;269&quot; data-origin-height=&quot;180&quot; data-filename=&quot;_2021-06-24__4.10.04.png&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;node_modules/에 socket.io.js 파일이 존재한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 socket.io 라이브러리 내에 client-dist 경로의 파일을 static 파일로 제공할 것 같아 socket.io github에 &quot;client-dist&quot; 를 검색해보니 다음과 같은 코드가 검색됐습니다.&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;private serve(req: http.IncomingMessage, res: http.ServerResponse): void {
    const filename = req.url!.replace(this._path, &quot;&quot;);
    const isMap = dotMapRegex.test(filename);
    const type = isMap ? &quot;map&quot; : &quot;source&quot;;

    // Per the standard, ETags must be quoted:
    // https://tools.ietf.org/html/rfc7232#section-2.3
    const expectedEtag = '&quot;' + clientVersion + '&quot;';
    const weakEtag = &quot;W/&quot; + expectedEtag;

    const etag = req.headers[&quot;if-none-match&quot;];
    if (etag) {
        if (expectedEtag === etag || weakEtag === etag) {
            debug(&quot;serve client %s 304&quot;, type);
            res.writeHead(304);
            res.end();
            return;
        }
    }

    debug(&quot;serve client %s&quot;, type);

    res.setHeader(&quot;Cache-Control&quot;, &quot;public, max-age=0&quot;);
    res.setHeader(
        &quot;Content-Type&quot;,
        &quot;application/&quot; + (isMap ? &quot;json&quot; : &quot;javascript&quot;)
    );
    res.setHeader(&quot;ETag&quot;, expectedEtag);

    if (!isMap) {
        res.setHeader(&quot;X-SourceMap&quot;, filename.substring(1) + &quot;.map&quot;);
    }
    Server.sendFile(filename, req, res);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드를 보면 알 수 있듯이, socket.io 서버 측 라이브러리에는 기존 http 서버를 활용해서, node_modules/socket.io/client-dist 경로에 있는 socket.io.js를 제공하는 함수 &lt;code&gt;serve&lt;/code&gt;가 있다는 것을 알 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;socket.io를 create 할 시에 node.js의 http 서버를 생성자로 받기에 이러한 코드가 있을 것 같은 예상을 하긴 했었지만 코드를 보니 확신할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 socket.io.js 파일의 경로와 클라이언트에서 요청하는 socket.io.js파일의 경로가 다르지만, &lt;code&gt;replace&lt;/code&gt;을 이용해 요청받은 url의 경로를 socket.io.js파일의 경로로 변경하는 것을 알 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 마무리 요약하자면 다음으로 정리할 수 있을 것 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;socket.io 라이브러리 내부에 클라이언트에서 사용하는 socket.io.js 파일이 존재한다.&lt;/li&gt;
&lt;li&gt;서버 측 socket.io는 기존 http 서버 인스턴스를 프로퍼티로 받아, 업그레이드 한다.&lt;/li&gt;
&lt;li&gt;업그레이드 된 socket.io 서버는 socket.io.js 파일을 serve 할 수 있게 된다.&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>Node.js</category>
      <category>/socket.io/socket.io.js</category>
      <category>node.js</category>
      <category>npm</category>
      <category>socket.io</category>
      <category>파일 경로</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/49</guid>
      <comments>https://psyhm.tistory.com/49#entry49comment</comments>
      <pubDate>Sun, 22 Aug 2021 16:19:49 +0900</pubDate>
    </item>
    <item>
      <title>[네이밍 컨벤션] 함수 이름 get vs find</title>
      <link>https://psyhm.tistory.com/48</link>
      <description>&lt;h1&gt;데이터를 가져오는 함수&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발할 때마다 데이터를 가져오는 함수명을 지을 때 어떻게 이름을 쓸 지 고민한 경험이 있습니다.&lt;br /&gt;함수 이름 앞에 &lt;b&gt;get&lt;/b&gt;을 쓸 지, &lt;b&gt;find&lt;/b&gt;를 쓸 지 고민한 적이 많았는데, 이번에 정리하려고 합니다.&lt;/p&gt;
&lt;h1&gt;get vs find 기준&lt;/h1&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;값을 가져오는 시간 기준&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;get: 데이터를 가져오는 &lt;b&gt;시간이 짧을 때&lt;/b&gt; 사용&lt;/li&gt;
&lt;li&gt;find: 검색 프로세스나 연산 알고리즘을 사용하며, 데이터를 가져오는데 걸리는 &lt;b&gt;시간이 좀 더 길다&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터 가져오는 데 오류 여부&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;get: 데이터를 가져오는데 &lt;b&gt;오류가 발생하지 않는다.&lt;/b&gt; 비교적 간단한 로직&lt;/li&gt;
&lt;li&gt;find: 데이터를 가져오는데 &lt;b&gt;오류가 발생한다.&lt;/b&gt; 비교적 복잡한 로직&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&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;h2 data-ke-size=&quot;size26&quot;&gt;get을 사용하는 경우&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터를 가져오는 시간이 짧다.&lt;/li&gt;
&lt;li&gt;로직이 간단하다.&lt;/li&gt;
&lt;li&gt;데이터를 가져오는데 오류가 발생하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function getUser() {};
function getEmail() {};&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;find를 사용하는 경우&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;검색 프로세스나 연산 알고리즘을 사용하며, 데이터를 가져오는데 걸리는 시간이 좀 더 길다.&lt;/li&gt;
&lt;li&gt;로직이 복잡하다.&lt;/li&gt;
&lt;li&gt;데이터를 가져오는데 오류가 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function findUserFromDB() {};
function findUserByEmail() {};
function findPostOrderByDate() {};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조: &lt;a href=&quot;https://softwareengineering.stackexchange.com/questions/182113/how-and-why-to-decide-between-naming-methods-with-get-and-find-prefixes&quot;&gt;How and why to decide between naming methods with &amp;ldquo;get&amp;rdquo; and &amp;ldquo;find&amp;rdquo; prefixes&lt;/a&gt;&lt;/p&gt;</description>
      <category>개발/네이밍 컨벤션</category>
      <category>Convention</category>
      <category>find</category>
      <category>Get</category>
      <category>get vs find</category>
      <category>Naming Convention</category>
      <category>prefix</category>
      <category>네이밍 컨벤션</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/48</guid>
      <comments>https://psyhm.tistory.com/48#entry48comment</comments>
      <pubDate>Sat, 21 Aug 2021 18:00:55 +0900</pubDate>
    </item>
    <item>
      <title>[nestjs] - nestjs 소개</title>
      <link>https://psyhm.tistory.com/47</link>
      <description>&lt;h2&gt;Nestjs란&lt;/h2&gt;
&lt;p&gt;Nest.js는 nodejs에서 새로 떠오르는 프레임워크입니다. &lt;a href=&quot;https://nestjs.com/&quot;&gt;공식 페이지&lt;/a&gt;를 가보면 Nestjs를 다음과 같이 소개하고 있습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Nestjs는 효율적이고, 안정적이며, 확장에 용이한 서버 어플리케이션을 구축하기 위한 진보된 nodejs 프레임워크입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;효율성&lt;/h3&gt;
&lt;p&gt;개인적으로 써보면서 nestjs가 효율적이라고 느꼈던 점은 규모가 있는 프로젝트에서의 생산성이라고 생각합니다.&lt;/p&gt;
&lt;p&gt;nestjs 문서의 &lt;a href=&quot;https://docs.nestjs.com/#philosophy&quot;&gt;Nestjs 프레임워크의 철학&lt;/a&gt; 구문을 보면 나타나 있습니다.&lt;/p&gt;
&lt;p&gt;nestjs는 typescript의 적극적인 도입, DI(Dependency Injection), IoC(Inversion of Control), Module을 통한 구조화 등의 기술을 통해 생산적인 개발이 용이합니다.&lt;/p&gt;
&lt;h3&gt;안정적&lt;/h3&gt;
&lt;p&gt;Nestjs는 typescript를 적극적으로 도입함으로서 서버 어플리케이션 개발 시 발생할 수 있는 오류들을 사전에 방지할 수 있도록 했습니다. 또한 모듈로 감싸는 형태로 개발하기 때문에 모듈 별로 테스트 코드를 쉽게 작성할 수 있도록 구현되어 있습니다.&lt;/p&gt;
&lt;p&gt;또한 개인적으로 사용하면서 프레임워크 때문에 발생한 오류는 없었습니다.&lt;/p&gt;
&lt;h3&gt;확장성&lt;/h3&gt;
&lt;p&gt;Nestjs는 &lt;b&gt;module&lt;/b&gt;을 통해 확장이 용이하도록 설계되어 있습니다. 실제로 사용해보면 module을 통해 코드적으로, 논리적으로 구분한다는 장점을 크게 느끼실 수 있습니다.&lt;/p&gt;
&lt;p&gt;또한 nestjs는 기본적으로 마이크로서비스 아키텍처 개발 스타일을 제공합니다. (&lt;a href=&quot;https://docs.nestjs.com/microservices/basics&quot;&gt;문서&lt;/a&gt;)&lt;/p&gt;
&lt;h2&gt;nestjs vs express&lt;/h2&gt;
&lt;p&gt;Nodejs에는 이미 유명한 웹 어플리케이션 프레임워크인 express.js가 있고, 많은 회사가 서버를 개발하기 위해 express.js를 사용하고 있습니다. 같은 nodejs의 프레임워크이지만 두 프레임워크의 스타일이 많이 다릅니다.&lt;/p&gt;
&lt;p&gt;nestjs와 express를 간단하게 비교해 보자면 다음과 같습니다.&lt;/p&gt;
&lt;h3&gt;구조&lt;/h3&gt;
&lt;p&gt;express.js는 웹 어플리케이션 서버를 빠르게 구현하기 위해 최적화 되어있습니다. 그래서 그 구조도 간단하고 따라서 개발 시 구조에 대한 자유도도 높습니다. 장점이라면 개발자들이 express를 사용하면서 여러 툴, 기술, 미들웨어 등을 마음껏 선택할 수 있습니다. 하지만 그런 선택의 자유로움이 독이 될 수 있습니다. 규모가 큰 개발의 경우 개발자들 서로 좋아하는 툴, 기술 등이 다를 수 있습니다. 그리고 그 자유로움은 같은 express를 개발해도 팀마다 express 구조가 달라지게 됩니다.&lt;/p&gt;
&lt;p&gt;하지만 nestjs의 경우는 조금 다릅니다. controller, service, module 클래스들은 각각 역할을 가지고 있습니다. middleware, guard, filter 등의 클래스들 또한 다 그들의 역할을 가지고 있습니다. IoC와 DI 같은 디자인 패턴들을 도입해서 그것들에 맞추지 않으면 개발하기 힘든 구조입니다. 하지만 그런 제한이 오히려 개발의 통일성을 가져옵니다.&lt;/p&gt;
&lt;p&gt;대표적으로 Java 진영은 걸출한 Spring 프레임워크가 있고 잘 정립된 spring 철학을 바탕으로 모든 개발자들은 개발의 통일성을 바탕으로 프로젝트를 시작할 때 구조를 잡지 않고 바로 개발을 시작할 수 있고, 개발 중간에 인원이 투입되어도 개발 구조는 같기 때문에 빠르게 개발할 수 있습니다. Nestjs를 유심히 보면 spring과 유사한 점이 많아 spring 개발자들이 nestjs를 개발한다면 쉽게 이해할 것 같습니다.&lt;/p&gt;
&lt;h3&gt;Typescript 지원&lt;/h3&gt;
&lt;p&gt;Nestjs는 설계부터 typescript를 지원하게끔 개발되어 있습니다. 문서를 봐도 typescript를 사용하라고 권장합니다. 이로써 nestjs는 typescript의 장점 또한 가지게 됩니다. typescript의 대표적인 장점은 컴파일 단계에서의 오류를 포착할 수 있다는 점입니다. 이는 어플리케이션의 안정성을 가져옵니다.&lt;/p&gt;
&lt;p&gt;물론 express 또한 typescript를 이용해 개발할 수 있습니다. 하지만 typescript를 적용하려면 직접 세팅해야 하며 Typescript를 제대로 활용하기 어렵습니다.&lt;/p&gt;
&lt;h3&gt;모듈&lt;/h3&gt;
&lt;p&gt;Nestjs는 &lt;b&gt;module&lt;/b&gt; 클래스를 지원합니다. module은 비슷한 기능 및 개념들을 module 클래스에 한 곳에 담아 캡슐화합니다. 그리고 Module들은 서로 import가 가능합니다. 이는 아키텍쳐를 &lt;b&gt;조직적(Organize)&lt;/b&gt;으로 가져가게 하고 &lt;b&gt;느슨한 결합(Loose Coupling)&lt;/b&gt;을 가능하게 만들어 &lt;b&gt;확장성(Extensible)&lt;/b&gt;과 &lt;b&gt;테스트 가능성(Testable)&lt;/b&gt;을 높입니다.&lt;/p&gt;
&lt;h3&gt;Standalone Application&lt;/h3&gt;
&lt;p&gt;Nestjs는 웹 어플리케이션만 만들 수 있는 것이 아닙니다. &lt;a href=&quot;https://docs.nestjs.com/standalone-applications&quot;&gt;문서&lt;/a&gt;를 보면 &lt;b&gt;DI&lt;/b&gt;와 &lt;b&gt;IoC&lt;/b&gt; 등의 핵심 기능만 가져가는 core 라이브러리를 통해 웹 서버 뿐만 아니라 여러 어플리케이션을 구현할 수 있습니다. 예를 들어 주기적으로 프로그램을 실행하는 cron 어플리케이션이나 batch 작업을 위한 어플리케이션을 구현할 수 있습니다.&lt;/p&gt;
&lt;p&gt;하지만 express의 경우 웹 프레임워크이기 때문에 웹 어플리케이션을 구현하는 것이 아니라면 express를 사용하기가 어렵습니다.&lt;/p&gt;
&lt;h2&gt;결론&lt;/h2&gt;
&lt;p&gt;개인적으로 Nestjs를 사용하면서 장점이 상당히 많은 프레임워크라고 느꼈습니다. 규모가 큰 프로젝트에서는 오히려 이 프레임워크를 사용하는 게 맞다고 생각할 정도로 큰 규모에서 갖는 장점을 많이 갖추었습니다.&lt;/p&gt;
&lt;p&gt;nestjs를 사용하는 개발자로서 nestjs가 많은 사람들에게 알려져 nodejs도 큰 프로젝트에서 사용할 날이 생겼으면 좋겠습니다. 한국에서 많은 회사들이 nestjs를, nodejs를 선택해 좋은 문화가 만들어졌으면 합니다&lt;/p&gt;</description>
      <category>Node.js/nestjs</category>
      <category>DI</category>
      <category>ioc</category>
      <category>javascript</category>
      <category>module</category>
      <category>nestjs</category>
      <category>nodejs</category>
      <category>typescript</category>
      <category>소개</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/47</guid>
      <comments>https://psyhm.tistory.com/47#entry47comment</comments>
      <pubDate>Tue, 3 Nov 2020 00:57:09 +0900</pubDate>
    </item>
    <item>
      <title>node.js express 6. express의 오류처리</title>
      <link>https://psyhm.tistory.com/46</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이전 포스트: &lt;a href=&quot;https://psyhm.tistory.com/8&quot;&gt;node.js express 5. middleware란? 미들웨어 정의, 미들웨어 유형&lt;/a&gt;&lt;br /&gt;저번 포스트에는 express의 미들웨어 개념을 알아봤습니다. (시간이 꽤 오래 지나버렸다..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 express의 오류 처리 방법에 대해 알아보도록 하겠습니다.&lt;br /&gt;이 포스트에 대한 내용은 express 공식 페이지에서 더 자세하게 알아볼 수 있습니다. &lt;a href=&quot;https://expressjs.com/ko/guide/error-handling.html&quot;&gt;express 오류처리&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;에러 핸들링&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;404 에러 처리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;express는 미들웨어 중간에 &lt;b&gt;오류가 발생&lt;/b&gt;하면 다음 &lt;b&gt;에러 처리 미들웨어로 error 객체를 넘겨 error를 처리&lt;/b&gt;할 수 있도록 만들었습니다.&lt;br /&gt;다음 코드는 app.js의 맨 밑에 있는 코드입니다.&lt;/p&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;// 라우터 등록
app.use('/', indexRouter);
app.use('/users', usersRouter);

// 등록되지 않은 path로 요청이 왔으면 404 페이지를 만들어야함.
// http-errors 모듈로 error 객체 생성 후 에러 처리 핸들러로 넘김
app.use(function(req, res, next) {
  // error 생성 후 next
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // error 템플릿에 전달할 데이터 설정
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드는 등록되지 않은 url에 요청이 온다면 404 Not Found 페이지를 표시하기 위해 오류처리를 한 것입니다.&lt;br /&gt;위의 등록된 url 외의 요청이 온다면 http-errors 모듈을 사용하는 미들웨어로 가게 됩니다.&lt;br /&gt;그 미들웨어에서 error를 생성한 뒤 에러 처리 핸들러로 error를 넘기게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러 처리 핸들러는 기존 미들웨어와 다르게 4개의 파라미터 즉, &lt;b&gt;err, req, res, next&lt;/b&gt;를 가진다는 점입니다.&lt;br /&gt;여기서 중요한 점은 에러 처리 핸들러를 등록하기 위해선 다른 app.use() 및 라우트 호출을 정의한 후에 마지막으로 정의해야 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;라우터의 오류 처리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러 처리 핸들러는 위에서 설명한 대로 다른 app.use() 에서도 사용 가능합니다.&lt;br /&gt;만약 /user 요청에 사용자 정보가 없을 때의 오류 처리 예시를 보도록 하겠습니다.&lt;/p&gt;
&lt;pre class=&quot;lua&quot;&gt;&lt;code&gt;const usersRouter = require('./routes/users');

...

app.use('/users', usersRouter, function (err, req, res, next) {
  console.log(&quot;User Not Found&quot;);
  if(err.message === 'user_not_found') {
      res.status(400)
      .type('html')
      .end(&quot;User doesn't exist&quot;);
  } else {
      res.status(500)
      .type('html')
      .end(&quot;500 error&quot;);
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞의 라우터 usersRouter에서 error가 발생했을 때만 오류 처리를 하고 싶을 땐 app.use()에 따로 등록할 수도 있습니다.&lt;br /&gt;혹은 error 타입마다 오류를 다르게 처리할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 Node.js의 Error 모듈을 상속받는 새로운 타입의 Error 객체를 정의하고 Error 타입마다 다른 방식의 오류 처리 핸들러를 구현한 적도 있습니다. Error 타입만 잘 설정하면 따로 Error 처리에 신경을 쓰지 않아도 되기 때문에 매우 편리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 예를 들어보겠습니다.&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;// ClientError.js
module.exports = class ClientError extends Error {
  constructor (message, status) {
    super(message);
    Error.captureStackTrace(this, this.constructor);

    // status를 따로 설정하지 않으면 default로 400이 설정된다.
    this.status = status || 400;
  }
};

---------------

// userRouter.js

...

const ClientError = require('../ClientError');
let myError = new ClientError(&quot;Test Error&quot;);
next(myError);

...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 이용해 핸들러에서 &lt;code&gt;if(err instanceof ClientError)&lt;/code&gt;로 error 타입 구분하신 뒤에 따로 처리할 수도 있습니다.&lt;/p&gt;
&lt;h1&gt;결론&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;express는 각 라우터에서 발생하는 error를 개별적으로 처리하지 않고 에러 처리 핸들러를 통해 묶어서 처리할 수 있다는 것을 알게됐습니다. 이를 통해 서버 오류를 쉽게 핸들링하고 묶어서 관리할 수 있습니다.&lt;/p&gt;</description>
      <category>Node.js/express</category>
      <category>error</category>
      <category>express</category>
      <category>node.js</category>
      <category>노드js</category>
      <category>오류 처리</category>
      <category>오류 핸들링</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/46</guid>
      <comments>https://psyhm.tistory.com/46#entry46comment</comments>
      <pubDate>Fri, 5 Apr 2019 15:25:40 +0900</pubDate>
    </item>
    <item>
      <title>single thread인 Node.js에서 thread 생성하기 1 - worker_thread 모듈</title>
      <link>https://psyhm.tistory.com/45</link>
      <description>&lt;h1&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(0, 0, 0);&quot;&gt;서론&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h1&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;Node.js는 싱글 스레드 이벤트 루프를 사용한다고 알려져있습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;따라서 Node.js는 싱글 스레드(?)이다. 라고 잘못 아시는 분들도 종종 있구요.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;하지만 Node.js는 이벤트 루프가 싱글 스레드에서 동작 한다는 것이지&lt;b&gt; 내부적으로 스레드풀&lt;/b&gt;을 두어&lt;b&gt; I/O 작업&lt;/b&gt;에 스레드를 사용할 수 있도록 합니다. 이를 통해 병렬적으로 작업을 진행할 수 있는 것입니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;확인을 위해 간단하게 node.js의 http 모듈을 사용해 서버를 띄워보도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none; line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none; line-height: 1.5;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9915884F5C67C39429&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9915884F5C67C39429&quot; width=&quot;820&quot; height=&quot;580&quot; filename=&quot;스크린샷 2019-02-16 오후 4.43.36.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none; line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;간단한 서버 코드&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none; line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none; line-height: 1.5;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 454px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99F3494F5C67C39424&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99F3494F5C67C39424&quot; width=&quot;454&quot; height=&quot;192&quot; filename=&quot;스크린샷 2019-02-16 오후 4.43.56.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none; line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;동작시켰을 때 화면&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;그리고 ps -M 명령어를 사용하여 스레드의 개수를 확인할 수 있습니다. (Mac OS 환경)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none; line-height: 1.5;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/994322415C67C4C022&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F994322415C67C4C022&quot; width=&quot;820&quot; height=&quot;295&quot; filename=&quot;스크린샷 2019-02-16 오후 4.44.15.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none; line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;총 7개의 내부 스레드가 있는 것을 확인할 수 있다.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;위의 사진에서 보다시피 현재 간단한 Node.js 프로세스인데 총 &lt;b&gt;7개의 스레드&lt;/b&gt;가 생겼다는 것을 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;이는 node.js가 사용하는 &lt;b&gt;libuv&lt;/b&gt;의 모듈은 내부적으로 &lt;b&gt;thread pool&lt;/b&gt;을 두어 I/O 작업을 thead pool에 존재하는 thread를 사용해 처리하기 때문에 event loop는 Block 당하지 않고 빠르게 작업을 계속 진행할 수 있는 것입니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그러므로&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;Node.js는 싱글 스레드다 라는 말은 거짓입니다.&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;하지만 프로그래머가 처리할 수 있는 일반적인 javascript 코드들은&amp;nbsp;싱글 스레드인 이벤트 루프에서 작업하게 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;따라서 CPU 작업량이 많은 코드는 다른 자바스크립트 코드를 Block하게 만들어 다른 작업이 중단된 것처럼 보일&amp;nbsp;수 있습니다. 이는 치명적인 문제입니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하지만 슬퍼하긴 이릅니다.&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;Node.js 버전 10.5&lt;/b&gt;부터 thread pool에&amp;nbsp;스레드를 프로그래머가 직접 생성할 수 있게 됐습니다!! 바로 &lt;b&gt;worker_thread&lt;/b&gt;라는 모듈을 통해 스레드를 생성할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;(해당 링크는 Node.js 릴리즈 노트. worker_thread가 추가된 것을 볼 수 있습니다.)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 216, 255);&quot;&gt;&lt;a href=&quot;https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V10.md#2018-06-20-version-1050-current-targos&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot; style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 216, 255);&quot;&gt;링크&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;주의할 점은 node를 실행시킬 때 다음 플래그를 삽입해야 한다는 것입니다.&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;--experimental-worker&lt;/span&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;이제 Node.js의 스레드를 이용하여 CPU hard한 작업들을 event loop에서 처리할 필요 없이 생성한 스레드에 할당하여 작업할 수 있게 됐습니다. 그러면 event loop는 CPU hard한 작업에서 벗어날 수 있습니다. 간단하게 살펴보죠.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;h1&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(0, 0, 0);&quot;&gt;테스트&lt;/span&gt;&lt;/h1&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;테스트 내용은&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;작업은 반복문을 &lt;b&gt;jobSize&lt;/b&gt;만큼 반복하는 것이다.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;1번 케이스는 이벤트 루프인 main thread와 새로운 스레드 2개, 총&lt;b&gt; 3개의 스레드&lt;/b&gt;가 각각의 jobSize를 처리했을 때이다.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2번 케이스는 &lt;b&gt;main thread&lt;/b&gt;가 스레드 2개의 작업을 몰아서 처리하게 되는 경우이다. (case 1의&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;b&gt;jobSize 3배&lt;/b&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;b style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;case1&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;index.js 파일&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;// index.js 파일
const { Worker } = require('worker_threads');
let startTime = process.uptime();           // 프로세스 시작 시간
let jobSize = 100000;
let myWorker1, myWorker2;

myWorker1 = new Worker(__dirname + '/worker.js');        // 스레드를 생성해 파일 절대경로를 통해 가리킨 js파일을 작업
myWorker2 = new Worker(__dirname + '/worker.js');

doSomething();  // event loop가 처리해야 할 CPU 하드한 작업

let endTime = process.uptime();
console.log(&quot;main thread time: &quot; + (endTime - startTime));  // 스레드 생성 시간 + doSomething 처리하는 데 걸린 시간.

function doSomething() {
	let data;
	for (let i = 0; i &amp;lt; jobSize; i++) {      // CPU Hard
		data += i;
	}
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;worker.js 파일&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;//worker.js 파일
let startTime = process.uptime();           // 스레드 생성 시간.
const Worker = require('worker_threads');
let jobSize = 100000;

doSomething();      // 스레드가 처리해야 할 CPU 하드한 작업

let endTime = process.uptime();
console.log(Worker.threadId + &quot; thread time: &quot; + (endTime - startTime));

function doSomething() {
	let data;
	for (let i = 0; i &amp;lt; jobSize; i++) {      // CPU Hard
		data += i;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;결과&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/992DFF335C67CF2836&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F992DFF335C67CF2836&quot; width=&quot;820&quot; height=&quot;116&quot; filename=&quot;스크린샷 2019-02-16 오후 5.51.25.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이번엔 스레드를 사용하지 않고 작업하게 되는 경우를 살펴봅시다&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;case2)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;b style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;index.js 파일&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt; (스레드 삭제 및 작업량을 3배로 함)&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;// index.js 파일
const { Worker } = require('worker_threads');
let startTime = process.uptime();           // 프로세스 시작 시간
let jobSize = 300000;                       // 이전 작업량의 3배
let myWorker1, myWorker2;

// myWorker1 = new Worker(__dirname + '/worker.js');
// myWorker2 = new Worker(__dirname + '/worker.js');

doSomething();  // event loop가 처리해야 할 CPU 하드한 작업

let endTime = process.uptime();
console.log(&quot;main thread time: &quot; + (endTime - startTime));  // 스레드 생성 시간 + doSomething 처리하는 데 걸린 시간.

function doSomething() {
	let data;
	for (let i = 0; i &amp;lt; jobSize; i++) {      // CPU Hard
		data += i;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;결과&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99CFDD395C67CFB22C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99CFDD395C67CFB22C&quot; width=&quot;820&quot; height=&quot;115&quot; filename=&quot;스크린샷 2019-02-16 오후 5.52.40.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이게 어찌 된 일이죠&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;?? &lt;b&gt;스레드를 생성했을 때 오히려 작업 속도가 더 떨어지는군요.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예상으로는 &lt;b&gt;스레드를 생성하는 작업&lt;/b&gt; 자체가 부하가 크다는 것으로 생각해 볼 수 있습니다&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;따라서 이번엔 작업량을 매우 크게 해보았습니다&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;b style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;case1)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;스레드를 사용했을 때 결과 &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;(jobSize =&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1000000000)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9904144E5C67D07D05&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9904144E5C67D07D05&quot; width=&quot;820&quot; height=&quot;156&quot; filename=&quot;스크린샷 2019-02-16 오후 5.56.56.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;b style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;case2)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;스레드를 사용하지 않고 메인 스레드에 몰아줬을 때 결과&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99103A4B5C67D0B32E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99103A4B5C67D0B32E&quot; width=&quot;820&quot; height=&quot;146&quot; filename=&quot;스크린샷 2019-02-16 오후 5.58.15.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이번엔 확실히 &lt;b&gt;스레드를 사용했을 때&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;main thread에서 작업 속도가 &lt;b&gt;3배&lt;/b&gt; 빠른 것을 볼 수 있었습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;h1&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(0, 0, 0);&quot;&gt;결론&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;이번 테스트로 결과를 내보자면 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;1. Node.js에도 &lt;b&gt;스레드를 생성&lt;/b&gt;할 수 있는 방법이 생겼다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;2. CPU hard한 작업이 아니면&lt;b&gt; 스레드 생성&lt;/b&gt;때문에 오히려 &lt;b&gt;처리 시간이 늘어날 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;h1&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(0, 0, 0);&quot;&gt;마무리&lt;/span&gt;&lt;/h1&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;사실 worker_thread 모듈은 더 많은 기능이 존재합니다. 예를 들어 각 thread는 메세지를 통해 데이터를 교환할 수 있습니다. 이번 포스트는 간단하게 Node.js도 스레드를 만들 수 있다라는 주제에 맞춰 작성했기 때문에 다음 작업은 worker_thread 모듈을&amp;nbsp;더 연구하여 다음 포스트에 전달하도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Node.js</category>
      <category>node.js</category>
      <category>Thread</category>
      <category>Thread Pool</category>
      <category>worker_thread</category>
      <category>노드</category>
      <category>생성</category>
      <category>스레드</category>
      <category>스레드 풀</category>
      <category>싱글 스레드</category>
      <category>이벤트 루프</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/45</guid>
      <comments>https://psyhm.tistory.com/45#entry45comment</comments>
      <pubDate>Sat, 16 Feb 2019 18:26:29 +0900</pubDate>
    </item>
    <item>
      <title>Java Socket 클래스 상속하는 방법</title>
      <link>https://psyhm.tistory.com/44</link>
      <description>&lt;meta charset=&quot;UTF-8&quot;&gt;&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width initial-scale=1&quot;&gt;
&lt;title&gt;Java_Socket클래스_상속하는_법&lt;/title&gt;
&lt;h1 style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Java Socket 상속하기&lt;/span&gt;&lt;/h1&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자바를 공부하는 와중에 채팅 서버를 구현해보고 싶었다. &lt;/span&gt;&lt;a href=&quot;https://github.com/Crazy0416/JavaChatServer&quot;&gt;&lt;span style=&quot;color: rgb(92, 209, 229);&quot;&gt;링크&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;간단하게 Room을 구현하는 도중에 채팅방을 이용하는 유저에게 닉네임을 부여하고 싶었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;유저 클래스를 생성하고 그 유저 클래스에 소켓 변수 필드를 만들어도 되지만 간단하게 하고 싶어서 Socket 클래스를 상속 받는 새로운 클래스를 만들어 닉네임과 아이디 필드를 생성하고 싶었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; lang=&quot;java&quot;&gt;&lt;span&gt;public class UserSocket extends Socket {
    private String uid;			// 아이디
    private String name;		// 닉네임
    private PrintWriter pw;		// 소켓 output stream 랩핑
    private BufferedReader br;	// 소켓 input stream 랩핑

    public void setIOStream() throws IOException{
        br = new BufferedReader(new InputStreamReader(this.getInputStream()));
        pw = new PrintWriter(new OutputStreamWriter(this.getOutputStream()));
    }
	...
}

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하지만 웬걸 오류가 발생했다. 다음 코드에서 문제가 발생했다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; lang=&quot;java&quot;&gt;&lt;span&gt;while(true) {
    UserSocket socket = serverSocket.accept();		// ERROR: 타입 에러!! 
    if( socket != null ) {
        ClientSocketHandler sr = new ClientSocketHandler(socket); // 소켓을 필드로 갖는 스레드를 생성합니다.
        t = new Thread(sr);
        t.start();
    }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;ServerSocket 클래스의 인스턴스 serverSocket의 accept() 함수는 연결된 클라이언트의 Socket 인스턴스를 반환한다. 하지만 참조 변수는 UserSocket 타입이기 때문에 타입 에러가 났던 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;안일했다. 이와 관련하여 자료가 있는 지 검색했다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;검색 결과 Socket 클래스를 상속한 새로운 Socket 클래스를 사용하기 위해서는 새로운 ServerSocket 클래스 또한 필요하다는 것을 알았다. &lt;/span&gt;&lt;a href=&quot;https://docs.oracle.com/javase/8/docs/technotes/guides/net/extendingSocks.html#ServerSocket&quot;&gt;&lt;span style=&quot;color: rgb(92, 209, 229);&quot;&gt;오라클 자료&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;/&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://stackoverflow.com/questions/10571777/java-socket-inheritance&quot;&gt;&lt;span style=&quot;color: rgb(92, 209, 229);&quot;&gt;스택오버플로 자료&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그 전에 먼저 ServerSocket 클래스의 accept 메서드 코드를 직접 봤다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; lang=&quot;java&quot;&gt;&lt;span&gt;public Socket accept() throws IOException {
        if (isClosed())
            throw new SocketException(&quot;Socket is closed&quot;);
        if (!isBound())
            throw new SocketException(&quot;Socket is not bound yet&quot;);
        Socket s = new Socket((SocketImpl) null);	// 소켓 인스턴스 생성
        implAccept(s);
        return s;
    }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;소켓 인스턴스 생성 부분을 UserSocket으로 변경하면 되기 때문에 먼저 새로운 ServerSocket 클래스 CustomServerSocket을 생성한 뒤 accept() 메서드를 오버라이딩했다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; lang=&quot;java&quot;&gt;&lt;span&gt;public class CustomServerSocket extends ServerSocket {
    public CustomServerSocket() throws IOException {
        super();
    }

    public CustomServerSocket(int PORT) throws IOException {
        super(PORT);
    }

    @Override
    public Socket accept() throws IOException{
        if (isClosed())
            throw new SocketException(&quot;Socket is closed&quot;);
        if (!isBound())
            throw new SocketException(&quot;Socket is not bound yet&quot;);
        final Socket s = new UserSocket((SocketImpl) null);
        implAccept(s);
        ((UserSocket) s).setIOStream();
        return s;
    }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;추가로 클라이언트가 서버에 소켓을 생성할 때 블록이 되는데 이 때, implAccept 함수에서 블록 되는 것을 알 수 있었다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Java</category>
      <category>extends</category>
      <category>Inherit</category>
      <category>java</category>
      <category>ServerSocket</category>
      <category>socket</category>
      <category>상속</category>
      <category>소켓</category>
      <category>자바</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/44</guid>
      <comments>https://psyhm.tistory.com/44#entry44comment</comments>
      <pubDate>Sun, 10 Feb 2019 21:58:57 +0900</pubDate>
    </item>
    <item>
      <title>REST와 RESTful API</title>
      <link>https://psyhm.tistory.com/43</link>
      <description>&lt;h1&gt;REST란?&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;란 &amp;#39;&lt;strong&gt;소프트웨어 아키텍쳐 모델&lt;/strong&gt;&amp;#39;이다. 자원을 정의하고 자원에 대한 주소를 지정하는 방법에 대한 방법론이다.&lt;br&gt;&lt;strong&gt;Re&lt;/strong&gt;presentational &lt;strong&gt;S&lt;/strong&gt;tate &lt;strong&gt;T&lt;/strong&gt;ransfer의 준말이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Representation (표현)&lt;/strong&gt;: Resources(이미지, 페이지, 비디오, 프로필)는 HTML, 이미지, JSON, XML 등과 같은 어떤 형식(format)으로든 웹 서버에 의해 클라이언트에게 표현된다.&lt;ul&gt;
&lt;li&gt;Resources는 데이터베이스의 데이터나 웹서버의 물리적인 정보를 의미한다.&lt;/li&gt;
&lt;li&gt;리소스를 사람이 읽을 수 있거나 프로그래밍할 수 있도록 정형화된 형식으로 transfer하여 클라이언트에게 전달.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;State (상태)&lt;/strong&gt;: 클라이언트 컴퓨터의 어플리케이션(웹 사이트) 상태가 한 링크에서 다른 링크로 클릭할 때 변경된다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transfer(전이)&lt;/strong&gt;: Representational state (표현 상태)의 Resources(자원)을 웹 서버에서 클라이언트로 전송하는 것을 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;요약&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;REST란 소프트웨어 아키텍처 모델이며 서버 자원(저장된 이미지, 데이터베이스 데이터)을 html이나 jpeg, json 등의 형식으로 나타내어 HTTP 프로토콜을 사용해 클라이언트에게 전달하여 상태를 전이시키는 아키텍처를 말한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;REST 특징 및 제한조건&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Uniform (유니폼 인터페이스)&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;URI로 지정한 리소스에 대한 조작을 &lt;strong&gt;통일되고 한정적인 인터페이스로 수행&lt;/strong&gt;하는 아키텍처 스타일을 말합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stateless (무상태성)&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;작업을 위한 상태 정보를 저장하거나 관리하지 않는다. 따라서 쿠키 정보나 세션 정보를 별도로 저장하지 않기 때문에 들어오는 요청만을 단순히 처리하기만 하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cacheable (캐시 가능)&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;REST는 HTTP 웹 표준을 그대로 따르기 때문에 웹에서 사용하는 기존 인프라를 그대로 사용 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Client-Server (클라이언트-서버 구조)&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;클라이언트와 서버 구조로 일관적인 분리가 되어야 한다. 그러면 클라이언트와 서버가 개발해야될 내용이 명확해지고 서로간의 의존성이 줄어든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Layerd System (계층형 구조)&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;REST 서버는 다중 계층으로 구성될 수 있다. (프록시 서버나 로드 밸런서 등이 중간 계층에 존재할 수 있다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code on Demand&lt;/strong&gt; -optional&lt;ul&gt;
&lt;li&gt;기능 확장을 위해 코드를 전송하여 실행할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;&lt;strong&gt;REST API란?&lt;/strong&gt;&lt;/h1&gt;
&lt;h3&gt;&lt;strong&gt;용어 설명&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;REST&lt;/strong&gt; &lt;strong&gt;A&lt;/strong&gt;pplication &lt;strong&gt;P&lt;/strong&gt;rogramming &lt;strong&gt;I&lt;/strong&gt;nterface의 준말이다.&lt;/li&gt;
&lt;li&gt;API는 &amp;quot;응용 프로그램에서 사용할 수 있도록 다른 시스템이 제공하는 기능을 제어할 수 있게 만든 인터페이스&amp;quot;를 의미한다.&lt;/li&gt;
&lt;li&gt;따라서 REST API는 REST 시스템의 기능을 이용할 수 있도록 인터페이스를 제공하는 것을 말한다.&lt;/li&gt;
&lt;li&gt;REST API를 만드는 방법은 명확한 기준은 없고 비공식적으로 의견들이 수렴되어 만들어졌다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;요약&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;REST 아키텍처의 기능을 제어할 수 있게 만든 인터페이스이며 HTTP URI와 HTTP Method를 이용하여 서버 자원에 대한 여러 기능을 이용할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>컴퓨터 사이언스/용어 정리</category>
      <category>REST</category>
      <category>REST API</category>
      <category>란?</category>
      <category>요약</category>
      <category>정의</category>
      <category>특징</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/43</guid>
      <comments>https://psyhm.tistory.com/43#entry43comment</comments>
      <pubDate>Sat, 9 Feb 2019 17:07:49 +0900</pubDate>
    </item>
    <item>
      <title>HTTP 프로토콜이란?</title>
      <link>https://psyhm.tistory.com/42</link>
      <description>&lt;meta charset=&quot;UTF-8&quot;&gt;&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width initial-scale=1&quot;&gt;
&lt;title&gt;HTTP란&lt;/title&gt;
&lt;h1 style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP 프로토콜&lt;/span&gt;&lt;/h1&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;h2 style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP란 무엇인가?&lt;/span&gt;&lt;/h2&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP란 &lt;/span&gt;&lt;strong&gt;&lt;em&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Hyper Text Transfer Protocal&lt;/span&gt;&lt;/em&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;의 약자로 하이퍼텍스트 문서를 교환하기 위한 프로토콜입니다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;TCP/IP 기반&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;으로 한 지점에서 다른 지점으로 요청과 응답을 전송합니다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;한 지점에서 다른 지점으로 HTTP 프로토콜에 맞춘 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;문자열&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;을 전송합니다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;ex)&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-http&quot; lang=&quot;http&quot;&gt;&lt;span&gt;GET  HTTP/1.1
Host: www.naver.com
cache-control: no-cache

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP는 많은 정보들이 필요하지만 보통 우리가 웹 프레임워크나 라이브러리들이 HTTP 프로토콜 쉽게 사용할 수 있도록 지원하기 때문에 손쉽게 사용할 수 있는 것입니다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;h2 style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP의 특징&lt;/span&gt;&lt;/h2&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;TCP/IP를 이용하는 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;응용 계층&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 프로토콜.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;TCP/IP의 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;socket&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;을 이용해 연결된다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;연결 상태를 유지하지 않는 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;비연결성(Connectionless) 프로토콜&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;요청을 받은 서버가 응답하게 되면 소켓을 유지하지 않고 연결을 disconnect한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;연결을 유지하게 되면 리소스가 계속 사용되고 리소스가 부족하면 다른 사용자가 이용하지 못하기 때문에 결과적으로 더 많은 연결을 위해 비연결 지향으로 설계&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP 1.1 부터는 &lt;/span&gt;&lt;em&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;keep-alive&lt;/span&gt;&lt;/em&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 헤더를 통해 연결을 유지할 수 있음.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Stateless&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클라이언트가 사용자 인증을 하더라도 상태가 유지되지 않기 때문에 Cookie(쿠키) 혹은 Session(세션)을 이용해 인증 등을 해결하기도 한다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;h2 style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP 메세지&lt;/span&gt;&lt;/h2&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;h3 style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메세지 타입&lt;/span&gt;&lt;/h3&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;요청(Request)&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사용자가 서버에게 원하는 데이터를 요구할 때 사용&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;응답(Response)&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;서버가 요청받은 대로 사용자에게 데이터를 줄 때 사용&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;h3 style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메세지 구조&lt;/span&gt;&lt;/h3&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;시작줄 / 헤더 / 바디&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 로 나눌 수 있다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;시작줄&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Request 시, 메서드와 요청 URL, HTTP version ( GET /exam/help.txt HTTP/1.1 )&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Response 시, HTTP version, 상태 코드 및 사유 구절 ( HTTP/1.1 200 OK )&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;헤더&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;요청과 응답 메세지에 대한 추가적인 정보를 담고 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Key/Value 형식으로 나타냄&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;바디&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;전송하고 싶은 실질적인 데이터를 나타냄&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;헤더를 마치고 \n 후에 나타남.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;요청&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 메세지 구조 예제&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-http&quot; lang=&quot;http&quot;&gt;&lt;span&gt;GET /hello.txt HTTP/1.1 		// 시작줄
User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3	// 헤더
Host: www.example.com												// 헤더
Accept-Language: en, mi												// 헤더


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;응답&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 메세지 구조 예제&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-http&quot; lang=&quot;http&quot;&gt;&lt;span&gt;HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: &quot;34aa387-d-1568eb00&quot;
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain

Hello World! My payload includes a trailing CRLF.	// 바디
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;h2 style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP 1.1 vs HTTP 2.0&lt;/span&gt;&lt;/h2&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;처리 방식&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP 1은 앞에 날렸던 요청의 응답을 받아야만 다음 요청이 처리될 수 있었다. (1 요청당 1 리소스)&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;따라서 HOL(Head of Line) 블로킹 문제가 발생했다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP 2에서는 Multiplexing 방식이 도입되어 동시에 여러 리소스를 받아올 수 있게 되었다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;데이터&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;기존 HTTP 1은 문자열로 전송되었다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP 2는 바이너리로 인코딩하여 압축해서 전송한다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;헤더 또한 압축할 수 있다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Server Push&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;브라우저에서 필요한 리소스들을 서버가 찾아서 내려준다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;따라서 HTTP 1에서 html을 파싱하고 필요한 리소스를 찾아 요청할 필요 없이 HTTP 2에서는 필요한 리소스를 찾는 과정 없이 요청할 수 있다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자세한 내용은 다음 링크에 아주 자세히 설명되어있음. &lt;/span&gt;&lt;a href=&quot;https://americanopeople.tistory.com/115&quot;&gt;&lt;span style=&quot;color: rgb(92, 209, 229);&quot;&gt;[HTTP] HTTP 2의 탄생 배경과 특징&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;참고: &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;a href=&quot;https://feco.tistory.com/7&quot; target=&quot;_blank&quot; class=&quot;url&quot;&gt;&lt;span style=&quot;color: rgb(92, 209, 229);&quot;&gt;https://feco.tistory.com/7&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;a href=&quot;https://www.zerocho.com/category/HTTP/post/5b344f3af94472001b17f2da&quot; target=&quot;_blank&quot; class=&quot;url&quot;&gt;&lt;span style=&quot;color: rgb(92, 209, 229);&quot;&gt;https://www.zerocho.com/category/HTTP/post/5b344f3af94472001b17f2da&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;a href=&quot;https://americanopeople.tistory.com/115&quot; target=&quot;_blank&quot; class=&quot;url&quot;&gt;&lt;span style=&quot;color: rgb(92, 209, 229);&quot;&gt;https://americanopeople.tistory.com/115&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(92, 209, 229);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;</description>
      <category>컴퓨터 사이언스/용어 정리</category>
      <category>http</category>
      <category>http 1.1</category>
      <category>HTTP 2.0</category>
      <category>메세지</category>
      <category>요청</category>
      <category>응답</category>
      <category>정의</category>
      <category>특징</category>
      <category>프로토콜</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/42</guid>
      <comments>https://psyhm.tistory.com/42#entry42comment</comments>
      <pubDate>Sat, 9 Feb 2019 01:40:06 +0900</pubDate>
    </item>
    <item>
      <title>[ngrinder] 2Core, 2GB Node.js 서버 간단한 GET 테스트 (pm2 클러스터링 인스턴스 2개)(vuser- 99 test- 19,800)</title>
      <link>https://psyhm.tistory.com/41</link>
      <description>&lt;meta charset=&quot;UTF-8&quot;&gt;&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width initial-scale=1&quot;&gt;

&lt;title&gt;[ngrinder] 2Core, 2GB Node.js 서버 간단한 GET 테스트 (pm2 클러스터링 인스턴스 2개)(vuser- 99 test- 19,800)&lt;/title&gt;

&lt;h1&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사전 설정 &lt;/span&gt;&lt;/h1&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Controller 스펙&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;ul&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;기종: 한성 Bossmonster lv. 67&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;OS: Windows10 pro 64bit&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;processor: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz, 2601Mhz, 4 코어, 8 논리 프로세서&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;RAM: 16.0 GB&lt;/span&gt;&lt;/li&gt;



&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Agent 스펙&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;ul&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;기종: MAC 애플 맥북프로 15형 레티나 리프레시 2015년형 (MJLQ2KH/A)&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;OS: MAC Mojave&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;processor: Intel Core i7 2.2 GHz&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;RAM: 16.0 GB&lt;/span&gt;&lt;/li&gt;



&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Target 스펙&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;ul&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;OS: Ubuntu 14.04&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;processor: 2 Core&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;RAM: 2.0 GB&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Process: 1개 (Not clustering)

&lt;/span&gt;&lt;/li&gt;



&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;스크립트&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; ※ URI 설정만 한 기본 스크립트이다. 이전 포스트와 같다. &lt;/span&gt;&lt;a href=&quot;https://psyhm.tistory.com/40&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이전포스트&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;import static net.grinder.script.Grinder.grinder

import static org.junit.Assert.*

import static org.hamcrest.Matchers.*

import net.grinder.plugin.http.HTTPRequest

import net.grinder.plugin.http.HTTPPluginControl

import net.grinder.script.GTest

import net.grinder.script.Grinder

import net.grinder.scriptengine.groovy.junit.GrinderRunner

import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess

import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread

// import static net.grinder.util.GrinderUtils.* // You can use this if you're using nGrinder after 3.2.3

import org.junit.Before

import org.junit.BeforeClass

import org.junit.Test

import org.junit.runner.RunWith



import java.util.Date

import java.util.List

import java.util.ArrayList



import HTTPClient.Cookie

import HTTPClient.CookieModule

import HTTPClient.HTTPResponse

import HTTPClient.NVPair



/**

 * A simple example using the HTTP plugin that shows the retrieval of a

 * single page via HTTP. 

 * 

 * This script is automatically generated by ngrinder.

 * 

 * @author admin

 */

@RunWith(GrinderRunner)

class TestRunner {



	public static GTest test

	public static HTTPRequest request

	public static NVPair[] headers = []

	public static NVPair[] params = []

	public static Cookie[] cookies = []



	@BeforeProcess

	public static void beforeProcess() {

		HTTPPluginControl.getConnectionDefaults().timeout = 6000

		test = new GTest(1, &quot;1.201.xxx.xxx&quot;)

		request = new HTTPRequest()

		grinder.logger.info(&quot;before process.&quot;);

	}



	@BeforeThread 

	public void beforeThread() {

		test.record(this, &quot;test&quot;)

		grinder.statistics.delayReports=true;

		grinder.logger.info(&quot;before thread.&quot;);

	}

	

	@Before

	public void before() {

		request.setHeaders(headers)

		cookies.each { CookieModule.addCookie(it, HTTPPluginControl.getThreadHTTPClientContext()) }

		grinder.logger.info(&quot;before thread. init headers and cookies&quot;);

	}



	@Test

	public void test(){

		HTTPResponse result = request.GET(&quot;http://1.201.xxx.xxx:xxxx/&quot;, params)



		if (result.statusCode == 301 || result.statusCode == 302) {

			grinder.logger.warn(&quot;Warning. The response may not be correct. The response code was {}.&quot;, result.statusCode); 

		} else {

			assertThat(result.statusCode, is(200));

		}

	}

}



&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;테스트 설정&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; (이전 포스트와 같다.) &lt;/span&gt;&lt;a href=&quot;https://psyhm.tistory.com/40&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이전 포스트&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;ul&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에이전트: 1&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;vuser: 99 (프로세스: 3, 스레드: 33)&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;실행횟수: 200&lt;/span&gt;&lt;/li&gt;



&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;/li&gt;



&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;결과&lt;/span&gt;&lt;/h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/991E49405C567AE733&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F991E49405C567AE733&quot; width=&quot;820&quot; height=&quot;422&quot; filename=&quot;mohim클러스터링(인스턴스2).png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;후기&lt;/span&gt;&lt;/h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에러가 확실히 줄었다. 194개였던 에러가 2개로 확 줄었다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;TPS가 살짝 줄었다. 인스턴스가 늘었는데 TPS가 줄은 것은 어떤 이유일까??&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;ul&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;가설1. pm2가 요청에 대해 로드밸런싱을 처리하기 때문에 줄은 것 같다.&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;가설2. 네트워크 대역폭에 문제가 있다.&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;가설3. 네트워크 I/O 자원에 대해 프로세스 간 경합이 있었다.&lt;/span&gt;&lt;/li&gt;



&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;TPS가 줄었기 때문에 동작 시간(Run time)은 1분 정도 늘었다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음 테스트땐 네트워크 대역폭 모니터링 툴 bmon을 이용하여 네트워크를 체크해봐야할 듯 하다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;/li&gt;



&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;</description>
      <category>프레임워크, 툴/ngrinder</category>
      <category>benchmark</category>
      <category>Groovy</category>
      <category>ngrinder</category>
      <category>node.js</category>
      <category>테스트</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/41</guid>
      <comments>https://psyhm.tistory.com/41#entry41comment</comments>
      <pubDate>Sun, 3 Feb 2019 14:25:23 +0900</pubDate>
    </item>
    <item>
      <title>[ngrinder] 2Core, 2GB Node.js 서버 간단한 GET 테스트(vuser: 99 test: 19,800, )</title>
      <link>https://psyhm.tistory.com/40</link>
      <description>&lt;meta charset=&quot;UTF-8&quot;&gt;&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width initial-scale=1&quot;&gt;
&lt;title&gt;[ngrinder] 2Core, 2GB Node.js 서버 간단한 GET 테스트(vuser- 99 test- 19,800, )&lt;/title&gt;
&lt;h1 style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사전 설정&lt;/span&gt;&lt;/h1&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Controller 스펙&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;기종: 한성 Bossmonster lv. 67&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;OS: Windows10 pro 64bit&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;processor: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz, 2601Mhz, 4 코어, 8 논리 프로세서&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;RAM: 16.0 GB&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Agent 스펙&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;기종: MAC 애플 맥북프로 15형 레티나 리프레시 2015년형 (MJLQ2KH/A)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;OS: MAC Mojave&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;processor: Intel Core i7 2.2 GHz&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;RAM: 16.0 GB&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Target 스펙&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;OS: Ubuntu 14.04&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;processor: 2 Core&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;RAM: 2.0 GB&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Process: 1개 (Not clustering)&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;스크립트&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 
※ URI 설정만 한 기본 스크립트이다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-groovy&quot; lang=&quot;groovy&quot;&gt;&lt;span&gt;import static net.grinder.script.Grinder.grinder
import static org.junit.Assert.*
import static org.hamcrest.Matchers.*
import net.grinder.plugin.http.HTTPRequest
import net.grinder.plugin.http.HTTPPluginControl
import net.grinder.script.GTest
import net.grinder.script.Grinder
import net.grinder.scriptengine.groovy.junit.GrinderRunner
import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess
import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread
// import static net.grinder.util.GrinderUtils.* // You can use this if you're using nGrinder after 3.2.3
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith

import java.util.Date
import java.util.List
import java.util.ArrayList

import HTTPClient.Cookie
import HTTPClient.CookieModule
import HTTPClient.HTTPResponse
import HTTPClient.NVPair

/**
 * A simple example using the HTTP plugin that shows the retrieval of a
 * single page via HTTP. 
 * 
 * This script is automatically generated by ngrinder.
 * 
 * @author admin
 */
@RunWith(GrinderRunner)
class TestRunner {

	public static GTest test
	public static HTTPRequest request
	public static NVPair[] headers = []
	public static NVPair[] params = []
	public static Cookie[] cookies = []

	@BeforeProcess
	public static void beforeProcess() {
		HTTPPluginControl.getConnectionDefaults().timeout = 6000
		test = new GTest(1, &quot;1.201.xxx.xxx&quot;)
		request = new HTTPRequest()
		grinder.logger.info(&quot;before process.&quot;);
	}

	@BeforeThread 
	public void beforeThread() {
		test.record(this, &quot;test&quot;)
		grinder.statistics.delayReports=true;
		grinder.logger.info(&quot;before thread.&quot;);
	}
	
	@Before
	public void before() {
		request.setHeaders(headers)
		cookies.each { CookieModule.addCookie(it, HTTPPluginControl.getThreadHTTPClientContext()) }
		grinder.logger.info(&quot;before thread. init headers and cookies&quot;);
	}

	@Test
	public void test(){
		HTTPResponse result = request.GET(&quot;http://1.201.xxx.xxx:xxxx/&quot;, params)

		if (result.statusCode == 301 || result.statusCode == 302) {
			grinder.logger.warn(&quot;Warning. The response may not be correct. The response code was {}.&quot;, result.statusCode); 
		} else {
			assertThat(result.statusCode, is(200));
		}
	}
}

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;테스트 설정&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에이전트: 1&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;vuser: 99 (프로세스: 3, 스레드: 33)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;실행횟수: 200&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;h3 style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;결과&lt;/span&gt;&lt;/h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;text-align: center; clear: none; float: none; line-height: 1.5;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99CA6F345C2B0BDB0F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99CA6F345C2B0BDB0F&quot; width=&quot;820&quot; height=&quot;370&quot; filename=&quot;스크린샷 2019-01-01 오후 3.16.55.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;h3 style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;후기&lt;/span&gt;&lt;/h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;리눅스 TCP나 파일 디스크럽터를 커스텀하지 않은 채 서버를 구동한 것이기 때문에 TPS가 굉장히 낮았다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;서버 성능이 아무리 낮아도 이 정도 성능 밖에 안나올 줄은 몰랐다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음엔 node 클러스터링 후에 테스트 해보고 비교해 볼 예정이다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>컴퓨터 사이언스/ngrinder 부하 테스트 정리</category>
      <category>benchmark</category>
      <category>Groovy</category>
      <category>ngrinder</category>
      <category>node.js</category>
      <category>테스트</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/40</guid>
      <comments>https://psyhm.tistory.com/40#entry40comment</comments>
      <pubDate>Tue, 1 Jan 2019 15:45:05 +0900</pubDate>
    </item>
    <item>
      <title>백준-1920 수 찾기 해답 및 풀이</title>
      <link>https://psyhm.tistory.com/39</link>
      <description>&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;문제 링크: &lt;/span&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;/span&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1920&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;https://www.acmicpc.net/problem/1920&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;핵심 아이디어&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;1.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;이진 탐색으로 검색하면 검색 시간을 줄일 수 있다. (이진 탐색을 위해 정렬은 필수)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;2. 정렬은 algorithm 라이브러리의 sort 함수를 사용. (충분히 빠르다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(36, 39, 41); font-family: Arial, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif; font-size: 15px;&quot;&gt;n log n&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;3. 빠른 출력을 위해 표준 출력 설정값을 바꾼다. 링크:&amp;nbsp;&lt;a href=&quot;https://www.acmicpc.net/problem/15552&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://www.acmicpc.net/problem/15552&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;내가 실수했던 것&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;1. vector의 size()의 리턴 타입이 unsigned long이여서 계산을 unsigned long으로 하였더니 계산 오류가 발생했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;2. 이진 탐색의 범위를 이상하게 설정하였다. ( ex.&amp;nbsp;end_idx = cur_idx - 1;을 end_idx = cur_idx로 또 계산하게 되었다.)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;c++ 코드&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;ltiostream&amp;gt
#include &amp;ltvector&amp;gt
#include &amp;ltcstdio&amp;gt
#include &amp;ltalgorithm&amp;gt

using namespace std;

bool binarySearch(vector&amp;ltint&amp;gt&amp; v, int x) {     //이진 탐색
    int cur_idx = 0;
    int begin_idx = 0;
    int end_idx = v.size() - 1;

    while(begin_idx &lt;= end_idx) {
        cur_idx = ( begin_idx + end_idx ) / 2;

        if(v[cur_idx] == x) {
            return true;
        } else {
            if(v[cur_idx] &gt; x)
                end_idx = cur_idx - 1;
            else
                begin_idx = cur_idx + 1;
        }
    }

    return false;
}

void inputVector(vector&amp;ltint&amp;gt&amp; v, int size) {
    int dump;

    for(int i = 0; i &lt; size; i++) {
        cin &gt;&gt; dump;
        v.push_back(dump);
    }
}

int main() {
    cin.tie(NULL);                    // 표준 입출력 설정
    ios::sync_with_stdio(false);


    int N, M;

    cin &gt;&gt; N;
    vector&amp;ltint&amp;gt A;
    inputVector(A,N);

    cin &gt;&gt; M;
    vector&amp;ltint&amp;gt m;
    inputVector(m,M);

    sort(A.begin(), A.end());

    for(int i = 0; i &lt; m.size(); i++) {
        cout &lt;&lt; binarySearch(A, m[i]) &lt;&lt; &quot;\n&quot;;
    }

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>잡다한 것들/알고리즘 문제풀이</category>
      <category>1920</category>
      <category>백준</category>
      <category>백준 1920</category>
      <category>알고리즘</category>
      <category>이진탐색</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/39</guid>
      <comments>https://psyhm.tistory.com/39#entry39comment</comments>
      <pubDate>Wed, 26 Dec 2018 13:44:15 +0900</pubDate>
    </item>
    <item>
      <title>지식 그래프(Knowledge Graph) 만들기-3 n-triple(nt)이란?, cayley 그래프란??</title>
      <link>https://psyhm.tistory.com/38</link>
      <description>&lt;h1&gt;들어가기 전에&lt;/h1&gt;
&lt;p&gt;이 포스트는 학교 프로젝트로 지식 그래프를 구축해보고 그에 대한 서비스 구현까지 완료해보기 위해 그에 대한 자료를 정리하는 글입니다. 이에 관해 공부해보는 사람들에게 도움이 되었으면 해서 글을 공유하고자 합니다.&lt;/p&gt;
&lt;p&gt;저번 포스트에서는 시맨틱 웹과 RDF가 무엇인지 알아보았다면 이번 포스트에선 RDF 그래프를 텍스트 형식으로 표현한 N-triple과 nt 파일, 그리고 cayley 오픈소스에 대해 알아보도록 하겠습니다.&lt;/p&gt;
&lt;h1&gt;N-triple이란?&lt;/h1&gt;
&lt;p&gt;출처: &lt;a href=&quot;https://www.w3.org/TR/n-triples/&quot;&gt;https://www.w3.org/TR/n-triples/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;N-triple이란 간단히 말하여 RDF 그래프를 한 줄씩 텍스트 형식으로 나타낸 것을 의미합니다. 파일 확장자로서 nt를 사용합니다.&lt;/p&gt;
&lt;p&gt;이전의 포스트에선 RDF 트리플이 무엇인지에 대해 배웠습니다. 이 RDF 트리플을 텍스트 파일 한 줄로 나타낸 것을 N-triple 형식이라고 하고 확장자 nt로서 저장합니다.&lt;/p&gt;
&lt;p&gt;눈으로 확인하는게 제일이니 예시를 들어보겠습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;http://psyhm.tistory.com/resource/laptop&amp;gt; &amp;lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&amp;gt; &amp;lt;http://www.w3.org/2000/01/rdf-schema#Class&amp;gt; . &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;먼저 보면 공백을 기준으로 4개로 나눌 수 있습니다. &amp;lt;&lt;a href=&quot;http://psyhm.tistory.com/resource/laptop&quot;&gt;http://psyhm.tistory.com/resource/laptop&lt;/a&gt;&amp;gt;, &amp;lt;&lt;a href=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&quot;&gt;http://www.w3.org/1999/02/22-rdf-syntax-ns#type&lt;/a&gt;&amp;gt;, &amp;lt;&lt;a href=&quot;http://www.w3.org/2000/01/rdf-schema#Class&quot;&gt;http://www.w3.org/2000/01/rdf-schema#Class&lt;/a&gt;&amp;gt; 그리고 &amp;#39;.&amp;#39; 입니다. 편하게 앞에서부터 A, B, C라고 하겠습니다.&lt;/p&gt;
&lt;p&gt;먼저 맨 앞의 데이터 A는 RDF 트리플의 &lt;strong&gt;주어(Subject&lt;/strong&gt;)입니다. 그 뒤로 순서대로 B는 &lt;strong&gt;서술어(Predicate)&lt;/strong&gt;와 C는 &lt;strong&gt;목적어(Object)&lt;/strong&gt;입니다. &amp;#39;.&amp;#39;(점)은 이 줄의 끝 즉, RDF 트리플의 끝을 나타냅니다.&lt;/p&gt;
&lt;p&gt;그리고 &amp;#39;&amp;lt;&amp;#39;와 &amp;#39;&amp;gt;&amp;#39;로 이루어진 데이터를 &lt;strong&gt;IRI(Internationalized Resource Identifier)&lt;/strong&gt;라고 부르고 이는 RDF 그래프에 존재하는 단 하나의 node를 의미합니다.&lt;/p&gt;
&lt;p&gt;다음 트리플을 해석하자면 A는 B 속성으로 C라는 의미입니다. 다시 말해서 &lt;strong&gt;A와 C는 B의 관계를 가지고 있다&lt;/strong&gt;는 의미입니다.&lt;/p&gt;
&lt;p&gt;다른 예시를 보겠습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;http://psyhm.tistory.com/resource/laptop&amp;gt; &amp;lt;http://psyhm.tistory.com/predicate/name&amp;gt; &amp;quot;노트북&amp;quot;^^&amp;lt;string&amp;gt; . &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;다음 N-triple은 위와 조금 다릅니다. 주어(Subject)는 같지만 서술어(Predicate)와 목적어(Object)는 다릅니다. 그리고 Object는 단순 문자열로 이루어져 있습니다. 이렇게 단순 string이나 number, date가 올 수 있는데 이를 &lt;strong&gt;Literal&lt;/strong&gt;이라고 부릅니다.&lt;/p&gt;
&lt;p&gt;두 예시를 그림으로 나타내면 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;820&quot; height=&quot;495&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;495&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://t1.daumcdn.net/cfile/tistory/99480C3F5C0E2CB60D?original&quot; data-phocus=&quot;https://t1.daumcdn.net/cfile/tistory/99480C3F5C0E2CB60D?original&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99480C3F5C0E2CB60D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99480C3F5C0E2CB60D&quot; width=&quot;820&quot; height=&quot;495&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;495&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;RDF 그래프는 사실 어휘 구조가 잡혀있지 않습니다. 단순히 주어와 목적어의 관계를 나타낼 뿐 그 이상의 의미를 가지기 어렵습니다. 따라서 사용자는 그래프에서 의미있는 혹은 연관있는 데이터를 추출하기 어렵습니다. 이를 해결할 방안으로 &lt;strong&gt;&amp;#39;스키마&amp;#39;&lt;/strong&gt; 혹은 &lt;strong&gt;&amp;#39;온톨로지&amp;#39;&lt;/strong&gt; 라고 불리는 어휘 구조를 만들어냈습니다.&lt;/p&gt;
&lt;p&gt;링크: &lt;a href=&quot;https://www.w3.org/TR/rdf-schema/&quot;&gt;https://www.w3.org/TR/rdf-schema/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;이처럼 RDF의 N-triple을 이용하면 그래프로서 구현할 수 있게 되고 그래프 데이터베이스에서 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;필자는 그래프 오픈소스로서 cayley를 이용하여 RDF 그래프를 생성하였습니다.&lt;/p&gt;
&lt;h1&gt;cayley 그래프&lt;/h1&gt;
&lt;p&gt;링크: &lt;a href=&quot;https://cayley.io/&quot;&gt;https://cayley.io/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;도큐먼트: &lt;a href=&quot;https://github.com/cayleygraph/cayley/tree/master/docs&quot;&gt;https://github.com/cayleygraph/cayley/tree/master/docs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cayley 홈페이지에서 cayley를 다음과 같이 소개하고 있습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;cayley는 Freebase 기반의 그래프 데이터베이스와 구글의 지식 그래프에 영감을 얻은 오픈 소스 그래프이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cayley를 이용하면 N-triple 같은 RDF 파일을 load 하여 자동으로 그래프를 구현해주고 다양한 Query를 이용하여 그래프에서 데이터를 추출할 수 있습니다. 사실 그래프 데이터베이스의 SQL 격인 Sparql은 Cayley에서 지원해주지 않아서 프로젝트에서 쿼리 작성하는게 조금 어려웠지만 Cayley에서 지원해주는 다른 Query로 질의어를 작성하였습니다.&lt;/p&gt;
&lt;p&gt;cayley를 사용하기 위해서 먼저 cayley를 다운 받아야합니다. 링크: &lt;a href=&quot;https://github.com/cayleygraph/cayley/releases&quot;&gt;https://github.com/cayleygraph/cayley/releases&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;저는 맥 유저이기 때문에 cayley darwin이라는 zip 파일을 다운받아 설치하였습니다.&lt;/p&gt;
&lt;p&gt;도큐먼트를 보면 간단히 Cayley를 이용하는 법에 대해 설명하고 있습니다. 링크: &lt;a href=&quot;https://github.com/cayleygraph/cayley/blob/master/docs/Quickstart-As-Application.md&quot;&gt;https://github.com/cayleygraph/cayley/blob/master/docs/Quickstart-As-Application.md&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./cayley http -i ./data/30kmoviedata.nq.gz -d memstore --host=:64210 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;위의 명령어는 cayley 그래프를 http 서버를 이용하여 visualize하거나 질의를 보낼 수 있도록 실행하는 것입니다.&lt;/p&gt;
&lt;p&gt;-i 옵션은 nq파일(N-Quad)을 그래프에 input 하라는 명령입니다.&lt;/p&gt;
&lt;p&gt;-d 옵션은 database로서 memstore를 사용한다는 의미입니다. cayley 자체가 그래프 데이터베이스가 아니라 그래프를 구현할 수 있도록 제공하는 애플리케이션이기 때문에 database를 설정해야합니다. 추후에 NoSql이나 Key-value, 그리고 RDBMS에서 그래프를 저장할 수도 있지만 현재는 간단하게 메모리에 저장하도록 설정한 것입니다.&lt;/p&gt;
&lt;p&gt;—host 옵션은 호스트:포트를 설정하여 서버를 설정하는 것입니다. :64210의 의미는 웹브라우저에 &lt;a href=&quot;http://localhost:64210&quot;&gt;http://localhost:64210&lt;/a&gt;을 입력하면 cayley 그래프에 접근할 수 있다는 의미입니다.&lt;/p&gt;
&lt;p&gt;다른 그래프 데이터베이스를 사용하기 위해선 configuration 파일을 작성한 뒤에 &lt;code&gt;init&lt;/code&gt; 명령어로 그래프를 초기화해주어야 합니다. 링크: &lt;a href=&quot;https://github.com/cayleygraph/cayley/blob/master/docs/Configuration.md&quot;&gt;https://github.com/cayleygraph/cayley/blob/master/docs/Configuration.md&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;저는 cayley.json을 cayley 디렉토리에 저장하여 configuration 파일을 작성하였습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{     &amp;quot;store&amp;quot;: {         &amp;quot;backend&amp;quot;: &amp;quot;mongo&amp;quot;,         &amp;quot;address&amp;quot;: &amp;quot;localhost:27017&amp;quot;,         &amp;quot;options&amp;quot;: {             &amp;quot;database_name&amp;quot;:&amp;quot;cayley&amp;quot;         }     },     &amp;quot;query&amp;quot;: {         &amp;quot;timeout&amp;quot;: &amp;quot;30s&amp;quot;     } } &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;저는 mongodb를 그래프를 저장할 데이터베이스로 설정하였습니다. 그 뒤에 init 명령어로 초기화하였습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./cayley init --db=mongo --dbpath=&amp;quot;localhost:27017&amp;quot; &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;그 뒤에 nt 파일을 load 하여 그래프를 구축하였습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./cayley load -i &amp;lt;nt 혹은 nq 파일의 path&amp;gt; &lt;/code&gt;&lt;/pre&gt;</description>
      <category>개인 프로젝트/지식 그래프(Knowledge Graph) 만들기</category>
      <category>Cayley</category>
      <category>Knowledge Graph</category>
      <category>N-triple</category>
      <category>RDF</category>
      <category>그래프</category>
      <category>지식 그래프</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/38</guid>
      <comments>https://psyhm.tistory.com/38#entry38comment</comments>
      <pubDate>Mon, 10 Dec 2018 18:09:30 +0900</pubDate>
    </item>
    <item>
      <title>운영체제 정리: 운영체제 시스템이란?</title>
      <link>https://psyhm.tistory.com/37</link>
      <description>&lt;meta charset=&quot;UTF-8&quot;&gt;&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width initial-scale=1&quot;&gt;
&lt;title&gt;chapter1&lt;/title&gt;
&lt;h1&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;소개&lt;/span&gt;&lt;/h1&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;링크: &lt;/span&gt;&lt;a href=&quot;https://github.com/Crazy0416/Study_Summery/blob/master/OS/chapter1.md&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;https://github.com/Crazy0416/Study_Summery/blob/master/OS/chapter1.md&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;h2&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;운영체제 시스템이란?&lt;/span&gt;&lt;/h2&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하드웨어&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;와 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;응용 프로그램&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 사이의 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;중개인 역할&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;을 하는 소프트웨어&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;운영체제의 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;목표&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사용자에게 컴퓨터에서 프로그램을 효율적이고 편리하게 실행할 수 있는 환경을 제공&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;컴퓨터 자원의 할당. 이 할당은 공정해야 하며 효율적으로 이루어져야 함.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;제어 프로그램으로 사용자 프로그램의 실행을 감독하여 오류와 컴퓨터 오용을 방지하고 입출력 장치의 제어와 동작을 관리한다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;h2&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;컴퓨터 시스템의 구조&lt;/span&gt;&lt;/h2&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;컴퓨터 시스템의 동작&lt;/span&gt;&lt;/h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Crazy0416/Study_Summery/master/OS/resource/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202018-11-01%20%EC%98%A4%ED%9B%84%201.21.43.png&quot; alt=&quot;컴퓨터 시스템 구조&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;현대의 범용 컴퓨터는 공유된 주기억장치에 접근을 제공하는 공통 버스에 의해 연결된 CPU와 여러 개의 장치 제어기(device controller)로 구성되어 있다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;장치 제어기: 각 장치(디스크, 오디오 장치, 비디오 디스플레이)를 관리한다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;컴퓨터가 처음으로 구동되면 초기에 실행될 프로그램이 필요하다. 이를 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;부트스트랩(bootstrap)&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이라고 한다. 이 프로그램은 보통 컴퓨터 하드웨어(ROM) 내에 저장되어 있다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;부트스트랩은 모든 하드웨어를 초기화하고 운영체제 커널을 주기억 장치에 적재한 후 커널을 실행한다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;컴퓨터에서 사건의 발생은 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터럽트(Interrupt)&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 신호 또는 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;트랩(Trap)&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;을 통해 운영체제로 통보된다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터럽트&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 하드웨어 장치가 CPU의 인터럽트 라인을 세팅&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;트랩&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 소프트웨어 인터럽트라고도 하며 소프트웨어가 CPU의 인터럽트 라인을 세팅. 대표적인 예로 시스템 콜(System call), 예외 상황(Exception)이 있다. &lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터럽트&lt;/span&gt;&lt;/h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ol start=&quot;&quot;&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터럽트의 일반적 기능&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터럽트가 발생하면 CPU는 하던 일을 멈추고 인터럽트를 처리하기 위한 루틴(운영 체제 커널 내부 코드)에 들어가서 정의된 일을 찾게 된다. 운영 체제는 할 일을 쉽게 찾아가기 위해 인터럽트 벡터(interrupt vector)를 가지고 있다. 인터럽트 벡터란 인터럽트 종류마다 번호를 정해서, 번호에 따라 처리해야 할 코드가 위치한 부분을 포인터로 가리키고 있는 자료 구조이다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터럽트 서비스 루틴을 통해 해당하는 인터럽트를 처리하고 나면 원래 수행하던 작업으로 돌아가 정지되었던 일을 계속해서 수행한다. 인터럽트 처리 후 되돌아갈 위치를 알아야 하므로 인터럽트 처리 전에 수행 중이던 작업이 무엇이었는지 반드시 저장해 두어야 한다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터럽트 처리 루틴&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ol start=&quot;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;장치가 인터럽트 신호를 보냄&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;CPU는 현재 작업 중이던 명령을 멈춘 뒤 커널 모드로 바뀐 후 현재 PC(Program counter)와 다른 상태를 커널 스택에 저장한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;CPU는 벡터 테이블에서 인터럽트 벡터를 fetch한 뒤 그 주소로 분기한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터럽트 루틴은 장치 데이터베이스를 검사하고 인터럽트가 요구한 명령을 수행합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터럽트 핸들러가 명령을 완료하고 이전 상태를 복구하고 유저 모드로 복귀합니다. (혹은 스케줄러에게 다른 프로그램으로 전환하도록 요청)&lt;/span&gt;&lt;/li&gt;

&lt;/ol&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ol&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;I/O 구조&lt;/span&gt;&lt;/h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;장치 제어기에 따라 하나 이상의 장치가 제어기에 연결될 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;장치 제어기는 로컬 버퍼와 몇가지 특수 레지스터를 유지한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;장치 제어기는 연결된 주변장치와 로컬 버퍼간의 데이터 이동을 책임진다. 버퍼 크기는 주변 장치에 따라 다르다. &lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ol start=&quot;&quot;&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;I/O 인터럽트&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;I/O를 시작하기 위해 CPU는 장치 제어기 내에 있는 레지스터에 적절한 데이터를 적재한다. 제어기는 이것을 검사하여 어떤 행동을 취할지 결정한다. 입출력의 수행이 끝나면 보통 인터럽트를 통해 CPU에 그 사실을 통보한다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;입출력의 두 가지 형태&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;동기식 입출력(Synchronous I/O): 입출력이 시작되면 요청한 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;프로세서&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 입출력이 완료될 때까지 기다린다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;비동기식 입출력(Asynchronous I/O): 요청한 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;프로세서&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 입출력이 완료될 때까지 기다리지 않고 계속 다른 작업을 수행한다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;I/O 방식&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;직접 I/O 방식: 주기억 장치와 장치 제어기 간의 데이터 전송을 CPU가 직접 책임지는 방식(ex. 폴링 방식)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;간접 I/O 방식&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: CPU가 직접 입출력을 담당하지 않고 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터럽트&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 사용하여 전용 입출력 프로세서인 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;DMA&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;나 채널을 이용하는 방식&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;DMA 구조&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;장치 제어기는 데이터 블록을 CPU의 관여 없이 직접 주기억 장치로 이동하며, 인터럽트는 바이트 단위가 아닌 블록 단위로 발생한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;입출력 명령을 만나면 CPU는 DMA에게 입출력 명령을 내린 후 다른 프로그램을 수행.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;DMA는 자동으로 입출력 처리하고 완료시 CPU에게 인터럽트로 완료 사실을 보고.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ol&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;저장 장치의 구조&lt;/span&gt;&lt;/h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;주기억 장치와 보조기억 장치로 구분&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;주기억 장치 용도&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;프로그램 실행 용도&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;보조기억 장치:&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;파일 시스템&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메모리 연장 공간인 스왑용&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ol start=&quot;&quot;&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;저장 장치의 계층 구조&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Crazy0416/Study_Summery/master/OS/resource/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202018-11-03%20%EC%98%A4%ED%9B%84%204.22.58.png&quot; alt=&quot;저장 장치의 계층 구조&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;캐싱&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;CPU가 데이터를 필요하면 먼저 캐시에 그 데이터가 있는 지 검사한다. 만약 있으면 캐시에서 바로 사용하고 없으면 메인 메모리에 있는 데이터를 사용하지만 이 데이터의 복사본을 캐시에 보관한다. 이것은 이 데이터를 곧 또 다시 사용할 확률이 높기 때문이다. &lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ol&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하드웨어 보호&lt;/span&gt;&lt;/h3&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다중 프로그래밍 환경에서는 하나의 프로세스의 오류가 다른 프로세스에게도 영향을 줄 수 있다. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;따라서 운영체제는 이런 오류가 다른 프로세스에 영향을 주지 않도록 해야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;보통, 오류가 발생하면 하드웨어는 트랩을 발생하며, 운영체제는 트랩을 발생시킨 프로세스를 강제로 종료시키고 적절한 오류 메세지를 출력한다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ol start=&quot;&quot;&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이중모드 동작&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;여러 오류로부터 프로세스를 보호하기 위해 두 가지 동작 모드를 제공한다. 현재 모드를 나타내기 위해 하드웨어에 이것을 나타내는 모드 비트(mode bit)가 있다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사용자 모드&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 사용자 프로세스는 이 모드에서 수행되다가 인터럽트나 트랩이 발생하면 모니터 모드로 전환된다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;모니터 모드&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 다른 말로 슈퍼바이저(supervisor) 모드, 시스템 모드, 특권(privileged) 모드라 한다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;문제를 일으킬 소지가 있는 명령어는 특권 명령으로 분류하고 이 명령은 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;모니터 모드(특권 모드, 슈퍼바이저 모드)&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에서만 수행되도록 하여 프로세스를 보호한다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사용자는 운영체제만이 수행할 수 있는 특권 명령의 수행을 부탁하여 운영체제와 상호작용한다. 이런 요청을 보통 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;시스템 콜(system call)&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이라 하며, 하드웨어는 이런 시스템 콜을 &lt;/span&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;소프트웨어 인터럽트(트랩)&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;로 간주한다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;입출력 보호&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사용자가 불법적인 입출력 요청을 할 수 없도록 모든 입출력 명령은 특권 명령으로 분류한다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;주기억장치 보호&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;주기억 장치 영역은 사용자 프로그램으로부터 보호되어야 하며, 사용자 프로그램이 사용하는 주기억장치 영역은 다른 사용자 프로그램으로부터 보호되어야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;주기억장치를 보호하기 위해서는 특정 프로그램이 접근할 수 있는 주기억장치 영역을 결저할 수 있어야 한다. 보통 기준 레지스터(base register)와 한계 레지스터(limit register)를 이용하여 영역을 나타낸다. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사용자 프로그램은 기준 레지스터에 있는 주소 ~ 한계 레지스터 값 사이의 주소 영역만 접근 가능&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;CPU 보호&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;운영체제가 항상 제어권을 확보할 수 있도록 해야 한다. 사용자 프로그램이 무한루프에 빠져 제어권을 다시 운영체제에 넘기지 않을 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 문제를 해결하기 위해 타이머를 사용한다. 일정 시간이 경과되면 타이머는 인터럽트를 발생하여 운영체제에 제어권을 넘긴다.&lt;/span&gt;&lt;/li&gt;

&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/li&gt;

&lt;/ol&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;

&lt;/span&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>컴퓨터 사이언스/운영체제</category>
      <category>I/O 구조</category>
      <category>운영체제</category>
      <category>인터럽트</category>
      <category>입출력 형태</category>
      <category>저장 장치</category>
      <category>컴퓨터 시스템</category>
      <category>트랩</category>
      <category>하드웨어 보호</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/37</guid>
      <comments>https://psyhm.tistory.com/37#entry37comment</comments>
      <pubDate>Fri, 9 Nov 2018 13:52:25 +0900</pubDate>
    </item>
    <item>
      <title>지식 그래프(Knowledge Graph) 만들기-2 시맨틱 웹이란??, RDF란 무엇인가??</title>
      <link>https://psyhm.tistory.com/36</link>
      <description>&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 700; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;font-size: 18pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 18pt;&quot;&gt;들어가기 전에&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;hr&gt;&lt;/div&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot; id=&quot;docs-internal-guid-901093dd-7fff-dad7-519a-98cefaced89d&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;이 포스트는 학교 프로젝트로 지식 그래프를 구축해보고 그에 대한 서비스 구현까지 완료해보기 위해 그에 대한 자료를 정리하는 글입니다. 이에 관해 공부해보는 사람들에게 도움이 되었으면 해서 글을 공유하고자 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;저번 포스트에서는 지식 그래프가 무엇인지 알아보았다면 이번 포스트에선 그의 기반 지식인 시맨틱 웹(Semantic Web)과 RDF에 관해 정리하는 포스트를 작성해볼까 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;직접 연구한 것이 아닌 여러 자료를 찾아서 나름대로 추합한 자료이기 때문에 틀린 내용이 있다면 태클 부탁드립니다!!&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 18pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 700; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;시맨틱 웹이란??&lt;/span&gt;&lt;/p&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;hr&gt;&lt;/div&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot; id=&quot;docs-internal-guid-50e8373c-7fff-4b61-5e81-6d0e4d70f34b&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;위키피디아에선 시맨틱 웹을 다음과 같이 정의합니다.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.38;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;시맨틱 웹(Semantic Web)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;'&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;의미론적인 웹&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;'&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;이라는 뜻으로,현재의 인터넷과 같은 분산환경에서 &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;b style=&quot;font-size: 14.6667px; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;리소스&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: 12pt; white-space: pre-wrap; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;와 &lt;/span&gt;&lt;span style=&quot;background-color: transparent; font-size: 12pt; white-space: pre-wrap; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;리소스(웹 문서, 각종 화일, 서비스 등)에 대한 &lt;/span&gt;&lt;b style=&quot;background-color: transparent; font-size: 11pt; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;정보&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: transparent; font-size: 11pt; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt; 사이의 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;관계-의미 정보(Semanteme)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;를 기계(컴퓨터)가 처리할 수 있는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;온톨로지 형태&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;로 표현하고, 이를 자동화된 기계(컴퓨터)가 처리하도록 하는 프레임워크이자 기술이다.&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.38;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;현재 인터넷의 기반인 WWW(World Wide Web)은 정보의 홍수라는 표현을 쓸 정도로 많은 정보들이 그 안에 존재합니다. &lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;background-color: transparent; font-size: 12pt; white-space: pre-wrap; color: rgb(0, 0, 0);&quot;&gt;그러나 이런 웹 데이터들은 사람들이 보기는 쉽지만 0과 1만 이해하는 기계들이 이해하기 어려운 정보들입니다. 단순한 HTML 구조로는 정보들간의 관계를 자동화된 기계가 처리하기 어렵기 때문입니다. 사람들은 이러한 정보들을 데이터베이스처럼 표현할 수 없을까 고민하기 시작했습니다. &lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;그래서 나온 대안이 &lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;시맨틱 웹(Semantic Web)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;입니다. &lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.38;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;따라서 위키피디아의 말을 풀어서 말하자면 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.38;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Gungsuh, 궁서, serif; color: rgb(0, 0, 0);&quot;&gt;웹 상의 정보에 잘 정의된 의미(semantic)를 부여함 으로써 사람뿐만 아니라 컴퓨터도 쉽게 문서의 의미를 자동 화하여 처리할 수 있도록 하는 기술&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;이라고 생각하면 되겠습니다.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;그렇다면 RDF는 시맨틱 웹에서 무엇이고 어떤 역할을 할까요??&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 18pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 700; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;RDF란??&lt;/span&gt;&lt;/p&gt;&lt;div style=&quot;line-height: 1.5;&quot;&gt;&lt;hr&gt;&lt;/div&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;RDF는 (Resource Description Framework)의 약자로 URI를 갖는 모든 Resouce(웹 페이지, 이미지, 동영상 등)들의 속성, 특성, 관계 등을 기술(설명)하기 위한 모델, 언어, 문법이라는 의미를 가지고 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;br class=&quot;kix-line-break&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;br class=&quot;kix-line-break&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;RDF는 그래프 방식의 데이터 모델입니다. &lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 410px; width: 410px; height: 91px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99FC37475BC17B403A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99FC37475BC17B403A&quot; width=&quot;410&quot; height=&quot;91&quot; filename=&quot;스크린샷 2018-10-12 오후 3.11.50.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;width: 410px; height: 91px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;br class=&quot;kix-line-break&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;RDF는 두 자원(주어, 목적어)간의 관계를 표현한 것으로, 서술어는 이 관계의 특성, 특징을 설명합니다. 다음 그래프를 RDF 그래프라고 부르며 &lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;&amp;lt;주어&amp;gt; &amp;lt;서술어&amp;gt; &amp;lt;목적어&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; 구조의 문장을 &lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;트리플(Triple)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;이라고 부릅니다. 그리고 관계는&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt; 방향성&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;을&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; 가집니다. &lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot; id=&quot;docs-internal-guid-ee3abbb0-7fff-df4e-7d6b-9bad926bc7c6&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;저번 포스트에선 지식 그래프는 시맨틱 그래프라고 하였습니다. &lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;a href=&quot;https://psyhm.tistory.com/35&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: rgb(140, 140, 140); font-size: 12pt;&quot;&gt;&lt;u&gt;2018/10/12 - [개인 프로젝트/지식 그래프(Knowledge Graph) 만들기] - 지식 그래프(Knowledge Graph) 만들기-1 지식 그래프란? 시멘틱 그래프란?&lt;/u&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;시맨틱 그래프는 개념들간의 관계를 나타내는 그래프이기 때문에 RDF를 사용하면&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt; 지식 그래프를 구축할 수 있습니다!!&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;따라서 지식 그래프를 구축하기 위해선 RDF 데이터들이 필요합니다.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 18pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 700; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;마무리 지으며..&lt;/span&gt;&lt;/p&gt;&lt;hr&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot; id=&quot;docs-internal-guid-39be44be-7fff-6d3c-081a-4408c5410162&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;제 프로젝트는 K리그의 지식 그래프를 구축하는 것이 목표이기 때문에 K리그의 정보들을 RDF로 바꿀 수 있다면 지식 그래프를 구축할 수 있습니다. &lt;/span&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;br class=&quot;kix-line-break&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;RDF에 대한 개념과 용어 설명은 다음 링크에서 한글로 굉장히 자세히 설명되어 있기 때문에 포스트에 설명하기 보단 링크를 보고 참고하면 될 것 같습니다. (실력이 미천하여 설명을 잘 못하겠..)&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;참조:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;background-color: transparent; font-variant-numeric: normal; font-variant-east-asian: normal; vertical-align: baseline; font-size: 14.6667px; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;RDF 개념 및 구문 소개: &lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.slideshare.net/barambi/rdf&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Arial; color: rgb(140, 140, 140); background-color: transparent; font-variant-numeric: normal; font-variant-east-asian: normal; text-decoration-skip-ink: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;u&gt;https://www.slideshare.net/barambi/rdf&lt;/u&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span id=&quot;docs-internal-guid-d74eb007-7fff-33ec-5f4e-355a14e0397e&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration-skip-ink: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;RDF(Resource De&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;scription Framework) 1.1&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration-skip-ink: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;: &lt;/span&gt;&lt;a href=&quot;http://bitnine.tistory.com/entry/RDF-Resource-Description-Framework-11&quot; style=&quot;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;&lt;u&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;http://bitnine.tistory.com/entry/RDF-Resource-Description-Framework-11&lt;/span&gt;&lt;/u&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;다음 포스트는 텍스트로 된 K리그의 기사를 RDF로 변환하는 방법을 포스팅할까 생각 중입니다. ㅎㅎ&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;참고 문헌&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot; id=&quot;docs-internal-guid-428f6db1-7fff-5676-0c7f-6bb4958f2d02&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;a href=&quot;http://www.tta.or.kr/data/androReport/ttaJnal/9-2_%5B5%5D.pdf&quot; style=&quot;text-decoration:none;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Arial; color: rgb(140, 140, 140); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;http://www.tta.or.kr/data/androReport/ttaJnal/9-2_%5B5%5D.pdf&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;a href=&quot;https://www.slideshare.net/barambi/rdf&quot; style=&quot;text-decoration:none;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Arial; color: rgb(140, 140, 140); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;https://www.slideshare.net/barambi/rdf&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;a href=&quot;http://bitnine.tistory.com/entry/RDF-Resource-Description-Framework-11&quot; style=&quot;text-decoration:none;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: Arial; color: rgb(140, 140, 140); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;http://bitnine.tistory.com/entry/RDF-Resource-Description-Framework-11&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;text-decoration: underline; font-size: 11pt; font-family: Arial; color: rgb(17, 85, 204); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration-skip-ink: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;a href=&quot;https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple&quot; style=&quot;text-decoration:none;&quot;&gt;&lt;span style=&quot;color: rgb(140, 140, 140); font-size: 12pt;&quot;&gt;https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>개인 프로젝트/지식 그래프(Knowledge Graph) 만들기</category>
      <category>Knowledge Graph</category>
      <category>RDF</category>
      <category>Semantic web</category>
      <category>시맨틱 웹</category>
      <category>지식 그래프</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/36</guid>
      <comments>https://psyhm.tistory.com/36#entry36comment</comments>
      <pubDate>Sat, 13 Oct 2018 14:06:44 +0900</pubDate>
    </item>
    <item>
      <title>지식 그래프(Knowledge Graph) 만들기-1 지식 그래프란? 시멘틱 그래프란?</title>
      <link>https://psyhm.tistory.com/35</link>
      <description>&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;font face=&quot;Arial&quot;&gt;&lt;span style=&quot;font-size: 18pt; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Batang, 바탕;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 18pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;들어가기에 앞서&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;hr&gt;&lt;/div&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;이 포스트는 학교 프로젝트로 지식 그래프를 구축해보고 그에 대한 서비스 구현까지 완료해보기 위해 그에 대한 자료를 정리하는 글입니다. 이에 관해 공부해보는 사람들에게 도움이 되었으면 해서 글을 공유하고자 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot; id=&quot;docs-internal-guid-10174672-7fff-0f33-6a1c-ee5f1141405f&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;이러한 서비스를 구축하기 위해선 먼저 용어 정리가 필요할 것 같습니다. 따라서 이번 프로젝트에서 가장 중요한 용어 &lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;지식 그래프(Knowledge Graph. 줄여서 KG)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;를 알아보고자 합니다. &lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 18pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;지식 그래프란??&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;hr&gt;&lt;/div&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;먼저 &lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;위키피디아&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;에선 지식 그래프를 다음과 같이 설명합니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;font-size: 14pt; font-family: Batang, 바탕;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 14pt; font-family: Batang, 바탕;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;지식 그래프&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;는 다양한 소스로부터 축적한 시맨틱 검색 정보를 사용하여 검색 결과를 향상시키는 것으로 구글이 사용하는 지식 베이스이다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;시맨틱 정보&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;란&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;자원과&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt; 자원 사이의 관계를 어떠한 정보로 표현한 것&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;입니다. 간단하게 A와 B라는 관계를 표현한 정보라고 볼 수 있습니다. 간단한 예시를 들어볼까요??&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;고양이는 털을 가지고 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-family: Batang, 바탕; font-size: 14.6667px; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;이 문장에서 고양이(A)와 털(B)의 관계는 ‘&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;가지다&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;'라는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;관계&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;로&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt; 표현할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;이러한 시맨틱 정보들을 모아 그래프 형태로서 데이터를 저장하고, 그 정보들이 쌓이고 쌓인게 지식 그래프입니다. 하나의 정보를 검색하게 되면 그에 관련된 여러가지 정보들을 찾을 수 있게 된 것입니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;사실 지식 그래프는 &lt;/span&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;시맨틱 그래프&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;입니다. 시맨틱 그래프는 “개념들 사이의 의미적 그래프를 나타내는 그래프”입니다. 지식 그래프는 구글이 만든 시맨틱 그래프인 것이죠. 그러나 구글의 힘(?) 때문에 보편적으로 지식 그래프라는 용어로 사용됩니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; background-color: transparent; font-variant-numeric: normal; font-variant-east-asian: normal; vertical-align: baseline; white-space: pre-wrap; color: rgb(0, 0, 0);&quot;&gt;일단 구글이 어떻게 지식 그래프를 활용하고 있는지 보겠습니다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; background-color: transparent; font-variant-numeric: normal; font-variant-east-asian: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99B24C385BC01A6828&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99B24C385BC01A6828&quot; width=&quot;820&quot; height=&quot;451&quot; alt=&quot;지식 그래프를 구글에 검색했을 때 화면&quot; filename=&quot;pasted image 0.png&quot; filemime=&quot;image/png&quot; original=&quot;yes&quot;/&gt;&lt;span class=&quot;cap1&quot; style=&quot;display: block; max-width:100%; &quot;&gt;지식 그래프를 구글에 검색했을 때 화면&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5; text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; background-color: transparent; font-variant-numeric: normal; font-variant-east-asian: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;지식 그래프를 검색했을 때의 캡쳐 사진입니다. 사진 오른쪽에 사용자가 구글에 질문한 내용을 분석하여 구글이 다양한 정보를 모아 만든 지식 그래프를 활용해 정보를 요약해서 알려주게 됩니다. &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;br class=&quot;kix-line-break&quot;&gt;&lt;br class=&quot;kix-line-break&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; background-color: transparent; font-variant-numeric: normal; font-variant-east-asian: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span id=&quot;docs-internal-guid-163e0ba8-7fff-a678-b9d5-e13f21206e44&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;단순한 검색 이외에도 복잡한 형식의 질문에도 답변이 가능합니다. 2018년 아시안 게임에서 크게 활약했던 황의조 선수의 나이를 검색해봅시다. &lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99710B395BC01AF902&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99710B395BC01AF902&quot; width=&quot;820&quot; height=&quot;634&quot; alt=&quot;황의조 나이를 구글에 검색했을 때 화면&quot; filename=&quot;pasted image 0 (1).png&quot; filemime=&quot;image/png&quot; original=&quot;yes&quot;/&gt;&lt;span class=&quot;cap1&quot; style=&quot;display: block; max-width:100%; &quot;&gt;황의조 나이를 구글에 검색했을 때 화면&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;나이에 대한 정보가 간략하게 사진 중간에 표시되는 것을 확인할 수 있습니다. 뿐만 아니라 사람들이 황의조 선수 나이에 관해 비슷한 유형의 응답도 표시해주는 것을 볼 수 있습니다. 사진 오른쪽에는 황의조에 대한 간략한 요약 정보가 표시되는 것을 확인할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot; id=&quot;docs-internal-guid-36310768-7fff-37bf-c46a-3f8ee71de00e&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;지식 그래프 이전의 구글은 검색에 대한 단순한 정보나 링크를 제공해줬다면 현재의 구글은 지식 그래프를 활용하게 됨으로써 검색에 대한 답을 제공해줄 수 있게 됐습니다. 위와 같이 황의조 선수의 나이를 바로 알 수 있도록 말이죠.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;그렇다면 이러한 지식 그래프(시맨틱 네트워크)는 어떤 식으로 구축할 수 있을까요??&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;RDF를 사용하여 구축할 수 있습니다. RDF에 대한 내용도 만만치 않게 많으므로 다음 포스트에 정리하도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;마치며..&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;hr&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.5; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.8; margin-top: 0pt; margin-bottom: 0pt;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;제 프로젝트에서는 K리그에 대한 시맨틱 정보를 지식 그래프로 구축하여 K리그 정보 검색 엔진을 만들어 볼 예정입니다. 혹시라도 틀린 부분이 있었다면 태클 감사히 받겠습니다~&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 11pt; font-family: Batang, 바탕; background-color: transparent; font-variant-numeric: normal; font-variant-east-asian: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>개인 프로젝트/지식 그래프(Knowledge Graph) 만들기</category>
      <category>kg</category>
      <category>Knowledge Graph</category>
      <category>k리그</category>
      <category>구글</category>
      <category>시맨틱 그래프</category>
      <category>지식 그래프</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/35</guid>
      <comments>https://psyhm.tistory.com/35#entry35comment</comments>
      <pubDate>Fri, 12 Oct 2018 12:47:47 +0900</pubDate>
    </item>
    <item>
      <title>Node.js에서 async await를 사용해야 하는 이유</title>
      <link>https://psyhm.tistory.com/34</link>
      <description>&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;background-color: transparent; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; white-space: pre-wrap; color: rgb(0, 0, 0);&quot;&gt;자바스크립트로 소스 코드를 작성하다보면 다음과 같은 일에 직면하게 된다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-js line-numbers&quot;&gt;&lt;span&gt;function foo(callback1) {
	callback1(function (callback2) {
		callback2(function(callback3) {
			callback3( … );	// 계속해서 탭이 늘어난다.
		});
	});
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;background-color: transparent; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span id=&quot;docs-internal-guid-82a3e1cf-7fff-8ea3-17ba-e18035941359&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;맞다. 바로 ‘&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;콜백헬&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;’이라고 불리우는 일이 발생한다. &lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;콜백헬이 발생하면 여러가지 단점이 생긴다. 그 중 제일 좋지 않은 단점은 극악의 가독성이다. 단순히 위의 코드만 보아도 남들이 읽기 힘들어 보인다. &lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;이런 경우를 방지하기 위해 여태&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt; promise 패턴&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;을 적용했었다. 하지만 promise 패턴도 단순히 콜백을 호출하는 것보다는 가독성이 좋아지지만 마찬가지로 그닥 좋지 않은 가독성을 보여준다. &lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 16px; white-space: pre-wrap; color: rgb(0, 0, 0);&quot;&gt;먼저 promise 함수의 예제를 작성해보자.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-js line-numbers&quot;&gt;&lt;span&gt;function fooPromise(data) {
	return new Promise((resolve, reject) =&amp;gt; {
		setTimeout(() =&amp;gt; {
			console.log(&quot;fooPromise&quot;);
			if(data === 1000)
				reject(new Error(&quot;my error&quot;));
			else
				resolve(data);
		}, data);
	})
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;그리고 fooPromise를 연속해서 사용해보자.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-js line-numbers&quot;&gt;&lt;span&gt;fooPromise(3000)
	.then(function (result1) {
		~~~
		return fooPromise(result1);
	})
	.then(function (result2) {
		~~~
		return fooPromise(result2);
	})
	.then(...)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;background-color: transparent; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; white-space: pre-wrap; color: rgb(0, 0, 0);&quot;&gt;맨 처음의 코드보단 훨씬 깔끔해졌다. 탭도 처음보다는 줄어들었고 정렬된 모습이다. 하지만 그래도 일반적인 탑다운 형식보다는 읽기 힘든 모습이다. &lt;/span&gt;&lt;/p&gt;&lt;span id=&quot;docs-internal-guid-a31183b5-7fff-ebc1-764d-93f7a254e540&quot;&gt;&lt;br /&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; background-color: transparent; font-variant-numeric: normal; font-variant-east-asian: normal; vertical-align: baseline; white-space: pre-wrap; color: rgb(0, 0, 0);&quot;&gt;promise는 비동기를 유지하며 좋은 가독성을 유지한다. &amp;nbsp;하지만 그보다 좋은 문법이 있다. &lt;b&gt;node.js 8 LTS 버전&lt;/b&gt;에서 정식 지원하는 문법인데, 바로 &lt;b&gt;async&lt;/b&gt;와 &lt;b&gt;await&lt;/b&gt;이다. &lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; background-color: transparent; font-variant-numeric: normal; font-variant-east-asian: normal; vertical-align: baseline; white-space: pre-wrap; color: rgb(0, 0, 0);&quot;&gt;async와 await의 최고의 장점은 node.js의 장점인 &lt;b&gt;비동기를 유지&lt;/b&gt;하면서 &lt;b&gt;동기적인 모습의 코드 스타일&lt;/b&gt;을 적용할 수 있다는 점이다. 따라서 코드를 읽을 때 런타임 시 내부적으로 비동기적으로 동작하지만 코드를 읽을 땐 위에서부터 아래로 쭉 읽으면 된다.&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; background-color: transparent; font-variant-numeric: normal; font-variant-east-asian: normal; vertical-align: baseline; white-space: pre-wrap; color: rgb(0, 0, 0);&quot;&gt;먼저 async await의 사용법을 살펴보자. &lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; background-color: transparent; font-variant-numeric: normal; font-variant-east-asian: normal; vertical-align: baseline; white-space: pre-wrap; color: rgb(0, 0, 0);&quot;&gt;사용법은 function 앞에 async 키워드를 붙여준 뒤 그 함수 안에서 promise 함수 앞에 await를 붙여 비동기를 유지한다. 그리고 async를 붙인 function은 내부적으로 promise를 반환하게 된다는 점을 알아두자. 먼저 코드를 보자.&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;span style=&quot;font-size: 11pt; font-family: Arial; background-color: transparent; font-variant-numeric: normal; font-variant-east-asian: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-js line-numbers&quot;&gt;
&lt;span&gt;async function foo(data) {				// function foo 앞에 async 키워드를 붙여준다.
	let result1 = await fooPromise(data);	// 프로미스 함수 앞에 await을 붙여준다. 코드가 간결해졌다.
	let result2 = await fooPromise(result1);
	let result3 = await fooPromise(result2);
...
}

foo(3000)				// function foo 가 내부적으로 promise를 반환하는 것을 볼 수 있다. 
	.then(() =&amp;gt; {
		console.log(“foo finish”);
	})
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;위의 promise 패턴보다 훨씬 매우 깔끔한 것을 볼 수 있다. &lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;promise의 연쇄 형태도 단순히 저렇게 변수의 초기화 형태로 깔끔한 표현이 가능할 뿐만 아니라 promise와 마찬가지로 비동기로 작동한다. async/await를 안 쓸 이유가 없다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b style=&quot;font-weight:normal;&quot; id=&quot;docs-internal-guid-b3930838-7fff-e804-b520-9d7e86481bc9&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;뿐만 아니라 async/await는 기존 자바스크립트의 기존 오류 처리인 &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b&gt;try/catch 문&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;에서도 잘 작동한다는 것이다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;먼저 promise를 오류 처리 하기 위해선 다음과 같이 코드를 작성해야 한다.&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;span style=&quot;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-js line-numbers&quot;&gt;&lt;span&gt;try {

	fooPromise(data)	// 첫 번째
		.then(function (result1) {
			~~~
			return fooPromise(result1);	// 두 번째
		})
		.then(function (result2) {
			~~~
			return fooPromise(result2);	// 세 번쨰
		})
		.catch(function(err) {	// 두 번째 fooPromise, 세 번째 fooPromise에서도 발생할 수 있기 때문에 trace 하기 어렵다.
			console.log(err);
			//throw err;	=&amp;gt; 에러를 throw 하지 못한다.
		})
} catch(err) {
	console.log(err);
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;docs-internal-guid-74bc590c-7fff-2fb2-ea92-ca1a984fd7cd&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;다음 코드에서는 프로미스 안에서 에러를 &amp;nbsp;throw를 사용할 순 없고 오로지 catch를 통해서만 에러 핸들링을 할 수 있다. &lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;promise의 catch 안의 throw는 callback function 안에 있기 때문에 throw를 했을 때 바깥의 try/catch문에 도달하지 못한다. 하지만 async/await는 다르다.&lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-js line-numbers&quot;&gt;&lt;span&gt;async function foo() {
	try {
		var result1 = await fooPromise(3000);
		var result2 = await fooPromise(result1);
		var result3 = await fooPromise(1000);	// 세 번째 fooPromise. 에러를 reject한다.
	}
	catch(err) {
		console.log(&quot;result: &quot;, err);			// reject한 new Error를 받아 콘솔창에 출력
	}
}
foo();
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;에러가 발생하는 세 번째 fooPromise는 1000을 받고 new Error를 reject한다. reject한 new Error는 바깥의 catch 문에서 에러를 받아 콘솔 창에 출력할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;b style=&quot;font-weight:normal;&quot; id=&quot;docs-internal-guid-924cb744-7fff-9c52-43a7-4ecff8105dea&quot;&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;이것이 async/await를 사용해야만 하는 중요한 특징 중 하나이다. &lt;/span&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;/p&gt;
&lt;p dir=&quot;ltr&quot; style=&quot;line-height:1.7999999999999998;margin-top:0pt;margin-bottom:0pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;코드를 정말 이쁘게 쓰고 싶고 에러 처리를 원활하고 깔끔하게 하고 싶다면 node 8 LTS부터 사용 가능한 async await를 추천하는 바이다. 아니 이제는 필수라고 하고 싶다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Node.js</category>
      <category>async</category>
      <category>async/await</category>
      <category>await</category>
      <category>node 8 LTS</category>
      <category>node.js</category>
      <category>Promise</category>
      <category>가독성</category>
      <category>노드js</category>
      <category>에러 핸들링</category>
      <category>예제</category>
      <category>오류처리</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/34</guid>
      <comments>https://psyhm.tistory.com/34#entry34comment</comments>
      <pubDate>Sat, 15 Sep 2018 13:37:19 +0900</pubDate>
    </item>
    <item>
      <title>express-session- cookie 외에 다른 방법으로 인증하는 법</title>
      <link>https://psyhm.tistory.com/33</link>
      <description>&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;nodejs에서는 express-session이란 모듈을 통해 사용자 인증을 구현하는 방법이 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이 express-session은 쿠키를 통해 sessionID를 클라이언트에게 전달하고, 클라이언트가 cookie를 통해 서버에 요청시 쿠키의 sessionID를 키 값으로 이용, session store에 있는 세션 객체를 가지고와서 사용자의 중요한 정보를 가지고 온다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;필자가 express-session으로 구현해 놓은 서버(사이드 프로젝트용)에 급하게 sessionID를 쿠키 대신 http header에 전달하게 되었기 때문에 로그인 시에 response.body에 sessionID를 전달해야 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그 방법을 급하게 알아본 결과 그런 방법은 존재하지 않았다...&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;하지만 이에 굴하지 않고 방법을 찾아보았다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;express-session은 express가 클라이언트에게 응답하기 전에 응답 header에 set-cookie를 설정하여 클라이언트의 쿠키를 저장하도록 만든다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이때 session의 id가 암호화되서 저장된다. 암호 키는 물론 session 설정시 secret에 있는 문자열이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그러나 req.session이나 header에 존재하는 set-cookie를 통해 암호화된 sessionID를 가지고 올 수 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;보내기 직전에 sessionID를 암호화를 시키기 때문에 그렇다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;express-session을 직접 뜯어본 결과 sessionID를 암호화하는 코드를 발견했다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;function setcookie(res, name, val, secret, options) {
&amp;nbsp; // sessionID 암호화
&amp;nbsp; var signed = 's:' + signature.sign(val, secret);&amp;nbsp; // signature는 require('cookie-signature');
&amp;nbsp; var data = cookie.serialize(name, signed, options);&amp;nbsp;
&lt;br /&gt;
&amp;nbsp; debug('set-cookie %s', data);
&lt;br /&gt;
&amp;nbsp; var prev = res.getHeader('set-cookie') || [];
&amp;nbsp; var header = Array.isArray(prev) ? prev.concat(data) : [prev, data];
&lt;br /&gt;
&amp;nbsp; res.setHeader('set-cookie', header)&amp;nbsp; &amp;nbsp;// 암호화된 sessionID를 set-cookie 헤더를 통해 클라이언트에게 전달, 클라이언트는 sessionID를 쿠키에 저장한다.
}&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그래서 내 코드에 그냥 sessionID 암호화 하는 부분을 가지고 와서 로그인 시에 response.body에 전달해버렸고 클라이언트가 이 sessionID를 받아서 나중에 요청할 때 토큰 인증 방식처럼 헤더에 전달하도록 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그리고 app.js에 app.use(session({ ... }))을 사용하기 전에 미들웨어를 하나 등록해뒀다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-js line-numbers&quot;&gt;tokenHeaderToCookie.js 파일
module.exports = function (req, res, next) {
    if(req.headers[TOKEN_NAME]) {
        debugger;
        if(!req.cookies) {
            req.cookies = {};
        }
        req.cookies[TOKEN_NAME] = req.headers[TOKEN_NAME];
        next();
     } else {
        next();
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-js line-numbers&quot;&gt;app.js 파일&amp;nbsp;
&lt;br /&gt;
...
app.use(require('./app/helpers/middleware/tokenHeaderToCookie'));
app.use(require('./app/helpers/sessionHandler'););&amp;nbsp; &amp;nbsp; &amp;nbsp; // 세션 설정해둔 모듈
...&amp;nbsp;
&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그렇게 했더니 임시로 구동이 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이렇게 임시로 때웠지만 차라리 jwt를 배워서 하는 게 나을지도 모르겠다.&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Node.js/express</category>
      <category>Cookie</category>
      <category>express</category>
      <category>express-session</category>
      <category>header</category>
      <category>id</category>
      <category>nodejs</category>
      <category>SESSION</category>
      <category>SessionID</category>
      <category>세션</category>
      <category>인증</category>
      <category>쿠키</category>
      <category>헤더</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/33</guid>
      <comments>https://psyhm.tistory.com/33#entry33comment</comments>
      <pubDate>Fri, 31 Aug 2018 19:33:08 +0900</pubDate>
    </item>
    <item>
      <title>개발자의 맥북 구매 후기: 맥북 프로 레티나 15인치 2015년형</title>
      <link>https://psyhm.tistory.com/32</link>
      <description>&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;개발자라면 맥북을 구매해야 한다!!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;맥북 감성!! 맥북 감성!!&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;한성 노트북을 쓰고 윈도우 10 환경에서 개발하던 개발자인 필자가 노트북을 켜자마자 주변에서 곧잘 듣던 소리였다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;당시 맥북에 굉장히 거부감을 느꼈었&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;던 것 중에 하나의 이유였다&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;. 아니 대체 뭐가 그렇게 좋길래 주변에서 맥북 &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;맥북 찬사를 하고 다닐까??&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;오히려 맥북 살 돈으로 끝내주는 게이밍 노트북 하나 사서 풀 세팅 환경에서&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;개발하면 더 좋은 것이 아닌가??&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;그당시 우분투 환경에서 개발도 줄곧 해왔기 때문에 환경 설정에 대해 커맨드 환경에서의 개발은 가히 최고의 장점이었다. 윈도우에서는 프로그램에 필요한 모듈이나 데이터베이스를 다운 받으려면 환경 설정도 해줘야하고 환경 변수도 세팅해야 했기 때문에 골치가 아팠지만 우분투에서는 단지 한 줄의 명령어로 모든 것이 해결되었기 때문이다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none; line-height: 1.8;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 498px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/996CC4355B6E7BF925&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F996CC4355B6E7BF925&quot; width=&quot;498&quot; height=&quot;375&quot; filename=&quot;개비스콘.jpg&quot; filemime=&quot;image/jpeg&quot; original=&quot;yes&quot;/&gt;&lt;span class=&quot;cap1&quot; style=&quot;display: block; max-width:100%; &quot;&gt;윈도우에서 설치 오류가 많던 프로그램을 우분투에서 설치할 때&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;맥OS 또한 그러한 장점을 가지고 있다는 것을 알고 있었지만 요즘 윈도우에서는 ubuntu bash도 지원해주었고 git bash 또한 우분투에서 사용하던 몇몇 명령어들을 사용할 수 있었기 때문에 맥OS의 커맨드 라인은 내게 그리 큰 장점이 되지 못했다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;또한 &quot;맥북은 감성으로 사는 것이다.&quot; 라는 해괴한 말도 들었는데 당시 필자가 볼 땐 어처구니 없는 것들이 감성에 해당했다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;맥 화면에서 창 내림을 눌렀을 때 스르륵 사라지는 것도 감성이고 맥북 커버에 달린 한입 먹은 사과도 감성이었다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;딱히 감성이라고 할&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;것도 없었다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;비싼 가격 뿐만 아니라 이상한 command 키 때문에 한영키 전환도 어려웠고(당시엔 익숙하지 않았기 때문에) 웹 브라우저 개발자 창을 켜기 위해선 fn+f12 키를 눌러야 하는 수고스러운 일을 해야 하는 등 너무 별로였다. 물론 윈도우 개발에 익숙했기 때문에 이 부분은 그렇게 크게 맥북의 단점이라고 느끼진 않는다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;하지만 한성 컴퓨터는 내구성이 매우 약했다...(bossmonster lv.67&amp;nbsp; 모델은 플라스틱 커버). 노트북을 열다가 모니터와 본체 접합 부분이 부러지기도 했고 모니터 화면에는 이상한 자국이 생기는 등 여러 문제점이 계속해서 생기자, 결국에는 노트북을 새로 사자는 마음을 먹게 되었고 회사 입사하기 전에 한번 맥북이 뭔지 경험이라도 해보자는 마음에 비싼 돈 주고 맥북&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-family: &amp;quot;Malgun Gothic&amp;quot;, &amp;quot;맑은 고딕&amp;quot;; font-size: 14pt; letter-spacing: -0.02em;&quot;&gt;MJLQ2KH/A형을 구매하기에 이르렀다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51); font-family: &amp;quot;Malgun Gothic&amp;quot;, &amp;quot;맑은 고딕&amp;quot;; font-size: 14pt; letter-spacing: -0.02em;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; letter-spacing: -0.373333px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;서론이 매우 길었다. &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;결론적으로 개발자로써&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;맥북에 대한 내 경험을 이야기하자면&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; letter-spacing: -0.373333px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(0, 0, 0);&quot;&gt;장점:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0);&quot;&gt;1. 커맨드 환경 개발(iterm, terminal)&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;커맨드 환경에서의 개발은 위에서 설명했듯이 단순한 명령어 하나만으로 모든 것이 해결되는 장점이 있다.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0);&quot;&gt;2. 트랙패드의 미친듯한 편안함&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; 맥북의 트랙패드는 정말이지 최고다. 개발할 때 너무 편안하다. 여러개의 손가락을 입력받을 수 있기 때문에 손가락 수에 따라 다른 기능이&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;동작할 수 있다. 화면을 space 단위로 구분하여 필요한 화면으로 넘기는 맛은 최고다. 듀얼 모니터가 필요 없다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0);&quot;&gt;3. 우분투에서는 동작하지 않는 프로그램 호환성&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; 윈도우 환경에서 동작하던 많은 프로그램은 우분투에서 동작하지 않는다. 동작하기 위해선 굉장히 많은 작업이 필요한데 프로그램 설치할 때마다 그 많은 작업은 매우 곤혹이다&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;(카카오톡 pc나 오피스 프로그램 등등&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;). 하지만 &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;많은 윈도우 프로그램들은 맥OS는 지원한다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0);&quot;&gt;4. 유틸리티 프로그램&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; 윈도우에서보다 많은 유틸리티 프로그램들이 맥북을 이용하기에 편하도록 돕는다. 캡쳐나 pdf를 바로 읽을 수 있는 유틸리티, 캘린더 등등 아직 많은 것을 사용해보진 못했지만 윈도우보단 편한 유틸리티 등이 많은 것 같다.&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(0, 0, 0);&quot;&gt;단점:&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0);&quot;&gt;1. 단축키의 불편함&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; letter-spacing: -0.373333px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; 윈도우에서 개발하던 입장에서 맥OS의 단축키는 너무 불편하다. command 키의 위치 덕분에 &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;복사 붙여넣기를 하는 도중 손가락이 꼬이기 일상이고 단어를 뛰어넘는 키(윈도우에선 ctrl + -&amp;gt; or &amp;lt;-&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;)는 따로 설정을 해줘야 하는 등 여간 복잡하고 어렵다. 내가 편한대로 설정해주는 것도 여간 귀찮다.&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0);&quot;&gt;2. 비싸다.&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; 맥북은 대체 뭘로 만드는 지 모든 게 다 비싸다. 정말 최대 단점이라고 생각한다.&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0);&quot;&gt;3. 가격 대비 성능이 다른 노트북보다 부족하다.&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; 100만원만 줘도 15인치 성능 좋은 노트북을 구매할 수 있지만 맥북은 택도 없다. 같은 노트북 가격에 cpu 성능도 부족하고 디스크 &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;용량도 부족하고 그래픽 카드도 내장밖에 없다.&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;X아&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;치 같은..&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot; face=&quot;Malgun Gothic, 맑은 고딕&quot;&gt;&lt;span style=&quot;font-size: 18pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14pt; letter-spacing: -0.373333px; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; color: rgb(0, 0, 0);&quot;&gt;뭐 이렇게 장황하게 써도 단순하게 맥북의 장점을 이야기하자면 맥OS 말곤 없는 것 같다.&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;font color=&quot;#333333&quot;&gt;&lt;span style=&quot;font-size: 18.6667px; letter-spacing: -0.373333px; color: rgb(0, 0, 0);&quot;&gt;그러나 단점을 커버할 만큼 맥OS의 장점은 대단한 것이라고 생각한다.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;</description>
      <category>잡다한 것들/일기</category>
      <category>15인치</category>
      <category>MAC</category>
      <category>MAC OS</category>
      <category>구매 후기</category>
      <category>레티나</category>
      <category>맥OS</category>
      <category>맥북</category>
      <category>맥북 프로</category>
      <category>일기</category>
      <category>후기</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/32</guid>
      <comments>https://psyhm.tistory.com/32#entry32comment</comments>
      <pubDate>Sat, 11 Aug 2018 15:45:21 +0900</pubDate>
    </item>
    <item>
      <title>chalk: 로그에 색을 입혀보자. (pm2에서의 색 나오지 않는 오류)</title>
      <link>https://psyhm.tistory.com/31</link>
      <description>&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;필자는 여태 Node를 구동하면서 console.log를 이용해 로그를 남기며 디버깅을 진행하였다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;좋은 방식은 아니지만 대충 확인만 하는 것들은 그런 방식으로 로그 데이터를 쌓았다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;하지만 Express를 사용하며 웹서버를 만들면서 로그를 체계적으로 쌓기 시작하면서 문제가 하나 발생했다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;로그를 남길 때 모두 하얀색 이었기 때문에 눈이 매우 아팠던 것이다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;따라서 터미널 창에 색깔을 입힐 수 있는 로그 모듈을 찾았는데 chalk 모듈이다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 616px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/994EAD3D5B6907E312&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F994EAD3D5B6907E312&quot; width=&quot;616&quot; height=&quot;48&quot; alt=&quot;색이 들어간 로그&quot; filename=&quot;Screen Shot 2018-08-07 at 11.44.06 AM.png&quot; filemime=&quot;image/png&quot; original=&quot;yes&quot;/&gt;&lt;span class=&quot;cap1&quot; style=&quot;display: block; max-width:100%; &quot;&gt;색이 들어간 것을 확인할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자세한 내용은 다음 docs에서 살펴보세요. &lt;/span&gt;&lt;a href=&quot;https://www.npmjs.com/package/chalk&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;npm사이트&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;하지만 필자의 경우 webstorm 콘솔 창에서는 색이 변했지만 pm2로 동작시킨 로그 내용을 tail로 추적했을 땐 색이 변하지 않았다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;해결법은 다음과 같았다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;1. node &amp;lt;js파일&amp;gt; --color =&amp;gt; --color 옵션을 추가하면 된다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2. pm2 start ecosystem.json&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;=&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&quot;args&quot;: [ &quot;--color&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&quot;] 추가&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그렇게 하면 잘 출력되는 것을 볼 수 있었다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Node.js</category>
      <category>chalk</category>
      <category>express</category>
      <category>log</category>
      <category>node</category>
      <category>pm2</category>
      <category>로그</category>
      <category>색</category>
      <category>색깔</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/31</guid>
      <comments>https://psyhm.tistory.com/31#entry31comment</comments>
      <pubDate>Tue, 7 Aug 2018 12:03:06 +0900</pubDate>
    </item>
    <item>
      <title>[mongoose] Query 옵션: new</title>
      <link>https://psyhm.tistory.com/30</link>
      <description>&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;다음과 같이 find종류인 findOneAndUpdate, findByIdAndUpdate&amp;nbsp;쿼리를 이용하여 컬렉션에 존재하는 스키마의 데이터를 업데이트 하는 일이 주어졌다고 하자.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;다음은 스키마 정의 부분이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;const userSchema = new mongoClient.Schema({
    name: {
        type: String,
        required: true,
        unique: true
    },
    category: {
        team: Number,
        categoryType: String
    },
    gender: {
        type: String,
        enum: [&quot;male&quot;, &quot;female&quot;],
        required: true
    },
    createOn: Date
});

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;다음은 name이 kkki인 원래의 document이다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;{ category: { categoryType: 'fast' },
  _id: 0,
  name: 'kkki',
  gender: 'male',
  createOn: 2018-07-30T07:14:37.404Z,
  __v: 0 }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;다음은 findOneAndUpdate 구문이다.&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;userSchema.findOneAndUpdate({name: &quot;kkki&quot;},
        {category: {categoryType: req.body.updateType}}).exec()
        .then((updateUser)=&amp;gt; {
            console.log(updateUser);
        })&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;위의 쿼리를 실행하면 &lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;바뀌기 전의 document의 정보가 then의 callback 함수를 통해 나온다.&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;userSchema.findOneAndUpdate({name: &quot;kkki&quot;},
        {category: {categoryType: req.body.updateType}}).exec()
        .then((updateUser)=&amp;gt; {
            console.log(updateUser);
        })
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0); font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;만약 Update를 실행한 뒤의 정보를 받고 싶다면 new 옵션을 사용해야 한다.&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0); font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;&lt;span style=&quot;font-size: 12pt; font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;userSchema.findOneAndUpdate({name: &quot;kkki&quot;},
        {category: {categoryType: req.body.updateType}},
        {new: true}).exec()
        .then((updateUser)=&amp;gt; {
            console.log(updateUser);
            res.send('ok');
        })
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0); font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;
&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0); font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;
&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Node.js/mongoose</category>
      <category>mongoose</category>
      <category>NEW</category>
      <category>node.js</category>
      <category>option</category>
      <category>Query</category>
      <category>노드</category>
      <category>옵션</category>
      <category>쿼리</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/30</guid>
      <comments>https://psyhm.tistory.com/30#entry30comment</comments>
      <pubDate>Mon, 30 Jul 2018 17:05:50 +0900</pubDate>
    </item>
    <item>
      <title>java의 정석 14강. 입출력 I/O (상)</title>
      <link>https://psyhm.tistory.com/29</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1. 자바에서의 입출력&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.1 입출력이란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;입출력이란 컴퓨터 내부 또는 외부의 장치와 프로그램간의 데이터를 주고받는 것을 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.2 스트림&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;스트림&lt;/b&gt;이란 일종의 &lt;b&gt;추상적인 개념&lt;/b&gt;인데 &lt;b&gt;입출력 기기나 프로세스, 파일 등 데이터가 어디로 가는 지, 어디로 나왔는 지 상관없이 통일된 방식으로 데이터를 다루기 위한 가상의 개념이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Node.js의 stream을 알고 싶다면 다음의 링크를 타고가면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;a href=&quot;http://psyhm.tistory.com/26&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;http://psyhm.tistory.com/26&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;스트림은 먼저 보낸 데이터를 먼저 받게 되어 있으며 중간어 건너뜀 없이 연속적으로 데이터를 주고받는다. &lt;b&gt;큐와 같은 FIFO 구조로 되어 있다고 생각하면 이해하기 편할 것&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1.3 바이트기반 스트림 - InputStream, OutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;스트림은 바이트단위로 데이터를 전송하며 입출력 대상에 따라 다음과 같은 입출력스트림이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;table class=&quot;txc-table&quot; width=&quot;784&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; style=&quot;border:none;border-collapse:collapse;;font-family:&quot; 맑은=&quot;&quot; 고딕&quot;,=&quot;&quot; sans-serif;font-size:13px&quot;=&quot;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;width: 261px; height: 24px; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;입력 스트림&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 261px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-top: 1px solid rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력 스트림&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 261px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-top: 1px solid rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;압출력 대상의 종류&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:261;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;File&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;InputStream&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:261;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;File&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;OutputStream&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:261;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; 파일&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:261;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;ByteArray&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;InputStream&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:261;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;ByteArray&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;OutputStream&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:261;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; 메모리(byte 배열)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:261;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Piped&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;InputStream&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:261;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Piped&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;OutputStream&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:261;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; 프로세스(프로세스간 통신)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:261;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Audio&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;InputStream&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:261;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Audio&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;OutputStream&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:261;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; 오디오장치&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;어떤 작업을 할 것인지에 따라 나뉘므로 적절한 상황에 맞게 사용하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이들 모두 &lt;b&gt;InputStream, OutputStream의 자손들&lt;/b&gt;이며, 각각 읽고 쓰는데 필요한 &lt;b&gt;추상메서드를 자신에 맞게 구현해 놓았다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;stream은 입출력을 처리할 수있는 표준화된 방법을 제공함으로써 입출력의 대상이 달라져도 동일한 방법으로 입출력이 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;table class=&quot;txc-table&quot; width=&quot;784&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; style=&quot;border:none;border-collapse:collapse;;font-family:&quot; 맑은=&quot;&quot; 고딕&quot;,=&quot;&quot; sans-serif;font-size:13px&quot;=&quot;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;width: 392px; height: 24px; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;InputStream&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 392px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-top: 1px solid rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;OutputStream&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:392;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;abstract int read()&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:392;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;abstract void write(int b)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:392;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;int read(byte[] b)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:392;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;void write(byte[] b)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:392;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;int read(byte[] b, int off, int len)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:392;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;void write(byte[] b, int off, int len)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;위의 표는 InputStream과 OutputStream에 정의된 &lt;b&gt;읽기와 쓰기를 수행하는 메서드&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.4 보조스트림&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;위의 표1의 스트림의 기능을 보완하기 위한 보조스트림이 제공된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;보조스트림은 실제 데이터를 주고받는 스트림이 아니기 때문에 데이터를 입출력할 수 있는 기능은 없지만, 스트림 기능을 향상시키거나 새로운 기능을 추가할 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;예를 들어 test.txt라는 파일을 읽기위해 FileInputStream을 사용할 때, 입력 성능을 향상시키기 위해 버퍼를 사용하는 보조스트림인 BufferedInputStream을 사용하는 코드는 다음과 같다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;// 먼저 기반스트림을 생성
FileInputStream fis = new FileInputStream(&quot;test.txt&quot;);
// 기반스트림을 이용해서 보조스트림을 생성한다.
BufferedInputStream bis = new BufferedInputStream(fis);

bis.read(); // 보조스트림인 bis로부터 데이터를 읽는다.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;보조스트림의 종류&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;table class=&quot;txc-table&quot; width=&quot;784&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; style=&quot;border:none;border-collapse:collapse;;font-family:&quot; 맑은=&quot;&quot; 고딕&quot;,=&quot;&quot; sans-serif;font-size:13px&quot;=&quot;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;width: 209px; height: 24px; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;입력&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 237px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-top: 1px solid rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 337px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-top: 1px solid rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;설명&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 209px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;FilterInputStream&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 237px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;FilterOutputStream&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 337px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;필터를 이용한 입출력 처리&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 209px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;BufferedInputStream&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 237px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;BufferedOutputStream&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 337px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;버퍼를 이용한 입출력 성능 향상&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 209px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;DataInputStream&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 237px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;DataOutputSttream&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 337px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;int, float와 같은 기본형 단위로 데이터를 처리하는 기능&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 209px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;SequenceInputStream&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 237px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;SequenceOutputStream&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 337px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;두 개의 스트림을 하나로 연결&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 209px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;LineNumberInputStream&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 237px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;없음&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 337px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;읽어 온 데이터의 라인 번호를 카운트(jdk 1.1부터 LineNumberReader로 대체)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 209px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;ObjectInputStream&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 237px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;ObjectOutputStream&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 337px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;데이터를 객체단위로 읽고 쓰는데 사용. 주로 파일을 이용하며 객체 직렬화와 관련 있음&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 209px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;없음&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 237px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;PrintStream&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 337px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;버퍼를 이용하며, 추가적인 print 관련 기능&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 209px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;PushbackInputStream&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 237px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;없음&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 337px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;버퍼를 이용해서 읽어 온 데이터를 다시 되돌리는 기능&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.5 문자기반 스트림 - Reader, Writer&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;지금까지 알아본 스트림은 모두 바이트기반의 스트림이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;자바에서는 문자를 의미하는 char형이 2 byte이기 때문에 바이트기반의 스트림으로 2 byte문자를 처리하는 데는 어려움이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이 점을 보완하기 위해서 &lt;b&gt;문자기반의 스트림이 제공&lt;/b&gt;된다. 문자데이터를 입출력할 때는 문자기반 스트림을 사용하자&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;InputStream -&amp;gt; Reader&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;OutputStream -&amp;gt; Writer&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;바이트기반과 문자기반 스트림은 이름만 조금 다를 뿐 활용방법은 거의 같다.&lt;/span&gt;&lt;/div&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2. 바이트기반 스트림&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2.1 InputStream과 OutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;InputStream 메서드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;table class=&quot;txc-table&quot; width=&quot;784&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; style=&quot;border:none;border-collapse:collapse;;font-family:&quot; 맑은=&quot;&quot; 고딕&quot;,=&quot;&quot; sans-serif;font-size:13px&quot;=&quot;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;메서드 명&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-top: 1px solid rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;설 명&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;int available()&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;스트림으로부터 읽어 올 수 있는 데이터의 크기를 반환한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 23px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;void close()&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 23px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;스트림을 닫음으로써 사용하고 있던 자원을 반환한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 33px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;void mark(int readlimit)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 33px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;현재 위치를 표시해 놓는다. 후에 reset()에 의해서 표시해 놓은 위치로 다시 돌아갈 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;readlimit: 되돌아갈 수 있는 byte의 수&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;boolean markSupported()&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;mark()와 reset()을 지원하는 지를 알려 준다.&amp;nbsp;이 메서드로 먼저 확인을 해야한다.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;abstract int read()&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;1 byte를 읽어온다. 더 이상 읽을 데이터가 없다면 -1을 반환한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;int read(byte[] b)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;배열 b의 크기만큼 읽어서 배열을 채우고 읽어 온 데이터의 수를 반환한다.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;int read(byte[] b, int off, int len)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;최대 len 개의 byte를 읽어서 배열 b의 위치off부터 저장한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;void reset()&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;스트림에서 위치를 마지막으로 mark()이 호출되었던 위치로 되돌린다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;long skip(long n)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;스트림에서 주어진 길이n만큼 건너뛴다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;OutputStream 메서드&lt;/span&gt;&lt;/p&gt;&lt;table class=&quot;txc-table&quot; width=&quot;784&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; style=&quot;border:none;border-collapse:collapse;;font-family:&quot; 맑은=&quot;&quot; 고딕&quot;,=&quot;&quot; sans-serif;font-size:13px&quot;=&quot;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;메서드 명&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-top: 1px solid rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;설 명&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;void close()&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;입력소스를 닫음으로써 사용하고 있던 자원을 반환한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;void flush()&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;스트림의 버퍼에 있는 모든 내용을 출력소스에 쓴다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;abstract void write(int b)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;주어진 값을 출력소스에 쓴다.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;void write(byte[] b)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;주어진 배열 b에 저장된 모든 내용을 출력소스에 쓴다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 178px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;void write(byte[] b, int off, int len)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 605px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;주어진 배열 b에 저장된 내용 중에서 off번째 부터 len개 만큼만을 읽어서 출력소스에 쓴다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2.2 ByteArrayInputStream과 ByteArrayOutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;두 스트림은 &lt;b&gt;메모리, 즉 바이트배열에 데이터를 입출력하는데 사용되는 스트림&lt;/b&gt;이다. 주로 다른 곳에 입출력하기전에 데이터를 임시로 바이트배열에 담아서 변환 등의 작업을 하는데 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;자주 사용하지는 않지만 스트림의 종류가 달라도 읽고 쓰는 방법은 동일하므로 예제를 통해서 스트림에 읽고 쓰는 방법을 잘 익혀두기 바란다.&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        byte[] inSrc = {0,1,2,3,4,5,6,7,8,9};
        byte[] outSrc = null;

        ByteArrayInputStream input = null;
        ByteArrayOutputStream output = null;

        input = new ByteArrayInputStream(inSrc);
        output = new ByteArrayOutputStream();

        int data = 0;

        while((data = input.read()) != -1) {
            output.write(data);
        }

        outSrc = output.toByteArray();

        System.out.println(&quot;Input Source: &quot; + Arrays.toString(inSrc));
        System.out.println(&quot;output Source: &quot; + Arrays.toString(outSrc));
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력 결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Input Source: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Input Source: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;ByteArrayInputStream ByteArrayOutputStream을 이용해서 바이트배열 inSrc의 데이터를 outSrc로 복사하는 예제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;하지만 이 코드는 while문 한번에 1 byte만 읽고 쓰므로 작업효율이 떨어진다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        byte[] inSrc = {0,1,2,3,4,5,6,7,8,9};
        byte[] outSrc = null;

        ByteArrayInputStream input = null;
        ByteArrayOutputStream output = null;

        input = new ByteArrayInputStream(inSrc);
        output = new ByteArrayOutputStream();

        int data = 0;

        while((data = input.read()) != -1) {
            output.write(data);
        }

        outSrc = output.toByteArray();

        System.out.println(&quot;Input Source: &quot; + Arrays.toString(inSrc));
        System.out.println(&quot;output Source: &quot; + Arrays.toString(outSrc));
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력 결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Input Source: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;temp Source: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;output Source: [5, 6, 7, 8, 9]&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;int read(byte[] b, int off, int len)와 void write(byte[] b, int off, int len)을 이용해서 입출력하는 방법을 보여주는 예이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이전 예제와는 달리 byte배열을 이용해서 한 번에 배열의 크기만큼 읽고 쓸 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;만약 스트림의 크기를 정확히 모를 때는 일정한 크기의 바이트를 계속해서 받아서 써야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        byte[] inSrc = {0,1,2,3,4,5,6,7,8,9};
        byte[] outSrc = null;

        byte[] temp = new byte[10];

        ByteArrayInputStream input = null;
        ByteArrayOutputStream output = null;

        input = new ByteArrayInputStream(inSrc);
        output = new ByteArrayOutputStream();

        input.read(temp, 0, temp.length);       // 읽어 온 데이터를 temp에 담는다.
        output.write(temp, 5, 5);           // temp[5]부터 5개의 데이터를 write한다.

        outSrc = output.toByteArray();

        System.out.println(&quot;Input Source: &quot; + Arrays.toString(inSrc));
        System.out.println(&quot;temp Source: &quot; + Arrays.toString(temp));
        System.out.println(&quot;output Source: &quot; + Arrays.toString(outSrc));

    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력 결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Input Source: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;temp Source: [8, 9, 6, 7]&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;output Source: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2.3 FileInputStream과 FileOutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;위의 두 스트림은 파일에 입출력을 하기 위한 스트림이다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        try {
            FileInputStream fis = new FileInputStream(args[0]);
            FileOutputStream fos = new FileOutputStream(args[1]);

            int data = 0;
            while((data = fis.read()) != -1) {
                fos.write(data);
            }

            fis.close();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;명령어:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;gt; java -classpath &amp;lt;class파일 위치&amp;gt; Main Main.java Main.bak&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이렇게 하면 Main.java 파일의 내용을 Main.bak 파일이 가지게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Java/Java의 정석 읽고 정리</category>
      <category>java</category>
      <category>Stream</category>
      <category>바이트기반 스트림</category>
      <category>보조스트림</category>
      <category>자바</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/29</guid>
      <comments>https://psyhm.tistory.com/29#entry29comment</comments>
      <pubDate>Wed, 13 Jun 2018 16:36:37 +0900</pubDate>
    </item>
    <item>
      <title>java의 정석 9강. java.lang 패키지(하)</title>
      <link>https://psyhm.tistory.com/28</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;3. StringBuffer클래스&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;3.1 StringBuffer클래스의 특징&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;StringBuffer클래스는 지정된 문자열 변경이 가능하다. 내부적으로 문자열 편집을 위한 버퍼(buffer)를 가지고 있으며, StringBuffer인스턴스를 생성할 때 그 크기를 지정할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;버퍼의 크기를 적절하게 정해주지 않으면 만약 문자열의 크기가 버퍼의 크기를 넘어서게 되면 버퍼 크기를 늘려주는 작업을 추가로 해야하기 때문에 작업효율이 떨어진다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;3.2 StringBuffer클래스의 생성자&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public StringBuffer(int length) {
    value = new char[length];
    shared = false;
}

public StringBuffer() {
    this(16);
}

public StringBuffer(String str) {
    this(str.length() + 16);
    append(str);
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;위의 코드를 보면 알 수 있듯이 기본 버퍼의 크기는 16이란 것을 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;3.3 StringBuffer인스턴스의 비교&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;StringBuffer클래스는 equals메서드를 오버라이딩하지 않아서 StringBuffer클래스의 equals메서드를 사용해도 등가비교연산자(==)와 같은 결과를 얻는다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;반면에 toString()은 오버라이딩되어 있어서 인스턴스가 담고있는 문자열을 반환한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그래서 StringBuffer인스턴스에 담긴 문자열을 비교하기 위해서는 StringBuffer인스턴스에 toString()을 호출해서 String인스턴스를 얻은 다음, 여기에 equals메서드를 사용해서 비교해야한다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        StringBuffer sb1 = new StringBuffer(&quot;abc&quot;);
        StringBuffer sb2 = new StringBuffer(&quot;abc&quot;);

        if(sb1 == sb2)
            System.out.println(&quot;sb1 == sb2 ? true&quot;);
        else
            System.out.println(&quot;sb1 == sb2 ? false&quot;);

        if(sb1.equals(sb2))
            System.out.println(&quot;sb1.equals(sb2) ? true&quot;);
        else
            System.out.println(&quot;sb1.equals(sb2) ? false&quot;);

        String s1 = sb1.toString();
        String s2 = sb2.toString();

        if(s1.equals(s2))
            System.out.println(&quot;s1.equals(s2) ? true&quot;);
        else
            System.out.println(&quot;s1.equals(s2) ? false&quot;);
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력 결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;sb1 == sb2 ? false&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;sb1.equals(sb2) ? false&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;s1.equals(s2) ? true&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;3.4 StringBuffer클래스의 생성자와 메서드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;생성자:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- StringBuffer()&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- StringBuffer(int length)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- StringBuffer(String str)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메서드:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- StringBuffer append(anything): 매개변수로 입력된 값을 문자열로 변환하여 인스턴스의 문자열 뒤에 덧붙인다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- int capacity(): StringBuffer인스턴스의 버퍼 크기를 반환한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- char charAt(int index): index위치의 문자를 반환&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- StringBuffer delete(int start, int end): 시작 위치부터 끝 위치 사이에 있는 문자를 제거한다. 단, 끝 위치 문자는 제외&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- StringBuffer deleteCharAt(int index): 지정된 위치의 문자를 제거&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- StringBuffer insert(int pos, anything): 두 번째 매개변수로 받은 값을 문자열로 변환하여 지정된 위치pos에 추가한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- int length(): 인스턴스에 저장된 문자열의 길이를 반환&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- StringBuffer replace(int start, int end, String str): 지정된 범위의 문자들을 주어진 문자열로 바꾼다. end 위치는 포함되지 않음.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- StringBuffer reverse(): 문자열 순서를 거꾸로 바꾼다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- void setCharAt(int index, char ch): 지정된 위치index의 문자를 문자ch로 바꾼다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- void setLength(int newLength): 지정된 크기로 문자열의 길이를 변경한다. 문자열 크기를 더 늘리면 나머지는 공백으로 채워진다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- String substring(int start[, int end]): 지정된 범위 내의 문자열을 String으로 뽑아서 반환한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;4. Math클래스&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;4.1 Math클래스&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Math클래스는 기본적인 수학계산에 유용한 메서드로 구성되어있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;5. wrapper클래스&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;5.1 wrapper클래스&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;기본형(primitive type) 변수도 때로는 객체로 다루어져야하는 경우가 있다. 예를 들면, 매개변수로 객체를 요구할 때, 기본형 값이 아닌 객체로 저장해야할 때, 객체간의 비교가 필요할 때 등등 객체로 변환을 해야하는데 이 때에 사용되는 것이 wrapper클래스이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;int와 char를 제외한 모든 기본형 타입은 wrapper 클래스와 이름이 같다.&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;int -&amp;gt; Integer&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;char -&amp;gt; Character&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        Integer i1 = new Integer(100);
        Integer i2 = new Integer(100);

        System.out.println(&quot;i1==i2 ? &quot; + (i1==i2));
        System.out.println(&quot;i1.equals(i2) ? &quot; + i1.equals(i2));
        System.out.println(&quot;i1.toString() = &quot; + i1.toString());

        System.out.println(&quot;MAX_VALUE = &quot; + Integer.MAX_VALUE);
        System.out.println(&quot;MIN_VALUE = &quot; + Integer.MIN_VALUE);
        System.out.println(&quot;SIZE = &quot; + Integer.SIZE + &quot; bits&quot;);
        System.out.println(&quot;TYPE = &quot; + Integer.TYPE);
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력 결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;i1==i2 ? false&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;i1.equals(i2) ? true&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;i1.toString() = 100&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;MAX_VALUE = 2147483647&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;MIN_VALUE = -2147483648&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;SIZE = 32 bits&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;TYPE = int&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;wrapper클래스들은 모두 equals()가 오버라이딩되어 있어서 주소값이 아닌 객체가 가지고 있는 값을 비교한다. 또한 MAX_VALUE, MIN_VALUE 등등 static 멤버를 공통적으로 가지고 있다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Java/Java의 정석 읽고 정리</category>
      <category>java</category>
      <category>StringBuffer</category>
      <category>wrapper</category>
      <category>자바</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/28</guid>
      <comments>https://psyhm.tistory.com/28#entry28comment</comments>
      <pubDate>Mon, 11 Jun 2018 16:47:08 +0900</pubDate>
    </item>
    <item>
      <title>java의 정석 9강. java.lang 패키지(상)</title>
      <link>https://psyhm.tistory.com/27</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자바에서 j&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;ava.lang&amp;nbsp;패키지는 기본이 되는 패키지&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이기 때문에 import 없이 사용할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그 중 많이 사용되는 것들을 알아보자&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1. Object 클래스&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Object는 모든 클래스의 최고 조상&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이기 때문에 Object 클래스의 모든 멤버들은 모든 클래스에서 모두 사용할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Object 메서드에서 중요한 몇가지를 살펴보자&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.1 equals 메서드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;객체의 참조변수를 받아서 비교&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하여 그 결과를 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;boolean &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;값으로 알려주는 역할을 한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span&gt;public boolean equals(Object obj) {
  return (this == obj);
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;코드를 보면 알 수 있듯이 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;서로 다른 두 객체를 equals 메서드로 비교하면 항상 false&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 반환한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;equals 메서드는 결국 두 개의 참조변수가 같은 객체를 참조하고 있는지, 즉 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;두 참조변수에 저장된 값(주소값)이 같은지를 판단하는 기능&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 밖에 할 수 없다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;물론 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;override&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 하여 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사용자가 정의한 기능&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;대로 바꿀 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;class Person {
    long id;

    public boolean equals(Object obj) {
        if(obj != null &amp;amp;&amp;amp; obj instanceof Person) {
            return id == ((Person)obj).id;
        } else {
            return false;
        }
    }

    Person(long id) {
        this.id = id;
    }
}

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person(8011081111222L);
        Person p2 = new Person(8011081111222L);

        if(p1 == p2) {
            System.out.println(&quot;p1과 p2는 같은 사람입니다.&quot;);
        } else {
            System.out.println(&quot;p1과 p2는 다른 사람입니다.&quot;);
        }

        if(p1.equals(p2)) {
            System.out.println(&quot;p1과 p2는 같은 사람입니다.&quot;);
        } else {
            System.out.println(&quot;p1과 p2는 다른 사람입니다.&quot;);
        }
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력 결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;p1과 p2는 다른 사람입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;p1과 p2는 같은 사람입니다.&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.2 hashCode 메서드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이 메서드는 해싱 기법에 사용되는 해시함수를 구현한 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;hashCode 메서드는 객체의 주소값을 이용해서 해시코드를 만들어 반환하기 때문에 서로 다른 두 객체는 절대 같은 값을 가질 수 없다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;위의 equals와 마찬가지로 사용자가 적절하게 오버라이딩 할 수 있다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        String str1 = new String(&quot;abc&quot;);
        String str2 = new String(&quot;abc&quot;);

        System.out.println(str1.hashCode());        // String은 hashCode 메서드를 같은 문자열이면
        System.out.println(str2.hashCode());        // 출력 결과가 같도록 오버라이딩 했다.
        System.out.println(System.identityHashCode(str1));  // System.identityHashCode는 객체의 주소값으로 해시코드를
        System.out.println(System.identityHashCode(str2));  // 생성하기 때문에 항상 다른 해시코드값을 반환할 것을 보장한다.
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.3 toString 메서드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;toString()은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인스턴스에 대한 정보를 문자열로 제공할 목적으로 정의&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;한 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Object클래스에 정의된 toString()은 다음과 같다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public String toString() {
    return getClass().getName() + &quot;@&quot;
            + Integer.toHexString(hashCode());
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;따로 오버라이딩 하지 않는다면 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스이름&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;16진수의 해시코드&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 얻게될 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.4 clone 메서드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이 메서드는 자신을 복제하여 새로운 인스턴스를 생성하는 일을 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Object클래스에 정의된 clone 메서드는 단순히 멤버변수의 값만 복사하기 때문에 배열이나 인스턴스가 멤버로 정의되어 있는 클래스의 인스턴스는 완전한 복제가 이루어지지 않는다.(얕은 복사)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이런 경우 clone 메서드를 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;오버라이딩해서 새로운 배열을 생성하고 배열의 내용을 복사하도록 해야 한다.(깊은 복사)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;class Point implements Cloneable {
    // Cloneable인터페이스를 구현한 클래스에서만 clone()을 호출할 수 있다. 이 인터페이스를 구현하지 않고
    // clone()을 호출하면 예외가 발생한다.
    int x;
    int y;

    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public String toString() {
        return &quot;x=&quot; + x + &quot;, y=&quot; + y;
    }
    public Object clone() {
        Object obj = null;
        try {
            // clone 메서드에는 CloneNotSupportedException이 선언되어 있으므로 try catch문 안에서 사용해야한다.
            obj = super.clone();
        } catch (CloneNotSupportedException e) {}
        return obj;
    }
}

public class Main {
    public static void main(String[] args) {
        Point original = new Point(3, 5);
        Point copy = (Point)original.clone();

        System.out.println(original);
        System.out.println(copy);
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력 결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;x=3, y=5&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;x=3, y=5&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사실 clone은 아무렇게 오버로딩하는 것이 아니라 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;특정한 조건을 만족시켜야 한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;clone()을 지원하려면 먼저 cloneable 인터페이스를 implements&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 해야하며 Object 클래스에 정의되어 있는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;protected native Object clone() 메서드를 public으로 재정의해서 사용&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;해야 합니다.(재정의하지 않으면 다른 패키지에서 호출할 수 없다.)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2. String 클래스&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;자바에서는 문자열을 위한 클래스 String이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2.1 String클래스의 특징&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;String클래스에는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;문자열을 저장하기 위해서 문자형 배열변수 (char[]) value를 인스턴스 변수로 정의&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;해놓고 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;인스턴스 생성 시 생성자의 매개변수로 입력받는 문자열은 이 인스턴스 변수에 문자열 배열(char[])로 저장되는 것이다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        String str1 = &quot;abc&quot;;
        String str2 = &quot;abc&quot;;

        System.out.println(&quot;String str1 = \&quot;abc\&quot;;&quot;);
        System.out.println(&quot;String str2 = \&quot;abc\&quot;;&quot;);

        if (str1 == str2)
            System.out.println(&quot;str1 == str2 ? true&quot;);
        else
            System.out.println(&quot;str1 == str2 ? false&quot;);

        if (str1.equals(str2))
            System.out.println(&quot;str1.equals(str2) ? true&quot;);
        else
            System.out.println(&quot;str1.equals(str2) ? false&quot;);
        System.out.println();

        String str3 = new String(&quot;\&quot;abc\&quot;&quot;);
        String str4 = new String(&quot;\&quot;abc\&quot;&quot;);

        System.out.println(&quot;String str3 = new String(\&quot;abc\&quot;);&quot;);
        System.out.println(&quot;String str4 = new String(\&quot;abc\&quot;);&quot;);

        if (str3 == str4)
            System.out.println(&quot;str3 == str4 ? true&quot;);
        else
            System.out.println(&quot;str3 == str4 ? false&quot;);

        if (str3.equals(str4))
            System.out.println(&quot;str3.equals(str4) ? true&quot;);
        else
            System.out.println(&quot;str3.equals(str4) ? false&quot;);
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력 결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;String str1 = &quot;abc&quot;;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;String str2 = &quot;abc&quot;;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;str1 == str2 ? true&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;str1.equals(str2) ? true&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;String str3 = new String(&quot;abc&quot;);&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;String str4 = new String(&quot;abc&quot;);&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;str3 == str4 ? false&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;str3.equals(str4) ? true&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 코드를 보여주는 이유는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;문자열을 리터럴로 지정하는 방법과 String클래스의 생성자를 사용했을 때의 차이점&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;을 보여주기 위한 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;리터럴로 생성하게 되면 &quot;abc&quot; 문자열의 주소값은 같으므로 비교 연산자로 비교했을 때 true가 나온다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;하지만 String클래스 생성자로 생성했을 경우 둘의 인스턴스의 주소값은 각각 따로 생겨나기 때문에 다르다. 따라서 비교 연산자로 비교했을 때 false가 나오는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;String클래스의 특징 중 또 한가지는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;한번 생성된 String인스턴스가 갖고 있는 문자열은 읽어올 수만 있고, 변경할 수는 없다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그래서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;덧셈연산자(+)를 사용해서 문자열을 결합&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하는 것은 매 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;연산 시 마다 새로운 문자열을 가진 String인스턴스가 생성&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;되어 메모리 공간을 차지하기 때문에 가능한 사용하지 않는 것이 좋다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;문자열간의 결합이나 추출 등 문자열 작업이 많을 때는 StirngBuffer클래스를 사용하는 것이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2.2 빈 문자열(empty string)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;크기가 0인 배열&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 존재할 수 있을까? 답은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그렇다&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;문자열 배열도 마찬가지이다. String str = &quot;&quot;; 이렇게 빈 문자열을 선언할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;보통 빈 문자열을 선언할 시에 String str = null 보다는 String str = &quot;&quot; 이렇게 선언하는 것이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2.3 String 클래스의 생성자와 메서드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;생성자:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- String(String s)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- String(char[] val): char배열과 같은 문자열을 갖는 String인스턴스 생성&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- String(StringBuffer buf) : StringBuffer와 같은 문자열을 갖는 String인스턴스 생성&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메서드:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- char charAt(int index): 지정된 위치에 있는 문자를 알려줌&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- String concat(String str): 문자열str을 뒤에 덧붙임&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- boolean contains(CharSequence s): 지정된 문자열s가 포함되었는지를 검사&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- boolean endsWith(String suffix): 지정된 문자열suffix로 끝나는지 검사&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- boolean equals(Object obj): 매개변수로 받은 문자열 obj와 String인스턴스의 문자열을 비교&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- boolean equalsIgnoreCase(String str): 문자열과 String인스턴스의 문자열을 대소문자 구분없이 비교&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- int indexOf(int ch): 주어진 문자ch가 문자열에 존재하는 지 확인하여 위치 반환. 없으면 -1&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- int indexOf(String str): 위와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- int lastIndexOf(int ch): 지정된 문자 또는 문자코드를 문자열의 오른쪽 끝에서부터 찾아서 위치를 반환. 없으면 -1&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- int lastIndexOf(String str): 위와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- int length(): 문자열의 길이를 알려줌.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- String replace(CharSequence old, CharSequence nw): 문자열old를 문자열nw로 바꿈&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- String replaceAll(String regex, String replacement): 문자열regex와 일치하는 것을 모두 문자열replacement로 바꾼다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- String[] split(String regex): 문자열을 지정된 분리자(regex)로 나누어 문자열 배열에 담아 반환.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- String substring(int begin[, int end]): 시작위치부터 끝 위치 범위에 포함된 문자열을 얻는다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- String toLowerCase, toUpperCase(): 문자열을 소문자 혹은 대문자로 바꿔서 반환&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- static String valueOf(anything): 지정된 값을 문자열로 변환하여 반환, Object의 경우 toString()을 호출한다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Java/Java의 정석 읽고 정리</category>
      <category>Clone()</category>
      <category>equals</category>
      <category>hashcode</category>
      <category>java</category>
      <category>object</category>
      <category>string</category>
      <category>자바</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/27</guid>
      <comments>https://psyhm.tistory.com/27#entry27comment</comments>
      <pubDate>Mon, 11 Jun 2018 14:24:05 +0900</pubDate>
    </item>
    <item>
      <title>[Node.js][노드] stream(스트림) 이란??</title>
      <link>https://psyhm.tistory.com/26</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Node.js에서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;stream&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이란 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&quot;스트리밍 데이터로 작업하기 위한 추상적인 인터페이스&quot;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;라고 공식 문서에 나와있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;뭔 소리일까..?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;일단 stream이란 개념을 짚고 넘어가야 될 듯 싶다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;stream&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이란 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;일종의 추상적인 개념&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인데 입출력 기기나 프로세스, 파일 등&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 어디로 가는 지, 어디로 나왔는 지 상관없이 통일된 방식으로 데이터를 다루기 위한 가상의 개념&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그러니까 stream을 정의하기란 너무나 모호하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Node.js에서 많은 Object들이 stream Object 이다. 예를 들어서 http 서버의 request나 process.stdout도 stream 인스턴스이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;stream들은 읽을 수 있거나(readable), 쓸 수 있거나(writable) 혹은 둘 다(both)가 될 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;모든 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;stream들은 EventEmitter의 인스턴스&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다. 따라서 이벤트 핸들러를 작성할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;Stream 타입 종류&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Readable&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 읽을 수 있는 스트림(ex. fs.createReadStream())&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Writable&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 쓸 수 있는 스트림(ex. fs.createWriteStream())&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Duplex&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 읽고 쓸 수 있는 스트림(ex. net.Socket)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Transform&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 데이터를 쓰고 읽을 때 데이터를 수정하거나 변형할 수 있는 Duplex 스트림(ex.zlib.createDeflate()) // 잘 모르겠지만 압축파일과 관련이 있는 듯&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;CreateWriteStream 예제 코드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;const fs = require('fs');
const file = fs.createWriteStream('./test.txt');  // stream 객체로 생성

for(let i = 0; i &amp;lt;= 1e6; i++) {   // 1 * 10^6번동안 계속 write
    file.write('Hello World!!\n');  // 문자열을 스트림에 씀
}
file.end();     // stream에게 더 이상 데이터를 전달하지 않겠다는 메서드.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;재밌는 건 다음과 같이 코딩했을 때이다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;const fs = require('fs');
const file = fs.createWriteStream('./test.txt');

for(let i = 0; i &amp;lt;= 5e6; i++) {
    file.write('Hello World.\n');
}
console.log(&quot;write end&quot;);
setTimeout(() =&amp;gt; {
    console.log(&quot;end&quot;);
    file.end();
}, 5000);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;작업관리자:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/998400375B1A89CD04&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F998400375B1A89CD04&quot; width=&quot;820&quot; height=&quot;402&quot; filename=&quot;20180608_215911.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;stream을 write 했을 때&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 메모리가 1GB 가까이 급격히 증가했던 점&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;과 콘솔 창에 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&quot;end&quot;가 적히는 시점부터 'test.txt' 파일 크기가 켜졌던 점&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;, 마지막으로 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;end가 찍히고도 프로그램이 종료되지 않은 점&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;차근차근 추리를 시작해보자.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;file.write를 했을 때는 스트림에 데이터가 누적되어서 메모리가 급격히 증가했던 것 같다.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;end가 적히는 시점, 즉 file.end()가 실행된 뒤부터 파일의 크기가 커졌던 점을 생각해보면 그때부터 file I/O 스레드가 돌면서 파일에 stream 데이터를 write 하기 시작했다는 점을 알 수 있다.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;really end가 찍히고도 끝나지 않았던 것은 file I/O가 돌고있는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;스레드가 아직 완료되지 않았기 때문에&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 프로세스가 완전히 종료되지 않은 것으로 보인다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이 부분에 대해선 공부해야될 부분이 많은 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;메모리가 증가한 것에 대해 이것저것 찾아보다가 다음과 같은 설명을 보았다.&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;file.write를 할 때 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;highWaterMark&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;(내부 버퍼에 저장할 최대 바이트)에 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;지정한 값보다 큰 버퍼를 쓰려고 할 땐, write()가 false를 리턴&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;스트림이 빠져나가는 동안 write()를 호출하면 청크가 버퍼링되고 false가 반환&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;되고,&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;현재 버퍼링된 모든 청크가 빠져나가면 drain 이벤트가 발생&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;만약 스트림이 다 빠져나가지 않았는데 write()가 계속 발생되면 메모리가 다시 반환되지 않을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그래서 메모리 누수가 발생했던 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;메모리 누수를 막기위해서는 다음과 같이 write()가 false일 때 스트림에 모든 데이터가 빠져나간 뒤(drain 이벤트 발동) test 함수가 다시 동작할 수 있도록 만들어야 한다.(적합한 코드는 아니다.)&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;const fs = require('fs');
let file = fs.createWriteStream('./test.txt');
let ok = true;
let i = 0;
function test() {
    for(; i &amp;lt;= 2e6 &amp;amp;&amp;amp; ok; i++) {
        ok = file.write('Hello World.\n');
        console.log(ok);
    }
    if(ok == false) {
        ok = true;
        file.once('drain', test);     // drain 이벤트가 발생했을 때 일회 리스너 함수 test를 등록
        console.log(&quot;call drain&quot;);
    }
    if(i == 2e6) {
        console.log(i,&quot;: end&quot;);
        file.end();
    }
}
test();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;CreateReadStream 예제 코드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;const fs = require('fs');
const file = fs.createReadStream('./test.txt');

let chunk;

file.on('readable', () =&amp;gt; {   // stream에 데이터가 남아있는 경우 자동으로 발생하는 이벤트
    // 가끔 다 읽지 않았을 때 chunk가 null일 경우가 있다.
    while (null !== (chunk = file.read(13))) {        // read의 buffer 크기: 13
        console.log(chunk.toString(), &quot;\nline&quot;);
    }
});
file.on('end', () =&amp;gt; {    // stream에 데이터가 더 이상 남아있지 않는 경우 발생하는 이벤트
    console.log('end');
});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;readable 이벤트는 Readable 스트림에 읽을 데이터가 남아있을 때 발생하는 이벤트이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이 이벤트 안에 read() 함수를 사용해서 데이터를 읽으면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Node.js</category>
      <category>createReadStream</category>
      <category>createWriteStream</category>
      <category>DRAIN</category>
      <category>highWaterMark</category>
      <category>node.js</category>
      <category>Stream</category>
      <category>노드</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/26</guid>
      <comments>https://psyhm.tistory.com/26#entry26comment</comments>
      <pubDate>Fri, 8 Jun 2018 22:53:07 +0900</pubDate>
    </item>
    <item>
      <title>java의 정석 8강. 예외처리(하)</title>
      <link>https://psyhm.tistory.com/25</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.7 예외의 발생과 catch 블럭&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;instanceof &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;연산자로&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; catch 블록&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;의 () 안의 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스와 비교&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;해서 맞는 catch 블록의 {} 코드들을 실행함.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;예외가 발생했을 때 생성되는 예외클래스의 인스턴스에는 발생한 예외에 대한 정보가 담겨져 있으며 다음 함수로 확인이 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;printStackTrace()&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; - 예외발생 당시의 호출스택에 있었던 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메서드의 정보&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;와 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예외 메세지&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 화면에 출력&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;getMessage() &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;- 발생한 예외클래스의 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인스턴스에 저장된 메세지&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 읽을 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        PrintStream ps = null;

        try {
            ps = new PrintStream(&quot;error.log&quot;);

            System.out.println(1);
            System.out.println(2);
            System.out.println(3);
            System.out.println(0/0);        // 예외 발생
            System.out.println(4);
        } catch (Exception ae) {
            ae.printStackTrace(ps);         // 호출 스택의 내용을 화면 대신 error.log 파일에 저장
            ps.println(&quot;예외 메세지: &quot; + ae.getMessage());       // 마찬가지로 오류 메세지를 error.log 파일에 저장
        }
        System.out.println(6);
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;1&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;2&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;3&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;6&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;error.log&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;java.lang.ArithmeticException: / by zero&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;white-space: pre; color: rgb(0, 0, 0);&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;at com.company.Main.main(Main.java:15)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;예외 메세지: / by zero&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;오류 메세지의 결과&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;PrintStream&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;으로 전달하는 예제이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하지만 위의 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;PrintStream&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;main 메서드 외에 다른 곳은 접근할 수가 없기 때문에 이럴 땐 'System.err'&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 이용하면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        PrintStream ps = null;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(&quot;error.log&quot;, true);  // error.log 파일 append를 true로 설정
            ps = new PrintStream(fos);
            System.setErr(ps);          // err의 출력을 화면이 아닌 error.log로 변경한다.

            System.out.println(1);
            System.out.println(2);
            System.out.println(3);
            System.out.println(0/0);
            System.out.println(4);
        } catch (Exception ae) {
            System.err.println(&quot;----------------------------&quot;);
            System.err.println(&quot;예외발생시간: &quot; + new Date());
            ae.printStackTrace(System.err);
            System.err.println(&quot;예외메세지: &quot;+ ae.getMessage());
            System.err.println(&quot;----------------------------&quot;);
        }
        System.out.println(6);
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력 결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;1&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;2&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;3&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;6&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;error.log:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;----------------------------&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;예외발생시간: Tue Jun 05 16:47:05 KST 2018&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;java.lang.ArithmeticException: / by zero&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;white-space: pre; color: rgb(0, 0, 0);&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;at com.company.Main.main(Main.java:19)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;예외메세지: / by zero&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;----------------------------&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;System.out이나 System.err는 프로그램 어디서든 접근 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;둘 다 콘솔창 출력이 디폴트이기 때문에 SetErr 메서드로 error.log 파일로 출력을 옮긴 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.8 finally 블럭&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;finally 블럭은 예외의 발생여부에 상관없이 실행되어야할 코드를 포함시킬 목적으로 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;try-catch-finally &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;순서로 구성된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;try{
} catch(Exception e){
} finally {
  // 예외의 발생여부와 관계없이 항상 수행되어야할 문장들을 넣는다.
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;try 문에서 return이 발생하여 메서드가 종료되더라도 finally문장은 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.9 메서드에 예외 선언하기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;try-catch문 외에 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예외를 메서드에 선언하는 방법&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메서드에 예외를 선언하려면, &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메서드의 선언부에 키워드 throws&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 사용해서 메서드 내에서 발생할 수 있는 예외를 적어두기만 하면 된다. 그리고, 예외가 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;여러 개일 경우에는 쉼표(,)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;로 구분한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;void method() throws Exception1, Exception2, ..., ExceptionN {
  // 메서드의 내용
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;선언 부분에 적어두면 다른 사람이 보았을 때 어떤 대처를 해야하는 지 이해하기 쉽기 때문에 튼튼한 코드를 만들 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사실 예외를 메서드의 throws에 명시한다고 메서드가 처리하는 것이 아니라 그 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메서드를 호출한 메서드에게 예외를 전달하여 예외처리를 떠맡기는 것&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) throws Exception {
        method1();
    }

    static void method1() throws Exception {
        method2();
    }

    static void method2() throws Exception {
        throw new Exception();
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Exception in thread &quot;main&quot; java.lang.Exception&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;white-space: pre; color: rgb(0, 0, 0);&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;at com.company.Main.method2(Main.java:14)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;white-space: pre; color: rgb(0, 0, 0);&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;at com.company.Main.method1(Main.java:10)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;white-space: pre; color: rgb(0, 0, 0);&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;at com.company.Main.main(Main.java:6)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;다음 출력 결과로 다음과 같은 사실을 알 수 있다.&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예외가 발생했을 때 모두 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;3개의 메서드가 호출스택&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에 있었으며,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예외가 발생한 곳은 맨 윗줄 method2&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;라는 것과&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;main 메서드가 method1()을, 그리고 method1()은 method2()를 호출했다는 것을 알 수 있다.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이렇게 예외를 넘겨줄 순 있지만 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;결국 어느 한 곳에서는 try-catch문으로 예외를 처리&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;해야 한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.10 예외 되던지기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;한 메서드에서 발생할 수 있는 예외가 여럿인 경우, 몇 개는 try-catch문을 통해서 메서드 내에서 자체적으로 처리하고, 그 나머지는 선언부에 지정하여 호출한 메서드에서 처리하도록 함으로써, 양쪽으로 나눠서 처리되도록 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이것은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예외를 처리한 후에 인위적으로 다시 발생시키는 방법을 통해서 가능한데, 이것을 '예외 되던지기'라고 한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        try {
            method1();
        } catch (Exception e) {
            System.out.println(&quot;main메서드에서 예외가 처리 되었습니다.&quot;);
        }
    }
    static void method1() throws Exception {
        try {
            throw new Exception();      // 예외 발생
        } catch (Exception e) {
            System.out.println(&quot;method1메서드에서 예외가 처리 되었습니다.&quot;);
            throw e;        // 다시 예외를 밖으로 발생시킨다.
        }
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;결과에서 알 수 있듯이 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;method1과 main 메서드 양쪽의 catch 블럭이 모두 수행&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;되었음을 알 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.11 사용자정의 예외 만들기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사용자가 필요에 따라 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;프로그래머가 새로운 예외클래스를 정의하여 사용할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;필요에 따라 알맞은 예외 클래스를 선택할 수 있다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;class MyException extends Exception {
    private final int ERR_CODE;         // 생성자를 통해 초기화한다.

    MyException(String msg, int errCode) {  // 생성자
        super(msg);         // 조상인 Exception 클래스의 생성자를 호출한다.
        ERR_CODE = errCode;
    }

    MyException(String msg) {
        this(msg, 100);
    }

    public int getErrCode() {
        return ERR_CODE;
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Java/Java의 정석 읽고 정리</category>
      <category>Catch</category>
      <category>finally</category>
      <category>메서드 예외처리</category>
      <category>사용자정의 예외</category>
      <category>예외 던지기</category>
      <category>예외처리</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/25</guid>
      <comments>https://psyhm.tistory.com/25#entry25comment</comments>
      <pubDate>Thu, 7 Jun 2018 17:32:31 +0900</pubDate>
    </item>
    <item>
      <title>java의 정석 8강. 예외처리(상)</title>
      <link>https://psyhm.tistory.com/24</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1. 예외처리&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.1 프로그램 오류&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;프로그램 오류는&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;컴파일 에러&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;와 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;런타임 에러&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;가 있는데 그 중 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;런타임 에러&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에러와 예외&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;, 2가지 종류가 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에러&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 프로그램 코드에 의해서 수습될 수 없는 심각한 오류&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예외&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.2 예외처리의 정의와 목적&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;프로그램 실행도중에 발생하는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에러&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 발생하면 복구할 수 없는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;심각한 오류&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;지만, &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예외&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 이에 대한 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;처리를 미리하면 프로그램의 비정상 종료를 막을 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.3 예외처리구문 try-catch&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;예외를 처리하기 위한 구문은 다음과 같다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;try {
    // 예외가 발생할 가능성이 있는 문장들을 넣는다.
} catch (Exception1 e1) {
    // Exception1이 발생했을 경우, 이를 처리하기 위한 문장 넣는다.
} catch (Exception2 e2) {
    // Exception2가 발생했을 경우, 이를 처리하기 위한 문장 넣는다.
}
...
} catch (ExceptionN eN) {
    // ExceptionN 이 발생했을 경우, 이를 처리하기 위한 문장 넣는다.
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;catch&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;문이 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;여러개&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 있지만 이 중 발생하는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예외의 종류와 일치하는 단 한 개의 catch 블럭만 수행&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예제 1)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        try {
        } catch (Exception e) {
            try {
            } catch (ArithmeticException e) {   // 에러: 같은 이름의 참조변수를 사용함
            }
        }
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;위의 예제는 catch 블럭 내에 try-catch문이 포함된 경우, 같은 이름의 참조변수를 사용했기 때문에 오류가 났다. 각&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; catch 블럭에 선언된 두 참조변수의 영역이 서로 겹치기 때문에&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 다른 이름을 사용해서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;구별해야한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예제 2)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        int number = 100;
        int result = 0;

        for(int i = 0; i &amp;lt; 10; i++) {
            result = number / (int)(Math.random() * 10);
            System.out.println(result);
        }
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;실행결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;16&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;33&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(255, 0, 0);&quot;&gt;Exception in thread &quot;main&quot; java.lang.ArithmeticException: / by zero&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;white-space: pre; color: rgb(255, 0, 0);&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;at com.company.Main.main(Main.java:9)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;위의 예제는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Math.random() 값이 어쩌다 0&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 나와서 number를 0으로 나누었기 때문에 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;생기는 예외&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;number를 0으로 나누려 했기 때문에 ArithmeticException이 발생했고 발생위치는 Main.java 파일의 9번째 줄이라는 것을 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;어디서 왜 일어났는 지 알았기 때문에 이번엔 try-catch를 추가하여 예외처리를 해보자.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        int number = 100;
        int result = 0;

        for(int i = 0; i &amp;lt; 10; i++) {
            try{
                result = number / (int)(Math.random() * 10);
                System.out.println(result);
            } catch (ArithmeticException e){
                System.out.println(&quot;0&quot;);
            }
        }
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이제는&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; Math.random()이 0이 나오게 되면 catch 구문으로 들어가서 0을 출력&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하게 되고 계속해서 for문을 동작하게 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;예외처리 하지 않았다면 0이 나오는 순간 프로그램은 비정상 종료를 할 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.4 try-catch문에서의 흐름&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        System.out.println(1);
        try {
            System.out.println(2);
            System.out.println(3/0);
            System.out.println(4);
        } catch (Exception e) {
            System.out.println(5);
        }
        System.out.println(6);
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력 결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;1&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;2&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;5&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;6&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;try문에서 오류가 생기자마자 바로 catch 문으로 넘어가기 때문에 4는 출력이 되지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.5 예외 발생시키기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;키워드 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;throw를 사용해서 프로그래머가 고의적으로 예외를 발생시킬 수 있다&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;. 방법은 다음과 같다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;ol style=&quot;list-style-type: decimal;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size:12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;먼저 연산자&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; new를 이용&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;해서 발생시키려는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예외 클래스의 객체를 만든 다음&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;Exception e = new Exception(&quot;고의로 발생시킴&quot;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;키워드 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;throw를 이용해서 예외를 발생&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;시킨다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    public static void main(String[] args) {
        try {
            Exception e = new Exception(&quot;고의로 발생시킴&quot;);
            throw e;
        } catch (Exception e) {
            System.out.println(&quot;에러 메세지: &quot; + e.getMessage());
            e.printStackTrace();
        }
        System.out.println(&quot;프로그램이 정상 종료되었음&quot;);
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력 결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에러 메세지: 고의로 발생시킴&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(255, 0, 0);&quot;&gt;java.lang.Exception: 고의로 발생시킴&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;white-space: pre; color: rgb(255, 0, 0);&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;at com.company.Main.main(Main.java:6)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;프로그램이 정상 종료되었음&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.6 예외 클래스의 계층 구조&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/991C57455B13C0F43C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F991C57455B13C0F43C&quot; width=&quot;500&quot; height=&quot;281&quot; filename=&quot;ilovepdf_com.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;사진을 보면 알 수 있듯이 Exception과 Error 클래스 역시 Object 클래스의 자손들이다.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;모든 예외의 최고 조상은 Exception이며, 상속 계층도를 Exception클래스부터 도식화 하면 다음과 같다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;p style=&quot;font-size: 16px; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9911474F5B13C1170D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9911474F5B13C1170D&quot; width=&quot;500&quot; height=&quot;281&quot; filename=&quot;ilovepdf_com-1.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그림에서 볼 수 있듯이 예외 클래스들은 다음과 같이 두 개의 그룹으로 나뉜다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size:12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;RuntimeException&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스와 그 자손클래스들&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Exception&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스와 그 자손클래스들&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;RuntimeException&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스는 주로 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;프로그래머의 실수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에 의해 발생하는 오류이고 그 외 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Exception &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사용자의 실수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;와 같은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;외적인 요인에 의해 발생하는 예외&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 두 개의 오류의 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;차이점&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;컴파일 시의 예외처리 체크 여부&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;RuntimeException&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스들 그룹에 속하는 예외가 발생할 가능성이 있는 코드에는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예외처리를 하지 않아도 컴파일 시 문제가 되지 않지만&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Exception&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스들 그룹에 속하는 예외가 발생할 가능성이 있는 예외는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;반드시 예외처리를 해야하며 그렇지 않으면 컴파일 에러&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;가 발생한다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Java/Java의 정석 읽고 정리</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/24</guid>
      <comments>https://psyhm.tistory.com/24#entry24comment</comments>
      <pubDate>Sun, 3 Jun 2018 19:26:56 +0900</pubDate>
    </item>
    <item>
      <title>java의 정석 7강. 객체지향프로그래밍2(하)</title>
      <link>https://psyhm.tistory.com/23</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;객체지향은 c++과 유사한 점이 많으니 특징과 다른 점만 짚고 넘어가도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;7. 인터페이스&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;7.1 인터페이스란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터페이스&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;일종의 추상클래스&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다. 인터페이스는 추상클래스처럼 추상메서드를 갖지만 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;몸통을 갖춘 일반 메서드 또는 멤버변수를 구성원으로 가질 수 없다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;추상클래스를 '미완성 설계도'라고 한다면 인터페이스는 밑그림만 그려져 있는 '기본 설계도'라고 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;7.2 인터페이스의 작성&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터페이스를 작성하는 것은 클래스와 같지만, 다만 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;키워드&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;로 class 대신 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;interface를 사용&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하는 것만 다르다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;interface 인터페이스이름 {
  public static final 타입 상수이름 = 값;
  public abstract 메서드이름(매개변수 목록)
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;일반적인 클래스와 달리 인터페이스의 멤버들은 다음과 같은 제약사항이 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;모든 멤버변수는 public static final&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이어야 하며, 이를 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;생략&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;모든 메서드는 puiblic abstract&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;여야 하며, 이를 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;생략&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;7.3 인터페이스의 상속&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터페이스는 인터페이스로부터만 상속받을 수 있으며, 클래스와는 달리 다중상속이 가능하다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;interface Movable {
  // 위치 x,y로 이동하는 기능
  puiblic abstract void move(x, y);
}
interface Attackable {
  // 지정된 대상을 공격하는 기능
  void attack(Unit u);          // puiblic abstract 생략가능
}

interface Fightable extends Movable, Attackable { }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;7.4 인터페이스의 구현&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터페이스&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 자신에 정의된&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 추상메서드의 몸통을 만들어주는 클래스를 만들어야 구현이 가능&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size:12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;대신 extends 대신 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;키워드 implements&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 사용한다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;class Fighter implements Fightable {
  public void move(int x, int y); { ... }
  public void attack(Unit u) { ... }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;만일 구현하는 인터페이스의 메서드 중 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;일부만 구현&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;했다면&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; class 앞에 abstract 키워드를 붙여야 한다&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;추상클래&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;스&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;여야만 한다).&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음과 같이&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 상속&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;과&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 구현을 동시&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에 할 수도 있다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;class Fighter extends Unit implements Fightable {
  public void move(int x, int y); { ... }
  public void attack(Unit u) { ... }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;7.5 인터페이스를 이용한 다중상속&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;만일 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;두 개의 클래스로부터 상속을 받아야 할 상황&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이라면, 두 조상클래스 중에서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;비중이 높은 쪽을 선택해 상속 받고&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다른 한 쪽은&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;내부의 멤버로 포함&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;시키는 방식으로 처리하거나 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;어느 한 쪽의 필요한 부분을 뽑아서 인터페이스로 만든 다음 구현&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하도록 한다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;class Tv {
    protected boolean power;
    protected int channel;
    protected int volume;

    public void power() { power = !power; }
    public void channelUp() { channel++; }
    public void channelDown() { channel--; }
    public void volumeUp() { volume++; }
    public void volumeDown() { volume--; }
}

class VCR {
    protected int counter;

    public void play() {

    }
    public void stop() {

    }
    public void reset() {
        counter = 0;
    }
    public int getCounter() {
        return counter;
    }
    public void setCounter(int counter) {
        this.counter = counter;
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;두 클래스를 상속하는 클래스를 만들고 싶지만 다중상속은 불가능하므로 한 쪽만 선택해 다른 한 쪽의 메서드와 일치하는 새로운 인터페이스를 만든다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;따라서 VCR 클래스에 정의된 메서드와 일치하는 추상메서드를 갖는 인터페이스를 정의한다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public interface IVCR {
  public void play();
  public void stop();
  public void reset();
  public int getCounter();
  public void setCounter(int counter);
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이제 IVCR을 구현하고 Tv클래스를 상속받는 TVCR 클래스를 작성한다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class TVCR extends Tv implements IVCR {
  VCR vcr = new VCR();

  public void play() {
    vcr.play();
  }
  public void stop() {
    vcr.stop();
  }
  public void reset() {
    vcr.reset();
  }
  public int getCounter() {
      return vcr.getCounter();
  }
  public void setCounter(int counter) {
      vcr.setCounter(counter);
  }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이런 식으로 다형적 특성을 살리면서 다중상속을 대체할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;7.6 인터페이스를 이용한 다형성&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터페이스&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 역시 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;해당 인터페이스 타입의&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;참조변수로 이를 구현한 클래스의 인스턴스를 참조 가능&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하며, &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터페이스 타입으로 형변환도 가능&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Fighter 클래스가 Fightable 인터페이스 상속받았을 때&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Fightable f = new Fighter();&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;메서드의 매개변수 타입으로 사용될 때&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;void attack (Fightable f) {&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; // ...&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;}&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;등등이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;7.7 인터페이스의 장점&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;인터페이스를 이해하기 전에 다음 두 가지 사항을 염두해 두고 있어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스를 사용하는 쪽&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;과 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스를 제공하는 쪽&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메서드를 사용하는 쪽&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에서는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사용하려는 메서드의 선언부만 알면 된다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;예를 들어서 클래스 A와 B가 있다고 가정하자.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;클래스 A는 클래스 B의 인스턴스를 생성하고 메서드를 호출한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/997DB03F5B1392033C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F997DB03F5B1392033C&quot; width=&quot;500&quot; height=&quot;213&quot; filename=&quot;20180603_155936.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이 경우 클래스 A를 작성하기 위해 클래스 B가 이미 작성되어야 한다. 그리고 B에 변경점이 생기면 클래스 A도 변경되어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이와 같이 직접적인 관계는 한 쪽이 변경되면 다른 한 쪽도 변경되어야 한다는 단점이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;하지만 인터페이스를 매개체로 해서 클래스 A가 인터페이스를 통해서 클래스 b의 메서드에 접근하도록 하면, 클래스 B에 변경사항이 생기거나 클래스 B와 같은 기능의 다른 클래스로 대체되어도 클래스 A는 전혀 형향을 받지 않도록 하는 것이 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99454C415B1392C21F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99454C415B1392C21F&quot; width=&quot;500&quot; height=&quot;185&quot; filename=&quot;20180603_160259.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Java/Java의 정석 읽고 정리</category>
      <category>java</category>
      <category>다형성</category>
      <category>인터페이스</category>
      <category>자바</category>
      <category>추상클래스</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/23</guid>
      <comments>https://psyhm.tistory.com/23#entry23comment</comments>
      <pubDate>Sun, 3 Jun 2018 16:04:14 +0900</pubDate>
    </item>
    <item>
      <title>java의 정석 7강. 객체지향프로그래밍2(중)</title>
      <link>https://psyhm.tistory.com/22</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;객체지향은 c++과 유사한 점이 많으니 특징과 다른 점만 짚고 넘어가도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;5.다형성&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;5.1 다형성이란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;객체지향개념에서의 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다형성&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이란 '&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;여러 가지 형태를 가질 수 있는 능력&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;'을 의미하며, 자바에서는 한&amp;nbsp; 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 함으로써 다형성을 프로그램적으로 구현하였다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 하였다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;5.2 참조변수의 형변환&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;서로 상속관계에 있는 클래스 사이에서만 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자손타입 -&amp;gt; 조상타입(&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;업캐스팅&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;): &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;형변환 생략가능&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자손타입 &amp;lt;- 조상타입(&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다운캐스팅&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;): &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;형변환 생략불가&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;class Car {
    String color;
    int door;
    void drive() {
        System.out.println(&quot;drive, Brrrr~&quot;);
    }
    void stop() {
        System.out.println(&quot;Stop!!&quot;);
    }
}

class FireEngine extends Car {
    void water() {
        System.out.println(&quot;Water!!&quot;);
    }
}

class Ambulance extends Car {
    void siren() {
        System.out.println(&quot;siren!!&quot;);
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = null;
        FireEngine fe1 = new FireEngine();
        FireEngine fe2 = null;

        car = fe1;                      // car = (Car) fe1;에ㅐ서 형변환이 생략된 형태이다.
        fe2 = (FireEngine)car;          // 형변환을 생략할 수 없다.
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;5.3 instanceof 연산자&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;참조변수가 참조하고 있는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인스턴스의 실제 타입을 알아보기 위해 instanceof 연산자&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 사용한다. 연산의 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;결과&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;로 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;boolean&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 값인 true, false를 반환한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;void doWork(Car c) {
  if(c instanceof FireEngine) {
    FireEngine fe = (FireEngine) c;
    fe.water();
  } else if (c instanceof Ambulance) {
    Ambulance am = (Ambulance) c;
    am.siren();
  }
  // ...
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;5.4 참조변수와 인스턴스의 연결&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메서드의 경우&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 조상 클래스의 메서드를 자손의 클래스에서 오버라이딩한 경우에도 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;참조변수의 타입에 관계없이 항상 실제 인스턴스의 메서드(오버라이딩한 메서드)가 호출&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;되지만, &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;멤버변수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;의 경우 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;참조변수의 타입에 따라 달라진다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;class Parent {
    int x = 100;
    void method() {
        System.out.println(&quot;Parent method&quot;);
    }
}

class Child extends Parent {
    int x = 200;
    void method() {
        System.out.println(&quot;Child method&quot;);
    }
}

public class Main {
    public static void main(String[] args) {
        Parent p = new Child();
        Child c = new Child();

        System.out.println(&quot;p.x = &quot; + p.x);
        p.method();

        System.out.println(&quot;c.x = &quot; + c.x);
        c.method();
    }
}&lt;/span&gt;&lt;font face=&quot;맑은 고딕, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 16px; white-space: normal; color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력 결과:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;p.x = 100&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Child method&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;c.x = 200&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Child method&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;5.5 매개변수의 다형성&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;참조변수의 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다형적인 특징&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메서드의 매개변수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에도 적용된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;void buy(Product p) {        // Product는 상품 클래스들의 조상 클래스이다.
        money = money - p.price;
        bonusPoint = bonusPoint + p.bonusPoint;
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;5.6 여러 종류의 객체를 하나의 배열로 다루기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;ex)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;Product p[] = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();&lt;/span&gt;&lt;font face=&quot;맑은 고딕, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 16px; white-space: normal; color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;6. 추상클래스&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;6.1 추상클래스란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;추상클래스는 키워드 '&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;abstract&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;'를 붙여주기만 하면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;absctract class 클래스 이름 {
        //....
}&lt;/span&gt;&lt;font face=&quot;맑은 고딕, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 16px; white-space: normal; color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;6.2 추상메서드(abstract method)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;선언부만 작성하고 구현부는 작성하지 않은 채로 남겨 둔 것이 &quot;추상메서드&quot;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;키워드 '&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;abstract&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;'를 앞에 붙여주고&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 주석으로 어떤 기능을 수행할 것인지 코멘트를 남긴다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;만일 조상으로부터 상속받은 추상메서드 중 하나라도 구현하지 않는다면, 자손클래스 역시 추상클래스로 지정해줘야한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Java/Java의 정석 읽고 정리</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/22</guid>
      <comments>https://psyhm.tistory.com/22#entry22comment</comments>
      <pubDate>Fri, 1 Jun 2018 01:31:47 +0900</pubDate>
    </item>
    <item>
      <title>c++ void 포인터(generic 포인터), 함수형 포인터</title>
      <link>https://psyhm.tistory.com/21</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1. void 포인터&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;c, c++ 언어에서&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; generic 포인터&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;라고도 알려진&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; void 포인터&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 굉장히 특별한 타입이다.&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 그 어떤 타입이든 객체든 가리킬 수 있는 포인터&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이기 때문이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;심지어 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;함수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;도 가리킬 수 있기 때문에 void 포인터를 이용해 함수를 실행할 수도 있다.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;선언은 다음과 같이 할 수 있다.&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;void *ptr;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그리고 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;어떤 데이터든 주소값만 대입&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;ex)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp line-numbers&quot;&gt;&lt;span&gt;int a = 10;
float b = 10.1f;

void *aPtr = &amp;amp;a;
void *bPtr = &amp;amp;b;&lt;/span&gt;&lt;font face=&quot;맑은 고딕, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 16px; white-space: normal; color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;void 포인터를 사용하기 위해선&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;대입한 데이터형으로 형변환 시킨 후에 사용&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;해야 한다. 왜냐하면 void 포인터가 뭘 가리키는 지 모르기 때문이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span&gt;ex)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp line-numbers&quot;&gt;&lt;span&gt;std::cout &amp;lt;&amp;lt; *(int*)aPtr &amp;lt;&amp;lt; std::endl;      // int의 주소값을 대입했기 때문에 (int*)로 형변환
std::cout &amp;lt;&amp;lt; *(float*)bPtr &amp;lt;&amp;lt; std::endl;    // float의 주소값을 대입했기 때문에 (float*)로 형변환
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;void 포인터를 사용하면 타입에 제한이 줄어들기 때문에 좀 더 유연한 프로그램을 만들 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2. 함수형 포인터&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;함수를 정의&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하게 되면 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;함수 이름&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;으로 함수를 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;실행&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp line-numbers&quot;&gt;&lt;span&gt;void print() {
	std::cout &amp;lt;&amp;lt; &quot;hello world!!&quot; &amp;lt;&amp;lt; std::endl;
}
void main() {
  print();
  return ;
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사실 이 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;함수의 이름은 함수를 가리키는 주소값&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다. 따라서 실제 함수를 호출하면 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;함수의 주소를 이용하여 호출&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하는 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그리고 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 함수를 가리키는 함수 포인터를 선언할 수도 있다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;함수 포인터는 함수의 주소를 가리키기 때문에 이를 이용해 함수를 간접적으로 실행시킬 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;함수 포인터를 선언하는 방법은 예시를 통해 알아보자.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;먼저&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp line-numbers&quot;&gt;&lt;span&gt;void func(int a) {
  ...
}&lt;/span&gt;&lt;font face=&quot;맑은 고딕, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 16px; white-space: normal; color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이런 함수가 존재한다고 할 때 이 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;함수를 가리킬 수 있는 포인터&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 다음과 같이 선언하면 된다.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;void (*funcPtr)(int);&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그리고 이 funcPtr에 함수 이름을 대입하면 된다.&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;funcPtr = func;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;다음 예제를 보자&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp line-numbers&quot;&gt;&lt;span&gt;void print() {
	std::cout &amp;lt;&amp;lt; &quot;hello world!!&quot; &amp;lt;&amp;lt; std::endl;
}

void main() {
	void(*funcPtr)(void);
	funcPtr = print;

	funcPtr();         // 이렇게 호출해도 print 함수를 실행할 수 있다.
	return;
}&lt;/span&gt;&lt;font face=&quot;맑은 고딕, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 16px; white-space: normal; color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;funcPtr&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;은 func 함수에만 사용 가능한 것이 아니라 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;반환형이 void이고 인수가 int 형 하나만 있는 함수에 모두 사용이 가능&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;따라서 반환형과 인수가 같은 함수들은 어떤 상황에 따라 funcPtr에 다르게 함수들을 대입한다면 funcPtr() 부분은 건드리지 않은 채 다른 함수들을 상황에 맞게 실행할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;ex)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp line-numbers&quot;&gt;void print1() {
	std::cout &amp;lt;&amp;lt; &quot;print1!!&quot; &amp;lt;&amp;lt; std::endl;
}
void print2() {
	std::cout &amp;lt;&amp;lt; &quot;print2!!&quot; &amp;lt;&amp;lt; std::endl;
}

void main() {
	void(*funcPtr)(void) = print1;
	funcPtr();         // print1 함수 호출!

	funcPtr = print2;
 	funcPtr();         // print2 함수 호출!
	return;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그리고 함수형 포인터를 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;typedef&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 이용하여 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자료형&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;으로 만들면 편하다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;typedef void(*myFuncDef)(void);&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;따라서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;myFuncDef funcPtr;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;로 함수 포인터를 선언할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;한편, 위에서 void 포인터는 함수도 가리킬 수 있다고 하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;void 포인터로 함수를 부르고 싶다면 마찬가지로 함수 포인터로 형변환하여 사용&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp line-numbers&quot;&gt;&lt;span&gt;typedef void(*myFuncDef)(void);

void print() {
	std::cout &amp;lt;&amp;lt; &quot;hello world!!&quot; &amp;lt;&amp;lt; std::endl;
}

void main() {
	void* ptr;
	ptr = print;

	((myFuncDef)ptr)();     // void func(void)형 함수 포인터로 형변환하여 함수 호출
	return;
}&lt;/span&gt;&lt;font face=&quot;맑은 고딕, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 16px; white-space: normal; color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;void 포인터와 함수 포인터는 프로그래밍을 유연하게 만드므로 꼭 알아둬야 할 문법인 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>C++언어</category>
      <category>C</category>
      <category>C++</category>
      <category>generic</category>
      <category>void 포인터</category>
      <category>포인터</category>
      <category>함수 포인터</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/21</guid>
      <comments>https://psyhm.tistory.com/21#entry21comment</comments>
      <pubDate>Thu, 31 May 2018 19:13:45 +0900</pubDate>
    </item>
    <item>
      <title>java의 정석 7강. 객체지향프로그래밍2(상)</title>
      <link>https://psyhm.tistory.com/20</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;객체지향은 c++과 유사한 점이 많으니 특징과 다른 점만 짚고 넘어가도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1. 상속&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.1 상속의 정의와 장점&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자바에서 상속을 구현하는 방법은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;extends&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 사용하면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.2 단일 상속&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다중 상속은 이름 겹침 등 다양한 문제가 있기 때문에 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;단일 상속만 허용&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하였다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;=&amp;gt; 다중 상속은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;interface&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;로 어느정도 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;대체 가능&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.3 Object 클래스 - 모든 클래스의 조상&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Object 클래스&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 모든 클래스 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;상속 계층도의 제일 위&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에 위치하는 조상클래스이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다른 클래스로부터 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;상속 받지 않는 모든 클래스&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;들은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자동적으로 Object 클래스로부터 상속&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;받게 함으로써 이를 가능하게 한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Object 클래스에 대해서는 나중에 배우도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2. 오버라이딩&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2.1 오버로딩 vs 오버라이딩&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;오버로딩&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 기존에 없는&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 새로운 매서드를 정의&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하는 것&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;오버라이딩&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;상속받은 매서드&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;의 내용을 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;변경&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하는 것&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2.2 super&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;super&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 자손 클래스에서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;조상 클래스&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;로부터 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;상속받은 멤버를 참조&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하는데 사용되는 참조변수이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;this와 마찬가지로 상속받은 멤버와 자신의 클래스에 정의된 멤버의 이름이 같을 때는 super를 사용해서 구별할 수 있다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;class Parent{
    int x = 10;
}

class Child extends Parent {
    int x = 20;

    void method() {
        System.out.println(&quot;x= &quot; + x);                  // Child의 x
        System.out.println(&quot;this.x= &quot; + this.x);        // Child의 x
        System.out.println(&quot;super.x= &quot; + super.x);      // Parent의 x
    }
}

public class Main {
    public static void main(String[] args) {
        Child c = new Child();
        c.method();
    }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2.3 super() - 조상 클래스의 생성자&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;this()와 마찬가지로 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;super() 역시 생성자&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;super()는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;조상 클래스의 생성자를 호출하는데 사용&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버의 생성과 초기화 작업이 수행되어야하기 때문에 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자손 클래스의 생성자&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;조상 클래스의 생성자가 호출되어야 한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그리고 반드시 생성자의 첫 줄에서 조상클래스의 생성자를 호출해야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;만약 super를 쓰지 않으면 자동적으로 super()를 첫 줄에 추가한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Object를 제외한 모든 클래스의 생성자 첫 줄에는 생성자를 호출해야한다.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;(같은 클래스의 다른 생성자 혹은 조상의 생성자)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;class Point {
    int x;
    int y;

    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
    String getLocation() {
        return &quot;x: &quot; + x + &quot;, y: &quot; + y;
    }
}

class Point3D extends Point {
    int z;
    Point3D(int x, int y, int z) {
        super(x, y);                // 조상 클래스의 생성자
        this.z = z;
    }
    String getLocation() {
        return &quot;x: &quot; + x + &quot;, y: &quot; + y + &quot;, z: &quot; + z;
    }
}

public class Main {
    public static void main(String[] args) {
        Point3D p3 = new Point3D(1,2,3);
    }
}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;3.&amp;nbsp;package와 import&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;3.1 패키지(package)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;패키지란, 클래스의 묶음&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다. 패키지에는 클래스 또는 인터페이스를 포함 시킬 수 있으며, 서로 관련된 클래스들끼리 그룹 단위로 묶어 놓음으로써 클래스를 효율적으로 관리할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스가 물리적으로 하나의 클래스파일(*.class)인 것과 같이 패키지는 물리적으로 하나의 디렉토리이다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;정리:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하나의 소스파일에는 첫 번째 문장으로 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;단 한 번의 패키지 선언&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;만을 허용한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;모든 클래스는 반드시 하나의 패키지에 속해야한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;패키지&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;점(.)을 구분자로 하여 계층구조로 구성&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;패키지&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 물리적으로 클래스 파일(*.class)을 포함하는 하나의 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;디렉토리&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;3.2 패키지의 선언&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;패키지를 선언하는 것은 간단하다. 클래스나 인터페이스의 소스파일(.java)에 다음과 같이 한 줄만 적어주면 된다.&lt;/span&gt;&lt;/div&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;package 패키지명;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;반드시 맨 처음 문장&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이어야 하며 하나의 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;소스파일에 단 한번만 선언&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;될 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;패키지 명은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;소문자로 하는 것을 원칙&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;으로 하고 있다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;쓰지 않는 다면&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 자바에서 기본적으로 제공하는&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; '이름없는 패키지'가 선언&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;된다. =&amp;gt; 패키지를 지정하지 않는 모든 클래스들은 같은 패키지에 속하는 셈이다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;3.3 import문&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;소스코드를 작성할 때 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다른 패키지의 클래스를 사용하려면&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;패키지명이 포함된 클래스 이름&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;을 사용해야한다. 하지만, 매번 패키지명을 붙여서 작성하기란 여간 불편한 일이다.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;따라서 클래스의 코드를 작성하기 전에&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; import문으로 사용하고자 하는 클래스의 패키지를 미리 명시&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;해주면 소스코드에 사용되는 클래스이름에서&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 패키지명은 생략&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있다.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;3.4 import문의 선언&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;import문은 package문 다음에, 그리고 클래스 선언 문 이전에 위치해야 한다.&lt;/span&gt;&lt;/div&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;일반적 순서)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; package문&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; import문&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;3)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 클래스 선언&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;4. 제어자&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;4.1 제어자란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;제어자&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 클래스, 변수 또는 매서드의 선언부에 함께 사용되어 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;부가적인 의미를 부여&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;한다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;접근 제어자:&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; public, protected, default, private&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 외: &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;static, final, abstract, native, transient, synchronized, volatile, strictfp&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;4.2 final - 마지막의, 변경될 수 없는&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;final&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;은 변수에 사용되면 변경할 수 없는 상수가 되며, 매서드에 사용되면 오버라이딩을 할 수 없고 클래스에 사용되면 자신을 확장하는 자손클래스를 정의하지 못하게 된다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;변수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에 사용: 변수는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;상수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;가 됌&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메서드&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에 사용: &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;오버라이딩을 할 수 없음&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에 사용: &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자손클래스를 정의하지 못하게 됌&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;4.3 생성자를 이용한 final 멤버변수 초기화&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;final이 붙은 인스턴스 변수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;생성자를 통해 초기화&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;가 가능하다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;class Card {
  ...
  finanl int NUMBER;
  ...

  Card(int num, ...) {
    Number = num;
    ...
  }
  ...
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;4.5 abstract - 추상의, 미완성의&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;abstract&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;미완성&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;의 의미를 가지고 있다. &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;매서드의 선언부&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;만 작성하고 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;실제 수행 내용은 구현하지 않은 추상매서드를 선언&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하는데 사용된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;또한 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스에 사용&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;되어 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스 내에 추상매서드가 존재한다는 것을 쉽게 알 수 있게 한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;ex)&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;abstract class AbstractTest {   // 추상 클래스(추상매서드를 포함한 클래스)
  abstract void move();         // 추상 매서드(구현부가 없는 매서드)
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;4.6 접근 제어자(accesss modifier)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;접근 제어자&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 멤버 또는 클래스에 사용되어, &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;해당하는 멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;을 한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;public, protected, private은 c++과 동일하지만 default만 새로 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;접근 권한 표)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;margin-left: 2em; text-align: center;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;table class=&quot;txc-table&quot; width=&quot;464&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; style=&quot;border:none;border-collapse:collapse;;font-family:&quot; 맑은=&quot;&quot; 고딕&quot;,=&quot;&quot; sans-serif;font-size:13px&quot;=&quot;&quot; align=&quot;center&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;width: 92px; height: 24px; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;제어자&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 92px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-top: 1px solid rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;같은 클래스&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 92px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-top: 1px solid rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;같은 패키지&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 93px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-top: 1px solid rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자손 클래스&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 93px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-top: 1px solid rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;전&amp;nbsp; &amp;nbsp;체&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 92px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;public&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 92px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); background-color: rgb(181, 178, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 92px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); background-color: rgb(181, 178, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 93px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); background-color: rgb(181, 178, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 93px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); background-color: rgb(181, 178, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:92;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;protected&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 92px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); background-color: rgb(181, 178, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 92px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); background-color: rgb(181, 178, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 93px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); background-color: rgb(181, 178, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 93px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:92;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;default&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 92px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); background-color: rgb(181, 178, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 92px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); background-color: rgb(181, 178, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 93px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 93px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:92;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;private&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 92px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); background-color: rgb(181, 178, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:92;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 93px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 93px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;4.7 접근 제어자를 이용한 캡슐화&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스 내부에 선언된 데이터를 보호하기 위해 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;접근 제어자를 통해 캡슐화를 적용&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;4.8 생성자의 접근 제어자&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;생성자에 접근 제어자&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 사용함으로써 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인스턴스의 생성을 제어&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;생성자에 private을 지정하면 외부에서는 그와 같은 방식으로 생성을 할 수는 없지만 다른 생성자가 private으로 지정된 생성자를 이용할 수는 있다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Java/Java의 정석 읽고 정리</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/20</guid>
      <comments>https://psyhm.tistory.com/20#entry20comment</comments>
      <pubDate>Tue, 29 May 2018 17:43:46 +0900</pubDate>
    </item>
    <item>
      <title>java의 정석 6강. 객체지향프로그래밍1</title>
      <link>https://psyhm.tistory.com/19</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;객체지향은 c++과 유사한 점이 많으니 특징과 다른 점만 짚고 넘어가도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size:18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1. 변수와 메서드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size:18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1.1 선언 위치에 따른 변수의 종류&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;변수 종류: 클래스 변수, 인스턴스 변수, 지역 변수&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스 변수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 멤버변수 중 static이 붙은 변수&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인스턴스 변수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 멤버변수 중 static이 붙지 않은 변수&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;지역 변수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 멤버변수를 제외한 나머지 변수&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;class Variable{
  int instanceValue;          // 인스턴스 변수
  static int classValue;      // 클래스 변수

  void method1() {
    int localValue = 0;       // 지역 변수
  }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1) &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인스턴스 변수&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스 영역&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에서 선언&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인스턴스가 생성되었을 때&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 생성&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;인스턴스는 독립적인 저장공간을 가지므로 인스턴스마다 서로 다른 인스턴스 변수를 가질 수 있다.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2) 클래스 변수&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스 영역&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에서 선언&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스가 로딩될 때&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 생성, 프로그램이 종료될 때까지 유지된다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클래스 변수는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;모든 인스턴스가 공통된 저장공간을 공유&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하게 된다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;public을 앞에 붙이면 같은 프로그램 내에 어디서나 접근할 수 있는 전역변수의 성격을 갖는다.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;3) 지역 변수&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;매서드 내에 선언되어 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;매서드 내에서만 사용 가능&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;매서드가 종료되면 소멸&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.2 매서드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;매서드는 어떤 작업을 수행하기 위한 명령문의 집합이다.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.3 JVM의 메모리 구조&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;응용&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;프로그램이 실행되면 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;JVM&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;운영체제로부터&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 프로그램을 수행하는데 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;필요한 메모리를 할당받고&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; JVM은 이 메모리를 용도에 따라 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;여러 영역으로 나누어 관리&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그 중 주요 런타임 데이터 영역에 대해 알아보자.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/990C3C3A5B0BC23B07&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F990C3C3A5B0BC23B07&quot; width=&quot;500&quot; height=&quot;281&quot; filename=&quot;ilovepdf_com.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8; text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1) Method 영역&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- 프로그램 실행 중 어떤 클래스가 사용되면 해당 &lt;b&gt;class 파일&lt;/b&gt;을 읽어 &lt;b&gt;클래스에 대한 정보(클래스 데이터)&lt;/b&gt;를 이곳에 &lt;b&gt;저장&lt;/b&gt;한다. 클래스 변수&lt;b&gt;(class variable) &lt;/b&gt;또한 저장한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2)&amp;nbsp;힙 영역&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- &lt;b&gt;인스턴스가 생성되는 공간&lt;/b&gt;. &lt;b&gt;인스턴스 변수(instance variable)&lt;/b&gt;들이 생성되는 공간이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;3)&amp;nbsp;호출스택&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;- 호출스택은 &lt;b&gt;메서드 작업에 필요한 메모리 공간을 제공&lt;/b&gt;한다. 메서드가 호출되면, 호출스택에 호출된 메서드를 위한 메모리가 할당되며, 이 메모리는 메서드가 작업을 수행하는 동안 &lt;b&gt;지역변수&lt;/b&gt;들과 &lt;b&gt;연산의 중간결과&lt;/b&gt; &lt;b&gt;등을 저장&lt;/b&gt;하는데 사용된다. 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1.4&amp;nbsp;기본형 매개변수와 참조형 매개변수&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;자바에서는 메서드를 호출할 때 매개변수로 지정한 값을 메서드의 매개변수에 복사해서 넘겨준다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;매개변수 타입&lt;/b&gt;이 &lt;b&gt;기본형&lt;/b&gt;이면 &lt;b&gt;기본형 값이 복사&lt;/b&gt;되지만,&lt;b&gt; 참조형&lt;/b&gt;이면 &lt;b&gt;인스턴스의 주소가 복사&lt;/b&gt;된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/996DD6385B0BC2D126&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F996DD6385B0BC2D126&quot; width=&quot;500&quot; height=&quot;281&quot; filename=&quot;ilovepdf_com-1.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;기본형 메서드 값 변경: 1&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;참조형 메서드 값 변경: 10&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;위의 사진을 보면 알 수 있듯이 &lt;b&gt;기본형 매개변수&lt;/b&gt;는 값을 복사하기 때문에 복&lt;b&gt;사된 데이터가 값이 바뀔 뿐&lt;/b&gt; 원래의 값은 바뀌지 않지만 &lt;b&gt;참조형 매개변수&lt;/b&gt;는 주소값을 복사하기 때문에 &lt;b&gt;원래의 데이터에 접근해서 값을 변경&lt;/b&gt;할 수가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2. 생성자&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2.1 생성자란&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;인스턴스가 생성될 때 호출되는 &lt;b&gt;인스턴스 초기화 메서드&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Card 클래스의 인스턴스를 생성하는 코드를 예를 들어, 수행되는 과정을 단계별로 나누면 다음과 같다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;Card c = new Card();

1. 연산자 new에 의해 메모리(heap)에 Card 클래스의 인스턴스가 생성된다.
2. 생성자 Card()가 호출되어 수행
3. 연산자 new의 결과로, 생성된 Card의 인스턴스의 주소가 반환되어 참조변수 c에 저장.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2.2&amp;nbsp;생성자에서 다른 생성자 호출하기. - this(), this&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;생성자 간에 서로 호출하기 위해서는 다음 두 조건을 만족시켜야한다.&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;생성자의 이름으로 클래스이름 대신 &lt;b&gt;this&lt;/b&gt;를 사용한다.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;한 생성자에서 다른 생성자를 호출할 때는 &lt;b&gt;반드시 첫 줄&lt;/b&gt;에서만 호출이 가능하다.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;class Car {
    String color;
    String gearType;
    int door;

    Car() {
        this(&quot;white&quot;, &quot;auto&quot;, 4);
    }
    Car(String color) {
        this(color, &quot;auto&quot;, 4);
    }
    Car(String color, String gearType, int door) {
        this.color = color;
        this.gearType = gearType;
        this.door = door;
    }
}

public class Main {
    public static void main(String[] args) {
        Car c1 = new Car();
        Car c2 = new Car(&quot;blue&quot;);

        System.out.println(&quot;c1의 color = &quot; + c1.color + &quot;, gearType = &quot; + c1.gearType + &quot;, door = &quot; + c1.door);
        System.out.println(&quot;c2의 color = &quot; + c2.color + &quot;, gearType = &quot; + c2.gearType + &quot;, door = &quot; + c2.door);
    }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2.3 생성자를 이용한 인스턴스 복사&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;복사생성자 만들 듯이 만들면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;3. 변수의 초기화&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;3.1 변수의 초기화&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;맴버변수와 배열의 초기화는 선택적(디폴트값으로 초기화 됨)이지만, &lt;b&gt;지역 변수&lt;/b&gt;는 반드시 &lt;b&gt;사용하기 전에 초기화를 해주어야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;3.2 명시적 초기화&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;변수를 선언과 동시에 초기화 하는 것&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;int door = 4;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;3.3 초기화 블럭(initialization block)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;초기화 블럭은 두가지 종류가 있다.&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;클래스 초기화 블럭&lt;/b&gt;: 클래스 변수의 복잡한 초기화에 사용.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;인스턴스 초기화 블럭&lt;/b&gt;: 인스턴스 변수의 복잡한 초기화에 사용된다.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;둘 다 &lt;b&gt;클래스 내에 블럭{}을 만들고&lt;/b&gt;&amp;nbsp;그 안에 코드를 작성하면 된다.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;클래스 초기화 블럭&lt;/b&gt;은 블럭{} 앞에 &lt;b&gt;static&lt;/b&gt;을 붙이면 된다.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;클래스 초기화 블럭&lt;/b&gt;은 클래스가 &lt;b&gt;메모리에 처음 로딩&lt;/b&gt;될 때 &lt;b&gt;한번만 수행&lt;/b&gt;되며, &lt;b&gt;인스턴스 초기화 블럭&lt;/b&gt;은 생성자와 같이 &lt;b&gt;인스턴스를 생성할 때마다&lt;/b&gt; &lt;b&gt;수행&lt;/b&gt;된다.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그리고 &lt;b&gt;생성자보다 인스턴스 초기화 블럭이 먼저 수행&lt;/b&gt;된다.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;예제)&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span&gt;public class Main {
    static {
        System.out.println(&quot;static { }&quot;);
    }
    {
        System.out.println(&quot;{ }&quot;);
    }

    public Main() {
        System.out.println(&quot;생성자&quot;);
    }

    public static void main(String[] args) {
        System.out.println(&quot;Main mn = new Main();&quot;);
        Main mn = new Main();

        System.out.println(&quot;Main mn2 = new Main();&quot;);
        Main mn2 = new Main();
    }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출력:&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;static { }&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Main mn = new Main();&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{ }&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;생성자&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Main mn2 = new Main();&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{ }&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;생성자&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Java/Java의 정석 읽고 정리</category>
      <category>java</category>
      <category>JVM 메모리 구조</category>
      <category>This</category>
      <category>객체지향</category>
      <category>변수 종류</category>
      <category>생성자</category>
      <category>자바</category>
      <category>자바의 정석</category>
      <category>프로그래밍</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/19</guid>
      <comments>https://psyhm.tistory.com/19#entry19comment</comments>
      <pubDate>Mon, 28 May 2018 18:08:23 +0900</pubDate>
    </item>
    <item>
      <title>java의 정석 5강. 배열</title>
      <link>https://psyhm.tistory.com/18</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;배열은 c++과 유사한 점이 많으니 특징과 다른 점만 짚고 넘어가도록 하겠다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.1 배열의 생성&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;배열을 생성하기 위해서는 연산자 &lt;b&gt;new&lt;/b&gt;와 함께 배열의 &lt;b&gt;타입&lt;/b&gt;과 &lt;b&gt;크기&lt;/b&gt;를 &lt;b&gt;지정&lt;/b&gt;해 주어야 한다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;int[] data;
data = new int[5];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.2 배열의 초기화&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;배열은 &lt;b&gt;생성과 동시에&lt;/b&gt; 자동적으로 자신의 타입에 해당하는 &lt;b&gt;기본값으로 초기화&lt;/b&gt;된다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;int[] data = new int[5];
System.out.println(data[0]);    // 0&lt;/span&gt;&lt;font face=&quot;맑은 고딕, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 16px; white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;변수의 타입에 따른 기본값은 다음과 같다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;table class=&quot;txc-table&quot; width=&quot;464&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; style=&quot;border:none;border-collapse:collapse;;font-family:&quot; 맑은=&quot;&quot; 고딕&quot;,=&quot;&quot; sans-serif;font-size:13px&quot;=&quot;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;width: 232px; height: 24px; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;자료형&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 232px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-top: 1px solid rgb(204, 204, 204); background-color: rgb(217, 229, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;기본&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;값&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 232px; height: 25px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;boolean&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 232px; height: 25px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;false&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;char&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;'\u0000'&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;byte&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;0&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;short&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;0&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;int&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;0&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;long&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;0L&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;float&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;0.0f&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;double&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;0.0 or 0.0d&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;참조형 변수&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width:232;height:24;border-bottom:1px solid #ccc;border-right:1px solid #ccc;;&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;null&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;배열을 초기화 하는데 두 가지 방법을 제공한다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;int[] data = {100, 90, 80, 70};            // 1번
int[] data = new int[]{100, 90, 80, 70}    // 2번&lt;/span&gt;&lt;font face=&quot;맑은 고딕, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 16px; white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;두 문장이 같은 결과를 낼 때도 있지만 경우에 따라 2번과 같은 초기화가 필요하다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;아래의 코드에서 볼 수 있듯이 선언과 초기화를 따로 해야하는 경우에는 반드시 2번 방식으로 배열을 초기화해야 한다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;int[] data;
data = {100, 90, 80, 70};             // 오류 발생!!

int[] data2;
data2 = new int[4]{100, 90, 80, 70};  // okay!!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.3 다차원 배열&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;2차원 배열의 선언방법은 다음과 같다.&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;int[][] data;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;1차원 배열에서와 같이 중괄호{}를 이용해서 2차원 배열의 생성과 초기화를 동시에 할 수도 있다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;int[][] data = new int [][] {
  {100, 100, 100},
  {20, 20, 20},
  {50, 50, 50},
  {60, 30, 80},
  {50, 40, 50}
};                  // int[][] data = new int[5][3];으로 생성된다.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.4 배열의 복사&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;배열은 한번 생성하면 그 크기를 변경할 수 없기 때문에 더 많은 저장공간이 필요하다면 보다 큰 배열로 새로 만들고 이전 배열로부터 내용을 복사해야한다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;배열을 복사하기 위해 for문을 돌리거나 System 클래스의 arraycopy를 사용하면 된다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;for문은 대충 알 것이고 arraycopy는 다음과 같이 사용하면 된다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-java line-numbers&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;int[] number = {1, 2, 3, 4, 5};
int[] newNumber = new int[10];

// src: 복사할 원본 배열, dst: 복사할 배열, pos: 복사를 시작할 위치, length: src의 복사 길이
// arraycopy(src, src.pos, dst, dst.pos, length)
System.arraycopy(number, 0, newNumber, 0, number.length);

// =&amp;gt; number[0]에서 number.length 개의 데이터를  newNumber[0]부터 복사&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Java/Java의 정석 읽고 정리</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/18</guid>
      <comments>https://psyhm.tistory.com/18#entry18comment</comments>
      <pubDate>Sun, 27 May 2018 18:35:12 +0900</pubDate>
    </item>
    <item>
      <title>java의 정석 2강. 변수</title>
      <link>https://psyhm.tistory.com/17</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;변수는 c++과 유사한 점이 많으니 특징과 다른 점만 짚고 넘어가도록 하겠다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1. 변수의 타입&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;기본형&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;실제 값&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;을 저장하는 데이터 타입&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;참조형&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 어떤 값이 저장되어 있는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;주소를 값&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;으로 갖는 데이터 타입(실제 연산 불가)&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;※ 기본형 종류: boolean, char, byte, short, int, long, float, double&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;참조형은 기본형이 아닌 모든 타입&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1.1 기본형&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;논리형, 문자형, 정수형, 실수형이 존재&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;논리형&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: boolean&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;문자형&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: char&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;정수형&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: byte, short, int, long&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;실수형&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: float, double&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.2 논리형 boolean&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;값: true or false&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;크기: 1 byte&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.3 문자형 char&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;자바에서는 &lt;b&gt;유니코드&lt;/b&gt; 문자체계를 사용하기 때문에 &lt;b&gt;char 크기가 2 bytes&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;short도 2 bytes인데 둘의 차이점은 char는 unsigned고 short는 signed이다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;String 클래스를 이용하면 문자열을 저장할 수 있다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;자바에서는 문자열을 &lt;b&gt;덧셈 연산자를 이용&lt;/b&gt;하여 문자열을 결합할 수 있다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;String name = &quot;Ja&quot;+&quot;va&quot;;&lt;/b&gt;&amp;nbsp; // name에는 &quot;Java&quot;가 저장&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;String은 &lt;b&gt;Immutable&lt;/b&gt; 클래스이기 때문에 heap 영역에서 &lt;b&gt;변경 불가능&lt;/b&gt;합니다.(재할당을 못하는 건 아님)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;즉, String test = &quot;abc&quot;에서 a = &quot;def&quot;를 했을 경우 test가 처음에 참조하고 있는 &quot;abc&quot;값이 &quot;def&quot;로 변경되는 것이 아니라 &quot;def&quot; 객체를 새로 생성한 뒤 test가 그 주소를 참조하는 것이다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;//Immutable 클래스에 대해서는 나중에 다시 찾아보도록 하겠습니다.&lt;/span&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(140, 140, 140);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.4 정수&lt;/span&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;형&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;byte&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; (1 바이트) &amp;lt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;short&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; (2 바이트) &amp;lt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;int&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; (4 바이트) &amp;lt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;long&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; (8 바이트)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;정수형은 기본형이 int형&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1.5 실수형&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;float&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; (4 바이트) &amp;lt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;double&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; (8 바이트)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;부동소수점 방식으로 실수를 저장&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;실수형은 double이 기본형임&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;따라서 float에 소수를 저장하기 위해서는 3.14f 이렇게 저장해야함.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;2. 형&lt;/span&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;변환&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;변수 또는 리터럴의 타입을 다른 타입으로 변환하는 것이 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;형&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;변환&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 또는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;캐스팅&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이라고 한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음에 공부할 것: &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Immutable 클래스에 대해 공부하기.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Java/Java의 정석 읽고 정리</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/17</guid>
      <comments>https://psyhm.tistory.com/17#entry17comment</comments>
      <pubDate>Sun, 27 May 2018 16:14:21 +0900</pubDate>
    </item>
    <item>
      <title>java의 정석 1강. 자바를 시작하기 전에</title>
      <link>https://psyhm.tistory.com/16</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;대학교 1학년 시절, c++로 첫 개발을 시작했을 때는 검은색 화면에서 무엇인가 컴퓨터로 계산한다는 점이 매우 매력적으로 다가왔다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;하지만 C++이란 러닝커브는 매우매우 극한에 달했고 필자는 c++하다가 너무 힘들어서 한동안 스크립트 언어인 자바스크립트와 node.js를 배웠다. 하지만 그들은 뭔가 언어적으로 배워간다기보다는 남이 만든 것을 내가 잘 쓰는 것을 배우는 것이었다. 뿐만 아니라 c++보다 언어적으로 체계가 있는 것도 아니었다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;그래서 결국 c++보다는 좀 쉽고 자바스크립트보다는 체계가 매우 잡힐 뿐만 아니라 생산성도 좋고, 우리나라에서 제일 많이 쓰는 자바를 배우게 되었다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;이 포스트의 목적은 자바의 정석 책을 읽으면서 공부했던 부분을 머릿 속 더욱 더 깊이 기억할 수 있게 정리하는 목적이다. 따라서 글이 매우 주관적일 수가 있다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1.1 자바 언어의 특징&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1) 운영체제에 독립적이다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자바 운영 프로그램&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;은 운영체제나 하드웨어가 아닌 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자바가상머신(jvm)을 통해서만 통신&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하고 jvm이 자바 응용프로그램으로부터 전달받은 명령을 해당 운영체제가 이해할 수 있도록 변환하여 전달한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;따라서&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 자바 응용프로그램&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;은&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 운영체제에 독립적&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이지만 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;jvm은 종속적&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이기 때문에 썬에서는 플랫폼마다 다른 jvm을 제공하고 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2) 객체지향언어이다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자바는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;상속&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;, &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;캡슐화&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;, &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다형성이 &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;잘 적용된 순수한 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;객체지향 언어&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;라는 평가를 받고있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;3) 배우기 쉽다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;자바의 간단명료한 객체지향적 설계는 사용자들이 객체지향개념을 보다 쉽게 이해하고 활용할 수 있도록 하여 객체지향 프로그래밍의 저변확대에 크게 기여했다. (물론 스크립트 언어보다는 배우는 게 쉽지는 않다.)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;4) 자동 메모리 관리&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자바 응용프로그램이 돌아가면 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;가비지컬렉터(garbage collector)가 자동적으로 메모리를 관리&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;해주기 때문에 코드 단에서 메모리를 관리할 필요가 없다.&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 다소 비효율적&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인 면모가 있지만 요즘 가비지 컬렉터 성능이 괜찮다고 한다. (이 부분에 대해서는 많은 공부가 필요할 것 같다.)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;5) 네트워크와 분산처리를 지원&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;6) 멀티스레드를 지원한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자바에서 개발되는 멀티쓰레드 프로그램은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;시스템에 관계없이&amp;nbsp;구현가능&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하며 관련된 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;라이브러리가 제공&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;되므로 구현이 쉽다. &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;스케줄링은 자바 인터프리터가 담당&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하게 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;7) 동적 로딩을 지원한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자바는 동적 로딩을 지원하기 때문에 실행 시에 모든 클래스가 로딩되지 않고 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;필요한 시점에서 클래스를 로딩&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하여 사용할 수 있다는 장점이 있다. 이 장점이 프로그램 유지 보수에 큰 장점이라 스프링이 이러한 특징을 잘 살려서 많은 웹 서비스에서 스프링이 서버 개발로써의 역할을 수행한다고 알고있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1.2 자바로 프로그램 작성하기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;JVM을 직역하면 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;'자바를 실행하기 위한 가상 기계'&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;라고 할 수 있다. 자바로 작성된 어플리케이션은 모두 이 가상 컴퓨터(JVM)에서만 실행되기 때문에, &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자바 어플리케이션&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 실행되기 위해서는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;반드시 JVM이 필요&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자바의 코드는 JVM을 거치는 이러한 특징 때문에, 그리고 하드웨어에 맞게 완전히 컴파일된 상태가 아니고 실행 시에 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인터프리터&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;가 돌기 때문에 속도가 느리다는 단점이 있다. 하지만 요즘엔 JIT 컴파일러와 최적화된 기술이 적용되어서 많이 완화되었다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8; text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99E188425B065F7E14&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99E188425B065F7E14&quot; width=&quot;500&quot; height=&quot;314&quot; filename=&quot;jvm.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2.1 자바 프로그램 작성하기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;java 파일을 만들어서 프로그램을 돌리기까지는 다음과 같은 과정을 겪게 된다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;자바파일 -&amp;gt; javac 컴파일 -&amp;gt; 클래스파일 생성 -&amp;gt; java Run&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;세세하게 나누어 보자.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 자바 파일 작성(*.java)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 자바 파일 컴파일(compile): javac가 컴파일을 함 -&amp;gt; class 파일(Bytecode) 생성&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;3)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; Run 과정: Class 파일 안의 main함수를 찾아 실행하고 JVM을 사용함. JVM은 Bytecode(즉, class 파일 내용)을 인터프리터 방식으로 프로그램을 한 줄씩 바로바로 실행한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;(1) &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;class loader가 class 파일들을 메모리로 load 하고, 또한 실행하려는 프로그램에 필요한 다른 class 파일들도 load 한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; (2)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; class 파일들이 load되면 bytecode verifier가 load된 class 파일들의 보안을 검사한다.(파일 형식, 악성코드 검사)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; (3)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; JVM이 특정 프로그램의 bytecode들을 읽어내 실행한다. 초기에는 인터프리터로써 역할을 수행했지만 현재 JIT 컴파일러를 추가하였다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Java/Java의 정석 읽고 정리</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/16</guid>
      <comments>https://psyhm.tistory.com/16#entry16comment</comments>
      <pubDate>Thu, 24 May 2018 16:09:46 +0900</pubDate>
    </item>
    <item>
      <title>nodejs fs 모듈 open 함수, stat 함수, read 함수. 파일 중간 위치에서 파일 읽기</title>
      <link>https://psyhm.tistory.com/15</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;nodejs의 기본 모듈 중 하나인 &lt;b&gt;fs는 file system의 약어&lt;/b&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;말 그대로 fs 모듈을 이용해 &lt;/span&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;파일 시스템에 사용되는 기능들을 사용&lt;/b&gt;할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;fs는 &lt;b&gt;표준 POSIX 함수와 비슷&lt;/b&gt;하게 만들어놨기 때문에 예전에 리눅스 프로그래밍을 배운 필자로서는 fs모듈이 매우 흥미롭게 다가왔다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;모든 파일 시스템 연산은 &lt;b&gt;동기식&lt;/b&gt;과 &lt;b&gt;비동기식&lt;/b&gt;이&lt;b&gt; 존재&lt;/b&gt;하는데 비동기식은 모두 연산이 완료되었을 시 마지막 argument에 callback으로 전달한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;callback의 첫번째 argument는 예외처리가 담긴 변수인데 예외가 없을 시 undefined나 null이 반환된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;동기식의 오류처리는 try/catch로 잡을 수 있다고 하는데 nodejs에서 동기식을 사용한다는 것은 매우 비효율적이므로 따로 적지는 않겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size:18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;fs.stat&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;fs.stat&lt;/b&gt;을 살펴보도록 하자.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;먼저 &lt;b&gt;stat 객체&lt;/b&gt;는 &lt;b&gt;파일에 대한 정보&lt;/b&gt;들이 담겨있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;&lt;span&gt;Stats {
  dev: 2114,                       // ID of device containing file
  ino: 48064969,                 // inode number
  mode: 33188,                  // protection
  nlink: 1,                           // number of hard links
  uid: 85,                           // user ID of owner
  gid: 100,                         // group ID of owner
  rdev: 0,                           // device ID (if special file)
  size: 527,                        // total file size, in bytes
  blksize: 4096,                  // blocksize for file system I/O
  blocks: 8,                       //  number of 512B blocks allocated
  atimeMs: 1318289051000.1,                       // time of last access in milliseconds
  mtimeMs: 1318289051000.1,                      // time of last modification in milliseconds
  ctimeMs: 1318289051000.1,                       // time of last status change in milliseconds
  birthtimeMs: 1318289051000.1,                   // The timestamp indicating the creation time of this file in milliseconds
  atime: Mon, 10 Oct 2011 23:24:11 GMT,      // time of last access
  mtime: Mon, 10 Oct 2011 23:24:11 GMT,     //  time of last modification
  ctime: Mon, 10 Oct 2011 23:24:11 GMT,      // time of last status change
  birthtime: Mon, 10 Oct 2011 23:24:11 GMT   // The timestamp indicating the creation time of this file
 }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출처:&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://nodejs.org/api/fs.html#fs_fs_stat_path_callback&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;https://nodejs.org/api/fs.html#fs_fs_stat_path_callback&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://man7.org/linux/man-pages/man2/stat.2.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;http://man7.org/linux/man-pages/man2/stat.2.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;fs.stat의 사용방법은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;fs.stat(path, callback)&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;path&lt;/b&gt;: 파일 정보를 살펴 볼 파일의 경로&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;callback&lt;/b&gt;: 콜백&amp;nbsp;함수&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;- &lt;b&gt;err&lt;/b&gt;: 에러 객체&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;- &lt;b&gt;stats&lt;/b&gt;: 위의 stat 객체&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;example)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;&lt;span&gt;fs.stat('./test.txt', function(error, stats) {
    console.log(&quot;파일 크기: &quot;, stats.size);
});
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;여기서는 파일의 크기를 가져오기 위해서 사용했다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;다음으로 &lt;b&gt;fs.open&lt;/b&gt;을 살펴보자.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b style=&quot;font-size: 24px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;fs.open&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;fs.open&lt;/b&gt;은 비동기로 파일을 open할 때 사용하는 함수이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;fs.open을 사용하는 방법은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;fs.open(path, flags[,mode], callback)&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;path&lt;/b&gt;:&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;파일 정보를 살펴 볼 파일의 경로&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;flags&lt;/b&gt;: 파일을 open할 때의 option&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;mode&lt;/b&gt;(옵션): 파일 퍼미션 설정(파일을 생성할 때만 설정하는 옵션)&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;callback&lt;/b&gt;: callback함수&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;- &lt;b&gt;err&lt;/b&gt;: 에러 객체&lt;br /&gt;- &lt;b&gt;fd&lt;/b&gt;: 파일 디스크럽터&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;flags&lt;/b&gt;에 대한 설명은 다음과 같다.&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;&lt;span&gt;flag: 
  'r' - 읽기로 열기. 파일이 존재하지 않으면 에러발생.
  'r+' - 읽기/쓰기로 열기. 파일이 존재하지 않으면 에러발생.
  'w' - 쓰기로 열기. 파일이 존재하지 않으면 만들어지고, 파일이 존재하면 지우고 처음부터 씀.
  'w+' - 읽기/쓰기로 열기. 파일이 존재하지 않으면 만들어지고, 파일이 존재하면 처음부터 씀.
  'a' - 추가 쓰기로 열기. 파일이 존재하지 않으면 만들어짐.
  'a+' - 파일을 읽고/추가쓰기모드로 열기. 파일이 존재하지 않으면 만들어짐.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b style=&quot;font-size: 24px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;fs.read&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;fd(파일 디스크럽터)를 이용해 특정한 파일의 데이터를 읽는 함수이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;fs.read&lt;/b&gt;를 사용하는 방법은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;fs.read(fd, buffer, offset, length, position, callback)&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;fd&lt;/b&gt;: 파일 디스크럽터. fs.open함수에서 얻을 수 있다.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;buffer&lt;/b&gt;: 데이터가 쓰여질 버퍼&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;offset&lt;/b&gt;: 데이터가 쓰여질 버퍼의 시작 위치이다.&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;length&lt;/b&gt;: 데이터를 읽을 문자열의 크기이다.&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;position&lt;/b&gt;: 데이터를 읽어들일 파일의 읽을 위치를 지정한다. 만약 값이 null이면 파일의 현재 위치에서부터 읽기 시작한다.&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;callback&lt;/b&gt;: callback 함수&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;- &lt;b&gt;err&lt;/b&gt;: 에러 객체&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;- &lt;b&gt;bytesRead&lt;/b&gt;: 읽어들인 문자열 길이&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;- &lt;b&gt;buffer&lt;/b&gt;: 읽은 문자열이 담긴 버퍼&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;따라서 만약 파일의 일부분만 읽어오고 싶다면 다음과 같은 코드를 작성하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;fs.stat('test.txt', function(error, stats) {
    fs.open('test.txt', &quot;r&quot;, function(error, fd) {  // 읽기 모드로 test.txt 파일 열기
        console.log(&quot;파일의 크기: &quot;, stats.size);
        if(error) console.log(&quot;error: &quot;, error);    // 에러 있을 시 에러 출력
        let buffer = new Buffer(100);        // 버퍼의 크기를 100으로 함
        fs.read(fd, buffer, 0, buffer.length, 84, function(error, bytesRead, buffer) {
            // buffer에 담을 위치 0, txt 파일 시작 위치는 84
            let data = buffer.toString(&quot;utf8&quot;);
            console.log(data);
            console.log(&quot;읽은 버퍼 크기: &quot;, bytesRead);
        });
    });
});&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Node.js</category>
      <category>fs.open</category>
      <category>fs.read</category>
      <category>fs.stat</category>
      <category>node.js</category>
      <category>nodejs</category>
      <category>노드</category>
      <category>모듈</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/15</guid>
      <comments>https://psyhm.tistory.com/15#entry15comment</comments>
      <pubDate>Mon, 21 May 2018 19:34:26 +0900</pubDate>
    </item>
    <item>
      <title>QT 정리 - QGraphicsItem 클래스의 boundingRect 함수</title>
      <link>https://psyhm.tistory.com/14</link>
      <description>&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;QGraphicsItem 클래스의 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;boundingRect &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;함수는 QGraphicsScene에 addItem된&amp;nbsp; QGraphicsItem들의 직사각형 모양의 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;외부 경계를 정하는 함수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;QGraphicsView 안에 존재하는&amp;nbsp; QGraphicsScene 안의 이벤트를 감지한다. 이때 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;QGraphicsView&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 item들을&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 다시 paint하는 지 결정&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;해야하는데 이때&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;boundingRect에서 정한 아까의 직사각형이&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;scene 범위 외에 존재한다면 그 item을 paint하지 않는다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;그래서 boundingRect를 잘못 지정한다면 화면에 item이 없어졌다가 다시 생기는 현상을 목격할 수도 있다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;참고로 사진에 보이는 선들은 QGraphicsItem을 상속 받았다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;문서&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: &lt;/span&gt;&lt;a href=&quot;http://doc.qt.io/archives/qt-4.8/qgraphicsitem.html#boundingRect&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(189, 189, 189); background-color: rgb(255, 255, 255);&quot;&gt;qt docs&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;참고사진&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;:&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/992E83395AF95DE50F&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F992E83395AF95DE50F&quot; width=&quot;500&quot; height=&quot;282&quot; filename=&quot;20180514_185815.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>C++언어/QT framework</category>
      <category>boundingRect</category>
      <category>C++</category>
      <category>QGraphicsItem</category>
      <category>QGraphicsView</category>
      <category>Qt</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/14</guid>
      <comments>https://psyhm.tistory.com/14#entry14comment</comments>
      <pubDate>Mon, 14 May 2018 19:00:42 +0900</pubDate>
    </item>
    <item>
      <title>C++ explicit 키워드와 암시적 묵시적 형변환</title>
      <link>https://psyhm.tistory.com/13</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 12pt; position: relative; color: rgb(0, 0, 0); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;간단히 말하면&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;font-weight: 600; position: relative; background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;explicit&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 12pt; position: relative; color: rgb(0, 0, 0); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&amp;nbsp;용어는&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;font-weight: 600; position: relative; background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;묵시적 형변환을 할 수 없게 만들고 명시적인 형변환만 가능하도록 만드는 것&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;이다.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;그렇다면 이렇게 굳이 귀찮게 하는 이유는 무엇일까? 묵시적으로 형변환을 가능하게 만들면 프로그래머가 개발할 때 의도 또는 생각지도 않는 오류가 발생할 수 있기 때문이다.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;예를 들어,&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;
&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp line-numbers&quot;&gt;class Point{ 
private:
    int y; 
public: 
  Point(int yy = 0) 
  { 
    y = yy; 
  } 
  void Print() const{ 
    cout &amp;lt;&amp;lt; y &amp;lt;&amp;lt; endl; 
  } 
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;이런 클래스가 있다고 가정했을 경우&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;
&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp line-numbers&quot;&gt;int main(){ 
  Point pt; 
  pt.Print();
}&lt;/code&gt;&lt;/pre&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;결과 :&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;font-weight: 600; position: relative; background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;이 출력된다.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;이때, main함수를 밑의 예제로 바꾼다면&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp line-numbers&quot;&gt;int main(){
  Point pt;
  pt = 10; 
  pt.Print();
}&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei; font-size: 16px;&quot;&gt;결과:&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei; font-size: 16px; font-weight: 600;&quot;&gt;10&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;이 출력되는 경우를 볼 수가 있다.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;color: rgb(0, 0, 0); font-size: 12pt; position: relative;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;color: rgb(0, 0, 0); font-size: 12pt; position: relative;&quot;&gt;이 경우에는 컴파일러가&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;font-weight: 600; position: relative; background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;class Point&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;color: rgb(0, 0, 0); font-size: 12pt; position: relative;&quot;&gt;에&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;font-weight: 600; position: relative; background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;int 형 변수를 할당하는 할당 연산자를 찾게 되는데&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;color: rgb(0, 0, 0); font-size: 12pt; position: relative;&quot;&gt;&amp;nbsp;보시다시피 없으므로 적절한 녀석을 찾다가&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;font-weight: 600; position: relative; background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;int를 매개변수를 갖는 생성자를 찾게된다&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;color: rgb(0, 0, 0); font-size: 12pt; position: relative;&quot;&gt;.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;color: rgb(0, 0, 0); font-size: 12pt; position: relative;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;color: rgb(0, 0, 0); font-size: 12pt; position: relative;&quot;&gt;그리하여 컴파일러는&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;font-weight: 600; position: relative; background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;pt = 10;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;color: rgb(0, 0, 0); font-size: 12pt; position: relative;&quot;&gt;을&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;font-weight: 600; position: relative; background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;pt = Point(10);&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;color: rgb(0, 0, 0); font-size: 12pt; position: relative;&quot;&gt;으로 변환시켜서 임시 객체인 Point(10)을&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;font-weight: 600; position: relative; background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;복사 할당 연산자를 호출해 pt에 대입&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;시켜버린다. 그래서 결과적으로 pt의 y값은 10이 되어 버린다.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;position: relative;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;position: relative;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;이런 황당한 경우를 막기 위해 생겨난 키워드가 explicit 이다. 생성자 옆에 explicit을 붙이게 되면&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp line-numbers&quot;&gt;class Point{ 
private:
  int y; 
public: 
  explicit Point(int yy = 0) 
  { 
    y = yy; 
  } 
  void Print() const{ 
    cout &amp;lt;&amp;lt; y &amp;lt;&amp;lt; endl; 
  } 
};

int main(){ 
  Point pt;
  // pt = 10;  // 에러 
  pt = Point(10); 
  pt.Print();
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 12pt; position: relative; color: rgb(0, 0, 0); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;와 같이&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;font-weight: 600; position: relative; background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;pt = 10;인 묵시적 변환은 빨간줄&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 12pt; position: relative; color: rgb(0, 0, 0); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;을 그어버리고&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;font-weight: 600; position: relative; background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;pt = Point(10);만 가능&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;하게 만든다.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;위와 같은 경우처럼 explicit을 사용하는 이유는 프로그래머의 실수를 막기 위함으로 생각하면 된다.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;그리고 저렇게 pt = Point(10); 같은 경우 여러가지 테스트를 해보았는데&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;Point pt;일때와 pt = Point(10); 일때의 주소값은 동일하다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;pt = Point(10); 를 실행할 때 내부적으로 Point(10)인 임시 객체를 메모리에 따로 생성 후에 복사 할당 연산자를 실행하게 되면 메모리에 올려진 pt에 int y 값만 바뀌고 다음 코드를 실행할 때 Point(10)은 사라지므로 pt는 y값만 바뀌고 위치는 그대로이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;se_fs_T2&quot; style=&quot;font-size: 19px; position: relative; color: rgb(138, 131, 126); font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei;&quot;&gt;&lt;span style=&quot;background-color: inherit; color: rgb(0, 0, 0); font-size: 12pt;&quot;&gt;출처:&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;http://opensw.wikidot.com/cpp-fundamentals-explicit&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot; style=&quot;text-decoration-line: underline; font-family: 나눔고딕, nanumgothic, se_NanumGothic, AppleSDGothicNeo, sans-serif, simhei; font-size: 19px; color: rgb(96, 140, 186) !important;&quot;&gt;http://opensw.wikidot.com/cpp-fundamentals-explicit&lt;/a&gt;&lt;/p&gt;&lt;div class=&quot;autosourcing-stub-extra&quot; style=&quot;position: absolute; opacity: 1; zoom: 1;&quot;&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>C++언어</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/13</guid>
      <comments>https://psyhm.tistory.com/13#entry13comment</comments>
      <pubDate>Mon, 14 May 2018 16:08:18 +0900</pubDate>
    </item>
    <item>
      <title>[nodejs][socket.io] nodejs socket.io 사용기-2. room 사용, 현재 연결된 socket 찾기, disconnect 이벤트</title>
      <link>https://psyhm.tistory.com/12</link>
      <description>&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;이전 포스트:&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://psyhm.tistory.com/11&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;[Node.js] - [nodejs][socket.IO] 노드js 소켓 IO 사용기-1. socket.io란? 간단한 예제 코드 살펴보기&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이전에는 socket.io를 간단히 사용하는 법을 살펴 보았다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이번 포스트는 socket.io를 좀 더 유용하게 만들었던 함수들을 어떻게 썼는 지 정리해보고자 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 24px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;현재 연결된 소켓을 id로 찾기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;현재 연결된 소켓 중에서 socket.id를 이용해 소켓 객체를 가지고 오고 싶을 때&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;io.sockets&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;namespace&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 리턴한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;namespace란 기본적으로 다른 end points나 경로를 지정하는 것을 의미한다고 정식 docs에 나와있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;사용해보지 않아서 잘 모르겠지만 소켓들은 namespace를 통해 구분될 수 있고 이벤트를 달리할 수 있는 것으로 이해했다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하지만 일단&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; const io = require('socket.io')(server)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 통해 생성된 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;socket&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;들은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;default namespace 안에 관리&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;되어있으므로 나중에 namespace에 대해 정리하고자 한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;여하튼 io.sockets는 default namespace를 리턴하고 namespace의 프로퍼티로써 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;connected&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;가 존재한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;connected는&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;socket.id를 key 값&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;으로 가지고&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 namespace에 연결(connect)된 객체들의 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;해쉬&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;간단히 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;io.sockets.connected[&amp;lt;특정 socket.id&amp;gt;]&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 통해 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;특정 socket을 리턴&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;한다는 의미이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;다 무시하고 &lt;b&gt;현재 연결된 특정 socket에만 이벤트를 emit할 경우&lt;/b&gt;가 생기면 다음과 같이 작성하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;let clientSocket = io.sockets.connected[user.socketId];
clientSocket.emit(&quot;event1&quot;, data);
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;Socket 자체에 프로퍼티를 추가하기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;socket이 connection이 되면 콜백함수로 socket 객체를 받는다.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;socket 객체&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;property를 추가&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;해 나중에 필요한 데이터를 사용할 수가 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;예를 들어 socket이 연결 된 후 nickname을 서버에서 할당 받았고 나중에 클라이언트가 emit한 이벤트에 닉네임을 사용할 일이 생겼다면 다음과 같이 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;server 코드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;io.on('connection', (socket)=&amp;gt; {
        console.log(&quot;SOCKETIO connection EVENT: &quot;, socket.id, &quot; client connected&quot;);

        let nickname = getNickName();   // 고유 닉네임 할당 받음
        socket.nickname = nickname;     // nickname 프로퍼티를 동적으로 생성

        socket.emit(&quot;getNickname&quot;, socket.nickname);    // socket의 nickname 프로퍼티에 접근
    })
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;client 코드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-html line-numbers&quot;&gt;&amp;lt;script&amp;gt;
    var socket = io(); 
    socket.on('connect', function () {
        socket.on(&quot;getNickname&quot;, function(msg) {	// getNickname 이벤트 핸들러 등록
            console.log(&quot;Nickname: &quot;, msg);		// 받은 nickname을 콘솔창에 띄움
        })
    });
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Room이란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Room&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이란 말 그대로&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 방&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;을 의미한다. 각 socket들은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;참여&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있고 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;탈퇴&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있는 임의의 room을 정의할 수 있는데 이 room이라는 것은 채팅방을 빗대어 생각하면 좀 이해하기 편리할 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;socket은&amp;nbsp;room에 대한 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;join&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;과 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;leave&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;join이란 room에 참여하는 것이고, leave는 room에 탈퇴하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;join 예제&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;io.on('connection', function(socket) {&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; &amp;nbsp; socket.join('room1');&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;leave 예제&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;leave함수는 위와 마찬가지로 socket.leave('room1');과 같이 작성하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;room을 사용하는 이유는 room에 참여한 socket 들에 대해서 한번에 이벤트를 emit할 수 있다는 점이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;예를 들어 채팅방에 메세지가 들어온다면 그 채팅방에 속한 소켓들에게만 데이터를 전달할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;server 코드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;io.on('connection', (socket)=&amp;gt; {
        console.log(&quot;SOCKETIO connection EVENT: &quot;, socket.id, &quot; client connected&quot;);

        socket.on('joinRoom', function(msg) {     // joinRoom을 클라이언트가 emit 했을 시
            let roomName = msg;
            socket.join(roomName);    // 클라이언트를 msg에 적힌 room으로 참여 시킴
        });

        socket.on('chatting', function(msg) {       // 클라이언트가 채팅 내용을 보냈을 시
            // 전달한 roomName에 존재하는 소켓 전부에게 broadcast라는 이벤트 emit
            io.to(msg.roomName).emit('broadcast', msg.msg); 
        })
    })
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;client 코드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-html line-numbers&quot;&gt;&amp;lt;head&amp;gt;
  &amp;lt;script src=&quot;/socket.io/socket.io.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;script&amp;gt;
      $(function () {
          var socket = io();
          socket.emit('joinRoom', &quot;room1&quot;);
          $('form').submit(function(){
              socket.emit('chatting', {
                  roomName: &quot;room1&quot;,
                  msg: $('#m').val()
              });
              $('#m').val('');
              return false;
          });
          socket.on('broadcast', function(msg){
              $('#messages').append($('&amp;lt;li&amp;gt;').text(msg));
          });
      });
  &amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;ul id=&quot;messages&quot;&amp;gt;&amp;lt;/ul&amp;gt;
  &amp;lt;form action=&quot;&quot;&amp;gt;
    &amp;lt;input id=&quot;m&quot; autocomplete=&quot;off&quot; /&amp;gt;&amp;lt;button&amp;gt;Send&amp;lt;/button&amp;gt;
  &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;disconnect 이벤트&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;disconnect 이벤트는 socket, 즉 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클라이언트와 서버와의 연결이 끊겼을 때 발생하는 이벤트&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;socket과의 연결이 끊겼을 때의 핸들러가 필요하다면 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;disconnect &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이벤트&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 이용하도록 한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;물론 io.on('connection', function(socket) { ... }); 에서의 콜백함수 안에 작성해야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;disconnect 예제&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;socket.on('disconnect', function() {&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;console.log(&quot;SOCKETIO disconnect EVENT: &quot;, socket.id, &quot; client disconnect&quot;);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;// 여기서부터 필요한 내용을 작성하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;style&gt;@import url(http://fonts.googleapis.com/earlyaccess/notosanskr.css);

*{
  font-family: 'Noto Sans KR', sans-serif !important;
}
.subtitle &amp;amp;amp;gt; li{
  font-size: 20px;
  font-weight: bold;
}&lt;/style&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Node.js</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/12</guid>
      <comments>https://psyhm.tistory.com/12#entry12comment</comments>
      <pubDate>Sun, 13 May 2018 18:14:59 +0900</pubDate>
    </item>
    <item>
      <title>[nodejs][socket.io] nodejs socket.io 사용기-1. socket.io란? 간단한 예제 코드 살펴보기</title>
      <link>https://psyhm.tistory.com/11</link>
      <description>&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;socket.io란??&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;socket.io&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;websocket 프로토콜&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;을 지원하는 네트워킹 라이브러리이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;비동기 이벤트 방식&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;으로 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&quot;실시간&quot;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;으로&amp;nbsp;간단하게 데이터를 주고받을 수 있게 만든 라이브러리이며 정말 쉽게 만들 수 있지만 강력한 기능들로 하여금 다양한 서비스를 만들 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;서버 사이드에서는 아직 node.js에서만 가능하고 클라이언트 사이드에서는 javascript가 가능한 곳, 브라우저 심지어 스위프트나 자바 안드로이드도 가능하고 C++11도 가능한 것으로 보인다. &lt;/span&gt;&lt;span style=&quot;color: rgb(189, 189, 189);&quot;&gt;&lt;span style=&quot;color: rgb(189, 189, 189);&quot;&gt;&lt;span style=&quot;color: rgb(189, 189, 189);&quot;&gt;&lt;a href=&quot;https://github.com/socketio&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(189, 189, 189);&quot;&gt;socket.io 깃허브 주소&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(189, 189, 189);&quot;&gt;&lt;span style=&quot;color: rgb(189, 189, 189);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;위에서 설명했듯 socket.io는 Websocket 프로토콜을 사용한다. 원래는 웹 브라우저에서 양방향으로 자유롭게 데이터를 교환하기 위해서 WebSocket이란 개념이 나왔고 그것을 구현할 수 있도록 만든 것이 socket.io이다.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(189, 189, 189);&quot;&gt;&lt;span style=&quot;color: rgb(189, 189, 189);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;필자는 이번에 socket.io를 사용하면서 어떤 기능을 사용했는 지 까먹지 않기 위해서 간단하게 정리하고자 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;먼저 서버 개발환경은&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;OS: Windows10&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;IDE: Webstorm2017&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;line-height: 1.8;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;express-generator로 application 생성&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;하였고,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;클라이언트는 간단히 웹 javascript로 하겠다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;서버 디렉토리 구조&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;express-generator가 무엇이지 궁금하고 프로젝트를 생성하는 방법은 다음 포스트에서 확인할 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://psyhm.tistory.com/2&quot; target=&quot;_blank&quot;&gt;2018/02/27 - [Node.js/express] - node.js express 1. express란??, express generator, directory 구조&lt;/a&gt;&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;express-generator로 application을 생성하면 다음과 같은 구조가 생성된다. ※ (dir)는 디렉토리라는 의미&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;.
├── app.js
├── bin(dir)
│   └── www
├── package.json
├── public(dir)
│   ├── images(dir)
│   ├── javascripts(dir)
│   └── stylesheets
│       └── style.css
├── routes(dir)
│   ├── index.js
│   └── users.js
└── views(dir)
    ├── error.pug
    ├── index.pug
    └── layout.pug
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;여기서 socket.io의 이벤트를 관리할 modules라는 디렉토리를 home directory에서 추가하고 socketIOHandler.js를 추가하였다.&lt;/span&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;.
├── bin
├── modules
│   └──  socketIOHandler.js
├── public
├── routes
└── views
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;socketIOHandler.js의 파일에는 다음과 같이 기본 틀을 잡는다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;- modules/socketIOHandler.js&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;exports = module.exports = function(io) {
    io.on('connection', (socket)=&amp;gt; {
        console.log(&quot;SOCKETIO connection EVENT: &quot;, socket.id, &quot; client connected&quot;);
        // 여기서부터 socket에 대한 이벤트를 작성하면 된다.
        socket.on(&quot;event1&quot;, function(msg) {
            console.log(&quot;SOCKETIO event1 EVENT: msg: &quot;, msg);
        })
    })
};
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;먼저 io.on을 이용해 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&quot;connection&quot;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이란 이벤트를 등록한다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이 이벤트는 클라이언트가 서버에 socket.io를 통해 접속한다면 발생하는 이벤트이다.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;connection&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이란 이벤트는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&quot;socket&quot;이란 객체&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 콜백함수에서 전달하는데 socket은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;접속한 개별의 클라이언트&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;로 보면 된다.&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;(정말 중요!!)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;io.on('connection')의 콜백함수 안에서 socket, 즉 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;클라이언트에게 발생하는 이벤트들을 등록&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그 후에 socket에 대한 이벤트를 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;on&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;을 통해 이벤트를 받을 준비를 하고 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;emit&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;을 통해 이벤트를 접속한 클라이언트로 발송한다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;위의 코드는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;event1&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 이란 이벤트를 클라이언트가 emit할 때를 대비해 받아놓을 핸들러를 만든 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;간단하게 클라이언트가 event1을 emit할 때 전송한 msg를 콘솔창에 찍는 함수를 등록했다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;(※ socketIOHandler는 코드를 보듯이 외부에서 socketIO에 대한 라이브러리를 io라는 변수로 받아온다. 이렇게 구조를 잡은 이유는 이벤트 핸들러가 많아질수록 한 파일에 관리하기 어려우므로 분리해서 관리하기 위함이다.)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그리고 bin/www에서&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;socketIOHandler&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;모듈을 불러온다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;- bin/www&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;const app = require('../app');
const debug = require('debug')('socketiotest:server');
const http = require('http');

const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

const server = http.createServer(app);
const io = require('socket.io')(server);        // socket.io 모듈을 사용 및 create 한 http 서버 전달

// socket.io의 이벤트 핸들러 등록 및 위의 socket.io 라이브러리를 socketIOHandler에 전달
const socketIOHandler = require('../routes/socketIO')(io);

....(뒤의 코드 생략)
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;주의할 점은 반드시 http 서버를 createServer한 후에 socket.io에 전달해야하는 것이다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;이제 클라이언트의 코드를 간단히 살펴보자.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-html line-numbers&quot;&gt;... (위의 코드 생략)
&amp;lt;head&amp;gt;
  &amp;lt;script src=&quot;/socket.io/socket.io.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;script src=&quot;https://code.jquery.com/jquery-1.11.1.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;script&amp;gt;
      var socket = io(); // TIP: io() with no args does auto-discovery
      socket.on('connect', function () { // TIP: you can avoid listening on `connect` and listen on events directly too!
          socket.emit('event1', 'tobi');
      });
  &amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  ... (코드 생략)
&amp;lt;/body&amp;gt;
... (코드 생략)
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;socket.io 클라이언트 스크립트인 &amp;lt;script src=&quot;/socket.io/socket.io.js&quot; /&amp;gt;는 socket.io를 잘 설치했고 위에서처럼 http server를 socket.io로 랩핑했다면 자동으로 클라이언트가 서버에 요청하고 받아서 사용할 것이니 저렇게 사용하면 된다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;그리고 접속할 서버를 지정해줘야하지만 var socket = io(); 처럼 그냥 생성하면 디폴트로 페이지를 전달해준 서버와 자동으로 연결한다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그 후에 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;socket.on&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;을 이용해 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;connect&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;가 되었다면 그 다음 이벤트를 작성할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;위의 코드는 connect가 되자마자 바로 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;event1&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이란 이벤트를 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;emit&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하고 그 데이터로 'tobi'란 문자열을 날린다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;따라서 서버는 msg로 tobi를 받게 되는 것이다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;서버의 콘솔 창을 보면 다음과 같은 문자열을 볼 수 있다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;SOCKETIO event1 EVENT: msg:&amp;nbsp; tobi&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;이렇듯 socket.io를 사용하면 매우 쉽게 실시간으로 데이터를 전송할 수가 있다.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;다음 포스트에선 socket.io를 좀 더 효율적으로 사용한 경험을 적도록 하겠습니다.&lt;/span&gt;&lt;/div&gt;&lt;style&gt;@import url(http://fonts.googleapis.com/earlyaccess/notosanskr.css);

*{
  font-family: 'Noto Sans KR', sans-serif !important;
}
.subtitle &amp;amp;amp;gt; li{
  font-size: 20px;
  font-weight: bold;
}&lt;/style&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Node.js</category>
      <category>node</category>
      <category>node.js</category>
      <category>socket.io</category>
      <category>노드</category>
      <category>노드js</category>
      <category>사용기</category>
      <category>소켓io</category>
      <category>예제</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/11</guid>
      <comments>https://psyhm.tistory.com/11#entry11comment</comments>
      <pubDate>Sun, 13 May 2018 16:46:13 +0900</pubDate>
    </item>
    <item>
      <title>리눅스 쓰레드(linux thread) 처리, 커널 레벨(kernal level) 쓰레드와 유저 레벨(user level) 쓰레드</title>
      <link>https://psyhm.tistory.com/10</link>
      <description>&lt;p&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;우분투 환경에서 C++을 공부하는 와중에 Thread에 대해 연습해보다가 Thread에는 커널 레벨과 유저 레벨이 존재한다고 들었다. 그렇다면 C++ thread 클래스(pthread를 랩핑한)는 어떤 종류인지 찾아보고 싶었다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;또한 Thread들이 과연 각 Thread마다 물리적인 다른 CPU에 각각 할당이 될까?? 라는 궁금함에 자료조사를 해보았다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그러기 위해서는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;ubuntu&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;스레드 당 정말 각각의&amp;nbsp;CPU에 할당 되는 지&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 직접 보고 싶었다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;과연 하나의 CPU에 할당이 되는 것인지, 스레드마다 각각 다른 CPU에 할당되는 지 눈으로 직접 보고싶었기에 조사를 해보았다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;먼저 C++ 코드를 작성하였다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp line-numbers&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;thread&amp;gt;
#include &amp;lt;queue&amp;gt;

using namespace std;

void helloWorld() {
  for(;;){}
}

int main() {
  thread t1(helloWorld);
  thread t1(helloWorld);

  t1.join();
  t2.join();

  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;스레드를 두 개&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 만들어서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;메인 스레드&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;까지&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 총 3개&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;가 생성되고 메인 스레드는 만들어진 두 개의 스레드가 끝나길 기다리고 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;하지만 무한루프이기 때문에 3개의 스레드는 CPU에 계속 할당되어 있고 우리가 모니터링할 때까지 계속 살아있을 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;이제 각각의 스레드가 어떤 CPU에 할당되는 지 알아볼 차례이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;먼저 PID(process id)를 알아야한다.&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;ps -ef | grep &amp;lt;프로그램 이름&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;로 먼저 프로세스 아이디를 확인한 후&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;ps -T -p &amp;lt;pid&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;style&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
@import url(http://fonts.googleapis.com/earlyaccess/notosanskr.css);

*{
  font-family: 'Noto Sans KR', sans-serif !important;
}
.subtitle &amp;amp;amp;gt; li{
  font-size: 20px;
  font-weight: bold;
}
&lt;/span&gt;&lt;/style&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;로 스레드가 몇개 있는 지 확인 후&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;ps -mo pid,tid,%cpu,psr -p &amp;lt;pid&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt; color: rgb(0, 0, 0);&quot;&gt;로 pid, tid, %cpu, psr을 확인할 수 있다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;위의 단어들은 다음을 의미한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;pid&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 프로세스 아이디&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;tid&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 스레드 아이디&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;%cpu&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: cpu 사용률&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;psr&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 어느 processor(CPU)에서 동작 중인지 나타냄&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음 사진으로 결과를 알 수 있다!!!&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99A3E64B5AE7009A05&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99A3E64B5AE7009A05&quot; width=&quot;500&quot; height=&quot;281&quot; filename=&quot;ubuntu에서의....png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음과 같이 각각의 스레드는 다른 7, 1, 2번 프로세서를 할당하는 것을 알 수 있다. (실행환경: ubuntu 16.04, 4 CPU, 8 Processor)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;또한 조사를 해보니 Thread에는 커널 레벨, 유저 레벨의 스레드가 존재한다고 했다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(0, 0, 0);&quot;&gt;커널 레벨&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size:18pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;설명&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;-&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;커널 영역에서 스레드 연산을 수행한다.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;- 커널이 스레드를 관리하기 때문에 커널에 종속적이다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;장점&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;프로세스의 스레드들을 몇몇 프로세서에 한꺼번에 디스패치 할 수 있기 때문에 멀티프로세서 환경에서 매우 빠르게 동작한다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;커널이 각 스레드를 개별적으로 관리할 수 있다.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;다른 스레드가 입출력 작업이 다 끝날 때까지 다른 스레드를 사용해 다른 작업을 진행할 수 있다.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;단점&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;스케줄링과 동기화를 위해 커널을 호출하는데 이는 비용이 상당하다(오래걸린다).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;사용자가 프로그래밍할 때 구현하기 어려받.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;자원을 더 많이 소비하는 경향이 있다.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(0, 0, 0);&quot;&gt;유저 레벨&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: 24pt; color: rgb(0, 0, 0);&quot;&gt;:&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; 설명&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;- 사용자 영역에서 스레드 연산을 수행한다.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;- 사용자 영역에서 스레드 연산을 수행하기 때문에 운영체제에 투명하다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;이는 운영체제가 각 스레드가 아닌 멀티스레드를 포함하는 프로세스 한 단위를 대상으로 프로세서를 할당한다는 의미이다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;장점&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;운영체제에서 스레드를 지원할 필요가 없다.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;스케줄링 결정이나 동기화를 위해 커놀을 호출하지 않기 때문에 인터럽트가 발생할 때 커널 레벨 스레드보다 오버헤드가 적다(컨텍스트 스위칭).&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp; 단점&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;커널이 멀티스레드 프로세스를 한 스레드로 간주한다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;시스템 전반에 걸친 스케줄링 우선순위를 지원하지 않는다.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;프로세스에 속한 스레드 중 I/O 작업등에 의해 하나라도 블록이 걸린다면 전체 스레드가 블록된다.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(189, 189, 189);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출처:&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://blog.naver.com/PostView.nhn?blogId=known7777&amp;amp;logNo=220493119905&amp;amp;categoryNo=47&amp;amp;parentCategoryNo=0&amp;amp;viewDate=&amp;amp;currentPage=1&amp;amp;postListTopCurrentPage=1&amp;amp;from=postView&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;[운영체제] 스레딩 모델&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;(링크)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;유저 레벨 스레드&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 실행되고 있는 프로세스가 스레드를 관리하는 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;커널 레벨 스레드는 OS가 관리한다. 반면에 유저 레벨 스레드는 유저(라이브러리 만든 사람)에 의해 관리되고 따라서&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; OS는 단일의 유저 레벨 스레드로 인식&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;한다(&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;실행중인 스레드)&lt;/span&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;div style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;따라서 단순 유저 레벨 스레드를 사용하는 경우 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;멀티프로세서의 장점을 갖지 못한다.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;어차피 하나의 프로세스는 여러개의 스레드를 갖는다하여도 단일 프로세서에서 작동하기 때문이다.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그렇다면 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;C++&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에서 제공하는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;thread 라이브러리&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 유저 레벨인지 커널 레벨인지 궁금했다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;리눅스는 커널 v2.6 이상부터 NPTL로 구현&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 되어 있다. NPTL은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;1대1 스레드 라이브러리&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이며 그것은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사용자가 만든 스레드(pthread_create)가 스케줄링 단위가 된다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(189, 189, 189);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;출처: &lt;/span&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Native_POSIX_Thread_Library&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;위키피디아 &lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(189, 189, 189);&quot;&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Native_POSIX_Thread_Library&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Native POSIX Thread Library&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;(링크)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;따라서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;NPTL&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;커널 스레드라고 말할 수 있으며&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 랩핑된 thread 클래스 또한 커널이 스케줄링하기 때문에&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18.6667px; color: rgb(0, 0, 0);&quot;&gt;스레드를 생성할 때 각각의 스레드는 다른 프로세서에 할당되는 것이다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>컴퓨터 사이언스/개인 연구</category>
      <category>C++</category>
      <category>linux</category>
      <category>NPTL</category>
      <category>Thread</category>
      <category>리눅스</category>
      <category>스레드</category>
      <category>우분투</category>
      <category>유저레벨</category>
      <category>커널레벨</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/10</guid>
      <comments>https://psyhm.tistory.com/10#entry10comment</comments>
      <pubDate>Mon, 30 Apr 2018 20:59:35 +0900</pubDate>
    </item>
    <item>
      <title>[node js] node.js 동작 원리, node.js 구조 및 시스템, event loop 구조</title>
      <link>https://psyhm.tistory.com/9</link>
      <description>&lt;p&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;그동안 노드js를&lt;/span&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;사용하면서 항상 머리 속을 맴돌았던 질문이 있었다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;노드는 어떻게 돌아가는 거지? 노드는 왜 싱글 스레드인거지? 뭐가 대체 싱글 스레드인걸까??&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;궁금증에 못이겨 노드js 공식 홈페이지의 문서를 뒤젹거리며 찾아본 결과를 정리해보고자 포스팅을 시작했다. 문서 내용을 가져온 내용이 있기 때문에 직접 Node.js 공식 문서를 보는 것도 좋은 방법일 것 같다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Node.js 공식 문서:&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://nodejs.org/ko/docs/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;https://nodejs.org/ko/docs/&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;블로킹과 논블로킹 살펴보기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;먼저 블로킹과 논블로킹에 대해 알아보도록 하겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;블로킹&lt;/b&gt;: 호출되는 함수가 자신의 작업을 마칠 때까지 제어권을 넘겨주지 않고 대기하는 방식&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;논블로킹&lt;/b&gt;: 호출되는 함수가 바로 제어권을 넘겨줘서 다른 작업을 진행할 수 있도록 하는 방식&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Node.js에서&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;libuv&lt;/b&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;를 사용하는 Node.js 표준 라이브러리의 &lt;/span&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;동기 메서드&lt;/b&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;가 가장 대표적인 &lt;/span&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;블로킹 작업&lt;/b&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;입니다. 네이티브 모듈도 블로킹 메서드를 가질 수 있습니다. (이런 동기 메서드는 이름 마지막에 Sync가 붙습니다.)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;그 외의 &lt;b&gt;Node.js&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 표준 라이브러리의 모든 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;I/O 메서드&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;논블로킹인 비동기 방식을 제공&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하고 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;콜백 함수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 받습니다.&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1) 코드 비교&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;블로킹 메서드와 논블로킹 메서드 예제&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Ex) 동기로 파일을 읽는 예제&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;const fs = require('fs');
const data = fs.readFileSync('/file.md'); // 파일을 읽을 때까지 여기서 블로킹됩니다.
console.log(data);
// moreWork();는 console.log 이후 실행될 것입니다.
// 싱글 스레드가 파일 읽기 작업 완료 후 moreWork() 수행 
&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;div style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;div style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Ex) 비동기로 파일을 읽는 예제&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;const fs = require('fs');
fs.readFile('/file.md', (err, data) =&amp;gt; {
  if (err) throw err;
  console.log(data);
});
// moreWork();는 console.log 이전에 실행될 것입니다.
// 파일을 읽는 작업은 다른 스레드에 맡긴 뒤 끝나면 Node.js에게 알려주어 적절한 콜백을 처리
&lt;/code&gt;&lt;/pre&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 12pt; color: rgb(0, 0, 0);&quot;&gt;파일 읽기가 완료되길 기다리지 않고 moreWork()를 실행할 수 있도록 한 것은 높은 처리율을 가능하게 하는 Node.js&amp;nbsp;핵심 디자인 철학입니다. (비동기)&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;동시성(Concurrency)과 처리율(Throughput)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Node.js에서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;JavaScript 실행이 싱글 스레드(이벤트 루프와 같은 스레드)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;에서 동작합니다. 따라서 Node.js의&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;동시성&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;은 다른 작업이 완료된 후에 JavaScript 콜백 함수를 실행하는 이벤트 루프의 능력을 의미합니다. 다시 말해서 javascript 실행은 하나의 이벤트 루프에서만 동작하지만 이벤트 루프의 여러 콜백 함수를 실행하여 &lt;b&gt;동시에 처리되도록 보이는 것&lt;/b&gt;을 의미합니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;동시에 실행되어야 하는 모든 코드는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;I/O 등의 JavaScript가 아닌 작업(이벤트 루프 스레드 외 다른 스레드)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 일어나는 동안&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 이벤트 루프가 계속 실행&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;될 수 있도록 해야 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이벤트 루프는 동시 작업을 다루려고 부가적인 스레드를 만드는 다른 언어의 모델과는 다릅니다. (Node.js는 스레드를 따로 생성하지 않음) =&amp;gt; (node.js 10버전으로 들어오면서 Worker_thread라는 모듈을 통해 스레드 생성 가능하도록 변경됐다.)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;node.js 시스템 구조&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/995D0F3B5ABE2B0405&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F995D0F3B5ABE2B0405&quot; width=&quot;500&quot; height=&quot;281&quot; filename=&quot;nodejs system.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;libuv&lt;/b&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;란 &lt;/span&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;비동기 I/O&lt;/b&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;에 집중하는 &lt;/span&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;멀티 플랫폼 라이브러리&lt;/b&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;이다. &lt;/span&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;C언어로 개발&lt;/b&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;되었으며 사실상 Node.js를 위해 개발된 것이다. 이 라이브러리는 다양한 &lt;/span&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;I/O 폴링 메커니즘&lt;/b&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;에 대한 단순한 추상화 이상의 기능을 제공한다. 어느 운영체제에서도 가능한&lt;/span&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;file&amp;nbsp;I/O&lt;/b&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;와 &lt;/span&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;thread&lt;/b&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;기능 또한 제공된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;libuv에는 &lt;b&gt;thread pool&lt;/b&gt;이 존재하는데 이 thread pool에 있는 thread가 &lt;b&gt;동기적인 입출력 작업&lt;/b&gt;을 이벤트 루프 대신 &lt;b&gt;처리&lt;/b&gt;를 해준다. 또한 이 libuv를 통해 &lt;/span&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;이벤트 루프를 제어&lt;/b&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;한다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;libuv 홈페이지:&amp;nbsp;&lt;/span&gt;&lt;font color=&quot;#bdbdbd&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;a href=&quot;http://libuv.org/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;http://libuv.org/&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Node.js는&lt;b&gt; binding API&lt;/b&gt;(C++ Addon)를 활용해 위에서 설명한 libuv과 연결되며 I/O 작업을 동기식으로 libuv가 처리한 뒤 I/O 작업이 끝나면 콜백함수가 처리되는 것이다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;I/O 작업&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;네트워크, 파일 시스템, 프로세스&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 등이 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;따라서 I/O 작업이 많은 곳에서 Node.js가 활용이 좋다. (여러 스레드를 활용하기 때문)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Node.js 코드를 수행하는 스레드와 이벤트 루프의 스레드는 동일하다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이벤트 루프&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이벤트 루프는 가능하다면 언제나 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;시스템 커널에 작업을 떠넘겨서&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; Node.js가&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 논블로킹 I/O 작업을 수행&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하도록 해줍니다.(노드를 효율적으로 운용하는 방법)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;대부분의 현대 커널은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;멀티 스레드&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이므로 백그라운드에서 다수의 작업을 실행할 수 있습니다. 이러한 작업 중 하나가 완료되면 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;커널이 Node.js에게 알려주어 콜백 함수를&amp;nbsp;poll 큐에 추가&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있게 하여 동시성 있게 처리하도록 합니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style=&quot;line-height: 1.5;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/998056375ABE334D19&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F998056375ABE334D19&quot; width=&quot;500&quot; height=&quot;281&quot; filename=&quot;event_loop structure.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;위의 그림은 이벤트 루프의 작업 순서의 간단한 개요를 보여준다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Timers&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 이 단계는 setTimeout()과 setInterval()로 스케줄링한 콜백을 실행합니다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;I/O callbacks&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 클로즈 콜백, 타이버로 스케줄링된 콜백, setImmediate()를 제외한 거의 모든 콜백을 실행합니다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Idle, prepare&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 내부용으로만 사용합니다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Poll&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 새로운 I/O 이벤트를 가져옵니다. 적절한 시기에 node는 여기서 블록합니다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Check&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: setImmediate() 콜백은 여기서 호출됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Close callbacks&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;: 예시: socket.on(‘close’, ….);&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;line-height: 1.5;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;이벤트 루프는 이 모든 큐 들에 존재하는 작업들을 순차적으로 처리함으로써 비즈니스 로직을 수행한다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;style&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
@import url(http://fonts.googleapis.com/earlyaccess/notosanskr.css);

*{
  font-family: 'Noto Sans KR', sans-serif !important;
}
.subtitle &amp;amp;amp;gt; li{
  font-size: 20px;
  font-weight: bold;
}
&lt;/span&gt;&lt;/style&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Node.js</category>
      <category>node.js</category>
      <category>구조</category>
      <category>노드</category>
      <category>시스템</category>
      <category>이벤트 루프</category>
      <category>파헤쳐보자</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/9</guid>
      <comments>https://psyhm.tistory.com/9#entry9comment</comments>
      <pubDate>Fri, 30 Mar 2018 21:56:06 +0900</pubDate>
    </item>
    <item>
      <title>node.js express 5. middleware란? 미들웨어 정의, 미들웨어 유형</title>
      <link>https://psyhm.tistory.com/8</link>
      <description>&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이전 포스트 :&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://psyhm.tistory.com/7?category=654716&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;http://psyhm.tistory.com/7?category=654716&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;저번 포스트에서는 route paths와 parameters에 대해 조금 더&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;살펴보았다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이번엔 대망의 middleware에 대해서 살펴 보도록 하겠다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size:24pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Middleware&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;docs를 보면 middleware에 대한 설명이 나와있다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&quot;Middleware functions are functions that have access to the&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;request object (req), the response object (res), and the next function&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;in the application’s request-response cycle.&quot;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;미들웨어 함수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;req(요청)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 객체, &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;res(응답)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 객체, 그리고 어플리케이션&amp;nbsp;&lt;/span&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;요청-응답 사이클&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt; 도중 그 &lt;/span&gt;&lt;b style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음의 미들웨어 함수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;에 대한 엑세스 권한을&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;갖는 함수이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;미들웨어란&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 간단하게 말하면 클라이언트에게 요청이 오고 그 요청을 보내기 위해&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;응답하려는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;중간(미들)에 목적에 맞게 처리를 하는, 말하자면 거쳐가는&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;함수들&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이라고 보면 되겠다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;예를 들어서 요청-응답 도중에 시간을 콘솔 창에 남기고 싶으면&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;미들웨어 함수를 중간에 넣어서 표시를 한 뒤에 계속해서 다음 미들웨어들을&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;처리할 수 있도록 하는 것이다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음 미들웨어 함수에 대한 엑세스는&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; next 함수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 이용해서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음 미들웨어로&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;현재 요청을 넘길 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;next라는 말에서 알 수 있듯이 next를 통해 미들웨어는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;순차적으로 처리&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;된다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;(따라서 순서가 중요하다!!)&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;다음 예시에 미들웨어 함수 호출의 요소가 표시되어 있다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;clear: both; float: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 410px; margin-right: 10px;; height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/991647445AB7C67707&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F991647445AB7C67707&quot; width=&quot;410&quot; height=&quot;308&quot; filename=&quot;express-mw.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;margin-right: 10px;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP 메서드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;미들웨어가 작동할 path&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;미들웨어 함수&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음 미들웨어로의 액세스 함수&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP response 객체&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;HTTP request 객체&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;1차때 만들었던 프로젝트의 app.js 파일을 보자.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 500px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/996CAD475AB7C7F32B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F996CAD475AB7C7F32B&quot; width=&quot;500&quot; height=&quot;316&quot; filename=&quot;20180326_010142.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;app.use&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 안에 있는 모든 함수들은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;모두 미들웨어&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이며 요청이 올때마다&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이 미들웨어를 거치며 클라이언트에게 응답하게 된다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이 미들웨어들을 어떨 때 사용하면 편리하냐면 페이지를 렌더링할 때 사용자 인증을 앞서&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;거친 후에 렌더링하고 싶을 때 사용자 인증 미들웨어를 작성하고 앞에&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;삽입하게 되면 편리하다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;혹은 로그를 먼저 남기고 싶을때도 로그를 남기는 미들웨어를 작성하고&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;앞서 삽입하면 편리하다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;미들웨어의 특징을 간략히 정리하자면 다음과 같다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;모든 코드를 실행&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음 미들웨어 호출&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;(미들웨어가 순차적으로 실행)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;res, req 객체 변경 가능&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;요청-응답 주기를 종료&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;(response&amp;nbsp;methods를 이용)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;다음 미들웨어를 호출한다는 의미는 다음 코드를 보면 알 수 있다.&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;var express = require('express');
var app = express();

var myLogger = function (req, res, next) {
  console.log('LOGGED');
  next();
};

app.use(myLogger);

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.listen(3000);
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;클라이언트가 루트 경로(ex. http:/localhost:3000/)로 요청을 보냈을 때&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;myLogger를 먼저 거치고 myLogger는 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음 미들웨어 호출(next())함수&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 지정하여&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;res.send(&quot;Hello World&quot;); 코드가 담긴 미들웨어로 넘어가게 된다는 의미이다.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;res, req 객체 변경 가능&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이라는 의미는 다음 코드를 보면 알 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;var express = require('express');
var app = express();

var requestTime = function (req, res, next) {
  req.requestTime = Date.now();
  next();
};

app.use(requestTime);

app.get('/', function (req, res) {
  var responseText = 'Hello World!';
  responseText += 'Requested at: ' + req.requestTime + '';
  res.send(responseText);
});

app.listen(3000);
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;requestTime 미들웨어는 req 객체 안에 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;requestTime라는 프로퍼티&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;를 만들었고&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;다음 미들웨어에서 프로퍼티 값을 가져올 수 있다.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;요청-응답 주기를 종료(res methods)&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;한다는 의미는 앞서 배웠던 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;response의&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;method를 이용&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하여 클라이언트에게 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;응답을 전송&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;한다는 의미이다. (응답 전송시 종료)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;위의 코드는 res.send(responseText);가 주기를 종료한다는 의미이다.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size:24pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Middleware 유형&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;express는 다음과 같은 middleware 유형이 존재한다.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;어플리케이션 레벨 미들웨어&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;라우터 레벨 미들웨어&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;오류 처리 미들웨어&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;써드파티 미들웨어&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;1)&lt;/span&gt;&lt;span style=&quot;font-size: 18pt; color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;어플리케이션 레벨 미들웨어&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;app.use()&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 및 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;app.METHOD()&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 함수(*method: get, post 등등)를 이용해 app 오브젝트의 인스턴스에 바인드&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;시킨다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;미들웨어를 어플리케이션&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;영역에서 지정한 path대로&amp;nbsp;처리 가능&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하게 하도록 한다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;var app = express();

app.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;style&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
@import url(http://fonts.googleapis.com/earlyaccess/notosanskr.css);

*{
  font-family: 'Noto Sans KR', sans-serif !important;
}
.subtitle &amp;amp;amp;gt; li{
  font-size: 20px;
  font-weight: bold;
}
&lt;/span&gt;&lt;/style&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음과 같이 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;특정 경로&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;나&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; http methods 에 대해서만&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;적용&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수도 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이 함수들은 /user/:id 경로에 대해 미들웨어들이 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;// 모든 /user/:id 요청에 대해 작동
app.use('/user/:id', function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

// /user/:id인 GET 요청에 대해서만 응답
app.get('/user/:id', function (req, res, next) {
  res.send('USER');
});
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;다음은 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하나의 경로를 통해 일련의 미들웨어 함수를 하나의 마운트 위치에 로드&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;하는&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;예가 표시되어있습니다. 위의 미들웨어가 먼저 실행 된 뒤에 다음, 미들웨어가&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;이어 받습니다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;app.use('/user/:id', function(req, res, next) {
  console.log('Request URL:', req.originalUrl);
  next();
}, function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;2) 라우터 레벨 미들웨어&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;라우터 레벨 미들웨어는&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; express.Router() 인스턴스에 바인드&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;된다는 점을 제외하면&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;어플리케이션 레벨 미들웨어와 동일한 방식으로 작동한다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Router객체를 이용해&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; router.use()&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 및 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;router.METHOD()&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 함수를&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;사용하여 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;라우터 레벨 미들웨어를 로드&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;Router 객체는 그 자체가 미들웨어처럼 움직&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이므로 app.use()의 인수(argument)로&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;사용될 수 있고 또한 다른 router의 use() 메서드에서 사용될 수 있다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;var router = express.Router()로 Router 객체를 생성한 뒤에&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;app.use()를 사용해 마운트 시켜야지만 사용가능하다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;app.use()에서 지정한 경로와 같은 것이 들어온다면 모두 적용&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;시켜버리기&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;때문에&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt; 중복&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;이 될 가능성이 있다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;예를 들어 app.use('/apple', ...) 이 있다면&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;/apple, /apple/images, /apple/images/news 등에 모두 적용시켜 버린다&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;router를 사용하는 이유&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;는 특정 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;root url을 기점&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;으로&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;기능이나 로직별로 라우팅을 나눠서 관리&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;할 수 있다는 점이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;user 라우터에는 다른 라우터에는 필요없는 인증 미들웨어를 따로 추가하는 등의&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;작업을 할 수 있다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;3) 에러 핸들링 미들웨어&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;에러 핸들링을 하는 미들웨어는 4개의 인자를 사용해서 정의하도록 한다. (err, req, res, next)&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;단순히 에러 핸들링 미들웨어는 에러를 다루기 위한 미들웨어이다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;다음 포스팅때 좀 더 다루기로 한다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;4) 서드 파티 미들웨어&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;기능적으로 express app에 미들웨어를 추가하기 위해 서드 파티 미들웨어 사용을 권고한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;Node.js 모듈을 사용하고 싶다면 application 레벨이든 router 레벨이든 로드해서 사용하면 된다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;npm에서 install 가능하다.&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;
&lt;/span&gt;&lt;p&gt;&lt;span style=&quot;font-size: 16px; color: rgb(0, 0, 0);&quot;&gt;다음 포스팅에서는 에러 핸들링에 대해서 간단히 보도록 하겠다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Node.js/express</category>
      <category>express</category>
      <category>middleware</category>
      <category>node.js</category>
      <category>노드</category>
      <category>미들웨어</category>
      <category>파헤쳐보자</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/8</guid>
      <comments>https://psyhm.tistory.com/8#entry8comment</comments>
      <pubDate>Mon, 26 Mar 2018 01:23:50 +0900</pubDate>
    </item>
    <item>
      <title>node.js express 4. route paths 라우트 경로, route parameters 라우트 파라미터, response methods 응답 메서드</title>
      <link>https://psyhm.tistory.com/7</link>
      <description>&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;이전 포스트 :&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;p&gt;&lt;a href=&quot;http://psyhm.tistory.com/6&quot; target=&quot;_blank&quot;&gt;2018/03/04 - [Node.js/express] - Node.js express를 파헤쳐보자-3: static file, path 객체&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;저번 포스트에서는 &lt;b&gt;static file&lt;/b&gt;과 &lt;b&gt;path 객체&lt;/b&gt;에 대해서 알아보았다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;express가 어떻게 정적 파일(static file)과 path 객체가 무엇이고 어떻게&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;사용하는 지 정말 간략하게 살펴보았다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;이번 포스트는 이전 포스트에서 다루었던 &lt;b&gt;router&lt;/b&gt;를 좀 더 살펴보도록 하겠다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;Route paths&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;이전에 Router는 &lt;b&gt;url의 path&lt;/b&gt;와 &lt;b&gt;http method&lt;/b&gt;로 &lt;b&gt;handler&lt;/b&gt;를 달리 할 수 있다고&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;설명하였다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;이 Route paths에 대해 조금 더 설명을 하고 싶었다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;express 문서를 보면 다음과 같은 구문이 있다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;express 문서: &lt;/b&gt;&lt;a href=&quot;http://expressjs.com/en/guide/routing.html&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;b&gt;http://expressjs.com/en/guide/routing.html&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&quot;Route paths can be strings, string patterns, or regular expressions.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;Route paths&lt;/b&gt;는 &lt;b&gt;string&lt;/b&gt;이나 &lt;b&gt;string 패턴&lt;/b&gt; 혹은 &lt;b&gt;정규 표현식&lt;/b&gt;이 될 수 있다라고 써져 있다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;보통은 string 그대로 쓰면 되므로 보기 귀찮으신 분들은 &lt;b&gt;이 부분은 건너 뛰셔도 된다&lt;/b&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;예제를 보며 살펴보자.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-size: 16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;// 일반적 문자열
app.get('/about', function (req, res) {
  res.send('about')
})
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;위의 표현은 주로 우리가 쓰는 방식인 문자열로 Route path를 정하는 방식이다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;다음과 같이 string 패턴이 사용될 수도 있다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;아래의 Route path는 &lt;b&gt;/abd나 /abcd&lt;/b&gt;가 될 수 있다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-size: 16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;app.get('/ab?cd', function (req, res) {
  res.send('ab?cd')
})
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;아래의 Route path는 &lt;b&gt;/abcd나 /abbcd /abbbcd&lt;/b&gt;가 될 수 있다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-size: 16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;app.get('/ab+cd', function (req, res) {
  res.send('ab+cd')
})
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;string 패턴은 &lt;b&gt;?, +, *, () &lt;/b&gt;등 &lt;b&gt;정규식 문자의 서브셋&lt;/b&gt;을 사용할 수 있다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;string 패턴은 아래 경로에서 사용 방법을 알 수 있다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/%EC%A0%95%EA%B7%9C%EC%8B%9D&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/%EC%A0%95%EA%B7%9C%EC%8B%9D&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;또한 Route paths는 &lt;b&gt;정규표현식&lt;/b&gt;도 가능하다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;다음 식은 paths에 &lt;b&gt;a가 포함된 모든 항목&lt;/b&gt;과 일치한다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-size: 16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;app.get(/a/, function(req, res) {
  res.send('/a/');
});
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;이렇듯 정규 표현식도 가능하지만 &lt;b&gt;솔직히 잘 쓰이는 것은 아닌 것 같다.&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;(아직 가방끈이 짧아서..)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;다음은 &lt;b&gt;Route parameters&lt;/b&gt;에 대해 설명하도록 하겠다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;Route parameters&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;문서에는 Route parameter에 대해 다음과 같은 설명을 붙이고 있다.&lt;/span&gt;&lt;/div&gt;&lt;blockquote class=&quot;tx-quote-tistory&quot;&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;&quot;Route parameters are named URL segments that are used to capture the&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-size: 12pt;&quot;&gt;&amp;nbsp;values specified at their position in the URL&quot;&lt;/b&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&quot;Route parameter란 url안의 특정 위치에서 &lt;b&gt;변수&lt;/b&gt;를 추출하기 위한 URL segment라고 불리는 것이다.&quot;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;라고 설명하였다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;그냥 예시를 보는 것이 편할 것 같다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;예를 들어 다음과 같은 url이 서버에 도착했다고 가정하자.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;b&gt;http://localhost:3000/users/34/books/8989&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;그러면 밑의 코드가 캐치하게 된다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;app.get('/users/:userId/books/:bookId', function (req, res) {
  res.send(req.params)  //  { &quot;userId&quot;: &quot;34&quot;, &quot;bookId&quot;: &quot;8989&quot; }
})
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;딱 보면 알듯이 특정 &lt;b&gt;user의 번호&lt;/b&gt;와 &lt;b&gt;특정 책의 번호&lt;/b&gt;를 &lt;b&gt;주기 위한 url&lt;/b&gt;이며&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;그 url에서 &lt;b&gt;특정 변수를 추출&lt;/b&gt;해내서 사용할 수 있다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;변수 이름은 위와 같이&lt;b&gt; :변수명&lt;/b&gt; 을 이용해서 추출할 수 있다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;또한 &lt;b&gt;하이픈(-)&lt;/b&gt;과 &lt;b&gt;점(.)&lt;/b&gt;은 문자 그대로 해석되기 때문에 유용하게 사용할 수 있다.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-size: 16px;&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript line-numbers&quot;&gt;Route path: /flights/:from-:to
Request URL: http://localhost:3000/flights/LAX-SFO
req.params: { &quot;from&quot;: &quot;LAX&quot;, &quot;to&quot;: &quot;SFO&quot; }

Route path: /plantae/:genus.:species
Request URL: http://localhost:3000/plantae/Prunus.persica
req.params: { &quot;genus&quot;: &quot;Prunus&quot;, &quot;species&quot;: &quot;persica&quot; }
&lt;/code&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size:16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;이렇게 Route path에 대해서 주구장창 설명하는 이유는&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;url을 어떻게 만드는 지도 서비스를 구성하는 데에 필요하기 때문이다.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;(일을 직접 해보지는 않았지만...)&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;Route parameters는 많이 쓰이는 것 같다.&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;그러니 잘 알아두도록 하자.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;Response methods&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;div style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;Response 객체(res)의 methods&lt;/b&gt;는 클라이언트에게 &lt;b&gt;어떤 방식으로 응답을 제공&lt;/b&gt;하는 지에 대한 메서드를 의미합니다.&lt;/div&gt;&lt;div style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-size: 16px;&quot;&gt;다음 메서드 중 어느 하나도 호출되지 않는 경우, timeout 시간이 될 때까지 클라이언트 요청은 정지된 채로 방치됩니다.&lt;/div&gt;&lt;div style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-size: 16px;&quot;&gt;&lt;table class=&quot;txc-table&quot; width=&quot;500&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; style=&quot;border: none; border-collapse: collapse; width: 700px;&quot; noto=&quot;&quot; sans=&quot;&quot; kr&quot;,=&quot;&quot; sans-serif;font-size:13px&quot;=&quot;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;width: 126px; height: 24px; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); background-color: rgb(178, 204, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&amp;nbsp;메소드&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 373px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-top: 1px solid rgb(204, 204, 204); background-color: rgb(178, 204, 255);&quot;&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;설명&amp;nbsp;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 126px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;res.download()&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 373px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;파일이 다운로드되도록 프롬프트합니다.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 126px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;res.end()&amp;nbsp;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 373px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;응답 프로세스를 종료합니다.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 126px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;res.json()&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 373px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;JSON 응답을 전송합니다.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 126px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;res.jsonp()&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 373px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;JSONP 지원을 통해 JSON 응답을 전송합니다.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 126px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;res.redirect()&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 373px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;요청의 경로를 재지정합니다.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 126px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;res.render()&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 373px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;보기 템플리트를 렌더링합니다.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 126px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;res.send()&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 373px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;다양한 유형의 응답을 전송합니다.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 126px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;res.sendFile()&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 373px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;파일을 옥텟 스트림의 형태로 전송합니다.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;width: 126px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;res.sendStatus()&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 373px; height: 24px; border-bottom: 1px solid rgb(204, 204, 204); border-right: 1px solid rgb(204, 204, 204);&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;맑은 고딕&amp;quot;, sans-serif;&quot;&gt;응답 상태 코드를 설정한 후 해당 코드를 문자열로 표현한 내용을 응답 본문으로서 전송합니다.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div style=&quot;font-size: 16px;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;&quot;&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;다음 포스트에서는 middleware란 무엇이며 어떻게 쓰는 것인지에 대해 알아보도록&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;하자.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;style&gt;
@import url(http://fonts.googleapis.com/earlyaccess/notosanskr.css);

*{
  font-family: 'Noto Sans KR', sans-serif !important;
}
.subtitle &amp;amp;gt; li{
  font-size: 20px;
  font-weight: bold;
}
&lt;/style&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Node.js/express</category>
      <category>express</category>
      <category>node.js</category>
      <category>Router</category>
      <category>노드</category>
      <category>파헤쳐보자</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/7</guid>
      <comments>https://psyhm.tistory.com/7#entry7comment</comments>
      <pubDate>Wed, 14 Mar 2018 01:08:15 +0900</pubDate>
    </item>
    <item>
      <title>node.js express 3. static file 정적 파일 옵션, path 모듈</title>
      <link>https://psyhm.tistory.com/6</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;이전 포스트 : &lt;/span&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&lt;a class=&quot;tx-link&quot; href=&quot;http://psyhm.tistory.com/5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://psyhm.tistory.com/5&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;&lt;span style=&quot;font-size: 12pt;&quot;&gt;저번 포스트에서는&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;router 객체와 render란 무엇인가에&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;대해 공부했었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;이제 &lt;b&gt;정적 파일&lt;/b&gt;(이미지 파일, javascript 파일, css 파일) 등을&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;express 서버가 어떻게 제공하는 지 알아보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;정적 파일(Static files)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;express가 &lt;b&gt;static files(정적 파일들)&lt;/b&gt;을 제공하기 위해선&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;express.static 미들웨어&lt;/b&gt;를 사용해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&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;&lt;span style=&quot;font-size: 16px;&quot;&gt;사용 방법은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;express.static(root, [options]);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;root&lt;/b&gt;는 정적 파일들이 위치한 경로를&amp;nbsp;&lt;b&gt;string &lt;/b&gt;타입으로 적으면 되고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;options&lt;/b&gt;는 속성을 키값으로 한 &lt;b&gt;객체&lt;/b&gt;를 넣으면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;options는 다음 테이블에서 확인 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;txc-table&quot; style=&quot;border: none; border-collapse: collapse; width: 750px;&quot; border=&quot;0&quot; width=&quot;508&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 102px; height: 24px; background-color: #d9e5ff; border: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;b&gt;&amp;nbsp;속성&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 486px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-top: 1px solid #cccccc; background-color: #d9e5ff;&quot;&gt;&lt;span&gt;&lt;b&gt;설명&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 70px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-top: 1px solid #cccccc; background-color: #d9e5ff;&quot;&gt;&lt;span&gt;&lt;b&gt;타입&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 90px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-top: 1px solid #cccccc; background-color: #d9e5ff;&quot;&gt;&lt;span&gt;&lt;b&gt;디폴트&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 102px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-left: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;b&gt;&amp;nbsp;dotfiles&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 486px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&amp;nbsp;&quot;.&quot; 으로 시작하는 폴더나 파일을 어떻게 다룰 것인지에 대한 설정&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 70px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;String&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 90px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&amp;nbsp;&quot;ignore&quot;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 102px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-left: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;b&gt;&amp;nbsp;etag&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 486px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&amp;nbsp;etag를 생성할 건지에 대한 설정(웹 캐시)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 70px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;Boolean&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 90px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;true&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 102px; height: 78px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-left: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;b&gt;&amp;nbsp;extenstions&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 486px; height: 78px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&amp;nbsp;파일 확장자 대체 설정: 만약 file이 존재하지 않는다면 지정된 확장자를 가진 파일을 검색하고 발견된 첫번째 파일을 제공. ex) ['html', 'htm']&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 70px; height: 78px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: '맑은 고딕', sans-serif;&quot;&gt;Mixed&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 90px; height: 78px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;span style=&quot;font-family: '맑은 고딕', sans-serif;&quot;&gt;false&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 102px; height: 26px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-left: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;b&gt;&amp;nbsp;fallthrough&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 486px; height: 26px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;(클라이언트 오류에 대한 것이라고 나오는데 어떤 때 쓰는 지 잘 모르겠다..)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 70px; height: 26px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&amp;nbsp;Boolean&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 90px; height: 26px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;true&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 102px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-left: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;b&gt;&amp;nbsp;immutable&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 486px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&amp;nbsp;Cache-Control 응답 헤더에서 immutable 사용유무를 결정합니다.&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 70px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;Boolean&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 90px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;false&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 102px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-left: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;b&gt;&amp;nbsp;index&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 486px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&amp;nbsp;지정된 디렉토리 index file을 전송합니다.&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 70px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;Mixed&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 90px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&quot;index.html&quot;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 102px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-left: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;b&gt;&amp;nbsp;lastModified&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 486px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&amp;nbsp;Last-Modified 헤더를 OS에서 파일의 마지막 수정 날짜로 합니다.&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 70px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;Boolean&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 90px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;true&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 102px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-left: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;b&gt;&amp;nbsp;maxAge&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 486px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&amp;nbsp;Cache-Control 헤더의 max-age 값을 설정합니다.&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 70px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;Number&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 90px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;0&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 102px; height: 39px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-left: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;b&gt;&amp;nbsp;redirect&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 486px; height: 39px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&amp;nbsp;pathname이 디렉토리인 경우 후미 &quot;/&quot;로 리다이렉트 한다.(???)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 70px; height: 39px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;Boolean&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 90px; height: 39px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;true&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 102px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-left: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;b&gt;&amp;nbsp;setHeaders&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 486px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&amp;nbsp;응답시 사용자 정의 헤더를 설정하는 기능. (밑에 부연설명)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 70px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;function&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 90px; height: 24px; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc;&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;※ &lt;b&gt;immutable&lt;/b&gt;:&amp;nbsp;immutable은 브라우저 캐시가 fresh(&lt;b&gt;max-age 내&lt;/b&gt;) 상태이면 페이지를 다시 로드할 때 Conditional GET을 발생시키는 대신 &lt;b&gt;무조건 fresh Cache&lt;/b&gt;를 사용합니다. (정적파일 제공시 유용할 듯)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;※ &lt;b&gt;setHeaders&lt;/b&gt;:&amp;nbsp;헤더에 대한 변경은 동기적으로 발생해야 합니다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;이 함수는 fn(res, path, stat)이며 인수는 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;res&lt;/b&gt;: the response object&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;path&lt;/b&gt;: the file path that is being sent&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;stat&lt;/b&gt;: the stat object of the file that is being sent&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;express.static 예제&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;var options = {
  dotfiles: 'ignore',
  etag: false,
  extensions: ['htm', 'html'],
  index: false,
  maxAge: '1d',
  redirect: false,
  setHeaders: function (res, path, stat) {
    res.set('x-timestamp', Date.now())
  }
}

app.use(express.static('public', options))
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;사실 위의 설정을 몰라도 무난하게 쓸 수 있으나 알고 있다가 나중에&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;세부 설정이 필요할 때 쉽고 빠르게 찾을 수 있으니 뭐가 있는지만 알아두자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;그리고 이 &lt;b&gt;express.static(root, [options]);&lt;/b&gt;을 express에서 사용하고자 한다면&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;app.js 파일 23째줄&lt;/b&gt;을 보면 이미 사용된 것을 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;app.use(express.static(path.join(__dirname, 'public')));
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;app.use()&lt;/b&gt;함수는 나중으로 일단 미루자. 지금 설명하기에는 이정도 설명이면 충분할 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;app.use()&amp;nbsp;함수는 클라이언트가 서버에 요청을 할 때 중간에 거쳐가는 함수를 사용(use)하려고 할 때 사용한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;라고 보면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;간단히 &lt;b&gt;express 서버에서 express.static(path.join(__dirname, 'public'))을 사용하겠다&lt;/b&gt;라고 보면&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;될 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;일단 express.static()함수에 &lt;b&gt;path.join() 함수&lt;/b&gt;가 사용된 것을 알 수 있고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;옵션은 없으니 모두 디폴트값&lt;/b&gt;을 사용하는 것을 알수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 24pt;&quot;&gt;&lt;b&gt;Path 모듈&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;먼저 &lt;b&gt;path 객체&lt;/b&gt;를 보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;path에 대한 설명은 아래 url에서 document를 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;출처: &lt;a class=&quot;tx-link&quot; href=&quot;https://nodejs.org/docs/latest/api/path.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nodejs.org/docs/latest/api/path.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;path&lt;/b&gt;는 말 그대로 &lt;b&gt;경로에 관련된 모듈&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;파일 경로를 쓰는데 문자열을 직접 자르고 합치는 것보다 path에서 제공하는&lt;b&gt; join 함수&lt;/b&gt;를&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;사용하는 것이 편하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;그리고 &lt;b&gt;__dirname&lt;/b&gt;은 node.js에서 제공하는 &lt;b&gt;node 파일의 경로&lt;/b&gt;를 담고 있는 변수이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;Node.js의 &lt;b&gt;global object&lt;/b&gt;의 변수이므로 Node.js&lt;b&gt; 어떤 모듈이든 접근 가능&lt;/b&gt;합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;global object에 관한 내용은 아래 url에서 document를 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;출처: &lt;a class=&quot;tx-link&quot; href=&quot;https://nodejs.org/dist/latest-v8.x/docs/api/globals.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nodejs.org/dist/latest-v8.x/docs/api/globals.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;path.join()&lt;/b&gt; 함수는 각 파라미터를 합쳐서 경로 문자열을 반환한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;따라서 path.join(__dirname, 'public')는 &lt;b&gt;'현재 app.js 파일의 경로 + /public'&lt;/b&gt;을 리턴한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;public 디렉토리 안의 정적 파일&lt;/b&gt;들을&lt;b&gt; 제공&lt;/b&gt;할 수 있도록 만들어야하기 때문이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&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;&lt;span style=&quot;font-size: 16px;&quot;&gt;public 디렉토리로 가보면 다음 폴더들을 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: square;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;images&lt;/b&gt;:&amp;nbsp;이미지 파일 저장하는 곳&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;javascripts&lt;/b&gt;:&amp;nbsp;웹페이지에서 쓰이는 자바스크립트 파일들 저장하는 곳&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;stylesheets&lt;/b&gt;:&amp;nbsp;웹페에지에서 쓰이는 css 파일들을 저장하는 곳&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;예를 들어 images 폴더에 있는 test.jpg 파일을 접근하기 위해서&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;웹브라우저에서 &quot;http://domain/&lt;b&gt;images/test.jpg&lt;/b&gt;&quot;를 입력하면 접근할 수 있다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;조금이라도 효율을 높이고 싶다면 폴더 명을 img, js, css로 바꾸는 것을 권장한다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;문자열 조금(진짜 조금) 바뀌는 게 얼마나 좋겠어 라고 생각하겠지만&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;네이버 같은 큰 웹서비스에서 하루에 오는 요청 양을 생각하면&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;바꾸는 것도 괜찮다고 생각이 들지 않는가?(아니면 말고..)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;그런데 보통의 웹서비스에서 정적파일들은 Node.js보단 nginx 같은 &lt;b&gt;프록시 서버&lt;/b&gt;가&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;메모리 캐시&lt;/b&gt;를 이용하여 &lt;b&gt;정적 파일(static file)들을 제공&lt;/b&gt;한다고 한다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;프록시 서버를 거쳐 express가 돌아가는 서버에 와서 제공하는 것보다&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;b&gt;프록시 서버가 바로 제공&lt;/b&gt;하는 것이 좀 더 빠르기 때문이다.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;따라서 정적파일 부분은 여기까지 하도록 하겠다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;그리고 &lt;b&gt;app.use()&lt;/b&gt; 함수는 다음&lt;b&gt; middleware&lt;/b&gt;에 대한 포스팅때 언급하도록 하겠다.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Node.js/express</category>
      <category>express</category>
      <category>node.js</category>
      <category>노드</category>
      <category>파헤쳐보자</category>
      <author>Labhong</author>
      <guid isPermaLink="true">https://psyhm.tistory.com/6</guid>
      <comments>https://psyhm.tistory.com/6#entry6comment</comments>
      <pubDate>Sun, 4 Mar 2018 18:23:56 +0900</pubDate>
    </item>
  </channel>
</rss>