<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.2">Jekyll</generator><link href="https://suhwan2004.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://suhwan2004.github.io/" rel="alternate" type="text/html" /><updated>2022-06-30T16:01:00+00:00</updated><id>https://suhwan2004.github.io/feed.xml</id><title type="html">far away</title><subtitle>이것 저것 기록하는 곳</subtitle><author><name>Suhwan Kim</name><email>suhwan2004@gmail.com</email></author><entry><title type="html">JS - for, Array.loopFunction</title><link href="https://suhwan2004.github.io/frontend/LoopAndArrayFunc/" rel="alternate" type="text/html" title="JS - for, Array.loopFunction" /><published>2022-06-30T00:00:00+00:00</published><updated>2022-06-30T00:00:00+00:00</updated><id>https://suhwan2004.github.io/frontend/LoopAndArrayFunc</id><content type="html" xml:base="https://suhwan2004.github.io/frontend/LoopAndArrayFunc/">&lt;h2 id=&quot;1-for--in--과-for-of-의-차이점은-무엇일까&quot;&gt;1. for … in … 과 for …of… 의 차이점은 무엇일까?&lt;/h2&gt;

&lt;p&gt;평소에, 코딩테스트를 풀 때에도…&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;array의 인덱스 상관없이 값을 다 돌면서 볼 때&lt;/li&gt;
  &lt;li&gt;object의 key와 value를 하나씩 돌려볼 때&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;보통 이럴 때에, for in과 of를 잘 활용했던 것 같습니다.&lt;/p&gt;

&lt;p&gt;하지만, 둘 다 쓰면서도 이 둘의 차이는 뭐고 어느상황에는 뭘 써야되지? 라는 고민이 많았습니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;아래는 MDN에서 정의한 for in과 for of 입니다.&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;for--in&quot;&gt;for … in&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;forEach문은 객체의 열거 속성을 통해 지정된 변수를 반복합니다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;각각의 고유한 속성&lt;/strong&gt;에 대해, JavaScript는 지정된 문을 실행합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;forof&quot;&gt;for…of&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;for…of문은 각각의 &lt;strong&gt;고유한 특성의 값&lt;/strong&gt;을 실행할 명령과 함께 사용자 지정 반복 후크를 호출합니다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;반복가능한 객체(배열, Map, Set, arguments 객체….)&lt;/strong&gt; 를 통해 반복하는 루프를 만듭니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;여기서 볼 수 있는 둘의 키워드의 차이는 &lt;strong&gt;고유한 속성&lt;/strong&gt;, &lt;strong&gt;고유한 특성의 값&lt;/strong&gt;입니다.&lt;/p&gt;

&lt;p&gt;이 키워드가 어떻게 적용되는지는 아래의 코드를 한번 볼까요?&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// logs &quot;0&quot;, &quot;1&quot;, &quot;2&quot;, &quot;foo&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// logs &quot;3&quot;, &quot;5&quot;, &quot;7&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;for …in의 경우는 고유한 속성의 이름으로 돌기 때문에 arr.foo에도 접근합니다.
    &lt;ul&gt;
      &lt;li&gt;한가지 더 팁이 있다면, for… in의 경우 value에 접근할 방법을 제공하지 않습니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;하지만, for…of의 경우에는 값을 기반으로 접근하기 때문에 key인 foo가 나오지 않습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;추가로, key:value로만 구성되어 있는 object가 기준일 땐 어떨까요?&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;수환&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//logs  &quot;a&quot;, &quot;b&quot;, &quot;c&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//TypeError: obj is not iterable&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;in을 사용할 시, key에는 접근이 가능하기에 a,b,c를 출력합니다.&lt;/li&gt;
  &lt;li&gt;of의 경우 에러가 났습니다.
    &lt;ul&gt;
      &lt;li&gt;지금 object는 반복 가능한 객체가 아니기 때문에 오류가 난 것입니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;그럼-obj은-of를-통해서-값을-못-보는-건가요&quot;&gt;그럼, obj은 of를 통해서 값을 못 보는 건가요??&lt;/h3&gt;

&lt;p&gt;아닙니다. Object의 메소드를 통해 재가공 후 해결이 가능합니다.
아래와 같은 종류가 있습니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Object.keys(원하는객체) =&amp;gt; 키만 빼서 만들어진 배열반환&lt;/li&gt;
  &lt;li&gt;Object.values(원하는객체) =&amp;gt; 값만 빼서 만들어진 배열반환&lt;/li&gt;
  &lt;li&gt;Object.entries(원하는객체) =&amp;gt; [키,값]으로 빼서 만들어진 배열반환&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;요것들을 써서 for…of를 돌아볼까요?&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;수환&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//logs. &quot;a&quot;, &quot;b&quot;, &quot;c&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//logs. 1, 2, &quot;수환&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;entries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//logs. &quot;a&quot;, 1  ,  &quot;b&quot;, 2   ,  &quot;c&quot;,&quot;수환&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이런 식으로, Object의 내장함수를 통해서도 반복문을 돌 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;2-foreach-map-filter-reduce&quot;&gt;2. forEach, map, filter, reduce…&lt;/h2&gt;

&lt;p&gt;일단, 위의 함수는 Array의 고차함수입니다. 고차함수란 무엇일까요?
=&amp;gt; &lt;strong&gt;고차함수는 함수를 인수로 전달받거나 함수를 반환하는 함수를 말합니다.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;기존에 배열을 한번 돌려면 for, while을 써야 했는데 여기에서 &lt;strong&gt;변수를 새로 만들어야 되는 상황이 필연적으로 발생했습니다.&lt;/strong&gt; (for의 let i를 만들기 같은…)&lt;/p&gt;

&lt;p&gt;또한, 한줄로 반복문을 구현하고 싶은데 코드줄을 좀 잡아먹기도 하죠 ㅋㅋㅋ…&lt;/p&gt;

&lt;p&gt;그렇기에, 기존 반복문에서의 &lt;strong&gt;변수의 사용을 억제&lt;/strong&gt;하고 &lt;strong&gt;코드를 단순화&lt;/strong&gt;하기 위해서 밑에서 배울 함수들을 사용하게 된 것입니다.&lt;/p&gt;

&lt;p&gt;자 하나씩 살펴볼까요?&lt;/p&gt;

&lt;h3 id=&quot;1-arrayprototypeforeach&quot;&gt;1. Array.prototype.forEach&lt;/h3&gt;

&lt;p&gt;코드를 보면 매우 빠르게 이해될 것 같습니다. 코드를 볼까요?&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;pows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위의 코드는 일반 for문을 통해서 numbers의 각 값들에 2를 곱한 값들을 pows에 push해주는 코드입니다.
이 코드는 forEach를 통해 더 깔끔하게 짤 수 있습니다. 한번, forEach를 쓴 코드를 봐볼까요?&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;코드가 매우매우매우 깔끔하게 바뀌었습니다. forEach를 좀 더 봐볼까요?
forEach는 대락 이렇게 생겼습니다.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;요소값&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;동작할_구문&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위의 코드에는 인수를 하나만 받았지만, 사실 &lt;strong&gt;세 개의 인수들을 얻을 수 있습니다.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;첫 째는 당연하게도, &lt;strong&gt;요소값&lt;/strong&gt;입니다. 위에서는 1,2,3을 받았습니다.&lt;/li&gt;
  &lt;li&gt;두 번째는 &lt;strong&gt;인덱스&lt;/strong&gt;입니다. 아마 받는다면 0,1,2를 받겠네요.&lt;/li&gt;
  &lt;li&gt;세 번째는 &lt;strong&gt;this&lt;/strong&gt;입니다. 여기서의 this는 forEach를 호출한 배열 Array입니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;또한, &lt;strong&gt;화살표 함수 옆에 동작할 구문들을 넣어줍니다.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;한 줄일 경우는 위의 코드처럼 블록을 쳐줄 필요 없습니다.&lt;/li&gt;
  &lt;li&gt;하지만, 여러 줄일 경우에는 위의 forEach 해부도처럼 블록을 만들어야겠죠?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;더 추가적으로 알아야 할 것이 있다면….&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;forEach의 내부는 사실 for문이 수행됩니다.&lt;/strong&gt; 다만, 코드를 숨긴 것이지요.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;forEach는 break, continue를 못 씁니다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;forEach의 성능은 순수 for보다는 나쁩니다.&lt;/strong&gt; 그래도, 코드가 깔끔해지죠.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;2-arrayprototypemap&quot;&gt;2. Array.prototype.map&lt;/h3&gt;

&lt;p&gt;분명 js에는 hashMap을 만드는 new Map()이 있었죠? 그 맵이랑은 다릅니다. 조심!&lt;/p&gt;

&lt;p&gt;바로 코드로 볼까요?&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//Math.sqrt(item) === item ** 2&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위에서 forEach를 볼 때 썼던 코드와 아예 똑같은 코드입니다. 하지만, 한 줄이 더 줄었네요??&lt;/p&gt;

&lt;p&gt;일단, 왜 이런 상황이 발생했는지 설명하기 전에 map도 한번 까볼까요?&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;요소값&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;동작할_구문&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;값&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;보면, 위의 forEach와 인수도 똑같습니다. 하지만, 차이가 존재하는데요.
&lt;strong&gt;map은 현재 보는 배열과 길이가 똑같은 배열에 각 인덱스값을 동작할_구문에서 반환한 값을 push해줍니다.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;그렇기, 때문에 위의 코드를 자세히 보면 식별자 pows로 반환된 배열을 받아주는 모습을 볼 수 있죠!&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;3-arrayprototypefilter&quot;&gt;3. Array.prototype.filter&lt;/h3&gt;

&lt;p&gt;다음은 filter입니다. 뭔가, 이름부터 어떤 조건으로 거른다는 느낌이 나죠?
말 그대로의 의미를 가지고 있는 함수입니다. 코드를 볼까요?&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;odds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;odds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//logs. [1,3,5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위의 코드는 numbers의 요소들 중 홀수들만 남긴 새로운 배열을 만들고, console.log로 찍어주는 코드입니다.&lt;/p&gt;

&lt;p&gt;해부도는 아래와 같습니다.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;요소값&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;동작할_구문&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;조건&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위의, forEach, map과 인수는 비슷합니다. 또한, map처럼 새로 만들어진 배열도 반환해줍니다.&lt;/p&gt;

&lt;p&gt;다만, 차이점이 있죠. &lt;strong&gt;return을 요소값을 새 배열에 push할 조건으로 넣습니다.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;위의 코드를 보면 한줄 적힌 구문은 {return item%2===1}와 같습니다.
=&amp;gt; &lt;strong&gt;그렇기에, 각 item을 2로 나눴을 때 나머지값이 1이면 홀수이고 이런 홀수인 item만 odds에 push되는 것이지요.&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;4-arrayprototypereduce&quot;&gt;4. Array.prototype.reduce&lt;/h3&gt;

&lt;p&gt;reduce의 경우 위의 것들과 성질이 살짝 다릅니다. 코드부터 보겠습니다.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cur&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;prev&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cur&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//logs. 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위의 코드를 보면, 뭔가 1+2+3+4를 해서 10을 받고 출력하는 것 같죠?
일단, reduce도 분해해볼까요?&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;accumulator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;실행문&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;초기값&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;currentValue, item, this는 위의 map, forEach와 동일합니다.
accumulator의 경우 매 턴마다 달라지는 값입니다. - &lt;strong&gt;accumulator는 실행문에서 반환한 값으로 매 턴마다 갱신됩니다.&lt;/strong&gt; - 또한, &lt;strong&gt;accumulator의 최초값은 실행문 옆에 초기값&lt;/strong&gt;입니다.&lt;/p&gt;

&lt;p&gt;그렇기 때문에, 위의 코드의 동작과정은 이렇게 볼 수 있는거죠.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;cur = 1 일때 , prev = 1 + 0&lt;/li&gt;
  &lt;li&gt;cur = 2 일때 , prev = 2 + 1&lt;/li&gt;
  &lt;li&gt;cur = 3 일때 , prev = 3 + 3&lt;/li&gt;
  &lt;li&gt;cur = 4 일때, prev = 6 + 4 = 10이 나옴.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;5-요약&quot;&gt;5. 요약&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;forEach는 배열을 한번 돕니다.&lt;/li&gt;
  &lt;li&gt;map은 배열을 한번 돌며, 새로운 배열을 반환합니다.&lt;/li&gt;
  &lt;li&gt;filter는 배열을 한번 돌며, 조건에 맞는 값만으로 구성된 새로운 배열을 반환합니다.&lt;/li&gt;
  &lt;li&gt;reduce는 배열을 한번 돌며, 누적 계산된 하나의 값을 반환합니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;reference&quot;&gt;Reference&lt;/h2&gt;

&lt;p&gt;Javascript deep dive(책)
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Loops_and_iteration
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce&lt;/p&gt;</content><author><name>Suhwan Kim</name><email>suhwan2004@gmail.com</email></author><category term="FrontEnd" /><category term="JavaScript" /><summary type="html">1. for … in … 과 for …of… 의 차이점은 무엇일까?</summary></entry><entry><title type="html">Internet - 인터넷은 무엇이고 어떻게 동작할까?</title><link href="https://suhwan2004.github.io/network/whatisInternet/" rel="alternate" type="text/html" title="Internet - 인터넷은 무엇이고 어떻게 동작할까?" /><published>2022-06-30T00:00:00+00:00</published><updated>2022-06-30T00:00:00+00:00</updated><id>https://suhwan2004.github.io/network/whatisInternet</id><content type="html" xml:base="https://suhwan2004.github.io/network/whatisInternet/">&lt;h2 id=&quot;갑자기-인터넷은-왜&quot;&gt;갑자기, 인터넷은 왜?&lt;/h2&gt;

&lt;p&gt;사실, node.js &amp;amp; express를 배워야 될 일이 생겼는데 MDN 의 튜토리얼을 따라 공부할려 했으나 선행 조건이 있었습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/176708911-7c0c47c9-d687-48b8-977e-93124bc3f1cf.png&quot; alt=&quot;image&quot; /&gt;
(node.js 바로 공부하기 멈춰!)&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;웹 서버란 무엇인가?&lt;/li&gt;
  &lt;li&gt;웹사이트를 만들기 위해서는 어떤 소프트웨어가 필요한가?&lt;/li&gt;
  &lt;li&gt;어떻게 웹 서버가 파일을 업로드하는가?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;당연히도 , 셋 다 제대로 남에게 설명할 수준이 아니기에 입구컷을 당했습니다.&lt;/p&gt;

&lt;p&gt;심지어, 웹 서버부터 공부해보자! 하고 들어가니 다단계처럼 계속 선행으로 해야될 것이 생겨나는 현상이 발생했구요…&lt;/p&gt;

&lt;p&gt;그리하야, 첫번째로 정리할 것이 인터넷은 어떻게 동작하는가? 입니다!&lt;/p&gt;

&lt;h2 id=&quot;인터넷은-뭐고-어떻게-생겨났나요&quot;&gt;인터넷은 뭐고, 어떻게 생겨났나요?&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;인터넷은 인터넷 프로토콜 스위트(TCP/IP)를 기반으로 전 세계적으로 연결되어있는 컴퓨터 네트워크 통신망&lt;/strong&gt;입니다.
=&amp;gt; &lt;a href=&quot;https://suhwan2004.github.io/frontend/WhatIsTCP/&quot;&gt;이 글을 보시면 TCP/IP가 무엇인지 초장에 간략히 나옵니다!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;또한, 최초의 시작이 언제인지 명확하게 알려졌지 않았습니다. MDN에서는 1960년 대 미육군에서 연구 프로젝트로 시작이 되었다고 하는데요.&lt;/p&gt;

&lt;p&gt;이런 지루한 얘기는 넘겨두고 왜 인터넷이 만들어 졌나 한번 같이 생각해볼까요?&lt;/p&gt;

&lt;p&gt;과거의 컴퓨터는 말 그대로 혼자였습니다. 계산기로써 계산 결과를 종이로 찍어서 출력하고, 암호를 분석하고 이런 기능적인 면이 좀 강했죠.&lt;/p&gt;

&lt;p&gt;세월이 흐르면서, 컴퓨터는 발전했습니다. 그에 따라서, 다른 컴퓨터에서 얻은 자료를 내 컴퓨터로 가져와야 되는 일도 있었을 겁니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/176713191-d691ffa9-50cd-4854-8bc9-087f538f650b.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;그런 상황을 해결하기 위해 내 컴퓨터와 다른 컴퓨터를 케이블같은 것으로 연결했죠.&lt;/strong&gt;
=&amp;gt; 지금은 wifi, bluetooth 같은 무선으로도 인터넷의 연결이 가능하나, 지금은 유선을 기준으로 두겠습니다.&lt;/p&gt;

&lt;p&gt;하지만, 단순히 1:1은 부족했죠. 한 부서가 같은 네트워크를 사용해야 될 때도 있었고, 한 회사가 네트워크를 이뤄야 될 필요도 있었습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/176714008-59f3ade3-11fd-4013-aaf6-536ce7b7de03.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;다만, 선이 계속 늘어나다 보니 어디로 가는 선인지 구별 못하는 혼돈의 카오스가 발생했습니다.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;당장 위의 컴퓨터 10대만 해도 필요한 케이블이 45개입니다. 그 당시, 이걸 직접 쓰셨던 분들은 어질어질했겠죠?&lt;/p&gt;

&lt;p&gt;이런 문제를 해결하기 위해 &lt;strong&gt;라우터&lt;/strong&gt;가 나왔습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/176714449-162b26bb-f103-4908-9f58-7a2d34f7229b.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;라우터는 일종의 특수한 소형컴퓨터입니다. 라우터에는 한 가지 작업만이 존재하는데요.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A에서 보낸 메시지가 B로 제대로 향했는지 확인하는 기능&lt;/strong&gt;이였습니다. 다른 컴퓨터로 메시지가 새지 않게도 해주었죠.&lt;/p&gt;

&lt;p&gt;이렇게, 라우터를 추가하니 필요 케이블이 많이 줄었고, 라우터를 이용해 하나의 네트워크를 구축할 수 있었습니다.&lt;/p&gt;

&lt;p&gt;다만, 네트워크는 한 개가 아니죠? 컴퓨터가 점차 보급되면서 정말 무수히 많은 네트워크들이 생겨났습니다. 당연히도 네트워크 속에 네트워크가 생겼습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/176715886-4b2e1c6b-3115-42c2-b635-5aebf9785f7f.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;네트워크 속 네트워크의 모습은 대략 이런 느낌입니다.&lt;/p&gt;

&lt;p&gt;여기서도 문제가 또 발생합니다.
이런 형태의 네트워크는 분명 저희가 알고있는 인터넷과 비슷합니다.&lt;/p&gt;

&lt;p&gt;그러나, 이런 네트워크가 인터넷이라면 한국에 있는 저와 미국에 있는 MoMo님이라는 분과 서로 메일을 주고 받을려면 어떤 네트워크가 구축되야 될까요?&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/176717848-66c26e85-87cc-4af8-a57e-4f7efdd77a74.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;대한민국 라우터에서부터 중앙 라우터까지 케이블을 쭉~~ 이은 다음에, 중앙 라우터에서 미국 라우터까지 케이블을 연결해야 되겠죠.&lt;/p&gt;

&lt;p&gt;대한민국에서 미국까지의 거리는 검색해보니 10,736 km입니다. 중앙 라우터가 바다 한 가운데에 있다 해도 필요한 케이블의 최소 길이는 5,368km겠죠.&lt;/p&gt;

&lt;p&gt;현재, 인간의 기술력으로는 통신 오류가 나지 않는 5천 킬로 짜리 통신 케이블을 만드는 것은 불가능합니다.&lt;/p&gt;

&lt;p&gt;만든다고 해도 매우매우매우 비효율적이죠.&lt;/p&gt;

&lt;p&gt;이런 문제를 해결하기 위해, 어느 누군가가 이런 생각을 합니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“전 세계 어느 곳과도 연결이 되어있는 전화기 기반 시설을 쓰면 어떨까?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;그걸 실행에 옮기기 위해서는 &lt;strong&gt;우리의 네트워크를 전화 시설과 먼저 연결&lt;/strong&gt;을 시켜야 했습니다. 그리고, 그 때 필요한 장치가 &lt;strong&gt;모뎀&lt;/strong&gt;이죠.&lt;/p&gt;

&lt;p&gt;이 모뎀은 우리의 네트워크의 정보를 전화 시설에서 처리할 수 있는 정보로 바꾸며, 그 반대의 경우도 마찬가지 입니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/176718103-80f9443a-b0e3-4c48-88f7-548cce1241b1.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그리하여, 우리의 네트워크는 전화시설에 연결될 수 있었고 대략 이런 모습이 됬습니다.&lt;/p&gt;

&lt;p&gt;이제 다음 관문으로 가죠. 저희 네트워크에서 목적 네트워크까지 네트워크로 메시지를 보내줘야 됩니다.&lt;/p&gt;

&lt;p&gt;그렇게 하기 위해서는, 네트워크를 인터넷 서비스 제공 업체(ISP)에 연결합니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ISP란? : 모두 함께 연결되는 몇몇 특수한 라우터를 관리하고 다른 ISP의 라우터에도 엑세스 할 수 있는 회사입니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/176718960-84d11b8b-e947-4577-96de-42c078d46853.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;ISP 덕분에 저는 MoMo님에게 메시지를 보낼 수 있게 됬고, 이 과정에서 드디어 전체 네트워크 인프라가 구축이 된 모습입니다.&lt;/p&gt;

&lt;p&gt;MoMo님 뿐 아니라, 제가 구글 페이지에 들어가는 것도 하나의 네트워크 통신이겠죠.&lt;/p&gt;

&lt;p&gt;이는 주소창에 구글의 IP 주소를 치는 것으로 시작되나 매우 기억하기도 어렵기에 구글의 URL을 넣는 걸로 시작됩니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://mdn.mozillademos.org/files/8405/dns-ip.png&quot; alt=&quot;Show how a domain name can alias an IP address&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이 URL을 네임서버라는 곳으로 보내고 IP를 가져옴으로써 통신을 할텐데 이건 웹의 동작방식입니다. 이에 도움되는 글은 아래에 있습니다.
=&amp;gt; &lt;a href=&quot;https://suhwan2004.github.io/frontend/BrowserRendering1/&quot;&gt;주소창에 구글을 치면 어떻게 될까?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;여기까지가 인터넷이 어떻게 생겨났고, 어떤 방식으로 동작되는지였습니다.&lt;/p&gt;

&lt;p&gt;다음 글에서는 웹 사이트, 웹 페이지, 웹 서버 그리고 검색엔진의 차이와 웹 서버에 대해 자세히 알아보겠습니다.&lt;/p&gt;</content><author><name>Suhwan Kim</name><email>suhwan2004@gmail.com</email></author><category term="Network" /><category term="Network" /><summary type="html">갑자기, 인터넷은 왜?</summary></entry><entry><title type="html">Git - Git으로 만드는 전설의 레시피</title><link href="https://suhwan2004.github.io/git/UdemyGitLectureSummery/" rel="alternate" type="text/html" title="Git - Git으로 만드는 전설의 레시피" /><published>2022-06-22T00:00:00+00:00</published><updated>2022-06-22T00:00:00+00:00</updated><id>https://suhwan2004.github.io/git/UdemyGitLectureSummery</id><content type="html" xml:base="https://suhwan2004.github.io/git/UdemyGitLectureSummery/">&lt;p&gt;udemy의 Git으로 만드는 전설의 레시피 강의를 필기한 내용입니다!&lt;/p&gt;

&lt;h2 id=&quot;section-1-git이란-대체-뭘까&quot;&gt;Section 1. git이란 대체 뭘까?&lt;/h2&gt;

&lt;p&gt;Git은 버전을 편리하게 관리하게 만들어주는 도구입니다.&lt;/p&gt;

&lt;p&gt;예를들어 학교 과제를 할 때…&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;최종, 진짜 최종, 진짜진짜 최종과 같은 파일명으로 버전관리를 하는 경우가 있다고 해볼까요?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;이러면 각 버전 별로, 어떤 수정 사항이 있는지 알 수 없기 때문에 하나하나 다 열어봐야 하는 문제가 발생합니다.&lt;/p&gt;

&lt;p&gt;하지만, git을 쓴다면? 이런 단점을 부술 뿐 아니라 장점도 있습니다!&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;최정 과정까지의 히스토리를 관리할 수 있다.&lt;/li&gt;
  &lt;li&gt;이전 버전으로 타임머신을 타고 돌아갈 수 있다.&lt;/li&gt;
  &lt;li&gt;동료와 협업할 수 있는 환경을 만들어 준다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;이런 git과 친구인 github도 많이 들어본 것일텐데요.&lt;/p&gt;

&lt;p&gt;github는 git으로 저장된 내역들을 원격으로 관리하고 저장하는 공간을 제공하는 서비스입니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;git은 동영상이면 github는 유튜브&lt;/strong&gt;라고 볼 수 있습니다!&lt;/p&gt;

&lt;h2 id=&quot;section2-git으로-간단한-레시피-만들어보기&quot;&gt;Section2. Git으로 간단한 레시피 만들어보기&lt;/h2&gt;

&lt;h3 id=&quot;1-commit---git-초기화와-로컬저장소-최초의-커밋-만들기&quot;&gt;1. commit - Git 초기화와 로컬저장소, 최초의 커밋 만들기&lt;/h3&gt;

&lt;p&gt;git init&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;git을 사용하겠다라는 명령을 내려주는 것.&lt;/li&gt;
  &lt;li&gt;로컬 저장소가 만들어짐.(숨겨진 폴더인 .git이 로컬 저장소임)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;git add 파일이름&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;버전으로 관리할 파일을 추가하는 것.&lt;/li&gt;
  &lt;li&gt;아직 버전에 포함되어 있지 않음. 말 그대로 추가만 한 상태임.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;git commit -m “쓰고싶은 메시지”&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;의미있는 변경사항을 묶어서 만드는 과정&lt;/li&gt;
  &lt;li&gt;-m은 해당 버전 상태에 대한 기록을 남기겠다는 뜻임.&lt;/li&gt;
  &lt;li&gt;git log —online을 통해 편하게 내역을 볼 수 있음.&lt;/li&gt;
  &lt;li&gt;add 명령어는 사진기 앞에 물건을 두는 것이라면 commit은 사진을 찍는 것.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-push---github-원격-저장소에-내가-만든-레시피-업로드하기&quot;&gt;2. push - Github 원격 저장소에 내가 만든 레시피 업로드하기&lt;/h3&gt;

&lt;p&gt;git remote add origin 주소&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;remote는 원격 저장소, add는 더해주기, origin은 원격저장소를 나타낼 주소입니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;git remote -v&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;내가 등록한 원격 저장소를 알 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;git branch -M main&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;메인이 될 브랜치를 main으로 설정합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;git push -u origin main&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;origin(원격저장소)의 main 브랜치에 push 한다는 뜻임.&lt;/li&gt;
  &lt;li&gt;-u는 로컬저장소를 원격 저장소에 연결하기 위해 사용하는 것이며 한번만 사용하면 됩니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;3-pull---원격-저장소에-있는-변경-사항을-내-로컬-저장소와-동기화-시키기&quot;&gt;3. pull - 원격 저장소에 있는 변경 사항을 내 로컬 저장소와 동기화 시키기&lt;/h3&gt;

&lt;p&gt;github repository 웹 페이지에서 README.md파일을 수정했다면 그건 원격 저장소에서만 수정이 일어난 것입니다.
=&amp;gt; 한 마디로 로컬에는 적용되지 않은 상태라고 볼 수 있습니다.&lt;/p&gt;

&lt;p&gt;그렇다면, 원격 저장소에서 수정된 내용을 로컬 저장소에 적용시켜야 되겠죠? 딱 맞는 명령어가 여기 있습니다.&lt;/p&gt;

&lt;p&gt;git pull&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;원격 저장소에서 적용된 수정 내용을 로컬 저장소에 적용시켜줍니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;section-3-git으로-여러-실험을-해볼-수-있는-레시피-만들기&quot;&gt;Section 3. Git으로 여러 실험을 해볼 수 있는 레시피 만들기&lt;/h2&gt;

&lt;h3 id=&quot;1-branch---새로운-레시피를-어떻게-안전하게-개발할-수-있을까&quot;&gt;1. branch - 새로운 레시피를 어떻게 안전하게 개발할 수 있을까?&lt;/h3&gt;

&lt;p&gt;git branch 원하는이름&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;원하는이름을 가진 새로운 브랜치를 만듭니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;git switch 원하는이름&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;원하는 이름을 가진 브랜치로 이동합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;자고로, 브랜치를 생성하고나서 추후에 원격 저장소로 push를 진행하면 오류가 뜹니다.&lt;/p&gt;

&lt;p&gt;⇒ 왜냐? 당연히, 원격 저장소에는 저희가 새로 만든 브랜치가 없거든요.&lt;/p&gt;

&lt;p&gt;이를 해결하기 위해서는 이걸 씁니다.&lt;/p&gt;

&lt;p&gt;git push —set-upstream origin 원하는이름&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;원격 저장소에 원하는이름 브랜치를 넣어주면서 push 명령어를 진행합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-merge---다른-브랜치에서의-작업한-내용을-합치고-싶다면-merge하세요&quot;&gt;2. merge - 다른 브랜치에서의 작업한 내용을 합치고 싶다면 merge하세요!&lt;/h3&gt;

&lt;p&gt;merge의 경우, commit은 현재 브랜치에서 하되 commit을 하고나서는 기반이 되는 브랜치로 이동해야 됨!&lt;/p&gt;

&lt;p&gt;예를들어 현재 새로 만든 브랜치인 비빔밥에 있다면?&lt;/p&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// 새 커밋 작성&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;commit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;“&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;이건&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;새로운&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;메시지야&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;”&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 주체가 되는 브랜치로 이동&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;main&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// branch 비빔밥과의 merge 실행&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;merge&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;비빔밥&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;3-pull-request---merge를-신중하게-하기-위해서-해야할-것&quot;&gt;3. pull request - merge를 신중하게 하기 위해서 해야할 것&lt;/h3&gt;

&lt;p&gt;사실, 현업에서는 코드를 짰다고 바로 merge를 하는 경우는 없습니다. main 브랜치는 사용자가 이용하는 최종 브랜치이기 때문에 철저한 검증이 필요합니다.&lt;/p&gt;

&lt;p&gt;내가 로컬에서 작업한 제 브랜치의 내용을 원격 저장소에 merge하기 위해 검증을 요청하는 것을 pull request라고 합니다.&lt;/p&gt;

&lt;p&gt;절차를 시각 자료로 봅시다!&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;예시로, 새로운 비빔밥이라는 브랜치를 넣어주고 나니 pull request를 생성할 수 있는 버튼이 뜹니다.
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/174852064-8557b8d9-e8d9-4eab-8aca-dfd42ed15971.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;이렇게 comment를 작성하고 Create pull request를 누르면 새로운 pull request가 생성됩니다.
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/174852183-940f8e09-a038-4b7d-8e77-2a9a18a17640.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;pull request가 되고 나서 그 내부에 file changed에서 특정 코드의 + 버튼 클릭 시 해당 코드에 대해 조언이나, 이 코드는 나쁘다던지 하는 코멘트를 달 수 있습니다.
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/174852300-c8a664e8-75f4-4bc5-b9d6-0f4a03521979.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;코멘트를 다 달았다면 저장해야겠죠? Finish your review를 클릭합니다.
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/174852372-e06d5ad6-be28-44d2-a236-4c6be105f625.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;여기에서는 몇 가지 옵션들이 존재하는데요.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Comment : 나는 그냥 코멘트만 남기기만 할래&lt;/li&gt;
  &lt;li&gt;Approve : 이거 merge 해도 될 것 같은데?&lt;/li&gt;
  &lt;li&gt;Request changes : 이 코드는 좀 바꿔야 될 필요가 있는것 같아&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이런 의미들을 담고 있습니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Finish your review가 끝났을 때 지금과 같은 경우는 새로운 Comment가 달렸습니다. 해당 Comment로 토론의 장도 열 수 있습니다.
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/174852580-e0af6ad1-df8f-4df3-8795-3ce6f6f88ba5.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;이러한 고민의 과정이 끝나면 하단의 Merge pull request를 통해 merge를 할 수 있습니다.
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/174852685-3d368d03-a077-4863-aaef-773eccf2b5e9.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;section-4-git으로-레시피-수정하기&quot;&gt;Section 4. Git으로 레시피 수정하기&lt;/h2&gt;

&lt;h3 id=&quot;1-amend---깜빡-하고-수정하지-못한-파일이-있다면&quot;&gt;1. amend - 깜빡 하고 수정하지 못한 파일이 있다면!&lt;/h3&gt;

&lt;p&gt;커밋을 하나 만들고 나서, 더 추가한 코드가 생각났을 때 새로운 commit을 만든다?&lt;/p&gt;

&lt;p&gt;⇒ 그렇다며 다른 사람들이 혼동이 올 확률이 큼.&lt;/p&gt;

&lt;p&gt;그걸 해결하기 위해 amend가 있습니다!&lt;/p&gt;

&lt;p&gt;git commit —amend&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;전에 있던 commit을 수정하며 지금 수정한 내용을 전 commit에 포함시킵니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-reset---시간-여행을-하고-싶다면&quot;&gt;2. reset - 시간 여행을 하고 싶다면?&lt;/h3&gt;

&lt;p&gt;코드를 다 짜고 commit을 했는데 생각해보니 특정 commit 시점으로 돌아가는게 더 나은 상황이 생길 수도 있습니다. 그렇다면?&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;git log —oneline&lt;/strong&gt;으로 지금까지 commit 내역을 보며 가고 싶은 commit 지점의 id를 복사합니다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;git reset 복사한id&lt;/strong&gt; 를 하여 해당 지점으로 돌아갈 수 있습니다!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;다만, 순수 reset을 한다고 바로 바뀌지 않습니다.&lt;/p&gt;

&lt;p&gt;reset에는 많은 옵션이 있는데 그 중에 —mixed가 default option입니다. —mixed의 경우 변경한 내용을 그대로 남긴 채로 커밋의 이력만 reset 해주기 때문입니다.&lt;/p&gt;

&lt;p&gt;만약 코드 자체를 과거의 commit에 맞추고 싶다면?&lt;/p&gt;

&lt;p&gt;⇒ &lt;strong&gt;git reset 복사한id —hard&lt;/strong&gt; 를 실행시키면 됩니다.&lt;/p&gt;

&lt;h3 id=&quot;3-revert---과거를-지우고-싶다면&quot;&gt;3. revert - 과거를 지우고 싶다면!&lt;/h3&gt;

&lt;p&gt;reset의 경우 되돌리면 장땡! 과 같은 느낌이라 되돌린 기록이 안 남네요.&lt;/p&gt;

&lt;p&gt;만약, 되돌린 기록또한 남기고 싶다면? revert를 쓰면 됩니다!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;git revert 복사한id&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;복사한id인 과거의 커밋을 현재 코드에 적용시킵니다.&lt;/li&gt;
  &lt;li&gt;적용시킨 상황에서 과거의 커밋으로 대체할지 그냥 이대로 쭉 갈지 정할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;4-stash---변경-사항을-잠시-지워두고-싶고-커밋은-안-만들고-싶다면&quot;&gt;4. stash - 변경 사항을 잠시 지워두고 싶고, 커밋은 안 만들고 싶다면?&lt;/h3&gt;

&lt;p&gt;예를들어 비빔밥 레시피를 만들다가, 다른 레시피를 적고 싶을때 현재 작업한 건 커밋하기 싫다면??&lt;/p&gt;

&lt;p&gt;⇒ stash를 써서 임시 저장소에 넣어둘 수 있습니다!&lt;/p&gt;

&lt;p&gt;git stash push -m “~~~”&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;현재 작업한 것을 stash 영역에 넣습니다. 작업중인 코드는 전 push 때의 코드로 돌아갑니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;git stash list&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;stash 영역에는 여러 개를 저장할 수 있고 이는 리스트 형식으로 담깁니다.&lt;/li&gt;
  &lt;li&gt;그렇기 때문에, 이 리스트들을 확인할 수 있는 명령어 또한 존재합니다.&lt;/li&gt;
  &lt;li&gt;stash 내에 저장된 내역들을 볼 수 있는 명령어입니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;git stash show stash&lt;em&gt;id&lt;/em&gt;값 -p&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;stash&lt;em&gt;id&lt;/em&gt;값에 들어있는 내용을 자세히 볼 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;git stash apply (원하는id)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;id를 입력하지 않는다면 가장 최근에 stash에 넣은 것으로 코드에 적용.&lt;/li&gt;
  &lt;li&gt;id를 입력하면 원하는 id에 있는 것으로 적용이 됩니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;5-cherry-pick---다른-브랜치의-이력을-뚝-가져오고-싶다면&quot;&gt;5. cherry-pick - 다른 브랜치의 이력을 뚝 가져오고 싶다면?&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;git cherry-pick 다른브랜치_원하는commit_id&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;다른 브랜치에서 작업한 commit을 나의 브랜치에 가져오고 반영 시킵니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;만약, merge conflict가 났을 경우에는 다 수정하고, &lt;strong&gt;git cherry-pick —continue&lt;/strong&gt;를 한 뒤에 커밋해주도록 합시다.&lt;/p&gt;

&lt;h2 id=&quot;section-5-6-추가-내용들&quot;&gt;Section 5, 6… 추가 내용들&lt;/h2&gt;

&lt;h3 id=&quot;1-fork란&quot;&gt;1. Fork란?&lt;/h3&gt;

&lt;p&gt;오픈 소스의 경우 쓰기 권한이 없으나, fork를 하여 해당 오픈소스 리포지토리를 복사된 해당 리포지토리는 내 저장소이므로 쓰기 권한이 존재합니다.&lt;/p&gt;

&lt;p&gt;그렇기 때문에, 내 저장소가 된 곳에서 작업을 하고 원본 오픈 소스 리포지토리에 pull request를 보내는 것이 오픈 소스에 기여하는 방법입니다.&lt;/p&gt;

&lt;h3 id=&quot;2-git은-누가-만들었나요&quot;&gt;2. Git은 누가 만들었나요?&lt;/h3&gt;

&lt;p&gt;우리가 아는 그분… 리누스 토발즈가 만들었습니다. 그 전, bitkeeper를 쓰고 있었으나 유료화가 되면서 성능을 향상시킨 git을 만들어서 내놓았다고 하네요.&lt;/p&gt;

&lt;h3 id=&quot;3-git을-사용하는-방법은&quot;&gt;3. git을 사용하는 방법은?&lt;/h3&gt;

&lt;p&gt;터미널을 이용하는 CLI 방식과, 버튼을 사용하는 GUI 방식이 있습니다.&lt;/p&gt;

&lt;p&gt;예를들어 SourceTree라는 것을 사용하면 CLI보다는 더 편리한 GUI 방식으로 git을 쓸 수 있습니다.&lt;/p&gt;

&lt;p&gt;그럼, 우리는 왜 처음부터 CLI로 했을까요? 숙련자는 CLI를 쓰고 초보자는 GUI를 쓴다는 것은 편견입니다. 둘 다 쓸 줄 알아야 되기 때문에 그렇다고 하네요.&lt;/p&gt;

&lt;h3 id=&quot;4-현업에서는-commit-message를-어떻게-적나요&quot;&gt;4. 현업에서는 commit message를 어떻게 적나요?&lt;/h3&gt;

&lt;p&gt;각 회사마다 일정의 약속이 있다고 합니다. 그 것외에 개발자들이 공통을 사용하는 컨벤션이 있다고 하네요.&lt;/p&gt;

&lt;p&gt;해당 정보글이 있는 사이트 : &lt;a href=&quot;https://udacity.github.io/git-styleguide/&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://udacity.github.io/git-styleguide/&quot;&gt;https://udacity.github.io/git-styleguide/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;또한, 오픈소스에 기여할 때 좀 큰 오픈소스라면 특유의 커밋 컨벤션이 있을 확률이 높습니다. 꼭 찾아보고 커밋을 해주시면 좋습니다.&lt;/p&gt;

&lt;p&gt;그리고 gitmoji라고 commit message 앞 type들을 이모티콘을 바꿔서 색다른 commit을 할 수도 있습니다.&lt;/p&gt;</content><author><name>Suhwan Kim</name><email>suhwan2004@gmail.com</email></author><category term="Git" /><category term="Git" /><summary type="html">udemy의 Git으로 만드는 전설의 레시피 강의를 필기한 내용입니다!</summary></entry><entry><title type="html">TCP/IP - TCP는 무엇일까?</title><link href="https://suhwan2004.github.io/frontend/WhatIsTCP/" rel="alternate" type="text/html" title="TCP/IP - TCP는 무엇일까?" /><published>2022-06-20T00:00:00+00:00</published><updated>2022-06-20T00:00:00+00:00</updated><id>https://suhwan2004.github.io/frontend/WhatIsTCP</id><content type="html" xml:base="https://suhwan2004.github.io/frontend/WhatIsTCP/">&lt;p&gt;오늘은 브라우저 렌더링 1화에서 언급되었던 TCP/IP 중 TCP에 대해 알아보겠습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/174483029-65b85f4b-7fab-46d4-8a6c-60319b3e1039.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;(자~ 드가자~)&lt;/p&gt;

&lt;h2 id=&quot;tcpip란-tcpip라는-프로토콜이-있었나&quot;&gt;TCP/IP란? TCP/IP라는 프로토콜이 있었나…?&lt;/h2&gt;

&lt;p&gt;제목이 붙어 있어서 좀 오해가 있을 수도 있었겠지만, 사실 “TCP/IP”라는 프로토콜은 오해의 소지가 살짝 있습니다. TCP와 IP라는 프로토콜이라고 구분 지어 생각 하는 게 맞습니다.&lt;/p&gt;

&lt;p&gt;먼저, 위키백과에 TCP/IP를 검색해보니 대략 이렇게 나옵니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;인터넷 프로토콜 스위트&lt;/strong&gt;는 인터넷에서 컴퓨터들이 서로 정보를 주고받는 데 쓰이는 &lt;strong&gt;통신규약 프로토콜의 모음&lt;/strong&gt;이다.&lt;/p&gt;

&lt;p&gt;인터넷 프로토콜 스위트 중 &lt;strong&gt;TCP와 IP가 가장 많이 쓰이기 때문에 TCP/IP 프로토콜 스위트라고도 불린다.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;그렇습니다. 둘이 잘 쓰여서 붙여서 썼지만 둘은 프로토콜 조합입니다. 오늘은 TCP에 대해서 알아볼 것이구요.&lt;/p&gt;

&lt;p&gt;또한, 둘은 서로 다른 계층에 있습니다.&lt;/p&gt;

&lt;p&gt;인터넷 프로토콜 스위트의 경우, 저희가 아는 OSI 7계층에서 변형된 자신만의 계층을 가지고 있기 때문인데요. 아래의 사진을 한 번 볼까요?&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/174483755-cd141b88-9ecb-4252-ab66-fb0a83c8af6f.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;(TCP/IP Protocol은 위에서 봤듯이 인터넷 프로토콜입니다!)&lt;/p&gt;

&lt;p&gt;오른쪽의 TCP/IP Protocol의 4가지 계층을 보면 OSI 7 계층을 좀 더 넓게 보고 구성한 느낌입니다. 또한, 위에서 말했듯이 TCP의 경우 전송 계층에 있고, IP의 경우 Internet 계층에 있는 것을 알 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;tcp는-뭘까&quot;&gt;TCP는 뭘까?&lt;/h2&gt;

&lt;p&gt;TCP (전송 제어 프로토콜)은 &lt;strong&gt;두 개의 호스트를 연결하고 데이터 스트림을 교환&lt;/strong&gt;하게 해주는 중요한 네트워크 프로토콜입니다.&lt;/p&gt;

&lt;p&gt;아까 위에서 봤듯이 &lt;strong&gt;전송 계층에 속해있고 같은 계층에는 UDP가 있습니다.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;TCP와 UDP의 차이점은 뭘까요? 간단하게 &lt;strong&gt;신뢰성의 차이&lt;/strong&gt;입니다.&lt;/p&gt;

&lt;p&gt;TCP의 경우 보내는 쪽에 제대로 도착했는지 응답을 받습니다. 잘못됬다고 응답이 오면 다시 보내주겠죠?&lt;/p&gt;

&lt;p&gt;그러나, UDP의 경우 단방향 통신이라 그런 것이 없습니다. 받는 쪽이 제대로 받았는지, 잘못된 것을 받았는지는 모릅니다. 나는 보냈으니 끝이야! 이런 스탠스라고 볼 수 있겠네요.&lt;/p&gt;

&lt;p&gt;그나마 UDP를 변호해보자면 &lt;strong&gt;TCP보다 UDP가 속도는 빠르다는 것….?&lt;/strong&gt;. 그냥 TCP를 쓰면 될 것 같아요.&lt;/p&gt;

&lt;p&gt;자, 다시 TCP로 돌아와서 TCP에는 4가지 정도의 특징이 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. 연결형 서비스&lt;/strong&gt;
연결형 서비스로 가상 회선 방식을 제공합니다. &lt;strong&gt;3-way handshaking으로 연결을 설정하며, 4-way handshaking으로 연결을 해제&lt;/strong&gt;합니다. 3-way handshaking에 대해서는 아래에서 자세히 보겠습니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. 흐름 제어&lt;/strong&gt;
송신 측과 수신 측의 TCP 버퍼 크기 차이로 인해 생기는 데이터 처리 속도 차이를 해결하기 위한 기법을 사용합니다.&lt;/p&gt;

&lt;p&gt;=&amp;gt; 여러 방법이 존재하나, 3-way handshaking 내에서 &lt;strong&gt;윈도우 크기(window size)를 설정&lt;/strong&gt;함으로써 해결하는 방식을 보통 씁니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. 혼잡 제어&lt;/strong&gt;
송신측의 데이터 전달과 네트워크의 데이터 처리 속도 차이를 해결하기 위한 기법을 사용합니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. 신뢰성이 높은 전송&lt;/strong&gt;
위에서도 얘기했듯이, TCP는 응답이 제대로 오지 않으면 데이터를 재전송 합니다.&lt;/p&gt;

&lt;p&gt;재전송의 기준은 아래와 같습니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;시간 기반 재전송(Time-based Retransmission)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;일정 기간동안 ACK 값이 수신을 못할 경우 재전송.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;중복 ACK 기반 재전송(Dup ACK - based Retransmission)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;정상적인 상황에서는 ACK 값이 연속적으로 전송 되야 합니다.&lt;/li&gt;
      &lt;li&gt;그러나, ACK값이 중복으로 올 경우 패킷 이상을 감지하고 재전송을 요청합니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;5. UDP보다 속도 느림&lt;/strong&gt;
위에서 TCP와 UDP를 비교하면서 나왔던 이야기입니다. UDP는 보내기만 하니까 당연히 TCP보다 속도가 더 빠릅니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. 전이중(Full-Duplex), 점대점(Point to Point) 방식&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;전이중 : 전송이 양방향으로 동시에 일어날 수 있음.&lt;/li&gt;
  &lt;li&gt;점대점 : 각 연결이 정확히 2개의 종단점을 가지고 있음.
=&amp;gt; &lt;strong&gt;멀티캐스팅이나 브로드캐스팅을 지원하지 않음.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;3-4---way-handshaking&quot;&gt;3, 4 - way Handshaking&lt;/h2&gt;

&lt;p&gt;자 그럼, TCP의 꽃인 3-way handshaking, 4-way handshaking도 한번 공부해봅시다.&lt;/p&gt;

&lt;h3 id=&quot;3-way-handshaking&quot;&gt;3 way Handshaking&lt;/h3&gt;

&lt;p&gt;TCP/IP 프로토콜을 이용해서 통신을 하는 응용프로그램이 데이터를 전송하기 전에 먼저 정확한 전송을 보장하기 위해 상대방 컴퓨터와 사전에 세션을 수립하는 과정을 의미합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/174486712-408fb22e-ff8f-4017-8b58-070ed6e759c7.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;A클라이언트는 B서버에 접속을 요청하는 SYN 패킷을 보냅니다.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;이때 A클라이언트는 SYN 을 보내고 SYN/ACK 응답을 기다리는SYN_SENT 상태가 됩니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;B서버는 SYN요청을 받고 A클라이언트에게 요청을 수락한다는 ACK 와 SYN flag 가 설정된 패킷을 발송하고 A가 다시 ACK으로 응답하기를 기다립니다.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;이때 B서버는 SYN_RECEIVED 상태가 됩니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A클라이언트는 B서버에게 ACK을 보내고 이후로부터는 연결이 이루어지고 데이터가 오가게 됩니다.&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;이때의 B서버 상태가 ESTABLISHED 입니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;4---way-handshaking&quot;&gt;4 - way Handshaking&lt;/h3&gt;

&lt;p&gt;4 - way Handshaking은 세션을 종료하기 위해 수행되는 절차입니다!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/174486962-63097255-802c-4197-bda8-b08f53e44e74.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;클라이언트가 연결을 종료하겠다는 FIN플래그를 전송한다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;서버는 일단 확인메시지를 보내고 자신의 통신이 끝날때까지 기다리는데 이 상태가 &lt;strong&gt;TIME_WAIT&lt;/strong&gt;상태 입니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;서버가 통신이 끝났으면 연결이 종료되었다고 클라이언트에게 FIN플래그를 전송합니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;클라이언트는 확인했다는 메시지를 보냅니다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;여기서 TIME_WAIT란?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Client에서 세션을 종료시킨 후 뒤늦게 도착하는 패킷으로 인해 데이터가 유실되는 현상이 발생될 수 있습니다.&lt;/li&gt;
  &lt;li&gt;이런 상황을 대비해서 &lt;strong&gt;Client는 Server로부터 FIN을 수신하더라도 일정시간(디폴트 240초) 동안 세션을 남겨놓고 잉여 패킷을 기다리는 과정&lt;/strong&gt;을 가집니다. 이것을 TIME_WAIT라고 합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이렇게, TCP의 초기화와 종료를 담당하는 두 방식에 대해 알아보았습니다.&lt;/p&gt;

&lt;h2 id=&quot;tcp-segment&quot;&gt;TCP Segment&lt;/h2&gt;

&lt;p&gt;보내거나 종료하는 방식까진 알겠는데 데이터가 어떤 형태로 가는지도 한번 알아봐야 겠죠?&lt;/p&gt;

&lt;p&gt;결론적으로 말하자면 저희가 브라우저 렌더링을 할 때 서버로부터 JS, CSS, HTML 파일들을 받을텐데 그 것들은 한 파일 채로 오지 않습니다.&lt;/p&gt;

&lt;p&gt;원래 파일을 쪼개서 &lt;strong&gt;패킷으로 분할되서 옵니다!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;또한, 여기서 골치아픈게 이게 좀 뒤죽박죽 순서가 섞여서 옵니다.
=&amp;gt; ?? : 그럼 이걸 나중에 어떻게 조립하죠?&lt;/p&gt;

&lt;p&gt;이건, TCP Segment에 정답이 있습니다. TCP Segment를 알아봅시다.&lt;/p&gt;

&lt;p&gt;TCP 세그먼트 내에는 우선 여러 개의 구성 요소가 있습니다. 이번 포스트에서 다 다루지 않을 것이고, 가장 중요한 것들 위주로 볼 것입니다.&lt;/p&gt;

&lt;h3 id=&quot;tcp-segment의-구성요소&quot;&gt;TCP Segment의 구성요소&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. TCP Header&lt;/strong&gt;
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/174488356-b94411c1-2bb3-4a8e-99c2-b74d47b006e4.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;꽤 많은 것들이 들어 있으나 중요한 것들만 보겠습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Source port address : 송신측 주소(from)&lt;/li&gt;
  &lt;li&gt;Destination port address : 수신측 주소(to)&lt;/li&gt;
  &lt;li&gt;Sequence Number : 담긴 데이터의 순서&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Data&lt;/strong&gt;
아까 말했듯이 잘린 데이터입니다.&lt;/p&gt;

&lt;p&gt;이렇게 두 가지로 TCP Segment는 구성이 됩니다.&lt;/p&gt;

&lt;p&gt;또한, 이제 위의 궁금증이 풀립니다. 처음에는 물론 데이터를 완성하기 위해 각 데이터의 순서를 몰랐지만 TCP Header내에 Sequence Number 덕분에 완전한 파일로 만들 수 있었습니다.&lt;/p&gt;

&lt;p&gt;또한, 가끔씩 데이터가 하나 빠져서 오는 경우도 있는데 이 때도, Sequnce Number를 통해 판단 후에 빈 데이터를 다시 받을 수 있겠죠?&lt;/p&gt;

&lt;p&gt;여기까지가, 이번 TCP에 대한 설명이였습니다. 다음 포스트는 IP에 대한 설명으로 찾아뵙겠습니다. 감사합니다!&lt;/p&gt;

&lt;h2 id=&quot;출처&quot;&gt;출처&lt;/h2&gt;

&lt;p&gt;https://ko.wikipedia.org/wiki/%EC%9D%B8%ED%84%B0%EB%84%B7&lt;em&gt;%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C&lt;/em&gt;%EC%8A%A4%EC%9C%84%ED%8A%B8&lt;/p&gt;

&lt;p&gt;https://developer.mozilla.org/ko/docs/Glossary/TCP&lt;/p&gt;

&lt;p&gt;https://mindnet.tistory.com/entry/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%89%BD%EA%B2%8C-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-22%ED%8E%B8-TCP-3-WayHandshake-4-WayHandshake&lt;/p&gt;

&lt;p&gt;https://velog.io/@seaworld0125/WEB-TCP%EB%9E%80&lt;/p&gt;</content><author><name>Suhwan Kim</name><email>suhwan2004@gmail.com</email></author><category term="FrontEnd" /><category term="FrontEnd" /><summary type="html">오늘은 브라우저 렌더링 1화에서 언급되었던 TCP/IP 중 TCP에 대해 알아보겠습니다.</summary></entry><entry><title type="html">BrowserRendering - 3 - 브라우저 렌더링 최적화</title><link href="https://suhwan2004.github.io/frontend/BrowserRendering3/" rel="alternate" type="text/html" title="BrowserRendering - 3 - 브라우저 렌더링 최적화" /><published>2022-06-17T00:00:00+00:00</published><updated>2022-06-17T00:00:00+00:00</updated><id>https://suhwan2004.github.io/frontend/BrowserRendering3</id><content type="html" xml:base="https://suhwan2004.github.io/frontend/BrowserRendering3/">&lt;h2 id=&quot;렌더링이-다-끝나면-장땡-아닌가요&quot;&gt;렌더링이 다 끝나면 장땡 아닌가요?&lt;/h2&gt;

&lt;p&gt;아닙니다. 분명, 저희가 전 시간에 일련의 과정을 통해 브라우저 렌더링이 어떻게 되는지 이해했습니다.&lt;/p&gt;

&lt;p&gt;그러나, 화면이 떴다고 해서 전부가 아니라 예를들어 사용자의 버튼 클릭에 다음 페이지를 보여준다던가 하는 상황에서는 분명 그에 영향을 받는 자식, 부모 노드들을 포함하여 Layout(Reflow)과정을 다시 수행해야 합니다.&lt;/p&gt;

&lt;p&gt;여기서 두 개의 과정이 나옵니다.&lt;/p&gt;

&lt;h2 id=&quot;reflow&quot;&gt;Reflow&lt;/h2&gt;

&lt;p&gt;Reflow란 렌더 트리와 각 요소들의 크기와 위치를 다시 계산하게 되는 과정입니다.&lt;/p&gt;

&lt;p&gt;구체적으로 Reflow가 일어나는 상황은 뭘까요?
다음과 같습니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;페이지 초기 렌더링 시(최초 Layout 과정)&lt;/li&gt;
  &lt;li&gt;브라우저 리사이징 시 (Viewport 크기 변경)&lt;/li&gt;
  &lt;li&gt;노드 추가 또는 제거&lt;/li&gt;
  &lt;li&gt;요소의 위치, 크기 변경&lt;/li&gt;
  &lt;li&gt;폰트 변경과 이미지 크기 변경&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;repaint&quot;&gt;Repaint&lt;/h2&gt;

&lt;p&gt;Repaint란 Reflow된 렌더 트리를 다시 화면에 그려주는 과정입니다. Repaint가 일어나지 않으면 Reflow에서 바뀐 렌더 트리가 저희 눈에 보이지 않습니다.&lt;/p&gt;

&lt;p&gt;이렇게, 보면 Reflow -&amp;gt; Repaint인 과정은 맞긴 한데 무조건 Reflow가 발생해야 Repaint가 수행되는 것은 아닙니다.&lt;/p&gt;

&lt;p&gt;background-color, opacity와 같이 &lt;strong&gt;레이아웃의 수치를 변화시키지 않는 스타일의 변경이 일어났을 때는 Reflow를 수행할 필요가 없기 때문에 Repaint만 수행하게 됩니다.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;이 두 개의 과정은 시간을 많이 잡아먹기 때문에 최적화가 필요합니다.&lt;/p&gt;

&lt;h2 id=&quot;그럼-최적화는-어떻게-하나요&quot;&gt;그럼 최적화는 어떻게 하나요?&lt;/h2&gt;

&lt;p&gt;사용자의 특정 행동에 따라 저희는 Reflow -&amp;gt; Repaint라는 과정을 통해 화면이 다시 렌더링 됨을 알았습니다.&lt;/p&gt;

&lt;p&gt;그럼, 이 과정을 최적화 하는 방법이 뭐가 있을까요?&lt;/p&gt;

&lt;h3 id=&quot;1-reflow가-일어나는-속성-지양하기&quot;&gt;1. Reflow가 일어나는 속성 지양하기&lt;/h3&gt;

&lt;p&gt;Reflow를 줄이면 당연히 Repaint도 줄어듭니다. 방금 위에 있던 얘기중에 &lt;strong&gt;레이아웃의 수치를 변화시키지 않는 스타일의 변경은 Repaint만 수행&lt;/strong&gt;한다고 했습니다.&lt;/p&gt;

&lt;p&gt;그렇다면 실제 CSS를 짤 때 Reflow가 일어나는 속성을 지양하면 성능 개선이 가능하겠죠?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reflow가 일어나는 대표적인 속성&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;position, width, height, left, top, right, bottom, margin, padding, border, border-width,
clear, display, float, font-family, font-size, font-weight, line-height, min-height,
overflow, text-align, vertical-align, white-space...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Repaint가 일어나는 대표적인 속성&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;background, background-image, background-position, background-repeat, background-size,
border-radius, border-style, box-shadow, color, line-style, outline, outline-color,
outline-style, outline-width, text-decoration, visibilty...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;2-영향을-주는-노드-최소화하기&quot;&gt;2. 영향을 주는 노드 최소화하기&lt;/h3&gt;

&lt;p&gt;Js와 CSS를 조합해 애니메이션이나 레이아웃의 변화가 많은 요소의 경우 position을 absolute, fixed를 사용하면 영향을 받는 노드들을 줄일 수 있습니다.&lt;/p&gt;

&lt;h3 id=&quot;3-프레임-줄이기&quot;&gt;3. 프레임 줄이기&lt;/h3&gt;

&lt;p&gt;단순하게, 0.1초 -&amp;gt; 1px씩 이동하는 걸 0.3초 -&amp;gt; 3px씩 이동한다면 Reflow 비용이 3배 줄은 거라고 볼 수 있습니다. 이렇게 프레임을 줄이면 성능이 향상됩니다.
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/174309800-55a8e64f-09c5-45e0-a82c-7c7755a1b269.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;(시각을 포기한 극한의 성능충이 아닐까…)&lt;/p&gt;

&lt;h3 id=&quot;4-블록-리소스-최적화&quot;&gt;4. 블록 리소스 최적화&lt;/h3&gt;

&lt;p&gt;우선, CSS와 JS는 블록 리소스입니다. HTML parsing 중 CSS와 JS를 만나면 parsing이 중단되는 현상이 발생하는데 이런 현상을 발생시키는 리소스를 블록리소스라고 합니다.&lt;/p&gt;

&lt;p&gt;그렇다보니, CSS와 JS 둘 다 넣어야 되는 위치가 참 중요합니다. 먼저 CSS부터 보겠습니다.&lt;/p&gt;

&lt;p&gt;랜더 트리를 구성하기 위해서는 DOM 트리와 CSSOM 트리가 필요합니다. DOM 트리는 태그를 발견할 때마다 순차적 구성이 가능하지만, &lt;strong&gt;CSSOM 트리
는 CSS를 모두 해석해야 구성할 수 있습니다.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CSSOM 트리가 완성되지 않으면 렌더링이 차단되기 때문에 이러한 이유로, CSS를 &lt;strong&gt;‘렌더링 차단 리소스’&lt;/strong&gt; 라고 하고 &lt;strong&gt;렌더링이 차단되지 않도록 CSS는 가능하면 head 태그 안쪽에 배치해야 합니다.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;특정한 경우에서만 사용하는 CSS를 불러올 때는 미디어쿼리를 사용하여 CSS를 분리 후, 필요할 때만 로드될 수 있도록 하는 것이 좋습니다.&lt;/p&gt;

&lt;p&gt;다음은 JS입니다.&lt;/p&gt;

&lt;p&gt;JS의 경우, body 태그 중간에서 불러올 시 지금까지 파싱된 태그에만 접근이 가능하기 때문에…&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;순수 script만 쓴다고 한다면 body 태그 맨 마지막에 넣는 것이 맞고&lt;/li&gt;
  &lt;li&gt;그러기 싫다면 defer 속성을 추가하여 head 태그 안에 넣으면 됩니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href=&quot;https://suhwan2004.github.io/frontend/ScriptdeferVSasync/&quot;&gt;script 태그와 관련된 글은 요기 있으니 한번 읽어보셔도 좋을 것 같습니다.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;이외에도 Lazy loading 구현으로 리소스 양 줄이기, 트리 쉐이킹 구현등이 있으나 이는 본질적인 구현부분에 가까워 넣지 못했습니다.&lt;/p&gt;

&lt;p&gt;추후에, Lazy loading 관련하여 실제로 만들어보고 이 곳에 링크를 추가할 예정입니다.&lt;/p&gt;

&lt;h2 id=&quot;회고&quot;&gt;회고&lt;/h2&gt;

&lt;p&gt;자세히 알아보기 전에는 솔직히 브라우저 렌더링에 관해서는 “그냥 서버에서 파일들 받아와서 렌더링 하는거 아니야? “라고 생각했었습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/174312887-d3ddebb9-7e0d-4130-9d67-a41e701a9709.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;(더닝 크루거 효과 곡선. 요즘들어 뼈저리게 느끼고 있습니다.)&lt;/p&gt;

&lt;p&gt;이번에 정리가 허술한 것들도 참 많았지만 적으면서 나 정말 구멍 술술 뚫려있구나… 이런 생각이 들던 것 같습니다ㅋㅋㅋ…&lt;/p&gt;

&lt;p&gt;우매함의 봉우리에서 내려와서 꾸준히 달려야겠습니다.&lt;/p&gt;</content><author><name>Suhwan Kim</name><email>suhwan2004@gmail.com</email></author><category term="FrontEnd" /><category term="FrontEnd" /><summary type="html">렌더링이 다 끝나면 장땡 아닌가요?</summary></entry><entry><title type="html">학교 - 4학년 1학기 파멸의 기말고사 - 빅데이터에서 살아남기</title><link href="https://suhwan2004.github.io/ptu/DisesterGimal_BigdataP/" rel="alternate" type="text/html" title="학교 - 4학년 1학기 파멸의 기말고사 - 빅데이터에서 살아남기" /><published>2022-06-13T00:00:00+00:00</published><updated>2022-06-13T00:00:00+00:00</updated><id>https://suhwan2004.github.io/ptu/DisesterGimal_BigdataP</id><content type="html" xml:base="https://suhwan2004.github.io/ptu/DisesterGimal_BigdataP/">&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/173362641-d2f323d8-7d86-4dfb-8448-75315d641f21.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;망하지 않기 위해 정리한 함수 모음…&lt;/p&gt;

&lt;h3 id=&quot;csv-파일-받기&quot;&gt;CSV 파일 받기&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pd.read_csv(파일경로)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;특정-데이터를-dataframe으로-변환&quot;&gt;특정 데이터를 Dataframe으로 변환&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df = pd.Dataframe(해당 자료)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;dataframe의-행-이름들을-설정&quot;&gt;dataframe의 행 이름들을 설정&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.columns = [~~~]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;정보를-보기컬럼-이름-null이-아닌-갯수-타입&quot;&gt;정보를 보기(컬럼 이름, null이 아닌 갯수, 타입)&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.info()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;해당-컬럼의-고유값들을-보여줌&quot;&gt;해당 컬럼의 고유값들을 보여줌&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df[컬럼이름].unique()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;컬럼-내에-특정-단어를-바꿈&quot;&gt;컬럼 내에 특정 단어를 바꿈.&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df[컬럼이름].replace(타켓단어, 바꿀단어, inplace = True or False)
	=&amp;gt; inplace = True 시 원본에 적용됨.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;또한-다중으로-변경-가능-아래는-로-값들을-묶고-123을-나라-이름으로-바꿔주는-모습임&quot;&gt;또한, 다중으로 변경 가능. 아래는 {}로 값들을 묶고 1,2,3을 나라 이름으로 바꿔주는 모습임.&lt;/h5&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ex) df['origin'].replace({1:'USA', 2:'EU', 3:'KOREA'}, inplace = True)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;df의-nan-값을-없애기&quot;&gt;df의 nan 값을 없애기&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.dropna(subset = [적용컬럼1, 적용컬럼2...], axis = 0, inplace = True or False)
=&amp;gt; axis가 0일 시 가로를 보고 행 정보를 제거, 1일 시 세로로 보고 그 해당 열 정보를 제거
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;특정-컬럼에-들어있는-값의-타입을-바꿔줌&quot;&gt;특정 컬럼에 들어있는 값의 타입을 바꿔줌.&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df[특정컬럼] = df[특정컬럼].astype('float')
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;다중으로-바꾸기-가능&quot;&gt;다중으로 바꾸기 가능&lt;/h5&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df = df.astype({'a' : np.int, 'b' : np.int64})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;특정-컬럼의-타입을-알려줌&quot;&gt;특정 컬럼의 타입을 알려줌&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df[특정컬럼].dtypes
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;dataframe의-앞-5개-보여주기&quot;&gt;Dataframe의 앞 5개 보여주기&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.head()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;끝에-5개는&quot;&gt;끝에 5개는?&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.tail()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;df의-특정컬럼을-이용해서-히스토그램생성&quot;&gt;df의 특정컬럼을 이용해서 히스토그램생성&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;np.histogram(df[특정컬럼], bins = 3)
 =&amp;gt; bins는 구간의 갯수임. 아래는 3개니까 3개의 구간으로 나눠짐.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;이런-식으로-js의-구조분해-할당처럼-여러-변수에-각각의-값을-넣어주고-있음&quot;&gt;이런 식으로 js의 구조분해 할당처럼 여러 변수에 각각의 값을 넣어주고 있음.&lt;/h5&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;count, bin_dividers = np.histogram(df[특정컬럼], bins = 3)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;위의-히스토그램과-비슷한-느낌의-cut함수&quot;&gt;위의 히스토그램과 비슷한 느낌의 cut함수&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pd.cut(데이터, 구간의 갯수, 레이블명)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;df-내-특정-컬럼의-각-값별-몇개가-있는지를-보여줌&quot;&gt;df 내 특정 컬럼의 각 값별 몇개가 있는지를 보여줌&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df[특정컬럼].value_counts()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;시간-형식의-object-자료형-컬럼의-자료형을-datetime-자료형으로-바꿔주기&quot;&gt;시간 형식의 object 자료형 컬럼의 자료형을 datetime 자료형으로 바꿔주기&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pd.to_datetime(df[특정컬럼])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;datatime-자료형timestamp를-period로-변환&quot;&gt;datatime 자료형(timestamp)를 Period로 변환&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;changeVal = timestamp.to_period(freq = 'D')  =&amp;gt; 년-월-일 단위로 변환
changeVal = timestamp.to_period(freq = 'M')  =&amp;gt; 년-월 단위로 변환
changeVal = timestamp.to_period(freq = 'Y')  =&amp;gt; 년 단위로 변환
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;timestamp-배열-만들기&quot;&gt;timestamp 배열 만들기&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pd.date_range(start = '년-월-일', end = None. periods = 6, freq = 'MS', tz = 'Asia/Seoul')
 =&amp;gt;'년-월-일' 부터 'None'까지 '서울시간' 기준 '6개'의 '월의 시작일'을 반환
 =&amp;gt; M만 하면 월의 마지막 날이 된다고 한다. 또한 3M을 하면 3개월이 된다고 한다.
 =&amp;gt; pd.date_range의 경우 freq는 정확히 범위라고 보면 됨. 또한, 아래와 같이 시분초까지 다 나오는 결과가 나옴.

DatetimeIndex(['2019-01-01 00:00:00+09:00', '2019-02-01 00:00:00+09:00', .....])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;period-배열-만들기&quot;&gt;Period 배열 만들기&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pd.period_range(start = '년-월-일', end = None, periods = 3, freq = 'M')
 =&amp;gt; 위와 많이 비슷함. 그러나, Period의 경우 나오는 값이 freq에 많이 영향을 받음.
  간격도 간격인데 값의 템플릿이 M이 될것.
PeriodIndex(['2019-01', '2019-02', .... ]) =&amp;gt; 요런식으로...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;년-월-일로-되어-있을-때-년-월-일-따로따로-자르기&quot;&gt;년-월-일로 되어 있을 때 년, 월, 일 따로따로 자르기&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df_stock['Year'] = df_stock['new_Date_p'].dt.year
df_stock['Month'] = df_stock['new_Date_p'].dt.month
df_stock['Day'] = df_stock['new_Date_p'].dt.day
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;dfloc-내에-날짜로-범위를-두고-구할때는-큰-날짜--작은-날짜가-됨을-꼭-기억하자&quot;&gt;df.loc[] 내에 날짜로 범위를 두고 구할때는 ‘큰 날짜’ : ‘작은 날짜’가 됨을 꼭 기억하자.&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df_ymd_range = df_stock.loc['2018-06-20':'2018-06-10']
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;시리즈-내-모든-값에-함수-매핑-반환값은-series&quot;&gt;시리즈 내 모든 값에 함수 매핑 (반환값은 series)&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Series.apply(함수)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;dataframe은-안됨-반환값은-dataframe이여야-됨--된다&quot;&gt;Dataframe은 안됨? 반환값은 Dataframe이여야 됨. =&amp;gt; 된다!&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dataFrame.applymap(함수)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;여러개를-하고-싶다면&quot;&gt;여러개를 하고 싶다면?&lt;/h5&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df[[특정컬럼, 특정컬럼1, ...]].applymap()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;각-컬럼-별로-데이터가-몇-개인지-세고-싶다면&quot;&gt;각 컬럼 별로 데이터가 몇 개인지 세고 싶다면?&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.count()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;이걸-더-활용하면-loc된-것에도-사용가능&quot;&gt;이걸 더 활용하면 loc된 것에도 사용가능.&lt;/h5&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.loc[df['episodes'] == 'Unknown'].count()
#에피소드가 '모르는 상태'인 것의 갯수.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;나는-특정-조건을-만족하는-가로-한-줄행은-제대로-뜨고-아니면-아닌-행은-값이-다-nan으로-되게-하고-싶음&quot;&gt;나는 특정 조건을 만족하는 가로 한 줄(행)은 제대로 뜨고, 아니면 아닌 행은 값이 다 NaN으로 되게 하고 싶음.&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.where(조건)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;loc의-매개변수중-조건의-첫-째는-가로의-조건-둘-째는-세로의-조건임-아래의-문은-episodes가-unknown인걸-npnan으로-교체&quot;&gt;loc의 매개변수중 조건의 첫 째는 가로의 조건, 둘 째는 세로의 조건임. 아래의 문은 episodes가 Unknown인걸 np.nan으로 교체&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.loc[df['episodes'] == 'Unknown', 'episodes'] = np.nan
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;가로-세로-갯수&quot;&gt;가로, 세로 갯수&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.shape
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;group별-집계&quot;&gt;group별 집계&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.groupby(특정컬럼)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;여러개-하고-싶다면&quot;&gt;여러개 하고 싶다면?&lt;/h5&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.grouby([특정 컬럼, 특정 컬럼1...])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;값별로-갯수를-보고-싶다면&quot;&gt;값별로 갯수를 보고 싶다면?&lt;/h5&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.groupby([]).count()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;카운트-평균-최저-최대-등의-여러-정보를-보고-싶다면&quot;&gt;카운트, 평균, 최저, 최대… 등의 여러 정보를 보고 싶다면?&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.describe()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;피봇-테이블-생성&quot;&gt;피봇 테이블 생성&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; =&amp;gt; index는 행 위치, columns는 열 위치, 데이터는 values,
  데이터 집계 함수는 aggfunc, nan 처리는 fill_value

df.pivot_table(index = 'type', columns = 'episodes',
 aggfunc = np.mean, fill_value = 0)


     episodes   episodes   episodes   episodes
type
type
type
 =&amp;gt; 이런 느낌임.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;apply-applymap과-비슷한-함수-매핑-아래는-람다함수를-넣은-것임&quot;&gt;apply, applymap과 비슷한 함수 매핑 (아래는 람다함수를 넣은 것임.)&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df[특정컬럼].map(lambda x : x.split(','))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;2차원-배열로-되-있는걸-아예-한-줄로-바꿔버림&quot;&gt;2차원 배열로 되 있는걸 아예 한 줄로 바꿔버림.&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;np.hstack(원하는 배열)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;공백제거&quot;&gt;공백제거&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Series.strip()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;정렬&quot;&gt;정렬&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Series.sort()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;아래는-concat인데-기능이-두-개-정도-확인-됨&quot;&gt;아래는 concat인데 기능이 두 개 정도 확인 됨.&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1.들어간 파라미터가 배열 단 한 개일때는 dataframe으로 만들어줌.
pd.concat(df_list)

2. 배열들을 합쳐줌
pd.concat([a,b], axis = 0 or 1, ignore_index = True or False)
 =&amp;gt; axis가 0일때는 가로로 합쳐짐. 1일때는 세로로 합쳐짐 또한 값이 빈 것들은 NaN이 들어감.
 =&amp;gt; ignore_index가 True면 기존 index 무시, False면 기존 인덱스 유지
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;concat처럼-dataframe을-병합해주는-기능이-있으나-공동-칼럼을-기준으로-join-해주는-merge도-있다&quot;&gt;concat처럼 Dataframe을 병합해주는 기능이 있으나 공동 칼럼을 기준으로 join 해주는 Merge도 있다.&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pd.merge(left, right, on = '기준열', how = '조인방식')
 =&amp;gt; how에는 left, right, inner, outer이 있다.
 =&amp;gt; left는 왼쪽 df, right은 오른쪽 df이다.
 =&amp;gt; on은 join에 사용할 기준열임.
 만약, 서로 각자 없는 기준열로 join하고 싶다면
  on을 left_on = 'left의 기준열',
  right_on ='right의 기준열'과 같은 방법으로 해주면 된다.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;긴-소수를-소숫점-한자리로-만들고-싶다면&quot;&gt;긴 소수를 소숫점 한자리로 만들고 싶다면?&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;join_data.describe().round(1)
 =&amp;gt; 소숫점 한자리로 만들어주는 모습이다.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;우리가-원하는-형식으로-연월을-받고싶다면&quot;&gt;우리가 원하는 형식으로 연,월을 받고싶다면?&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df[시계열 컬럼].dt.strftime(&quot;%Y-%m&quot;)
 =&amp;gt; &quot;%Y-%m&quot; 방식으로 받기 위해 strftime을 쓴 것임.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;선형-그래프를-그리고-싶다면&quot;&gt;선형 그래프를 그리고 싶다면?&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import matplotlib.pyplot as plt
plt.plot(x값들, y값들, label = &quot;~~&quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;그래프에-범례지금-이-선이-label이-pc-a인-선이에요-라는-표시를-하고-싶다면&quot;&gt;그래프에 범례(지금 이 선이 label이 pc-a인 선이에요! 라는 표시)를 하고 싶다면?&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;plt.legend()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;문자열을-대문자로-만들기&quot;&gt;문자열을 대문자로 만들기&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;str.upper()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;dataframe과-같은-데이터에서-값으로-정렬한다면&quot;&gt;dataframe과 같은 데이터에서 값으로 정렬한다면&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sort_values(by = [목표컬럼, ....], ascending = True or False)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;각-컬럼-별-결측값-갯수-보기&quot;&gt;각 컬럼 별 결측값 갯수 보기&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;df.isnull().sum()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;k-means-선형회귀-모델-훈련-및-결과-띄워보기&quot;&gt;K-Means, 선형회귀 모델 훈련 및 결과 띄워보기&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;이게 K-Means
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
customer_clustering_sc = sc.fit_transform(customer_clustering)
	=&amp;gt; fit + transfrom =&amp;gt; fit : 평균과 표준편차 계산, transform : 정규화.

kmeans = KMeans(n_clusters=4, random_state=0)
=&amp;gt; n_clusters는 k이다. 한마디로 군집형성의 갯수, random_state는 난수를 고정해준다.

clusters = kmeans.fit(customer_clustering_sc) =&amp;gt; 모형 학습

customer_clustering[&quot;cluster&quot;] = clusters.labels_ =&amp;gt; 예측(군집)
print(customer_clustering[&quot;cluster&quot;].unique())

------------
이게 선형회귀
from sklearn import linear_model
import sklearn.model_selection

model = linear_model.LinearRegression() =&amp;gt; 모델생성

X = predict_data[[&quot;count_0&quot;,&quot;count_1&quot;,&quot;count_2&quot;,&quot;count_3&quot;,&quot;count_4&quot;,&quot;count_5&quot;,&quot;period&quot;]]
y = predict_data[&quot;count_pred&quot;]
X_train, X_test, y_train, y_test = 	sklearn.model_selection.train_test_split(X,y)
	=&amp;gt;X,y를 훈련값, 테스트값으로 쪼갬
model.fit(X_train, y_train) =&amp;gt; 훈련값 x,y로 훈련

x1 = [3, 4, 4, 6, 8, 7, 8]
x2 = [2, 2, 3, 3, 4, 6, 8]
x_pred = [x1, x2]

model.predict(x_pred) =&amp;gt; 새 입력값 x1, x2을 방금 학습한 모델을 통해 예측값 받기
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>Suhwan Kim</name><email>suhwan2004@gmail.com</email></author><category term="PTU" /><category term="빅데이터프로그래밍(4학년-1학기)" /><summary type="html"></summary></entry><entry><title type="html">BrowserRendering - 2 - 브라우저 렌더링과 렌더링 엔진</title><link href="https://suhwan2004.github.io/frontend/BrowserRendering2/" rel="alternate" type="text/html" title="BrowserRendering - 2 - 브라우저 렌더링과 렌더링 엔진" /><published>2022-06-10T00:00:00+00:00</published><updated>2022-06-10T00:00:00+00:00</updated><id>https://suhwan2004.github.io/frontend/BrowserRendering2</id><content type="html" xml:base="https://suhwan2004.github.io/frontend/BrowserRendering2/">&lt;h2 id=&quot;브라우저의-기본-구조&quot;&gt;브라우저의 기본 구조&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/172888008-1bf37b90-f64b-4862-9b27-07c8792b0ce7.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;사용자 인터페이스&lt;/strong&gt; - 주소 표시줄, 이전/다음/새로고침 버튼 등 웹 페이지를 제외하고 사용자와 상호작용합니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;브라우저 엔진&lt;/strong&gt; - 사용자 인터페이스와 렌더링 엔진을 연결하고 둘 사이의 동작을 제어합니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;렌더링 엔진&lt;/strong&gt; - HTML과 CSS를 parsing하여 요청한 웹 페이지를 표시해줍니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;통신&lt;/strong&gt; - HTTP 요청과 같은 네트워크 호출에 사용됩니다. 이 것은 플랫폼 독립적인 인터페이스이고 각 플랫폼 하부에서 실행됩니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;UI 백엔드&lt;/strong&gt; - 체크박스나 버튼같은 기본적인 위젯을 그려줍니다. 플랫폼에서 명시하지 않은 일반적인 인터페이스로서, OS 사용자 인터페이스 체계를 사용합니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;자바스크립트 해석기(인터프리터)&lt;/strong&gt; - 자바스크립트 코드를 해석하고 실행합니다. =&amp;gt; chrome은 v8임..&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;자료 저장소&lt;/strong&gt; - localStorage나 Cookie와 같이 보조 기억장치에 데이터를 저장하는 부분입니다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;브라우저의 기본구조는 위와 같이 7개의 요소로 이뤄집니다.&lt;/p&gt;

&lt;p&gt;여기서 더 알아야 할 부분이 있는데…&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;자바스크립트 해석기와 렌더링 엔진은 브라우저 별로 다릅니다.&lt;/li&gt;
  &lt;li&gt;각 브라우저 별로 브라우저 구조가 다릅니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;각-브라우저-별-자바스크립트-해석기&quot;&gt;각 브라우저 별 자바스크립트 해석기&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Rhino - 모질라&lt;/li&gt;
  &lt;li&gt;SpiderMonkey - 파이어폭스&lt;/li&gt;
  &lt;li&gt;V8 - 구글, 오페라&lt;/li&gt;
  &lt;li&gt;JavascriptCore - 사파리&lt;/li&gt;
  &lt;li&gt;Chakra - 익스플로러, 마이크로소프트 엣지&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;각-브라우저-별-렌더링-엔진&quot;&gt;각 브라우저 별 렌더링 엔진&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Gecko - 모질라, 파이어폭스&lt;/li&gt;
  &lt;li&gt;Blink - 구글, 오페라&lt;/li&gt;
  &lt;li&gt;Webkit - 사파리&lt;/li&gt;
  &lt;li&gt;Trident - 익스플로러&lt;/li&gt;
  &lt;li&gt;EdgeHTML - 마이크로소프트 엣지&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;파이어폭스-브라우저-구조의-모습&quot;&gt;파이어폭스 브라우저 구조의 모습&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/172893452-61f4c497-b48c-4ff5-b48c-a783271d83f8.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;크롬-브라우저-구조의-모습&quot;&gt;크롬 브라우저 구조의 모습&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/172893522-e62610d1-0498-423a-ad8e-c7292927270a.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;브라우저-렌더링-동작-과정&quot;&gt;브라우저 렌더링 동작 과정&lt;/h2&gt;

&lt;p&gt;브라우저 렌더링의 동작과정을 간단하게 알아봅시다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;사용자가 주소표시줄에 URI를 입력하여 브라우저 엔진에 전달합니다.
=&amp;gt; URL과 URI의 차이가 뭐죠(주소 예정)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;브라우저 엔진은 주소를 이용해서 HTML, CSS, image등을 가져옵니다.
=&amp;gt; &lt;a href=&quot;https://suhwan2004.github.io/frontend/BrowserRendering1/&quot;&gt;주소창에 구글을 치면 어떻게 될까?&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;렌더링 엔진은 브라우저 엔진에서 가져온 자료들을 분석합니다. 동시에 URI 데이터를 통신, 자바스크립트 해석기, UI 백엔드로 전파한다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;또한 렌더링 엔진은 통신 레이어에 URI에 대한 추가 데이터(있다면)를 요청하고 응답할 때까지 기다립니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;응답받은 데이터에서 HTML, CSS는 렌더링 엔진이 파싱합니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;응답받은 데이터에서 JavaScript는 JavaScript 해석기가 파싱합니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;JavaScript 해석기는 파싱한 결과를 렌더링 엔진에 전달하여 3번과 5번에서 파싱한 HTML의 결과인 DOM tree을 조작합니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;조작이 완료된 DOM node(DOM tree 구성요소)는 render object(render tree 구성요소)로 변합니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;UI 벡엔드는 render object를 브라우저 렌더링 화면에 띄워줍니다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;렌더링-엔진의-동작-과정&quot;&gt;렌더링 엔진의 동작 과정&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/172893881-678a03b1-394f-46cb-9ab1-5d1ec5b91c26.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;랜더링 과정에 대한 사진은 위와 같습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2.naver.com/content/images/2015/06/helloworld-59361-3.png&quot; alt=&quot;brouser3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;또한, 위의 사진은 Webkit의 동작과정의 모습입니다. 각 브라우저별로 단어의 차이는 있으나 전체적인 순서는 비슷합니다.&lt;/p&gt;

&lt;p&gt;아래부터, 각 과정에 대해 설명해보겠습니다.&lt;/p&gt;

&lt;h3 id=&quot;1-html을-parsing하여-dom-tree를-생성한다&quot;&gt;1. HTML을 parsing하여 DOM Tree를 생성한다.&lt;/h3&gt;

&lt;p&gt;DOM은 마크업과 1:1 관계를 맺습니다. 예를 들면 이런 마크업이 있다고 해볼께요.&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Hello World&lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&amp;gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;example.png&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위의 마크업은 아래와 같은 DOM Tree로 변환할 수 있습니다.
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/172902952-ca6c4886-9bc5-475c-9089-cf88463af567.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이런 DOM Tree로 만들기 위해서는 아래와 같은 파싱 알고리즘을 거쳐야 합니다.
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/172903458-0ce1e00e-f0df-47ce-aa39-6f6e905d3c14.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이렇게 HTML 문서를 파싱하고, 파싱 트리를 생성합니다.&lt;/p&gt;

&lt;p&gt;여기서 문서 파싱은 브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것을 의미합니다.&lt;/p&gt;

&lt;p&gt;파싱 트리를 기반으로 DOM 요소와 속성 노드를 가지는 DOM 트리를 생성합니다.&lt;/p&gt;

&lt;h3 id=&quot;2-cssstyle-sheets를-parsing하여-스타일-규칙을-얻는다&quot;&gt;2. CSS(style sheets)를 parsing하여 스타일 규칙을 얻는다&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/172904762-c027568f-d67c-43e0-8320-9118f86e8c5b.png&quot; alt=&quot;image&quot; /&gt;
위 사진은 웹킷의 css 파싱 과정입니다.&lt;/p&gt;

&lt;p&gt;HTML 파싱과 비슷한 느낌으로 CSS또한 파싱해줍니다.
=&amp;gt; 그 결과로 CSSOM이 생성됩니다.&lt;/p&gt;

&lt;h3 id=&quot;3-dom-tree를-생성하는-동시에-이미-생성된-dom-tree와-스타일-규칙cssom을-attachment한다&quot;&gt;3. DOM Tree를 생성하는 동시에, 이미 생성된 DOM Tree와 스타일 규칙(CSSOM)을 Attachment한다&lt;/h3&gt;

&lt;p&gt;DOM Tree가 구축이 되어가는 동안 브라우저는 DOM Tree를 기반으로 렌더 트리를 생성해줍니다.&lt;/p&gt;

&lt;p&gt;문서를 시각적인 구성 요소로 만들어 주는 역활을 해준다고 볼 수 있습니다.&lt;/p&gt;

&lt;p&gt;여기서 알고 있어야 되는 점은&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;렌더 트리는 DOM 노드 하나, 하나가 생성될 때 마다 렌더 오브젝트가 추가&lt;/strong&gt;되며 이 것들이 렌더 트리가 됩니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;모든 DOM 노드가 렌더 오브젝트가 되는건 아닙니다.&lt;/strong&gt;(head tag, display none tag…)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;html, body tag DOM 노드&lt;/strong&gt; 또한 렌더 오브젝트로 구성되긴 하는데 얘네들은 &lt;strong&gt;render tree root로써 render view라고 부릅니다.&lt;/strong&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;렌더 오브젝트는 render tree root에 추가된다&lt;/strong&gt;는 사실!&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;렌더 트리는 위치와 크기를 가지고 있지 않기 때문에, 렌더 오브젝트들에게 &lt;strong&gt;위치와 크기를 결정&lt;/strong&gt;해준다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;4-구축한-render-tree를-배치layout한다&quot;&gt;4. 구축한 render tree를 배치(layout)한다&lt;/h3&gt;

&lt;p&gt;렌더링 트리는 위치와 크기를 가지고 있지 않기 때문에, 렌더 오브젝트들에게 위치와 크기를 결정해줍니다.&lt;/p&gt;

&lt;h3 id=&quot;5-배치가-끝난-render-tree를-그린다&quot;&gt;5. 배치가 끝난 render tree를 그린다.&lt;/h3&gt;

&lt;p&gt;렌더 트리의 각 노드를 화면의 픽셀로 나타내집니다.&lt;/p&gt;

&lt;p&gt;렌더 트리 그리기가 완료되면, 화면에 콘텐츠가 표현됩니다.&lt;/p&gt;

&lt;h2 id=&quot;마무리&quot;&gt;마무리&lt;/h2&gt;

&lt;p&gt;브라우저 렌더링과 렌더링 엔진의 동작 과정에 대해 간단하게 알아 보았습니다.&lt;/p&gt;

&lt;p&gt;결론적으로 렌더 트리가 만들어져 화면에 콘텐츠가 나온다고 해도 다시 이 작업들을 해야되는 상황이 존재합니다.&lt;/p&gt;

&lt;p&gt;다음 글에서는 이런 상황에서 최적화를 어떤 부분에서 잡아낼 수 있는지 알아보겠습니다.&lt;/p&gt;

&lt;h2 id=&quot;reference&quot;&gt;Reference&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;https://davidhwang.netlify.app/Developments/browser-rendering-process/&lt;/li&gt;
  &lt;li&gt;https://d2.naver.com/helloworld/59361&lt;/li&gt;
  &lt;li&gt;https://all-young.tistory.com/22&lt;/li&gt;
  &lt;li&gt;https://www.youtube.com/watch?v=EBe-OHkf9w8&lt;/li&gt;
  &lt;li&gt;https://www.youtube.com/watch?v=sJ14cWjrNis&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Suhwan Kim</name><email>suhwan2004@gmail.com</email></author><category term="FrontEnd" /><category term="FrontEnd" /><summary type="html">브라우저의 기본 구조</summary></entry><entry><title type="html">BrowserRendering - 1 - 주소창에 구글을 치면 어떻게 될까?</title><link href="https://suhwan2004.github.io/frontend/BrowserRendering1/" rel="alternate" type="text/html" title="BrowserRendering - 1 - 주소창에 구글을 치면 어떻게 될까?" /><published>2022-06-09T00:00:00+00:00</published><updated>2022-06-09T00:00:00+00:00</updated><id>https://suhwan2004.github.io/frontend/BrowserRendering1</id><content type="html" xml:base="https://suhwan2004.github.io/frontend/BrowserRendering1/">&lt;p&gt;해당 시리즈는 브라우저내에서 원하는 페이지를 화면에 띄울때 정말 여러 개의 과정이 존재하는데 그 과정들에 대해 공부한 내용을 정리하고 복습하기 위해 만든 페이지입니다.&lt;/p&gt;

&lt;h2 id=&quot;전체적인-과정&quot;&gt;전체적인 과정&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;도메인을 통해 JS, HTML, CSS 파일을 받음&lt;/li&gt;
  &lt;li&gt;받은 파일들을 이용해 화면에 띄움(브라우저 랜더링)&lt;/li&gt;
  &lt;li&gt;랜더링 이후에 액션, 이벤트에 따라 Reflow와 Repaint 과정이 발생한다. =&amp;gt; 최적화 필요&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;넓게 보면 이 3가지의 과정인 것 같습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/172627199-dfe70a2c-fc88-457f-82b6-7bcfad797231.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;물론, 이렇게 설명하면 이미 브라우저 랜더링을 알고 있는 사람 빼고는 ‘얘가 무슨 말을 하는거지??’라는 생각을 가질 것 같습니다.&lt;/p&gt;

&lt;p&gt;그리해서, 이번 페이지에서는 &lt;strong&gt;1번. 도메인을 통해 파일들을 받아오는 과정&lt;/strong&gt;에 대해 설명하고 다음 페이지에서 2번과정, 다다음 페이지에서 3번과정을 설명하는 느낌의 시리즈 물로 만들어 보고자 합니다.&lt;/p&gt;

&lt;p&gt;아래부터, 과정에 따른 설명을 적어보도록 하겠습니다.&lt;/p&gt;

&lt;h2 id=&quot;1-주소창에-원하는-주소를-입력한다&quot;&gt;1. 주소창에 원하는 주소를 입력한다&lt;/h2&gt;

&lt;h2 id=&quot;2-ip-주소를-찾는다&quot;&gt;2. IP 주소를 찾는다.&lt;/h2&gt;

&lt;p&gt;2번 과정을 넓은 개념으로 적어둔 이유는 이 과정 안에서 여러 가지 상황에 따른 경우가 존재해서 그렇습니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;DNS 레코드를 캐시를 통해 찾을 수 있는 경우&lt;/li&gt;
  &lt;li&gt;IP를 찾기 위해 네임 서버까지 가서, 현재 입력한 주소를 통해 IP를 받는 경우&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;이렇게 두 가지 경우가 존재하는데요.&lt;/p&gt;

&lt;p&gt;먼저, DNS, 네임서버 그리고 DNS 레코드에 대해 간략히 이해하고 가보자면…&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;DNS(Domain Name System)&lt;/strong&gt; 은 범국제적 단위로 &lt;strong&gt;웹사이트의 IP 주소와 도메인 주소를 이어주는 환경/시스템&lt;/strong&gt; 입니다. 약간 자료구조의 Hash Map 느낌인데 우리가 친 주소(key)를 통해 IP(value)를 찾게 해준다고 볼 수 있습니다.&lt;/li&gt;
  &lt;li&gt;네임 서버는 이런 DNS를 운영하는 서버입니다.&lt;/li&gt;
  &lt;li&gt;DNS 레코드는 DNS에서 받은 요청을 어떻게 처리할 것인지에 대한 정보라고 합니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;일단, 첫번째 경우부터 한 번 살펴보겠습니다.&lt;/p&gt;

&lt;h3 id=&quot;21-dns-레코드를-캐시를-통해-찾을-수-있는-경우&quot;&gt;2.1. DNS 레코드를 캐시를 통해 찾을 수 있는 경우&lt;/h3&gt;

&lt;p&gt;이 경우는 저희가 이 사이트를 이미 방문한 전적이 있을 때 발생하는 경우입니다.&lt;/p&gt;

&lt;p&gt;한 마디로, 이미 간 기록이 캐시 내에 존재하기 때문에 저희는 굳이 네임 서버까지 가서 IP를 찾고 다시 돌아오는 고생을 할 필요가 없기 때문에 네트워크 트래픽, 데이터 전송 시간이 개선될 수 있기 때문에 더 좋습니다.&lt;/p&gt;

&lt;p&gt;먼저, 캐시에는 찾아보니 4가지 종류가 있었습니다. 아래는 과정이 저희가 원하는 정보를 찾는 과정이 기술되어 있습니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;처음에는 &lt;strong&gt;브라우저 캐시&lt;/strong&gt;를 확인합니다. 브라우저는 일정한 기간동안 저희가 갔던 장소를 DNS 레코드 저장소에다가 저장을 해놓습니다. 그렇기 때문에, 만약에 저희가 원하는 정보가 DNS 레코드 저장소에 있으면 여기서 DNS 쿼리를 통해 저희가 원하는 정보를 찾을 수 있습니다!&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;없다면 &lt;strong&gt;OS 캐시&lt;/strong&gt;를 확인합니다. OS도 DNS 레코드 캐시를 유지관리 하는 기능이 있기 때문에 OS에 대한 시스템 호출을 통해 만약, DNS 레코드가 존재한다면 가져 올 수 있겠죠?&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;OS 캐시에도 없었다면 &lt;strong&gt;라우터 캐시&lt;/strong&gt;를 향해 가야 합니다. 라우터가 자체 DNS 레코드 캐시를 유지 관리를 하기 때문에 여기에 있기 때문입니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;라우터 캐시에도 없다?? 이러면 마지막으로 &lt;strong&gt;ISP 캐시&lt;/strong&gt;를 보러 갑니다. ISP는 DNS 레코드 캐시를 포함하는 자체 네임 서버를 유지관리 하기 때문에 한번 찔러 봅니다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;?? : 캐시 다 뒤져봤는데 없는데요? 저 어떡하죠?&lt;/li&gt;
  &lt;li&gt;A : 어떡하긴 그냥 네임 서버 가야지요 히히&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;22-네임-서버로-가는-경우&quot;&gt;2.2 네임 서버로 가는 경우&lt;/h3&gt;

&lt;p&gt;저희는 일단 캐시에서 IP를 찾지 못한 상황이구요. 이제 저희가 해야될 건 우리가 갈 웹사이트에 대한 올바른 IP 주소를 찾을 때까지 인터넷에서 여러 네임 서버를 검색하는 해야 됩니다.&lt;/p&gt;

&lt;p&gt;이 과정에서, &lt;strong&gt;IP 주소를 찾거나, 못 찾았다는 오류 주소가 뜰 때까지&lt;/strong&gt; 현재 네임 서버 =&amp;gt; 다음 네임 서버 =&amp;gt; 다다음 네임 서버… 이렇게 반복되기 때문에 이런 유형의 검색을 &lt;strong&gt;reculsive search(재귀 검색)&lt;/strong&gt;이라고 합니다.&lt;/p&gt;

&lt;p&gt;이 상황에서 총대를 맨건 &lt;strong&gt;ISP&lt;/strong&gt;입니다. ISP는 네임 서버를 인터넷의 다른 네임 서버에 응답을 요청하여 저희가 원하는 주소를 찾는 것에 대해 책임을 지는데 이걸 &lt;strong&gt;DNS recursor&lt;/strong&gt; 라고 부릅니다.&lt;/p&gt;

&lt;p&gt;아래는 DNS recursor가 IP를 찾을 때까지의 과정을 그림으로 나타낸 것입니다.
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/172639421-86b92bd9-69b6-4abf-810f-b67d6d747691.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;현재 저희가 접하는 많은 웹 사이트 URL은 총 4가지 단계의 도메인이 포함되어 있습니다. 각각 단계에서 DNS lookup 프로세스 중에 쿼리되는 고유한 네임서버 또한 존재합니다.&lt;/p&gt;

&lt;p&gt;저희가 보는 URL이 www.google.com이라고 예시로 들고 진행해보겠습니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;먼저, Root domain으로 이동합니다.&lt;/li&gt;
  &lt;li&gt;도착하면 DNS recursor가 root 네임 서버에 연락을 겁니다.&lt;/li&gt;
  &lt;li&gt;root 네임 서버는 Top-level domains에 &lt;strong&gt;.com 네임 서버&lt;/strong&gt;로 redirect 합니다.&lt;/li&gt;
  &lt;li&gt;.com 네임 서버는 &lt;strong&gt;google.com 네임 서버&lt;/strong&gt;로 redirect 할 것이구요.&lt;/li&gt;
  &lt;li&gt;google.com 네임 서버는 DNS 기록에서 www.google.com에 매칭되는 IP 주소를 찾고 DNS recursor로 보내줍니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;이 모든 요청들은 &lt;strong&gt;보내는 요청의 내용과 DNS recursor의 IP 주소가 포함되어 있는 작은 데이터 패킷들&lt;/strong&gt;을 통해 보내집니다.&lt;/p&gt;

&lt;p&gt;이 패킷들은 원하는 DNS 레코드를 가진 네임 서버에 도달할 때 까지 클라이언트와 서버를 여러 번 오가구요.&lt;/p&gt;

&lt;p&gt;패킷들이 움직이는 것은 routing table에 기반합니다. Routing table을 통해서 어떤 길로 가야 가장 빠른지 확인할 수 있고, 만약 패킷이 도중에 loss되면 request fail error가 발생하게 됩니다.&lt;/p&gt;

&lt;h2 id=&quot;3-브라우저가-서버의-tcp-connection&quot;&gt;3. 브라우저가 서버의 TCP connection&lt;/h2&gt;

&lt;p&gt;자, 저희는 드디어 원하던 IP를 얻었습니다. 이제 그럼 저희가 원하는 HTML, CSS, js 파일들을 받기 위해 먼저 서버와 연결을 해야 될 것 같아요.&lt;/p&gt;

&lt;p&gt;이 서버와의 연걸은 인터넷 프로토콜을 사용해서 진행되는데, 보통 웹 사이트의 HTTP 요청은 &lt;strong&gt;TCP/IP&lt;/strong&gt;를 통해 이뤄집니다.&lt;/p&gt;

&lt;p&gt;일단은, 이 TCP/IP의 &lt;strong&gt;3 way handshake&lt;/strong&gt;라는 프로세스를 통해 연결이 되는데 TCP/IP에 대한 설명은 다른 페이지에 해 두도록 하겠습니다.
=&amp;gt; TCP/IP란 무엇일까? (페이지 제작 예정)&lt;/p&gt;

&lt;p&gt;만약, 안 보고 오셨더라도 저희는 일단, TCP/IP 프로토콜을 통해 서버와 연결이 잘 됬다!를 저희는 알고 있기 때문에 문제는 없습니다.&lt;/p&gt;

&lt;h2 id=&quot;4-브라우저의-웹-서버를-향한-http-request&quot;&gt;4. 브라우저의 웹 서버를 향한 HTTP request&lt;/h2&gt;

&lt;p&gt;이제 진짜, 파일들을 받을 수 있습니다.&lt;/p&gt;

&lt;p&gt;클라이언트 브라우저(저희)는 이제 GET 요청을 통해 서버에게 저희가 원하는 사이트의 웹 페이지를 구성하는 파일들을 요구합니다.&lt;/p&gt;

&lt;p&gt;보통 GET이 사용되긴 하는데 비밀 자료가 포함된다거나, form을 제출하는 상황에서는 POST 요청을 사용할 수도 있습니다.&lt;/p&gt;

&lt;p&gt;위의 GET, POST는 REST API에서 나온 용어입니다. 이 또한 정리해둔 페이지를 하단에 첨부해볼께요!
=&amp;gt; REST는 뭐고 REST API는 뭐지? ( 페이지 제작 예정)&lt;/p&gt;

&lt;p&gt;쨋든, 저희가 이러한 요청을 하면 부가적인 정보들이 많이 들어옵니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;browser identification(User-Agent 헤더)&lt;/li&gt;
  &lt;li&gt;받아들일 요청의 종류(Accept 헤더)&lt;/li&gt;
  &lt;li&gt;추가적인 요청을 위해 TCP connection을 유지를 요청하는 connection 헤더&lt;/li&gt;
  &lt;li&gt;브라우저에서 얻은 쿠키 정보&lt;/li&gt;
  &lt;li&gt;기타 등등
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/172645177-e1d0c579-90dc-4cee-9615-e5afd460176a.png&quot; alt=&quot;image&quot; /&gt;
(만약, 이런 결과값을 눈으로 보고 싶다면 Postman, firebug과 같은 API 테스트 툴을 사용해보셔도 좋을 것 같습니다.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;5-서버가-request를-처리하고-response를-생성&quot;&gt;5. 서버가 request를 처리하고 response를 생성&lt;/h2&gt;

&lt;p&gt;서버는 웹서버를 가지고 있습니다(i.e. Apache, IIS…).
이들은 브라우저로부터 요청을 받고 request handler한테 요청을 전달해서 요청을 읽고 response를 생성하게 합니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Request handler란 ASP.NET, PHP, Ruby 등으로 작성된 프로그램&lt;/strong&gt;을 의미합니다.&lt;/p&gt;

&lt;p&gt;이 Request handler는 요청과 요청의 헤더, 쿠키를 읽어서 요청이 무엇인지 파악하고 필요하다면 서버에 정보를 업데이트 합니다.&lt;/p&gt;

&lt;p&gt;그 다음에 response를 특정한 포맷으로(JSON, XML, HTML) 작성합니다.&lt;/p&gt;

&lt;h2 id=&quot;6-서버가-http-response를-보냄&quot;&gt;6. 서버가 HTTP response를 보냄.&lt;/h2&gt;

&lt;p&gt;서버의 response에는 요청한 웹페이지, status code, compression type(Content-Encoding), 어떻게 페이지를 캐싱할지(Cache-Control), 설정할 쿠키가 있다면 쿠키, 개인정보 등이 포함됩니다.&lt;/p&gt;

&lt;p&gt;postman을 사용해서 네이버에서 받은 HTTP response의 header 입니다.
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/172650633-2e2e7bd4-c6c6-47be-a5a6-b359f56337e3.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;자세히 보시면 status : 200 OK라고 나와있는데 이게 Status code 입니다.
Status code란 현재 response의 상태를 의미하고 총 5가지의 종류가 있습니다:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;1xx은 정보만 담긴 메세지라는 것을 의미함.&lt;/li&gt;
  &lt;li&gt;2xx response가 성공적이라는 것을 의미함. =&amp;gt; 보통 200인 것 같아요.&lt;/li&gt;
  &lt;li&gt;3xx 클라이언트를 다른 URL로 redirect함을 의미함.&lt;/li&gt;
  &lt;li&gt;4xx 클라이언트 측에서 에러가 발생했음을 의미함.&lt;/li&gt;
  &lt;li&gt;5xx 서버 측에서 에러가 발생했음읠 의미함.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;8-browser-rendering&quot;&gt;8. Browser Rendering&lt;/h2&gt;

&lt;p&gt;이제, 드디어 저희가 다음 페이지에서 봐야할 브라우저 렌더링이 됩니다.&lt;/p&gt;

&lt;p&gt;렌더링이 되고 나서, 또 서버랑 통신하면서 시간을 쓰는 것은 매우 아깝기 때문에 저희는 받아온 정적인 파일들을 Browser Elements들 중 &lt;strong&gt;자료 저장소&lt;/strong&gt; 라는 곳에 저장해둡니다.&lt;/p&gt;

&lt;p&gt;아마, 자료 저장소에 저희가 갈 사이트의 파일들이 존재한다면 통신은 안해도 되겠죠?&lt;/p&gt;

&lt;p&gt;Browser Rendering 과정은 다음 포스트 글을 확인해주심 될 것 같아요. 오늘은 여기서 마치겠습니다.&lt;/p&gt;

&lt;p&gt;감사합니다!&lt;/p&gt;

&lt;h2 id=&quot;reference&quot;&gt;Reference&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;https://devjin-blog.com/what-happen-browser-search/&lt;/li&gt;
  &lt;li&gt;https://medium.com/@maneesha.wijesinghe1/what-happens-when-you-type-an-url-in-the-browser-and-press-enter-bb0aa2449c1a&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Suhwan Kim</name><email>suhwan2004@gmail.com</email></author><category term="FrontEnd" /><category term="FrontEnd" /><summary type="html">해당 시리즈는 브라우저내에서 원하는 페이지를 화면에 띄울때 정말 여러 개의 과정이 존재하는데 그 과정들에 대해 공부한 내용을 정리하고 복습하기 위해 만든 페이지입니다.</summary></entry><entry><title type="html">학교 - 4학년 1학기 파멸의 기말고사 - 인공지능의 역습</title><link href="https://suhwan2004.github.io/ptu/DisesterGimal_AI/" rel="alternate" type="text/html" title="학교 - 4학년 1학기 파멸의 기말고사 - 인공지능의 역습" /><published>2022-06-07T00:00:00+00:00</published><updated>2022-06-07T00:00:00+00:00</updated><id>https://suhwan2004.github.io/ptu/DisesterGimal_AI</id><content type="html" xml:base="https://suhwan2004.github.io/ptu/DisesterGimal_AI/">&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/172381488-c5f1e668-457f-40e9-9177-a7ec51df95de.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;해당-사진은-2022년-평택대학교-4학년-1학기-인공지능-과목을-수강하시는-모든-학우들을-위해-바칩니다&quot;&gt;해당 사진은 2022년 평택대학교 4학년 1학기 인공지능 과목을 수강하시는 모든 학우들을 위해 바칩니다.&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;교수님이 제공해준 기말고사 준비도 테스트 문제(?)의 답을 먼저 적어넣었음.&lt;/li&gt;
  &lt;li&gt;9 ~ 14주 까지에서 나올만한 것들을 추려서 적었음.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;1-기준테-문제--답과-해설&quot;&gt;1. 기.준.테 문제 : 답과 해설&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;()은 나와 유사한 성향을 갖고 있는 사람들이 좋아하는 것은 나도 좋아할 가능성이 높을 것이라는 가정에 기반한 알고리즘이다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;()은 지능을 가진 동물이 시행착오를 통해 학습하는 방법을 모델링한 것이다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;()을 제안한 이안 굿펠로(Ian Goodfellow)는 ()을 경찰과 위조 지폐범 사이의 게임에 비유한다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;k-평균 알고리즘에서 k는 몇 개의 무리로 ()할 것인지를 나타내는 것이다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;강화학습에서 유일하게 참조하는 것은 에이전트가 행동을 취한 후 얻는 ()이다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;고전적인 방법으로 자연어를 처리하는 것에 한계를 느껴 암흑기가 도래하였으나 이후 ()으로 해결하였다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;깊이가 깊은 심층신경망에서는 역전파 알고리즘이 입력층으로 전달됨에 따라 그래디언트가 점점 작아져 결국 가중치 매개변수가 업데이트 되지 않는 경우가 발생하게 된다. 이러한 문제를 ()이라고 한다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;다층 신경망은 중간에 은닉층을 추가함으로써 () 문제를 해결한다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;딥러닝은 ()를 해결하기 위해 랜덤하게 신경망 연결을 끊어 일반화 능력을 향상시켰다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;딥러닝은 ‘논리적인 접근 방식’에서 () 접근 방식으로 전환한 것이다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;비지도학습은 입력된 데이터를 받아 컴퓨터가 스스로 데이터들의 ()을 찾아내 학습한다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;비지도학습의 목표는 레이블 없이 확보된 데이터의 특성을 분석해서 유사한 특성을 가진 값끼리 ()하는 것이다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;인공지능 분야에서 가장 어려운 분야가 () 분야이다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;자연어처리에서 앞뒤 데이터 간에 연관성이 있는 데이터셋에 사용하는 모델인 ()을 사용하여 시계열적 시간 특성이 포함된 동적인 언어 데이터 처리가 가능해졌다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;지도학습의 목적은 입력 데이터와 결과값을 이용해 특정한 타깃을 ( )하는 것이다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;학습된 알고리즘이 예측하는 결과값이 이산값이면 ( ) 문제이고, 연속 값이면 () 문제에 해당된다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;아래는-정답입니다&quot;&gt;아래는 정답입니다.&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;협업 필터링&lt;/li&gt;
  &lt;li&gt;강화학습&lt;/li&gt;
  &lt;li&gt;생성적 적대 신경망(Generative Adversarial Network), GAN&lt;/li&gt;
  &lt;li&gt;클러스터링&lt;/li&gt;
  &lt;li&gt;보상&lt;/li&gt;
  &lt;li&gt;딥러닝&lt;/li&gt;
  &lt;li&gt;그래디언트 소실&lt;/li&gt;
  &lt;li&gt;XOR&lt;/li&gt;
  &lt;li&gt;과대적합 문제&lt;/li&gt;
  &lt;li&gt;실험적&lt;/li&gt;
  &lt;li&gt;특징&lt;/li&gt;
  &lt;li&gt;그룹화&lt;/li&gt;
  &lt;li&gt;자연어 처리&lt;/li&gt;
  &lt;li&gt;RNN&lt;/li&gt;
  &lt;li&gt;예측&lt;/li&gt;
  &lt;li&gt;분류, 회귀&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;ppt-중-나올-만한-부분-키워드로-정리&quot;&gt;PPT 중 나올 만한 부분 키워드로 정리&lt;/h2&gt;

&lt;h3 id=&quot;7장&quot;&gt;7장&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;지도학습 : 문제(Feature)와 정답(Label)이 있는 학습데이터(Training Set)를 컴퓨터에 학습&lt;/li&gt;
  &lt;li&gt;지도학습의 목적은 특정한 타깃을 예측하는 것&lt;/li&gt;
  &lt;li&gt;예측하는 결과값이 &lt;strong&gt;이산값 =&amp;gt; 분류 문제&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;예측하는 결과값이 &lt;strong&gt;연속값 =&amp;gt; 회귀 문제&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;회귀 : 독립변수와 종속변수의 관계를 설명할 때 가장 많이 쓰는 모델&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;선형 회귀 모델&lt;/strong&gt; : &lt;strong&gt;분류하는 요인의 수가 적을 때 활용&lt;/strong&gt;하기 용이&lt;/li&gt;
  &lt;li&gt;분류에는 의사결정 트리, 로지스틱 회귀&lt;/li&gt;
  &lt;li&gt;회귀에는 회귀 트리(랜덤 포레스트), 선형 회귀&lt;/li&gt;
  &lt;li&gt;k - 최근접 이웃 : 최근접 이웃을 찾음&lt;/li&gt;
  &lt;li&gt;로지스틱 회귀 : 시그모이드 함수를 씀&lt;/li&gt;
  &lt;li&gt;서포트 백터 머신 : 데이터들의 경계 중 가장 큰 폭을 가진 경계를 찾음&lt;/li&gt;
  &lt;li&gt;나이트 베이즈 : 복잡한 베이즈 정리를 간단한 조건부 확률 방법을 이용해 분류하는 알고리즘&lt;/li&gt;
  &lt;li&gt;의사결정 트리 : 특정 기준에 따라 데이터를 구분하는 학습 모델&lt;/li&gt;
  &lt;li&gt;랜덤 포레스트 : 분류, 회귀분석 등에 사용되는 앙상블 학습 방법의 일종&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;신경망/딥러닝 : 인간의 신경 모델을 모방한 학습 방법. 뉴런의 가중값 구함.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;의사 결정 트리&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;정보 획득량 : 어떤 사건이 얼마만큼의 정보를 줄 수 있는지를 수치화 =&amp;gt; 정보 함수와 엔트로피 필요&lt;/li&gt;
      &lt;li&gt;엔트로피 : 무질서도를 정량화해 나타낸 값&lt;/li&gt;
      &lt;li&gt;의사결정 트리는 정보 함수와 엔트로피를 사용해 나타낸 정보 획득량을 최대화한느 순서로 배치하는 것. 중요도 값 계산을 위해 기계학습 사용.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;k-NN, k-최근접 이웃 알고리즘 : 새로운 데이터가 주어질 때 기존 데이터 가운데 &lt;strong&gt;가장 가까운 k개 이웃의 정보로 새로운 데이터 예측&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;k는 작은 값이 좋음. =&amp;gt; 크면 분류 못할수도 있음.&lt;/li&gt;
  &lt;li&gt;k값은 기본적으로 홀수&lt;/li&gt;
  &lt;li&gt;유클리드 거리로 계산함.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;8장&quot;&gt;8장&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;비지도학습 : 훈련데이터에 레이블이 없음. 스스로 데이터의 특징 찾음.&lt;/li&gt;
  &lt;li&gt;목표 : 유사한 속성을 가진 값끼리 그룹화하는 것&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;알고리즘 종류&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;군집
        &lt;ul&gt;
          &lt;li&gt;k-평균(k-means) : 주어진 데이터를 지정된 클러스터 갯수(k)로 그룹핑&lt;/li&gt;
          &lt;li&gt;계층 군집 분석(HCA) : 하나의 case가 될 때까지 군집을 묶는 클러스터링. 군집 간의 거리를 기반으로 클러스터링을 하는 알고리즘. 군집 수 안 정해도 됨.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;시각화와 차원 축소 : 주성분 분석, 커널, 지역적 선형 임베딩, -SNE&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;k-평균 알고리즘
    &lt;ul&gt;
      &lt;li&gt;클러스터 : 유사한 특성을 가진 데이터끼리의 묶음&lt;/li&gt;
      &lt;li&gt;클러스터링 : 어떤 데이터들이 주어질 때, 그 데이터들을 클러스터로 무리지어 주는 것&lt;/li&gt;
      &lt;li&gt;센트로이드 : 클러스터의 중심&lt;/li&gt;
      &lt;li&gt;k : 몇 개의 무리로 클러스터링할 것인지 나타냄.&lt;/li&gt;
      &lt;li&gt;차원 축소 : 상관관계가 있는 여러 특징을 하나로 합치는 것&lt;/li&gt;
      &lt;li&gt;특징 추출 : 두 가지 특성을 어떤 사건의 원인을 나타내는 하나의 특성으로 합침.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;협업 필터링 : 내가 좋아하는건 남도 좋아할 가능성이 높다고 생각한 알고리즘.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;협업 필터링의 종류
        &lt;ul&gt;
          &lt;li&gt;사용자 기반 : **좋아하는 성향이 유사한 사용자들을 같은 그룹으로 묶고 ** 그 그룹에서 선호하는 상품을 추천&lt;/li&gt;
          &lt;li&gt;아이템 기반 : &lt;strong&gt;사용자가 이전에 구매한 아이템을 기반&lt;/strong&gt;으로 연관성 있는 상품 추천&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;장점 : 직관적, 신뢰도 높음&lt;/li&gt;
      &lt;li&gt;단점
        &lt;ul&gt;
          &lt;li&gt;콜드 스타트 문제 : 데이터 의존도 높음 =&amp;gt; 새로운 페턴에 대한 추천 어려움.&lt;/li&gt;
          &lt;li&gt;First-Rater 문제 : 기존에 구매가 이뤄지지 않은 상품은 추천이 안 일어남.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;단점을 보완하기 위해 콘텐츠 기반 필터링이 함께 쓰임!&lt;/li&gt;
      &lt;li&gt;전통적 알고리즘
        &lt;ul&gt;
          &lt;li&gt;협업 필터링&lt;/li&gt;
          &lt;li&gt;콘텐츠 기반 필터링&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;최신 알고리즘
        &lt;ul&gt;
          &lt;li&gt;모델 기반 협력 필터링&lt;/li&gt;
          &lt;li&gt;딥러닝 기반 필터링&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;GAN, 생성적 적대 신경망 : 이안 굿펠로는 GAN을 경찰과 위조 지폐범 사이의 게임에 비유
    &lt;ul&gt;
      &lt;li&gt;저해상도 이미지를 고해상도 개선, 음성 복원, 게임 배경화면 생성…&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;9장&quot;&gt;9장&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;강화학습 : 보상을 최대화 하기 위해 스스로 선택하는 학습, 동물의 학습법&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;에이전트 : 지정한 작업을 수행하기 위해 훈련하는 프로그램&lt;/li&gt;
      &lt;li&gt;환경 : 에이전트가 조치를 수행하는 실제 또는 가상 세계&lt;/li&gt;
      &lt;li&gt;동작 : 에이전트에 의한 조치로 환경의 상태가 변경&lt;/li&gt;
      &lt;li&gt;보상 : 긍적적이거나 부정적일 수 있는 행동의 평가 값&lt;/li&gt;
      &lt;li&gt;지도, 비지도는 정적이며 강화학습은 동적임&lt;/li&gt;
      &lt;li&gt;강화학습은 명백한 정답이 없음&lt;/li&gt;
      &lt;li&gt;실시간 탐색이 필요함&lt;/li&gt;
      &lt;li&gt;지도학습은 단일 결정 프로세스, 강화학습은 다중 결정 프로세스가 필요.&lt;/li&gt;
      &lt;li&gt;강화학습의 대표적인 기법 : 확률 기반 정책 그레이디언트, Q-러닝&lt;/li&gt;
      &lt;li&gt;마르코프 결정 프로세스(MDP) : 순차적으로 내려야 하는 문제를 정의할 때 사용.
        &lt;ul&gt;
          &lt;li&gt;Q(At) : 결정하는 프로세스의 각 상태&lt;/li&gt;
          &lt;li&gt;Q(At)의 값 : 보상이 높은 쪽으로 이동하는 정책&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;마르코프 체인 : 마르코프 성질을 지닌 이산 확률 과정&lt;/li&gt;
      &lt;li&gt;미르코프 모델 : 상태 =&amp;gt; 상태 전이 확률 =&amp;gt; 상태 전이도 순서&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Q-Learning : R-matrix를 이용. 그를 위해서는 각 이동 경로를 학습하기 위한 Q-matrix 만듬.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;10장&quot;&gt;10장&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;인공신경망 : 사람 뇌 신경세포를 복잡한 스위치들이 연결된 네트워크로 표현&lt;/li&gt;
  &lt;li&gt;단층 퍼셉트론 : Y = Activity Function(X * W + b)&lt;/li&gt;
  &lt;li&gt;W = 가중값, b = (편향 Bias)&lt;/li&gt;
  &lt;li&gt;단층 퍼셉트론의 경우 AND, OR이 가능하나, XOR이 안되어 인공지능 1차 겨울이 도래함&lt;/li&gt;
  &lt;li&gt;다층 퍼셉트론 : 중간에 은닉층을 추가해 XOR 문제 해결
    &lt;ul&gt;
      &lt;li&gt;S자모양의 시그모이드 사용&lt;/li&gt;
      &lt;li&gt;신경망 개념을 도입하면 가중값과 편향값을 자동으로 학습해 적절한 값 대입.&lt;/li&gt;
      &lt;li&gt;계단 함수 : 출력 값이 0과 1 나옴&lt;/li&gt;
      &lt;li&gt;시그모이드 : s자 모양의 곡선이 특징임&lt;/li&gt;
      &lt;li&gt;ReLu(렐루) 함수 : 0이하의 값은 무시하고 0을 넘으면 그대로 출력&lt;/li&gt;
      &lt;li&gt;가중값 조절 방법은 아래와 같다 - 경사 하강법 : 가중값 w가 기울기 방향으로 조금씩 이동. 오차가 작아질 때 까지 반복 -다층 신경망의 문제점 - 모든 노드마다 계산하기에 느림 - 그레디언트 소실(위 문제 참조) - 과대 적합(과도한 학습은 새로운 입력에 정확성이 떨어짐)&lt;/li&gt;
      &lt;li&gt;문제 해결법
        &lt;ul&gt;
          &lt;li&gt;역전파 알고리즘 : 오차의 기울기를 한 번만 미분하고, 그 결과를 뒤로 전파하면서 재사용&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;딥러닝(심층 신경망)
    &lt;ul&gt;
      &lt;li&gt;기존 신경망에서 은닉층과 출력층이 2개 이상으로 증가.&lt;/li&gt;
      &lt;li&gt;계산량이 지수적으로 증가했으나, 여러 가지 분류가 가능.&lt;/li&gt;
      &lt;li&gt;손실함수 : 신경망의 출력값이 기대하는 것 보다 얼마나 벗어났는지 측정하며 관찰 필요&lt;/li&gt;
      &lt;li&gt;훈련을 반복하며, 실험적 접근방식을 가지고 있음.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;12장-자연어-처리&quot;&gt;12장. 자연어 처리&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;자연어 : 인간이 일상생활에서 사용하는 언어(말, 글, 모국어)&lt;/li&gt;
  &lt;li&gt;자연어 처리(NLP) : 인간의 언어와 표현을 컴퓨터가 처리할 수 있도록 하는 계산 기법&lt;/li&gt;
  &lt;li&gt;자연어 처리가 어려운 이유 : 복잡성, 애매성, 종속성&lt;/li&gt;
  &lt;li&gt;자연어 처리의 분야(대표적인 것들만 추리자!)
    &lt;ul&gt;
      &lt;li&gt;정보 검색 : 많은 문서중 사용자가 원하는 문서를 빠르게 찾음.&lt;/li&gt;
      &lt;li&gt;정보 추출 : 비정형의 문서로부터 정규화된 정보를 뽑아내는 기술. 개체명 인식과 관계 추출로 나누어짐&lt;/li&gt;
      &lt;li&gt;음성 인식 : 컴퓨터가 인간의 음성 언어를 이해하게 하는 기술&lt;/li&gt;
      &lt;li&gt;단어 분류 : 문장 내 단어의 카테고리를 목적에 따라 컴퓨터가 자동으로 분류.&lt;/li&gt;
      &lt;li&gt;구문 분석 : 문장의 구조, 의존 구조 등 구조를 컴퓨터가 자동으로 인식&lt;/li&gt;
      &lt;li&gt;문장/문서 분류 : 한 문장/문서가 어떤 분류/카테고리에 속하는지 컴퓨터가 자동으로 분류&lt;/li&gt;
      &lt;li&gt;감정 분석 : 한 문장의 감정/의도를 분류&lt;/li&gt;
      &lt;li&gt;의미 결정 : 문장에서 주어, 목적어가 무엇인지, 그들의 의미적 관계가 어떤지 분류&lt;/li&gt;
      &lt;li&gt;자동 대화 시스템 : 우리가 아는 심심이라고 볼 수 있음.&lt;/li&gt;
      &lt;li&gt;기계 번역 : 한국어를 영어로 자동으로 바꾸는 것이 예시&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;앨런 튜링 : 사람의 언어를 기계가 이해할 수 있도록 최초로 도전하게 한 사람.
    &lt;ul&gt;
      &lt;li&gt;튜링 테스트를 제안했음.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;파이젠바움 : 엘리자라는 대화 시스템 구현&lt;/li&gt;
  &lt;li&gt;유진 구스트만 시스템이 튜링 테스트 첫 통과&lt;/li&gt;
  &lt;li&gt;자연어 처리 과정
    &lt;ul&gt;
      &lt;li&gt;자연어 전처리 : 긴 문자열을 분석을 위한 작은 단위(토큰)로 나눔
        &lt;ul&gt;
          &lt;li&gt;의미 있는 단위(단어, 문장, 형태소 등)으로 토큰을 정의&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;형태소 분석 : 최소 의미 단위인 형태소로 분석
        &lt;ul&gt;
          &lt;li&gt;어간 추출, 원형 복원, 품사 부착 작업을 시행&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;구문 분석 : 문장의 구문 구조는 트리 형태로 나타냄
        &lt;ul&gt;
          &lt;li&gt;파스 트리(Parse Tree) 형태로 개발&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;의미 분석&lt;/li&gt;
      &lt;li&gt;담화 분석 : 입력된 문장을 전체 문맥과 연결하면서 정확하게 그 의미를 분석&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;자연어 처리의 발전 방향
    &lt;ul&gt;
      &lt;li&gt;일반화 : 커버할 수 있는 문장 종류가 다양해야됨&lt;/li&gt;
      &lt;li&gt;구별성 : 올바른 문장과 비문장 구별&lt;/li&gt;
      &lt;li&gt;이해성 : 보기 쉬운 문법&lt;/li&gt;
      &lt;li&gt;자연어 전처리 =&amp;gt; 순환 신경망(RNN)으로 발전되고 있음.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;딥러닝을 이용한 자연어 처리
    &lt;ul&gt;
      &lt;li&gt;CNN(합성곱 신경망) : 이미지 인식, 정적인 분석&lt;/li&gt;
      &lt;li&gt;RNN(순환 신경망) : 동적인 언어 데이터 분석
        &lt;ul&gt;
          &lt;li&gt;RNN은 동적으로 분석가능하면 CNN의 단점을 개선했으나, 입력 정보가 뒤로 갈수록 사라진다는 문제점이 있음.
            &lt;ul&gt;
              &lt;li&gt;이를 해결하기 위해 LSTM 등장 : 입력 중 핵심적인 정보를 잊어버리지 않고 뒤로 전달해줌.&lt;/li&gt;
              &lt;li&gt;Seq2Sep 모델 : 인코더로 입력 문장을 먼저 처리, 디코더로 답변 문장을 출력&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;LSTM, Seq2Sep를 써도 답변의 정확도 부족 -이를 해결하기 위해 어텐션(Attention) 등장 : 길이가 긴 문장의 기억을 돕기 위해 만들어짐. 트랜스 포머 범용 딥러닝 모듈 아키텍처라고 한다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>Suhwan Kim</name><email>suhwan2004@gmail.com</email></author><category term="PTU" /><category term="인공지능(4학년-1학기)" /><summary type="html"></summary></entry><entry><title type="html">JS - callBack, Promise, async/await</title><link href="https://suhwan2004.github.io/frontend/Callback,Promise,AsyncAwait/" rel="alternate" type="text/html" title="JS - callBack, Promise, async/await" /><published>2022-06-06T00:00:00+00:00</published><updated>2022-06-06T00:00:00+00:00</updated><id>https://suhwan2004.github.io/frontend/Callback,Promise,AsyncAwait</id><content type="html" xml:base="https://suhwan2004.github.io/frontend/Callback,Promise,AsyncAwait/">&lt;h2 id=&quot;이-셋은-어디에-쓰나요&quot;&gt;이 셋은 어디에 쓰나요?&lt;/h2&gt;

&lt;p&gt;=&amp;gt; 보통, 비동기 프로그래밍을 구현하기 위해 사용된다.&lt;/p&gt;

&lt;p&gt;오늘은 비동기 프로그래밍을 위해 CallBack Function, Promise, async/await가 뭐고, 뭘 쓰면 되는지 간단하게 보자.
(Generator도 존재하는 것으로 알고 있으나 다 담지 못했다… 차후에 더 공부해볼 예정이다.)&lt;/p&gt;

&lt;p&gt;먼저 CallBack Function과 Promise를 비교해보자.&lt;/p&gt;

&lt;h2 id=&quot;promise-vs-callback-function&quot;&gt;Promise vs Callback function&lt;/h2&gt;

&lt;p&gt;CallBack 함수란?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;다른 함수의 전달인자(argument)로 넘겨주는 함수&lt;/strong&gt;를 말한다.&lt;/li&gt;
  &lt;li&gt;또한, CallBack 함수로 무조건 비동기 프로그래밍만 하는 건 아니다. &lt;strong&gt;콜백 함수를 써서 비동기 프로그래밍을 할 수도 있구나 라고 이해함이 옳다.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;아래는 CallBack 함수를 통한 간단한 비동기 프로그래밍의 구현이다.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;findUserAndCallBack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;user:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;findUserAndCallBack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;waited 0.1 sec.&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;@test.com&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;cb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;다만-callback을-썼을-때에는-promise-방식보다-단점이-여러-개-존재한다&quot;&gt;다만, Callback을 썼을 때에는 Promise 방식보다 단점이 여러 개 존재한다.&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;CallBack hell&lt;/strong&gt;
=&amp;gt; 간단한, 비동기 구현이면 상관이 없긴 한데, 계속 받은 결과값을 꼬리물기로 활용하면 지옥의 코드가 탄생한다. 아래와 같은 코드를 CallBack hell이라고 한다.
&lt;img src=&quot;https://user-images.githubusercontent.com/60723373/172058494-3132ba29-cee0-443f-8bbc-5241e07e147b.png&quot; alt=&quot;image&quot; /&gt;
(도망가고 싶다.)
ㅤ
ㅤ
ㅤ&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;에러 처리가 곤란하다는 것이다.&lt;/strong&gt;
예를 들어, 이런 코드가 있다고 해보자.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Error!&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;캐치된 에러&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;놀랍게도 catch 문이 실행되지 않는다!&lt;/p&gt;

&lt;p&gt;예외는 함수를 호출한 상위로 거슬러 전파된다. 지금, setTimeout 내부의 에러를 발생시키는 함수는 try-catch 안에서 단순히 정의된 상황이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;실제로 함수는 setTimeout에 의해서 실행된다. 그렇기에, try-catch 안에서 발생한 오류가 아니므로 예외를 감지할 수 없는 상황이 발생한 것이다.&lt;/strong&gt;
ㅤ
ㅤ
ㅤ
ㅤ
ㅤ
ㅤ&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;자 이제, 반대로 Promise를 보자.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Promise의 경우 성공했다는 &lt;strong&gt;fullfilled&lt;/strong&gt;, 실패했다는 &lt;strong&gt;rejected&lt;/strong&gt;, 진행중이라는 &lt;strong&gt;pending&lt;/strong&gt;이라는 3가지 상태가 존재한다.&lt;/p&gt;

&lt;p&gt;또한, then과 catch를 이 것들과 연계하여 비동기 처리를 구성하는데 성공하면 &lt;strong&gt;then을 통해 코드를 내려가면서 계속 값을 가져가기 때문에 복잡한 callback hell을 방지할 수 있다. 그리고 catch를 통해 에러 핸들링또한 가능&lt;/strong&gt;하다.&lt;/p&gt;

&lt;p&gt;아래의 코드는 두 가지를 담고 있는 코드이다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;기본적인 Promise 사용 코드&lt;/li&gt;
  &lt;li&gt;Promise.catch를 통한 에러처리 코드&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;condition&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//resolve는 성공했을 때 실행되는 함수이다.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//reject는 실패했을 때 실행되는 함수이다.&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;promise&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;reject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;resolved&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;reject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;rejected&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;promise&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;결론적으로는-callback의-단점을-해결한-promise가-더-좋다고-볼-수-있다&quot;&gt;결론적으로는, Callback의 단점을 해결한 Promise가 더 좋다고 볼 수 있다.&lt;/h3&gt;

&lt;p&gt;ㅤ
ㅤ
ㅤ
ㅤ
ㅤ
ㅤ&lt;/p&gt;

&lt;h2 id=&quot;asyncawait-vs-promise&quot;&gt;async/await vs promise&lt;/h2&gt;

&lt;p&gt;async/await의 경우 위의 두 방법의 단점을 어느정도 해소하고자 어느정도 최근에 나온 비동기 프로그래밍 문법이다.&lt;/p&gt;

&lt;p&gt;아래는, 자주쓰는 async/await로 구현한 request 코드이다.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;API_END_POINT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;https://~~~~&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;nodeId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;API_END_POINT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;nodeId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;nodeId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;서버의 상태가 이상합니다!&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`무언가 잘못 되었습니다! &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;둘의 차이는 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;에러 핸들링&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Promise&lt;/code&gt; 를 활용할 시에는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.catch()&lt;/code&gt; 문을 통해 에러 핸들링이 가능하지만, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async/await&lt;/code&gt; 은 에러 핸들링 할 수 있는 기능이 없어 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;try-catch()&lt;/code&gt; 문을 활용하는 모습을 위의 코드로 볼 수 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;코드 가독성&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Promise&lt;/code&gt;는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.then()&lt;/code&gt; 이 쭉 내려가는, “then 지옥”이 발생할 수도 있다.&lt;/li&gt;
      &lt;li&gt;코드가 길어지면 길어질수록, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async/await&lt;/code&gt; 를 활용한 코드가 가독성이 좋다.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async/await&lt;/code&gt; 은 비동기 코드가 동기 코드처럼 읽히게 해준다. 코드 흐름을 이해 하기 쉽다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;당장 위의 코드도, fetch를 통해 받은 데이터를 상수 res에 저장하고 동기 코드처럼 쭉 내려가면서 코드가 진행된다.&lt;/p&gt;

&lt;p&gt;이런 점들이 있다보니, 필자의 경우 비동기 코드를 짜야 할 때 async/await 방식을 통해 구현하고 있다.&lt;/p&gt;</content><author><name>Suhwan Kim</name><email>suhwan2004@gmail.com</email></author><category term="FrontEnd" /><category term="JavaScript" /><summary type="html">이 셋은 어디에 쓰나요?</summary></entry></feed>