<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Xxell.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Mon, 22 Nov 2021 01:48:28 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. Xxell.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/xxell-8" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[JS ⑤ Arrays & Objects]]></title>
            <link>https://velog.io/@xxell-8/JS-Arrays-Objects</link>
            <guid>https://velog.io/@xxell-8/JS-Arrays-Objects</guid>
            <pubDate>Mon, 22 Nov 2021 01:48:28 GMT</pubDate>
            <description><![CDATA[<h3 id="1-arrays">1. Arrays</h3>
<blockquote>
<p>키와 속성들을 담고 있는 참조 타입의 객체(object)</p>
<ul>
<li>순서 보장</li>
<li>0을 포함한 양의 정수 인덱스로 특정 값에 접근</li>
<li>배열의 길이는 <code>array.length</code>로 접근</li>
</ul>
</blockquote>
<h4 id="1-기본-배열-조작-method">1. 기본 배열 조작 Method</h4>
<table>
<thead>
<tr>
<th>Method</th>
<th>Description</th>
<th>etc.</th>
</tr>
</thead>
<tbody><tr>
<td>reverse</td>
<td>원본 배열의 요소들의 순서를 반대로 정렬</td>
<td></td>
</tr>
<tr>
<td>push &amp; pop</td>
<td>배열의 가장 뒤에 요소를 추가 또는 제거</td>
<td></td>
</tr>
<tr>
<td>unshift &amp; shift</td>
<td>배열의 가장 앞에 요소를 추가 또는 제거</td>
<td></td>
</tr>
<tr>
<td>includes</td>
<td>배열에 특정 값이 존재하는지 판별 후 참/거짓 반환</td>
<td></td>
</tr>
<tr>
<td>indexOf</td>
<td>배열에 특정 값이 존재하는지 판별 후 해당 인덱스 반환</td>
<td>없을 경우 -1 반환</td>
</tr>
<tr>
<td>join</td>
<td>배열의 모든 요소를 구분자를 매개로 연결</td>
<td>구분자 생략 시 쉼표 <code>,</code></td>
</tr>
</tbody></table>
<h4 id="2-array-helper-methods">2. Array Helper Methods</h4>
<ul>
<li>배열을 순회하며 특정 로직을 수행하는 메서드</li>
<li>메서드 호출 시 인자로 callback 함수를 받는 것이 특징<ul>
<li>callback 함수: 어떤 함수의 내부에서 실행될 목적으로 인자로 넘겨받는 함수</li>
</ul>
</li>
</ul>
<table>
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td>forEach</td>
<td>배열의 각 요소에 대해 콜백 함수를 한 번씩 실행 (반환 값 없음)</td>
</tr>
<tr>
<td>map</td>
<td>콜백 함수의 반환 값을 요소로 하는 새로운 배열 반환</td>
</tr>
<tr>
<td>filter</td>
<td>콜백 함수의 반환 값이 <code>true</code>인 요소들만 모아 새로운 배열 반환</td>
</tr>
<tr>
<td>reduce</td>
<td>콜백 함수의 반환 값들을 하나의 값(acc)에 누적 후 반환</td>
</tr>
<tr>
<td>find</td>
<td>콜백 함수의 반환 값이 <code>true</code>면 해당 요소를 반환</td>
</tr>
<tr>
<td>some</td>
<td>배열의 요소 중 하나라도 판별 함수를 통과하면 <code>true</code>를 반환</td>
</tr>
<tr>
<td>every</td>
<td>배열의 모든 요소가 판별 함수를 통과하면 <code>true</code>를 반환</td>
</tr>
</tbody></table>
<ul>
<li><p><code>array.forEach(callback(element[, index[, array]]))</code></p>
<ul>
<li>break, continue 사용 불가능</li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">const students = [&#39;Tim&#39;, &#39;Harry&#39;, &#39;Jackson&#39;, &#39;carol&#39;]

students.forEach((name, index) =&gt; {
  console.log(name, index)
})</code></pre>
<ul>
<li><p><code>array.map(callback(element[, index[, array]]))</code></p>
</li>
<li><p><code>array.filter(callback(element[, index[, array]]))</code></p>
</li>
</ul>
<pre><code class="language-javascript">const nums = [1, 2, 3, 4, 5]

const doulbleNums = nums.map((num) =&gt; {
  return num * 2
})

const oddNums = nums.filter((num) =&gt; {
  return num % 2
})

console.log(doulbleNums) // 👉 [2, 4, 6, 8, 10]
console.log(oddNums) // 👉 [1, 3, 5]</code></pre>
<ul>
<li><p><code>array.reduce(callback(acc, element, [index[, array]])[, initialValue])</code></p>
<ul>
<li><code>acc</code> : 이전 callback 함수의 반환 값이 누적되는 변수</li>
<li><code>initialValue</code> : callback 함수 최초 호출 시, acc에 할당되는 값<ul>
<li>설정하지 않으면 배열의 첫 번째 값으로 사용</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">const nums = [1, 2, 3, 4, 5]

const sumOfNums = nums.reduce((acc, num) =&gt; {
  return acc + num
}, 0)

console.log(sumOfNums) // 👉 15</code></pre>
<ul>
<li><p><code>array.find(callback(element[, index[, array]]))</code></p>
<ul>
<li>찾는 값이 배열에 없으면 <code>undefined</code> 반환</li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">const students = [
  { name: &#39;Tim&#39;, score: 87}, 
  { name: &#39;Harry&#39;, score: 92},
  { name: &#39;Jackson&#39;, score: 76},
  { name: &#39;Carol&#39;, score: 100},
]

const result = students.find((student) =&gt; {
  return student.score == 100
})

console.log(result) // 👉 { name: &#39;Carol&#39;, score: 100}</code></pre>
<ul>
<li><p><code>array.some(callback(element[, index[, array]]))</code></p>
<ul>
<li>빈 배열은 항상 <code>false</code></li>
</ul>
</li>
<li><p><code>array.every(callback(element[, index[, array]]))</code></p>
<ul>
<li>빈 배열은 항상 <code>true</code></li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">const nums = [1, 2, 3, 4, 5]

const hasOddNum = nums.some((num) =&gt; {
  return num % 2
})

const isEveryNumsOdd = nums.every((num) =&gt; {
  return num % 2
})</code></pre>
<h4 id="3-배열-순회-방식">3. 배열 순회 방식</h4>
<pre><code class="language-javascript">const animals = [&#39;Cat&#39;, &#39;Dog&#39;, &#39;Lion&#39;, &#39;Tiger&#39;, &#39;Snake&#39;, &#39;Bird&#39;]

// 1. for loop
for (let i = 0; i &lt; animals.length; i++) {
    console.log(i, animals[i])
}

// 2. for - of
for (animal of animals) {
    console.log(animal)
}

// 3. forEach
animals.forEach((animal, index) =&gt; {
    console.log(index, animal)
})</code></pre>
<h3 id="2-objects">2. Objects</h3>
<blockquote>
<p>속성의 집합으로, 중괄호 내부에 key-value 쌍으로 표현 </p>
<ul>
<li>key는 문자열 타입 (구분자가 있을 경우 따옴표로 묶어서 표현)</li>
<li>value는 모든 타입</li>
</ul>
</blockquote>
<h4 id="1-객체-생성-및-조작-문법">1. 객체 생성 및 조작 문법</h4>
<ol>
<li><p>속성명 축약</p>
<ul>
<li>객체 정의 시, key와 할당하는 변수 이름이 같으면 축약 가능</li>
</ul>
</li>
</ol>
<pre><code class="language-javascript">let fruits = [&#39;apple&#39;, &#39;orange&#39;, &#39;banana&#39;, &#39;lemon&#39;]
let vagetables = [&#39;mushroom&#39;]

const market = {
  fruits,
  vegetables,
}</code></pre>
<ol start="2">
<li><p>메서드명 축약</p>
<ul>
<li>메서드 선언시 function 키워드 생략 가능</li>
</ul>
</li>
</ol>
<pre><code class="language-javascript">const greeting = {
  hello() {
    console.log(&#39;Hello!&#39;)
  }
}</code></pre>
<ol start="3">
<li><p>계산된 속성 사용</p>
<ul>
<li>객체 정의 시 key 이름을 표현식을 통해 동적으로 생성 가능</li>
</ul>
</li>
</ol>
<pre><code class="language-javascript">const firstCat = &#39;pepper&#39;
const secondCat = &#39;kanda&#39;
const myCats = {
  [firstCat]: 5,    
  [secondCat.toUpperCase()]: 3,
}
console.log(myCats) // 👉 {pepper: 5, KANDA: 3}</code></pre>
<ol start="4">
<li><p>구조 분해 할당</p>
<ul>
<li><p>배열 또는 객체를 분해하여 속성을 변수에 쉽게 할당할 수 있는 문법</p>
<ul>
<li>key와 변수 명이 같을 경우 사용 가능</li>
</ul>
</li>
</ul>
</li>
</ol>
<pre><code class="language-javascript">const info = {
  name: &#39;Pepper&#39;,
  age: 5,
  color: &#39;Grey&#39;
}
const { name } = info
const { age, color } = info</code></pre>
<h2 id="3-json">3. JSON</h2>
<ul>
<li>JavaScript Object Notation</li>
<li>key-value 쌍 형태의 데이터를 표기하는 언어 독립적 표준 포맷</li>
<li>자바스크립트 객체(objects)와 유사하게 생겼으나, 실제로는 <strong>문자열 타입</strong><blockquote>
<ul>
<li>JSON을 조작하기 위한 두 가지 내장 메서드<ul>
<li><code>JSON.parse()</code> 👉 JSON &gt; 자바스크립트 객체</li>
<li><code>JSON.stringify()</code> 👉 자바스크입트 객체 &gt; JSON</li>
</ul>
</li>
</ul>
</blockquote>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JS ④ Function]]></title>
            <link>https://velog.io/@xxell-8/JS-Function</link>
            <guid>https://velog.io/@xxell-8/JS-Function</guid>
            <pubDate>Mon, 22 Nov 2021 01:41:42 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>자바스크립트 함수는 일급 객체(First-class citizens)로,<ul>
<li>변수에 할당이 가능하며</li>
<li>함수의 매개변수로 전달할 수 있고</li>
<li>함수의 반환 값으로 사용이 가능합니다.</li>
</ul>
</li>
</ul>
</blockquote>
<h3 id="1-함수-선언식">1. 함수 선언식</h3>
<ul>
<li>함수의 이름과 함께 정의하는 방식<ul>
<li>익명 함수 불가능, 호이스팅 O</li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">function name (args) {
  // do something 
}</code></pre>
<h3 id="2-함수-표현식">2. 함수 표현식</h3>
<ul>
<li>힘수를 표현식 내에서 정의하는 방식<ul>
<li>함수 이름을 생략하고 익명 함수로 정의 가능, 호이스팅 X</li>
<li>Airbnb Style Guide 권장 방식</li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">const myFunction = function (args) {
  // do something
}</code></pre>
<h4 id="cf-함수-선언식-vs-함수-표현식">cf. 함수 선언식 vs 함수 표현식</h4>
<ol>
<li>호이스팅<pre><code class="language-javascript">// 1. 함수 선언식 👉 호이스팅 O
</code></pre>
</li>
</ol>
<p>plus(2, 5) // → 7</p>
<p>function plus (num1, num2) {
  return num1 + num2
}</p>
<p>// 2. 함수 표현식 👉 호이스팅 X
minus(5, 2) // → Uncaught ReferenceError</p>
<p>const minus = function (num1, num2) {
  return num1 - num2
}</p>
<pre><code>


## 3. 화살표 함수 (Arrow Function)

- 함수를 비교적 간결하게 정의할 수 있는 문법

  1. function 키워드 생략 가능

  2. 함수의 **매개변수가 하나** 뿐이면 `()`도 생략 가능
  3. 함수 바디에 표현식 하나라면 `{}`과 `return` 생략 가능

```javascript
// 0. 함수 표현식
const greeting = function (name) {
  return `hello, ${name}`
}

// 1. function 생략
const greeting = (name) =&gt; { return `hello, ${name}` }

// 2. () 생략
const greeting = name =&gt; { return `hello, ${name}` }

// 3. {} &amp; return 생략
const greeting = name =&gt; `hello, ${name}`</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[JS ③ Conditions & Loops]]></title>
            <link>https://velog.io/@xxell-8/JS-Conditions-Loops</link>
            <guid>https://velog.io/@xxell-8/JS-Conditions-Loops</guid>
            <pubDate>Mon, 22 Nov 2021 01:36:12 GMT</pubDate>
            <description><![CDATA[<h3 id="1-conditions">1. Conditions</h3>
<h4 id="1-if-statement">1. if statement</h4>
<ul>
<li><p>조건 표현식의 결과값을 Boolean 타입으로 변환 후 참/거짓 판단</p>
<pre><code class="language-javascript">if (condition) {
    // do something
} else if (condition) {
    // do something
} else {
    // do something
}</code></pre>
</li>
</ul>
<h4 id="2-switch-statement">2. switch statement</h4>
<ul>
<li><p>조건 표현식의 결과 값이 어느 값(case)에 해당하는지 판별</p>
<ul>
<li>주로 특정 변수의 값에 따라 조건을 분기할 때 활용<ul>
<li>조건이 많아질 경우, if문보다 가독성이 나을 수 있음</li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">switch(expression) {
    case &#39;first value&#39;: {
      // do something
      break
    }
    case &#39;second value&#39;: {
      // do something
      break
    }
    default : {
      // do something
    }
}</code></pre>
<ul>
<li><code>break</code>, <code>default</code> 문은 선택적으로 사용 가능<ul>
<li>break문이 없는 경우,  break문을 만나거나 default문을 실행할 때까지 다음 조건문 실행</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="cf-if-vs-switch">cf. <code>if</code> vs <code>switch</code></h4>
<pre><code class="language-javascript">const numOne = 100
const numTwo = 7
let operator = &#39;+&#39;

// 1. if statement
if (operator == &#39;+&#39;) {
  console.log(numOne + numTwo)
} else if (operator == &#39;-&#39;) {
  console.log(numOne - numTwo)
} else if (operator == &#39;*&#39;) {
  console.log(numOne * numTwo)
} else if (operator == &#39;/&#39;) {
  console.log(numOne / numTwo)
} else {
  console.log(&#39;올바른 연산자를 입력해주세요.&#39;)
}

// 2. switch statement
switch(operator) {
  case &#39;+&#39;: {
    console.log(numOne + numTwo)
    break
  }
  case &#39;-&#39;: {
    console.log(numOne - numTwo)
    break
  }
  case &#39;*&#39;: {
    console.log(numOne * numTwo)
    break
  }
  case &#39;/&#39;: {
    console.log(numOne / numTwo)
    break
  }
  default: {
    console.log(&#39;올바른 연산자를 입력해주세요.&#39;)
  }
}</code></pre>
<h3 id="2-loops">2. Loops</h3>
<h4 id="1-while">1. while</h4>
<ul>
<li><p>조건문이 참인 동안 반복 시행</p>
<pre><code class="language-javascript">let num = 0

while (num &lt; 10) {
  console.log(num)
  num += 1
}</code></pre>
</li>
</ul>
<h4 id="2-for">2. for</h4>
<ul>
<li><p>세미콜론 <code>;</code> 으로 구분되는 세 부분으로 구성</p>
<ul>
<li><p>initialization : 최초 반복문 진입 시 1회만 실행</p>
</li>
<li><p>condition : 매 반복 시행 전 평가되는 부분</p>
</li>
<li><p>expression : 매 반복 시행 이후 평가되는 부분</p>
<pre><code class="language-javascript">for (initialization; condition; expression) {
  // do something
}</code></pre>
</li>
</ul>
<pre><code class="language-javascript">for (let num = 0; num &lt; 10; num++) {
  console.log(num)
}</code></pre>
</li>
</ul>
<h4 id="3-for---in">3. for - in</h4>
<ul>
<li><p>객체(object)의 속성들을 순회할 때 사용</p>
<ul>
<li>배열 순회도 가능하나 권장하지 않음</li>
</ul>
<pre><code class="language-javascript">const animals = {
    Pepper: &#39;tiger&#39;,
    Kanda: &#39;cat&#39;,
    Tony: &#39;dog&#39;
}

for (let animal in animals) {
    console.log(animal)
}</code></pre>
</li>
</ul>
<h4 id="4-for---of">4. for - of</h4>
<ul>
<li><p>반복 가능한(iterable) 객체를 순회하며 값을 꺼낼 때 사용</p>
<pre><code class="language-javascript">const animals = [&#39;Pepper&#39;, &#39;Kanda&#39;, &#39;Tony&#39;]

for (let animal of animals) {
    console.log(animal)
}</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JS ② 기본 데이터 타입과 연산자]]></title>
            <link>https://velog.io/@xxell-8/JS-%EA%B8%B0%EB%B3%B8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%EA%B3%BC-%EC%97%B0%EC%82%B0%EC%9E%90</link>
            <guid>https://velog.io/@xxell-8/JS-%EA%B8%B0%EB%B3%B8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%EA%B3%BC-%EC%97%B0%EC%82%B0%EC%9E%90</guid>
            <pubDate>Mon, 22 Nov 2021 01:19:31 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>자바스크립트의 모든 값은 특정한 데이터 타입을 가지는데, 크게 원시 타입(Primitive type)과 참조 타입(Reference type)으로 분류됩니다.</li>
</ul>
<ol>
<li><p>원시 타입</p>
<ul>
<li>Number, String, Boolean, undefined, null, Symbol</li>
</ul>
<ol start="2">
<li>참조 타입 👉 Objects<ul>
<li>객체(Objects) 타입의 자료형<ul>
<li>변수에 해당 객체의 참조 값이 담기고, 참조 값을 복사</li>
</ul>
</li>
<li>Array, Function, Object, ...</li>
</ul>
</li>
</ol>
</li>
</ol>
</blockquote>
<h2 id="1-primitive-type">1. Primitive Type</h2>
<blockquote>
<ul>
<li>객체(Objects)가 아닌 기본 타입</li>
<li>변수에 해당 타입의 값이 담기고, 실제 값을 복사</li>
</ul>
</blockquote>
<h4 id="1-number">1. Number</h4>
<ul>
<li>정수, 실수 구분이 없는 하나의 숫자 타입<ul>
<li>부동소수점 형식</li>
<li>cf. <code>NaN</code>(Not-A-Number)<ul>
<li>계산 불가능한 경우 반환되는 값</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="2-string">2. String</h4>
<ul>
<li>텍스트 데이터를 나타내는 타입<ul>
<li>16비트 유니코드 문자의 집합</li>
</ul>
</li>
<li>템플릿 리터럴 (Template Literal)<ul>
<li>backtick(`) 으로 표현</li>
<li>`${ expression } 형태로 표현식 삽입</li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">const name = &#39;Pepper&#39;
const age = 5
const introduce = `${name} is ${age} years old.`</code></pre>
<h4 id="3-undefined--null">3. undefined &amp; null</h4>
<table>
<thead>
<tr>
<th>undefined</th>
<th>null</th>
</tr>
</thead>
<tbody><tr>
<td>빈 값을 표현하기 위한 데이터 타입</td>
<td>빈 값을 표현하기 위한 데이터 타입</td>
</tr>
<tr>
<td>변수 선언 이후 직접 값을 할당하지 않으면 자동으로 <code>undefined</code>가 할당</td>
<td>개발자가 빈 값을 표현하기 위해 *<em>의도적으로 *</em>할당</td>
</tr>
<tr>
<td><code>typeof undefined</code> 결과 값은 <code>undefined</code></td>
<td><code>typeof null</code> 결과 값은 객체(<code>object</code>)</td>
</tr>
</tbody></table>
<h4 id="4-boolean">4. Boolean</h4>
<ul>
<li><p>논리적 참/거짓을 나타내는 타입</p>
<ul>
<li>true/false로 표현</li>
</ul>
</li>
<li><p>조건문 또는 반복문에서 유용하게 사용</p>
<ul>
<li><p>cf. 자동 형변환 규칙</p>
<table>
<thead>
<tr>
<th align="center">Data Type</th>
<th align="center">true</th>
<th align="center">false</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><code>undefined</code></td>
<td align="center">-</td>
<td align="center">항상 거짓</td>
</tr>
<tr>
<td align="center"><code>null</code></td>
<td align="center">-</td>
<td align="center">항상 거짓</td>
</tr>
<tr>
<td align="center">Number</td>
<td align="center">나머지 경우</td>
<td align="center">0, -0, NaN</td>
</tr>
<tr>
<td align="center">String</td>
<td align="center">나머지 경우</td>
<td align="center">빈 문자열</td>
</tr>
<tr>
<td align="center">Object</td>
<td align="center">항상 참</td>
<td align="center">-</td>
</tr>
</tbody></table>
</li>
</ul>
</li>
</ul>
<h2 id="2-연산자">2. 연산자</h2>
<h4 id="1-할당-연산자">1. 할당 연산자</h4>
<ul>
<li>다양한 연산에 대한 단축 연산자 지원<pre><code class="language-javascript">// 1. 기본 할당
let x = 0
</code></pre>
</li>
</ul>
<p>// 2. 사칙연산
x += 1
x -= 2
x *= 3
x /= 4</p>
<p>// 3. Increment &amp; Decrement 연산자
x++ // += 1 과 동일
x-- // -= 1 과 동일</p>
<p>```</p>
<h4 id="2-비교-연산자">2. 비교 연산자</h4>
<ul>
<li>피연산자(숫자, 문자, Boolean 등)를 비교하고 비교의 결과값을 Boolean으로 반환하는 연산자</li>
<li>문자열은 유니코드 값을 사용하며 표준 사전순서를 기반으로 비교<ul>
<li>알파벳끼리 비교할 경우<ul>
<li>알파벳 오름차순으로 우선순위를 지님</li>
<li>소문자가 대문자보다 우선순위를 지님</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="3-동등-비교-연산자-">3. 동등 비교 연산자 (<code>==</code>)</h4>
<ul>
<li>두 피연산자가 같은 값으로 평가되는지 비교 후 Boolean 값 반환<ul>
<li><strong>암묵적 타입 변환</strong>을 통해 타입을 일치시킨 후 같은 값인지 비교<ul>
<li>예상치 못한 결과가 발생할 수 있으므로 특별한 경우를 제외하고 사용하지 않음</li>
</ul>
</li>
<li>두 피연산자가 모두 객체일 경우, 메모리의 같은 객체를 바라보는지 판별</li>
</ul>
</li>
</ul>
<h4 id="4-일치-비교-연산자-">4. 일치 비교 연산자 (<code>===</code>)</h4>
<ul>
<li>두 피연산자가 ① 같은 타입인지 확인하고 ② 같은 값으로 평가되는지 비교 후 Boolean 값 반환<ul>
<li><strong>엄격한 비교</strong>가 이뤄지며 암묵적 타입 변환이 발생하지 않음</li>
<li>두 피연산자가 모두 객체일 경우, 메모리의 같은 객체를 바라보는지 판별</li>
</ul>
</li>
</ul>
<h4 id="5-논리-연산자">5. 논리 연산자</h4>
<ul>
<li>세 가지 논리 연산자로 구성<ul>
<li>and 연산은 <code>&amp;&amp;</code> 연산자</li>
<li>or 연산은 <code>||</code> 연산자</li>
<li>not 연산은 <code>!</code> 연산자</li>
</ul>
</li>
</ul>
<h4 id="6-삼항-연산자">6. 삼항 연산자</h4>
<ul>
<li><p>세 개의 피연산자를 사용하여 조건에 따라 값을 반환하는 연산자</p>
<ul>
<li><p><code>condition ? optionA : optionB</code></p>
<ul>
<li>조건식이 참이면 A 값을, 거짓이면 B 값을 사용</li>
</ul>
</li>
<li><p>삼항 연산자의 결과는 변수에 할당 가능</p>
</li>
<li><p>한 줄에 표기하는 것을 권장</p>
<pre><code class="language-javascript">console.log(true ? 1 : 2) // → 1
console.log(false ? 1 : 2) // → 2</code></pre>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JS ① Variable(변수)]]></title>
            <link>https://velog.io/@xxell-8/JS-Variable%EB%B3%80%EC%88%98</link>
            <guid>https://velog.io/@xxell-8/JS-Variable%EB%B3%80%EC%88%98</guid>
            <pubDate>Tue, 09 Nov 2021 00:34:35 GMT</pubDate>
            <description><![CDATA[<h3 id="1-식별자-identifier">1. 식별자 (Identifier)</h3>
<ul>
<li>변수를 구분할 수 있는 변수명</li>
<li>반드시 문자, <code>$</code>, <code>_</code>로 시작해야 하며, 클래스명 외에는 모두 소문자로 시작</li>
</ul>
<h4 id="🚩-식별자-작성-스타일">🚩 식별자 작성 스타일</h4>
<ol>
<li><p>카멜 케이스(<code>camelCase</code>, lower-camel-case)</p>
<ul>
<li>변수, 객체, 함수에 사용<pre><code class="language-javascript">// [example]
let variableName
const userInfo = { name: &#39;pepper&#39;, age: 5 }
function getUserName () {}</code></pre>
</li>
</ul>
</li>
<li><p>파스칼 케이스(<code>PascalCase</code>, upper-camel-case)</p>
<ul>
<li>클래스, 생성자에 사용<pre><code class="language-javascript">// [example]
class User {
  constructor(options) {
    this.name = options.name
  }
}
const person = new user({
  name: &#39;Pepper&#39;
})</code></pre>
</li>
</ul>
</li>
</ol>
<ol start="3">
<li><p>대문자 스네이크 케이스(<code>SNAKE_CASE</code>)</p>
<ul>
<li>상수(개발자의 의도와 상관없이 변경될 가능성이 없는 값)에 사용<pre><code class="language-javascript">// [example]
const API_KEY = &#39;adslhalf-wrljr21&#39;
const PI = Math.PI</code></pre>
</li>
</ul>
</li>
</ol>
<h3 id="2-변수-선언">2. 변수 선언</h3>
<blockquote>
<ul>
<li><p>JavaScript에서 변수를 선언하는 키워드는 크게 3가지로 볼 수 있습니다. ES6에서는 <code>const</code>와 <code>let</code> 예약어로 변수를 선언합니다.</p>
<table>
<thead>
<tr>
<th align="center">키워드</th>
<th align="center">재선언</th>
<th align="center">재할당</th>
<th align="center">스코프</th>
<th align="center">etc.</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><code>let</code></td>
<td align="center">X</td>
<td align="center">O</td>
<td align="center">블록</td>
<td align="center">ES6 도입</td>
</tr>
<tr>
<td align="center"><code>const</code></td>
<td align="center">X</td>
<td align="center">X</td>
<td align="center">블록</td>
<td align="center">ES6 도입</td>
</tr>
<tr>
<td align="center"><code>var</code></td>
<td align="center">O</td>
<td align="center">O</td>
<td align="center">함수</td>
<td align="center">-</td>
</tr>
</tbody></table>
</li>
</ul>
</blockquote>
<h4 id="1-기본-개념">1. 기본 개념</h4>
<ol>
<li>선언(Declaration)<ul>
<li>변수를 생성하는 행위 또는 시점</li>
</ul>
</li>
<li>할당(Assignment)<ul>
<li>선언된 변수에 값을 저장하는 행위 또는 시점</li>
</ul>
</li>
<li>초기화(Intialization)<ul>
<li>선언된 변수에 처음으로 값을 저장하는 행위 또는 시점</li>
</ul>
</li>
</ol>
<h4 id="2-변수-선언-키워드">2. 변수 선언 키워드</h4>
<table>
<thead>
<tr>
<th><code>let</code></th>
<th><code>const</code></th>
<th><code>var</code></th>
</tr>
</thead>
<tbody><tr>
<td>- 변수 재할당 가능<br />- 변수 재선언 불가능<br />- 블록 스코프</td>
<td>- 변수 재할당 불가능<br />- 변수 재선언 불가능<br />- 블록 스코프</td>
<td>- 변수 재할당 가능<br />- 변수 재선언 가능<br />- 함수 스코프</td>
</tr>
</tbody></table>
<ol>
<li><code>let</code></li>
</ol>
<ul>
<li><code>let</code> 예약어는 재할당이 가능하지만, 재선언은 불가능합니다.<pre><code class="language-javascript">// 재할당 가능
let number = 1
number = 2
console.log(number) // → 2
</code></pre>
</li>
</ul>
<p>// 재선언 불가능 (SyntaxError)
let number = 3 // → Uncaught SyntaxError: Identifier &#39;number&#39; has already been declared</p>
<pre><code>
2. `const`
- `let` 예약어는 재할당과 재선언 모두 불가능합니다.
```javascript
const number = 1
number = 2 // → Uncaught TypeError: Assignment to constant variable.</code></pre><ul>
<li>단, Object(<code>{}</code>)나 Array(<code>[]</code>) 선언 시, 객체의 속성과 배열의 요소는 변경할 수 있습니다.<pre><code class="language-javascript">// 1) 객체의 속성 변경
const user = {
name: &#39;Pepper&#39;,
age: 5
}
console.log(user.age) // → 5
</code></pre>
</li>
</ul>
<p>user.age = 6
console.log(user.age) // → 6</p>
<p>// 2) 배열 요소 추가
const animals = [&#39;cat&#39;]
animals.push(&#39;dog&#39;)
console.log(animals) // → [&#39;cat&#39;, &#39;dog&#39;]</p>
<pre><code>
3. `var`
- ES5의 `var` 예약어는 재할당, 재선언 모두 가능합니다.
- `const`, `let`과의 가장 큰 차이점은 유효범위입니다.
  - `var`의 유효 범위는 함수의 블록 단위로 제한되며, `const`와 `let`은 블록(`{}`) 단위로 제한됩니다. 
```javascript
// 블록 스코프: let, const
let name = &#39;Pepper&#39;
if (name === &#39;Pepper&#39;) {
  let name = &#39;Kanda&#39;
  console.log(&#39;블록 스코프:&#39;, name) // 블록 스코프: Kanda
}
console.log(&#39;전역 스코프:&#39;, name) // 전역 스코프: Pepper

const name = &#39;Pepper&#39;
if (name === &#39;Pepper&#39;) {
  const name = &#39;Kanda&#39;
  console.log(&#39;블록 스코프:&#39;, name) // 블록 스코프: Kanda
}
console.log(&#39;전역 스코프:&#39;, name) // 전역 스코프: Pepper

// 함수 스코프: var
var name = &#39;Pepper&#39;
if (name === &#39;Pepper&#39;) {
  var name = &#39;Kanda&#39;
  console.log(&#39;블록 스코프:&#39;, name) // 블록 스코프: Kanda
}
console.log(&#39;전역 스코프:&#39;, name) // 전역 스코프: Kanda</code></pre><ul>
<li><code>var</code>의 경우, <strong>호이스팅</strong>되는 특성으로 인해 예기치 못한 문제 발생 가능합니다.<ul>
<li>호이스팅은, 변수를 선언 이전에 참조할 수 있는 현상으로 선언 이전의 위치에서 접근 시 <code>undefined</code> 반환합니다.</li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">// let, const의 경우, 변수 선언 이전 접근 시 에러가 발생
console.log(age) // Uncaught ReferenceError: age is not defined
let age = 5

// var의 경우, 호이스팅 현상 발생
console.log(name) // undefined
var name = &#39;Pepper&#39;

// 선언 이전에 접근하면, 아래와 같은 방식으로 인식
var name // → 선언문이 위로 끌어올려지는 것!
console.log(name) // undefined
name = &#39;Pepper&#39;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] 이미지 Hover 효과]]></title>
            <link>https://velog.io/@xxell-8/CSS-%EC%9D%B4%EB%AF%B8%EC%A7%80-Hover</link>
            <guid>https://velog.io/@xxell-8/CSS-%EC%9D%B4%EB%AF%B8%EC%A7%80-Hover</guid>
            <pubDate>Sun, 07 Nov 2021 13:18:05 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>영화 포스터 이미지에 마우스 오버를 했을 때, 영화 정보를 표시할 수 있는 <code>hover</code> 기능을 사용해보겠습니다. <a href="https://jsfiddle.net/ccell/mdph2410/23/">Demo</a></p>
</blockquote>
<h4 id="html-파일-작성">HTML 파일 작성</h4>
<ul>
<li>img 태그에 포스터 이미지 경로를 입력하고</li>
<li>마우스 오버시, 표시할 내용을 <code>inner-content</code> class 안에 작성합니다.<pre><code class="language-html">&lt;div class=&quot;card&quot;&gt;
&lt;img
  src=&quot;https://image.tmdb.org/t/p/w300_and_h450_bestv2/5AFKp85Bka4mQeaeVNs3evyMYYE.jpg&quot; 
alt=&quot;포스터 이미지&quot;
&gt;
&lt;div class=&quot;inner-content&quot;&gt;
  &lt;span class=&quot;title&quot;&gt;라이프 오브 파이&lt;/span&gt;
  &lt;hr&gt;
  &lt;span class=&quot;overview&quot;&gt;
    인도에서 동물원을 운영하던 ‘파이’의 가족들은 정부의 지원이 끊기자 캐나다로 이민을 준비한다.
    동물들을 싣고 캐나다로 떠나는 배에 탑승한 가족들.
  &lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;</code></pre>
</li>
</ul>
<h4 id="css-효과-넣기">CSS 효과 넣기</h4>
<pre><code class="language-css">.card {
  position: relative;
  background: linear-gradient(180deg, #441DB2 0%, #0d0425 100%);
  width: 13rem;
  overflow: hidden;
  box-shadow: 15px 15px 25px black;
}
.card img {
  width: 100%;
  height: auto;
  /* 포스터 크기 조정을 위해 scale 조정 */
  transform: scale(1.1);
  transition: all 0.25s linear;
}
.card:hover img {
  opacity: 0.2;
  transform: scale(1.25);
}
.card .inner-content {
  width: 80%;
  opacity: 0;
  transform: translateX(-50%) translateY(-50%);
  position: absolute;
  top: 80%;
  left: 50%;
  transition: all 600ms ease;
  color: white;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.card:hover .inner-content {
  opacity: 1;
  top: 50%;
}
.card .inner-content .title {
  font-size: 1.2rem;
  font-weight: 700;
}
.card .inner-content .overview {
  font-size: 0.9rem;
  font-weight: 300;
}
.card .inner-content hr {
  border-top: 1px solid #f1f1f1;
  width: 100%;
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[CI/CD ② GitHub Actions로 Vue.js 자동 배포]]></title>
            <link>https://velog.io/@xxell-8/GitHub-Pages-%ED%99%9C%EC%9A%A9-GitHub-Actions%EB%A1%9C-Vue.js-%EC%9E%90%EB%8F%99-%EB%B0%B0%ED%8F%AC</link>
            <guid>https://velog.io/@xxell-8/GitHub-Pages-%ED%99%9C%EC%9A%A9-GitHub-Actions%EB%A1%9C-Vue.js-%EC%9E%90%EB%8F%99-%EB%B0%B0%ED%8F%AC</guid>
            <pubDate>Thu, 09 Sep 2021 01:56:50 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>GitHub Pages를 통한 정적 페이지 호스팅에서, 수동으로 진행하던 빌드와 배포를 자동화할 수 있습니다. 워크플로우를 구성하여 GitHub Actions를 통해 commit &amp; push만으로 배포할 수 있는 환경을 만들어보겠습니다.</p>
</blockquote>
<h3 id="1-기본-세팅">1. 기본 세팅</h3>
<ol>
<li><p>GitHub Repository 생성</p>
</li>
<li><p>패키지 매니저 설치</p>
</li>
</ol>
<ul>
<li>대표적으로 <code>npm</code>과 <code>yarn</code>이 있는데, 여기서는 <code>npm</code>을 기준으로 사용법을 정리해보겠습니다. 같은 방식으로 진행하며 npm 대신 yarn을 적용할 수 있습니다. </li>
</ul>
<ol start="3">
<li>Vue CLI 프로젝트 생성</li>
</ol>
<ul>
<li><p>배포할 Vue 프로젝트를 생성합니다.</p>
<ul>
<li>이번에는 프로젝트 생성 시, Default 설정이 아닌 직접 필요한 항목을 선택하는 방식을 사용해보겠습니다.
① <code>Manually select features</code>를 선택합니다.
<img src="https://images.velog.io/images/xxell-8/post/b91ab61a-e98b-4e7c-b116-41f351840f81/20210908_102651_1.png" alt="">
② 본인 프로젝트에 필요한 feature를 선택하면 됩니다. 자동 배포 과정에  <code>Test</code> 단계를 추가할 예정이기 때문에, <code>Unit Testing</code>를 추가로 선택해보겠습니다. 
<img src="https://images.velog.io/images/xxell-8/post/8ed7c546-ad3f-4ded-ac1b-704bf1e03137/20210908_102651_2.png" alt="">
③ 나머지 옵션도 아래와 같이 선택하여 프로젝트를 생성합니다.
<img src="https://images.velog.io/images/xxell-8/post/307f3560-6dbe-4d77-9f93-d4b8a29e3027/20210908_102651_7.png" alt=""></li>
</ul>
</li>
<li><p>프로젝트 생성이 끝나면, 프로젝트 디렉토리로 이동하여 <code>npm run serve</code> 혹은 <code>yarn serve</code>를 통해 Vue 페이지가 제대로 생성되었는지 확인합니다.</p>
</li>
</ul>
<ol start="4">
<li>리모트 저장소 연결</li>
</ol>
<ul>
<li>프로젝트와 생성한 Git Repository를 연결해 기본 Vue 프로젝트를 push합니다.</li>
</ul>
<h3 id="2-배포-관련-설정">2. 배포 관련 설정</h3>
<ol>
<li><code>gh-pages</code> 추가</li>
</ol>
<ul>
<li>자동 배포를 통해 배포된 페이지의 소스 코드를 <a href="https://www.npmjs.com/package/gh-pages">gh-pages</a>를 통해 관리할 수 있도록 관련 라이브러리를 추가합니다.<pre><code class="language-bash">npm install gh-pages --save-dev</code></pre>
</li>
</ul>
<ol start="2">
<li>package.json에 배포 관련 명령어 추가</li>
</ol>
<ul>
<li>npm의 패키지 관리 파일인 <code>package.json</code>에서 <code>scripts</code>라는 속성을 통해 사용자가 임의로 명령어의 이름과 동작을 정의해 사용할 수 있습니다.<blockquote>
<p>사용해야 하는 명령어가 길거나 반복적으로 사용해야 하는 경우, 아래와 같이 <code>커스텀 명령어</code>를 설정해 원하는 동작을 실행할 수 있습니다.</p>
</blockquote>
<pre><code class="language-js">// package.json
{
  ...
  &quot;scripts&quot;: {
      // npm run hello를 실행하면, 콘솔에 world가 출력됩니다
      &quot;hello&quot;: &quot;echo world&quot;
  }
}</code></pre>
</li>
<li>프로젝트 루트 디렉토리에 위치한 package.json을 열어 필요한 정보를 추가합니다.<pre><code class="language-json">{
&quot;name&quot;: &quot;vue-devops&quot;,
&quot;version&quot;: &quot;0.1.0&quot;,
&quot;private&quot;: true,
&quot;scripts&quot;: {
  &quot;serve&quot;: &quot;vue-cli-service serve&quot;,
  &quot;build&quot;: &quot;vue-cli-service build&quot;,
  &quot;test:unit&quot;: &quot;vue-cli-service test:unit&quot;,
  &quot;lint&quot;: &quot;vue-cli-service lint&quot;
  // 아래 부분을 추가합니다.
  &quot;predeploy&quot;: &quot;vue-cli-service build&quot;,
  &quot;deploy&quot;: &quot;gh-pages -d dist&quot;,
  &quot;clean&quot;: &quot;gh-pages-clean&quot;
},
...
}</code></pre>
</li>
</ul>
<ol start="3">
<li><code>vue.config.js</code> 설정</li>
</ol>
<ul>
<li>Vue 프로젝트의 루트 directory에 <code>vue.config.js</code>를 생성해 기본 설정 값을 넣어줍니다.</li>
<li><code>publicPath</code>는 배포된 페이지의 URL 설정입니다.<ul>
<li>GitHub Pages를 통한 기본 배포 URL은 <code>https://&lt;username&gt;.github.io/&lt;repository name&gt;/</code> 형태입니다.<ul>
<li><code>outputDir</code>은 기본 값인 <code>dist</code>를 사용합니다.<pre><code class="language-js">module.exports = {
publicPath: &#39;/&lt;repository name&gt;/&#39;,
outputDir: &#39;dist&#39; 
}</code></pre>
</li>
<li><a href="https://cli.vuejs.org/config/#vue-config-js">[참고자료] Vue CLI Configuration Reference</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="중간-점검-지금까지-작업이-잘-되었는지-확인해보겠습니다">[중간 점검] 지금까지 작업이 잘 되었는지 확인해보겠습니다.</h4>
<ul>
<li>터미널에 <code>npm run deploy</code> 명령을 입력하면 아래의 과정이 실행됩니다.<ul>
<li>Vue 프로젝트가 빌드되고 결과물에 <code>dist</code>에 저장됩니다.</li>
<li>연결된 리모트 저장소에 <code>gh-pages</code> 브랜치로 빌드된 정적 파일이 push 됩니다.</li>
</ul>
</li>
<li>Git Repository로 이동해 Vue 프로젝트가 잘 배포되었는지 확인해봅니다.</li>
</ul>
<h3 id="3-github-actions-활용">3. GitHub Actions 활용</h3>
<blockquote>
<p><code>GitHub Actions</code>는 GitHub의 SW 개발 workflow에서 작업을 자동화하기 위한 패키지 스크립트입니다.</p>
</blockquote>
<ul>
<li>새로운 소스 코드 Push 혹은 PR 이벤트 등에 반응하여 트리거하도록 구성할 수 있으며, 이를 통해 빠르고 안정적인 배포 및 운영이 가능한 DevOps 환경을 구축할 수 있습니다.</li>
<li>Github Action Core 개념을 살펴보겠습니다.</li>
</ul>
<ol>
<li><p>Workflow</p>
<ul>
<li>여러 Job으로 구성되고 Event에 의해 트리거될 수 있는 자동화된 프로세스입니다. <ul>
<li>Workflow 파일은 YAML로 작성하며, 해당 Github Repo 내 <code>.github/workflows</code> 폴더에 저장됩니다.</li>
</ul>
</li>
</ul>
</li>
<li><p>Event</p>
<ul>
<li>Workflow를 트리거하는 특정 활동이나 규칙으로,<ul>
<li>특정 브랜치로 Push, PR 등의 상황에 사용할 수 있습니다.<pre><code class="language-yaml"># Workflow가 실행되어야 하는 이벤트를 지정합니다.
on:
  # 1. master 브랜치로 push될 경우
  push:
    branches: [ master ]
  # 2. master 브랜치로 PR가 발생할 경우
  pull_request:
    branches: [ master ]</code></pre>
</li>
</ul>
</li>
</ul>
</li>
<li><p>Job</p>
<ul>
<li>Job은 여러 개의 Step으로 구성되며, 가상 환경의 인스턴스에서 실행됩니다.<ul>
<li>다른 Job에 의존 관계를 가지거나 독립적으로 병렬 실행도 가능합니다.</li>
</ul>
</li>
</ul>
</li>
<li><p>Step</p>
<ul>
<li>Task들의 집합으로 action을 실행합니다.</li>
</ul>
</li>
<li><p>Action</p>
<ul>
<li>Workflow의 가장 작은 블럭으로, <ul>
<li>개인적으로 만든 Action을 사용하거나 <a href="https://github.com/marketplace?type=actions">Github Marketplace</a>를 통해 공용 Action을 사용할 수 있습니다.</li>
</ul>
</li>
<li><code>uses</code>는 각 step에 사용할 액션을 지정</li>
<li><code>run</code>은 시스템의 shell에 명령어를 실행</li>
</ul>
</li>
<li><p><code>workflow</code> 파일 생성
① GitHub Repository의 <code>Actions</code> 탭에 들어가 workflow 설정을 클릭합니다. 
<img src="https://images.velog.io/images/xxell-8/post/05b977b6-9bdb-4a03-9eb9-74bb590ac803/20210909_095605.png" alt="">
② 기본적으로 제공되는 workflow 파일의 이름을 확인하고 (목적에 맞게 수정한 뒤) commit을 남깁니다.
<img src="https://images.velog.io/images/xxell-8/post/3e35402c-c29e-44f8-9f73-b20343fb0a68/20210909_095817.png" alt=""></p>
</li>
<li><p><code>workflow</code> 파일 작성
① 로컬 Directory에서 workflow 파일을 pull 받습니다.
② <code>main</code> 브랜치에 push/PR 이벤트가 발생했을 때, 수행할 작업을 작성해보겠습니다.</p>
<pre><code class="language-yaml">jobs:
# job의 이름 설정
deploy:
   # 해당 job을 실행하는 운영 체제
 runs-on: ubuntu-latest

 # 수행할 동작 정의
 steps:
   # 1. 저장소 체크아웃
   - name: Checkout source code
     uses: actions/checkout@main

   # 2. node.js 환경설정
   - name: Set up Node.js
     uses: actions/setup-node@main
     with:
       node-version: 14.x

   # 3. 패키지 설치
   - name: Install dependencies
     run: npm install

   # 4. 테스트
   - name: Test unit
     run: npm run test:unit

   # 5. 빌드
   - name: Build Page
     run: npm run build
     env:
       NODE_ENV: production

   # 6. gh-pages로 배포
   - name: Deploy to gh-pages
     uses: peaceiris/actions-gh-pages@v3
     with:
       github_token: ${{ secrets.GITHUB_TOKEN }}
       publish_dir: ./dist</code></pre>
<ul>
<li>[참고] 활용한 공용 Action<ul>
<li><a href="https://github.com/marketplace/actions/checkout">checkout</a></li>
<li><a href="https://github.com/marketplace/actions/setup-node-js-environment">setup-node</a></li>
<li><a href="https://github.com/peaceiris/actions-gh-pages">actions-gh-pages</a></li>
</ul>
</li>
</ul>
</li>
</ol>
<h4 id="최종-확인-commit-push-만으로-자동-배포가-잘-동작하는지-확인해봅시다">[최종 확인] Commit-push 만으로 자동 배포가 잘 동작하는지 확인해봅시다!</h4>
<ol>
<li>간단한 확인을 위해 기본 Vue 프로젝트의 <code>Home.vue</code> 문구를 수정해보겠습니다.
<img src="https://images.velog.io/images/xxell-8/post/4ede9c01-2eb1-4ded-8bb5-be5cf717e80a/20210909_104335.png" alt=""></li>
<li>프로젝트를 commit-push하면 <code>Actions</code>를 통해 workflow가 진행됩니다.
<img src="https://images.velog.io/images/xxell-8/post/51a934c4-8687-4483-a3fb-d03686ea078c/20210909_105316.png" alt=""></li>
<li>workflow가 완료되면 GitHub Pages에 배포된 페이지를 확인할 수 있는데, 아래와 같이 수정한 부분이 반영된 모습을 볼 수 있습니다.
<img src="https://images.velog.io/images/xxell-8/post/695f11dd-a5cc-45c7-9906-4ee0fa0893ec/20210909_104807.png" alt=""></li>
</ol>
<h4 id="이제-vue-프로젝트를-git-repository에-commit-push-만으로-배포할-수-있게-되었습니다-😁">이제 Vue 프로젝트를 Git Repository에 commit-push 만으로 배포할 수 있게 되었습니다! 😁</h4>
]]></description>
        </item>
        <item>
            <title><![CDATA[CI/CD ① GitHub Pages를 활용한 Vue.js 수동 배포 (docs 폴더 ver.)]]></title>
            <link>https://velog.io/@xxell-8/GitHub-Pages%EB%A5%BC-%ED%86%B5%ED%95%9C-%EB%B0%B0%ED%8F%AC-docs-%ED%8F%B4%EB%8D%94%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-Vue.js-%EC%88%98%EB%8F%99-%EB%B0%B0%ED%8F%AC</link>
            <guid>https://velog.io/@xxell-8/GitHub-Pages%EB%A5%BC-%ED%86%B5%ED%95%9C-%EB%B0%B0%ED%8F%AC-docs-%ED%8F%B4%EB%8D%94%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-Vue.js-%EC%88%98%EB%8F%99-%EB%B0%B0%ED%8F%AC</guid>
            <pubDate>Tue, 07 Sep 2021 03:22:46 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>Vue CLI를 통해 생성한 프로젝트를 Github Pages로 배포하는 방법은 여러 가지가 있습니다. 그 중 <code>docs</code> 폴더를 활용한 수동 배포 방법을 정리해봅시다!</p>
</blockquote>
<h3 id="1-기본-세팅">1. 기본 세팅</h3>
<ol>
<li>GitHub Repository 생성</li>
</ol>
<ul>
<li>GitHub Pages는 정적 페이지를 호스팅합니다. 이때, 정적 파일을 저장할 리모트 저장소가 필요하며, 새 Repository를 생성하고 목적에 맞게 이름을 설정합니다.</li>
</ul>
<ol start="2">
<li>Vue CLI 프로젝트 생성</li>
</ol>
<ul>
<li>배포할 Vue 프로젝트를 생성합니다.</li>
<li>GitHub에 생성한 Repository와 로컬 상의 프로젝트의 연결이 필요합니다. <ul>
<li>연결 방법은 ① 로컬에서 프로젝트를 생성해 <code>git remote</code>를 활용하거나 ② 생성된 repository를 <code>git clone</code>한 뒤, 프로젝트를 생성하는 방법이 있습니다. (+ 자세한 내용은 <a href="https://velog.io/@xxell-8/Git-%EB%A1%9C%EC%BB%AC-%EC%A0%80%EC%9E%A5%EC%86%8C-%ED%99%9C%EC%9A%A9">Git 로컬 저장소 활용</a>과 <a href="https://velog.io/@xxell-8/Git-%EC%9B%90%EA%B2%A9-%EC%A0%80%EC%9E%A5%EC%86%8C-%ED%99%9C%EC%9A%A9">Git 원격 저장소 활용</a>에 있습니다!)</li>
</ul>
</li>
</ul>
<h3 id="2-배포-관련-설정">2. 배포 관련 설정</h3>
<ol>
<li>Vue 프로젝트 기본 설정</li>
</ol>
<ul>
<li>Vue 프로젝트의 루트 directory에 <code>vue.config.js</code>를 생성해 기본 설정 값을 넣어줍니다.<ul>
<li><code>outputDir</code>은 빌드한 파일을 저장하는 경로이며, <code>docs</code> 폴더로 지정합니다.</li>
<li><code>publicPath</code>는 배포된 페이지의 URL 설정입니다.<ul>
<li>GitHub Pages를 통한 기본 배포 URL은 <code>https://&lt;username&gt;.github.io/&lt;repository name&gt;/</code> 형태입니다.<pre><code class="language-js">module.exports = {
outputDir: &#39;./docs&#39;,
publicPath: &#39;/&lt;repository name&gt;/&#39;
}</code></pre>
</li>
</ul>
</li>
<li><a href="https://cli.vuejs.org/config/#vue-config-js">[참고자료] Vue CLI Configuration Reference</a></li>
</ul>
</li>
</ul>
<ol start="2">
<li>GitHub Repo 설정</li>
</ol>
<ul>
<li>해당 Repository의 Settings-Pages로 들어갑니다.<ul>
<li>소스를 설정할 수 있는 화면이 나오는데, 아래와 같이 main(혹은 master) 브랜치의 docs 폴더를 선택해줍니다.
<img src="https://images.velog.io/images/xxell-8/post/f4c62246-c20e-4e98-ab2d-ee2ae4c8f7dd/gitpub%20pages.png" alt="github 설정"></li>
</ul>
</li>
</ul>
<h3 id="3-실행">3. 실행</h3>
<ol>
<li>프로젝트 내부에 <code>docs</code> 폴더를 생성합니다.</li>
</ol>
<ul>
<li>기본적으로 Vue 프로젝트를 build하면 <code>/dist</code>에 빌드 파일이 저장되는데, 앞서 <code>vue.config.js</code> 설정을 통해 빌드 결과물이 <code>/docs</code>에 저장됩니다.</li>
</ul>
<p><img src="https://images.velog.io/images/xxell-8/post/c76e86b5-375a-4d70-8314-679fc43173c3/gitpubdir.png" alt="파일 구조">
2. 터미널에서 <code>npm run build</code> 명령을 통해 프로젝트를 빌드합니다.</p>
<ol start="3">
<li>Vue 프로젝트를 리모트 저장소에 푸시해봅시다!<pre><code>git add .
git commit -m &#39;&lt;commit msg&gt;&#39;
git push -u origin main</code></pre></li>
</ol>
<h4 id="이제-httpsusernamegithubiorepository-name로-접속해-vue-프로젝트가-배포된-것을-확인할-수-있습니다">이제, <code>https://&lt;username&gt;.github.io/&lt;repository name&gt;/</code>로 접속해 Vue 프로젝트가 배포된 것을 확인할 수 있습니다.</h4>
<ul>
<li>Vue.js를 활용해 개발을 진행하고, build-push를 통해 github page를 만들면 됩니다!</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Network ① OSI 7 Layers]]></title>
            <link>https://velog.io/@xxell-8/OSI-7-Layers</link>
            <guid>https://velog.io/@xxell-8/OSI-7-Layers</guid>
            <pubDate>Mon, 06 Sep 2021 02:14:18 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li><p>OSI(Open Systems Interconnection Reference Model)는 다양한 통신 시스템이 표준 프로토콜을 사용하여 통신할 수 있도록 국제표준화기구(ISO)에서 만든 개념적 모델입니다. </p>
</li>
<li><p>컴퓨터 네트워크 프로토콜 디자인과 통신을 계층으로 나눠 설명합니다.</p>
</li>
</ul>
<p>  <img src="https://s7280.pcdn.co/wp-content/uploads/2018/06/osi-model-7-layers-1.png" alt="img"></p>
<p>  <a href="https://www.bmc.com/blogs/osi-model-7-layers/">OSI Model: The 7 Layers of Network Architecture – BMC Blogs</a></p>
</blockquote>
<h4 id="1-물리-계층physical-layer">1. 물리 계층(Physical layer)</h4>
<ul>
<li>물리 계층에서는 주로 전기적·기계적 특성을 이용해 통신 테이블로 <strong>데이터를 송·수신</strong>합니다.</li>
<li>통신 단위는 <strong>Bit</strong>이며, <strong>데이터를 주고 받기 위해 전기 신호(아날로그 신호)를 사용</strong>합니다.<ul>
<li>0과 1의 나열을 아날로그 신호로 바꾸어 전선으로 흘려 보내고, (encoding)</li>
<li>아날로그 신호가 들어오면 0과 1의 나열로 해석하여 (decoding)</li>
<li>물리적으로 연결된 두 대의 컴퓨터가 0과 1의 나열을 주고 받을 수 있게 해줍니다.</li>
</ul>
</li>
<li>단, 물리계층에서는 <strong>데이터를 전달할 뿐</strong> 데이터의 내용이나 오류 등에는 관여하지 않습니다.</li>
</ul>
<h4 id="2-데이터-링크-계층data-link-layer">2. 데이터 링크 계층(Data link layer)</h4>
<blockquote>
<p>프레임 구성, 물리 주소 지정(MAC 주소), 흐름 제어, 오류 제어</p>
</blockquote>
<ul>
<li><p>데이터 링크 계층은 <strong>동일한 네트워크</strong>에 있는 기기 간의 전송을 촉진하며, Point to Point 간 신뢰성 있는 전송을 보장하기 위한 계층입니다.</p>
<ul>
<li>발생 가능한 오류를 찾아내고 수정하는데 필요한 기능적·절차적 수단을 제공하는 <strong>오류 제어</strong> 기능과</li>
<li>송·수신 측 간의 속도 차이를 해결해 버퍼에 걸리지 않도록 하는 <strong>흐름 제어</strong> 기능을 수행합니다.</li>
</ul>
</li>
<li><p>데이터 링크 계층에서는 <strong>MAC 주소(Media Access Control Address)를 통해 통신</strong>하는데,</p>
<ul>
<li>이는 상호 통신을 위해 네트워크 카드마다 물리적으로 할당받는 주소값입니다.</li>
</ul>
</li>
<li><p>이 계층에서의 데이터 전송 단위는 <strong>Frame</strong>이며, </p>
<ul>
<li>여기에 Header와 Trailer를 추가하는데,<ul>
<li>Header에는 출발지와 목적지의 MAC 주소, 데이터 내용을 정의하며</li>
<li>Trailer에서는 비트 에러를 감지합니다.</li>
</ul>
</li>
</ul>
</li>
<li><p>cf. 데이터 링크 계층은 두 개의 하위 계층(논리적 링크 제어(LLC) , 매체 접근 제어(MAC))으로 나뉩니다.</p>
</li>
</ul>
<h4 id="3-네트워크-계층network-layer">3. 네트워크 계층(Network layer)</h4>
<blockquote>
<p>패킷 전달, 논리 주소 지정(IP), 라우팅</p>
</blockquote>
<ul>
<li>네트워크 계층은 <strong>서로 다른 네트워크</strong> 간의 데이터 전송을 촉진하며, 데이터를 목적지까지 가장 안전하고 빠르게 전달하기 위한 계층입니다.<ul>
<li>네트워크 특성, 경로, 서비스 우선 순위 등 다양한 요소를 기반으로 최적의 물리 경로를 찾아 <strong>라우팅(routing)</strong>하며,<ul>
<li>여러 개의 노드를 거칠 때마다 경로를 찾아주는 역할입니다.</li>
</ul>
</li>
<li>추가로 흐름 제어, 세그멘테이션(segmentation/desegmentation), 오류 제어, 인터네트워킹(Internetworking) 등을 수행합니다.</li>
</ul>
</li>
<li>이 계층은 논리적 주소를 담당하고 패킷(Packet)의 전달 경로를 결정하는데,<ul>
<li><strong>논리적인 주소 구조(IP)</strong>, 곧 네트워크 관리자가 직접 주소를 할당하는 구조를 가지며, </li>
<li>상위 계층에서 받은 데이터에 목적지 호스트의 논리 주소를 Header에 추가하여 전송합니다.</li>
</ul>
</li>
<li>즉, 수많은 네트워크들의 연결로 이루어지는 Internetwork 속에서 목적지 컴퓨터로 데이터를 전송하기 위해 <strong>IP 주소를 이용해 라우팅</strong>하고, 다음 라우터로 <strong>패킷을 전달</strong>하는(forwarding) 계층입니다.</li>
</ul>
<h4 id="4-전송-계층transport-layer">4. 전송 계층(Transport layer)</h4>
<blockquote>
<p>세그먼트 분할·조립, 서비스 지점 주소 지정(Port), 연결 제어, 흐름 제어, 오류 제어</p>
</blockquote>
<ul>
<li><p>전송 계층은 <strong>양 끝단(End to end)의 사용자</strong>들이 신뢰성있는 데이터를 주고 받을 수 있도록 하는 계층으로, 상위 계층에서 데이터 전달의 유효성이나 효율성을 생각하지 않도록 합니다.</p>
<ul>
<li>오류 제어, 흐름 제어 및 정체 제어와 같은 메커니즘을 제공하여 데이터 패킷을 추적하고, 오류와 중복을 확인하고, 전송에 실패한 정보를 재전송합니다.</li>
<li>데이터 전송 단위는 <strong>Segment</strong>이며, <ul>
<li>송신 시, 데이터 분할을 통해 각 세그먼트에 시퀀스 넘버를 부여하고</li>
<li>수신 시, 시퀀스 넘버에 따라 재조립하여 데이터의 무결성과 정확성을 검사합니다.</li>
</ul>
</li>
</ul>
</li>
<li><p>이 계층에서는 <strong>서비스 지점 주소를 지정</strong>하는데,</p>
<ul>
<li>하나의 컴퓨터에서 동시에 실행되고 있는 프로세스들을 구분할 수 있는 주소값, <strong>포트 번호</strong>를 사용하여 </li>
<li>도착지 컴퓨터의 특정 프로세스에 응답하여 데이터가 전송되도록 보장합니다.</li>
</ul>
</li>
<li><p>전송 프로토콜의 대표적인 예로는 <strong>TCP</strong>와 <strong>UDP</strong>가 있습니다.</p>
<ul>
<li>TCP(Transmission Control Protocol)는 연결형 프로토콜로, 신뢰성이 요구되는 App에서 사용합니다.<ul>
<li>송신측과 수신측의 연결을 확인한 후 데이터를 전송하며, </li>
<li>수신자 응답을 받아 필요한 경우, 데이터를 재전송할 수 있습니다.</li>
</ul>
</li>
<li>UDP(User Datagram Protocol)는 비연결형 프로토콜로, 간단한 데이터를 빠른 속도로 전송하는 App에서 사용합니다.<ul>
<li>송신측과 수신측의 연결을 거치지 않고 일방적으로 데이터를 전송하며,</li>
<li>수신측으로부터 응답을 따로 받지 않습니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="5-세션-계층session-layer">5. 세션 계층(Session layer)</h4>
<blockquote>
<p>대화 제어, 체크포인트 동기화</p>
</blockquote>
<ul>
<li>세션 계층은 서버 간의 <strong>세션을 관리</strong>하여 데이터 <strong>통신을 조정</strong>하는 계층입니다. <ul>
<li>세션은 프로세서들이 서로를 인식하고 데이터 송수신을 마칠 때까지의 시간을 의미하며,<ul>
<li>이 계층은 모든 데이터를 전송할 수 있도록 세션을 개방한 후 리소스를 낭비하지 않기 위해 세션을 즉시 닫을 수 있도록 합니다.</li>
</ul>
</li>
<li>프로세스 간의 상호 작용이나 <strong>대화 관리</strong>를 위해 전이중 방식(Full Duplex), 반이중 방식(half-duplex) 등을 사용합니다.<ul>
<li>전이중 방식은 하나의 연결을 통해 데이터가 동시에 양방향으로 오고 갈 수 있는 방식이며,</li>
<li>반이중 방식은 데이터 토큰을 사용해 데이터 전달 권한을 확인하며, 전달에 대한 응답이 도착한 후 다른 전달을 수행하는 방식입니다.</li>
</ul>
</li>
<li>데이터 전송을 <strong>체크 포인트와 동기화</strong>하는데,<ul>
<li>데이터 전송 시, 체크 포인트를 설정하여 전송 도중 연결이 끊어지거나 충돌이 발생하면 마지막 체크 포인트에서 세션을 재개합니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="6-표현-계층presentation-layer">6. 표현 계층(Presentation layer)</h4>
<blockquote>
<p>데이터 변환·암호화·압축</p>
</blockquote>
<ul>
<li><p>표현 계층은 서로 다른 데이터 표현 방식을 사용하는 응용 프로세스가 잘 통신할 수 있도록 <strong>데이터 형식과 표현</strong>을 다루는 계층입니다.</p>
<ul>
<li>서로 다른 환경의 시스템에서 전송된 데이터를 서로 이해할 수 있도록 돕는데,<ul>
<li>송신 측과 수신 측 사이의 <strong>서로 다른 부호 체계 간 변환과 표준화된 데이터 형식을 규정</strong>을 통해</li>
<li>데이터 구조를 하나의 통일된 형식으로 표현하여 응용계층의 데이터 형식 차이로 인한 부담을 덜어줍니다.</li>
</ul>
</li>
<li>즉, 각 컴퓨터에서 사용하는 데이터 표현 규칙(추상 문법)을 네트워크 전체에서 일관성을 지니는 표현 규칙(전송 문법)으로 변환하여 데이터를 전송함으로써, 양단의 프로세스가 데이터를 이해하고 해석할 수 있도록 하는 것입니다.</li>
<li><strong>데이터 압축</strong>을 통해 전송 데이터의 양을 최소화함으로써 통신의 속도와 효율을 높이는 기능과 <strong>암호화</strong> 등의 동작을 수행합니다.</li>
</ul>
</li>
</ul>
<h4 id="7-응용-계층application-layer">7. 응용 계층(Application layer)</h4>
<ul>
<li>응용 계층은 응용 프로세스와 직접 관계하여 일반적인 응용 서비스를 수행하는 계층입니다.<ul>
<li>응용 계층은 소프트웨어가 사용자에게 의미 있는 데이터를 제공하기 위해 의존하는 프로토콜과 데이터를 조작하는 역할을 합니다.<ul>
<li>사용자의 데이터와 직접 상호작용하며, 웹 브라우저 및 이메일 클라이언트와 같은 소프트웨어 애플리케이션이 통신을 돕는데,<ul>
<li>여기서, 클라이언트 소프트웨어 애플리케이션은 응용 계층의 일부가 아니라는 점을 명확히 해야 합니다.</li>
</ul>
</li>
</ul>
</li>
<li>응용 계층의 프로토콜에는 HTTP, SMTP(이메일 통신을 위한 프로토콜) 등이 있습니다.</li>
</ul>
</li>
</ul>
<h4 id="💡-about-osi-7-layers">💡 About OSI 7 Layers</h4>
<ul>
<li><p>OSI 모델은 통신이 일어나는 과정을 단계별로 파악하기 위해 계층을 나눴으며,</p>
<ul>
<li>특정한 곳에 이상이 생길 경우, 해당 단계의 하드웨어나 소프트웨어를 고쳐 문제를 해결할 수 있습니다.</li>
</ul>
</li>
<li><p>그러나 특유의 구현 복잡성으로 인해 발생하는 비효율적인 네트워크 운영으로</p>
<ul>
<li>현대 인터넷은 OSI 모델이 아닌 TCP/IP 모델을 따르고 있습니다. </li>
</ul>
</li>
</ul>
<p>🚩 추가 개념</p>
<ul>
<li><p>Encapsulation &amp; Decapsulation</p>
<table>
<thead>
<tr>
<th>Encapsulation (캡슐화)</th>
<th>Decapsulation (디캡슐화)</th>
</tr>
</thead>
<tbody><tr>
<td>상위 계층에서 하위 계층으로 데이터가 이동하며, 헤더에 각 계층의 기능이 합쳐지는 방식</td>
<td>하위 계층에서 상위 계층으로 데이터가 이동하며, 각 계층에서 요구되는 헤더 정보가 제거되는 방식</td>
</tr>
<tr>
<td>데이터 송신</td>
<td>데이터 수신</td>
</tr>
</tbody></table>
</li>
<li><p>Protocol (프로토콜)</p>
<ul>
<li>컴퓨터 내부 또는 서로 다른 기기들 간의 데이터 교환을 위해 표준화한 통신 규약입니다.</li>
<li>프로토콜의 기능에는 흐름제어, 오류제어, 순서제어 등이 있습니다.<ul>
<li>흐름제어는 수신 측에서 송신 측이 송신하는 데이터의 전송량이나 전송 속도를 조절하는 기능입니다.</li>
<li>오류제어는 전송 중에 발생하는 오류를 검출하고 정정하여 정보의 파손에 대비하는 기능입니다.</li>
<li>순서제어는 데이터 블록에 전송 순서를 부여하는 기능입니다. 송신 데이터들이 순서적으로 전송되도록 함으로써 흐름제어와 오류제어를 용이하게 합니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git ⑤ Branch 관리]]></title>
            <link>https://velog.io/@xxell-8/Git-Branch-%EA%B4%80%EB%A6%AC</link>
            <guid>https://velog.io/@xxell-8/Git-Branch-%EA%B4%80%EB%A6%AC</guid>
            <pubDate>Sun, 29 Aug 2021 06:59:11 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>브랜치(branch)란, <strong>독립적인 개발</strong>을 위한 기능으로 볼 수 있다. 개발 과정에서 여러 사람이 동시에 다양한 작업을 진행하게 되는데, 필요에 따라 브랜치를 생성하여 다른 브랜치의 영향을 받지 않고 각자 개발을 진행할 수 있으며 이후 다른 브랜치에 병합하는 과정을 통해 작업을 합칠 수 있다.</p>
</blockquote>
<h4 id="1-git-branch">1. <code>git branch</code></h4>
<ul>
<li><code>git branch</code> 명령은 브랜치와 관련한 다양한 기능을 지원한다.</li>
<li>새로운 작업을 위해 브랜치를 생성할 경우, 새로 생성된 브랜치는 현재 작업 중인 브랜치로부터 분기되어 해당 브랜치의 마지막 커밋을 가리킨다.<pre><code class="language-bash"># 1-1. 브랜치 목록 확인
$ git branch 
# 1-2. 브랜치 목록과 각각의 마지막 커밋 확인
$ git branch -v
</code></pre>
</li>
</ul>
<h1 id="2-브랜치-생성">2. 브랜치 생성</h1>
<p>$ git branch <branch_name></p>
<h1 id="3-브랜치-삭제">3. 브랜치 삭제</h1>
<p>$ git branch -d <branch_name></p>
<pre><code>

#### 2. `git switch`
- `git switch` 명령을 통해 원하는 브랜치로 이동할 수 있다.
&gt; 💡 Git 2.23 버전에서 기존에 사용하던 `checkout`이 `switch`와 `restore`로 분리되었다. `switch`는 브랜치를 변경하는 부분을 담당하며, `restore`는 작업 파일을 복원해주는 역할을 담당한다.
```bash
# 1. 브랜치 이동
$ git switch &lt;branch_name&gt;

# 2. 새로운 브랜치를 생성해 이동
$ git switch -c &lt;branch_name&gt;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Git ④ Gitflow Workflow]]></title>
            <link>https://velog.io/@xxell-8/Git-Gitflow-Workflow</link>
            <guid>https://velog.io/@xxell-8/Git-Gitflow-Workflow</guid>
            <pubDate>Sat, 28 Aug 2021 09:18:31 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow">Gitflow Workflow</a>는 nvie의 Vincent Driessen에 의해 제안되었으며, 프로젝트 릴리즈를 중심으로 설계된 엄격한 branching model이다. 지속적 SW개발 및 DevOps 구현에 도움이 되어 대규모 프로젝트 관리에도 적용 가능한 workflow이다.</p>
</blockquote>
<ul>
<li>Gitflow Workflow는 <strong>5가지의 git branch</strong>를 사용하는데,<blockquote>
<p>항상 유지되는 메인 브랜치인 <code>main</code>과 <code>develop</code>과 일정 기간 동안만 유지되는 보조 브랜치인 <code>feature</code>, <code>release</code>, <code>hotfix</code>이다.</p>
</blockquote>
</li>
</ul>
<p>① <code>main</code></p>
<ul>
<li>공식 릴리스 기록을 저장하는 최상단 브랜치</li>
<li>배포 이력을 관리하기 위해 사용하기 때문에 배포 가능한 상태만을 관리하는 역할</li>
</ul>
<p>② <code>develop</code></p>
<ul>
<li>다음 릴리스 버전을 개발하며, 최신 개발 변경 사항을 기록하는 통합 브랜치</li>
<li>기능 개발을 위한 브랜치들을 merge하기 위해 사용하며, 모든 기능이 추가되고 버그가 수정되어 배포 가능한 상태일 때 <code>main</code> 브랜치에 merge </li>
<li>개발 단계에서는 <code>develop</code> 브랜치를 기준으로 작업 진행</li>
</ul>
<p>③ <code>feature</code></p>
<ul>
<li>기능을 개발하는 브랜치 (ex. <code>feature/login</code>)</li>
<li>새로운 기능을 개발하거나 버그 수정이 필요할 때, <code>develop</code> 브랜치에서 특정 <code>feature</code> 브랜치를 분기하여 개발을 진행</li>
<li>개발이 완료되면 다시 <code>develop</code> 브랜치로 merge되며, 더이상 필요하지 않은 <code>feature</code> 브랜치는 삭제</li>
</ul>
<p>④ <code>release</code></p>
<ul>
<li>출시 버전을 준비하는 브랜치 (ex. <code>release-2.1</code>)</li>
<li>배포를 위한 전용 브랜치로 릴리스가 준비되면 <code>develop</code> 브랜치로부터 <code>release</code> 브랜치를 분기하여 배포에 필요한 최종 버그 수정 및 문서 작업 등을 수행</li>
<li><code>release</code> 브랜치를 통해 배포를 준비하면, 그 기간 동안에도 <code>develop</code> 브랜치에서는 다음 버전을 위한 개발이 진행될 수 있음</li>
</ul>
<p>⑤ <code>hotfix</code></p>
<ul>
<li>릴리스 버전에서 발생한 버그를 수정하는 브랜치 (ex. <code>hotfix-2.1.1</code>)</li>
<li>배포된 버전에서 급하게 수정이 필요한 경우, <code>master</code> 브랜치에서 <code>hotfix</code> 브랜치를 분기하여 작업을 수행</li>
<li><code>master</code> 브랜치로부터 분기되어 다른 개발 단계를 고려하지 않고, 특정 문제를 빠르게 해결할 수 있음</li>
</ul>
<h4 id="branch의-전체적인-흐름">Branch의 전체적인 흐름</h4>
<p><img src="https://images.velog.io/images/xxell-8/post/5ff90db2-5af2-40ef-b189-2f20ccd9d12a/branches.svg" alt="Branch 관리"></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git ③ 원격 저장소 활용]]></title>
            <link>https://velog.io/@xxell-8/Git-%EC%9B%90%EA%B2%A9-%EC%A0%80%EC%9E%A5%EC%86%8C-%ED%99%9C%EC%9A%A9</link>
            <guid>https://velog.io/@xxell-8/Git-%EC%9B%90%EA%B2%A9-%EC%A0%80%EC%9E%A5%EC%86%8C-%ED%99%9C%EC%9A%A9</guid>
            <pubDate>Sat, 28 Aug 2021 08:23:23 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>원격 저장소(Remote Repository)란, 인터넷이나 네트워크 어딘가에 있는 저장소를 말한다. 흔히 <code>github</code>이나 <code>gitlab</code>에 원격 저장소를 만들어 사용하며, 저장소를 관리하고 데이터를 Push&amp;Pull 하는 작업을 통해 협업이 진행된다. 리모트 저장소를 관리한다는 것은 저장소를 추가, 삭제하는 것뿐만 아니라 브랜치 관리와 데이터 추적 여부 등을 관리하는 것을 말한다.</p>
</blockquote>
<h4 id="1-원격-저장소-연결">1. 원격 저장소 연결</h4>
<ul>
<li><code>git remote</code> 연결을 통해 현재 프로젝트에 등록된 원격 저장소를 확인하거나 추가할 수 있다.</li>
</ul>
<ol>
<li>원격 저장소 가져오기
_    💡 저장소를 Clone할 경우, 원격 저장소의 단축 이름은 <code>origin</code>으로 표시된다._<pre><code class="language-bash">$ git clone &lt;http url&gt;</code></pre>
</li>
<li>로컬 저장소를 원격 저장소에 연결하기
_    💡 원격 저장소를 추가할 때에는 origin 대신 다른 단축 이름을 설정할 수 있다._<pre><code class="language-bash">$ git remote add origin &lt;http url&gt;
$ git remote add &lt;단축 이름&gt; &lt;http url&gt;</code></pre>
</li>
<li>연결된 원격 저장소 확인하기<pre><code class="language-bash">$ git remote -v</code></pre>
</li>
</ol>
<h4 id="2-pull--push">2. pull &amp; push</h4>
<ol>
<li>원격 저장소에서 데이터 가져오기</li>
</ol>
<ul>
<li>데이터를 가져오는 방식은 <code>pull</code>과 <code>fetch</code>로 볼 수 있다.
‣ <code>pull</code>: 원격 저장소에서 데이터를 가져와 <strong>자동</strong>으로 Merge
‣ <code>fetch</code>: 원격 저장소에서 데이터를 가져와 <strong>수동</strong>으로 Merge</li>
</ul>
<ol start="2">
<li>원격 저장소에 데이터 추가하기</li>
</ol>
<ul>
<li>로컬 저장소에 변경 이력을 commit한 뒤, <code>git push</code> 명령을 통해 원격 저장소에 해당 commit을 저장할 수 있다.</li>
</ul>
<pre><code class="language-bash">$ git pull origin &lt;branch&gt;
$ git push origin &lt;branch&gt;</code></pre>
<h4 id="3-원격-저장소-관리">3. 원격 저장소 관리</h4>
<ol>
<li>원격 저장소 정보 확인하기</li>
</ol>
<ul>
<li><code>git remote show &lt;저장소 이름&gt;</code> 명령으로 원격 저장소에 구체적인 정보를 확인할 수 있다. 
  ‣ 출력 정보에는 원격 저장소의 <code>URL</code>과 추적하는 <code>브랜치</code>, git pull 명령을 실행할 때 master 브랜치와 Merge 할 브랜치가 무엇인지 등이 포함된다.</li>
</ul>
<ol start="2">
<li>저장소 이름 수정/삭제</li>
</ol>
<ul>
<li><code>git remote rename &lt;old&gt; &lt;new&gt;</code>를 통해 저장소 이름을 변경할 수 있다.</li>
<li><code>git remote remove &lt;name&gt;</code>을 통해 해당 저장소 이름을 삭제할 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git ② 로컬 저장소 활용]]></title>
            <link>https://velog.io/@xxell-8/Git-%EB%A1%9C%EC%BB%AC-%EC%A0%80%EC%9E%A5%EC%86%8C-%ED%99%9C%EC%9A%A9</link>
            <guid>https://velog.io/@xxell-8/Git-%EB%A1%9C%EC%BB%AC-%EC%A0%80%EC%9E%A5%EC%86%8C-%ED%99%9C%EC%9A%A9</guid>
            <pubDate>Sat, 28 Aug 2021 07:42:42 GMT</pubDate>
            <description><![CDATA[<h4 id="-1-git-저장소-만들기-">** 1. Git 저장소 만들기 **</h4>
<ul>
<li>Git 저장소를 만드는 법은 크게 2가지로 볼 수 있다. 
① 아직 버전관리를 하지 않는 <code>로컬 디렉토리</code> 하나를 선택해서 <code>Git 저장소를 적용</code>하는 방법
② 다른 어딘가에서 <code>Git 저장소를 Clone</code> 하는 방법</li>
</ul>
<ol>
<li><p>기존 디렉토리를 Git 저장소로 만들기</p>
<ul>
<li>Git으로 관리할 프로젝트 디렉토리로 이동</li>
<li>해당 경로에서 <code>git init</code> 명령 실행
👉 Git 저장소가 되면, <code>.git</code> 폴더가 생성되며, 경로 끝에 현재 branch 이름이 표시된다!</li>
</ul>
</li>
<li><p>기존 저장소를 Clone 하기</p>
<ul>
<li><code>git clone &lt;url&gt;</code> 명령을 통해 원하는 저장소를 Clone</li>
</ul>
</li>
</ol>
<h4 id="2-git으로-파일-관리-">*<em>2. Git으로 파일 관리 *</em></h4>
<ul>
<li>Git이 파일을 관리하게 하려면 저장소에 파일을 추가하고 커밋해야 하는데, <code>git add</code> 명령으로 파일을 추가하고 <code>git commit</code> 명령으로 커밋할 수 있다.
<img src="https://images.velog.io/images/xxell-8/post/52b49e1a-b401-4384-adae-fb1e7218c6e1/git%20repo.png" alt="Git 상태"></li>
</ul>
<ol>
<li><p><code>git add</code></p>
<blockquote>
<p><code>working directory</code>, 즉 작업 공간에서 변경된 사항을 저장하기 위해 해당 파일을 <code>staging area</code>에 추가할 수 있다.</p>
</blockquote>
<pre><code class="language-bash"># 1. 현재 경로의 모든 파일을 add
$ git add .
# 2. 특정 파일 or 경로를 지정해서 add
$ git add &lt;해당 경로&gt;</code></pre>
<p> cf. <code>git status</code>를 통해 현재 Git 상태 파악 가능 </p>
</li>
<li><p><code>git commit</code></p>
<blockquote>
<p><code>staged</code> 상태의 파일들에 대한 이력을 커밋하려 해당 시점의 스냅샷을 기록할 수 있다.
👉 커밋 메시지는 변경사항을 명확히 알 수 있도록 작성!</p>
</blockquote>
</li>
</ol>
<pre><code class="language-bash"># 1. staged 상태의 파일 커밋
$ git commit -m &#39;&lt;message&gt;&#39;

# 2. 모든 변경 사항 자동 추가 후 커밋
$ git commit -a -m &#39;&lt;message&gt;&#39;</code></pre>
<ul>
<li>저장소 히스토리는 <code>git log</code>를 통해 확인할 수 있다. (log를 그만 보려면 <code>q</code> 입력)<pre><code class="language-bash"># 각 라인을 한 줄로 보고 싶을 경우
$ git log --oneline</code></pre>
</li>
</ul>
<h4 id="3-파일-관리-조작-">*<em>3. 파일 관리 조작 *</em></h4>
<ol>
<li>특정 파일 무시하기</li>
</ol>
<ul>
<li><code>.gitignore</code> 파일을 만들어 Git으로 관리할 필요가 없는 파일 패턴을 등록할 수 있다.
cf. <a href="https://www.toptal.com/developers/gitignore">gitignore.io</a>를 활용해 git으로 관리하지 않을 파일 패턴을 편하게 만들 수 있다!</li>
</ul>
<ol start="2">
<li><code>git add</code> 취소하기</li>
</ol>
<ul>
<li>Staging Area에 추가된 특정 파일을 다시 unstaged 상태로 되돌리기 위해 <code>git restore</code> 명령을 사용할 수 있다.<pre><code class="language-bash">$ git restore --staged &lt;파일 이름&gt;</code></pre>
</li>
</ul>
<ol start="3">
<li><code>git commit</code> 수정하기</li>
</ol>
<ul>
<li><code>--amend</code> 옵션을 통해 커밋 메시지를 수정하거나 최신 커밋에 파일을 추가할 수 있다.<pre><code class="language-bash"># 1. 특정 파일을 빠뜨리고 커밋을 남겼을 경우,
$ git commit -m &#39;&lt;message&gt;&#39;
$ git add &lt;forgotten file&gt; # 해당 파일을 다시 add 하고
$ git commit --amend # 최근 커밋에 함께 커밋하기
</code></pre>
</li>
</ul>
<h1 id="2-커밋-메시지를-수정해야-하는-경우">2. 커밋 메시지를 수정해야 하는 경우</h1>
<p>$ git commit -m &#39;<old message>&#39;
$ git commit --amend -m &#39;<new message>&#39;</p>
<pre><code>
4. `git commit` 취소하기
- `git reset [--option] [commit]` 명령을 통해 해당 commit 시점으로 돌아갈 수 있다.
    - 해당 commit 시점으로 돌아가며, 이후 변경 이력에 대해서는 `option`을 통해 조정할 수 있다.
    1. `hard`: 해당 commit 시점 이후 변경 이력을 Working Directory에서 삭제
    2. `mixed` (default): 해당 commit 시점 이후 변경 이력은 unstaged된 상태로 Working Directory에 보존
    3. `soft`: 해당 commit 시점 이후 변경 이력을 staged 상태로 Working Directory에 보존
```bash
# 1. 최근 커밋 취소
$ git reset HEAD^
# 2. 최근 2개 커밋 취소
$ git reset HEAD~2
# 3. 특정 커밋 시점으로 돌아가기
$ git log # 커밋 기록을 통해 특정 커밋 ID 확인
$ git reset &lt;commit ID&gt;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Git ① git bash 기본 명령어]]></title>
            <link>https://velog.io/@xxell-8/Git-%EA%B8%B0%EB%B3%B8-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@xxell-8/Git-%EA%B8%B0%EB%B3%B8-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Fri, 27 Aug 2021 04:52:40 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://git-scm.com/">git</a>은 DVCS(분산 버전 관리 시스템, Distribute Version Control System)으로, 소스 코드의 버전 및 이력을 관리할 수 있다.</p>
</blockquote>
<h2 id="1-basic">1. Basic</h2>
<h4 id="1-기본-단축키">1. 기본 단축키</h4>
<ul>
<li><p><code>Ctrl</code> + <code>c</code> : Cancel</p>
</li>
<li><p><code>Ctrl</code> + <code>d</code> : Delete</p>
</li>
<li><p><code>Ctrl</code> + <code>l</code> : cLear</p>
</li>
<li><p><code>Ctrl</code> + <code>a</code> : 라인 맨 앞(A)으로 이동</p>
</li>
<li><p><code>Ctrl</code> + <code>e</code> : 라인 맨 뒤(End)로 이동</p>
</li>
<li><p><code>Ctrl</code> + <code>b</code> : 앞으로 커서 이동 (←)</p>
</li>
<li><p><code>Ctrl</code> + <code>f</code> : 뒤로 커서 이동 (→)</p>
</li>
<li><p><code>Ctrl</code> + <code>w</code> : 단어 단위로 삭제</p>
</li>
<li><p><code>Ctrl</code> + <code>u</code> : 현재 입력 중인 라인 전체 삭제</p>
<p><em>cf. manual 보기 👉 <code>$ man &lt;command&gt;</code></em></p>
</li>
</ul>
<h4 id="2-directory">2. Directory</h4>
<pre><code class="language-bash"># 1. Print Working Directory 👉 현재 위치 확인
$ pwd

# 2. Change Directory 👉 이동
$ cd # 홈 dir로 이동
$ cd .. # 상위 dir로 이동
$ cd - # 이전 dir로 이동(뒤로 가기)
$ cd &lt;dir&gt; # 해당 dir로 이동

# 3. MaKe DIRectory 👉 디렉토리 생성
$ mkdir &lt;dir_name&gt;

# 4. 폴더 삭제
$ rm -rf &lt;dir_name&gt;

# 5. 폴더 내 검색
$ find . -name &#39;*.txt&#39;</code></pre>
<h4 id="3-files">3. Files</h4>
<ol>
<li>기본<pre><code class="language-bash"># 1. touch 👉 파일 생성
$ touch &lt;file&gt;
</code></pre>
</li>
</ol>
<h1 id="2-remove-👉-파일-삭제">2. ReMove 👉 파일 삭제</h1>
<p>$ rm <file>
$ rm -f <file> # 파일 강제 삭제</p>
<h1 id="3-move-👉-파일-이동-or-이름-변경">3. MoVe 👉 파일 이동 (or 이름 변경)</h1>
<p>$ mv <file> <dir> # 파일을 해당 디렉토리로 이동
$ mv <old> <new> # <old> 이름을 <new>로 변경</p>
<h1 id="4-copy-👉-파일-복사">4. CoPy 👉 파일 복사</h1>
<p>$ cp <old> <new> # <old>를 <new> 이름으로 복사</p>
<h1 id="5-현재-위치에-있는-파일-확인">5. 현재 위치에 있는 파일 확인</h1>
<p>$ ls
$ ls -a # 숨긴 파일까지 보기
$ ls -l # 상세 정보 같이 보기
$ ls -t # 파일 생성 순으로 정렬해서 보기
$ ls -alt # 옵션은 붙여서 사용 가능</p>
<pre><code>
2. 파일 조작
```bash
# 1. 입·출력
$ echo &#39;hello&#39; # print
$ echo &#39;hello&#39; &gt; &lt;file&gt; # redirect(&gt;) 👉 출력 값을 파일에 덮어쓰기
$ echo &#39;world&#39; &gt;&gt; &lt;file&gt; # append(&gt;&gt;) 👉 출력 값을 파일에 이어붙이기
$ cat greetings.txt # 파일 내용 출력

# 2. 출력 방식 설정
$ head &lt;file&gt; # 상단 10줄만 출력
$ tail &lt;file&gt; # 하단 10줄만 출력

# 3. Word Count
$ wc &lt;file&gt; # 줄, 단어, 바이트를 세서 출력

# cf. 파이프 활용 가능
$ head &lt;file&gt; | wc # 상단 10줄의 줄/단어/바이트 수 출력

# 4. 파일 탐색
$ less &lt;file&gt;
# 페이지 이동(F, B) / 반 페이지 이동(U, D) / 검색 (/&lt;pattern&gt;)

# 5. 파일 편집
$ vim</code></pre><h2 id="2-plus-">2. Plus +</h2>
<ol>
<li>정규식(Global Regular Expression and Print)<pre><code class="language-bash">$ grep &lt;string&gt; &lt;file&gt; # 해당 문자열을 파일에서 검색
$ grep -i &lt;string&gt; &lt;file&gt; # 대소문자 구분없이 검색
</code></pre>
</li>
</ol>
<h1 id="example">[example]</h1>
<p>$ pip list | grep -i django</p>
<pre><code>
2. Process Status
```bash
$ ps # 프로세스 보기
$ ps aux | grep &#39;runserver&#39;

# 프로세스를 pid로 kill
$ kill -&lt;level&gt; &lt;pid&gt;

# 프로세스를 이름으로 kill
$ kill -&lt;level&gt; -f &lt;name&gt;</code></pre><ol start="3">
<li>etc.<pre><code class="language-bash"># 1. 프로그램 설치 위치(path) 출력
$ which &lt;program&gt;
</code></pre>
</li>
</ol>
<h1 id="2-url과-상호작용">2. URL과 상호작용</h1>
<p>$ curl <url></p>
<h1 id="3-새로-갱신되는-내용-확인하기">3. 새로 갱신되는 내용 확인하기</h1>
<p>$ ping google.com &gt; google.log
$ tail -f google.log
```</p>
]]></description>
        </item>
    </channel>
</rss>