<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>_bao_.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Thu, 01 Oct 2026 07:55:09 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>_bao_.log</title>
            <url>https://velog.velcdn.com/images/_bao_/profile/49cfbc35-16ce-4190-b0e6-376ae2ce18d8/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. _bao_.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/_bao_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[26.10.01 / Thu]]></title>
            <link>https://velog.io/@_bao_/26.10.01-Thu</link>
            <guid>https://velog.io/@_bao_/26.10.01-Thu</guid>
            <pubDate>Thu, 01 Oct 2026 07:55:09 GMT</pubDate>
            <description><![CDATA[<h1 id="dq-review">DQ REVIEW</h1>
<ul>
<li>브라우저의 JS 실행 순서 중, HTML 파싱 완료로 DOM 트리 구축 끝났음을 알리는 이벤트, 외부 리소스의 로드 완료 여부와 상관없이 발생하는 것<ul>
<li>DOMContentLoaded</li>
</ul>
</li>
<li>기본 JS는 HTML의 구분 분석을 중지하므로, 효율적인 렌더링을 위해서 사용<ul>
<li>async : HTML 문서 파싱 처리를 중지 하지 않고, 비동기적으로 스크립트 다운로드, 다운로드가 종료되는 즉시 실행, 실행 시점 파싱 중단, 여러 파일 간 실행 순서 보장 X =&gt; 독립 프로그램 실행</li>
<li>defer : HTML 파싱, 스크립트 다운로드를 병렬로 처리, 실행은 DOM 트리 구축이 끝난 시점으로 예약, 실행 순서 유지로 초기화 스크립트에 적합 =&gt; DOM 조작 가능</li>
</ul>
</li>
<li>현재 페이지의 방문 이력 삭제 하지 않고, 새로운 URL로 페이지를 이동하는 Location<ul>
<li>assign</li>
</ul>
</li>
<li>JS의 전역 실행 컨텍스트에서 window 객체와 완전히 동일한 참조 대상이 아닌 것<ul>
<li>this, parent, top, globalthis</li>
</ul>
</li>
<li>HTML 요소를 구성하는 객체가 제공하는 프로퍼티, add-remove-toggle-contains 메서드를 통해 클래스 문자열을 직접 파싱하지 않고 CSS 클래스를 안전하게 추가-삭제-전환 할 수 있도록 해주는 것<ul>
<li>classList</li>
</ul>
</li>
</ul>
<h1 id="7">7</h1>
<h3 id="이벤트--event-">이벤트 ( Event )</h3>
<ul>
<li>웹 페이지 내에서 발생하는 모든 사용자의 행동</li>
</ul>
<h4 id="이벤트-핸들러--event-handler-">이벤트 핸들러 ( Event Handler )</h4>
<ul>
<li>이벤트가 발생했을 때 실행되는 함수</li>
<li>Thread : 작업자(일꾼), 작업단위<ul>
<li>call stack</li>
<li>실행 영역 함수</li>
</ul>
</li>
<li>Multi Thread : 쓰레드 여러개를 쌓아놓은 형태<ul>
<li>작업자를 여려명 두고 동시 작업을 진행하기 위해서</li>
</ul>
</li>
</ul>
<ol>
<li>setTimeout ( 이벤트 핸들러, 지연시간 );  =&gt; 이벤트 핸들러 등록 번호를 반환 한다. <ul>
<li>취소시에 등록 번호 사용 =&gt; clearTimeout(등록번호);</li>
<li>지연시간은 1000당 1초</li>
<li>비동기 </li>
</ul>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/_bao_/post/c480256f-395f-4fe6-bf50-86ea4103eea1/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_bao_/post/11dcf133-38d2-438d-892d-af74cbe5a071/image.png" alt=""></p>
<ol start="2">
<li>setInterval ( 이벤트 핸들러, 지연 시간 );<ul>
<li>반복 지연 실행</li>
<li>clearInterval( 핸들러 등록 번호 ); =&gt; 취소</li>
</ul>
</li>
</ol>
<h3 id="이벤트를-등록하는-방법">이벤트를 등록하는 방법</h3>
<ul>
<li>HTML 요소의 이벤트 속성<ul>
<li>on 이벤트 명</li>
</ul>
</li>
<li>btnEl2.onclick에 함수의 주소를 대입하는 방식이기 때문에 함수 2개를 선언하면 마지막 함수의 주소만 가질 수 있다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/_bao_/post/1b990cb9-ee29-489b-bffe-c134b2a22334/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_bao_/post/bedcbb69-f63a-4aae-8dfb-a9d6083de2f7/image.png" alt=""></p>
<ul>
<li>document.addEventListener( 이벤트 명, 이벤트 핸들러 함수, 캡쳐링 여부[false] )</li>
<li>캡처링 -&gt; 이벤트 전파 방향<ul>
<li>false : 버블링 단계에서 전파 ( 기본값 )</li>
<li>true : 캡처링 단계에서 전파</li>
</ul>
</li>
</ul>
<pre><code class="language-html">    &lt;script&gt;
        window.addEventListener(&quot;DOMContentLoaded&quot;, function() {
            const btnEl = document.getElementById(&#39;btn&#39;);
            btnEl.addEventListener(&#39;click&#39;, function(){
                console.log(&#39;click1&#39;)
            });

            btnEl.addEventListener(&#39;click&#39;, function(){
                console.log(&#39;click2&#39;)
            });
        });
    &lt;/script&gt;
    &lt;button type=&quot;button&quot; id=&quot;btn&quot;&gt;버튼&lt;/button&gt;</code></pre>
<ul>
<li><p>캡처링 단계 -&gt; 타겟 단계 -&gt; 버블링 단계</p>
<pre><code>           |
           - &gt; 이벤트 핸들러가 실행</code></pre></li>
<li><p>타겟 단계의 이벤트가 상위 요소로 전파</p>
<pre><code class="language-html">  &lt;style&gt;
      .box{
          padding: 150px;
          background: gray;
      }

      .box2 {
          background: orange;
      }

      .box3 {
          background: black;
      }
  &lt;/style&gt;
  &lt;script&gt;
      window.addEventListener(&#39;DOMContentLoaded&#39;, function() {
          const box1 = document.querySelector(&#39;.box1&#39;);
          const box2 = document.querySelector(&#39;.box2&#39;);
          const box3 = document.querySelector(&#39;.box3&#39;);

          box1.addEventListener(&#39;click&#39;, function(e) {
              console.log(&#39;box1 click&#39;);
          });

          box2.addEventListener(&#39;click&#39;, function(e) {
              console.log(&#39;box2 click&#39;);
          });

          box2.addEventListener(&#39;click&#39;, function(e) {
              console.log(&#39;box3 click&#39;);
              console.log(e);
          });
      });
  &lt;/script&gt;
  &lt;div class=&quot;box box1&quot;&gt;
      &lt;div class=&quot;box box2&quot;&gt;
          &lt;div class=&quot;box box3&quot;&gt;

          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;</code></pre>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/_bao_/post/0c258746-a1c3-4c3c-bb0b-440e1711c408/image.png" alt=""></p>
<h3 id="이벤트-객체">이벤트 객체</h3>
<ul>
<li>이벤트 핸들러의 첫번째 매개변수</li>
</ul>
<ol>
<li>발생한 이벤트와 관련된 정보</li>
<li>이벤트 통제 메서드<ul>
<li>stopPropagation() : 이벤트 전파 차단</li>
<li>stopImmediatePropagation () : 이벤트 전파 차단, 같은 요소의 다른 이벤트도 차단</li>
<li>preventDefault() :  태그 기본 동작 방지</li>
</ul>
</li>
<li>e.currentTarget : this와 동일한 대상 참조 / 이벤트가 바인딩 된 요소<ul>
<li>e.target : 실제 이벤트가 발생한 요소</li>
</ul>
</li>
</ol>
<h4 id="preventdefault">preventDefault()</h4>
<p><img src="https://velog.velcdn.com/images/_bao_/post/25f1e2f7-89b5-4d98-b214-f7d73960c5c9/image.png" alt=""></p>
<h4 id="currenttarget-target">currentTarget, target</h4>
<p><img src="https://velog.velcdn.com/images/_bao_/post/2d64acda-18ed-499d-b014-4849cc7233f6/image.png" alt=""></p>
<h2 id="마우스-이벤트">마우스 이벤트</h2>
<ul>
<li>click</li>
<li>dblclick</li>
<li>mousemove</li>
<li>mousedown</li>
<li>mouseup<h2 id="키보드-이벤트">키보드 이벤트</h2>
</li>
<li>keydown - 주 사용</li>
<li>keypress - 기능키 ( Alt, Ctrl 동작 안함)</li>
<li>keyup - 눌렀다 뗼 때</li>
</ul>
<table>
<thead>
<tr>
<th>프로퍼티</th>
<th>값의 타입</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>key</code></td>
<td>문자열</td>
<td>눌린 키가 나타내는 실제 문자 값 (예: <code>&quot;a&quot;</code>, <code>&quot;Enter&quot;</code>, <code>&quot;ArrowUp&quot;</code>)</td>
</tr>
<tr>
<td><code>code</code></td>
<td>문자열</td>
<td>키보드 상에서 자판이 가지는 물리적인 위치 코드 (예: <code>&quot;KeyA&quot;</code>, <code>&quot;Enter&quot;</code>)</td>
</tr>
<tr>
<td><code>keyCode</code></td>
<td>정수</td>
<td>눌린 키를 나타내는 레거시 숫자 코드 (사용 비권장)</td>
</tr>
<tr>
<td><code>altKey</code> / <code>ctrlKey</code> / <code>shiftKey</code></td>
<td>논리값</td>
<td>입력 시 Alt / Ctrl / Shift 키가 함께 눌려 있었는지 여부</td>
</tr>
</tbody></table>
<h2 id="기타">기타</h2>
<ul>
<li>change<ul>
<li>select</li>
<li>number</li>
<li>range</li>
<li><code>&lt;input type=&#39;file&#39;&gt;</code> =&gt; fileList</li>
</ul>
</li>
<li>submit</li>
<li>focus</li>
<li>blur</li>
</ul>
<h1 id="7-2">7-2</h1>
<h1 id="동기식">동기식</h1>
<p><img src="https://velog.velcdn.com/images/_bao_/post/d24a8ef7-c45f-4cbb-8e50-c66cd6ba5bc7/image.png" alt=""></p>
<h1 id="비동기식">비동기식</h1>
<p><img src="https://velog.velcdn.com/images/_bao_/post/4178cbc9-6b28-4c67-9b22-bfb4ca4a57e5/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_bao_/post/bc414cd7-1e40-4b9e-992a-dfec2492761e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_bao_/post/f5e36236-1dab-4933-a0ca-6d2981bf14f8/image.png" alt=""></p>
<h3 id="ajax--asychronous-javascript-and-x-">ajax ( Asychronous JavaScript and X )</h3>
<ul>
<li>페이지 새로고침 없이 데이터를 치환하는 기술</li>
</ul>
<p><img src="https://velog.velcdn.com/images/_bao_/post/081a1d8a-9481-4705-a046-4d6c8ee71ce0/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_bao_/post/67196a11-cf45-482d-9fe2-1da6629e0c7c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_bao_/post/f8ab939a-d3f6-4c98-bac0-fb2f0fc37072/image.png" alt=""></p>
<h3 id="xmlhttprequest">XMLHTTPRequest</h3>
<h3 id="fetch-api--promise-기반-">Fetch API ( Promise 기반 )</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.30 / Wed]]></title>
            <link>https://velog.io/@_bao_/26.9.30-Wed</link>
            <guid>https://velog.io/@_bao_/26.9.30-Wed</guid>
            <pubDate>Wed, 30 Sep 2026 08:47:58 GMT</pubDate>
            <description><![CDATA[<h1 id="dq-review">DQ REVIEW</h1>
<ul>
<li>수정 메서드 : 배열 메서드 중 원본 배열 자체를 직접 변경하는 메서드와</li>
<li>접근자 메서드 : 원본은 그대로 두고 새로운 배열이나 값을 반환하는 메서드를 통칭하는 용어</li>
<li>화살표 함수의 특징<ul>
<li>함수 실행 자체 목적, 생성자 역할 불가능, prototype 미존재</li>
</ul>
</li>
<li>클로저 : 내부 함수가 외부 함수의 실행 완료 후에도 소멸된 상위 렉시컬 환경의 변수를 지속적으로 참조하고 조작할 수 있는 메모리 구조</li>
</ul>
<h1 id="6-1">6-1</h1>
<pre><code>브라우저 -&gt; 서버에게 요청
서버 -&gt; 브라우저에 응답, html, 텍스트 전달
브라우저 - document 객체 변환 -&gt; 트리 구조 구축 (DOM Tree) [ -&gt;  script 태그 -&gt; 동기 실행]
 -&gt; DOMContentLoaded 이벤트 발생 -&gt; Load 이벤트 발생 ( 자원 로드 완료 )</code></pre><h2 id="웹-브라우저의-자바스크립트-실행-9단계-순서">웹 브라우저의 자바스크립트 실행 9단계 순서</h2>
<img src='./0930_imgs/1.png'>


<h2 id="호스트-객체">호스트 객체</h2>
<ul>
<li>런타임 마다 다르게 구성되어 있는 특화 객체</li>
</ul>
<ol>
<li>웹브라우저 내에 탑재, 웹브라우저 객체<ul>
<li>브라우저의 기능과 밀접하게 관련</li>
</ul>
</li>
<li>window <ul>
<li>location 객체 : 주소창과 관련된 정보 / 기능을 제공<ul>
<li>실시간성, 변경내용이 실제 반영 ( 주소창 변화 )</li>
<li>assign(..) : 지정된 주소로 이동 ( 방문 기록 남김 ) -&gt; location.href -&gt; 속성 변경 시 페이지 이동</li>
<li>replace(..) : 지정된 주소로 이동 ( 방문 기록 남기지 않음 )</li>
<li>reload(..) : 새로고침</li>
</ul>
</li>
<li>history 객체 : 방문기록과 관련된 정보 / 기능 제공<ul>
<li>length : 방문 기록<ul>
<li>back() : 뒤로 가기</li>
<li>forward() : 앞으로 가기</li>
<li>go() : 음수 = 수 만큼 뒤로 가기, 양수 = 수 만큼 앞으로 가기</li>
</ul>
</li>
<li>scrollRestoration<ul>
<li>auto : 스크롤 위치 기억 복구</li>
<li>manual : 복구 x</li>
</ul>
</li>
</ul>
</li>
<li>scroll 객체 : 브라우저 사용 화면 관련된 정보 / 기능 제공</li>
<li>navigator 객체 : 브라우저 OS 사용환경, 기타 API 관련 정보 / 기능 제공</li>
<li>document 객체 : 문서와 관련된 정보 / 기능 제공</li>
</ul>
</li>
</ol>
<h2 id="document-객체">Document 객체</h2>
<ul>
<li>DOM Tree : 빠른 요소 탐색에 필요</li>
<li>요소(DOM)을 선택하는 방법<ul>
<li>아이디(id)로 선택 =&gt; document.getElementById(아이디명);  =&gt; 단일 선택</li>
<li>클래스(class)로 선택 =&gt; document.getElementsByClassName(클래스명); =&gt; 복수 선택</li>
<li>태그(tag)로 선택 =&gt; document.getElementsByTagName(&#39;태그명&#39;); =&gt; 복수 선택</li>
<li>name 속성명으로 선택 =&gt; document.getElementsByName(&#39;Name 속성명&#39;); =&gt; 복수</li>
<li>css 선택자로 선택 =&gt; document.querySelector(&#39;css 선택자&#39;); =&gt; 첫번째 요소 단일 선택<ul>
<li>document.querySelectorAll(&#39;css 선택자&#39;); =&gt; 복수 선택</li>
</ul>
</li>
<li>문서 전체 (html) - window.document<ul>
<li>head - window.document.head</li>
<li>body - window.document.body</li>
</ul>
</li>
<li>양식 (form) 이름 - frmNIDLogin<ul>
<li>양식 하위 입력 태그는 이름으로 바로 접근 가능 frmNIDLogin.id</li>
</ul>
</li>
<li>요소 노트 (상대적 접근)<ul>
<li>parentElement : 부모 요소</li>
<li>children : 자식 요소</li>
<li>firstElementchild : 첫번째 자식</li>
<li>lastElementchild : 마지막 자식</li>
<li>nextElementSibling : 다음 근접 요소</li>
<li>previousElementSiblig : 이전 근접 요소</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="속성-attribute">속성 (Attribute)</h2>
<ul>
<li><p>document.getAttribute(&#39;속성명&#39;) =&gt; 속성 조회</p>
</li>
<li><p>document.setAttribute(&#39;속성명&#39;, &#39;속성값&#39;) =&gt; 속성 추가 / 변경</p>
</li>
<li><p>document.removeAttribute(&#39;속성명&#39;) =&gt; 속성 제거</p>
</li>
<li><p>document.hasAttribute(&#39;속성명&#39;) =&gt; 속성의 존재여부</p>
</li>
<li><p>많이 쓰는 속성 바로 접근 가능</p>
<ul>
<li>id, type, src, href, target, action ...</li>
<li>className, style<hr>
</li>
</ul>
</li>
<li><p>데이터 속성</p>
<ul>
<li>다른 속성들의 영향을 끼치지 않고, 데이터를 전달하기 위해</li>
<li>실시간성 보장</li>
<li>document.dataset()<hr>
</li>
</ul>
</li>
<li><p>클래스 속성</p>
<ul>
<li>document.classList<ul>
<li>추가, 수정, 삭제, 조회</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="실습-과제">실습 과제</h1>
<p><a href="https://app.notion.com/p/6-1-BOM-c90794972ce583cab9c6011b299e84a5?source=copy_link"> [6장 1강] 브라우저 렌더링 엔진과 브라우저 객체 모델(BOM) </a>
<a href="https://app.notion.com/p/6-2-DOM-bae794972ce58254bfde0118bc2120bb?source=copy_link"> [6장 2강] - DOM 객체 트리 탐색 및 문서 요소 동적 제어 </a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.29 / Tue]]></title>
            <link>https://velog.io/@_bao_/26.9.29-Tue</link>
            <guid>https://velog.io/@_bao_/26.9.29-Tue</guid>
            <pubDate>Tue, 29 Sep 2026 08:41:07 GMT</pubDate>
            <description><![CDATA[<h1 id="dq-review">DQ REVIEW</h1>
<ol>
<li>생성자 함수 내부에서 this.area = function() {...} 형태로 메서드 정으할 때 가장 큰 구조적 문제점</li>
</ol>
<ul>
<li>객체 생성시에 메모리에 매번 생성됨, 생성자 함수 객체 안의 prototype을 통하는 방법이 더 효율적임</li>
</ul>
<ol start="2">
<li>객체에 존재하지 않는 프로퍼티나 메서드에 접근했을 때, 자바스크립트 엔진이 내부 링크(<em>proto</em>)를 따라 상위 객체들을 차례로 검색하는 연결 구조</li>
</ol>
<ul>
<li>Prototype Chain</li>
</ul>
<ol start="3">
<li>클래스 구문과 일반 생성자 함수를 비교한 설명</li>
</ol>
<ul>
<li>클래스 구문 -&gt; new 연산자 없이 호출 불가</li>
</ul>
<ol start="4">
<li>자식 클래스의 constructor 내부에서 부모 클래스의 속성을 초기화하고 this에 정상적으로 접근하기 위해 반드시 먼저 호출해야 하는 구문</li>
</ol>
<ul>
<li>super()</li>
</ul>
<ol start="5">
<li>객체 내부에 중첩된 객체가 있을때, JSON.stringify와 JSON.parse를 연속으로 적용하여 참조 주소를 공유하지 않는 완전히 독립적인 복사번을 만드는 기법</li>
</ol>
<ul>
<li>깊은 복사</li>
</ul>
<h1 id="5-1">5-1</h1>
<h2 id="인수의-유연성--가변-매개변수">인수의 유연성 &amp; 가변 매개변수</h2>
<h3 id="매개변수-기본값--default-parameter-">매개변수 기본값 ( Default Parameter )</h3>
<img src='./0929_imgs/1.png'>

<h3 id="arguments-객체를-이용한-가변-매개변수-입력받기">Arguments 객체를 이용한 가변 매개변수 입력받기</h3>
<ul>
<li>과거에 사용하던 방법</li>
</ul>
<img src='./0929_imgs/2.png'>

<h3 id="rest-parameter-가변-매개변수-나머지-매개변수">Rest Parameter, 가변 매개변수, 나머지 매개변수</h3>
<ul>
<li>Array 배열 형태로 값 반환</li>
</ul>
<img src='./0929_imgs/3.png'>
<br>
<img src='./0929_imgs/4.png'>
<img src='./0929_imgs/5.png'>

<h3 id="비구조화-할당">비구조화 할당</h3>
<ul>
<li>구조 -&gt; 비구조화(구조 분해) -&gt; 변수에 할당</li>
</ul>
<img src='./0929_imgs/6.png'>

<ul>
<li>중첩 객체 비구조화</li>
</ul>
<img src='./0929_imgs/7.png'>

<h3 id="함수-선언문-방식">함수 선언문 방식</h3>
<img src='./0929_imgs/8.png'>

<h3 id="함수-리터럴표현식-방식">함수 리터럴(표현식) 방식</h3>
<img src='./0929_imgs/9.png'>

<h2 id="값으로서의-함수-일급-객체--콜백">값으로서의 함수 (일급 객체) &amp; 콜백</h2>
<h3 id="일급-객체로서의-3대-속성">일급 객체로서의 3대 속성</h3>
<ul>
<li>변수 할당 ( Assignment )</li>
<li>매개변수 전달 ( Argument Passing ) == 콜백 함수 / 사용자 정의 함수 / 일회용 함수</li>
<li>변환값 활용 ( Return Value )</li>
</ul>
<img src='./0929_imgs/10.png'>

<h3 id="화살표-함수">화살표 함수</h3>
<ul>
<li>function 키워드 생략</li>
<li>매개변수 정의부와 코드 실행 영역({}) 사이에 =&gt; 로 표기</li>
</ul>
<img src='./0929_imgs/11.png'>

<h3 id="화살표-함수-제한사항">화살표 함수 제한사항</h3>
<ul>
<li>생성자 함수 사용 불가</li>
<li>arguments 객체 미지원</li>
<li>yield 사용 불가</li>
</ul>
<h3 id="화살표-함수의-this">화살표 함수의 this</h3>
<ul>
<li>일반 함수의 this : 함수가 호출되면 호출한 객체</li>
<li>화살표 함수의 this : 함수가 정의되는 시점에 이미 결정되어 있는 this로 정의</li>
</ul>
<img src='./0929_imgs/12.png'>

<p>#</p>
<pre><code>function abc(a, b){}
-&gt; abc = new Function(...);</code></pre><ul>
<li>모든 함수 객체는 Function.prototype을 상속 받음<ul>
<li>Function.prototype에 정의된 기능 사용 가능</li>
</ul>
</li>
</ul>
<h2 id="명시적-this-바인딩">명시적 this 바인딩</h2>
<h3 id="call-메서드">call 메서드</h3>
<img src='./0929_imgs/13.png'>

<h3 id="apply-메서드">apply 메서드</h3>
<h3 id="bind-메서드">bind 메서드</h3>
<ul>
<li>새로운 함수 생성</li>
<li>받게 되는 첫 인자의 value로 this 키워드 설정 이후 인자들은 바인드 된 함수의 인수에 제공</li>
</ul>
<img src='./0929_imgs/14.png'>

<h2 id="제너레이터">제너레이터</h2>
<h1 id="4-3">4-3</h1>
<h3 id="js-객체">JS 객체</h3>
<ul>
<li>네이티브 객체<ul>
<li>공통 객체</li>
<li>내장 생성자, 표준 생성자 객체<ul>
<li>원시 래퍼 객체 <ul>
<li>Object</li>
<li>String</li>
<li>Number<ul>
<li>isNaN 보다 typeof 쓰는게 안정적</li>
<li>isNaN은 String 숫자도 받아들이는 경우 있음</li>
<li>parseInt : 정수로 변경</li>
<li>parseFloat : 소수로 변경</li>
</ul>
</li>
<li>Boolean</li>
</ul>
</li>
<li>Function, Date, Error, RegExp(정규표현식 사용 가능 객체)</li>
</ul>
</li>
<li>내장 객체<ul>
<li>처음부터 쓸 수 있는 편의 객체</li>
<li>JSON<ul>
<li>Stringify (직렬화) : 자바스크립트 객체 -&gt; JSON 문자열</li>
<li>Parse (역직렬화) : JSON 문자열 -&gt; 자바스크립트 객체</li>
</ul>
</li>
<li>Math<ul>
<li>abs(..) : 절댓값</li>
<li>sqrt(..) : 제곱근</li>
<li>round(..) : 반올림</li>
<li>floor(..) : 버림</li>
<li>ceil(..) : 올림</li>
<li>trunc(..) : 절사 등</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>호스트 객체<ul>
<li>런타임 환경에 특화된 객체</li>
<li>웹 브라우저 객체, Node.js 특화 객체</li>
</ul>
</li>
</ul>
<h3 id="array-객체">Array 객체</h3>
<ul>
<li>모든 타입 값 지정 가능, 여러개 관리</li>
</ul>
<hr>

<ul>
<li>Array 생성자 함수 생성</li>
<li>Array Prototype 상속 여부 =&gt; 기준</li>
<li>instanceof =&gt; 객체의 상속 관계 체크 ( Prototype Chain 관계 )</li>
<li>[...] = new Array(...) 동일</li>
<li>delete로 배열의 값을 삭제 했을 경우 index를 순서에 맞춰서 변경하진 않음</li>
<li>주요 메서드<ul>
<li>추가<ul>
<li>push(..) : 요소 끝에 추가</li>
<li>unshift(..) : 요소 앞에 추가</li>
<li>splice(..): 지정된 위치의 요소를 추가 또는 삭제<ul>
<li>시작, 삭제 개수, ... 추가 요소</li>
</ul>
</li>
</ul>
</li>
<li>삭제<ul>
<li>pop(..) : 끝 요소를 꺼내기 (반환, 제거)</li>
<li>shift(..) : 앞 요소 꺼내기 (반환, 제거)</li>
<li>splice(..)</li>
</ul>
</li>
<li>수정<ul>
<li>map(callback 함수) : callback 함수의 정의 내용대로 변경</li>
<li>filter(callback 함수) : callback 함수의 정의 내용대로 필터링</li>
</ul>
</li>
<li>조회<ul>
<li>forEach(callback 함수)</li>
<li>indexof() : 요소의 위치 반환 ( 왼 -&gt; 오 )</li>
<li>lastIndexof: 요소의 위치 번호 ( 오 -&gt; 왼 )</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.23 / Wed]]></title>
            <link>https://velog.io/@_bao_/26.9.23-Wed</link>
            <guid>https://velog.io/@_bao_/26.9.23-Wed</guid>
            <pubDate>Wed, 23 Sep 2026 08:14:50 GMT</pubDate>
            <description><![CDATA[<h1 id="43">4.3</h1>
<h3 id="객체-리터럴">객체 리터럴</h3>
<ul>
<li>{ 키 : 값, 키 : 값 ... }</li>
<li>값<ul>
<li>원시 타입 : 재료가 되는 값 =&gt; 숫자, 문자, 논리값, undefined, null</li>
<li>객체 타입 : 원시타입 외 전부</li>
</ul>
</li>
</ul>
<p>속성(Property)</p>
<ol>
<li>접근<ul>
<li>.  : 속성명이 변수명 규칙에 부합하는 경우</li>
<li>[] : 속성명이 변수명 규칙에 부합하지 않는 경우</li>
</ul>
</li>
<li>추가 : 새로운 속성명으로 값을 대입</li>
<li>수정 : 기존에 존재하는 속성명에 값 대입</li>
<li>삭제 : delete 객체 참조 변수를 통해서 =&gt; 객체참조변수.속성명 </li>
</ol>
<img src='./imgs_0923/1.png'>

<h4 id="주소-참조">주소 참조</h4>
<pre><code>person2 = person
-&gt; person2는 단독의 주소를 가지는 것이 아닌 person의 주소값을 가지고 참조를 하는 형태
-&gt; person2에서 속성값을 변경하거나, person에서 속성값을 변경하면
-&gt; person, person2 두 개 모두 속성값이 변경됨</code></pre><img src='./imgs_0923/2.png'>

<h1 id="5-1">5-1</h1>
<h3 id="함수">함수</h3>
<ol>
<li><p>function</p>
<pre><code>function 함수명(함수 객체의 이름표 | 변수와 같다) ( 매개변수 ..) {
 함수가 실행할 코드
 return 반환값</code></pre><p>}</p>
</li>
<li><p>함수의 실행 평가 과정</p>
<ul>
<li>실행 가능한 객체(Execution Context) 로 함수를 번역 하는 과정</li>
</ul>
<pre><code class="language-js">function outer(num1, num2){
 return num1 + num2;
}

</code></pre>
</li>
</ol>
<pre><code>

### 객체 상속

1. 프로토타입 기반의 객체간의 상속(프로토타입 체인)
  - 객체 --- 객체  =&gt; 상속
2. 생성자 함수
  - 객체를 생성하는 함수
  - 네이밍 관례 =&gt; 첫글자를 대문자
  - new 연산자
3. 생성자 함수가 객체를 생성하는 과정 new
  - 생성자 함수의 prototype 객체 상속
  - 생성자 함수의 this를 생성된 객체의 주소로 변경 ( 값 할당 ), 실행
4. 생성자, prototype, method
  - 객체가 생성되면 공유하는 메서드 ( 인스턴스 메서드 )
5. 생성자 메서드
  - 객체 생성 없이 공유하는 메서드 ( 정적 메서드 )

```js
class Ellipse {
    constructor(a, b){
        this.a = a;
        this.b = b;
    }

    getArea() {
        return this.a * this.b * Math.PI;
    }
}

class Circle extends Ellipse {
    constructor(r){
        super(r, r);
    }

    getArea() {
        console.log(&quot;재정의 된 getArea()&quot;);
        return super.getArea();
    }
    // 생성자가 아닌, 기능이 제한된 메서드
}</code></pre><p>####
객체를 생성할때마다 신규 주소를 부여받음</p>
<p>##</p>
<ul>
<li><p>데이터 프로퍼티</p>
<ul>
<li>value : 값</li>
<li>writable : 변경 가능 여부</li>
<li>enumerable : 열거 가능 여부<ul>
<li>for ..in =&gt; false면 객체 속성 노출 안함</li>
</ul>
</li>
<li>configurable : 재정의 가능 여부 =&gt; 설정을 변경 할 수 있는가?<ul>
<li>false : 삭제도 불가능</li>
</ul>
</li>
</ul>
</li>
<li><p>접근자 프로퍼티</p>
<ul>
<li>get 함수 : 읽기  </li>
<li>set 함수 : 쓰기<ul>
<li>내부 속성 통제는 가능하지만 은닉은 다른 기법을 사용하는 것이 좋다. 클로저 ( 캡슐화 )</li>
</ul>
</li>
<li>enumerable : 열거 가능 여부</li>
<li>configurable : 재정의 가능</li>
</ul>
</li>
</ul>
<pre><code class="language-js">const person = {
    _name : &#39;kim&#39;,
    _age: 20,
    get name() {
        // 통제 로직...
        return this._name;
    },
    set name(name) {
        // 통제 로직...
        this._name = name;
    },
    get age() {
        return this._age;
    },
    set age(age) {
        this._age = age;
    },
};</code></pre>
<h3 id="즉시-실행-함수">즉시 실행 함수</h3>
<ul>
<li>정의 후 즉시 호출<pre><code class="language-js">( function 함수명 ( 매개변수 ) {
</code></pre>
</li>
</ul>
<p>})( );</p>
<p>```</p>
<p>###</p>
<ul>
<li><p>Object.seal(...) : 객체 밀봉</p>
<ul>
<li>속성 추가 안됨</li>
<li>속성 삭제 안됨</li>
<li>속성 변경 가능</li>
</ul>
</li>
<li><p>Object.freeze(..) : 객체 동결 </p>
<ul>
<li>속성 추가 안됨</li>
<li>속성 삭제 안됨</li>
<li>속성 변경 안됨</li>
</ul>
</li>
<li><p>Object.preventExtensions (...) -&gt; 속성 추가 방지</p>
</li>
</ul>
<h3 id="직렬화--serialization-">직렬화 ( Serialization )</h3>
<ul>
<li><p>전송 가능한 형태로 변환 (문자열) -&gt; JSON 문자열</p>
</li>
<li><p>함수, Undefined는 변환이 불가하여 null이 됨</p>
</li>
<li><p>JSON 객체</p>
<ul>
<li>JS 객체 -&gt; JSON 문자열 (직렬화) =&gt; stringify(..)</li>
<li>JSON 문자열 -&gt; JS 객체 (역직렬화) =&gt; parser(...)</li>
</ul>
</li>
</ul>
<p>주소만 복사 : 얕은 복사
깊은 복사 : 새로운 객체 + 내용도 복사</p>
<h1 id="dq-review">DQ REVIEW</h1>
<ol>
<li>var 키워드로 선언한 변수의 특징<ul>
<li>호이스팅</li>
<li>같은 변수명을 가진 변수에 var 중복 적용 가능</li>
<li>함수 지역 범위 </li>
</ul>
</li>
<li>자바스크립트에서 피연산자의 데이터 타입을 반환해주는 단항 연산자<ul>
<li>typeof</li>
</ul>
</li>
<li>자바스크립트 조건문에서 Falsy(거짓 같은 값)로 취급되는 것.<ul>
<li>false, 0, &quot;&quot;, null, Undefined, NaN</li>
</ul>
</li>
<li>switch-case 문에서 일치하는 case의 코드를 실행한 후, 아래 다른 case들이 조건 비교 없이 연쇄적으로 실행되는 현상<ul>
<li>fall through</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.22 / Tue]]></title>
            <link>https://velog.io/@_bao_/26.9.22-Tue</link>
            <guid>https://velog.io/@_bao_/26.9.22-Tue</guid>
            <pubDate>Tue, 22 Sep 2026 05:35:56 GMT</pubDate>
            <description><![CDATA[<h1 id="4-2">4-2</h1>
<h2 id="기본-연산자">기본 연산자</h2>
<h3 id="산술-및-복합-대입-연산자">산술 및 복합 대입 연산자</h3>
<ul>
<li>증감 연산자<ul>
<li>++ : 1씩 증가</li>
<li>-- : 1씩 감소</li>
</ul>
</li>
</ul>
<pre><code class="language-js">let num = 10;
// let num2 = num++; // ++ 연산자가 뒤에 존재하는 경우 대입보다 우선순위가 낮음
let num3 = ++num;    // ++ 연산자가 앞에 존재하는 경우 대입보다 우선순위가 높음

// console.log(num2); // 10
console.log(num3);    // 11</code></pre>
<ul>
<li>동등성 비교 VS 동일성 비교<ul>
<li>동등성 비교<ul>
<li>==</li>
</ul>
</li>
<li>동일성 비교<ul>
<li>=== (권장 사항)</li>
</ul>
</li>
<li>부정 연산자<ul>
<li>! : 참은 거짓으로, 거짓은 참으로 변경</li>
<li>!= : 동등하지 않다.</li>
<li>!== :  동일하지 않다.</li>
</ul>
</li>
<li>논리 연산자<ul>
<li>&amp;&amp; : AND</li>
<li>|| : OR</li>
<li>!  : NOT</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="제어문">제어문</h2>
<h3 id="조건문--if-else---if-else-">조건문 ( if, else - if, else )</h3>
<pre><code class="language-js">// IF문
if (조건1) {
    조건1이 참일때 실행 코드
}

// IF-ELSE 문
if (조건1) {
    조건1이 참일때 실행할 코드
} else {
    조건1이 거짓일때 실행할 코드
}

// IF - ELSE IF - ELSE 문
if(조건1) {
    조건1이 참일때 실행할 코드
} else if(조건2){
    조건1이 거짓, 조건2가 참일때 실행할 코드
} else if (조건3){
    조건1이 거짓, 조건2가 거짓, 조건3이 참일때 실행할 코드  
} else {
    조건1이 거짓, 조건2가 거짓, 조건3이 거짓일때 실행할 코드 
}

// 삼항 조건식
(조건식) ? 참일때 실행되는 코드, 값 : 거짓일때 실행되는 코드, 값 

let num = 10;
const result = num === 10 ? &#39;숫자 10임&#39; : &#39;숫자 10 아님&#39;
console.log(result) // 숫자 10임</code></pre>
<pre><code class="language-js">let greeting = &#39;&#39;;
greeting = greeting || &#39;기본값&#39;;

// gretting을 선언만 하고 값을 대입하지 않았기 때문에 undefined 상태 논리연산자가 false라고 판별하는 값을 가진 경우 
// OR 연산자를 사용하면 다음항의 값을 대입할 수 있기 때문에 기본값 설정으로 사용할 수 있다.
console.log(greeting)

let num = 0;
num = num || 10;
// 0 또한 논리 연산자에서는 false로 인식하기 때문에 num = 10이 된 상태
console.log(num) // 10

let num = 0;

num = num || 10;
// 0 또한 논리 연산자에서는 false로 인식하기 때문에 num = 10이 된 상태
console.log(num) // 10


// ?? -&gt; nullish 연산자 -&gt; null, undefined 일 때만 판단
// &quot;&quot;이나 0을 값으로 사용하고 싶지만 논리 연산자가 false로 인식하는걸 해결하기 위해서 사용
let num = 0;
let num2;
num = num ?? 10;
num2 = num2 ?? 10;
console.log(num) // 0
console.log(num2) // 10

// &amp;&amp; : 단락회로평가를 이용한 간단한 조건식 수행
const message = &#39;hello&#39;;
message &amp;&amp; console.log(message); // hello
// 첫번째 항이 참이여야 두번째 항이 실행되는 코드이기 때문에
// 첫번째에 값이 존재하는지 파악하여 코드를 실행시키는 용도로 사용 가능</code></pre>
<h3 id="선택문-switch---case">선택문 (Switch - case)</h3>
<pre><code class="language-js">// switch ~ case : case의 키워드에 매칭이 되면 코드 실행 시작점이며, break를 만날때까지 하위로 내려가며 지속 실행
// break : 코드 실행 흐름을 중단한다.

const rank = 2;

switch(rank) {
    case 1:
        console.log(&#39;금메달&#39;);
        break;
    case 2:
        console.log(&#39;은메달&#39;);
        break;
    case 3:
        console.log(&#39;동메달&#39;);
        break;
    default:
        // default 키워드는 상위의 case들에 키워드 매칭이 되지 않은 경우
        // default 키워드 내부의 코드를 실행 시작점으로 한다.
        // if문의 else 같은 느낌
        console.log(&#39;까비&#39;);
        break;
}

// 선택문에서 break;를 사용하지 않았을 경우에는 선택문을 탈출하지 못하기 때문에
// 키워드 매칭 시점부터 맨 끝까지 전체 실행을 하게 된다.
// break가 없는 경우에 rank가 2라면 은메달, 동메달, default까지 전체 출력이 진행되기 때문에
// break 키워드를 사용하여 다른 케이스의 코드를 실행하지 않도록 방지해야 함</code></pre>
<h2 id="반복문">반복문</h2>
<h3 id="for문">for문</h3>
<ul>
<li>횟수가 정해진 반복에서 주로 사용</li>
</ul>
<pre><code class="language-js">num = 0;
for (let i = 1; i &lt;= 100; i++){
    num += i;
}

console.log(num); // 5050</code></pre>
<h3 id="반복문-흐름-제어--break--continue">반복문 흐름 제어 : break &amp; continue</h3>
<ul>
<li>break : 반복을 중단 시키고 반복문 탈출</li>
<li>continue : 반복을 건너뛰고 다음 반복 시작</li>
</ul>
<h3 id="while문">while문</h3>
<pre><code class="language-js">while(조건식){
    // 조건식이 참일때 반복되는 구간
    // 반복을 중단 시키는 코드가 존재해야 함 - break
}

while(true){
    const menu = prompt(&quot;choice&quot;);

    if (menu === &#39;q&#39;){
        console.log(&#39;중단..&#39;);
        break;
    }
}</code></pre>
<h3 id="do-while문">do-while문</h3>
<ul>
<li>무조건 한 번 실행 후에 조건식 비교</li>
</ul>
<pre><code class="language-js">do {
    // 조건식이 참일때 반복되는 구간
} while(조건식);

let i = 101, total = 0;

while(i &lt;= 100){
    total += i;
    i++;
}
console.log(`합계 : ${total}`); // 합계 : 0

let i = 101, total = 0;
do {
    total += i;
    i++;
} while(i &lt;= 100)
console.log(`합계 : ${total}`); // 합계 : 101

/*
    기본 while문은 최상단에서 조건을 체크 후에 코드를 실행하지만,
    do while문은 최하단에서 조건을 체크 하기 때문에 최소 1번은 실행 후에 조건에 따라서 반복을 진행하거나, 중지한다.
*/</code></pre>
<h2 id="예외-처리-try---catch---finally">예외 처리 (try - catch - finally)</h2>
<pre><code class="language-js">try {
    // 예외가 발생할 가능성이 있는 코드
} catch(err) {
    // 예외가 발생하면 유입되는 구간 - 대안적인 처리, err: 발생한 예외에 대한 정보
} finally{
    // 예외가 발생하거나, 안하거나 무조건 실행되는 코드
} 


try{
    let str;
    const str2 = str.uoUpperCase();
    console.log(str2, &quot;대문자로 변경 완료&quot;);
} catch (err){
    console.log(err);
}

// TypeError: Cannot read properties of undefined (reading &#39;uoUpperCase&#39;)
try {
    let str;
    const str2 = str.toUpperCase();
    console.log(str2, &quot;대문자료 변경 완료&quot;);
} catch(err){
    //console.dir(err);
    //console.error(err);
    console.log(err.message, err.name);
}</code></pre>
<ul>
<li>throw : 예외 발생 시킴 / throw new 예외 객체(Error의 하위 생성자 객체)</li>
</ul>
<pre><code class="language-js">// new 연산자
</code></pre>
<h1 id="4-3">4-3</h1>
<h2 id="자바스크립드-객체">자바스크립드 객체</h2>
<h3 id="객채-빈-객체-생성">객채, 빈 객체 생성</h3>
<pre><code class="language-js">obj = {
    key : value,
    key : value,
    ...
}

const person = {
    name : &#39;KIM&#39;,
    age : 31,
    study : function() {
        console.log(&#39;공부한다!&#39;)
    }
};

console.log(person)
// { name: &#39;KIM&#39;, age: 31, study: [Function: study] }</code></pre>
<h3 id="프로퍼티-읽기--수정">프로퍼티 읽기 &amp; 수정</h3>
<ul>
<li>마침표 연산자 : 속성의 이름이 변수 이름 규칙에 해당하는 속성만 접근 가능<ul>
<li>변수명 규칙<ul>
<li>알파벳(대소), 숫자, _ , $ 문자로만 구성해야함</li>
<li>숫자는 맨 앞자리 불가능</li>
<li>예약어(if, throw 등) 불가능</li>
</ul>
</li>
<li>변수명 관례<ul>
<li>여러 단어로 구성된 변수가 있는 경우 : 카멜 케이스 사용 ( noOfStudent )</li>
<li>여러 단어로 구성된 상수가 있는 경우 : 전체 대문자, 언더바 사용 NO_OF_STUDENT</li>
</ul>
</li>
<li>함수명 관례<ul>
<li>변수명 관례와 동일</li>
<li>함수 중 생성자로 사용되는 함수는 앞글자를 대문자로 씀 -&gt; OrderItem</li>
</ul>
</li>
</ul>
</li>
<li>대괄호 연산자 : 변수명 규칙에 해당하지 않는 속성 접근시에 사용</li>
<li>없는 프로퍼티 접근</li>
</ul>
<pre><code class="language-js">// 마침표 연산자로 속성 값 불러오기
console.log(person.age, person.name); // 31, KIM

// 마침표 연산자로 함수 호출하기
person.study(); // 공부한다!

// 대괄호 연산자로 속성 값 불러오기
console.log(person[&#39;age&#39;], person[&#39;name&#39;]) // 31, KIM

// 대괄호 연산자로 함수 호출하기
person[&#39;study&#39;](); // 공부한다!

// 존재하지 않는 속성 접근 통해서 신규 추가
person.address = &#39;주소&#39;;

// 존재하는 속성 접근 통해 정보 수정
person.address = &#39;(수정) 주소&#39;;

// 속성 제거
delete person.address;
// 속성이 정상적으로 제거 되면 true를 반환함</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.21 / Mon]]></title>
            <link>https://velog.io/@_bao_/26.9.21-Mon</link>
            <guid>https://velog.io/@_bao_/26.9.21-Mon</guid>
            <pubDate>Mon, 21 Sep 2026 06:51:19 GMT</pubDate>
            <description><![CDATA[<h1 id="4-1-javascript">4-1 JavaScript</h1>
<ul>
<li>인터프리터 언어 =&gt; JS 해석 엔진 존재</li>
<li>런타임<ul>
<li>웹브라우저(크롬) 기준 -&gt; V8</li>
<li>Node.js -&gt; v8</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/_bao_/post/1b2e07b6-5906-4de5-a701-1bff80e2c01a/image.png" alt=""></p>
<h3 id="nvm-node-version-manager">NVM (Node Version Manager)</h3>
<ul>
<li><a href="https://www.nvmnode.com/guide/download.html">https://www.nvmnode.com/guide/download.html</a> -&gt; 윈도우 최상위 버전 -&gt; nvm install 24</li>
<li>node : 자바스크립트 코드를 실행하는 runtime</li>
<li>npm : Node Package Manager<ul>
<li>외부 패키지 설치 시에 사용하는 명령어</li>
<li>Node.js 프로젝트 생성 / 실행</li>
</ul>
</li>
<li>npx : Node Package Excutor<ul>
<li>패키지의 명령어를 실행할 때 사용</li>
</ul>
</li>
</ul>
<h3 id="의존성-파일-설치">의존성 파일 설치</h3>
<ol>
<li>uv tool install --with jupyter jupyter-core</li>
<li>uv run --with jupyter npx tslab install</li>
<li>C:\Users\yonggyo\AppData\Local\Author Software\nvm\installs\v24.21.0\node_modules\tslab\bin\tslab -&gt; 경로 복사<ul>
<li>안보이면 숨긴 항목 체크</li>
</ul>
</li>
<li>C:\Users\yonggyo\AppData\Roaming\jupyter\kernels\jslab\kernel.json</li>
<li>C:\Users\yonggyo\AppData\Roaming\jupyter\kernels\tslab\kernel.json<ul>
<li>vscode에서 열기, argv -&gt; &quot;node&quot;, &quot;상단 경로&quot;, &quot;kernel&quot;, -&gt; 저장 후, vscode 재시작</li>
</ul>
</li>
</ol>
<h1 id="4-2-js-기초-문법">4-2 JS 기초 문법</h1>
<h3 id="주석">주석</h3>
<pre><code class="language-js"> // : 한 줄 주석

 /* 여러줄 주석 */ 

 /** 함수 주석
  *
  *
  */</code></pre>
<h3 id="변수-var">변수 var</h3>
<h4 id="var의-3가지-결함">var의 3가지 결함</h4>
<ul>
<li>호이스팅(Hoisting)</li>
<li>선원 키워드 생략 허용 (암묵적 전역 변수)<ul>
<li>선언자를 생략하고 변수를 지역변수로 설정</li>
</ul>
</li>
<li>함수 레벨 스코프 (Function-level Scope) -&gt; &quot;함수&quot;</li>
</ul>
<pre><code class="language-js">var i = 10000;
for (var i = 0; i &lt; 10; i++) {
  // 반복 로직
  console.log(&quot;for문에 정의된 i :&quot;, i);
}

console.log(i); // 10</code></pre>
<ul>
<li>변수 자체로 이해하는 것이 아닌 window 객체의 a로 값을 인식 ( 호이스팅 )<ul>
<li>변역 과정 -&gt; window 객체의 하위 속성으로 추가(웹브라우저 기준) / global 객체의 하위 속성으로 추가 (Node.js 환경)</li>
<li>window 객체는 창이 하나씩 열릴 때마다 하나씩 생성되며, 최상위 객체</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/_bao_/post/4a6fb54f-dcc2-401e-a681-10bb8dd9196b/image.png" alt=""></p>
<ul>
<li>호이스팅 : 정의한 변수, 함수가 최상위 객체에 할당되는 현상<ul>
<li>함수 정의 전에 window를 호출했으나, window 객체에 add 함수가 이미 포함되어 있음</li>
<li>아래쪽에 정의되어 있는 함수들도 최상위 객체인 window에 추가시켜야 하기 때문에 번역 과정을 거치며 최상단으로 올려 정의한다.</li>
<li>호이스팅으로 인해서 함수 정의 위치에 상관 없이 호출 가능해짐</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/_bao_/post/0a122530-4bf6-481b-a06c-c024ba5103eb/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_bao_/post/d2f228d3-92d7-4f8d-a55e-14827fc11c99/image.png" alt=""></p>
<h2 id="js-es6">JS ES6</h2>
<ul>
<li>변수 선언자<ul>
<li>let : 변수</li>
<li>const : 상수</li>
</ul>
</li>
<li>유효 범위 - block level</li>
<li>호이스팅 해결</li>
<li>중복 정의 문제 해결<br>

</li>
</ul>
<h3 id="호이스팅-문제-해결">호이스팅 문제 해결</h3>
<p><img src="https://velog.velcdn.com/images/_bao_/post/9e11f7fb-b115-4341-bc3f-facbba24e37e/image.png" alt=""></p>
<br>

<h3 id="유효-범위-지정">유효 범위 지정</h3>
<p><img src="https://velog.velcdn.com/images/_bao_/post/5ee1c059-c1b8-4c72-b0a1-f5c75b4bf74d/image.png" alt=""></p>
<hr>

<p><img src="https://velog.velcdn.com/images/_bao_/post/3914c70c-14a6-44c7-bd60-c363de79c9e6/image.png" alt=""></p>
<br>

<h3 id="let과-const-차이">let과 const 차이</h3>
<ul>
<li>JavaScript 에서는 변수를 선언할 때 const로 선언하고 변경이 필요한 경우만 let으로 변경
<img src="https://velog.velcdn.com/images/_bao_/post/829776e9-38c4-4d35-9095-636d3e30739e/image.png" alt=""></li>
</ul>
<h3 id="주요-데이터-타입">주요 데이터 타입</h3>
<ul>
<li>Number (숫자형) : 정수와 실수를 따로 구분하지 않고 모든 숫자 형식</li>
<li>String (문자열) : &#39;&#39;, &quot;&quot;로 감싼 텍스트</li>
<li>Boolean (불리언) : true, false</li>
<li>null : 값이 없는(비어 있는) 상태임을 표시하는 값</li>
<li>undefined : 정의되지 않음, 변수를 선언 후 값을 대입하지 않았을 때 기본값</li>
</ul>
<p><img src="https://velog.velcdn.com/images/_bao_/post/17e6deba-435c-4c81-8650-4bcf762b7f56/image.png" alt=""></p>
<h3 id="연산자-오버로드">연산자 오버로드</h3>
<ul>
<li>연산자의 기능을 새롭게 정의</li>
<li>( +, -, /, *, ...)</li>
</ul>
<pre><code class="language-js">// + 숫자
10 + 10 = 20

// + 문자열
a + b == ab
a + 1 == a1 // 문자열</code></pre>
<h4 id="문자열과-다른-타입을-로-결합시에-전체-문자열로-인식">문자열과 다른 타입을 +로 결합시에 전체 문자열로 인식</h4>
<p><img src="https://velog.velcdn.com/images/_bao_/post/c21f21d2-025d-495c-8189-8b4076c88ffc/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_bao_/post/c3e73436-4259-4775-90e0-5f7065ee5165/image.png" alt=""></p>
<h3 id="템플릿-리터럴--template-literals-">템플릿 리터럴 ( Template Literals )</h3>
<p><img src="https://velog.velcdn.com/images/_bao_/post/315bdaa0-5f16-40f7-9de1-dd8057ca9240/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_bao_/post/c0f27709-6be5-4225-ab05-0e64c97a3e5b/image.png" alt=""></p>
<h3 id="falsy-값으로-false를-자동-인식하는-6가지">Falsy (값으로 false를 자동 인식하는 6가지)</h3>
<ul>
<li>false (불리언 거짓)</li>
<li>0 (숫자 영)</li>
<li>&quot;&quot; (빈 문자열 - 문자 내부에 아무 글자도 적지 않은 상태)</li>
<li>null (값 없음)</li>
<li>undefined (정의되지 않은 값)</li>
<li>NaN (산술 불가 상태 - Not a Number)</li>
</ul>
<h1 id="llm">LLM</h1>
<pre><code class="language-python"># lib.py
import os
from dotenv import load_dotenv
from langchain.chat_models import init_chat_model

load_dotenv()

config = {
    &quot;model_provider&quot; : os.getenv(&quot;MODEL_PROVIDER&quot;),
    &quot;model&quot; : os.getenv(&quot;MODEL_NAME&quot;)
}

api_key = os.getenv(&quot;OPENAI_API_KEY&quot;)
if api_key:
    config[&#39;api_key&#39;] = api_key

def get_model(temperature = 0):
    config[&#39;temperature&#39;] = temperature

    return init_chat_model(**config)</code></pre>
<pre><code class="language-python"># model 불러오기
from lib import get_model, config

model = get_model()
print(config)</code></pre>
<pre><code class="language-python">from langchain_core.messages import HumanMessage

model.invoke([HumanMessage(&quot;안녕&quot;)])</code></pre>
<h3 id="runnable-인터페이스-구현">Runnable 인터페이스 구현</h3>
<ul>
<li><p>동기식</p>
<ul>
<li>invoke</li>
<li>stream</li>
<li>batch</li>
</ul>
</li>
<li><p>비동기식</p>
<ul>
<li>ainvoke</li>
<li>astream</li>
<li>abatch</li>
</ul>
</li>
<li><p>RunnableLambda =&gt; Runnable 객체로 래핑</p>
<ul>
<li>앞선 체인이 Runnable이면 뒤에 있는 함수는 자동적으로 Runnable로 변환
@chain -&gt; Runnable 객체로 래핑</li>
</ul>
</li>
</ul>
<pre><code class="language-python"># RunnableLambda

from langchain_core.runnables import RunnableLambda, chain

@chain
def func_a(message: str) -&gt; str:
    return f&quot;func_a:{message}&quot;

def func_b(message: str) -&gt; str:
    return f&quot;func_b:{message}&quot;


# func_a_runnable = RunnableLambda(func_a)
# func_b_runnable = RunnableLambda(func_b)

chain = func_a | func_b

chain.invoke(&#39;안녕하세요!&#39;)
# &#39;func_b:func_a:안녕하세요!&#39;</code></pre>
<pre><code class="language-python">import re
from langchain_core.messages import HumanMessage
from langchain_core.runnables import chain
from langchain_core.output_parsers import StrOutputParser
from lib import get_model

@chain
def protected_message(message : str) -&gt; list[HumanMessage] :
    pattern = re.compile(r&quot;(010)\D*(\d{4})\D*(\d{4})&quot;)

    message = pattern.sub(r&quot;\g&lt;1&gt;-****-****&quot;, message)
    return [HumanMessage(message)]

model = get_model()
parser = StrOutputParser()

chain = protected_message | model | parser

chain.invoke(&quot;나의 전화번호는 010-1000-1000이다.&quot;)

# &#39;입력하신 전화번호 형식은 &quot;010-****-****&quot;로, 대한민국의 일반 휴대폰 번호 형식과 일치합니다.  \n하지만 실제 개인정보 보호를 위해 숫자를 \&#39;*\&#39;로 가린 형태입니다.\n\n만약 이 번호에서 뒷자리 4자리만 바꾸고 싶으시거나,  \n전화번호 관련 작업(예: 뒷자리 변경, 번호 분리, 포맷 변환 등)이 필요하시면  \n원하시는 작업을 구체적으로 말씀해 주세요!  \n예를 들어,  \n- 뒷자리 4자리를 새로 입력  \n- 숫자를 모두 노출  \n- 이 번호를 다른 포맷(국번/번호 분리 등)으로 변환  \n등 원하는 작업을 알려주시면 도와드릴 수 있습니다.&#39;</code></pre>
<pre><code class="language-python">for chunk in chain.stream(&#39;나의 전화번호는 010-1000-1000이다. 당신의 번호는?&#39;):
    print(chunk, end=&quot;&quot;)

# 죄송합니다. 저는 실제로 전화번호를 저장하거나 받을 수 없습니다.  
# 만약 전화번호를 안전하게 보관하거나 복구를 위해 메모해 두신 거라면, 믿을 수 있는 저장소에 기록해 두시는 것이 좋습니다.

# 혹시 전화번호 관리 방법, 분실 시 대처법, 또는 다른 IT 관련 도움이 필요하시면 언제든 말씀해 주세요!</code></pre>
<pre><code class="language-python">messages = [
    &quot;나의 전화본호는 010-1000-1000입니다. 당신의 번호는?&quot;,
    &quot;안녕하세요!&quot;,
    &quot;반갑습니다.&quot;
]

for i, res in enumerate(chain.batch(messages)):
    print(i, res)

#     0 죄송합니다. 해당 문장은 일반적으로 상대방의 전화번호를 재차 확인하거나 농담으로 주고받는 상황에서 사용됩니다. 만약 상대방의 전화번호를 묻는 의도라면, 서로의 번호를 직접 말하거나 확인해야 합니다.

# 예시:
# - &quot;나의 전화번호는 010-****-****입니다. 당신의 번호는 무엇인가요?&quot;
# - 또는 농담이나 장난스럽게 &quot;당신의 번호는 010-1234-5678인가요?&quot;처럼 말할 수도 있습니다.

# 상황에 따라 답변을 조정해 주세요!
# 1 안녕하세요! 😊  
# 오늘도 좋은 하루 보내세요.  
# 무엇을 도와드릴까요?
# 2 반갑습니다! 무엇을 도와드릴까요? 😊</code></pre>
<pre><code class="language-python">async def async_messages():
    async for chunk in chain.astream(&quot;나의 전화번호는 010-1000-1000입니다. 당신의 번호는?&quot;):
        print(chunk, end=&quot;&quot;)

await async_messages()

# 죄송합니다. 저는 실제로 전화번호를 저장하거나 받을 수 없습니다.  
# 만약 전화번호를 안전하게 보관하거나 복구를 위해 메모해 두신 거라면, 다른 안전한 곳에 기록해 두시는 것을 추천드립니다.

# 혹시 전화번호 관리 방법, 분실 시 대처법, 또는 다른 IT 관련 도움이 필요하시면 언제든 말씀해 주세요!</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.18 / Fri]]></title>
            <link>https://velog.io/@_bao_/26.9.18-Fri</link>
            <guid>https://velog.io/@_bao_/26.9.18-Fri</guid>
            <pubDate>Fri, 18 Sep 2026 01:22:33 GMT</pubDate>
            <description><![CDATA[<h1 id="dq-review">DQ REVIEW</h1>
<ol>
<li>CSS 스타일 적용 방식 중 구조와 디자인의 완전한 분리로 재사용성 및 유지보수성을 극대화 할 수 있는 방식</li>
</ol>
<ul>
<li>외부 스타일 시트</li>
</ul>
<ol start="2">
<li>한 요소에 여러 CSS 규칙이 충돌할 때, 선택자가 더 구체적이고 좁은 범위를 타겟팅할수록 점수가 높게 산정되어 최우선 적용되는 규칙</li>
</ol>
<ul>
<li>명시도</li>
</ul>
<ol start="5">
<li>flexbox에서 확장 비율 나눠가지기</li>
</ol>
<ul>
<li>flex-grow : 여백을 할당 받는 비율 설정<ul>
<li>정확한 3등분 크기로 조정하기 위해서는 여백을 전체 크기로 조정하고 등분 (width: 0;)</li>
</ul>
</li>
</ul>
<h1 id="view-port">VIEW PORT</h1>
<ul>
<li>width<ul>
<li>device-width : 장비의 너비 기준</li>
<li>device-height : 장비의 가로모드 기준</li>
</ul>
</li>
<li>user-scalable<ul>
<li>yes : 확대, 축소 가능</li>
<li>no : 확대, 축소 불가</li>
</ul>
</li>
<li>minimum-scale : 축소 비율</li>
<li>maximum-scale : 확대 비율</li>
<li>initial-scale : 처음 화면 비율</li>
</ul>
<h3 id="break-point">break point</h3>
<ul>
<li>css 적용을 다르게 할 수 있음<ul>
<li>모바일 ( ~ 767px)</li>
<li>태블릿 ( 768 ~ 1023px )</li>
<li>데스크탑 ( 1024px ~ )</li>
</ul>
</li>
</ul>
<h3 id="미디어-쿼리--media--">미디어 쿼리 ( @media ... )</h3>
<ul>
<li>@media 미디어타입(장비종류) and 미디어 특성(브레이크 포인트 주로 지정) { css .... }</li>
</ul>
<h3 id="미디어-타입장비종류">미디어 타입(장비종류)</h3>
<ul>
<li>screen : 데스크탑 모니터, 태블릿, 스마트폰</li>
<li>print : 프린트에만 해당하는 css</li>
<li>speech : 시각장애인용 스크린 리더 css</li>
<li>all : 전체 ( 기본값 )</li>
</ul>
<h3 id="미디어-특성">미디어 특성</h3>
<ul>
<li>width : 특정 넓이, 높이에 도달했을때 css 적용</li>
<li>min-width : ~ 크기 이상</li>
<li>max-width : ~ 크기 이하</li>
<li>orientation : 기기의 방향<ul>
<li>portrait : 세로 방향</li>
<li>landscape : 가로 방향</li>
</ul>
</li>
</ul>
<pre><code class="language-html">&lt;style&gt;
  body {
    margin: 0;
  }
  * {
    box-sizing: border-box;
  }
  .box-group {
    display: grid;
    grid-template-columns: 1fr;
    padding: 20px;
    row-gap: 15px;
  }
  .box-group .box {
    background: skyblue;
    height: 250px;
    border-radius: 15px;
  }
  /* 태블릿 사이즈 브레이크 포인트 */
  @media screen and (min-width: 768px) and (max-width: 1023px) {
    .box-group {
      grid-template-columns: repeat(2, 1fr);
      column-gap: 15px;
    }
  }
  /* 데스크탑 사이즈 브레이크 포인트 */
  @media screen and (min-width: 1024px) {
    .box-group {
      grid-template-columns: repeat(3, 1fr);
      column-gap: 30px;
    }
  }
  /* 프린트시에만 적용되는 css */
  @media print {
    body {
      background: black;
    }
  }
&lt;/style&gt;
&lt;div class=&quot;box-group&quot;&gt;
  &lt;div class=&quot;box&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;box&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;box&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;box&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;box&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;box&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;box&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;box&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;box&quot;&gt;&lt;/div&gt;
&lt;/div&gt;</code></pre>
<h3 id="모바일-사이즈">모바일 사이즈</h3>
<p><img src="https://velog.velcdn.com/images/_bao_/post/a7606958-66ff-4017-befc-4f8d7dc765f8/image.png" alt=""></p>
<h3 id="태블릿-사이즈">태블릿 사이즈</h3>
<p><img src="https://velog.velcdn.com/images/_bao_/post/e07868ba-efaf-4b01-837b-974888180c42/image.png" alt=""></p>
<h3 id="데스크탑-사이즈">데스크탑 사이즈</h3>
<p><img src="https://velog.velcdn.com/images/_bao_/post/b093308b-05a0-4b06-93f8-97c0cbc3bef5/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.17 / Thu]]></title>
            <link>https://velog.io/@_bao_/26.9.17-Thu</link>
            <guid>https://velog.io/@_bao_/26.9.17-Thu</guid>
            <pubDate>Thu, 17 Sep 2026 08:14:34 GMT</pubDate>
            <description><![CDATA[<h1 id="dq-review">DQ REVIEW</h1>
<ul>
<li>HTML 문서에 CSS 적용하는 3가지 방식</li>
<li>인라인 스타일</li>
<li>내부 style 태그</li>
<li>외부 css 파일 연동 [ 주 사용 ]</li>
<li>부모 요소에 적용된 스타일 속성이 별도 선언 없이 자식 요소에게 물려 내려오는 현상</li>
<li>상속, cascading</li>
<li>css 명시도 가중치가 높은 순
태그 선택자 &lt; 클래스 선택자 &lt; 아이디 선택자 &lt; 인라인 스타일</li>
<li>콜론 두개 (::)를 사용하여 실제 존재하지 않는 가상의 요소를 css를 통해 동적으로 삽입하는 문법<ul>
<li>가상 요소</li>
</ul>
</li>
</ul>
<h1 id="css">CSS</h1>
<h2 id="flex-direction">flex-direction</h2>
<pre><code class="language-html">&lt;style&gt;
  body {
    margin: 0;
    padding: 10%;
  }
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
    border: 1px solid #000;
    color: white;
  }
  li:nth-of-type(1) {
    background: red;
  }
  li:nth-of-type(2) {
    background: blue;
  }
  li:nth-of-type(3) {
    background: gray;
  }
  .flex1 {
    display: flex;
  }
  .flex2 {
    display: flex;
    flex-direction: row-reverse;
  }
  .flex3 {
    display: flex;
    flex-direction: column;
  }
  .flex4 {
    display: flex;
    flex-direction: column-reverse;
  }
&lt;/style&gt;

&lt;h3&gt;flex-direction : row ( 좌 -&gt; 우 )&lt;/h3&gt;
&lt;ul class=&quot;flex1&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;flex-direction : row-reverse ( 우 -&gt; 좌 )&lt;/h3&gt;
&lt;ul class=&quot;flex2&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;flex-direction : column ( 상 -&gt; 하 )&lt;/h3&gt;
&lt;ul class=&quot;flex3&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;flex-direction : column-reverse ( 하 -&gt; 상 )&lt;/h3&gt;
&lt;ul class=&quot;flex4&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<p><br><br></p>
<h2 id="justify-content">justify-content</h2>
<pre><code class="language-html">&lt;style&gt;
  body {
    margin: 0;
    padding: 0 10%;
  }
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
    border: 1px solid #000;
  }
  li {
    min-width: 100px;
    min-height: 100px;
  }

  li:nth-of-type(1) {
    background: red;
  }
  li:nth-of-type(2) {
    background: blue;
  }
  li:nth-of-type(3) {
    background: gray;
  }

  .flex1 {
    display: flex;
    justify-content: flex-start;
  }
  .flex2 {
    display: flex;
    justify-content: flex-end;
  }
  .flex3 {
    display: flex;
    justify-content: center;
  }
&lt;/style&gt;

&lt;h3&gt;justify-content: flex-start(기본값)&lt;/h3&gt;
&lt;ul class=&quot;flex1&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;justify-content: flex-end&lt;/h3&gt;
&lt;ul class=&quot;flex2&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;justify-content: center&lt;/h3&gt;
&lt;ul class=&quot;flex3&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<p><br><br></p>
<pre><code class="language-html">&lt;style&gt;
  body {
    margin: 0;
    padding: 0 10%;
  }
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
    border: 1px solid #000;
  }
  li {
    min-width: 100px;
    min-height: 100px;
  }
  li:nth-of-type(1) {
    background: red;
  }
  li:nth-of-type(2) {
    background: blue;
  }
  li:nth-of-type(3) {
    background: gray;
  }
  .flex1 {
    display: flex;
    justify-content: space-between;
  }
  .flex2 {
    display: flex;
    justify-content: space-around;
  }
  .flex3 {
    display: flex;
    justify-content: space-evenly;
  }
&lt;/style&gt;

&lt;h3&gt;justify-content: space-between&lt;/h3&gt;
&lt;ul class=&quot;flex1&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;justify-content: space-around&lt;/h3&gt;
&lt;ul class=&quot;flex2&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;justify-content: space-evenly&lt;/h3&gt;
&lt;ul class=&quot;flex3&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<p><br><br></p>
<h2 id="align-items--요소의-배치">align-items : 요소의 배치</h2>
<pre><code class="language-html">&lt;style&gt;
  body {
    margin: 0;
    padding: 10%;
  }
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
    border: 1px solid #000;
    color: white;
    height: 100px;
  }
  li {
    min-width: 100px;
  }
  li:nth-of-type(1) {
    background: red;
  }
  li:nth-of-type(2) {
    background: blue;
  }
  li:nth-of-type(3) {
    background: gray;
  }
  .flex1 {
    display: flex;
    align-items: stretch;
  }
  .flex2 {
    display: flex;
    align-items: flex-start;
  }
  .flex3 {
    display: flex;
    align-items: flex-end;
  }
  .flex4 {
    display: flex;
    align-items: center;
  }
&lt;/style&gt;

&lt;h3&gt;align-items : strecth (기본값)&lt;/h3&gt;
&lt;ul class=&quot;flex1&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;align-items : flex-start&lt;/h3&gt;
&lt;ul class=&quot;flex2&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;align-items : flex-end&lt;/h3&gt;
&lt;ul class=&quot;flex3&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;align-items : center&lt;/h3&gt;
&lt;ul class=&quot;flex4&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<h2 id="flex-grow">flex-grow</h2>
<ol>
<li>자식 요소 적용</li>
<li>남아 있는 공백을 차지할 비율 설정</li>
<li>값을 지정하는 만큼 비율에서 가져감</li>
<li>요소 크기에 대한 등분이 아닌, 남아있는 공백에 대한 구분이기 때문에, 요소의 길이가 다르면 지정되는 크기가 달라짐</li>
</ol>
<pre><code class="language-html">&lt;style&gt;
  body {
    margin: 0;
    padding: 10%;
  }
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
    border: 1px solid #000;
    color: white;
    height: 100px;
  }
  li {
    min-width: 100px;
  }

  li:nth-of-type(1) {
    background: red;
    flex-grow: 1;
  }
  li:nth-of-type(2) {
    background: blue;
    flex-grow: 1;
  }
  li:nth-of-type(3) {
    background: gray;
    flex-grow: 1;
  }

  .flex1 {
    display: flex;
    align-items: stretch;
  }
&lt;/style&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;ul class=&quot;flex1&quot;&gt;
  &lt;li&gt;메뉴1&lt;/li&gt;
  &lt;li&gt;메뉴2&lt;/li&gt;
  &lt;li&gt;메뉴3&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<h3 id="1--0--0">1 : 0 : 0</h3>
<h3 id="1--1--0">1 : 1 : 0</h3>
<h3 id="1--1--1">1 : 1 : 1</h3>
<h3 id="1--1--1---요소의-길이에-따라-총-길이가-달라짐">1 : 1 : 1 - 요소의 길이에 따라 총 길이가 달라짐</h3>
<h2 id="flex-shrink">flex-shrink</h2>
<ul>
<li>부모 요소의 공간이 부족할 때 자식 요소의 크기 줄임 비율</li>
<li>비율 가중치</li>
<li>0 : 요소를 축소 하지 않음</li>
<li>flex-basis : 요소의 기본사이즈 ( auto : 기본값 )</li>
</ul>
<h2 id="flex-wrap">flex-wrap</h2>
<ul>
<li>wrap : 부모 요소의 너비가 부족하면 다음칸에 개행</li>
<li>nowrap (기본값) - 개행 X</li>
</ul>
<h1 id="grid--2차원-격자-레이아웃">Grid : 2차원 격자 레이아웃</h1>
<ul>
<li>grid-template-columns<ul>
<li>px : 고정된 크기<ul>
<li>150px 150px 300px; -&gt; column 3개</li>
</ul>
</li>
<li>fr : 남은 공간에 대한 비율<ul>
<li>150px 1fr 2fr; -&gt; 첫번째 150px, 두번째 1/3 비율, 세번째 2/3 비율</li>
</ul>
</li>
<li>repeat(컬럼 갯수, 사이즈) -&gt; 같은 사이즈의 지정된 컬럼 갯수 만큼 설정</li>
</ul>
</li>
<li>grid-template-rows</li>
</ul>
<pre><code class="language-html">&lt;style&gt;
  .box1 {
    display: grid;
    /* grid-template-columns: 150px 150px 300px; */
    grid-template-columns: 150px 1fr 2fr;
  }
  .card {
    background-color: skyblue;
    height: 100px;
  }
&lt;/style&gt;

&lt;div class=&quot;box1&quot;&gt;
  &lt;div class=&quot;card&quot;&gt;A&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;B&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;C&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;D&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;E&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;F&lt;/div&gt;
&lt;/div&gt;</code></pre>
<h4 id="px">px</h4>
<h4 id="fr">fr</h4>
<h4 id="repeat3-1fr">repeat(3, 1fr)</h4>
<h3 id="gap">gap</h3>
<ul>
<li>row-gqp : 행별 여백</li>
<li>column-gap : 열별 여백<hr></li>
<li>gap : 20px 10px; -&gt; row column</li>
<li>gap : 30px; -&gt; row + column</li>
</ul>
<pre><code class="language-html">&lt;style&gt;
  .box1 {
    width: 500px;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    font-size: 1.5rem;
    /* row-gap: 20px;
      column-gap: 10px; */
    gap: 20px 10px;
  }
  .card {
    background-color: skyblue;
    height: 100px;
  }
&lt;/style&gt;
&lt;div class=&quot;box1&quot;&gt;
  &lt;div class=&quot;card&quot;&gt;A&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;B&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;C&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;D&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;E&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;F&lt;/div&gt;
&lt;/div&gt;</code></pre>
<h3 id="grid-column">grid-column</h3>
<ul>
<li>grid-column : 1 / 3; 1번열 부터 ~ 3번열까지</li>
<li>grid-column : span 2; -&gt; 열 2칸 차지</li>
</ul>
<h3 id="grid-row">grid-row</h3>
<ul>
<li>grid-row : 1/3</li>
<li>grid-row: span 2; -&gt; 2개 행 차지</li>
</ul>
<pre><code class="language-html">&lt;style&gt;
  .box {
    display: grid;
    background: #ccc;
    grid-template-columns: repeat(3, 1fr);
    width: 600px;
    padding: 30px;
    gap: 15px;
  }
  .area {
    height: 100px;
    background: skyblue;
  }
  .area:nth-of-type(1) {
    grid-column: span 2;
  }
  .area:nth-of-type(2) {
    height: 100%;
    grid-row: span 2;
  }
&lt;/style&gt;
&lt;div class=&quot;box&quot;&gt;
  &lt;div class=&quot;area&quot;&gt;영역1&lt;/div&gt;
  &lt;div class=&quot;area&quot;&gt;영역2&lt;/div&gt;
  &lt;div class=&quot;area&quot;&gt;영역3&lt;/div&gt;
  &lt;div class=&quot;area&quot;&gt;영역4&lt;/div&gt;
&lt;/div&gt;</code></pre>
<h3 id="place_items">place_items</h3>
<ul>
<li>streatch( 기본값 )</li>
<li>start ( 왼쪽 상단 )</li>
<li>end ( 오른쪽 하단 )</li>
<li>center ( 정가운데 )</li>
</ul>
<pre><code class="language-html">&lt;style&gt;
  .box1 {
    width: 500px;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    font-size: 1.5rem;
    gap: 20px 10px;
    place-items: center;
    background-color: skyblue;
  }
  .card {
    height: 100px;
  }
  .card span {
    border: 3px solid black;
    /* background: red; */
    color: black;
  }
&lt;/style&gt;

&lt;div class=&quot;box1&quot;&gt;
  &lt;div class=&quot;card&quot;&gt;&lt;span&gt;A&lt;/span&gt;&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;&lt;span&gt;B&lt;/span&gt;&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;&lt;span&gt;C&lt;/span&gt;&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;&lt;span&gt;D&lt;/span&gt;&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;&lt;span&gt;E&lt;/span&gt;&lt;/div&gt;
  &lt;div class=&quot;card&quot;&gt;&lt;span&gt;F&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;</code></pre>
<h4 id="palce_items--start">palce_items : start</h4>
<h4 id="palce_items--end">palce_items : end</h4>
<h4 id="palce_items--center">palce_items : center</h4>
<h2 id="폰트">폰트</h2>
<ul>
<li>color : 글 색상 ( 색상명, hexcode, rgb(), rgba())</li>
<li>font-size : 글 크기 - 절대 크기, 상대크기 (em, rem)</li>
<li>line-height : 행간 [ 기본값 1.2 ] -&gt; 글자 높이 1, 20% 여백을 10 상단 / 10 하단으로 할당<ul>
<li>비율 : 1.5 &lt;- 권장 사항 | % : 150% | px | em | rem</li>
</ul>
</li>
<li>letter-spacing : 자간</li>
<li>word-spacing : 단어 사이 간격</li>
<li>word-break : wrap / nowrap / break-all</li>
<li>font-weight : 폰트 두께 지정<ul>
<li>normal ( 기본값 ) - 400</li>
<li>bold ( 두껍게 ) - 700</li>
<li>100 ~ 900 : 얇음 ~ 두꺼움 ==&gt; 폰트 별로 지원하는 두께가 다름. ( 확인 필요 )</li>
</ul>
</li>
<li>text-align<ul>
<li>인라인 요소에 대한 정렬 -&gt; 상위 블록 영역에서 지정해주어야 한다.</li>
<li>left ( 기본값 ) : 왼쪽 정렬</li>
<li>right : 오른쪽 정렬</li>
<li>center : 가운데 정렬</li>
<li>justify : 양쪽 정렬</li>
</ul>
</li>
<li>font-style :<ul>
<li>normal ( 기본값 )</li>
<li>italic 기울임체</li>
</ul>
</li>
<li>text-decoration<ul>
<li>-underline : 밑줄</li>
<li>line-through : 취소선</li>
<li>none : 기본값</li>
</ul>
</li>
<li>font-family : 글꼴<ul>
<li>font-family : &quot;폰트명&quot;, &quot;대체폰트1&quot;, &quot;대체폰트2&quot;<ul>
<li>ex) font-family:&#39;Malgun Gothic&#39;, &#39;Apple Gothic&#39;, &#39;sans-serif&#39;;</li>
</ul>
</li>
<li>시스템 폰트 : OS 내에 설치되어 있는 폰트</li>
<li>웹 폰트 : OS에 설치 상관 없이 동일하게 공유 가능한 폰트</li>
</ul>
</li>
</ul>
<pre><code class="language-html">&lt;!-- 원격 서버 폰트 로딩 --&gt;
&lt;style&gt;
  @import url(&quot;https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..90display=swap&quot;) * {
    font-family: &quot;Noto Sans KR&quot;, sans-serif;
    font-size: 25px;
  }
  .w-100 {
    font-weight: 100;
  }
  .w-200 {
    font-weight: 200;
  }
  .w-300 {
    font-weight: 300;
  }
  .w-400 {
    font-weight: 400;
  }
  .w-500 {
    font-weight: 500;
  }
  .w-600 {
    font-weight: 600;
  }
  .w-700 {
    font-weight: 700;
  }
  .w-800 {
    font-weight: 800;
  }
  .w-900 {
    font-weight: 900;
  }
&lt;/style&gt;

&lt;div class=&quot;w-100&quot;&gt;가나다라&lt;/div&gt;
&lt;div class=&quot;w-200&quot;&gt;가나다라&lt;/div&gt;
&lt;div class=&quot;w-300&quot;&gt;가나다라&lt;/div&gt;
&lt;div class=&quot;w-400&quot;&gt;가나다라&lt;/div&gt;
&lt;div class=&quot;w-500&quot;&gt;가나다라&lt;/div&gt;
&lt;div class=&quot;w-600&quot;&gt;가나다라&lt;/div&gt;
&lt;div class=&quot;w-700&quot;&gt;가나다라&lt;/div&gt;
&lt;div class=&quot;w-800&quot;&gt;가나다라&lt;/div&gt;
&lt;div class=&quot;w-900&quot;&gt;가나다라&lt;/div&gt;</code></pre>
<pre><code class="language-html">&lt;!-- 로컬 폰트 로드 --&gt;
&lt;style&gt;
  /* @import url(&#39;https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100.900display=swap&#39;); */
  @font-face {
    font-family: &quot;NotoFont&quot;;
    src: url(&quot;../01/font/NotoSansKR-Regular.ttf&quot;) format(&quot;truetype&quot;);
    font-weight: 400;
    font-style: normal;
    font-display: swap; /* 폰트 로딩 전에 기본 폰트로 적용, 로딩 끝나면 해당 폰트로 적용 */
  }
  * {
    /* font-family: &quot;Noto Sans KR&quot;, sans-serif; */
    font-family: &quot;NotoFont&quot;, &quot;sans-serif&quot;;
    font-size: 25px;
  }
&lt;/style&gt;</code></pre>
<h1 id="overflow">OVERFLOW</h1>
<ul>
<li>visible ( 기본값 ) -&gt; 넘치는 컨텐츠가 있어도 보이기</li>
<li>hidden -&gt; 넘치는 컨텐츠 숨기기</li>
<li>scroll -&gt; 넘치는 컨텐츠 존재 시에 스크롤바 노출</li>
<li>auto -&gt; 넘치는 컨텐츠 존재 시에 스크롤바 노출, 없으면 미노출</li>
</ul>
<h3 id="visible">visible</h3>
<h3 id="hidden">hidden</h3>
<h3 id="scroll">scroll</h3>
<h1 id="border--경계선">border : 경계선</h1>
<ul>
<li>border-width: 두께</li>
<li>border-style : none ( 기본값 )<ul>
<li>solid : 실선</li>
<li>dashed : 파선</li>
<li>dotted : 점선</li>
<li>double : 이중 실선</li>
</ul>
</li>
<li>border-color : 색상</li>
<li>단축 표현법 -&gt; border : 두꼐 스타일 색상;<ul>
<li>border : 1px solid black;</li>
</ul>
</li>
<li>border-radius : 모서리 둥글게 만듬<ul>
<li>border-top-left-radius : 좌측 상단 모서리 </li>
<li>border-top-right-radius : 우측 상단 모서리</li>
<li>border-bottom-left-radius : 좌측 하단 모서리</li>
<li>border-bottom-right-radius : 우측 하단 모서리</li>
</ul>
</li>
</ul>
<pre><code class="language-html">&lt;style&gt;
    .border {
      width: 250px;
      height: 250px;
      margin: 20px;
      border: 5px solid blue;
    }
    .border1 {
      /* border-radius: 25px; 원의 반지름 길이 */
      border-top-left-radius: 50px;
      border-bottom-right-radius: 50px;
    }
    .border2 {
      border-style: dashed;
    }
    .border3 {
      border-style: dotted;
    }
    .border4 {
      border-style: double;
    }
    .border5 {
      border-left : 0;
      border-right: 0;
    }
    .border6{
        border-radius: 50%;
    }
&lt;/style&gt;

&lt;div class=&quot;border border1&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;border border2&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;border border3&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;border border4&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;border border5&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;border border6&quot;&gt;&lt;/div&gt;</code></pre>
<h3 id="solid">solid</h3>
<h3 id="dashed">dashed</h3>
<h3 id="dotted">dotted</h3>
<h3 id="double">double</h3>
<h3 id="좌우선-제거">좌우선 제거</h3>
<h3 id="radius">radius</h3>
<h3 id="부분-radius">부분 radius</h3>
<h3 id="부분-radius-1">부분 radius</h3>
<h1 id="background">background</h1>
<ul>
<li>background-color : 배경색</li>
<li>background-image : 배경 이미지 url(&#39;이미지 경로&#39;)</li>
<li>background-repeat<ul>
<li>repeat ( 기본값 ) : x,y축 모두 반복</li>
<li>repeat-x : x축 반복</li>
<li>repeat-y : y축 반복</li>
<li>no-repeat : 하나만 출력</li>
</ul>
</li>
<li>background-position : 배경 이미지 위치 설정<ul>
<li>background-position ; 100px 50px;<ul>
<li>좌 -&gt; 우 100px 이동</li>
<li>상 -&gt; 하 50px 이동</li>
</ul>
</li>
</ul>
</li>
<li>background-size <ul>
<li>background-size : 200px 100px =&gt; 가로, 세로</li>
<li>cover : 영역 모두 채우기<ul>
<li>이미지의 비율이 배경 요소와 차이가 있다면 일부는 짤림</li>
</ul>
</li>
<li>contain -&gt; 이미지가 모두 보일수 있도록 채움</li>
</ul>
</li>
<li>background-attachment<ul>
<li>fixed -&gt; scroll해도 배경 이미지 고정</li>
<li>scroll -&gt; scroll시 배경 이미지도 함께 스크롤</li>
</ul>
</li>
<li>단축 표기법<ul>
<li>background: 색상 이미지 반복 고정 위치 사이즈<ul>
<li>색상, 이미지 중 하나는 필수 나머지는 선택 옵션</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="position">position</h1>
<ul>
<li>static (기본값) : 요소의 위치는 고정 - 절대 위치</li>
<li>상대 위치 <ul>
<li>relative : 속성이 정의 되어 있는 요소</li>
<li>absolute : 문서 전체 기준<ul>
<li>부모가 상대 속성 (relative, absolute, fixed)이면 부모가 기준점</li>
</ul>
</li>
<li>fixed : view port 기준 [ view port : 현재 보이는 화면 ]<ul>
<li>층위 설정 가능 : Z - index : 값이 높을수록 앞쪽 배치, 값이 낮을수록 뒤쪽 배치</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code class="language-html">&lt;style&gt;
    .box{
        width: 300px;
        height: 300px;
        position: absolute;
        left: 0;
        top: 0;
    }

    .box1{
        background: red;
        z-index: 3;
    }

    .box2 {
        background: green;
        z-index: 2;
        left:50px;
    }

    .box3 {
        background: blue;
        z-index: 1;
        left:100px;
    }
&lt;/style&gt;
&lt;div class=&quot;box box1&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;box box2&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;box box3&quot;&gt;&lt;/div&gt;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.16 / Wed]]></title>
            <link>https://velog.io/@_bao_/26.9.16-Wed-328grwkz</link>
            <guid>https://velog.io/@_bao_/26.9.16-Wed-328grwkz</guid>
            <pubDate>Wed, 16 Sep 2026 06:52:37 GMT</pubDate>
            <description><![CDATA[<h1 id="2-1">2-1</h1>
<h3 id="복합-관계-선택자">복합 관계 선택자</h3>
<ul>
<li>일반 형제 선택자 ( 형 ~ 동생 )<ul>
<li>형 기준으로 뒤에 오는 모든 요소</li>
</ul>
</li>
<li>인접 형제 선택자 ( 형 + 동생 )<ul>
<li>형 기준 바로 옆 동생 선택</li>
</ul>
</li>
<li>그룹 선택자 (, )</li>
</ul>
<pre><code class="language-html">    &lt;style&gt;
        a, p, .greeting{
            color: green;
        }
        span.greeting{
            color: orange
        }
        input[type]{
            border:3px;
        }
    &lt;/style&gt;
    &lt;a href=&quot;#&quot;&gt;네이버&lt;/a&gt;
    &lt;p&gt;단락&lt;/p&gt;
    &lt;div class=&quot;greeting&quot;&gt;안녕하세요.&lt;/div&gt;
    &lt;span class=&quot;greeting&quot;&gt;반갑습니다.&lt;/span</code></pre>
<h4 id="속성-선택자">속성 선택자</h4>
<ul>
<li>[속성명] : 지정된 속성이 존재하면 선택<ul>
<li>다른 선택자와 조합을 통한 선택 주로 사용</li>
<li>선택자[속성명]</li>
</ul>
</li>
<li>[속성명 = &quot;값&quot;] : 속성의 값이 일치하는 요소 선택</li>
<li>[속성명^ = &quot;값&quot;] : 속성의 값으로 시작하는 요소 선택</li>
<li>[속성명$ = &quot;값&quot;] : 속성의 값으로 끝나는 요소 선택</li>
<li>[속성명* = &quot;값&quot;] : 속성의 값이 포함되어 있는 요소 선택</li>
</ul>
<pre><code class="language-html">&lt;style&gt;
  /* 그룹 선택자 */
  a,
  p,
  .greeting {
    color: green;
  }
  span.greeting {
    color: orange;
  }
  /* 속성 선택자 : 속성명*/
  input[type] {
    border: 3px solid red;
  }
  /* 속성 선택자 : 속성값 */
  input[type=&quot;number&quot;] {
    border-color: blue;
  }
  a[href^=&quot;tel&quot;] {
    background: gray;
  }
  a[href$=&quot;com&quot;] {
    background: olive;
  }
  a[href$=&quot;.net&quot;] {
    background: yellow;
  }
&lt;/style&gt;
&lt;a href=&quot;https://www.naver.com&quot;&gt;네이버&lt;/a&gt;
&lt;a href=&quot;https://daum.net&quot;&gt;다음&lt;/a&gt;
&lt;a href=&quot;tel:010-1000-1000&quot;&gt;전화 걸기&lt;/a&gt;
&lt;p&gt;단락&lt;/p&gt;
&lt;div class=&quot;greeting&quot;&gt;안녕하세요.&lt;/div&gt;
&lt;span class=&quot;greeting&quot;&gt;반갑습니다.&lt;/span&gt;

&lt;hr /&gt;
&lt;input type=&quot;text&quot; /&gt;
&lt;input type=&quot;number&quot; /&gt;</code></pre>
<h4 id="가상-클래스-선택자">가상 클래스 선택자</h4>
<ul>
<li><p>선택자 : 상태, 조건, 위치</p>
</li>
<li><p>가상 클래스 : 위치</p>
<ul>
<li>자식 요소는 타입이 달라도 선택 가능<ul>
<li>:first-child = 첫번째 자식 요소</li>
<li>:last-child = 마지막 자식 요소</li>
<li>:nth-child(숫자) = 숫자 위치에 있는 요소 선택</li>
<li>:nth-child(수식) = 수식에 해당하는 요소 선택</li>
</ul>
</li>
<li>같은 타입들만 선택<ul>
<li>:first-of-type</li>
<li>:last-of-type</li>
<li>:nth-of-type</li>
<li>:only-of-type : 하위 요소가 한 개만 있는 경우</li>
</ul>
</li>
</ul>
</li>
<li><p>조건 선택자</p>
<ul>
<li>not(선택자) : 선택자<ul>
<li>지정된 선택자가 아닌 요소 선택</li>
</ul>
</li>
<li>is(선택자1, 선택자2, ...) 자식요소<ul>
<li>상위 요소 그룹 -&gt; 하위 요소를 선택</li>
</ul>
</li>
</ul>
</li>
<li><p>상태 선택자</p>
<ul>
<li>:hover = 마우스가 요소 위에 올라간 상태</li>
<li>:focus = 특정 요소가 선택 되는 경우, 커서가 있는 상태</li>
<li>:blur = 특정 요소가 선택 된 후, 커서가 없어지는 상태</li>
<li>:checked = 체크 된 상태</li>
<li>:read-only = 읽기 전용 상태</li>
<li>:disabled = 비활성 상태 &lt;-&gt; :enabled</li>
</ul>
</li>
</ul>
<pre><code class="language-html">&lt;style&gt;
        .box {
            width: 150px;
            height: 150px;
            background: orange;
            transition: all 0.5s;
        }
        .box:hover {
            width: 300px;
            height: 300px;
            rotate: 270deg; 
        }

        .text:focus {
            background: yellow;
        }
        .tab-group{
            width:400px;
            display:flex;
            align-items: center;
        }
        .tab-group input[type=&#39;radio&#39;] {
            display:none;
        }

        .tab-group label{
            border: 1px solid #ccc;
            padding: 20px 15px;
            margin: 0 5px;
        }
        .tab-group input[type=&#39;radio&#39;]:checked + label {
            border-color:black;
            background: black;
            color:white;
        }
    &lt;/style&gt;
    &lt;div class=&quot;box&quot;&gt;&lt;/div&gt;
    &lt;input type=&quot;text&quot; class=&quot;text&quot;&gt;
    &lt;br&gt;
    &lt;br&gt;
    &lt;br&gt;
    &lt;div class=&quot;tab-group&quot;&gt;
        &lt;input type=&quot;radio&quot; name=&quot;tab&quot; value=&quot;menu1&quot; id=&quot;tab-1&quot;&gt;
        &lt;label for=&quot;tab-1&quot;&gt;메뉴1&lt;/label&gt;
        &lt;input type=&quot;radio&quot; name=&quot;tab&quot; value=&quot;menu2&quot; id=&quot;tab-2&quot;&gt;
        &lt;label for=&quot;tab-2&quot;&gt;메뉴2&lt;/label&gt;
        &lt;input type=&quot;radio&quot; name=&quot;tab&quot; value=&quot;menu3&quot; id=&quot;tab-3&quot;&gt;
        &lt;label for=&quot;tab-3&quot;&gt;메뉴3&lt;/label&gt;
    &lt;/div&gt;</code></pre>
<h4 id="요소-추가-선택자">요소 추가 선택자</h4>
<ul>
<li>선택자::___<ul>
<li>::before = 자식의 첫번째 요소로 추가</li>
<li>::after = 자식의 마지막 요소로 추가<ul>
<li>반드시 추가할 내용이 있어야 노출 됨 / CONTENT 필수</li>
<li>inline 속성</li>
</ul>
</li>
<li>::placeholder : 가이드라인 텍스트</li>
<li>::selection : 선택된 영역</li>
</ul>
</li>
</ul>
<pre><code class="language-html">&lt;style&gt;
        ul::before{
            content: &#39;첫번째&#39;;
        }
        ul::after{
            content: &#39;마지막&#39;;
        }
        /* 기본값 색상 변경 */
        textarea::placeholder{
            color:red;
        }
        /* 드래그 색상 변경 */
        .text::selection{
            background:yellow;
        }
    &lt;/style&gt;
    &lt;ul&gt;
        &lt;li&gt;메뉴1&lt;/li&gt;
        &lt;li&gt;메뉴2&lt;/li&gt;
        &lt;li&gt;메뉴3&lt;/li&gt;
    &lt;/ul&gt;

    &lt;textarea placeholder=&quot;자기소개를 입력하세요...&quot; rows=&quot;5&quot; cols=&quot;50&quot;&gt;&lt;/textarea&gt;
    &lt;div class=&quot;text&quot;&gt;
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus sit vitae iste esse, id ad nostrum placeat, porro voluptates, iure et officia consequuntur? Consectetur optio saepe dolore, reiciendis perferendis ipsum?
    &lt;/div&gt;</code></pre>
<h3 id="css-속성">CSS 속성</h3>
<ul>
<li>텍스트 및 폰트 속성<ul>
<li>color : 폰트 색상<ul>
<li>색상명, rgb(255,255,255), Hexcode, rgba(255,255,255,0~1)</li>
</ul>
</li>
<li>font-size : 폰트 크기 조정<ul>
<li>절대 크기<ul>
<li>px, pt(인쇄 기준), </li>
</ul>
</li>
<li>상대 크기<ul>
<li>em  : 폰트 사이즈가 지정된 상위 태그</li>
<li>rem : 가장 상위 태그의 글자 사이즈가 기준, html 태그에 설정된 px</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code class="language-html">
&lt;style&gt;
    .text1{
        /* rgb함수, 헥사코드 */
        /* color: rgb(255, 0, 0); */
        /* color: #ff0000 */
        color : #f00;
    }
&lt;/style&gt;
&lt;div class=&quot;text1&quot;&gt;abc&lt;/div&gt;</code></pre>
<pre><code class="language-html">&lt;!-- em, rem --&gt;
&lt;style&gt;
    html{
        font-size:30px; /* 1rem = 13px*/
    }
    .text1 {
        font-size: 1rem;
    }
    .text2 {
        font-size: 2rem;
    }
    .text3 {
        font-size: 3rem;
    }
    .text-group{
        font-size: 20px; /* 20px -&gt; 1em */ 
    }
    .text4 {
        font-size: 1em;
    }
    .text5{
        font-size: 2em; /* 40px */
    }
&lt;/style&gt;
&lt;div class=&quot;text1&quot;&gt;ABC&lt;/div&gt;
&lt;div class=&quot;text2&quot;&gt;DEF&lt;/div&gt;
&lt;div class=&quot;text3&quot;&gt;GHI&lt;/div&gt;

&lt;div class=&quot;text-group&quot;&gt;
    &lt;div class=&quot;text4&quot;&gt;가나다&lt;/div&gt;
    &lt;div class=&quot;text5&quot;&gt;라마바&lt;/div&gt;
&lt;/div&gt;</code></pre>
<h3 id="css-박스-모델">CSS 박스 모델</h3>
<ul>
<li><p>content : 내용이 존재하는 위치</p>
<ul>
<li>기본 설정으로 너비와 높이의 기준 (width, height)</li>
<li>실질적인 박스 모델의 사이즈는 content + padding + border</li>
</ul>
</li>
<li><p>padding : 내부 여백, border 안쪽</p>
</li>
<li><p>border : 외곽선</p>
</li>
<li><p>margin : 외부 여백, border 바깥쪽</p>
</li>
<li><p>box-sizing 속성을 사용하여 너비와 높이의 기준</p>
<ul>
<li>content-box ( default ) : 내용 영역(content) 기준</li>
<li>border-box : 외곽선 기준, 외곽선을 기준으로 박스 모델의 사이즈를 지정하기 때문에, padding의 사이즈가 변하거나, border의 사이즈가 변하면 내용 영역의 사이즈도 변한다.</li>
</ul>
</li>
</ul>
<h3 id="외부-여백--margin-">외부 여백 ( margin )</h3>
<ul>
<li><p>block 속성 태그 : 제한 X ( 상하좌우 가능 )</p>
<ul>
<li>여백 중첩시의 더 높은 값의 여백만 적용</li>
<li>margin : 100px auto; =&gt; 상하 100px, 좌우는 균등하게 분배함</li>
</ul>
</li>
<li><p>inline 속성 태그 : 제한 O ( 좌우 만 가능 )</p>
</li>
<li><p>margin 옵션 개수 차이</p>
<ul>
<li>1 : 전체</li>
<li>2 : 상하 좌우</li>
<li>3 : 상 좌우 하</li>
<li>4 : 상 우 하 좌</li>
</ul>
</li>
<li><p>margin,padding 방향 지정 옵션</p>
<ul>
<li>top, bottom, left, right</li>
</ul>
</li>
</ul>
<h1 id="display">Display</h1>
<ul>
<li>block -&gt; block이 아닌 속성을 block으로 변경</li>
<li>inline -&gt; inline이 아닌 속성을 inline으로 변경</li>
</ul>
<pre><code class="language-html">&lt;style&gt;
    .box {
        width: 150px;
        height: 150px;
        background : orange;
        margin: 100px;
    }
    .box:nth-of-type(2){
        background: blue;
    }
    .box:nth-of-type(3){
        background: green;
    }
    .box:nth-of-type(4){
        background: red
    }
    div.box{
        display:inline;
    }
    span.box{
        display:block;
    }
&lt;/style&gt;
&lt;div class=&quot;box&quot;&gt;A&lt;/div&gt;
&lt;div class=&quot;box&quot;&gt;B&lt;/div&gt;
&lt;span class=&quot;box&quot;&gt;C&lt;/span&gt;
&lt;span class=&quot;box&quot;&gt;D&lt;/span&gt;</code></pre>
<ul>
<li>inline-block : 줄개행 X, 너비 높이 지정 가능, 외부 여백 전체 가능<ul>
<li>여백의 중첩이 일어나지 않으며, 독립적인 여백을 유지함</li>
</ul>
</li>
</ul>
<pre><code class="language-html">&lt;style&gt;
    .box {
        width: 150px;
        height: 150px;
        background : orange;
        margin: 100px;
    }
    .box:nth-of-type(2){
        background: blue;
    }
    .box:nth-of-type(3){
        background: green;
    }
    .box:nth-of-type(4){
        background: red
    }
    div.box, span.box{
        display:inline-block;
    }
&lt;/style&gt;
&lt;div class=&quot;box&quot;&gt;A&lt;/div&gt;
&lt;div class=&quot;box&quot;&gt;B&lt;/div&gt;
&lt;span class=&quot;box&quot;&gt;C&lt;/span&gt;
&lt;span class=&quot;box&quot;&gt;D&lt;/span&gt;
</code></pre>
<ul>
<li>none : 감추기 <ul>
<li>visibility : visible(기본값), hidden</li>
<li>visibility는 영역을 유지하며 숨김, none은 영역 자체를 숨김<pre><code class="language-html">&lt;!-- display: none --&gt;
&lt;style&gt;
.box {
    width: 150px;
    height: 150px;
    background : orange;
    margin: 100px;
}
.box2{
    background: blue;
}
.box:nth-of-type(3){
    background: green;
}
.box:nth-of-type(4){
    background: red;
}
div.box, span.box{
    display:inline-block;
}
.box2{
    display: none;
}
&lt;/style&gt;
&lt;div class=&quot;box&quot;&gt;A&lt;/div&gt;
&lt;div class=&quot;box2&quot;&gt;B&lt;/div&gt;
&lt;span class=&quot;box&quot;&gt;C&lt;/span&gt;
&lt;span class=&quot;box&quot;&gt;D&lt;/span&gt;</code></pre>
</li>
</ul>
</li>
</ul>
<pre><code class="language-html">&lt;!-- visibility --&gt;
&lt;style&gt;
    .box {
        width: 150px;
        height: 150px;
        background : orange;
        margin: 100px;
    }
    .box2{
        background: blue;
    }
    .box:nth-of-type(3){
        background: green;
    }
    .box:nth-of-type(4){
        background: red
    }
    div.box, span.box{
        display:inline-block;
    }

    .box2{
        visibility: hidden;
    }
&lt;/style&gt;
&lt;div class=&quot;box&quot;&gt;A&lt;/div&gt;
&lt;div class=&quot;box2&quot;&gt;B&lt;/div&gt;
&lt;span class=&quot;box&quot;&gt;C&lt;/span&gt;
&lt;span class=&quot;box&quot;&gt;D&lt;/span&gt;</code></pre>
<h1 id="flexbox--1차원-정렬-">flexbox ( 1차원 정렬 )</h1>
<ul>
<li>설정 : 부모 요소 -&gt; display: flex;</li>
<li>적용 : 자식 요소 </li>
<li>정렬 방향 <ul>
<li>flex-direction : row ( 기본값 ) 좌 -&gt; 우로 정렬<pre><code>           : row-reverse  우 -&gt; 좌로 정렬
           : column 상 -&gt; 하로 정렬
           : column-reverse 하 -&gt; 상으로 정렬</code></pre></li>
</ul>
</li>
<li>정렬 속성 제어 : justify-content<ul>
<li>flex-start : 왼쪽 정렬</li>
<li>flex-end : 오른쪽 정렬</li>
<li>center : 가운데</li>
<li>space-between : 좌,우측 요소 1개를 양끝에 배치, 나머지 요소를 균등한 여백 부여</li>
<li>space-around : 요소 1개당 양쪽에 공백을 부여함.</li>
<li>space-evenly : 각 요소 사이의 공백이 모두 동일하게 부여</li>
</ul>
</li>
<li>align-items : 자식 요소들의 위치, 배치 <ul>
<li>stretch : 부모의 높이에 맞게 늘려서 맞춤</li>
<li>flex-start : 위쪽 배치</li>
<li>flex-end : 아래쪽 배치</li>
<li>center : 가운데 배치</li>
</ul>
</li>
</ul>
<pre><code class="language-html">&lt;!-- display: flex 적용--&gt;
&lt;style&gt;
    body{
        margin: 0;
    }
    ul{
        margin:0;
        padding: 0;
        list-style-type: none; 
        height:100px;
    }
    ul li {
        min-width: 100px; 
    }
    li:nth-of-type(1){
        background: red;
    }
    li:nth-of-type(2){
        background: blue;
    }
    li:nth-of-type(3){
        background: green;
    }
    .flex1{
        display : flex;
    }
&lt;/style&gt;
&lt;ul class=&quot;flex1&quot;&gt;
    &lt;li&gt;A&lt;/li&gt;
    &lt;li&gt;B&lt;/li&gt;
    &lt;li&gt;C&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<pre><code class="language-html">&lt;!-- flex-direction을 활용한 우 -&gt; 좌 정렬 --&gt;
&lt;style&gt;
    body{
        margin: 0;
    }
    ul{
        margin:0;
        padding: 0;
        list-style-type: none; 
        height:100px;
    }
    ul li {
        min-width: 100px;

    }
    li:nth-of-type(1){
        background: red;
    }
    li:nth-of-type(2){
        background: blue;
    }
    li:nth-of-type(3){
        background: green;
    }
    .flex1{
        display : flex;
        flex-direction: row-reverse;
    }
&lt;/style&gt;
&lt;ul class=&quot;flex1&quot;&gt;
    &lt;li&gt;A&lt;/li&gt;
    &lt;li&gt;B&lt;/li&gt;
    &lt;li&gt;C&lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<pre><code class="language-html">&lt;!-- justify-content를 활용한 리스트 정렬 --&gt;
&lt;style&gt;
    body{
        margin: 0;
    }
    ul{
        margin:0;
        padding: 0;
        list-style-type: none; 
        height:100px;
    }
    ul li {
        min-width: 100px;

    }
    li:nth-of-type(1){
        background: red;
    }
    li:nth-of-type(2){
        background: blue;
    }
    li:nth-of-type(3){
        background: green;
    }
    .flex1{
        display : flex;
    }
    .flex2{
        display : flex;
        justify-content: center;
    }
    .flex3{
        display : flex;
        justify-content: flex-end;
    } 
&lt;/style&gt;
&lt;h1&gt;start&lt;/h1&gt;
&lt;ul class=&quot;flex1&quot;&gt;
    &lt;li&gt;A&lt;/li&gt;
    &lt;li&gt;B&lt;/li&gt;
    &lt;li&gt;C&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;center&lt;/h1&gt;
&lt;ul class=&quot;flex2&quot;&gt;
    &lt;li&gt;A&lt;/li&gt;
    &lt;li&gt;B&lt;/li&gt;
    &lt;li&gt;C&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;end&lt;/h1&gt;
&lt;ul class=&quot;flex3&quot;&gt;
    &lt;li&gt;A&lt;/li&gt;
    &lt;li&gt;B&lt;/li&gt;
    &lt;li&gt;C&lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<pre><code class="language-html">&lt;!-- space-between, around, evenly 적용 --&gt;
&lt;style&gt;
    body{
        margin: 0;
    }
    ul{
        margin:0;
        padding: 0;
        list-style-type: none; 
        height:100px;
    }
    ul li {
        min-width: 100px;

    }
    li:nth-of-type(1){
        background: red;
    }
    li:nth-of-type(2){
        background: blue;
    }
    li:nth-of-type(3){
        background: green;
    }
    .flex4{
        display: flex;
        justify-content: space-between;
    }
    .flex5{
        display: flex;
        justify-content: space-around;
    }
    .flex6{
        display: flex;
        justify-content: space-evenly;
    }

&lt;/style&gt;
&lt;h1&gt;space-between&lt;/h1&gt;
&lt;ul class=&quot;flex4&quot;&gt;
    &lt;li&gt;A&lt;/li&gt;
    &lt;li&gt;B&lt;/li&gt;
    &lt;li&gt;C&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;space-around&lt;/h1&gt;
&lt;ul class=&quot;flex5&quot;&gt;
    &lt;li&gt;A&lt;/li&gt;
    &lt;li&gt;B&lt;/li&gt;
    &lt;li&gt;C&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;space-evenly&lt;/h1&gt;
&lt;ul class=&quot;flex6&quot;&gt;
    &lt;li&gt;A&lt;/li&gt;
    &lt;li&gt;B&lt;/li&gt;
    &lt;li&gt;C&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<pre><code class="language-html">&lt;!-- align-items : flex-start, flex-end, center --&gt;
&lt;style&gt;
    body{
        margin: 0;
    }
    ul{
        margin:0;
        padding: 0;
        list-style-type: none; 
        height:100px;
    }
    ul li {
        min-width: 100px;

    }
    li:nth-of-type(1){
        background: red;
    }
    li:nth-of-type(2){
        background: blue;
    }
    li:nth-of-type(3){
        background: green;
    }
    .flex7{
        display: flex;
        justify-content: space-evenly;
        align-items: flex-start;
    }
    .flex8{
        display: flex;
        justify-content: space-evenly;
        align-items: flex-end;
    }
    .flex9{
        display: flex;
        justify-content: space-evenly;
        align-items: center;
    }

&lt;/style&gt;
&lt;h1&gt;align-items: flex-start&lt;/h1&gt;
&lt;ul class=&quot;flex7&quot;&gt;
    &lt;li&gt;A&lt;/li&gt;
    &lt;li&gt;B&lt;/li&gt;
    &lt;li&gt;C&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;align-items: flex-end&lt;/h1&gt;
&lt;ul class=&quot;flex8&quot;&gt;
    &lt;li&gt;A&lt;/li&gt;
    &lt;li&gt;B&lt;/li&gt;
    &lt;li&gt;C&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;align-items: center&lt;/h1&gt;
&lt;ul class=&quot;flex9&quot;&gt;
    &lt;li&gt;A&lt;/li&gt;
    &lt;li&gt;B&lt;/li&gt;
    &lt;li&gt;C&lt;/li&gt;
&lt;/ul&gt;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.15 / Tue]]></title>
            <link>https://velog.io/@_bao_/26.9.15-Tue-a3372t1i</link>
            <guid>https://velog.io/@_bao_/26.9.15-Tue-a3372t1i</guid>
            <pubDate>Tue, 15 Sep 2026 06:45:35 GMT</pubDate>
            <description><![CDATA[<h1 id="1-2">1-2</h1>
<h3 id="form-태그">Form 태그</h3>
<ul>
<li><p>target : 출력할 창의 위치</p>
</li>
<li><p>action : 제출 처리 URL ( 서버 URL )</p>
</li>
<li><p>Method : 전송 방식</p>
<ul>
<li>GET ( default )<ul>
<li>자원 조회 [ 검색 ]</li>
<li>전송할 데이터는 URL에 포함</li>
<li>_?이름=값&amp;이름=값.... =&gt; ( Query String )</li>
</ul>
</li>
<li>POST<ul>
<li>서버에 변경을 가하는 요청 =&gt; 회원가입 or 글작성 등</li>
<li>요청 전문의 body에 데이터가 전송됨</li>
</ul>
</li>
</ul>
</li>
<li><p>input 태그 : 입력을 위한 태그</p>
<ul>
<li>type : 입력 유형 설정<ul>
<li>text (default)</li>
<li>password : 비밀번호 입력</li>
<li>radio : 여러개 중 하나 선택</li>
<li>checkbox : 여러개 중 다중 선택</li>
<li>submit : 양식 제출, reset - 입력항목 초기화, button</li>
</ul>
</li>
<li>name:<ul>
<li>전송할 값의 이름</li>
<li>radio, checkbox 그룹 명칭</li>
</ul>
</li>
<li>value:<ul>
<li>입력 값</li>
<li>radio, checkbox에서는 개발자가 각 value값을 지정해야 함</li>
<li>type이 text, password, number 에서는 사용자가 입력하면 값이 할당</li>
</ul>
</li>
</ul>
</li>
<li><p>button 태그</p>
<ul>
<li>type<ul>
<li>submit : 양식 제출</li>
<li>reset : 양식 입력 취소</li>
<li>button : 일반 버튼</li>
</ul>
</li>
<li><code>&lt;button&gt; BUTTON NAME &lt;/button&gt;</code></li>
</ul>
</li>
<li><p>태그랑 입력 요소 연결</p>
<ul>
<li>입력 요소를 태그로 감싼다. 주로 lable 태그 사용</li>
<li>for(lable) id(입력요소, 유일무의) 속성 연결</li>
</ul>
</li>
<li><p>textarea : 여러줄 텍스트 입력</p>
</li>
<li><p>select : 여러개 중 한개 또는 여러개 선택</p>
<ul>
<li>selected : 선택 상태로 지정</li>
<li>multiple : 여러개 선택</li>
<li>size : 한 번에 보일 수 지정</li>
</ul>
</li>
<li><p>required : 필수 입력 항목</p>
<ul>
<li>required 속성값이 있는 데이터는 입력값이 없을 경우에 이후 과정으로 넘어가지 않음</li>
</ul>
</li>
<li><p>placeholder : 안내 문구</p>
</li>
<li><p>readonly : 읽기 전용 ( 데이터 전송 O )</p>
</li>
<li><p>disabled : 기능 무력화 ( 데이터 전송 X )</p>
</li>
</ul>
<pre><code class="language-html">&lt;!-- GET / radio,checkbox에 value값 추가 --&gt;
&lt;h1&gt;회원 가입&lt;/h1&gt;
&lt;form action=&quot;sign_up.html&quot;&gt;
  이메일   &lt;input type=&quot;text&quot; name=&quot;email&quot; /&gt; &lt;br /&gt;
  비밀번호  &lt;input type=&quot;password&quot; name=&quot;password&quot; /&gt; &lt;br /&gt;
  비밀번호 확인 &lt;input type=&quot;password&quot; name=&quot;confirm_password&quot; /&gt; &lt;br /&gt;
  회원 이름  &lt;input type=&quot;&#39;text&quot; name=&quot;user_name&quot; /&gt; &lt;br /&gt;
  성별 &lt;input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;FEMALE&quot; /&gt; 여성
      &lt;input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;MALE&quot; /&gt; 남성 &lt;br /&gt;
  취미 &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; value=&quot;GAME&quot; /&gt; 게임
      &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; value=&quot;READ&quot; /&gt; 독서
      &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; value=&quot;MOVIE&quot; /&gt; 영화 &lt;br /&gt;
      &lt;input type=&quot;submit&quot; /&gt;
&lt;/form&gt;
&lt;!-- sign_up.html?email=123&amp;password=qwe&amp;confirm_password=qwe&amp;user_name=123&amp;gender=MALE&amp;hobby=GAME&amp;hobby=READ --&gt;</code></pre>
<pre><code class="language-html">&lt;!-- POST --&gt;
&lt;h1&gt;회원 가입&lt;/h1&gt;
&lt;form method=&quot;POST&quot; action=&quot;sign_up.html&quot;&gt;
  이메일  &lt;input type=&quot;text&quot; name=&quot;email&quot; /&gt; &lt;br /&gt;
  비밀번호 &lt;input type=&quot;password&quot; name=&quot;password&quot; /&gt; &lt;br /&gt;
  비밀번호 확인 &lt;input type=&quot;password&quot; name=&quot;confirm_password&quot; /&gt; &lt;br /&gt;
  회원 이름 &lt;input type=&quot;&#39;text&quot; name=&quot;user_name&quot; /&gt; &lt;br /&gt;
  성별 &lt;input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;FEMALE&quot; /&gt; 여성
      &lt;input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;MALE&quot; /&gt; 남성 &lt;br /&gt;
  취미 &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; value=&quot;GAME&quot; /&gt; 게임
      &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; value=&quot;READ&quot; /&gt; 독서
      &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; value=&quot;MOVIE&quot; /&gt; 영화 &lt;br /&gt;
      &lt;input type=&quot;submit&quot; /&gt;
&lt;/form&gt;
&lt;!-- chapter01/sign_up.html --&gt;
&lt;!-- URL 상에서 정보가 숨겨짐 --&gt;</code></pre>
<pre><code class="language-html">&lt;!-- value값 통해서 기본 입력값 설정, button 태그 사용--&gt;
&lt;form method=&quot;POST&quot; action=&quot;sign_up.html&quot;&gt;
  이메일  &lt;input type=&quot;text&quot; name=&quot;email&quot; value=&quot;user01@test.org&quot; /&gt; &lt;br /&gt;
  비밀번호 &lt;input type=&quot;password&quot; name=&quot;password&quot; /&gt; &lt;br /&gt;
  비밀번호 확인 &lt;input type=&quot;password&quot; name=&quot;confirm_password&quot; /&gt; &lt;br /&gt;
  회원 이름    &lt;input type=&quot;&#39;text&quot; name=&quot;user_name&quot; value=&quot;user01&quot; /&gt; &lt;br /&gt;
  성별 &lt;input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;FEMALE&quot; /&gt;여성
      &lt;input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;MALE&quot; /&gt;남성 &lt;br /&gt;
  취미 &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; value=&quot;GAME&quot; /&gt; 게임
      &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; value=&quot;READ&quot; /&gt; 독서
      &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; value=&quot;MOVIE&quot; /&gt; 영화
  &lt;br /&gt;
  &lt;!-- &lt;input type=&quot;submit&quot; value=&quot;회원가입&quot;/&gt; --&gt;
  &lt;button type=&quot;submit&quot;&gt;회원가입&lt;/button&gt;
&lt;/form&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/_bao_/post/034562ea-a409-46ba-b902-a0a1221fc60f/image.png" alt=""></p>
<br>
<br>

<pre><code class="language-html">&lt;!-- radio, checkbox에서 checked 속성 사용--&gt;
이메일  &lt;input type=&quot;text&quot; name=&quot;email&quot; value=&quot;user01@test.org&quot; /&gt; &lt;br /&gt;
비밀번호 &lt;input type=&quot;password&quot; name=&quot;password&quot; /&gt; &lt;br /&gt;
비밀번호 확인 &lt;input type=&quot;password&quot; name=&quot;confirm_password&quot; /&gt; &lt;br /&gt;
회원 이름 &lt;input type=&quot;&#39;text&quot; name=&quot;user_name&quot; value=&quot;user01&quot; /&gt; &lt;br /&gt;
성별 &lt;input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;FEMALE&quot; checked /&gt;여성
    &lt;input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;MALE&quot; /&gt;남성 &lt;br /&gt;
취미 &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; value=&quot;GAME&quot; checked /&gt; 게임
    &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; value=&quot;READ&quot; /&gt; 독서
    &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; value=&quot;MOVIE&quot; checked /&gt; 영화
&lt;br /&gt;
&lt;button type=&quot;submit&quot;&gt;회원가입&lt;/button&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/_bao_/post/21379202-f2a5-4bed-8484-d617d85df822/image.png" alt=""></p>
<br>
<br>

<pre><code class="language-html">&lt;!-- label 활용 --&gt;
성별
&lt;label&gt;
  &lt;input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;FEMALE&quot; checked /&gt;여성
  &lt;input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;MALE&quot; /&gt;남성
&lt;/label&gt;
&lt;br /&gt;
취미
&lt;input type=&quot;checkbox&quot; id=&quot;hobby_game&quot; name=&quot;hobby&quot; value=&quot;GAME&quot; checked /&gt;
&lt;label for=&quot;hobby_game&quot;&gt;게임&lt;/label&gt;
&lt;input type=&quot;checkbox&quot; id=&quot;hobby_read&quot; name=&quot;hobby&quot; value=&quot;READ&quot; /&gt;
&lt;label for=&quot;hobby_read&quot;&gt;독서&lt;/label&gt;
&lt;input type=&quot;checkbox&quot; id=&quot;hobby_movie&quot; name=&quot;hobby&quot; value=&quot;MOVIE&quot; checked /&gt;
&lt;label for=&quot;hobby_movie&quot;&gt;영화&lt;/label&gt;
&lt;br /&gt;
&lt;button type=&quot;submit&quot;&gt;회원가입&lt;/button&gt;</code></pre>
<pre><code class="language-html">&lt;!-- textarea / placeholder 활용--&gt;
자기소개
&lt;textarea
  name=&quot;introduction&quot;
  rows=&quot;5&quot;
  cols=&quot;100&quot;
  placeholder=&quot;두 줄 이상 입력하세요&quot;
&gt;&lt;/textarea
&gt;&quot;</code></pre>
<p><img src="https://velog.velcdn.com/images/_bao_/post/a4018118-6b82-40df-a0a8-4ff6a1468de0/image.png" alt=""></p>
<br>
<br>

<pre><code class="language-html">&lt;!-- select 태그 --&gt;
태어난 년도
&lt;select name=&quot;birth_year&quot;&gt;
  &lt;option value=&quot;2020&quot;&gt;2020&lt;/option&gt;
  &lt;option value=&quot;2019&quot;&gt;2019&lt;/option&gt;
  &lt;option value=&quot;2018&quot;&gt;2018&lt;/option&gt;
  &lt;option value=&quot;2017&quot;&gt;2017&lt;/option&gt;
  &lt;option value=&quot;2016&quot;&gt;2016&lt;/option&gt;
&lt;/select&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/_bao_/post/7e00db2e-b859-43ea-bcbc-d6442f69b845/image.png" alt=""></p>
<br>
<br>

<pre><code class="language-html">&lt;body&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;ol&gt;
    &lt;li&gt;소렌토&lt;/li&gt;
    &lt;li&gt;팰리세이드&lt;/li&gt;
    &lt;li&gt;모하비&lt;/li&gt;
  &lt;/ol&gt;

  &lt;dl&gt;
    &lt;dt&gt;상품명&lt;/dt&gt;
    &lt;dd&gt;아이폰 Duo&lt;/dd&gt;
  &lt;/dl&gt;
  &lt;dl&gt;
    &lt;dt&gt;판매가&lt;/dt&gt;
    &lt;dd&gt;3,290,000원&lt;/dd&gt;
  &lt;/dl&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;번호&lt;/th&gt;
        &lt;th&gt;이름&lt;/th&gt;
        &lt;th&gt;국어&lt;/th&gt;
        &lt;th&gt;수학&lt;/th&gt;
        &lt;th&gt;영어&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;1&lt;/td&gt;
        &lt;td&gt;K&lt;/td&gt;
        &lt;td&gt;90&lt;/td&gt;
        &lt;td&gt;90&lt;/td&gt;
        &lt;td&gt;90&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2&lt;/td&gt;
        &lt;td&gt;L&lt;/td&gt;
        &lt;td&gt;80&lt;/td&gt;
        &lt;td&gt;80&lt;/td&gt;
        &lt;td&gt;80&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;br /&gt;
  &lt;img src=&quot;photo.png&quot; alt=&quot;가수 사진&quot; style=&quot;width : 300px;&quot; /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  &lt;video
    src=&quot;https://www.w3schools.com/html/mov_bbb.mp4&quot;
    controls
    muted
    loop
    poster=&quot;https://picsum.photos/400/225&quot;
    width=&quot;400&quot;
  &gt;
    최신 브라우저를 이용해 주세요.
  &lt;/video&gt;
&lt;/body&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/_bao_/post/c99e774b-056c-4910-a66d-73243351d3cb/image.png" alt=""></p>
<br>
<br>

<h1 id="1-3">1-3</h1>
<h3 id="시멘틱-태그">시멘틱 태그</h3>
<ul>
<li>의미를 가지고 있는 태그<ul>
<li>form, table, video, nav</li>
</ul>
</li>
<li>비시멘틱 태그<ul>
<li>div, span</li>
</ul>
</li>
</ul>
<h4 id="필요한-이유">필요한 이유</h4>
<ul>
<li>검색 엔진 최적화</li>
<li>웹 접근성</li>
<li>코드 가독성 향상</li>
</ul>
<p>레이아웃 구성 태그</p>
<ul>
<li>header  : 상단 공통 영역</li>
<li>footer  : 하단 공통 영역</li>
<li>main    : 본문, 하나만 정의</li>
<li>section : 내용 구분</li>
<li>article : 섹션별 내용</li>
<li>nav     : 주 메뉴</li>
<li>aside : 왼쪽, 오른쪽 영역</li>
</ul>
<pre><code class="language-html">&lt;!doctype html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;header&gt;
      &lt;a href=&quot;..&quot;&gt;&lt;img src=&quot;logo.png&quot; alt=&quot;Logo&quot; /&gt;&lt;/a&gt;
      &lt;form method=&quot;get&quot;&gt;검색 부분 정의&lt;/form&gt;

      &lt;nav&gt;
        &lt;a href=&quot;#&quot;&gt;메뉴1&lt;/a&gt;
        &lt;a href=&quot;#&quot;&gt;메뉴2&lt;/a&gt;
        &lt;a href=&quot;#&quot;&gt;메뉴3&lt;/a&gt;
        &lt;a href=&quot;#&quot;&gt;메뉴4&lt;/a&gt;
      &lt;/nav&gt;
    &lt;/header&gt;

    &lt;main&gt;
      &lt;section&gt;
        &lt;article&gt;....&lt;/article&gt;
        &lt;article&gt;....&lt;/article&gt;
      &lt;/section&gt;

      &lt;section&gt;
        &lt;article&gt;....&lt;/article&gt;
        &lt;article&gt;....&lt;/article&gt;
      &lt;/section&gt;
    &lt;/main&gt;

    &lt;aside&gt;숨김 왼쪽 더보기 메뉴&lt;/aside&gt;

    &lt;footer&gt;사이트 공통 하단&lt;/footer&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
<h1 id="2-1">2-1</h1>
<h3 id="css--cascading-style-sheet-">CSS ( Cascading Style Sheet )</h3>
<ul>
<li>HTML 문서에 정의된 요소들의 시각적 스타일을 지정하는 스타일시트 언어</li>
<li>주석 : /* */</li>
</ul>
<h3 id="스타일-적용-기본-구조">스타일 적용 기본 구조</h3>
<pre><code class="language-css">선택자 {
  속성: 값,
  속성: 값,
  ...
}</code></pre>
<h3 id="적용방법">적용방법</h3>
<ul>
<li>인라인 스타일<ul>
<li>태그의 style 속성에 직접 적용</li>
</ul>
</li>
<li>내부 스타일 시트<ul>
<li>style 태그 안에 스타일을 정의</li>
</ul>
</li>
<li>외부 스타일 시트 ( 주 사용 )<ul>
<li>css 파일을 따로 생성 후 연동 <code>&lt;link&gt; ...</code></li>
</ul>
</li>
</ul>
<pre><code class="language-html">&lt;!-- 인라인 스타일 --&gt;
&lt;ul&gt;
  &lt;li&gt;사과&lt;/li&gt;
  &lt;li&gt;배&lt;/li&gt;
  &lt;li style=&quot;color: orange; background-color:black; &quot;&gt;감&lt;/li&gt;
  &lt;li&gt;귤&lt;/li&gt;
  &lt;/ul&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/_bao_/post/9f39533f-290a-414b-b7d6-50bee550e9f7/image.png" alt=""></p>
<p><br><br></p>
<pre><code class="language-html">&lt;!-- 내부 스타일 --&gt;
    &lt;style&gt;
        li {
            color: blue;
            background-color : gray;
        }
    &lt;/style&gt;
    &lt;ul&gt;
        &lt;li&gt;사과&lt;/li&gt;
        &lt;li&gt;배&lt;/li&gt;
        &lt;li style=&quot;color: orange; background-color:black; &quot;&gt;감&lt;/li&gt;
        &lt;li&gt;귤&lt;/li&gt;
    &lt;/ul&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/_bao_/post/7bb78032-0ad6-42cd-944a-0a998605abd4/image.png" alt=""></p>
<p><br><br></p>
<pre><code class="language-css">/* style.css */
body {
    background-color : green ;
}</code></pre>
<pre><code class="language-html">&lt;!-- css 파일 불러오기--&gt;
&lt;head&gt;
    &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/style.css&quot; /&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;style&gt;
    li {
        color: blue;
        background-color : gray;
    }
&lt;/style&gt;
&lt;ul&gt;
    &lt;li&gt;사과&lt;/li&gt;
    &lt;li&gt;배&lt;/li&gt;
    &lt;li style=&quot;color: orange; background-color:black; &quot;&gt;감&lt;/li&gt;
    &lt;li&gt;귤&lt;/li&gt;
&lt;/ul&gt; </code></pre>
<p><img src="https://velog.velcdn.com/images/_bao_/post/4816d9ea-8ec8-4a93-9fda-bb127efd1588/image.png" alt=""></p>
<p><br><br></p>
<h3 id="css-선택자">CSS 선택자</h3>
<ul>
<li>전체 선택자<ul>
<li>*</li>
</ul>
</li>
<li>태그 선택자 <ul>
<li>태그명 사용</li>
</ul>
</li>
<li>클래스 선택자<ul>
<li>여러개 요소 선택</li>
<li>.클래스명 =&gt; 방식으로 접근</li>
<li>복수 선언, 복수 지정 가능</li>
</ul>
</li>
<li>아이디 선택자<ul>
<li><code># 아이디명</code></li>
<li>아이디명은 하나만 지정 가능, 중복 안됨</li>
</ul>
</li>
</ul>
<h3 id="스타일-적용-우선-순위">스타일 적용 우선 순위</h3>
<ul>
<li><p>선택자의 범위가 넓을수록 우선순위가 낮으며, 좁을수록 우선순위가 높다.</p>
</li>
<li><p>태그 &lt; 클래스 &lt; 아이디 &lt; style 속성 </p>
</li>
<li><p>태그 = 공통 스타일 , 클래스 = 세부 스타일 설정으로 가장 많이 사용</p>
</li>
<li><p>우선순위 강제 적용 : !important </p>
</li>
</ul>
<pre><code class="language-html">    &lt;style&gt;
        li {
            background-color: gray ;
        }
        .Kia {
            background: orange ;
        }
        .discontinued {
            font-style: italic;
        }
        #sorento {
            background: red;
        }
        .kia2{
            background: skyblue;
        }
    &lt;/style&gt;
    &lt;ul&gt;
        &lt;li class=&quot;Kia&quot; id=&quot;sorento&quot;&gt;소렌토&lt;/li&gt;
        &lt;li&gt;팰리세이드&lt;/li&gt;
        &lt;li class=&quot;Kia kia2 discontinued&quot;&gt;모하비&lt;/li&gt;
        &lt;li&gt;트레일블레이져&lt;/li&gt;
        &lt;li&gt;카이엔&lt;/li&gt;
    &lt;/ul&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/_bao_/post/2f37f83f-b505-4349-b573-921b7858cdcc/image.png" alt=""></p>
<br>
<br>
<br>


<h3 id="복합-관계-선택자">복합 관계 선택자</h3>
<ul>
<li>하위 선택자 ( 조상 - 자손 )</li>
<li>자식 선택자 ( 부모 &gt; 자식 )<pre><code class="language-html">&lt;style&gt;
      /* 조상 - 자손 선택자 */
      ol span{
          background : orange;
      }
      /* 부모 &gt; 자녀 선택자 */
      li div &gt; span{
          background: skyblue;
      }
  &lt;/style&gt;
  &lt;ul&gt;
      &lt;li&gt;menu1&lt;/li&gt;
      &lt;li&gt;menu2&lt;/li&gt;
      &lt;li&gt;&lt;span&gt;menu3&lt;/span&gt;&lt;/li&gt;
      &lt;li&gt;menu4
          &lt;ol&gt;
              &lt;li&gt;
                  &lt;div&gt;
                      &lt;span&gt;sub menu1&lt;/span&gt;
                  &lt;/div&gt;
              &lt;/li&gt;
              &lt;li&gt;&lt;span&gt;sub menu2&lt;/span&gt;&lt;/li&gt;
              &lt;li&gt;sub menu3&lt;/li&gt;
          &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;menu5&lt;/li&gt;
  &lt;/ul&gt;</code></pre>
<img src="https://velog.velcdn.com/images/_bao_/post/ebadcc7d-eb4f-4fce-b586-423b8a90b94c/image.png" alt=""></li>
</ul>
<ul>
<li>일반 형제 선택자 ( 형 ~ 동생 )<ul>
<li>형을 기준으로 기준 아래에 정의된 요소</li>
</ul>
</li>
<li>인접 형제 선택자 ( 형 + 동생 )<ul>
<li>형을 기준으로 바로 아래 요소 1개</li>
</ul>
</li>
</ul>
<pre><code class="language-html">    &lt;style&gt;
        .menu5 ~ li {
            background: magenta;
        }
        .menu5 + li {
            background: green;
        }
    &lt;/style&gt;
    &lt;ul&gt;
        &lt;li&gt;메뉴1&lt;/li&gt;
        &lt;li&gt;메뉴2&lt;/li&gt;
        &lt;li&gt;메뉴3&lt;/li&gt;
        &lt;li&gt;메뉴4&lt;/li&gt;
        &lt;li class=&quot;menu5&quot;&gt;메뉴5&lt;/li&gt;
        &lt;li&gt;메뉴6&lt;/li&gt;
        &lt;li&gt;메뉴7&lt;/li&gt;
        &lt;li&gt;메뉴8&lt;/li&gt;
        &lt;li&gt;메뉴9&lt;/li&gt;
        &lt;li&gt;메뉴10&lt;/li&gt;
    &lt;/ul&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/_bao_/post/6f6ec51a-eb6c-4729-99ba-0bb978c4b94e/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.14 / Mon]]></title>
            <link>https://velog.io/@_bao_/26.9.14-Mon</link>
            <guid>https://velog.io/@_bao_/26.9.14-Mon</guid>
            <pubDate>Mon, 14 Sep 2026 09:00:20 GMT</pubDate>
            <description><![CDATA[<h1 id="html-개념">HTML 개념</h1>
<h3 id="web">Web</h3>
<ul>
<li>뼈대 : Hyper Text Markup Language ( 페이지 이동, 매크로 구성 ) / <code>&lt;tag&gt;</code> 사용</li>
<li>스타일링 : CSS (Cascading Style Sheet) 상위 요소의 스타일이 하위요소에 전달</li>
<li>동적요소 : JavaScript</li>
</ul>
<h3 id="html">HTML</h3>
<ol>
<li>웹 표준 (Web Standard)</li>
</ol>
<ul>
<li>어떤 브라우저를 사용하더라도 동일한 화면, 기능을 제공하도록 만든 국제 공식 규칙</li>
</ul>
<ol start="2">
<li>기본 구성</li>
</ol>
<ul>
<li><code>&lt;!DOCTYPE html&gt;</code> : 현재 HTML5 최신 버전을 사용하고 있다.</li>
<li><code>&lt;html&gt;</code> : HTML 문서 시작, 종료 알림</li>
<li><code>&lt;head&gt;</code> : 웹페이지의 제목, 인코딩 설정 등 브라우저가 알아야 할 문서의 정보(메타데이터)를 담는 구역</li>
<li><code>&lt;body&gt;</code> : 실제로 눈으로 보이는 모든 콘텐츠(텍스트, 이미지, 영상)가 들어가는 구역</li>
</ul>
<ol start="3">
<li>태그</li>
</ol>
<ul>
<li>제목 태그<ul>
<li><code>&lt;h1&gt; ~ &lt;h6&gt;</code></li>
</ul>
</li>
<li>본문 서식 태그<ul>
<li><code>&lt;p&gt;</code> : 문단 구분</li>
<li><code>&lt;b&gt;</code>, <code>&lt;strong&gt;</code> : 볼드체</li>
<li><code>&lt;i&gt;</code> : 이탤릭체</li>
<li><code>&lt;u&gt;</code> : 밑줄</li>
<li><code>&lt;del&gt;</code>, <code>&lt;strike&gt;</code> : 취소선</li>
<li><code>&lt;br&gt;</code> : 줄 개행</li>
</ul>
</li>
</ul>
<ol start="4">
<li>주석</li>
</ol>
<ul>
<li><code>&lt;!-- --&gt;</code> : 설명, 출력 배제</li>
</ul>
<ol start="5">
<li>문단 태그 (Block 속성)</li>
</ol>
<ul>
<li>줄 개행 O</li>
<li>p, div, h1 ~ h6, form ...</li>
<li>공간 가짐 ( 너비, 높이 지정 가능 )</li>
</ul>
<ol start="6">
<li>글 태그 (Inline 속성)</li>
</ol>
<ul>
<li>줄 개행 X</li>
<li>i, b, strong, u, a, span ...</li>
<li>공간을 가지지 않음 ( 너비, 높이 지정 못함 )</li>
</ul>
<pre><code class="language-html">&lt;style&gt;
  div {
    width: 150px;
    height: 150px;
    background-color: blue;
  }

  span {
    width: 150px;
    height: 150px;
    background-color: orange;
  }
&lt;/style&gt;
&lt;p&gt;A&lt;/p&gt;
&lt;p&gt;B&lt;/p&gt;
&lt;div&gt;C&lt;/div&gt;

&lt;i&gt;D&lt;/i&gt;
&lt;b&gt;E&lt;/b&gt;
&lt;span&gt;F&lt;/span&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/_bao_/post/90cef62b-8be3-4f00-9032-7532813cb65c/image.png" alt=""></p>
<h2 id="하이퍼링크-멀티미디어--폼-태그">하이퍼링크, 멀티미디어 &amp; 폼 태그</h2>
<h3 id="하이퍼링크">하이퍼링크</h3>
<ul>
<li>페이지 이동</li>
<li><code>&lt;a&gt;</code> : 하이퍼링크 태그</li>
<li>속성 ( Attribute ) : 태그의 추가 정보 -&gt; 태그의 기능을 수행하기 위한 정보<ul>
<li>href : 이동할 경로<ul>
<li>절대 경로</li>
<li>상대 경로</li>
</ul>
</li>
<li>target : 출력할 창의 위치<ul>
<li>_self ( default ) =&gt; 현재 창</li>
<li>_blank =&gt; 새로운 창</li>
<li>_parent =&gt; 부모 창<ul>
<li><code>&lt;iframe&gt;</code>: src -&gt; 창에 출력할 경로(URL)</li>
</ul>
</li>
<li>_top : 가장 상위에 있는 창</li>
<li>창의 이름</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="form-태그">Form 태그</h3>
<ul>
<li>action : 제출 처리 URL</li>
<li>input 태그 : 입력을 위한 태그<ul>
<li>type : 입력 유형 설정<ul>
<li>text (default)</li>
<li>password : 비밀번호 입력</li>
<li>radio : 여러개 중 하나 선택</li>
<li>checkbox : 여러개 중 다중 선택</li>
<li>submit : 양식 제출, reset - 입력항목 초기화, button</li>
</ul>
</li>
<li>name:<ul>
<li>radio, checkbox 그룹 명칭</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code class="language-html">&lt;h1&gt;회원 가입&lt;/h1&gt;
&lt;form&gt;
  이메일 &lt;input type=&quot;text&quot; /&gt; &lt;br /&gt;
  비밀번호 &lt;input type=&quot;password&quot; /&gt; &lt;br /&gt;
  비밀번호 확인 &lt;input type=&quot;password&quot; /&gt; &lt;br /&gt;
  회원 이름 &lt;input type=&quot;&#39;text&quot; /&gt; &lt;br /&gt;
  성별 &lt;input type=&quot;radio&quot; name=&quot;gender&quot; /&gt;여성
      &lt;input type=&quot;radio&quot; name=&quot;gender&quot; /&gt;남성 &lt;br /&gt;
  취미 &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; /&gt; 게임
      &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; /&gt; 독서
      &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; /&gt; 영화
      &lt;input type=&quot;checkbox&quot; name=&quot;hobby&quot; /&gt; 낚시
  &lt;br /&gt;

  &lt;input type=&quot;submit&quot; /&gt;
&lt;/form&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/_bao_/post/0cb1f5f3-a15b-4959-8529-36887e5fdc93/image.png" alt=""></p>
<br>
<br>
<br>

<h1 id="llm-한계--위험-요소">LLM 한계 &amp; 위험 요소</h1>
<h3 id="주요-한계">주요 한계</h3>
<ul>
<li>환각 (Hallucination)</li>
<li>지식 컷오프 (Knowledge Cutoff)</li>
<li>비결정성 (Non-determinism)</li>
<li>편향 (Bias)</li>
</ul>
<h3 id="파이썬-실습-환각-방지-프롬프트-및-temperature-제어">파이썬 실습: 환각 방지 프롬프트 및 temperature 제어</h3>
<ul>
<li>top-k : 가장 높은 확률의 k개 만큼의 토큰을 선택, 선택된 토큰을 응답으로 사용<ul>
<li>ex) top-k = 100, 가장 높은 확률 토큰 100개 중 선택</li>
</ul>
</li>
<li>top-p : p 확률 이상의 토큰에서 선택</li>
<li>top-p + top-k 사용하는게 좋음</li>
<li>temperature : 확률 분포를 조정 ( 0에 가까울수록 정확한 답변, 1에 가까울수록 창의적인 답변 )<ul>
<li>0에 가깝게 설정 : 도구선택, 형식의 고정</li>
</ul>
</li>
</ul>
<pre><code class="language-python">from langchain_core.prompts import ChatPromptTemplate
# from langchain_ollama import ChatOllama
from langchain.chat_models import init_chat_model # 사용시에 다른 모델을 사용하더라도 코드가 정상작동 가능함
from langchain_core.output_parsers import StrOutputParser # 출력값을 문자열 형태로 변환하는듯

prompt_template = ChatPromptTemplate.from_messages([
  (&quot;system&quot;, &quot;당신은 객관적 사실만을 전달하는 정보 검증관입니다.제공된 지식 범위 밖의 내용이거나 사실 확인이 불가능하다면 &#39;해당 정보는 확인할 수 없습니다&#39;라고만 명확히 답변하세요. 절대 거짓 정보를 지어내지 마세요.&quot;),
  (&quot;user&quot;, &quot;{user_question}&quot;)
])


model = init_chat_model(
  model_provider=&quot;ollama&quot;,
  model=&quot;mistral&quot;,
  temperature=0.9
)

parser = StrOutputParser()

chain = prompt_template | model | parser

question = &quot;2028년 한국에서 개최된 달 탐사 기념 축제의 주요 행사를 알려줘&quot;

response = chain.invoke({&quot;user_question&quot;, question})

response
# &quot; 해당 정보는 확인할 수 없습니다. 2028년 달 탐사 기념 축제의 정보는 현재 알려져 있지 않습니다. 그러나 2028년 예정된 대중 인터넷 축제인 &#39;World Internet Conference&#39; 또는 2028년 예정된 기타 축제의 주요 행사는 아닙니다. 추가적인 정보가 있다면, 최신의 정보를 확인하세요.&quot;</code></pre>
<h2 id="system·user·assistant-메시지-구조">System·User·Assistant 메시지 구조</h2>
<h3 id="역할별-메세지-템플릿-조립">역할별 메세지 템플릿 조립</h3>
<ul>
<li><p>System    : 모델의 역할(페르소나), 상황, 과업, 규칙 정의, 최우선순위 / SystemMessage</p>
</li>
<li><p>User      : 실제 질의 응답에 대한 사용자 질문, 처리할 데이터의 전달, 가변적, 프롬프트 템플릿 / HumanMessage</p>
</li>
<li><p>Assistant : AI가 출력한 응답 / AIMessage</p>
</li>
<li><p>User - Assistant -&gt; 대화의 맥락 정보를 쌍으로 전달, 1쌍 = 턴, 여러쌍 = 멀티턴</p>
</li>
<li><p>BaseMessage의 하위 클래스(HumanMessage, SystemMessage, AIMessage, ToolMessage)</p>
</li>
</ul>
<h3 id="역할별-메세지-템플릿">역할별 메세지 템플릿</h3>
<pre><code class="language-python">from langchain_core.prompts import ChatPromptTemplate

prompt_template = ChatPromptTemplate.from_messages([
  (&quot;system&quot;, &quot;당신은 재치있게 컴퓨터의 개념을 설명하는 유치원 교사입니다.&quot;),
  (&quot;user&quot;, &quot;다음 개념을 설명하세요 : {text}&quot;)
])

chain2 = prompt_template | model | parser

response = chain2.invoke({&quot;text&quot; :  &quot;변수&quot;})

response</code></pre>
<h3 id="대화이력-구조-설계">대화이력 구조 설계</h3>
<ul>
<li>Assistant 메세지 기반 문맥 유지<pre><code class="language-python">messages: list[BaseMessage] = [
HumanMessage(&quot;내 이름은 김철수야&quot;),
AIMessage(&quot;반갑습니다. 철수님 무엇을 도와드릴까요?&quot;),
HumanMessage(&quot;오늘 점심 메뉴 추천 해줘&quot;),
AIMessage(&quot;오늘 점심은 돈까스가 좋을것 같아요.&quot;),
HumanMessage(&quot;오늘 점심 추천이 뭐였지?&quot;)
# HumanMessage(&quot;내 이름이 뭐라고 했지?&quot;)
]
</code></pre>
</li>
</ul>
<p>response = chain.invoke(messages)</p>
<p>response</p>
<h1 id="-오늘-점심-추천은-돈까스였습니다">&#39; 오늘 점심 추천은 돈까스였습니다.&#39;</h1>
<p>```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.11 / Fri]]></title>
            <link>https://velog.io/@_bao_/26.9.11-Fri</link>
            <guid>https://velog.io/@_bao_/26.9.11-Fri</guid>
            <pubDate>Fri, 11 Sep 2026 08:19:54 GMT</pubDate>
            <description><![CDATA[<h3 id="파이썬-타입-힌트">파이썬 타입 힌트</h3>
<ul>
<li><p>타입을 명시할 뿐이지, 강제하지 않으므로 다른 자료형으로 선언하여도 동작함</p>
</li>
<li><p>변수 : 타입</p>
<ul>
<li>num : int = 100</li>
<li>title : str = &#39;ABC&#39;</li>
</ul>
</li>
<li><p>함수</p>
<ul>
<li>def 함수명(...) -&gt; 타입 [반환 타입 / void]:</li>
</ul>
</li>
</ul>
<pre><code class="language-python">num1 : int = 100
print(num1) # 100

def list_sum(nums : list[int]) -&gt; int:
    return sum(nums)

list_sum([10, 20, 30]) # 60</code></pre>
<h3 id="데이터-클래스---dataclass">데이터 클래스 - @dataclass</h3>
<pre><code class="language-python">from dataclasses import dataclass

# @dataclass (kw_only=True) -&gt; 키워드 매개변수만 사용
@dataclass
class Product:
    name : str
    price : int = 0
    description : str = &quot;&quot;

# 위치 인수 사용
product = Product(&#39;iphone&#39;, 10000, &#39;duo&#39;)
print(product) # Product(name=&#39;iphone&#39;, price=10000, description=&#39;duo&#39;)

# 키워드 인수 사용
product = Product(
    name = &#39;iphone&#39;,
    description = &#39;Duo&#39;,
    price = 3290000
)
print(product) # Product(name=&#39;iphone&#39;, price=3290000, description=&#39;Duo&#39;)</code></pre>
<h1 id="postgresql-함수function와-프로시저procedure를-활용한-트랜잭션-제어">PostgreSQL 함수(Function)와 프로시저(Procedure)를 활용한 트랜잭션 제어</h1>
<h2 id="저장-프로그램--stored-program-">저장 프로그램 ( Stored Program )</h2>
<h3 id="함수-function">함수 (Function)</h3>
<ul>
<li>매개변수와 반환값</li>
<li>단일 트랜잭션, TCL 사용 불가</li>
<li>SELECT 구문 내에서 사용 가능</li>
<li>ex) AVG(..), SUM(..)</li>
</ul>
<h3 id="프로시저--procedure-">프로시저 ( Procedure )</h3>
<ul>
<li>독립 프로그램</li>
<li>트랜잭션 제어 가능(COMMIT, ROLLBACK 정의 가능)</li>
<li>CALL 프로시저명(...);</li>
</ul>
<pre><code class="language-SQL">CREATE OR REPLACE FUNCTION create_order_transaction(
    p_order_name TEXT,
    p_order_email TEXT,
    p_order_phone TEXT,
    p_receiver_name TEXT,
    p_receiver_phone TEXT,
    p_zipcode TEXT,
    p_address TEXT,
    p_address_sub TEXT,
    p_delivery_memo TEXT,
    p_user_id UUID,
    p_items JSONB -- [{&quot;product_id&quot;: &quot;uuid&quot;, &quot;quantity&quot;: 1}, ...]
)
RETURNS JSONB
LANGUAGE plpgsql
SECURITY DEFINER

AS $$
DECLARE
  v_order_id UUID;
  v_order_no TEXT; -- 20260911113021300
  v_total_price INT := 0;
  v_item RECORD;
  v_product RECORD;
BEGIN
  -- 상품이 있는지 체크
  IF p_items IS NULL OR jsonb_array_length(p_items) = 0 THEN
    RAISE EXCEPTION &#39;주문할 상품이 없습니다.&#39;;
  END IF;

  -- 주문번호 생성
  v_order_no := TO_CHAR(CURRENT_TIMESTAMP, &#39;YYYYMMDDHH24MISS&#39;);

  -- orders 테이블에 기본 정보를 주문서 추가, 상품 총합 0
  INSERT INTO orders (
    order_no, order_name, order_email, order_phone,
    receiver_name, receiver_phone, zipcode, address, address_sub, delivery_memo,
    total_price, user_id
  ) VALUES (
    v_order_no, p_order_name, p_order_email, p_order_phone,
    p_receiver_name, p_receiver_phone, p_zipcode, p_address,
    p_address_sub, p_delivery_memo, 0, p_user_id
  )
  RETURNING id INTO v_order_id;

  -- products 테이블에서 상품을 조회한 후 order_items 테이블에 상품 정보를 추가
  FOR v_item IN
      SELECT (elem-&gt;&gt;&#39;product_id&#39;)::UUID product_id,
              (elem-&gt;&gt;&#39;quantity&#39;)::INT quantity
      FROM jsonb_array_elements(p_items) elem
  LOOP
    -- 구매 수량 검증
    IF v_item.quantity &lt;= 0 THEN
      RAISE EXCEPTION &#39;주문 수량은 1개 이상이어야 합니다.&#39;;
    END IF;

    -- 실제 상품 조회
    SELECT id, name, price INTO v_product
    FROM products WHERE id = v_item.product_id AND deleted_at IS NULL;

    -- 상품 조회의 결과가 없는 경우
    IF NOT FOUND THEN
      RAISE EXCEPTION &#39;등록되지 않거나 삭제된 상품 입니다. (ID: %)&#39;, v_item.product_id;
    END IF;

    -- 주문 상품 등록
    INSERT INTO order_items (
      order_id, product_id, item_name, price, quantity
    ) VALUES (
      v_order_id, v_product.id, v_product.name, v_product.price, v_item.quantity
    );

    -- total_price 누적
    v_total_price := v_total_price + (v_product.price * v_item.quantity);
  END LOOP;

  -- orders 테이블에 상품 총금액(total_price)을 업데이트
  UPDATE orders
  SET total_price = v_total_price
  WHERE id = v_order_id;

  -- 결과 반환
  RETURN jsonb_build_object(
    &#39;success&#39;, TRUE,
    &#39;order_id&#39;, v_order_id,
    &#39;order_no&#39;, v_order_no
  );

EXCEPTION
  -- 트랜잭션 실패
  WHEN OTHERS THEN
    RAISE EXCEPTION &#39;주문처리 실패: %&#39;, SQLERRM;
END;
$$;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.10 / Thu]]></title>
            <link>https://velog.io/@_bao_/26.9.10-Thu</link>
            <guid>https://velog.io/@_bao_/26.9.10-Thu</guid>
            <pubDate>Thu, 10 Sep 2026 08:42:47 GMT</pubDate>
            <description><![CDATA[<h3 id="method-chaining">Method Chaining</h3>
<ul>
<li>선언적 방식</li>
</ul>
<pre><code class="language-python">supabase.table(...)
        .select(...)
        .eq(...)
        .execute(...)</code></pre>
<pre><code class="language-python">class SupabaseEx:
    def __init__(self):
        self.settings = []

    def table(self, table):
        self.settings.append(table)
        return self

    def select(self, fields):
        self.settings.append(fields)
        return self # 생성된 동일 객체

    def eq(self, name, value):
        self.settings.append(f&#39;{name}={value}&#39;)
        return self

    def execute(self):
        print(self.settings)
        print(&#39;실행..&#39;)
        return &#39;처리된 결과&#39;

supabase = SupabaseEx()

response = (
    supabase.table(&quot;users&quot;)
        .select(&#39;*&#39;)
        .eq(&#39;email&#39;, &#39;user01@test.org&#39;)
        .execute()
)
</code></pre>
<pre><code class="language-python"># CRUD Class
class AiLog:

    def __init__(self):
        user = supabase.auth.get_user()
        if not user: # 미로그인 상태
            raise PermissionError(&#39;로그인 필요함&#39;)

        self.user = user.user

    def create_documents(self, title, content):
        response = (
            supabase.table(&quot;documents&quot;)
                    .insert({
                        &quot;title&quot; : title,
                        &quot;content&quot; : content,
                        &quot;user_id&quot; : self.user.id
                    }).execute()
        )

        return response.data

    def get_my_documents(self):
        response = (
            supabase.table(&quot;documents&quot;)
                    .select(&quot;*&quot;)
                    .eq(&quot;user_id&quot;, self.user.id)
                    .execute()
        )

        return response.data


ai_log = AiLog()

ai_log.create_documents(&quot;세 번째 문서&quot;, &quot;본문 내용&quot;)
ai_log.get_my_documents()</code></pre>
<h3 id="rls--row-level-security-">RLS ( Row Level Security )</h3>
<ul>
<li>CRUD<ul>
<li>회원의 권한 체크 </li>
</ul>
</li>
</ul>
<pre><code class="language-sql">-- 본인 데이터에 대해 모든 작업(SELECT, INSERT, UPDATE, DELETE) 허용
create policy &quot;본인 문서 전체 관리&quot;
on documents
for all
to authenticated
using (auth.uid() = user_id) -- 이미 존재하는 데이터에 대한 통제 (조회, 수정, 삭제)
with check (auth.uid() = user_id); -- 추가, 수정, 삭제시에 권한 확인</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.9 / Wed]]></title>
            <link>https://velog.io/@_bao_/26.9.9-Wed</link>
            <guid>https://velog.io/@_bao_/26.9.9-Wed</guid>
            <pubDate>Wed, 09 Sep 2026 06:48:02 GMT</pubDate>
            <description><![CDATA[<h1 id="트랜잭션-acid-rollback">트랜잭션, ACID, ROLLBACK</h1>
<h3 id="acid--트랜잭션-원칙">ACID : 트랜잭션 원칙</h3>
<ul>
<li>A<ul>
<li>원자성 ( Atomicity ) : 모두 성공하거나 실패</li>
</ul>
</li>
<li>C<ul>
<li>일관성 ( Consistency ) : 규제(제약조건)을 깨뜨리지 않음</li>
</ul>
</li>
<li>I<ul>
<li>격리성 ( Isolation ) : 동시 트랜잭션이 서로를 간섭하지 않음</li>
<li>DB LOCK을 통해서 격리성 유지?</li>
</ul>
</li>
<li>D<ul>
<li>지속성 ( Durability ) : Commit 된 것은 장애가 발생해도 남음</li>
</ul>
</li>
</ul>
<h3 id="트랜잭션">트랜잭션</h3>
<ul>
<li>BEGIN : 트랜잭션 시작</li>
<li>COMMIT : 트랜잭션 종료 / DB 영구 반영</li>
<li>ROLLBACK : 트랜잭션 복구 / COMMIT 전에만 가능</li>
</ul>
<h1 id="supabase-sdk">SUPABASE SDK</h1>
<h3 id="supabase-연결하기">SUPABASE 연결하기</h3>
<pre><code class="language-PYTHON">import os
from dotenv import load_dotenv
from supabase import create_client

# .env 파일의 환경변수 로드
load_dotenv()

url = os.getenv(&quot;SUPABASE_URL&quot;)
key = os.getenv(&quot;SUPABASE_PUBLISHABLE_KEY&quot;)

# Client 초기화
# supabase 클라이언트 객체 생성
supabase = create_client(url, key)

print(supabase)
# &lt;supabase._sync.client.Client object at 0x10d2cc440&gt;</code></pre>
<h3 id="supabase-sdk-insert">SUPABASE SDK INSERT</h3>
<pre><code class="language-PYTHON"># 사용자 추가
response = supabase.table(&#39;users&#39;).insert({&quot;email&quot; : &quot;user03@test.org&quot;}).execute()

# documents INSERT
response = supabase.table(&#39;documents&#39;).insert({
    &#39;title&#39; : &#39;첫 번째 문서&#39;,
    &#39;content&#39; : &#39;본문 내용&#39;,
    &#39;user_id&#39; : &#39;1320f352-13eb-44fc-8662-3ae945e616cd&#39;
}).execute()</code></pre>
<h3 id="supabase-sdk-select">SUPABASE SDK SELECT</h3>
<pre><code class="language-PYTHON"># 회원 목록 조회
response = supabase.table(&#39;users&#39;).select(&#39;*&#39;).execute()
response.data

# ilike : 대소문자 구분없이 like문 실행
response = (supabase.table(&#39;users&#39;)
            .select(&#39;*&#39;)
            .ilike(&#39;email&#39;, &#39;user02%&#39;)
            .execute()
)


# single Keyword
response = (supabase.table(&#39;users&#39;)
            .select(&#39;*&#39;)
            .ilike(&#39;email&#39;, &#39;user04%&#39;)
            .single() # 레코드 한 개, 딕셔너리 형태로 반환
            # single 키워드 사용시에 레코드가 없거나, 1개 이상 존재하는 경우에 APIERROR 발생
            .execute()
)
response.data # API ERROR


# maybe_single Keyword
response = (supabase.table(&#39;users&#39;)
            .select(&#39;*&#39;)
            .ilike(&#39;email&#39;, &#39;user04%&#39;)
            .maybe_single() # 레코드가 0 ~ 1 일 때 사용, 레코드가 없다고 예외 발생 안함
            .execute()
)
response.data # None



# LIMIT Keyword
response = (supabase.table(&#39;users&#39;)
            .select(&#39;*&#39;)
            .ilike(&#39;email&#39;, &#39;user%&#39;)
            .limit(1) # like문을 사용할 떄 여러개의 레코드를 출력하면,
            #오류가 발생하므로 LIMIT 키워드를 이용해서 강제로 1개의 레코드만 출력
            .single()
            .execute()
)
response.data
# {&#39;id&#39;: &#39;e8057300-87a3-43e2-aee6-e4b0d817d0b2&#39;,
#  &#39;email&#39;: &#39;user01@test.org&#39;,
#  &#39;created_at&#39;: &#39;2026-09-08T03:00:44.799562&#39;}


# OFFSET Keyword
response = (supabase.table(&#39;users&#39;)
            .select(&#39;*&#39;)
            .ilike(&#39;email&#39;, &#39;user%&#39;)
            .limit(1)
            .offset(1) # 1 인덱스에서 1개 조회
            .single()
            .execute()
)
response.data
# {&#39;id&#39;: &#39;bd0f1b0d-5921-4751-9235-3e21dfb722ef&#39;,
#  &#39;email&#39;: &#39;user02@test.org&#39;,
#  &#39;created_at&#39;: &#39;2026-09-09T00:42:22.44246&#39;}


# ORDER BY Keyword
response =(
    supabase.table(&#39;users&#39;)
    .select(&#39;*&#39;)
    .order(&#39;email&#39;, desc=True) # email 컬럼 기준, 내림차순 정렬
    .execute()
)
response.data

# JOIN Keyword
## LEFT JOIN
response = (
    supabase.table(&#39;documents&#39;)
    .select(&#39;id, title, content, users(id, email)&#39;)
    .execute()
)
response.data

## INNER JOIN(!inner)
response = (
    supabase.table(&#39;documents&#39;)
    .select(&#39;id, title, content, users!inner(id, email)&#39;)
    .execute()
)
response.data

# join table 조건 걸기
response = (
    supabase.table(&#39;documents&#39;)
    .select(&#39;id, title, content, users!inner(id, email)&#39;)
    .ilike(&#39;users.email&#39;, &#39;user%&#39;)
    .execute()
)
response.data
</code></pre>
<h3 id="sdk-기반-데이터-수정·삭제-구현">SDK 기반 데이터 수정·삭제 구현</h3>
<pre><code class="language-PYTHON"># UPDATE Keyword
response = (
    supabase.table(&#39;documents&#39;)
    .update({
        &#39;title&#39; : &#39;첫 번째 문서(수정)&#39;
    })
    .eq(&#39;id&#39;, &#39;d865df61-ecaa-4117-90e0-84d5a3726118&#39;)
    .execute()
)

# DELETE Keyword
response = (
    supabase.table(&#39;users&#39;)
    .delete()
    .eq(&#39;id&#39;, &#39;e8057300-87a3-43e2-aee6-e4b0d817d0b2&#39;)
    .execute()
)</code></pre>
<h1 id="supabase-authentication">SUPABASE Authentication</h1>
<h3 id="회원가입--로그인">회원가입 &amp; 로그인</h3>
<pre><code class="language-PYTHON">key = os.getenv(&#39;SUPABASE_ANON_KEY&#39;)
supabase = create_client(url, key)

&quot;&quot;&quot;
supabase.auth : 인증(로그인) / 인가(접근 권한) 관련 메서드를 가지고 있는 객체

테이블 명 : auth.users
&quot;&quot;&quot;

# 회원가입
response = supabase.auth.sign_up({
    &#39;email&#39; : &#39;user01@test.org&#39;,
    &#39;password&#39; : &#39;password1234&#39;,
    &#39;phone&#39; : &#39;010-1000-1000&#39;
})

# 로그인
response = supabase.auth.sign_in_with_password({
    &#39;email&#39; : &#39;user01@test.org&#39;,
    &#39;password&#39; : &#39;password1234&#39;
})
response.user

# 현재 로그인된 사용자 확인
user = supabase.auth.get_user() # 현재 로그인한 사용자 정보, 있으면 로그인, None이면 미 인증 상태
if user:
    print(f&#39;로그인 상태 : {user}&#39;)
else :
    print(f&#39; 미 로그인 상태 &#39;)

# 로그아웃
supabase.auth.sign_out()</code></pre>
<h1 id="llm">LLM</h1>
<h3 id="langchain">Langchain</h3>
<ul>
<li>사용자의 자연어를 받아 프롬프트로 조립하고 모델을 호출하여 결과를 가공하는 소프트웨어</li>
<li>개발자가 복잡한 문자열 처리와 수동으로 API를 호출하지 않도록 표준화된 파이프라인 제공</li>
</ul>
<h3 id="langchain을-사용하는-이유">Langchain을 사용하는 이유</h3>
<ul>
<li><p>순수 API 직접 호출의 한계</p>
<ul>
<li>매번 긴 문자열 포맷팅과 변수 주입 코드를 수동으로 작성해야 함</li>
<li>모델 응답 객체에서 순수 텍스트만 꺼내기 위해서 딕셔너리 접근을 반복적으로 수행해야 함</li>
<li>추후 문서 검색(RAG)나 도구 연동을 추가로 수행할 때 코드가 복잡해짐</li>
</ul>
</li>
<li><p>장점</p>
<ul>
<li>레고 블록 조립 방식 (LCEL)<ul>
<li><code>프롬프트 | 모델 | 파서</code> 형태로 파이프 기호를 통해 데이터 흐름을 한눈에 파악 가능</li>
</ul>
</li>
<li>입출력 표준화<ul>
<li>변수를 프롬프트에 안전하게 주입하고, 모델 응답에서 텍스트만 추출 가능</li>
</ul>
</li>
<li>일관된 확장성<ul>
<li>체인 구조 그대로 RAG, 구조화 출력, AI 에이전트로 자연스럽게 확장 가능</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code class="language-PYTHON">from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate

# system : 역할, 상황, 제한 조건, 예시 -&gt; 시스템 메세지, SystemMessage(..)
# user : 사용자의 질의 / HumanMessage(..)
# asistant : AI 답변 / AIMessage(..)

# 시스템에게 역할, 상황, 제한 조건, 예시 등 제시
prompt_template = ChatPromptTemplate.from_messages([
    (&#39;system&#39;, &quot;당신은 컴퓨터 기초 개념을 일상적인 사물에 빗대어 설명하는 교육 전문가입니다. 2문장 이내로 친절하게 설명하세요.&quot;),
    (&#39;user&#39;, &#39;{user_question}&#39;)
])

# 샘플 프롬프트 선언
sample_prompt = prompt_template.invoke({
    &quot;user_question&quot; : &quot;프로그래밍에서 &#39;변수&#39;가 무엇인가요?&quot;
})

# 모델 호출
model = ChatOllama(
    model=&#39;mistral&#39;,
)

# 모델에 샘플 프롬프트 삽입
response = model.invoke(sample_prompt)</code></pre>
<pre><code class="language-PYTHON"># 순수 텍스트만 추출하기
from langchain_core.output_parsers import StrOutputParser


parser = StrOutputParser()
text = parser.invoke(response)</code></pre>
<pre><code class="language-PYTHON"># 파이프 연산자를 사용해서 3개의 컴포넌트를 하나의 파이프라인으로 연결
chain = prompt_template | model | parser
res = chain.invoke({
    &quot;user_question&quot; : &quot;&#39;클래스&#39;가 뭔데&#39;&quot;
})

res</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.7 / Mon]]></title>
            <link>https://velog.io/@_bao_/26.9.7-Mon</link>
            <guid>https://velog.io/@_bao_/26.9.7-Mon</guid>
            <pubDate>Mon, 07 Sep 2026 08:47:18 GMT</pubDate>
            <description><![CDATA[<h1 id="dml---select">DML - SELECT</h1>
<h3 id="select">SELECT</h3>
<ul>
<li>테이블에서 원하는 컬럼을 선택하여 데이터 조회시에 사용</li>
</ul>
<h3 id="select-">SELECT *</h3>
<ul>
<li><p>실무에서는 SELECT * 을 잘 사용하지 않는다.</p>
</li>
<li><p>불필요한 데이터 조회로 인한 성능 저하</p>
</li>
<li><p>테이블 구조 변경시에 예상치 못한 열 포함 가능</p>
</li>
<li><p>코드 가독성이 떨어져 유지보수 어려움</p>
</li>
<li><p>SELECT [ *, 컬럼 이름1, 컬럼 이름2....] FROM 테이블명[, 테이블명2.... ] [ WHERE 조건식 ]</p>
</li>
<li><p>SELECT [ALL | DISTINCT ] 컬럼명 FROM 테이벌명</p>
</li>
</ul>
<pre><code class="language-SQL">-- 컬럼 지정 조회
SELECT first_name, last_name, email from customers;

-- 전체 컬럼 조회
SELECT * FROM products

-- 중복 제거
SELECT DISTINCT store_id from orders;

-- store_id + staff_id 조합 중복 제거
SELECT DISTINCT store_id, staff_id FROM orders;</code></pre>
<h3 id="distinct">DISTINCT</h3>
<ul>
<li>컬럼에 중복 값이 존재 하는 경우, 고유한 값만 남겨 조회 가능</li>
</ul>
<h3 id="where-조건식--조회의-범위-지정">WHERE 조건식 : 조회의 범위 지정</h3>
<ul>
<li>비교 연산자 : &gt;, &lt;, &gt;=, &lt;=, =</li>
<li>논리 연산자 : AND, OR, NOT</li>
<li>IN, NOT IN : 포함 여부</li>
<li>BETWEEN A AND B : A와 B 사이</li>
<li>IS NULL, IS NOT NULL : NULL인지 아닌지 -&gt; NULL은 데이터가 없는 상태로 비교 및 산술 연산이 불가능</li>
<li>CASE WHEN : 조건에 따른 다른 값을 부여하는 경우, 필드 명시 위치에 적용<ul>
<li>SELECT CASE WHEN 조건식1 THEN 결과1 WHEN 조건식2 THEN 결과2 ELSE 결과 END AS 새로운 컬럼 명</li>
</ul>
</li>
<li>LIKE &#39;키워드&#39;: 키워드와 적황히 매칭
LIKE &#39;키워드%&#39; : 키워드 이후 아무글자나 있어도 됨
LIKE &#39;%키워드&#39; : 키워드 이전 아무글자나 있어도 됨
LIKE &#39;%키워드%&#39; : 키워드 전후로 아무글자나 있어도 됨
LIKE &#39;*키워드&#39; : 키워드 앞으로 반드시 *의 길이만큼 데이터가 있어야함</li>
</ul>
<pre><code class="language-SQL">-- 연습문제 4
SELECT DISTINCT store_id FROM orders;

-- 연습문제 5
SELECT DISTINCT state FROM customers;

-- 연습문제 6
SELECT DISTINCT brand_id FROM products;

-- 연습문제 7
SELECT * FROM orders WHERE shipped_date IS NULL;

-- 연습문제 8
SELECT * FROM staffs WHERE store_id = 1;

-- 연습문제 9
SELECT * FROM products WHERE 500 &lt; list_price AND 1000 &gt; list_price;
SELECT * FROM products WHERE list_price BETWEEN 500 AND 1000;

SELECT order_id, product_id, list_price,
    CASE WHEN list_price &lt; 100 THEN &#39;저가&#39;
         WHEN list_price &lt; 500 THEN &#39;중가&#39;
         ELSE &#39;고가&#39;
    END AS price_grade
   FROM order_items;

-- 상품명에 Trek이 포함되는 데이터
SELECT * FROM products WHERE product_name LIKE &#39;%Trek%&#39;;
-- 상품명 2018로 끝나는 데이터
SELECT * FROM products WHERE product_name LIKE &#39;%2018&#39;;
-- 지정한 날짜 사이에 있는 데이터
SELECT * FROM orders WHERE order_date BETWEEN &#39;2016-01-01&#39; AND &#39;2016-01-31&#39;;

SELECT * FROM customers WHERE state = &#39;CA&#39; or state =&#39;NY&#39;;
SELECT * FROM customers WHERE state IN (&#39;NY&#39;, &#39;CA&#39;);
SELECT * FROM customers WHERE state NOT IN (&#39;NY&#39;, &#39;CA&#39;);

-- 연습문제 11
SELECT 
  CASE WHEN order_status = 1 THEN &#39;처리중&#39;
    WHEN order_status = 2 THEN &#39;거부&#39;
    WHEN order_status = 3 THEN &#39;배송완료&#39;
    ELSE &#39;취소&#39;
  END AS &#39;주문 상태 코드&#39;
  FROM orders;

-- 연습 문제 15
SELECT * FROM stocks WHERE quantity &lt;= 5;
</code></pre>
<h3 id="order-by">ORDER BY</h3>
<ul>
<li>지정한 컬럼 기준 정렬</li>
<li>컬럼을 여러개 지정한 경우 순차적으로 정렬하되, 동일한 값의 경우 다음 컬럼 기준으로 정렬</li>
<li>ASC, DESC : 오름차, 내림차</li>
</ul>
<pre><code class="language-SQL">SELECT * FROM products ORDER BY list_price DESC;

SELECT * FROM orders ORDER BY store_id ASC, order_date DESC;</code></pre>
<h1 id="데이터-집계-및-분석">데이터 집계 및 분석</h1>
<h3 id="집계-함수">집계 함수</h3>
<ul>
<li>COUNT(컬럼명1, [컬럼명2, ...]) : 레코드 갯수 조회<ul>
<li>count(*): 전체 레코드 조회</li>
<li>NULL 배제하고 계산</li>
</ul>
</li>
<li>SUM(컬럼명) : 합계</li>
<li>AVG(컬럼명) : 평균</li>
<li>MIN(컬럼명) : 최솟값</li>
<li>MAX(컬럼명) : 최댓값</li>
</ul>
<pre><code class="language-SQL">SELECT COUNT(*) from orders;</code></pre>
<img src='./imgs/exam1.png'>

<pre><code class="language-SQL">select avg(list_price), max(list_price), min(list_price) from products;</code></pre>
<img src='./imgs/exam2.png'>

<pre><code class="language-SQL">SELECT sum(quantity) 합계 from order_items;</code></pre>
<img src='./imgs/exam3.png'>




<h3 id="group-by">GROUP BY</h3>
<ul>
<li>특정 컬럼의 같은 값을 기준으로 그룹화</li>
<li>대부분 집계 함수와 함께 사용</li>
<li>레코드 갯수는 그룹화된 결과 갯수 만큼 조회</li>
<li>조회 컬럼은 반드시 GROUP BY에 명시된 컬럼만 사용가능</li>
<li>집계 함수 포함한 조건은 절대 WHERE 절에서 사용 불가능</li>
<li>GROUP BY __ HAVING 집계함수 조건</li>
</ul>
<pre><code class="language-SQL">-- brand_id 별 통계
select avg(list_price), max(list_price), min(list_price) from products GROUP BY brand_id ORDER BY brand_id;

-- 실행 불가
SELECT brand_id, COUNT(*) FROM products WHERE count(*) &gt; 100 GROUP BY brand_id;
-- 실행 가능
SELECT brand_id, COUNT(*) FROM products GROUP BY brand_id HAVING count(*) &gt; 100;

-- 연습문제 7
select avg(list_price) from products GROUP BY category_id HAVING avg(list_price) &gt; 500;</code></pre>
<h1 id="테이블-결합">테이블 결합</h1>
<h3 id="집합">집합</h3>
<ul>
<li>합집합 : UNION</li>
<li>교집합 : INTERSECT</li>
<li>차집합 : EXCEPT</li>
</ul>
<pre><code class="language-SQL">-- 2016-01-17 이전
select order_id, order_date from orders
WHERE order_date &lt;= &#39;2016-01-17&#39; ORDER BY order_date;

-- 2016-01-15 이후 데이터
select order_id, order_date from orders
WHERE order_date &gt;= &#39;2016-01-15&#39; ORDER BY order_date;

-- 공통 레코드 조회 ( INTERSECT )
select order_id, order_date from orders
WHERE order_date &lt;= &#39;2016-01-17&#39;
INTERSECT
select order_id, order_date from orders
WHERE order_date &gt;= &#39;2016-01-15&#39; ORDER BY order_date;

-- 레코드 합치기 ( UNION )
select order_id, order_date from orders
WHERE order_date &lt;= &#39;2016-01-17&#39;
UNION
select order_id, order_date from orders
WHERE order_date &gt;= &#39;2016-01-15&#39; ORDER BY order_date;

-- 레코드 합치기 ( UNION ALL 중복 허용 )
select order_id, order_date from orders
WHERE order_date &lt;= &#39;2016-01-17&#39;
UNION ALL
select order_id, order_date from orders
WHERE order_date &gt;= &#39;2016-01-15&#39; ORDER BY order_date;


-- 차집합
select order_id, order_date from orders
WHERE order_date &lt;= &#39;2016-01-17&#39;
EXCEPT
select order_id, order_date from orders
WHERE order_date &gt;= &#39;2016-01-15&#39; ORDER BY order_date;</code></pre>
<h3 id="join">JOIN</h3>
<ul>
<li>두 테이블에서 공통적인 값을 기준으로 테이블을 하나처럼 조회되도록 결합하는 것</li>
</ul>
<h4 id="inner-join--동등-내부-조인">INNER JOIN : 동등, 내부 조인</h4>
<ul>
<li>INNER 키워드 생략 가능</li>
</ul>
<pre><code class="language-SQL"></code></pre>
<h4 id="left-outer-join--외부-조인">LEFT OUTER JOIN : 외부 조인</h4>
<ul>
<li>왼쪽 테이블을 메인으로 모두 출력하고 오른쪽 테이블은 보조정보</li>
</ul>
<h4 id="right-outer-join--외부조인">RIGHT OUTER JOIN : 외부조인</h4>
<ul>
<li>오른쪽 테이블을 메인으로 모두 출력하고 왼쪽 테이블은 보조정보</li>
</ul>
<h4 id="full-outer-join--전체-조인">FULL OUTER JOIN : 전체 조인</h4>
<ul>
<li>두 테이블 모두 주 테이블로 모든 데이터 출력</li>
</ul>
<pre><code class="language-SQL">select * from orders, stores;

-- 주문이 발생한 매장 정보
select * from orders, stores where orders.store_id = stores.store_id;

--INNER JOIN ( 동등, 내부 조인 )
select * from orders o INNER JOIN stores s ON o.store_id = s.store_id;

select DISTINCT store_id FROM orders;

insert into stores (store_id, store_name) values (4, &#39;sparta market&#39;);

-- stores 기준에서 orders 테이블의 정보를 결합
SELECT DISTINCT s.store_id FROM stores s JOIN orders o ON s.store_id = o.store_id;

-- LEFT OUTER JOIN -&gt; stores가 주테이블로 모든 데이터 출력, orders는 보조 테이블로 있는 것만 출력
SELECT * FROM stores s LEFT JOIN orders o ON s.store_id = o.store_id ORDER BY s.store_id DESC;</code></pre>
<pre><code class="language-SQL">INSERT INTO orders (order_id, customer_id, order_date) VALUES (1700, 1, current_timestamp );
-- FULL OUTER JOIN -&gt; 양쪽 테이블 모두 주 테이블로 전부 출력
SELECT * FROM stores s FULL OUTER JOIN orders o ON s.store_id = o.store_id ORDER BY s.store_id DESC, o.order_id DESC;</code></pre>
<h4 id="다수-테이블-조인">다수 테이블 조인</h4>
<pre><code class="language-SQL">-- 다수 테이블 조인하기
SELECT 
  o.order_id, o.order_date,
  s.store_name,
  f.first_name staff_first_name,
  f.last_name staff_last_name,
  c.first_name custo_first_name,
  c.last_name  custo_last_name
FROM orders o 
  LEFT JOIN customers c ON o.customer_id = c.customer_id
  LEFT JOIN stores s ON o.store_id = s.store_id
  LEFT JOIN staffs f ON o.staff_id = f.staff_id;</code></pre>
<pre><code class="language-SQL">-- 연습문제 1
SELECT store_id FROM staffs
UNION
SELECT store_id FROM orders;

-- 연습문제 2
SELECT order_id, first_name, last_name, order_date
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id;

-- 연습문제 3
SELECT p.product_id, product_name, quantity
FROM products p
FULL OUTER JOIN stocks s ON p.product_id = s.product_id;

-- 연습문제 6
select o.order_id, s.first_name, s.last_name, s.store_id
from orders o
join staffs s ON o.staff_id = s.staff_id AND o.store_id = s.store_id ;</code></pre>
<h3 id="limit">LIMIT</h3>
<ul>
<li>조회할 행 수 지정</li>
<li>[OFFSET 시작 인덱스 번호]<pre><code class="language-SQL">SELECT * FROM orders LIMIT 10 </code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.4 / Fri]]></title>
            <link>https://velog.io/@_bao_/26.9.4-Fri-lxy0wvzl</link>
            <guid>https://velog.io/@_bao_/26.9.4-Fri-lxy0wvzl</guid>
            <pubDate>Fri, 04 Sep 2026 06:59:30 GMT</pubDate>
            <description><![CDATA[<h3 id="postgresql-">PostgreSQL &#39;&#39; &amp; &quot;&quot;</h3>
<ul>
<li>&#39;&#39; [작은 따옴표] : 문자열 리터럴</li>
<li>&quot;&quot; [큰 따옴표]  : 구분 식별자 ( 컬럼, 테이블명 ) -&gt; 특수 문자 or 대소문자 or 예약어</li>
</ul>
<h3 id="ddl">DDL</h3>
<ul>
<li><p>데이터 삭제시 복구 (ROLLBACK) 불가능</p>
</li>
<li><p>CREATE : 생성</p>
<ul>
<li>CREATE [ TABLE, INDEX, TYPE ... ]</li>
</ul>
</li>
<li><p>DROP   : 삭제</p>
<ul>
<li>DROP [ TABLE, INDEX, TYPE ... ]</li>
</ul>
</li>
<li><p>TRUNCATE : 테이블의 스키마 유지 후 초기화</p>
<ul>
<li>TRUNCATE TABLE 테이블명</li>
</ul>
</li>
<li><p>ALTER : 수정</p>
<pre><code class="language-SQL">-- COLUMN 추가
ALTER TABLE 테이블명 ADD COLUMN 컬럼명 데이터타입 [제약조건];
-- COLUMN명 변경
ALTER TABLE 테이블명 RENAME COLUMN 기존컬럼명 TO 신규컬럼명;
-- COLUMN 제거
ALTER TABLE 테이블명 DROP COLUMN 컬럼명;
-- COLUMN 데이터 없는 경우 DATA TYPE 변경
ALTER TABLE 테이블명 ALTER COLUMN 컬럼명 TYPE 데이터타입;
-- COLUMN 데이터 존재 + 형변환 필요시 DATA TYPE 변경
ALTER TABLE 테이블명 ALTER COLUMN 컬럼명 TYPE 데이터타입 USING (컬럼명::데이터타입);
-- 제약조건 추가
ALTER TABLE 테이블명 ALTER COLUMN 컬럼명 SET [ 제약조건 or 기본값 ];
-- 제약조건 제거
ATLER TABLE 테이블명 ALTER COLUMN 컬럼명 DROP [ 제약조건 or 기본값 ];

-- 기본키 추가
ALTER TABLE 테이블명 ADD CONSTRAINT 제약조건구분이름 PRIMARY KEY (컬럼명);
-- 외래키 추가
ALTER TABLE 테이블명 ADD CONSTRAINT 제약조건구분이름 
FOREIGN KEY (현재 컬럼명) REFERENCES 참조 테이블명 (참조 컬럼명) [ ON DELETE, CASCADE, SET NULL];
-- UNIQUE 추가
ALTER TABLE 테이블명 ADD CONSTRAINT 제약조건구분이름 UNIQUE (컬럼명1, 컬럼명2 ....);
-- CHECK 추가
ALTER TABLE 테이블명 ADD CONSTRAINT 제약조건구분이름 CHECK (조건식);

-- 기본키, 외래키, UNIQUE, CHECK 제거
ALTER TABLE 테이블명 DROP CONSTRAINT 제약조건구분이름;</code></pre>
</li>
</ul>
<h3 id="dml">DML</h3>
<ul>
<li>INSERT : 추가<ul>
<li>INSERT INTO 테이블명 [( 컬럼명1, 컬럼명2 ...)] VALUES (값1, 값2...);</li>
</ul>
</li>
<li>UPDATE : 수정<ul>
<li>UPDATE 테이블명 SET 컬럼명 = 변경할 값, 컬럼명 = 변경할 값 [ WHERE 조건식 ]</li>
</ul>
</li>
<li>DELETE : 삭제<ul>
<li>DELETE FROM 테이블명 [ WHERE 조건식 ]</li>
</ul>
</li>
</ul>
<h1 id="dq">DQ</h1>
<p><img src="https://velog.velcdn.com/images/_bao_/post/b7003ff8-04d1-4471-b5fe-0bdf9a3e3d4f/image.png" alt="">
<img src="https://velog.velcdn.com/images/_bao_/post/71ab9e4d-0f4d-4fe1-9423-b2253570763f/image.png" alt="">
<img src="https://velog.velcdn.com/images/_bao_/post/037fa974-cae1-4aed-981e-35ddae8bfaca/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.3 / Thu]]></title>
            <link>https://velog.io/@_bao_/26-9-3-Thu</link>
            <guid>https://velog.io/@_bao_/26-9-3-Thu</guid>
            <pubDate>Thu, 03 Sep 2026 07:10:20 GMT</pubDate>
            <description><![CDATA[<h1 id="sql">SQL</h1>
<h3 id="데이터-타입">데이터 타입</h3>
<ul>
<li>각 컬럼에 어떤 종류의 값을 저장할 수 있는지 정의</li>
<li>잘못된 형식의 데이터가 저장되는 것을 방지하고, 저장공간을 효율적으로 활용 가능</li>
</ul>
<h3 id="스키마">스키마</h3>
<ul>
<li>데이터 베이스의 구조와 제약 조건을 정의한 설계도</li>
<li>테이블, 컬럼, 데이터타입, 제약 조건 등의 정보가 포함</li>
<li>데이터가 일정한 구조와 규칙을 유지할 수 있도록 돕는다.</li>
</ul>
<h3 id="ddl--data-definition-language-">DDL ( Data Definition Language )</h3>
<ul>
<li><p>데이터 정의어</p>
<ul>
<li>CREATE</li>
</ul>
<pre><code class="language-SQL">CREATE 테이블 명 (
  컬럼명1 데이터타입 제약조건
  컬럼명2 .....
)

-- 제약조건 종류
-- PRIMARY KEY : 기본키 설정 : 중복 금지, NULL 금지
-- NOT NULL : NULL 금지
-- UNIQUE : 중복 금지, NULL 허용
-- CHECK : 특정 조건에 해당 하는지 체크

-- 자동 증감 : int generated always as identity -&gt; 표준방식
-- postgreSQL: SERIAL (4byte), BIGSERIAL(8byte)</code></pre>
<ul>
<li>ALTER : 테이블 수정<pre><code class="language-SQL"># 신규 컬럼 추가
alter table member
add column phone varchar(20);
</code></pre>
</li>
</ul>
<h1 id="기존-컬럼-수정">기존 컬럼 수정</h1>
<p>alter table member
alter column name type varchar(100);</p>
<h1 id="신규-제약-조건-추가">신규 제약 조건 추가</h1>
<p>ALTER TABLE member
ALTER CONSTRAINT phone_unique UNIQUE (phone)</p>
<pre><code>- DROP
```SQL
DROP TABLE member</code></pre><ul>
<li>TRUNCATE : 테이블 구조를 유지하며 초기화</li>
</ul>
</li>
</ul>
<h3 id="dml">DML</h3>
<ul>
<li>데이터 조작어<ul>
<li>INSERT<pre><code class="language-sql"># 컬럼명 맞춤 값 대입
INSERT INTO 테이블명 ( 컬럼명 ) values ( 값 )
# 전체 컬럼 자동 맞춤 값 대임
INSERT INTO 테이블명 values ( 값)
# 여러개의 값 한번에 대입
INSERT INTO 테이블명 values (값1), (값2), (값3) ....</code></pre>
</li>
<li>UPDATE</li>
<li>DELETE</li>
<li>SELECT</li>
</ul>
</li>
</ul>
<h3 id="dcl">DCL</h3>
<ul>
<li>데이터 제어어<ul>
<li>GRANT : 권한 부여</li>
<li>REVOKE : 권한 취소</li>
</ul>
</li>
</ul>
<h3 id="트랙잭션">트랙잭션</h3>
<ul>
<li>COMMIT : 데이터를 DB에 영구 반영</li>
<li>ROLLBACK : COMMMIT 전 반영 내용 돌리기</li>
</ul>
<h3 id="데이터-무결성-제약조건">데이터 무결성 제약조건</h3>
<ul>
<li>잘못된 데이터가 존재하면 데이터의 신뢰도가 떨어질 수 있으므로 데이터가 정확하고 일관된 상태를 유지하는것.</li>
</ul>
<h4 id="도메인-무결성-제약-조건--자료형">도메인 무결성 제약 조건 / 자료형</h4>
<ul>
<li>테이블 생성시에 정의된 자료형 외에 다른 자료형 입력 불가능</li>
</ul>
<h4 id="개체-무결성-제약-조건--기본키">개체 무결성 제약 조건 / 기본키</h4>
<ul>
<li>테이블 내에서 각 행을 유일하게 식별하는 열</li>
<li>중복 금지, NULL 금지</li>
</ul>
<h4 id="참조-무결성-제약조건--외래키">참조 무결성 제약조건 / 외래키</h4>
<ul>
<li>다른 테이블의 기본키를 참조하는 열 </li>
<li>부모 쪽 테이블에 없는 참조값을 자식 테이블이 사용 불가능</li>
<li>부모 쪽 레코드에 자식 레코드가 있으면 부모 레코드 삭제 불가능</li>
<li>ON DELETE<ul>
<li>CASCADE : 부모 레코드 삭제 -&gt; 자식 레코드도 함께 삭제</li>
<li>SET NULL : 부모 레코드가 삭제 -&gt; 자식 레코드의 참조 컬럼의 값을 NULL로 변환</li>
</ul>
</li>
</ul>
<h3 id="데이터베이스-정규화">데이터베이스 정규화</h3>
<ul>
<li>불필요한 데이터 중복, 이상현상 개선을 위해 테이블의 구조를 단계적으로 개선하는 과정</li>
<li>테이블을 분리함으로써 데이터 수정 및 관리가 쉬워지고 데이터의 일관성을 유지하기 쉽다</li>
</ul>
<h4 id="제1정규형-1nf">제1정규형 1NF</h4>
<ul>
<li>원자값 유지, 하나의 컬럼에는 하나의 데이터만 존재해야 한다</li>
</ul>
<h4 id="제2정규형-2nf">제2정규형 2NF</h4>
<ul>
<li>기본키가 두개인 경우</li>
</ul>
<h4 id="제3정규형-3nf">제3정규형 3NF</h4>
<ul>
<li>기본키가 한개인 경우임에도 불구하고 데이터의 분리가 가능한 데이터의 집합</li>
</ul>
<h1 id="dq">DQ</h1>
<p><img src="https://velog.velcdn.com/images/_bao_/post/4a061bc6-1af0-4e49-9e1b-c1245cfbbfd8/image.png" alt="">
<img src="https://velog.velcdn.com/images/_bao_/post/bc3419ea-0463-4985-b247-ffed6e78f9f9/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.2 / Wed]]></title>
            <link>https://velog.io/@_bao_/26.9.2-Wed</link>
            <guid>https://velog.io/@_bao_/26.9.2-Wed</guid>
            <pubDate>Wed, 02 Sep 2026 04:59:17 GMT</pubDate>
            <description><![CDATA[<h1 id="dq">DQ</h1>
<ul>
<li>시퀀스 투 시퀀스 모델에서 인코더가 디코더에 전달하는 &#39;컨텍스트 벡터&#39;의 내부 구성 요소<ul>
<li>LSTM 기준 [ 마지막 은닉 상태(h) 및 마지막 셀 상태(c) ]</li>
</ul>
</li>
<li>디코더 학습 시, 이전 시점의 예측값 대신 실제 정답 단어를 다음 시점 입력으로 강제 주입하여 학습을 안정화 하는 기법<ul>
<li>교사 강요</li>
</ul>
</li>
<li>어텐션 메커니즘에서 디코더의 현재 상태 벡터에 해당, 정보를 탐색하기 위한 &#39;질문&#39; 역할을 하는 요소<ul>
<li>Query</li>
</ul>
</li>
<li>시퀀스 투 시퀀스 모델과 비교했을 때, 트랜스포머가 채텍한 설계 철학<ul>
<li>순환 신경망을 사용하지 않고 병렬 처리 + 셀프 어텐션</li>
</ul>
</li>
<li>트랜스포머 디코더에서 학습 시 미래의 정답 단어를 미리 참조하지 못하도록 차단하는 기법<ul>
<li>인과적 마스크</li>
</ul>
</li>
</ul>
<h1 id="hugging-face">Hugging Face</h1>
<ul>
<li>Hugging Face<ul>
<li>전 세계의 고성능 오픈소스 모델을 표준화된 인터페이스로 제공하는 플랫폼</li>
</ul>
</li>
</ul>
<h3 id="허깅페이스-구성-요소">허깅페이스 구성 요소</h3>
<ul>
<li>파이프라인 ( Pipeline )<ul>
<li>토큰화, 인코딩, 모델 연산, 소프트맥스 확률 변환 등 추론에 필요한 전 과정을 추상화하여 제공하는 상위 API</li>
</ul>
</li>
<li>자동 클래스 ( Auto Class )<ul>
<li>AutoTokenizer, AutoModel 등의 클래스를 사용하면, 모델 이름 문자열만으로 적합한 전용 아키텍쳐와 가중치를 자동으로 다운로드 및 설정</li>
</ul>
</li>
</ul>
<h3 id="토크나이저--tokenizer-">토크나이저 ( Tokenizer )</h3>
<ul>
<li>모델의 임베딩 레이어는 가공되지 않은 텍스트를 직접 처리할 수 없으므로, 정해진 사전에 맞게 단어를 쪼개고 고유 정수 ID로 매핑하는 과정이 필요함</li>
</ul>
<h4 id="bpf--byte-pair-encoding-">BPF ( Byte Pair Encoding )</h4>
<ul>
<li>데이터에서 가장 빈번하게 등장하는 글자 쌍을 반복적으로 병합하여 어휘 사전을 구축하는 알고리즘</li>
<li>현대 LLM의 기반</li>
</ul>
<h4 id="wordpiece">WordPiece</h4>
<ul>
<li>BPE와 유사하게 빈도 기반으로 작동, 단순히 자주 겹치는 단어 쌍을 합치는 것을 넘어 통합했을때 전체 코퍼스의 우도(Likeihood)를 얼마나 높이는지 통계적으로 계산하여 분할.</li>
<li>전체 코퍼스의 우도란?<ul>
<li>내가 만든 언어 모델이 학습 데이터 전체를 얼마나 그럴듯하게 설명하느냐</li>
<li>언어 모델은 각 문장에 대해서 확률을 계산하는데, 전체 코퍼스의 우도는 이 확률들을 전부 곱한 값.</li>
</ul>
</li>
</ul>
<h4 id="sentencepiece">SentencePiece</h4>
<ul>
<li>BPE나 WordPiece와 다르게 문장에 사전 공백이 존재하지 않아도 처리가 가능한 독립형 전처리 라이브러리</li>
<li>공백 자체를 특수 기호로 취급하여 처리하므로, 띄어쓰기 규칙이 불규칙한 한국어나 공백이 없는 중국어, 일본어에 효과적</li>
</ul>
<h1 id="sql-data">SQL, Data</h1>
<ul>
<li><p>데이터 : 처리되지 않은 원시 값</p>
</li>
<li><p>정보 : 데이터에 의미를 부여</p>
</li>
<li><p>DB</p>
<ul>
<li>데이터의 집합</li>
<li>단순히 모아두는 것이 아니라 효율적인 저장 및 조회가 가능하도록 구조화된 저장공간</li>
</ul>
</li>
<li><p>DBMS ( Data Base Management System )</p>
<ul>
<li>데이터 베이스 관리 소프트웨어</li>
<li>데이터 무결성 제약조건을 지키기 위해 사용</li>
<li>RDBMS ( Relation DBMS )<ul>
<li>테이블 간의 관계</li>
</ul>
</li>
</ul>
</li>
<li><p>SQL ( Structured Query Language)</p>
<ul>
<li>데이터베이스에 보내는 질문, 질의의 문법적 규칙</li>
</ul>
</li>
<li><p>테이블</p>
<ul>
<li>데이터를 저장하기 위한 공간</li>
<li>행과 열로 구성된 2차원 구조<ul>
<li>행 ( Row / Record )</li>
<li>열 ( Column / Field / 속성 )</li>
<li>셀 : 각각의 데이터</li>
</ul>
</li>
</ul>
</li>
<li><p>스키마 </p>
<ul>
<li>테이블의 구조 및 제약사항을 정의한 명세서 or 설계도</li>
</ul>
</li>
</ul>
<h3 id="데이터-무결성-제약-조건">데이터 무결성 제약 조건</h3>
<ul>
<li>도메인 무결성 제약 조건<ul>
<li>동일 컬럼은 동일한 자료형 이어야 함</li>
</ul>
</li>
<li><h2 id="개체-무결성-제약-조건--기본키-제약-조건-">개체 무결성 제약 조건 ( 기본키 제약 조건 )</h2>
</li>
<li><h2 id="참조-무결성-제약-조건">참조 무결성 제약 조건 </h2>
</li>
</ul>
<h3 id="sql-data-type">SQL Data type</h3>
<ul>
<li>정수형 <ul>
<li>int ( 4 byte )</li>
<li>smallint ( 2 byte )</li>
<li>bigint ( 8 byte )</li>
</ul>
</li>
<li>실수형<ul>
<li>REAL ( 4 byte )</li>
<li>DOUBLE PRECISION ( 8 byte )</li>
<li>DECIMAL(p, s) : 소수점이 있는 숫자 ( 전체 p 자리, 소수점 s 자리)</li>
</ul>
</li>
<li>문자형<ul>
<li>CHAR(자리수) : 고정 사이즈 문자</li>
<li>varchar(n) : 가변 길이 문자열 (최대 n의 크기만큼)</li>
<li>text : 긴 문자열 ( 길이 제한 없는 가변 문자열 )</li>
</ul>
</li>
<li>Boolean : True / False / Null ( 1 byte )</li>
<li>날짜 시간<ul>
<li>Date : 날짜 YYYY-MM-DD 형식</li>
<li>Time : 시간 HH:MM:SS 형식</li>
<li>timestamp : 날짜 + 시간 </li>
<li>timestampz : 날짜 + 시간 + 시간대</li>
</ul>
</li>
<li>JSON<ul>
<li>jsonb : 바이너리 형태로 저장 , 속도가 빨라서 권장됨</li>
<li>json </li>
</ul>
</li>
<li>기타<ul>
<li>enum : 열거형, 지정된 항목 내에서만 데이터 선택이 가능하도록 함</li>
<li>vector(차원수) : 벡터 db에서 사용</li>
</ul>
</li>
</ul>
<h3 id="회원-테이블-구성">회원 테이블 구성</h3>
<p><img src="https://velog.velcdn.com/images/_bao_/post/293ba0f9-f895-435c-8d5d-a543f958e7a6/image.png" alt=""></p>
<h3 id="기본키--primary-key-">기본키 ( Primary key )</h3>
<ul>
<li>하나의 레코드를 식별할 수 있는 대표 컬럼 또는 컬럼의 조합</li>
<li>중복 금지 및 Null 금지</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.9.1 / Tue]]></title>
            <link>https://velog.io/@_bao_/26.9.1-Tue</link>
            <guid>https://velog.io/@_bao_/26.9.1-Tue</guid>
            <pubDate>Tue, 01 Sep 2026 13:29:31 GMT</pubDate>
            <description><![CDATA[<h3 id="시퀀스-투-시퀀스--seq2seq--아키텍처">시퀀스 투 시퀀스 ( Seq2Seq ) 아키텍처</h3>
<ul>
<li>순환 신경망 이용</li>
<li>주로 변역에서 사용 목적으로 연구</li>
<li>인코더 ( 문장 이해, 컨텍스트 벡터 ) - 디코더 ( 문장 생성, 인코더의 컨텍스트 벡터를 초기값으로 )</li>
<li>인코더는 LSTM 레이어 활용 : 은닉 상태(단기기억), 셀 상태(장기기억)</li>
</ul>
<h3 id="인코더">인코더</h3>
<ul>
<li>입력 단어들을 순차적으로 읽으며 문장의 전체 맥락을 하나의 벡터로 압축</li>
<li>정보 유실을 방지 하기 위하여 LSTM 레이어 활용</li>
<li>단기 기억 담당인 은닉 상태(h), 장기 기억 담당인 셀 상테 (c)를 업데이트<img src='./imgs/Incoder.png'>

</li>
</ul>
<img src='./imgs/Incoder_context_vecter.png'>

<h3 id="컨텍스트-벡터">컨텍스트 벡터</h3>
<ul>
<li>입력 문장의 마지막 단어 시점에서 도출된 최종 은닉 상태와 셀 상태의 세트</li>
<li>입력 문장의 전체 맥락이 컨텍스트 벡터에 압축</li>
</ul>
<h3 id="디코더">디코더</h3>
<ul>
<li>인코더가 전달한 최종 컨텍스트 벡터를 초기 은닉 상태와 셀 상태로 설정</li>
<li>번역할 언어의 단어를 한 단계씩 예측하여 생성</li>
<li>문장 시작 토큰 &lt; sos &gt;, 종료 토큰 &lt; eos &gt;</li>
</ul>
<h4 id="교사-강요-teacher-forcing">교사 강요 (Teacher Forcing)</h4>
<ul>
<li>학습 초기에 디코더가 잘못된 단어를 예측하더라도, 다음 시점의 입력으로 디코더의 예측값 대신 실제 정답을 강제로 주입</li>
</ul>
<h3 id="고정-크기-컨텍스트-벡터의-한계">고정 크기 컨텍스트 벡터의 한계</h3>
<ul>
<li>병목 현상 ( Bottleneck Problem )<ul>
<li>입력 문장의 길이에 상관 없이 컨텍스트 벡터의 길이는 항상 고정되어 있다.</li>
<li>LSTM 레이어를 선언할때 Hidden state의 값으로 지정</li>
</ul>
</li>
<li>정보 유실<ul>
<li>짧은 문장은 효과적으로 압축하지만, 문장이 길어질수록 고정된 크기의 벡터에 많은 정보를 담아야 하므로 앞부분에 입력된 단어 정보가 점차 유실되는 현상</li>
</ul>
</li>
</ul>
<h3 id="임베딩">임베딩</h3>
<ul>
<li>자연어 토큰을 신경망이 수치 연산을 진행할 수 있도록 고정된 차원의 연속적인 밀집 벡터로 매핑하는 변환 기법</li>
</ul>
<h1 id="어텐션-메커니즘">어텐션 메커니즘</h1>
<h3 id="기존-시퀀스-투-시퀀스-모델의-한계">기존 시퀀스 투 시퀀스 모델의 한계</h3>
<ul>
<li>정보 압축의 한계<ul>
<li>입력 문장의 길이에 상관없이 무조건 고정된 크기의 컨텍스트 벡터 하나에 전체 문맥을 압축해야 함</li>
</ul>
</li>
<li>정보 손실<ul>
<li>짧은 문장은 효과적으로 압축하지만, 문장이 길어질수록 고정된 크기의 벡터에 많은 정보를 담아야 하므로 앞부분에 입력된 단어 정보가 점차 유실되는 현상</li>
</ul>
</li>
<li>구조적 결합<ul>
<li>대규모 학습 데이터를 사용하더라도 문장이 길어질수록 문장 앞부분의 정보가 점차 유실되는 현상을 해결하기 어려움</li>
</ul>
</li>
</ul>
<h3 id="어텐션-메커니즘-1">어텐션 메커니즘</h3>
<ul>
<li>모든 상태를 활용<ul>
<li>모든 은닉 상태를 보관</li>
</ul>
</li>
<li>선택적 주의 집중<ul>
<li>매 단어 생성 시에 인코더의 단어들을 다시 확인</li>
<li>현재 예측하려는 단어와 관련성이 높은 성분에 더 높은 가중치 부여</li>
</ul>
</li>
<li>Q, K, V 벡터<ul>
<li>Query : 무엇을 찾을 것인가</li>
<li>Key   : 어떻게 찾을 것인가 ( 이름표 )</li>
<li>Value : Key를 통해서 찾은 의미 정보</li>
</ul>
</li>
<li>번역 과정에서 한국어와 영어의 어순의 차이가 있더라도, 어텐션 메커니즘이 단어 간의 올바른 연관 관계를 찾아낸다</li>
</ul>
<h3 id="언텐션-메커니즘-작동-원리">언텐션 메커니즘 작동 원리</h3>
<ul>
<li>사용자가 입력한 검색어(Query)를 바탕으로 데이터베이스의 키워드(Key)를 검색한 뒤, 이와 가장 매칭 되는
실제 데이터(Value)를 가져오는 과정</li>
</ul>
<h3 id="어텐션-연산의-3단계-흐름">어텐션 연산의 3단계 흐름</h3>
<ul>
<li><p>유사도 측정</p>
<ul>
<li><p>디코더의 현재 상태와 인코더의 각 단어 이름표를 내적하여 단어 간의 유사도 점수 계산</p>
<p>$\text{Score}(Q, K) = Q \cdot K^T$ </p>
</li>
</ul>
</li>
<li><p>가중치 분해</p>
<ul>
<li><p>유사도 점수에 소프트맥스를 적용하여 총합이 1(100%)가 되는 확률 분포 형태의 가중치로 변환</p>
<p>$\text{Attention Weights} = \text{Softmax}(\text{Score})$</p>
</li>
</ul>
</li>
<li><p>가중합 계산</p>
<ul>
<li>계산된 가중치를 각 Value 벡터에 곱한 후 모두 더해서, 현재 시점에 가장 필요한 최종 요약 벡터 생성
$\text{Context Vector} = \sum (\text{Attention Weights} \times V)$</li>
</ul>
</li>
</ul>
<h3 id="어텐션-메커니즘의-등장">어텐션 메커니즘의 등장</h3>
<ul>
<li>모든 상태의 활용<ul>
<li>입력 문장의 단어 정보를 버리지 않고, 디코더가 언제든 참조할 수 있도록 인코더의 모든 은닉 상태 보관</li>
</ul>
</li>
<li>선택적 주의 집중<ul>
<li>디코더가 매 단어를 생성할 때마다 인코더의 단어들을 다시 확인, 현재 예측하려는 단어와 관련성이 높은 성분에 더 높은 가중치 부여</li>
</ul>
</li>
<li>번역 품질 향상<ul>
<li>모델이 단어 간의 직접적인 연관 관계를 학습하게 되면서, 복잡한 어순이나 긴 문장에서도 변역 성능 크게 개선</li>
</ul>
</li>
</ul>
<h3 id="토큰-임베딩-벡터-생성-순서-상실-문제">토큰 임베딩 벡터 생성, 순서 상실 문제</h3>
<ul>
<li>컴퓨터는 자연어 문자열 자체를 연산할 수 없으므로, 문장을 최소 단위인 토큰으로 쪼갠 뒤 고차원 실수 공간의 좌표로 변환하는 임베딩 벡터 생성 과정이 선행</li>
<li>각 단어는 고유한 의미적 힌트를 담은 은닉 차원 크기의 숫자 배열 벡터로 재탄생</li>
<li>트랜스포머는 문장 속 단어들을 순서대로 읽지 않고, 모든 단어 임베딩 벡터를 한꺼번에 병렬로 모델에 주입하므로 연산 속도가 압도적으로 빠르다</li>
</ul>
<img src = 1>

<ul>
<li>위 사진의 토큰의 임베딩 벡터 -&gt; 인코더 블록 적층 구간을 보면 문장이 통째로 유입되는 구조를 볼 수 있다</li>
<li>모든 단어가 동시에 연산 레이어에 쏟아지다 보니, 모델 입장에서는 어떤 단어가 몇번째 자리에 왔는지에 대한 선후 관계를 분간하지 못한다</li>
<li>위치 인코딩이 없다면, I love you와 you love me라는 완전히 다른 두 문장의 어텐션 스코어 판이 토큰 위치에 상관없이 동일하게 계산되는 치명적인 부작용이 발생</li>
<li>단어들의 자리가 바뀌어도 어텐션 점수가 같게 나오는 문제를 해결하기 위해, 단어의 문장 내 절대 위치에 따라 변하는 벡터를 생성하여 기존 임베딩에 더하는 과정이 필수적</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[26.8.31 / Mon]]></title>
            <link>https://velog.io/@_bao_/26.8.31-Mon</link>
            <guid>https://velog.io/@_bao_/26.8.31-Mon</guid>
            <pubDate>Mon, 31 Aug 2026 14:24:57 GMT</pubDate>
            <description><![CDATA[<h1 id="pytorch--심층-신경망">pytorch &amp; 심층 신경망</h1>
<h3 id="pytorch">pytorch</h3>
<h4 id="인공신경망-구축">인공신경망 구축</h4>
<p>딥러닝 모델(AI)을 만들고 학습시키는 데 필요한 모든 수학적 연산과 신경망 레이어를 제공합니다.</p>
<h4 id="텐서tensor-연산">텐서(Tensor) 연산</h4>
<p>파이썬의 넘파이(NumPy)처럼 다차원 행렬 연산을 수행하지만, 핵심은 <strong>GPU 가속</strong>을 지원하여 엄청나게 빠른 연산이 가능하다는 점입니다.</p>
<h4 id="자동-미분autograd">자동 미분(Autograd)</h4>
<p>AI가 스스로 학습할 수 있도록 역전파(Backpropagation) 미분 계산을 자동으로 처리합니다.</p>
<h3 id="단층-퍼셉트론--다층-퍼셉트론">단층 퍼셉트론 &amp; 다층 퍼셉트론</h3>
<h4 id="단층-퍼셉트론--은닉층-x-">단층 퍼셉트론 ( 은닉층 X )</h4>
<ul>
<li>입력 신호($X$)에 가중치($W$)를 곱하고 편향($b$)을 더하여 곧바로 최종 출력 점수를 산출하는 구조</li>
<li>직선 형태의 판별선만 그릴수 있어서, 곡선형태나 복잡한 실제 데이터를 분류하는데 한계가 있음</li>
</ul>
<h4 id="다층-퍼셉트론--은닉층-o-">다층 퍼셉트론 ( 은닉층 O )</h4>
<ul>
<li>입력 정보가 출력층으로 바로 전달되는 것이 아닌, 중간에 정보를 다각도로 연산하는 은닉 뉴련 (Hidden Neuron)층을 거치는 구조</li>
<li>첫 번째 층이 저차원의 특징(선,면)을 감지하면, 은닉층은 이 특징들을 조합하여 사물의 형태, 질감과 같은 고차원 정보를 활성화 함수를 통해 학습</li>
</ul>
<h3 id="모델-파라미터">모델 파라미터</h3>
<ul>
<li>은닉층을 추가하면서 가중치의 개수가 폭증하게 되고, 이를 통해 늘어난 파라미터만큼 모델은 더 복잡한 데이터의 패턴을 포착할 수 있는 잠재력을 갖게 된다</li>
</ul>
<h4 id="은닉층-증가에-따른-단점">은닉층 증가에 따른 단점</h4>
<ul>
<li>단점<ul>
<li>과적합의 위험<ul>
<li>모델의 표현력인 파라미터 수가 과도해지면, 데이터의 본질적인 규칙을 찾는 것이 아니라 훈련 데이터의 학습할 필요 없는 지엽적인 특징까지 학습하게 된다.</li>
<li>학습에는 정확도가 100% 가까이 나오지만, 한 번도 보지못한 새로운 데이터를 받게 되면 엉뚱한 답을 내놓으며 예측 성능이 떨어지게 된다</li>
</ul>
</li>
<li>연산 비용 및 시간의 급격한 증가<ul>
<li>은닉층을 하나씩 추가할 때마다 조율해야 하는 가중치와 편향의 개수가 기하급수적으로 늘어남</li>
<li>파라미터가 많아질수록 모델을 학습시키는데 더 많은 컴퓨터의 메모리와 더 긴 학습시간이 소요되게 된다</li>
</ul>
</li>
<li>기울기 소실<ul>
<li>층이 깊어지면 출력층에서 계산된 오차가 입력층 쪽으로 역전파 되는 과정에서 점차 희미해지는 현상이 발생한다.</li>
<li>앞쪽 층에 있는 파라미터들이 제대로 업데이트 되지 않아서, 층을 많이 쌓았음에도 불구하고 학습이 이루어지지 않는 역효과가 발생할 수 있다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="신경망-학습의-4단계-순환-구조">신경망 학습의 4단계 순환 구조</h3>
<h4 id="순방향-예측-forward-pass">순방향 예측 Forward Pass</h4>
<ul>
<li>입력 데이터가 신경망의 각 층을 통과하며 최종 예측값을 산출하는 과정</li>
</ul>
<h4 id="손실-계산-loss-calculation">손실 계산 Loss Calculation</h4>
<ul>
<li>실제 정답과 모델의 예측값을 비교하여 오차의 크기를 하나의 Loss로 산출 한다</li>
</ul>
<h4 id="역방향-오차-전파-backpropagation">역방향 오차 전파 Backpropagation</h4>
<ul>
<li>출력층에서 발생한 오차를 입력층 방향으로 거꾸로 전파하면서, 미분의 연쇄법칙을 통해 각 가중치가 오차에 미친 영향도(기울기)를 계산</li>
</ul>
<h4 id="가중치-조정-optimizer">가중치 조정 Optimizer</h4>
<ul>
<li>계산된 기울기를 바탕으로 오차가 최소화되는 방향으로 가중치를 업데이트</li>
</ul>
<h4 id="역전파의-한계선">역전파의 한계선</h4>
<ul>
<li>수식에서 기울기를 계산하는 것만 관여한다</li>
<li>학습률, 에포크 등은 전혀 모른채, 현재 상태의 미분값만 컴퓨터 메모리에 기록하고 자기 역할을 끝냄</li>
</ul>
<h4 id="옵티마이저의-시작점">옵티마이저의 시작점</h4>
<ul>
<li>역전파가 전달한 기울기를 받으며 작동을 시작한다</li>
<li>하이퍼 파라미터로 설정된 학습률을 이 편미분 값 앞에 곱해주는 주체</li>
<li>실제 가중치에서 이 값을 빼 새로운 값으로 업데이트 하는 최종 행위자</li>
</ul>
<h3 id="옵티마이저-종류">옵티마이저 종류</h3>
<h4 id="sgd-확률적-경사하강법">SGD (확률적 경사하강법)</h4>
<ul>
<li>현재 위치에서 계산된 경사도가 가장 가파른 내리막 방향으로 일정 보폭만큼 이동</li>
<li>구조가 단순하지만, 국소 최적점이나 고윈 현상을 만나면 학습이 정체되거나 진행 방향이 불안정하게 흔들릴 수 있다</li>
</ul>
<h4 id="momentum">Momentum</h4>
<ul>
<li>경사하강법에 관성의 개념을 도입하여 이전에 이동하던 방향과 속도를 유지하려는 성질을 더함</li>
<li>완만한 경사나 국소 최적점을 관성의 힘으로 통과하여 더 빠르게 최적점에 도달 할 수 있음</li>
</ul>
<h4 id="adam-adaptive-moment-estimation">Adam (Adaptive Moment Estimation)</h4>
<ul>
<li>관성을 고려하는 Momentum과 파라미터별 보폭을 조절하는 RMSprop의 장점을 결합한 하이브리드 알고리즘</li>
<li>딥러닝 태스크에서 안정적이고 우수한 성능을 보여주어 기본 옵티마이저로 사용됨</li>
</ul>
<h3 id="활성화-함수--비선형성-주입-relu">활성화 함수 &amp; 비선형성 주입, ReLU</h3>
<h4 id="은닉층-활성화-함수비선형성-주입">은닉층 활성화 함수(비선형성 주입)</h4>
<ul>
<li>은닉층 선형 연산(W * X + b) 결과에 비선형 특성을 부여하는 역할</li>
</ul>
<h4 id="출력층-활성화-함수-결과-해석-및-확률-변환">출력층 활성화 함수 (결과 해석 및 확률 변환)</h4>
<ul>
<li>모델이 최종 계산한 점수(Logits)를 문제의 목적에 맞는 형태로 변환</li>
<li>다중 분류에서는 점수들을 0과 1 사이의 값으로 만들고 전체 합이 1이 되도록 확률 분포로 압축하기 위해 Softmax 사용</li>
</ul>
<h4 id="은닉층에-비선형-활성화-함수가-필수인-이유">은닉층에 비선형 활성화 함수가 필수인 이유</h4>
<ul>
<li>활성화 함수 없이 선형층을 깊게 쌓아도, 수학적으로는 결국 하나의 단층 선형 모델과 동일해진다</li>
<li>모델이 선형 분리가 불가능한 복잡한 현실의 패턴을 학습하기 위해서는, 레이터 사이에 선형 결합을 구부리는 비선형 활성화 함수가 필요</li>
</ul>
<h3 id="시그모이드의-한계--기울기-소실">시그모이드의 한계 : 기울기 소실</h3>
<ul>
<li>초기 딥러닝에는 은닉층에도 시그모이드 사용</li>
<li>시그모이드는 입력 값이 양방향 극단(-5 이하 또는 +5 이상)으로 치우치면 그래프의 경사도(미분값)가 0에 가깝게 평평해지는 특성이 있음</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>