<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>moon_dd.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Tue, 08 Aug 2023 07:50:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. moon_dd.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/moon_dd" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[SQL + PL/SQL]]></title>
            <link>https://velog.io/@moon_dd/SQL-PLSQL</link>
            <guid>https://velog.io/@moon_dd/SQL-PLSQL</guid>
            <pubDate>Tue, 08 Aug 2023 07:50:00 GMT</pubDate>
            <description><![CDATA[<h1 id="sql">SQL</h1>
<h2 id="1-개요">1. 개요</h2>
<hr>
<h3 id="sql-1">SQL</h3>
<ul>
<li>Structed Query Language → 구조화된 질의 언어</li>
<li>DBMS에서 데이터를 조작, 관리하기 위한 프로그램 언어</li>
<li>집합적 언어<ul>
<li>데이터를 특정 집합 단위로 분류해 단위별로 처리하는 언어</li>
<li>절차적 언어 → 프로그래밍 순서대로 로직 처리</li>
</ul>
</li>
</ul>
<h3 id="ddl">DDL</h3>
<p>Data Definition Language</p>
<p>데이터베이스 객체를 관리</p>
<ul>
<li>CREATE</li>
<li>DROP</li>
<li>ALTER</li>
<li>TRUNCATE</li>
</ul>
<h3 id="dml">DML</h3>
<p>Data Manipulation Language</p>
<p>데이터를 조작하는 언어</p>
<ul>
<li>SELECT</li>
<li>INSERT</li>
<li>UPDATE</li>
<li>DELETE</li>
<li>COMMIT</li>
<li>ROLLBACK</li>
</ul>
<h3 id="plsql">PL/SQL</h3>
<ul>
<li>SQL을 절차적으로 사용하는 언어</li>
<li>변수 할당, 예외처리, 함수 생성 가능</li>
<li>DB 서버에서 컴파일 된다는 특징이 있다.</li>
</ul>
<h2 id="2-데이터베이스의-객체">2. 데이터베이스의 객체</h2>
<hr>
<p>데이터베이스에 존재하는 논리적인 저장 구조</p>
<h3 id="데이터베이스-객체의-종류">데이터베이스 객체의 종류</h3>
<h3 id="1-테이블">(1) 테이블</h3>
<p>데이터를 담고 있는 객체</p>
<p>행과 열로 구성되어 있다.</p>
<p><strong>데이터 타입</strong></p>
<ul>
<li>문자 데이터 타입<ul>
<li>CHAR : 고정</li>
<li>VARCHAR2 : 가변</li>
</ul>
</li>
<li>숫자 데이터 타입</li>
<li>날짜 데이터 타입<ul>
<li>DATE</li>
<li>TIMESTAMP</li>
</ul>
</li>
<li>LOB 데이터 타입</li>
<li>NULL</li>
</ul>
<p><strong>제약조건</strong></p>
<ul>
<li><p>NOT NULL</p>
</li>
<li><p>UNIQUE</p>
</li>
<li><p>기본키</p>
</li>
<li><p>외래키</p>
<p>  테이블 간의 참조 데이터 무결성을 위한 제약조건</p>
</li>
<li><p>CHECK</p>
<p>  컬럼에 입력되는 데이터를 특정 조건에 맞는 지 확인</p>
</li>
</ul>
<h3 id="2-뷰">(2) 뷰</h3>
<p>하나 이상의 테이블이나 다른 뷰의 데이터를 볼 수 있다.</p>
<p>테이블, 뷰 참조하여 새로운 뷰 생성 가능</p>
<p>실제로 만들어진 테이블은 아니지만 테이블처럼 사용가능하다.</p>
<p>데이터 보안 측면에서 유리</p>
<h3 id="3-인덱스">(3) 인덱스</h3>
<p>여러가지 인덱스 종류가 있지만 B-tree 인덱스가 가장 일반적이다</p>
<p>특정 컬럼들을 기준으로 정렬해 해당 컬럼으로 조회하는 기능의 성능을 높이려는 목적</p>
<p>하지만 데이터 동기화로 인해 오히려 너무 많이 만들면 오히려 과부화로 성능이 낮아질 수 있다.</p>
<h3 id="4-시노님">(4) 시노님</h3>
<p>동의어, 별명 같은 기능</p>
<ul>
<li>Public : 모든 사용자가 접근 가능</li>
<li>Private : 특정 사용자에게만 참</li>
</ul>
<p><strong>사용하는 이유</strong></p>
<ul>
<li>데이터 베이스 투명성 제공을 위해 사용다른 사용자의 객체를 참조할 때 많이 사용</li>
<li>시노님이 참조하던 객체의 이름이 바뀌어도 이전에 작성한 SQL문 수정할 필요가 없다.</li>
<li>별칭으로 사용되기에 원 객체를 숨길 수 있다.</li>
</ul>
<h3 id="5-시퀀스">(5) 시퀀스</h3>
<p>자동 순번을 반환하는 데이터베이스 객체</p>
<h3 id="6-파티션-테이블">(6) 파티션 테이블</h3>
<p>논리적으로 1개 테이블이지만 물리적으로 분할한 만큼 파티션이 만들어저 컬럽 값에 따라 데이터가 분리되서 저장된다.</p>
<p>대용량  데이터테이블 조회 시 효율성과 성능을 높여준다.</p>
<h2 id="3-sql-문장">3. SQL 문장</h2>
<hr>
<ol>
<li><p>SELECT</p>
</li>
<li><p>INSERT</p>
</li>
<li><p>UPDATE</p>
</li>
<li><p>MERGE</p>
<p> 조건을 비교해 조건에 맞는 데이터가 없으면 → INSERT  / 있으면 → UPDATE</p>
</li>
<li><p>DELETE</p>
</li>
<li><p>COMMIT</p>
<p> 변경한 데이터를 반영하는 역할</p>
</li>
<li><p>ROLLBACK</p>
<p> 반영한 데이터를 이전 상태롤 되돌리는 역할</p>
</li>
<li><p>TRUNCATE</p>
<p> DELETE의 역할과 동일하지만 COMMIT을 하지않아도 반영이 되고 ROLLBACK X</p>
</li>
<li><p>의사컬럼</p>
<p> 테이블의 컬럼처럼 동작하지만 실제로 테이블레 저장 X</p>
</li>
<li><p>연산자</p>
</li>
<li><p>표현식</p>
<p>1개 이상의 값과 연산자, SQL 함수로 결합된 식</p>
<ul>
<li>CASE ~ WHEN ~ THEN / ELSE / END</li>
</ul>
</li>
<li><p>조건식</p>
<ul>
<li><p>비교 조건식</p>
<p>  논리 연산자 혹은 ANY, SOME, ALL 키워드로 비교</p>
</li>
<li><p>논리 조건식</p>
</li>
<li><p>NULL</p>
</li>
<li><p>BETWEEN AND</p>
</li>
<li><p>IN</p>
</li>
<li><p>EXIST</p>
</li>
<li><p>LIKE</p>
</li>
</ul>
</li>
</ol>
<h2 id="4-sql-함수">4. SQL 함수</h2>
<hr>
<h3 id="1-숫자-함수">(1) 숫자 함수</h3>
<ul>
<li>ABS(n)</li>
<li>CEIL(n), FLOOR(n)</li>
<li>ROUND(n, i), TRUNC(n1,n2)</li>
<li>POWER(n2, n1), SORT(n)</li>
<li>MOD(n2,n1), REMAINDER(n2,n1)</li>
<li>EXP(n), LN(n), LOG(n2,n1)</li>
</ul>
<h3 id="2-문자-함수">(2) 문자 함수</h3>
<ul>
<li>INITCAP(char), LOWER(char), UPPER(char)</li>
<li>CONCAT(char1, char2), SUBSTR(char, pos, len), SUBSTRB(char, pos, len)</li>
<li>LTRIM(char, set), RTRIM(char, set)</li>
<li>LPAD(expr1, n, expr2), RPAD(expr1, n, expr2)</li>
<li>REPLACE(char, search_str, replace_str), TRANSLATE(expr, from_str, to_str)</li>
<li>INSTR(str, substr, pos, occure), LENGTH(chr), LENGTH(chr)</li>
</ul>
<h3 id="3-날짜-함수">(3) 날짜 함수</h3>
<ul>
<li>SYSDATE, SYSTIMESTAMP</li>
<li>ADD_MONTHS(date, integer)</li>
<li>MONTHS_BETWEEN(date1, date2)</li>
<li>LAST_DAY(date)</li>
<li>ROUND(date,format), TRUNC(date, format)</li>
</ul>
<h3 id="4-변환-함수">(4) 변환 함수</h3>
<ul>
<li>TO_CHAR(숫자 혹은 날짜, format)</li>
<li>TO_NUMBER(expr, format)</li>
<li>TO_DATE(char, format)</li>
</ul>
<h3 id="5-null-관련-함수">(5) NULL 관련 함수</h3>
<ul>
<li>NVL(expr1, expr2), NVL2(expr1,expr2,expr3)</li>
<li>COALESCE(expr1, expr2, …)</li>
<li>LNNVL(조건식)</li>
</ul>
<h3 id="6-기타-함수">(6) 기타 함수</h3>
<ul>
<li>GREATEST(expr1, expr2, …), LEAST(expr1, expr2, …)</li>
<li>DECODE(expr, search1, result1 ..)</li>
</ul>
<h2 id="5-그룹-쿼리와-집합-연산자">5. 그룹 쿼리와 집합 연산자</h2>
<hr>
<h3 id="1-기본-집계-함수">(1) 기본 집계 함수</h3>
<h3 id="2-group-by절-having-절">(2) GROUP BY절, HAVING 절</h3>
<h3 id="3-roll-up절-cube-절">(3) ROLL UP절, CUBE 절</h3>
<h3 id="4-집합-연산자">(4) 집합 연산자</h3>
<ol>
<li>ROLL UP절 / CUBE  </li>
</ol>
<h2 id="6-조인과-서브-쿼리">6. 조인과 서브 쿼리</h2>
<hr>
<h3 id="내부조인--외부조인">내부조인 &amp; 외부조인</h3>
<p><strong>(1) 내부 조인</strong></p>
<ul>
<li><p>동등 조인</p>
<p>  <code>WHERE</code> 사용</p>
</li>
<li><p>세미 조인</p>
<p>  <code>IN</code>, <code>EXIST</code> 사용하여 서브쿼리 이용</p>
</li>
<li><p>안티 조인</p>
<p>  <code>NOT IN</code>, <code>NOT EXIST</code></p>
</li>
<li><p>셀프 조인</p>
</li>
</ul>
<p><strong>(2) 외부 조인</strong></p>
<p>조인 조건 모두에 (+)를 붙여야한다.</p>
<p><strong>(3) 카타시안 조인</strong></p>
<p>WHERE X </p>
<h3 id="ansi-조인">ANSI 조인</h3>
<p><strong>(1) ANSI 내부 조인</strong></p>
<p><code>INNER JOIN + ON / USING + 테이블명.컬럼명 / 컬럼명</code></p>
<p><strong>(2) ANSI 외부 조인</strong></p>
<p><code>LEFT/RIGHT [OUTER] JOIN + ON</code> </p>
<p><strong>(3) CROSS 조인</strong></p>
<p>= 카타시안 조인</p>
<p><strong>(4) FULL OUTER 조인</strong></p>
<h3 id="서브쿼리">서브쿼리</h3>
<p><strong>서브쿼리</strong></p>
<p>SQL 문장안에서 보조로 사용되는 SELECT문</p>
<p>메인 쿼리를 제외한 나머지 모든 SELECT 문</p>
<p>조건식에 주로 사용된다.</p>
<p><strong>인라인 뷰</strong></p>
<p>FROM 절에 사용된느 서브 쿼리를 인라인 뷰라고 한다. </p>
<h2 id="7-고급-쿼리">7. 고급 쿼리</h2>
<hr>
<h3 id="계층형-구조">계층형 구조</h3>
<p>테이블에 저장된 데이터를 계층형 구조로 반환하는 쿼리를 <strong>계층형 쿼리</strong>라고 한다.</p>
<ul>
<li><strong>최상위 계층</strong> → <code>START WITH</code></li>
<li><strong>계층형 구조 조건</strong> → <code>CONNECT BY</code></li>
</ul>
<h3 id="계층형-쿼리-활용">계층형 쿼리 활용</h3>
<ul>
<li><code>ORDERY BY</code></li>
<li><code>CONNECT_BY_ROOT</code></li>
<li><code>CONNECT_BY_ISLEAF</code></li>
<li><code>SYS_CONNECT_BY_PATH</code></li>
<li><code>CONNECT_BY_ISCYCLE</code></li>
</ul>
<h3 id="with-절">WITH 절</h3>
<pre><code class="language-sql">WITH 별칭1 AS (SELECT 문).
         별칭2 AS (SELECT 문)
…
SELECT
FROM 별칭1, 별칭 2</code></pre>
<p>별칭으로 사용하는 SELECT문에서도 별칭 참조가 가능하다 </p>
<h3 id="순환-서브-쿼리">순환 서브 쿼리</h3>
<p>WITH절을 활용해서 계층형 쿼리를 만들 수 있다.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        </p>
<p>조회의 출력 순서를 자식 혹은 형제 로우를 기준으로 출력할 지 정할 수 있다.</p>
<ul>
<li><code>DEPTH FIRSTY BY</code></li>
<li><code>BREADTH FIRST BY</code></li>
</ul>
<h3 id="분석함수">분석함수</h3>
<p>테이블의 로우에 대해 특정 그룹별로 집계 값을 산출할 때 사용한다.</p>
<ul>
<li><code>ROW_NUMBER()</code></li>
<li><code>RANK()</code>, <code>DENSE_RANK()</code></li>
<li><code>CUME_DIST</code>, <code>PERCENT_RANK()</code></li>
<li><code>NTILE</code></li>
<li><code>LAG</code> <code>LEAD</code></li>
</ul>
<h3 id="window-절">Window 절</h3>
<p>파티션으로 분할된 그룹에 대해 범위를 정해 다시 부분 집합을 만든다.</p>
<pre><code class="language-sql">{ ROWS | RANGE }
    { BETWEEN { UNBOUNDED PRECENDING
                            | CURRENT ROW
                            | value_expr{ PRECEDING | FOLLOWING}
                        }
        AND { UNBOUNDED FOLLOWING
                    | CURRENT ROW
                    | value_expr{ PRECEDING | FOLLOWING }
                }
    | { UNBOUNDED PRECEDING
            | CURRENT ROW
            | value_expr PRECEDING}
}</code></pre>
<p>함수와 함께 사용될 수 있다.</p>
<ul>
<li><code>FIRST_VALUE()</code>, <code>LAST_VALUE()</code></li>
<li><code>NTH_VALUE()</code></li>
<li>….</li>
</ul>
<h3 id="다중-테이블-insert">다중 테이블 INSERT</h3>
<pre><code class="language-sql">INSERT ALL | FIRST
WHEN 조건 1 then
    INTO [스키마. ]테이블명(컬럼1, 컬럼2 .. ) VALUES(값1, 값2, ..)
..
ELSE
    INTO INTO [스키마. ]테이블명(컬럼1, 컬럼2 .. ) VALUES(값1, 값2, ..)
SELECT 문;</code></pre>
<h2 id="8-plsql-구조와-구성요소">8. PL/SQL 구조와 구성요소</h2>
<hr>
<h3 id="plsql-기본-구조">PL/SQL 기본 구조</h3>
<p><strong>블록</strong></p>
<p>프로그램 소스의 기본 단위</p>
<p><strong>구조</strong></p>
<pre><code class="language-sql">이름부 
IS(AS)
    선언부
BEGIN
    실행부
EXCEPTION
    예외 처리부
END;</code></pre>
<ul>
<li>이름부<ul>
<li>이름 x : 익명블럭</li>
<li>이름 o : 함수, 프로시저, 패키지</li>
</ul>
</li>
</ul>
<h3 id="plsql-구성요소">PL/SQL 구성요소</h3>
<p><strong>변수 선언</strong></p>
<p><code>변수명 데이터 타입 := 초깃값;</code></p>
<p><strong>상수 선언</strong></p>
<p><code>상수명 **CONSTANT** 데이터 타입 := 상수값:</code></p>
<p><strong>연산자</strong></p>
<p><strong>주석</strong></p>
<ul>
<li>-- 한줄 주석</li>
<li>/* 여러 줄 주석 */</li>
</ul>
<p><strong>DML문</strong></p>
<p><strong>SELECT문에서 INTO절</strong>을 사용해서 변수에 할당해준다.</p>
<p><strong>%TYPE</strong></p>
<p>변수의 데이터 타입을 컬럼 타입으로 가져온다.</p>
<h2 id="9-plsql-함수-프로시저">9. PL/SQL 함수, 프로시저</h2>
<hr>
<h3 id="plsql-제어문">PL/SQL 제어문</h3>
<ul>
<li>IF문</li>
<li>CASE문</li>
<li>LOOP문</li>
<li>WHILE문</li>
<li>FOR문</li>
<li>CONTINUE문</li>
<li>GOTO문</li>
<li>NULL문</li>
</ul>
<h3 id="plsql-사용자-정의-함수">PL/SQL 사용자 정의 함수</h3>
<p><strong>함수생성</strong></p>
<pre><code class="language-sql">CREATE OR REPLACE FUNCTION 함수이름 (매개변수1, 매개변수2, ...)
RETURN 데이터타입;
IS[AS]
    변수, 상수 선언
BEGIN
    실행부
    ...
    RETURN 반환값;
[EXCEPTION
    예외 처리부]
END [함수 이름];</code></pre>
<h3 id="프로시저">프로시저</h3>
<p>함수와 달리 특정한 로직만 처리하고 반환값 X</p>
<pre><code class="language-sql">CREATE OR REPLACE PROCEDURE 프로시저 이름 
    (매개변수1[IN |OUT|IN OUT ] 데이터타입[:= 디폴트값],
        매개변수1[IN |OUT|IN OUT ] 데이터타입[:= 디폴트값] ,
        ...
    )
IS[AS]
    변수, 상수 선언
BEGIN
    실행부
    ...

[EXCEPTION
    예외 처리부]
END [함수 이름];</code></pre>
<p>익명블록에서 함수, 프로시저, 패키지를 호출할때는 EXEC, EXECUTE를 붙이지 않는다.</p>
<h2 id="10-예외처리와-트랜젝션">10. 예외처리와 트랜젝션</h2>
<hr>
<h3 id="예외처리">예외처리</h3>
<pre><code class="language-sql">EXCEPTION WHEN 예외명1 THEN 예외처리 구문1
WHEN 예외명2 THEN 예외처리 구문2
...
WHEN OTHERS THEN 예외처리 구문n;</code></pre>
<ul>
<li>OTHERS는 맨 마지막 구문에 배치한다.</li>
<li>사용자 정의 예외는 예외 발생 시 로그를 남기고 관리하기 위해 모듈화하는 것을 권장한다.</li>
</ul>
<p><strong>예외정보 참조</strong></p>
<ul>
<li>SQLCODE, SQLERRM</li>
</ul>
<p><strong>사용자 정의 예외</strong></p>
<ol>
<li>선언부에 사용자 정의 예외 선언</li>
<li>PRAGAMA EXCEPTION_INIT(예외명, 코드) 이용해서 연결</li>
<li>RAISE, RAISE_APPLICATION_ERROR를 이용해 예외 발생</li>
<li>EXCEPTION WHEN ..을 이용해 예외 처리</li>
</ol>
<h3 id="트랜잭션">트랜잭션</h3>
<p><strong>COMMIT</strong></p>
<p><code>COMMIT [WORK];</code></p>
<p>테이블에 최종적으로 반영한다.</p>
<p><strong>ROLLBACK</strong></p>
<p><code>ROLLBACK [WORK] [TO [SAVEPOINT] 세이브포인트명];</code></p>
<p>변경사항 취소</p>
<p><strong>SAVEPOINT</strong></p>
<p><code>SAVEPOINT 세이브포인트명;</code></p>
<p>해당 savepoint 이전까지는 commit 된다.</p>
<h2 id="11-커서-레코드-컬렉션">11. 커서, 레코드, 컬렉션</h2>
<hr>
<h3 id="커서">커서</h3>
<p>SQL문장을 처리한 결과값의 위치를 가리키는 일종의 포인터 역할을 한다.</p>
<ul>
<li>묵시적 커서 → 오라클 내부에서 자동 생성되어 사용</li>
<li>명시적 커서  → 사용자가 직접 정의해서 사용</li>
</ul>
<p><strong>명시적커서의 사용단계</strong></p>
<ol>
<li><p>커서 정의</p>
<pre><code class="language-sql"> CURSOR 커서명 [(매개변수1, 매개변수2, ...)]
 IS
 SELECT 문장;</code></pre>
</li>
<li><p>커서 열기</p>
<pre><code class="language-sql"> OPEN 커서명 [(매개변수1, 매개변수2, ...)]</code></pre>
</li>
<li><p>패치</p>
<ol>
<li><p>LOOP 사용</p>
<pre><code class="language-sql"> LOOP
     FETCH 커서명 INTO 변수1, 변수2, ...;
     EXIT HEN 커서명%NOTFOUND;
 END LOOP;</code></pre>
</li>
<li><p>FOR문 사용</p>
<pre><code class="language-sql"> FOR 레코드 IN 커서명(매개변수1, 매개변수2, ...)
 LOOP
     처리문;
 END LOOP;</code></pre>
</li>
</ol>
</li>
<li><p>커서 닫기</p>
<pre><code class="language-sql"> CLOSE 커서명;</code></pre>
</li>
</ol>
<p><strong>커서 변수</strong></p>
<p>여러 쿼리에 재사용할 수 있는 커서 변수가 있다.</p>
<ol>
<li><p><strong>커서 변수 선언</strong></p>
<ul>
<li><p>강한 커서 타입</p>
<ul>
<li><p>방법1</p>
<pre><code class="language-sql">  TYPE 커서 타입명 IS REF CURSOR { RETURN 반환 타입};
  커서_변수명 커서_타입명;</code></pre>
</li>
<li><p>방법 2</p>
<p>  <code>커서_변수명 REFCURSOR;</code></p>
</li>
</ul>
</li>
<li><p>약한 커서 타입</p>
<ul>
<li><p>방법1</p>
<p>  <code>TYPE 커서_변수명 IS REF CURSOR;</code></p>
</li>
<li><p>방법2</p>
<p>  <code>커서_변수명 SYS_REFCURSOR;</code></p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>커서 변수 사용하기</strong></p>
<p> <code>OPEN 커서 변수명 FOR select 문;</code></p>
</li>
</ol>
<ol>
<li><strong>커서 변수에서 결과 집합 가져오기</strong><ul>
<li><code>FETCH 커서 변수명 INTO 변수1, 변수2, …;</code></li>
<li><code>FETCH 커서 변수명 INTO 레코드명;</code></li>
</ul>
</li>
</ol>
<p><strong>커서 표현식</strong></p>
<p>컬럼 형태로 커서를 사용하는 것</p>
<p><code>CURSOR (서브 쿼리)</code></p>
<h3 id="레코드">레코드</h3>
<p>여러 개의 값을 가지고 각각 타입이 다른 복합형 구조이다.</p>
<p>테이블의 로우와 비슷한 형태이다.</p>
<p>테이블의 컬럼을 레코드에서는 <strong>필드</strong>라고 부른다.</p>
<p><strong>사용자 정의형 레코드</strong></p>
<pre><code class="language-sql">TYPE 레코드명 IS RECORD (
    필드명1 필드1 타입 [[NOT NULL := 디폴트값],
    필드명2 필드2 타입 [[NOT NULL := 디폴트값],
    ...
);
레코드변수명 레코드명;</code></pre>
<p><strong>테이블형 레코드</strong></p>
<p>테이블의 모든 컬럼을 필드로 가지는 레코드</p>
<p><code>레코드 변수명 테이블명.%ROWTYPE;</code></p>
<p><strong>커서형 레코드</strong></p>
<p>커서를 레코드 변수로 받는 것</p>
<p><code>레코드 변수명 커서명%ROWTYPE;</code></p>
<h3 id="컬렉션">컬렉션</h3>
<p>같은 타입의 필드들이 나란히 연결되어 있는 로우가 여러개 모인 형태이다.</p>
<p><strong>컬렉션의 종류</strong></p>
<ol>
<li>연관배열<ul>
<li>키-값</li>
<li>사용자 정의 타입으로 사용 불가</li>
<li><code>TYPE 연관_배열명 IS TABLE OF 연관_배열_값타입 INDEX BY 인덱스타입;</code></li>
</ul>
</li>
<li>VARRY<ul>
<li>컬렉션에 들어갈 수 있는 요소의 개수에 제한이 있다.</li>
<li>인덱스로 숫자만 가능하다</li>
<li><code>TYPE VARRY명 IS VARRAY(최대크기) OF 요소값 타입;</code></li>
</ul>
</li>
<li>중첩 테이블<ul>
<li>요소 개수에 제한은 없다.</li>
<li>생성자로 초기화가 가능하다</li>
<li>숫자형 인덱스만 사용가능하다.</li>
<li><code>TYPE 중첩_테이블명 IS TABLE OF 값타입;</code></li>
</ul>
</li>
</ol>
<h3 id="사용자-정의-데이터-타입">사용자 정의 데이터 타입</h3>
<p>컬렉션을 선언하면 해당 블록의 실행이 완료되면 사라진다.</p>
<p>이때 해당 컬렉션을 다른 블록에서도 재사용하기위해 사용자 정의 데이터 타입을 사용하면 된다.</p>
<p><strong>사용자 정의 타입으로 사용할 수 있는 타입</strong></p>
<ul>
<li>VARRY</li>
<li>중첩 테이블</li>
<li>OBJECT</li>
</ul>
<h3 id="컬렉션-타입별-차이점과-활용법">컬렉션 타입별 차이점과 활용법</h3>
<ul>
<li><p>다차원 컬렉션</p>
<p>  /컬렉션의 요소로 중첩 테이블, VARRY 타입을 사용하여 2차원 배열처럼 사용가능하다.</p>
</li>
<li><p>VARRY 중첩 테이블</p>
<p>  사용자 정의 타입으로 정의를 해두면 데이터베이스의 객체로 저장되므로 일반 테이블의 컬럼 타입으로 사용가능하다.</p>
</li>
</ul>
<h2 id="12-함수와-프로시저-관리-패키지">12. 함수와 프로시저 관리, 패키지</h2>
<hr>
<h2 id="패키지">패키지</h2>
<p>논리적 연관성이 있는 항목들을 묶어둔 객체</p>
<h3 id="패키지-구조">패키지 구조</h3>
<ul>
<li>패키지 선언부<ul>
<li>공용 항목</li>
<li>데이터 : 변수, 상수, 예외 등 선언</li>
<li>서브 프로그램 : 함수, 프로시저 명세</li>
</ul>
</li>
<li>패키지 본문<ul>
<li>내부 항목</li>
<li>커서, 서브 프로그램 구현</li>
</ul>
</li>
</ul>
<h3 id="패키지-사용">패키지 사용</h3>
<p><code>패키지명.변수명/상수명</code></p>
<p><code>패키지명.서브프로그램명</code></p>
<p>다른 프로그램에서도 변수, 서브 프로그램을 호출해서 사용할 수 있다.</p>
<blockquote>
<h3 id="참고도서">참고도서</h3>
</blockquote>
<ul>
<li>오라클 SQL과 PL/SQL을 다루는 기술</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Servlet & JSP]]></title>
            <link>https://velog.io/@moon_dd/JSP-y95tsj0o</link>
            <guid>https://velog.io/@moon_dd/JSP-y95tsj0o</guid>
            <pubDate>Tue, 08 Aug 2023 07:46:26 GMT</pubDate>
            <description><![CDATA[<h1 id="jsp">JSP</h1>
<ul>
<li><p>Part1. 서블릿 프로그래밍</p>
<h1 id="part1-서블릿-프로그래밍">Part1. 서블릿 프로그래밍</h1>
<h2 id="1-자바와-웹">1. 자바와 웹</h2>
<hr>
<h3 id="서블릿">서블릿</h3>
<p>  클라이언트에서 웹 브라우저를 통해 요청이 들어오면 서버에서 해당 요청을 수행하고 결과값을 클라이언트에게 전송한다.</p>
<p>  HTTP 프로토콜로 통신하는 웹을 잘 활용할 수 있는 <strong>API</strong>를 제공한다.</p>
<p>  <strong>자바</strong>언어로 구현해야한다.</p>
<h3 id="jsp-1">JSP</h3>
<p>  서블릿과 동일한 기능을 가지고 있지만, 서블릿과 다른 점이 있다.</p>
<ol>
<li><p>HTML 페이지 안에서 <strong>스크립트 형태</strong>로 구현된다. 코드가 좀 더 간결하다</p>
</li>
<li><p>웹 애플리케이션의 역할에서 </p>
<ol>
<li><strong>JSP는 뷰 페이지</strong>를 만들 때 사용 → 뷰 : 요청을 받거나 보여주는 페이지</li>
<li><strong>서블릿을 컨트롤러 페이지</strong>를 만들 때 사용 → 컨트롤러 : 뷰에서 온 요청을 처리하는 페이지 </li>
</ol>
<h3 id="웹-애플리케이션">웹 애플리케이션</h3>
<p>웹에서 수행되는 애플리케이션</p>
<p>수행되는 위치에 따라 </p>
<ul>
<li>Client Side : 클라이언트의 자원을 이용하고 클라이언트에 의해 수행될 때</li>
<li>Server Side : 서버에서 수행되고 서버의 자원을 사용하며, 그 결과를 클라이언트에 전송할 때</li>
</ul>
<p>구현하는 방식에 따라 </p>
<ul>
<li>컴파일 방식 :  웹 애플리케이션이 미리 컴파일되고 실행 파일이 만들어진 후 사용되면</li>
<li>비컴파일 방식 : 요청이 있을 때마다 해석되거나 컴파일이 필요없을 때</li>
</ul>
<h3 id="restful-기반-웹-서비스">RESTful 기반 웹 서비스</h3>
<p>Resourcce Oreiented Architecture : 리소스 중심의 표현, 전달, 접근 방식의 기술</p>
<p>서버 ↔ 클라이언트</p>
<p>자원의 접근을 위해서 URI와 HTTP 요청방식을 사용하고 다양한 형식으로 클라이언트에게 응답을 보낼 수 있다.</p>
<h3 id="웹서버와-웹-어플리케이션-서버">웹서버와 웹 어플리케이션 서버</h3>
</li>
</ol>
<p>  <strong>웹 서버</strong></p>
<p>  웹에서 서버 기능을 수행하는 프로그램</p>
<p>  HTTP 프로토콜을 기반으로 클라이언트에게 요청을 받으면 해당 요청을 서비스하는 기능을 담당한다.</p>
<p>  <strong>제공하는 기능들</strong></p>
<pre><code>- 요청한 웹 문서 찾기
- 요청 처리 도중 발생한 문제를 코드 값으로 응답하기
- 사용자 인증
- 서버 프로그램에 대한 요청을 웹 어플리세이션 서버에게 수행시키고 그 결과를 응답받는다.</code></pre><p>  <strong>웹 어플리케이션 서버</strong></p>
<p>  웹 서버 → 다양한 문서와 웹 애플리케이션 처리 / 웹 , Client, Server 환경의 요청 처리 → 많은 요청이 왔을 때 웹 서버 혼자서 감당 X</p>
<p>  ⇒ 웹 서버의 기능을 분리해서 처리하기 위해 <strong>웹 애플리케이션 서버</strong>를 사용</p>
<p>  ex) Tomcat</p>
<p>  WAS의 구성</p>
<pre><code>- 웹 서버 기능 : Presentation Logic만 담당
    - 클라이언트로부터 요청받은 일과 화면에 표현하는 로직만 담당
- 컨테이너 기능 : Business Logic을 담당
    - 다양한 기능을 수행하는 로직
- 엔터프라이즈 환경에 필요한 기능
    - 트랜잭션, 보안, 트래픽 관리, DB 커넥션 풀, 사용자 관리</code></pre><p>  <strong>톰캣</strong></p>
<p>  JSP/서블릿 컨테이너와 웹서버만 제공</p>
<p>  일반적으로 독립적인 웹서버를 설치 + 톰캣 연동</p>
<p>  WAS 시장의 점유율이 높다.</p>
<h3 id="컨테이너">컨테이너</h3>
<pre><code>- **서블릿/JSP 웸 서버 애플리케이션**
    - 동적 컨텐츠를 생성하는 웹 컴포넌트
- **컨테이너**
   - 개발자대신 웹 컴포넌트 저장, 메모리 로딩, 객체 생성 및 초기화 같이 웹 컴포넌트를 관리해주는 역할
   - 서블릿 컨테이너

       서블릿 생명주기 관리 및 수행하는 프로그램
       클라이언트 요청에 따라 서블릿을 수행하는 프로그램
       서블릿 표준 API를 기반으로 클래스를 제공
        → 기본적인 동작과 API 호환성을 지원

 - **JSP 컨테이너**

 JSP를 서블릿으로 변환하는 프로그램</code></pre></li>
</ul>
<pre><code>### HTTP 프로토콜

Application Layer에 해당하는 프로토콜

Transport Layer에서 TCP를 이용해 웹 브라우저와 웹 서버 간에 통신하는 프로토콜이다.

**특징**

  - 무연결
  - 무상태
  - 요청, 응답

**HTTP 요청정보**

  - 요청 줄
      - 요청방식
          - GET
          - POST
          - PUT
          - DELETE
      - URI
          - 프로토콜
          - 서버 주소
          - 포트 번호
          - URI
      - HTTP 버전
  - 헤더
      - 웹 클라이언트와 웹 서버가 공유해야할 정보들
  - 몸체
      - 웹 클라이언트가 웹 서버에 보내는 데이터들

**HTTP 응답정보**

  - 상태 줄
      - HTTP 버전
      - 상태 코드
      - 상태 코드 설명
  - 헤더
      - 클라이언트의 요청에 대한 실행 결과를 웹 클라이언트가 잘 처리할 수 있게 하기 위한 정보들
  - 메세지 몸체



## 2. 서블릿 구현 및 실행

---

### **서블릿**

웹 브라우저에서 클라이언트에게 요청을 받아 서버가 실행할 수 있는 유일한 자바 프로그램

서블릿 표준 API를 기반으로 클래스를 제공

→ 기본적인 동작과 API 호환성을 지원

⇒ **서블릿 API를 상속**하고 있기에 웹에서 동작하는 기본 동작을 갖추고 있다.

### 서블릿이 상속 받고 있는 클래스

  - **Servlet** Interface
      - 기본 동작에 해당되는 init(), service(), destroy(), getServletConfig(), getServletInfo() 메소드 선언
          - 서블릿 생명주기에 연관된 메소드들
  - **GenericServlet** abstract class
      - service() 메소드를 제외한 모든 메소드를 재정의
  - **HttpServlet** abstract class
      - service() 메소드를 재정의
          - 요청방식에 따라 정해진 사양의 메소드가 호출된다.

**서블릿 객체의 생명주기** 

  - init()
      - 웹 서버가 실행되고 서블릿을 최초로 요청할 때만 호출된다.
  - service()
      - 클라이언트 요청이 있을 때마다 실행된다.
  - destroy()
      - 웹 애플리케이션 서비스가 중지되는 시점에 한번만 실행된다.

  ⇒ 즉 서빌릿은 최초 요청 시 객체가 생성되고 그 이후 요청들에 대해서는 재사용되다가 서버가 종료될때 서블릿 객체는 삭제된다.

## 3. 요청정보와 응답정보

---

### HttpServletRequest, HttpServletResponse

  - HTTP 통신 기반의 요청 응답 관련 메소드 제공
  - ServletRequest, ServeltResponse 인터페이스를 상속하고 있다.

**응답, 요청 객체가 생성되고 사라지는 과정**

  1. 클라이언트 요청
  2. 웹 서버
  3. 서블릿 컨테이너
  4. 최초 요청 파악
      (1) 서블릿 객체 생성
  5. HttpServletRequest, HttpServletResponse 객체 생성
  6. service() 메소드 호출
  7. service() 메소드 완료 → 클라이언트에게 응답 
  8. HttpServletRequest, HttpServletResponse 객체 소멸

**ServletRepoonse 인터페이스**

HttpServletResponse가 상속하고 있는 인터페이스

일반적인 네트워크 통신에서의 응답 관련 메소드 제공

  - 주요메소드
      - void setCharacterEncoding
      - void setContentLength
      - void setContentType
        - 보내는 데이터의 문서타입과 문자셋

**HttpServletResponese**

HTTP 통신 기반의 응답 관련 메소드 제공

ex) 쿠키 설정, HTTP 응답 헤더 설정

  - 주요메소드
      - void addCookie
      - void setHeader
      - void setStatus

**ServletRequet 인터페이스**

HttpServletRequest가 상속하고 있는 인터페이스

일반적인 네트워크 통신에서의 요청관련 메소드 제공

- 주요메소드
    - getContentLength
    - getPrameter
    - getServerPort

**HttpServletRequest**

HTTP 통신 기반의 요청 관련 메소드 제공

  - 주요메소드
      - getHeader
      - getCookies
      - getQueryString
      - getMethod


### URI , URL

**호출 메소드**

HttpServletRequest 인터페이스를 통해 호출 가능 → getRequestURI() / getRequestURL()

URI : 클라이언트가 요청한 문서정보를 반환

URL : 클라이언트가 서비스를 요청한 문서의 전체 정보  (프로토콜 + 서버주소 + 포트번호 + URI) 

### 헤더정보

  - Enumeration&lt;String&gt; getHeaderNames()
      - 요청정보의 헤더에 있는 이름들
      - Enumeration 특성 상 커서를 이용해서 다음 요소에 접근할 수 있다.
          - boolean hasMoreElements()
          - String nextElement()

### 쿼리정보

쿼리 : URL과 함께 넘어온 정보들

GET 요청은 requestybody가 없으므로 URL에 붙어 쿼리형태로 데이터를 넘겨줄 수 있다.

  - key=value?key1=value1
  - HttpServletRequest 인터페이스 → getQueryString()

## 4. 질의 문자열

---

클라이언트가 웹서버에 정보를 요청할 떄 질의 문자열을 사용해서 필요한 데이터를 전달한다.

### **질의문자열 규칙**

  - name=value 형식
  - 영문자,숫자, 일부 특수기호는 그대로, 나머지 문자는 16진수로 변환해서 전달
  - 공백기호는 +로 변경되어 전달

### GET 요청 방식

  - 데이터를 조회하는 요청에 사용
  - request body가 없고 질의 문자열이 URI에 포함되어 전달된다.
      - 외부 노출 위험
      - 문자열 길이가 제한적
      - 인코딩/디코딩 X
  - GET으로 요청하는 방법
      - a 태그의 기본 요청방식
      - 브라우저 주소줄에 직접 입력
      - form 태그의 기본 요청방식

### POST 요청 방식

  - 데이터 값을 수정하거나 상태변화를 일으키는 요청에 사용
  - 질의 문자열이 request body에 포함된다.
  - POST로 요청하는 방법
      - form 태그의 method 속성 → POST로 지정

### 서블릿 연결

  1. action 속성 → URI 주소 지정 (상대주소)
      1. method 속성
  2. 서블릿 클래스에 @WebServlet(”/ + URI주소”) 지정

### 질의 문자열 추출

  - getParameter()
  - getParameterValues()
  - getQueryString()
      - GET에서 사용
  - getInputStream()
      - POST에서 사용
    - readLine()을 이용해 줄 단위로 데이터 읽어옴

## 5. 서블릿 설정과 변수

---

### 💡서블릿 설정을 위한 태그

  - `&lt;servlet&gt;`
      - `&lt;servlet-name&gt;`
      - `&lt;servlet-class&gt;`
  - `&lt;init-param&gt;`
      - `&lt;param-name&gt;`
      - `&lt;param-value&gt;`
      - ServletConfig.getInitParameter()를 이용해서 접근할 수 있다.
  - `&lt;load-on-startup&gt;`
      - 서블릿 생성 우선순위


### 서블릿 동시 요청

**CGI** 

클라이언트 요청이 들어올때마다 독립적인 프로세스가 만들어진다.

→ 프로세스마다 메모리에 데이터가 로딩된다.

**서블릿**

서블릿 최초 요청 → init() 호출 ⇒ 하나의 프로세스 생성

최초 이후 서블릿 요청 → service() 호출 = 만들어진 프로세스내에 **스레드** 생성

스레드는 독립적인 stack을 가지고 있지만 code, heap 영역은 다른 스레드와 공유한다.

⇒ 메모리 측면에서 효율적

⇒ 변수의 범위를 주의해서 사용해야한다.

### 자바의 변수

멤버 변수

  - class 변수
      - 선언 방법 : static 선언
      - 사용 메모리 : code 영역
      - 생성 시점 : 프로그램 시작
      - 제거 시점 : 프로그램 종료
  - instance 변수
     - 선언 방법 : 메소드 바깥쪽에 선언
     - 사용 메모리 : heap 영역
     - 생성 시점 : 객체 생성 시
     - 제거 시점 : 참조가 끊긴 후 GC에 의해

지역 변수

  - 선언 방법 : 메소드 안쪽에 선언
  - 사용 메모리 : stack 영역
  - 생성 시점 : 메소드 실행 시
  - 제거 시점 : 메소드 종료 시

## 6.  상태정보 유지 기술

---

### Stateless

HTTP 통신의 특징 중 하나

클라이언트가 요청을 보내고 서버가 응답을 보내면 연결이 끊기기때문에 이전에 요청을 보냈던 클라이언트에 대한 정보가 없는 것을 의미한다.

### 상태정보

계속된 요청에 사용할 수 있도록 이전 서비스 결과를 저장한 정보들을 상태정보라고 한다.

클라이언트 혹은 서버에 저장하는 방식이 있다.

  - 클라이언트 측 → 브라우저에 저장 ex )쿠키
  - 서버 측→ 메모리 힙 영역에 저장

### 유지 기간 분류

  - 웹 애플리케이션 단위 유지
      - 웹 애플리케이션 생명주기 = ServletContext 생명주기
      - ServletContext는 웹 애플리케이션이 시작될때 생성되고 종료될 때 소멸한다.
  - 클라이언트 단위 유지
      - **쿠키, 세션**
      - 상태정보다 다른 클라이언트는 사용할 수 없어야할때
      - ex) 로그인 정보
  - 요청 단위 유지
    - 하나의 요청(클라이언트 요청 + 서버의 응답)에서만 유지

### ServletContext

웹 애플리케이션 단위로 유지하며 **서버측**에 저장되는 객체이다.

ServletContext는 해당 웹 애플리케이션에 포함된 모든 서블릿이 공유하고 있다.

→ 속성을 이용해 서블릿 간 정보 공유가 가능하다.

**ServletContext 추출하는 방법**

ServletContext는 해당 웹 애플리케이션에 포함된 모든 서블릿이 공유하고 있다.

  - ServletContext 객체
      - ServletConfig.getServletContext() 이용해서 추출
      - ServletContext 객체에서 서버의 정보를 얻을 수 있다.
      - 객체에 속성을 set/get/remove → 서블릿 간 정보 공유를 가능하게 한다.
  - ServletContext의 주소
      - init() 메소드 재정의
      - HttpServlet 객체 이용
          - 서블릿을 만들기 위해서는 반드시 HttpServlet을 상속받아야한다.
          - ServletConfig 상속 —&gt;  GenericServlet →   HttpServlet

**ServletContext 변수 설정**

web.xml 파일에서 &lt;context-param&gt;이용

**ServletContext 변수 추출**

ServletContext.getInitParameter() 이용

### 쿠키

**활용 예시**

  - 유저 로그인 인증 상태 유지
  - 방문 횟수
  - 사용자 정보 저장

**특징**

  - 클라이언트 단위로 저장
  - 클라이언트 쪽에 저장
  - 클라이언트가 직접 점검해볼 수 있기에 보안상 유의해서 사용
  - name=value 형식으로 저장
  - expire=날짜 → 쿠키 유지 기간

**쿠키생성**

**javax.servlet.http.Cookie** 객체를 이용해 생성한다.

→ 해당 객체의 함수들을 이용해 쿠키의 속성을 설정할 수 있다.

### 세션

일정기간동안 클라이언트 상태 정보 저장을 목적으로 한다.

**저장 위치**

  - 세션 객체는 서버 측에 저장.
  - 세션 ID는 클라이언트 측에 쿠키로 저장.

**활용 예시**

  - 장바구니
  - 로그인, 로그아웃 사용자 인증 처리

💡**세션 트래킹**

  1. 클라이언트의 세션이 이미 존재하면 해당 세션을 추출 / 없다면 생성
      1. 세션 ID를 클라이언트에게 쿠키로 보낸다.
  2. 정보를 저장한 객체를 세션에 등록
  3. 클라이언트가 요청이 올때마다 세션에 저장된 정보를 활용해서 기능에 사용
  4. 세션이 더이상 필요없어진 시점에 세션 삭제

**HttpSession 객체 생성**

**HttpServletRequest.getSession(boolean create)**

  - ruquest의 클라이언트 세션 ID와 동일한 세션 객체를 찾아준다.
  - create = true → 없으면 객체 생성
  - create = falase → 없으면 null 반환

### Request 단위 정보 공유

**요청 재지정**

아래 객체들을 이용해 요청온 페이지에서 다른 페이지로 요청을 옮겨줄 수 있다.

  - HttpServletResponse 객체
      - sendRedirect()
      - encodeRedirectURL()
  - RequestDistpatcher 객체
      - forward()
      - include()

**Reqeust 단위 정보 공유**

  1. HttpServletRequest, HttpServletResponse 객체에 속성으로 정보를 저장한다.
  2. ReaureDispatcher의 foward, include 메소드에 request, response 객체를 담아 다른 페이지에 정보를 공유한다.

## 7. 고급 기능

---

### 필터

  - 서블릿 실행 전후로 **필터**가 실행된다.
      - 서블릿의 처리와 유지 보수를 좀 더 효과적으로 처리할 수 있다.
  - 필터는 여러개의 서블릿에 적용
      - 여러 페이지에 동일한 기능을 적용해야할 때 활용하면 좋다.
  - Filter 인터페이스를 통해 구현

### 필터 구현

  **Filter 인터페이스**

  - init()
      - 웹 애플리케이션이 시작될 때 한번만 작동
  - destroy()
      - 웹 애플리케이션이 종료될 때 한번만 작동
  - doFilter()
      - 해당 필터에 매핑된 서블릿이 실행될때마다 호출
      - FilterChain
          - 3번째 인자
          - web.xml에 작성된 모든 필터 정보를 가지고 있다.
          - chain.doFilter() 메소드 생략할 경우 실행 흐름이 멈춰 서블릿까지 전달되지 못하고 해당 메소드에서 끝난다.

### 필터 등록 및 매핑

**방법 1 : 태그 이용**

  1. Filter 인터페이스 상속 후 객체 구현
  2. `&lt;filter&gt;` 태그 이용해 필터 객체 등록
  3. `&lt;filter-mapping&gt;` 태그로 필터와 서블릿 매핑

**필터 등록**

  - `&lt;filter&gt;` 태그
      - `&lt;filter-name&gt;`
      - `&lt;filter-class&gt;`
      - `&lt;init-param&gt;`
          - `&lt;param-name&gt;`
          - `&lt;param-value&gt;`

**필터 매핑**

  - `&lt;filter-mapping&gt;` 태그
      - `&lt;filter-name&gt;`
      - `&lt;url-pattern&gt;`
      - `&lt;servlet-name&gt;`

**FilterConfig**

필터 객체에 필터에 대한 정보값들을 전달한다.

**방법 2 :  @WebFilter 이용**

  1. filter 인터페이스 상속 후 객체 구현
  2. 필터 객체에 @WebFilter 어노테이션 선언
  3. 속성으로 filterName, urlPatterns 속성을 추가한다.

### 리스너

= 이벤트 핸들러

각 이벤트가 발생한 시점에서 수행될 처리 내용을 구현할 수 있다

**웹의 이벤트 소스**

  - ServletContext
  - HttpSession
  - HttpServletRequest

### **리스너 구현 및 등록**

**방법 1 : 태그 이용**

  1. Listener, AttributeListener 인터페이스 상속 후 구현
      - Listner는 객체 생명주기와 관련된 이벤트
      - AttributeListner는 객체의 속성에 대한 이벤트
  2. `&lt;listner&gt;` 태그 이용해서 web.xml에 등록

**방법 2 : @WebListener 이용**

  1. Listener, AttributeListener 인터페이스 상속 후 구현
  2. 리스너 클래스 선언부 위에 @WebListener를 선언한다.

### 오류처리

자바에서는 프로그램 실행 중 발생하는 오류도 객체로 표현한다.

**방법 1:  try catch 처리**

**방법 2: Throw 처리**

  throw로 처리한 오류가 발생시 해당 함수를 호출한 부분에서 오류 해결

  + finally → 오류 해결 X, 오류 발생시에도 무조건 실행해야하는 역할

**방법 3 : web.xml 오류 처리**

  - `&lt;error-page&gt;`

      `&lt;error-code&gt;`, `&lt;exception-type&gt;`에 지정된 오류 유형을 가진 오류가 발생 시

      → `&lt;location&gt;` 태그에 지정된 오류 페이지가 실행</code></pre><ul>
<li><p>Part2. JSP 프로그래밍</p>
<h1 id="part2-jsp-프로그래밍">Part2. JSP 프로그래밍</h1>
<h2 id="8-jsp-프로그래밍">8. JSP 프로그래밍</h2>
<hr>
<p>  템플릿 데이터에 동적인 데이터를 끼워 넣을 수 있는 방법을 제공한다.</p>
<p>  추상화를 위한 JSP 기능</p>
<ul>
<li><p>자바빈즈 컴포넌트 아키텍처</p>
<ul>
<li>태그 라이브러리</li>
</ul>
<h3 id="jsp-장점">JSP 장점</h3>
<ul>
<li>플랫폼 독립성</li>
<li>역할 분리</li>
<li>컴포넌트와 태그 라이브러리의 재사용</li>
<li>정적 콘텐츠와 동적 컨텐츠의 분리</li>
<li>액션, 표현식, 스크립트 제공</li>
<li>N-tier 엔터프라이즈 애플리케이션을 위한 웹 접근 레이어</li>
</ul>
<h3 id="jsp-실행-단계">JSP 실행 단계</h3>
<p>컨테이너는 JSP와 서블릿 클래스를 웹 컴포넌트로 인식</p>
<ol>
<li>변환 단계 : JSP Container<ol>
<li>JSP (.jsp) → 서블릿 소스 (.java) — 컴파일 —&gt; 서블릿 클래스 (.class)</li>
</ol>
</li>
<li>실행 : ServletContainer<ul>
<li>실행은 요청이 있을때마다</li>
<li>구현된 서블릿 클래스를 초기화하고, 실행해서 요청을 처리하고 응답을 보낸다.</li>
</ul>
</li>
</ol>
<h3 id="💡스크립트-기반-태그">💡스크립트 기반 태그</h3>
<p>스크립트 태그의 종류에 따라 자바 소스로 변환된다.</p>
<ul>
<li><p>지시자</p>
<ul>
<li><p><code>&lt;%@ … %&gt;</code></p>
</li>
<li><p>페이지에 대한 정보 설정</p>
</li>
<li><p>page 지시자</p>
<p>  <code>&lt;%@ page 속성 = 값 %&gt;</code></p>
<ul>
<li>contentType</li>
<li>import</li>
<li>errorPage, isErrorPage</li>
</ul>
</li>
<li><p>include 지시자</p>
<p>  <code>&lt;%@ include file = “파일명” %&gt;</code></p>
</li>
</ul>
</li>
<li><p>선언문</p>
<ul>
<li><code>&lt;%! 변수 선언 %&gt;</code> 혹은 <code>&lt;%! 메소드 선언 %&gt;</code></li>
<li>멤버변수 또는 메소드 선언</li>
</ul>
</li>
<li><p>스크립트릿</p>
<ul>
<li><code>&lt;% … %&gt;</code></li>
<li>_jspService()내에 그대로 옮겨짐</li>
</ul>
</li>
<li><p>표현식</p>
<ul>
<li><code>&lt;%= … %&gt;</code></li>
<li>_jspServe()의 out.println()으로 그대로 옮겨짐</li>
</ul>
</li>
<li><p>주석</p>
<ul>
<li><code>&lt;%-- … --&gt;</code></li>
</ul>
</li>
</ul>
<h2 id="9-내장-객체">9. 내장 객체</h2>
<hr>
<p>JSP 파일이 자바 소스로 변환될 때 <strong>_jspService() 메소드 안</strong>에 자동으로 생성된 코드로 인해 미리 선언과 초기화가 된 객체들</p>
<p>_jspSerive() 메소드내에서만 내장 객체는 사용할 수 있기때문에, 스크립트릿과 표현식에서만 사용할 수 있다.</p>
<ul>
<li>request<ul>
<li>질의 문자열, forward() 함수를 활용할 수 있다.</li>
</ul>
</li>
<li>response</li>
<li>session<ul>
<li>로그인, 로그아웃에 세션을 통해 인증을 유지할 수 있다.</li>
</ul>
</li>
<li>application<ul>
<li>ServletContext 객체 메소드들을 사용할 수 있다.</li>
</ul>
</li>
<li>config</li>
<li>out<ul>
<li>웹 브라우저에 출력하는 기</li>
</ul>
</li>
<li>pageContext<ul>
<li>jsp 페이지 하나당 만들어진다.</li>
<li>내장객체를 반환하여 사용할 수 있다.</li>
</ul>
</li>
</ul>
<h2 id="10-표준-액션-태그와-jsp-자바빈즈">10. 표준 액션 태그와 JSP 자바빈즈</h2>
<hr>
<h3 id="xml-기반-태그">XML 기반 태그</h3>
<ul>
<li>표준 액션 태그</li>
<li>커스텀 태그</li>
</ul>
<h3 id="표준-액션-태그">표준 액션 태그</h3>
<p>많이 쓰는 기능을 JSP 스펙으로 이미 정의해서 컨테이너마다 동일하게 구현해놓은 표준 액션 태그이다.</p>
<p><strong>태그 사용</strong></p>
<p><code>&lt;태그 라이브러리 이름 : 태그 이름&gt;</code></p>
<p><strong>표준 액션 태그 종류</strong></p>
<ul>
<li><code>&lt;jsp : forward page = “경로”&gt;</code><ul>
<li>= 서블릿 RequestDisaptcher.forward() 실행</li>
</ul>
</li>
<li><code>&lt;jsp : include file = “파일경로”&gt;</code><ul>
<li>include 지시자 : java로 변환될때 파일 포함</li>
<li><jsp : inlcude> : 실행될때 파일 포함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code>### JSP 자바빈즈

**JSP 자바빈즈의 장점**

  - 폼 데이터 처리 용이
      - 클라이언트로부터 전달받은 데이터를 쉽게 추출하고 다른 페이지에서 참조할 수 있다.
  - 자바빈즈 활용 범위 확장 용이
      - 여러 페이지에서 사용해야하는 데이터는 자바빈즈를 이용해 쉽게 유지하여 여러 범위에서 사용할 수 있다.
  - 컴포넌트 기반 구현 기능
      - 비지니스 로직을 컴포넌트로 만들어 활용하면 JSP 페이지 크기는 작아지고 컴포넌트 재활용을 통해 구현되므로 효과적으로 구현할 수 있다.

**JSP 자바빈즈 개발 규약**

1. 패키지화
    1. 기본 패키지에 있으면 인식 X
2. 기본 생성자 존재
3. 멤버 변수 ⇒ private
4. getter/setter 메소드 ⇒ public
5. 직렬화 구현 (선택사항)

**자바빈즈 생성 및 사용**

1. 생성
    1. 패키지화
    2. 자바빈즈로 사용할 클래스 구현
2. 사용
    1. `&lt;jsp:useBean class = “클래스명” id=”식별자명”&gt;`
    2. `&lt;jsp:getProperty property=”변수명” name=”id명”&gt;`
    3. `&lt;jsp:setProperty property=”변수명” name=”id명” value=”저장할값”&gt;`
        1. value를 설정하지 않으면 질의 문자열에서 찾아서 설정된다.
        2. property=”*” ⇒ 클라이언트의 질의 문자열에서 추출해서 바인딩한다.</code></pre><ul>
<li><p>Part3. JSP 프로그래밍2</p>
<h1 id="part3-jsp-프로그래밍-2">Part3. JSP 프로그래밍 2</h1>
<h2 id="11-데이터베이스">11. 데이터베이스</h2>
<hr>
<h3 id="jdbc">JDBC</h3>
<p>  자바 프로그램에서 DB 관련 작업을 수행한다.</p>
<p>  자바언어로 다양한 관계형 데이터베이스에 접속하고 SQL 문을 수행하기 위해 사용되는 표준 SQL 인터페이스 API 이다.</p>
<p>  💡 <code>JDBC 프로그램 ↔ JDBC 인터페이스 ↔ JDBC 드라이버 ↔ DB</code></p>
<ul>
<li>접속하려는 DBMS마다 JDBC 드라이버가 필요하다.</li>
</ul>
<h3 id="💡jdbc-프로그래밍">💡JDBC 프로그래밍</h3>
<ol>
<li><p>JDBC 드라이버 로딩</p>
<ul>
<li>Class.forName(JDBC 드라이버 패키지)</li>
</ul>
</li>
<li><p>DBMS 서버 접속</p>
<ul>
<li>DriverManager.getConnection()<ul>
<li>연결에 성공 시 Connection 객체 반환</li>
</ul>
</li>
</ul>
</li>
<li><p>Statement, PreparedStatement 객체</p>
<ul>
<li>DB에 SQL문을 전달할 때 사용되는 객체</li>
<li>Statement 객체<ul>
<li>Connection 객체에서 createStatement()를 통해 Statement 객체 생성</li>
</ul>
</li>
<li>PreparedStatement 객체<ul>
<li>Statement와 같은 기능이지만 ?를 사용해서 동적으로 값을 할당할 수 있다.</li>
</ul>
</li>
</ul>
</li>
<li><p>Statement 실행</p>
<ul>
<li>ResultSet ExecuteQurey()<ul>
<li>select 결과값을 가지는 객체</li>
</ul>
</li>
<li>int ExecuteUpdate()</li>
</ul>
</li>
<li><p>자원 해제</p>
<ul>
<li>최근에 사용한 객체부터 거꾸로 올라가며 해제</li>
</ul>
<h3 id="datasource">DataSource</h3>
<p>Connection을 효율적으로 관리하고 사용하기 위해 Connection Pool을 사용</p>
<p>Connection Pool은 미리 Connection 객체를 가지고 있어 사용자가 요청이 들어올때 바로 사용할 수 있는 특징이 있다.</p>
<p>이때 Connection Pool을 관리하는 목적으로 DataSource 객체를 사용한다.</p>
<p>💡<strong>사용방법</strong></p>
<ol>
<li>JNDI 서버 객체 생성<ul>
<li>서용하고자하는 자원의 이름값만으로 자원을 연결하여 이용할 수 있다.</li>
</ul>
</li>
<li>look up()<ul>
<li>매개변수로 들어온 이름에 해당하는 DataSource를 찾아서 객체로 반환해준다.</li>
</ul>
</li>
<li>getConnection()</li>
<li>Statement 객체 생성</li>
<li>Statement 실행</li>
<li>자원 해제</li>
</ol>
<h2 id="12-expression-language">12. Expression Language</h2>
</li>
</ol>
<hr>
<pre><code>- ${ } 내에 표현식으로 표현한다.
- 문자, 연산자, 변수를 사용해서 표현식을 작성한다.
    - 문자 : 논리, 숫자, 문자열
    - 연산자 : 산술, 논리, 비교 연산자 , empty 연산자</code></pre><h3 id="내장객체">내장객체</h3>
<p>  JSP의 내장객체처럼 내장 객체 참조변수 이름으로 곧바로 사용할 수 있다.</p>
<p>  내장객체의 대부분은 map 형태로 되어 있다.</p>
<p>  <strong>param</strong></p>
<p>  질의 문자열을 쉽게 가져올 수 있다.</p>
<p>  <code>${param.keyName}</code> 혹은 <code>${param[keyName]}</code></p>
<p>  활용 예시) <code>&lt;jsp:forward page=”${param.p}” /&gt;</code></p>
<p>  <strong>header</strong></p>
<p>  요청정보의 헤더정보를 가져온다.</p>
<h3 id="💡정보추출">💡정보추출</h3>
<p>  request, session, application 단위로 정보를 추출하는 간단한 방법</p>
<pre><code>1. 자바빈즈 객체 구현
2. 자바빈즈 등록 
    - 원하는 단위의 객체에 setAttribute(”id명”, beans 객체 )
3. EL구문을 통해 사용
    - request, session, application 순서로 getAttribute(”속성명”) 메소드를 실행</code></pre><h2 id="13-커스텀-태그">13. 커스텀 태그</h2>
<hr>
<h3 id="장점">장점</h3>
<pre><code>- 재사용성
- 역할분담
- 유지 보수성
- 기독성</code></pre><h3 id="클래스-기반-커스텀-태그">클래스 기반 커스텀 태그</h3>
<pre><code>1. Tag Handler Class

    태그 기능을 자바 클래스 파일에 구현

2. Tag Libray Descriptor

    JSP 태그와 연결

3. TLD 파일 등록

    JSP 컨테이너가 TLD 파일을 인지하도록 web.xml에 등록 혹은 WEB-INF 폴더에 넣기

4. 커스텀 태그 사용

    taglib 지시자를 이용해 JSP 페이지에서 선언</code></pre></li>
</ul>
<pre><code>### 태그 기반 커스텀 태그

JSP 파일에 직접 구현한다.

  1. Tag 파일 (*.tag)

      JSP 페이지처럼 작성하지만 tag 지시자를 사용

      일반 JSP 페이지에서 사용할 수 없는 지시자 사용

      내부적으로 태그 파일이 태그 핸들러 파일로 변환되어 사용된다.

  2. 커스텀 태그 사용

      taglib 지시자를 사용해 JSP 페이지에서 선언


**tag 지시자**

커스텀 태그에 대한 기본적인 정보를 설정

  - body-content
      - empty : 몸체 없음
      - tagdependent : 몸체 내용을 그대로 사용
      - scriptless (default) : 액션 처리 후 결괏값 사용
  - dynamic-attribute
      - 속성을 동적으로 사용할때 속성을 저장할 변수 이름 지정

**attribute 지시자**

커스텀 태그에 사용할 속성 정의

  - name
  - required

**variable 지시자**

EL에서 사용하는 변수를 선언할 때 사용

  - name-given

      EL에서 사용할 변수의 이름을 지정

  - scope
      - AT_BEGIN : 시작 태그부터 사용
      - NESTED : 시작 태그와 끝 태그 사이에서 사용
      - AT_END : 끝 태그 이후부터 사용


**&lt;jsp:doBody&gt;**

커스텀 태그 몸체의 내용을 출력해주는 태그

## 14. JSTL

---

태그 라이브러리를 공통으로 사용하기 위한 표준

Core, Formatting, SQL, XML, Functions 5개의 태그 라이브러리를 제공하고 있다.

### Core

  - **기본 액션**

      ex) &lt;c:set&gt;, &lt;c:out&gt;, &lt;c:remove&gt;, &lt;c:catch&gt;

  - **조건 액션**

      ex) &lt;c:if&gt;, &lt;c:choose&gt;, &lt;c:when&gt;, &lt;c:otherwise&gt;

  - 반복 액션

      ex) &lt;c:forEach&gt;, &lt;c:forTokens&gt;

  - URL 액션

      ex) &lt;c:import&gt;. &lt;c:url&gt;, &lt;c:param&gt;, &lt;c:redirect&gt;


### Formatting

서비스 지역이나 문화에 맞줘 작업이 수행될 수 있게 도와주는 역할을 한다.

ex) &lt;fmt:message&gt;, &lt;fmt:param&gt;, &lt;fmt:requestEncoding&gt;, &lt;fmt:timeZone&gt;

### SQL

데이터베이스에 관련된 기능을 수행한다.

ex) &lt;sql:setDataSource&gt;, &lt;sql:query&gt;, &lt;sql:update&gt;</code></pre><ul>
<li><p>Part4. MVC 기반 웹 프로젝트</p>
<h2 id="15-웹-애플리케이션-디자인-패턴">15. 웹 애플리케이션 디자인 패턴</h2>
<hr>
<h3 id="mvc">MVC</h3>
<p>  개발 디자인 패턴</p>
<ul>
<li><p>Model</p>
<ul>
<li><p>Service 객체 / Business 객체</p>
<p>  → 서비스 처리를 하기 위한 객체</p>
</li>
<li><p>Dao 객체</p>
<p>  → DB 처리에 관한 기능을 하는 객체</p>
</li>
</ul>
</li>
<li><p>View</p>
<p>  → 클라이언트로부터 요청이 일어나거나 처리된 결과를 보여주는 페이지</p>
</li>
<li><p>Controller</p>
<p>  → 뷰에서 클라이언트가 서비스를 요청했을 때 실행되는 곳</p>
</li>
</ul>
</li>
</ul>
<pre><code>### 3계층 아키텍쳐

구조적인 측면에서 3계층 아키텍쳐 사용

  - Presentation tier

      클라이언트 ↔ 애플리케이션

      프론트엔드

  - Business tier

      서비스 처리를 위한 비즈니스 로직을 구현

      벡엔드, 미들웨어

  - Persistent tier

      데이터베이스 서버나 파일 시스템에 접근해서 데이터를 생성, 관리하는 계층

    벡엔드</code></pre><ul>
<li>질문<ul>
<li>폴더 구조를 어떻게 해야할지,,</li>
<li>Servlet 클래스들이 왜 serialVersionUID를 가지고 있는지<ul>
<li>HttpServlet 클래스는 GenericSerlvet 클래스를 상속 받고 있다. GenericServlet은 Servlet뿐만 아니라 Serialize 인터페이스도 상속받고 있는데, 이는 서블릿 객체 직렬화를 위해 상속받고 있다고 한다. 서블릿이 네트워크를 통해 응답 스트림을 보내기 위해서 직렬화가 필요하다고 한다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="피드백">피드백</h4>
<p>jdbc 드라이버 로딩 과정</p>
<p>sql Injection</p>
<blockquote>
<h3 id="참조도서">참조도서</h3>
</blockquote>
<ul>
<li>처음 해보는 Servlet &amp; JSP 웹 프로그래밍</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript]]></title>
            <link>https://velog.io/@moon_dd/JavaScript</link>
            <guid>https://velog.io/@moon_dd/JavaScript</guid>
            <pubDate>Mon, 24 Jul 2023 06:51:50 GMT</pubDate>
            <description><![CDATA[<h1 id="javascript">Javascript</h1>
<h1 id="1-자바스크립트-기초">1. 자바스크립트 기초</h1>
<hr>
<h3 id="자바스크립트-변수-규칙">자바스크립트 변수 규칙</h3>
<ul>
<li>식별자 규칙<ul>
<li>문자, 밑줄, 달러기호($)로 시작해야한다.</li>
</ul>
</li>
<li>변수 선언 규칙<ul>
<li>여러 단어를 연결한 변수 이름을 camelCase 법으로 작성한다.</li>
</ul>
</li>
</ul>
<p>ES6 버전부터 변수를 선언할 때 <strong>var</strong> 예약어 외 <strong>let</strong>, <strong>const</strong>를 사용할 수 있다.</p>
<ul>
<li>var<ul>
<li>변수 범위<ul>
<li>함수 외부 선언 ⇒ 전역 범위</li>
<li>함수 내부 선언 ⇒ 함수 범위</li>
</ul>
</li>
<li>특징<ul>
<li>재선언과 업데이트 O<ul>
<li>재선언이 가능하여 다른 곳에서 이미 정의된 것을 재선언할 경우 취약점이 발생할 수 있다</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>let<ul>
<li>변수 범위<ul>
<li>해당 블록 내에서만 사용가능하다.</li>
</ul>
</li>
<li>특징<ul>
<li>업데이트 O , 재선언 X<ul>
<li>동일한 변수가 다른 범위에서 정의되는 것은 가능하다. 서로 다른 범위를 가지고 있어 서로 다른 변수로 취급된다.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>const<ul>
<li>변수 범위<ul>
<li>선언된 블록 범위 내에서만 접근 가능</li>
</ul>
</li>
<li>특징<ul>
<li>업데이트, 재선언 X</li>
<li>즉 선언과 동시에 정의가 되어야한다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="자바스크립트-연산자">자바스크립트 연산자</h3>
<ul>
<li>연결 연산자 : + / 상수 연산자 : -<ul>
<li>숫자형 자료와 문자형 자료를 <strong>+</strong>를 이용해 더하면 숫자형 자료가 문자형 자료로 변환된다.</li>
<li>숫자형 자료와 문자형 자료를 <strong>-</strong> 를 이용해 더하면 문자형 자료가 숫자형 자료로 변환된다.</li>
</ul>
</li>
<li>탬플릿 문자열<ul>
<li><code>문자열 ${변수명} 문자열</code></li>
</ul>
</li>
<li>비교 연산자<ul>
<li>== : 자료형이 다를 경우 자료형을 변환해서 비교</li>
<li>=== : 자료형 변환 X</li>
</ul>
</li>
</ul>
<h1 id="2-제어문">2. 제어문</h1>
<hr>
<h3 id="조건문">조건문</h3>
<h3 id="반복문--for">반복문 : for</h3>
<h3 id="반복문--while">반복문 : while</h3>
<h1 id="3-함수와-이벤트">3. 함수와 이벤트</h1>
<hr>
<h3 id="함수-정의와-실행">함수 정의와 실행</h3>
<p>함수를 선언한 순서에 상관없이 함수 실행은 어디서나 가능하다. </p>
<h3 id="익명함수">익명함수</h3>
<ul>
<li><p>함수 자체가 식</p>
<p>  ⇒ 변수에 할당 가능</p>
<p>  ⇒ 다른 함수의 매개변수로 활용 가능</p>
<pre><code class="language-jsx">  var add = function(a,b){
      return a + b;
  }</code></pre>
</li>
<li><p>화살표 표기법</p>
<p>  ⇒ 화살표 표기법을 통해 익명 함수의 함수 선언을 좀 더 간단하게 작성할 수 있다.</p>
<pre><code class="language-jsx">  // 매개변수 X
  let hi = () =&gt; &quot;안녕하세요?&quot;;
  hi();

  //매개변수 1개
  let greet = name =&gt; `${name}님, 안녕하세요?&quot;`;
  greet(&quot;경희&quot;);

  //매개변수 2개 이
  let add = (a,b) =&gt; a + b;
  add(1,2);
</code></pre>
</li>
</ul>
<h3 id="즉시-실행-함수">즉시 실행 함수</h3>
<p>함수를 정의함과 동시에 실행되는 함수</p>
<pre><code class="language-jsx">(function() {
                ...
})();

또는

(function() {
                ...
}());</code></pre>
<h3 id="이벤트-다루기">이벤트 다루기</h3>
<ul>
<li><p>이벤트 : 사용자나 웹 브라우저가 행하는 어떤 동작</p>
<ol>
<li>마우스 이벤트</li>
<li>키보드 이벤트</li>
<li>문서 로딩 이벤트</li>
<li>폼 이벤트</li>
</ol>
</li>
<li><p>이벤트 처리기</p>
<ul>
<li>이벤트가 발생했을 때 어떤 함수를 실행시킬 지 알려주기 위해 이벤트와 이벤트 처리 함수를 연결해주는 것</li>
<li>on + 이벤트</li>
<li>연결 방식<ul>
<li>태그에 함수 연결</li>
<li>태그에 미리 만들어둔 함수를 연결</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="4-객체">4. 객체</h1>
<hr>
<h3 id="자바스크립트의-객체">자바스크립트의 객체</h3>
<ul>
<li>내장객체</li>
<li>문서 객체 모델</li>
<li>브라우저 객체 모델</li>
<li>사용자 정의 객체</li>
</ul>
<h3 id="객체란">객체란?</h3>
<ul>
<li>속성과 메서드로 이루어져 있다.</li>
<li>인스턴스<ul>
<li>프로토타입을 이용해서 만든 객체</li>
<li><code>new 예약어()</code> 로 생성할 수 있다.</li>
</ul>
</li>
</ul>
<h3 id="사용자-정의-객체">사용자 정의 객체</h3>
<p>원하는 프로그램을 만들기위해서는 미리 만들어저 있는 내장객체 외에도 사용자가 직접 객체를 만들어서 프로그래밍에 사용해야한다.</p>
<ul>
<li>사용자 정의 객체 생성하는 방법<ul>
<li>객체 리터럴 표기법</li>
<li>생성자 함수</li>
</ul>
</li>
</ul>
<h3 id="array객체">Array객체</h3>
<ul>
<li><p>Array 객체의 인스턴스 생성</p>
<pre><code class="language-jsx">  var arr = new Array();
  var otherArr = [1,2,3,4];</code></pre>
</li>
<li><p>주요함수</p>
<ul>
<li>concat()</li>
<li>join()</li>
<li>push(), unshift()</li>
<li>pop(), shift()</li>
<li>splice()</li>
<li>slice()</li>
</ul>
</li>
</ul>
<h1 id="5-document-object-model--dom">5. Document Object Model : DOM</h1>
<hr>
<p>웹 문서의 모든 요소를 자바스크립트를 이용해서 조작할 수 있도록 객체를 사용해 문서를 해석하는 방법</p>
<h3 id="dom의-구조">DOM의 구조</h3>
<ul>
<li>DOM 트리 형태</li>
<li>body(root element) → tag element → text / 속성 element</li>
</ul>
<h3 id="dom-요소에-접근하는-방법">DOM 요소에 접근하는 방법</h3>
<ol>
<li>getElementById(), getElementsByClassName(), getElementByTagName()</li>
<li>querySelector(), querySelectorAll()<ul>
<li>→ getAttribute()</li>
<li>→ setAttribute()</li>
</ul>
</li>
</ol>
<p>⇒ 1,2 : 요소까지만 접근 3 : 해당 요소의 텍스트, 속성 요소까지 접근 가능</p>
<h3 id="이벤트-처리-방법">이벤트 처리 방법</h3>
<ul>
<li>태그 안에 직접 이벤트 처리기 추가</li>
<li><script>안에 이벤트 발생 웹 요소를 가져온 후 이벤트 처리기를 연결</li>
<li>여러 이벤트 발생 시 → addEventListener(이벤트유형, 함수, 캡처 여부) 사용</li>
</ul>
<h3 id="새로운-노드-추가하기">새로운 노드 추가하기</h3>
<ol>
<li>요소 노드 생성 : createElement() </li>
<li>텍스트 요소 노드 생성 : createTextNode()</li>
<li>자식 노드로 추가하기 :  appendChild()</li>
<li>속성 추가하기<ol>
<li>createAttribute() → setAttributeNode()</li>
<li>setAttribute()</li>
</ol>
</li>
</ol>
<h3 id="원하는-위치에-노드-추가하기--삭제하기">원하는 위치에 노드 추가하기 / 삭제하기</h3>
<ul>
<li>insertBefore()</li>
<li>removeChild()</li>
</ul>
<h3 id="폼-요소에-접근하기">폼 요소에 접근하기</h3>
<ol>
<li>querySelector()로 요소를 가져옴</li>
<li>해당 요소에서 value 속성이나 배열을 이용해서 폼의 필드에 접근</li>
</ol>
<p><strong>폼 요소 검증에 유용한 함수</strong></p>
<p>자바스크립트 내장 함수 기존 입력한 값을 선택하거나 입력한 값이 지워진 자리에 커서를 가져다 놓는 역할을 한다.</p>
<ul>
<li>select()</li>
<li>focus()</li>
</ul>
<h3 id="선택-목록-및-옵션-항목에-접근하기">선택 목록 및 옵션 항목에 접근하기</h3>
<ul>
<li><code>formName.selectName.options**[index]**</code></li>
<li><code>formName.selectName.**selectedIndex**</code></li>
</ul>
<h3 id="라디오-버튼과-체크-상자에-접근하기">라디오 버튼과 체크 상자에 접근하기</h3>
<ul>
<li>라디오 버튼 요소나 체크 상자의 요소의 <code>checked</code> 속성 이용</li>
</ul>
<h1 id="5-browser-object-model--bom">5. Browser Object Model : BOM</h1>
<hr>
<h3 id="window-객체의-함수">Window 객체의 함수</h3>
<ul>
<li>alert()</li>
<li>prompt()</li>
<li>open()</li>
</ul>
<h3 id="navigator-객체">Navigator 객체</h3>
<p><strong>랜더링 엔진</strong>을 통해 웹 브라우저 종류를 구별할 수 있다.</p>
<h1 id="코드리뷰">코드리뷰</h1>
<p>이벤트 전파 원리를 공부 -&gt; receipe for문처럼 다 돌리지말고 부모에게 이벤트를 넣고 전파되는 방식을 공부해볼 것</p>
<p>로그인을 제외하고 입력받을때 잘못 입력받을때 focus 이용</p>
<p>로그인 실패시 실패 이유를 정확히 알려주지말</p>
<p>this → 이벤트가 발생한 객체</p>
<p>익명함수를 썼을때는 상위객체가 잡히기에 유의해서 사용할 것</p>
<p>익명함수에서 상위 객체를 못 가져올 수 있으니 매개변수로 받아와야함.</p>
<blockquote>
<p>  참고 서적
Do it! 웹 프로그래밍을 위한 자바스크립트 기본 편</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML + CSS ]]></title>
            <link>https://velog.io/@moon_dd/HTML-CSS</link>
            <guid>https://velog.io/@moon_dd/HTML-CSS</guid>
            <pubDate>Mon, 24 Jul 2023 06:48:23 GMT</pubDate>
            <description><![CDATA[<p>입사 후 한달동안 웹프로그래밍의 기본기를 다지는 시간을 가졌다. 
html css js jsp는 직접적으로 사용할 일이 없어서 따로 공부한 적이 없었다. 
그러다 나중에 주니어, 시니어가 되어 후배가 물어봤을 때 나도 이거 잘 모르는데? 하기는 너무 민망할 것 같아서 한달동안 카테고리별로 1권씩해서 4권의 책을 공부했다. 
(실제로 이제 개발공부를 시작한 사촌오빠가 물어봤는데, 좀 더 잘 설명해주고 싶었다.)</p>
<p>커리큘럼은</p>
<ol>
<li>html+css</li>
<li>js</li>
<li>servlet + jsp</li>
<li>sql + pl/sql</li>
</ol>
<p>이 순서로 공부했다.</p>
<h1 id="1-html-기본-다지기">1. HTML 기본 다지기</h1>
<p>파일문서는 형식자를 붙인 상태로 저장되는데, 여기서 형식자를 통해 해당 문서가 어떤 프로그램을 사용해서 작성되었는 지를 알 수 있다.</p>
<p><em>.*</em>html**이 붙어있는 파일 또한 파일인데, 이는 웹 브라우저를 통해서 실행되는 웹 문서이다.</p>
<p>기존문서와 다르게 문서를 편집하는 프로그램과 실행하는 프로그램이 다르다.</p>
<h2 id="1-1-html">1-1 HTML</h2>
<hr>
<ul>
<li>HyperText Markup Language의 약자이다.<ul>
<li><strong>HyperText</strong>는 링크를 통해서 사이트를 옮겨다닐 수 있는 문자를 말한다.</li>
<li><strong>Markup</strong>은 태그를 이용해서 해당 부분이 어떤 기능을 하고 있는 지 알 수 있는 것을 의미한다.</li>
</ul>
</li>
</ul>
<p>모든 웹 브라우저에서 HTML이 공통적으로 적용되기 위해 만들어진 표준 규칙이 HTML5이다.</p>
<h2 id="1-2-html-기본-문서구조">1-2 HTML 기본 문서구조</h2>
<hr>
<h3 id="특징"><strong>특징</strong></h3>
<ul>
<li>태그는 &lt;&gt;를 이용해 구분한다.</li>
<li>태그는 소문자로</li>
<li>여는 태그와 닫는 태그를 구분한다.</li>
<li>들여쓰기를 통해 문서 구조를 파악할 수 있다.</li>
<li>태그는 속성을 이용할 수 있다.</li>
</ul>
<h3 id="기본-구조">기본 구조</h3>
<ol>
<li><strong>&lt;!doctype&gt; : 문서 유형을 지정하는 선언문</strong></li>
<li><code>&lt;html&gt;</code> : 해당 문서의 시작과 끝을 표시<ol>
<li><code>&lt;head&gt;</code><ul>
<li>브라우저의 정보를 알려주는 태그</li>
</ul>
</li>
<li><code>&lt;meta&gt;</code><ul>
<li>문자 세트를 비롯한 문서 정보를 알려주는 태그</li>
</ul>
</li>
<li><code>&lt;body&gt;</code><ul>
<li>실제 브라우저에서 보여질 내용<h1 id="2-텍스트-관련-태그들">2. 텍스트 관련 태그들</h1>
</li>
</ul>
</li>
</ol>
</li>
</ol>
<h2 id="2-1-텍스트를-덩어리로-묶어주는-태그">2-1 텍스트를 덩어리로 묶어주는 태그</h2>
<hr>
<ol>
<li><p><code>&lt;hn&gt;</code> 태그</p>
</li>
<li><p><code>&lt;p&gt;</code> 태그</p>
</li>
<li><p><code>&lt;br&gt;</code> 태그</p>
</li>
<li><p><code>&lt;hr&gt;</code> 태그
 가로</p>
</li>
<li><p><code>&lt;blockquote&gt;</code> 태그</p>
</li>
<li><p><code>&lt;pre&gt;</code> 태그</p>
<p> 텍스트에 사용된 모든 여백과 줄바꿈이 그대로 표현된다.</p>
</li>
</ol>
<h2 id="2-2-텍스트를-한-줄로-표시하는-태그">2-2 텍스트를 한 줄로 표시하는 태그</h2>
<hr>
<ol>
<li><p><code>&lt;q&gt;</code> 태그</p>
<p> 짧은 인용용</p>
</li>
<li><p><code>&lt;span&gt;</code> 태그</p>
<p> <code>&lt;div&gt;</code> 와 비슷한 역할이지만 인라인 요소이다. ⇒ div : 레이아웃, 구조를 잡는 역할</p>
</li>
<li><p><code>&lt;ruby&gt;</code> 태그</p>
<p> 루비주석 추가</p>
</li>
</ol>
<h3 id="효과를-주는-태그"><strong>효과를 주는 태그</strong></h3>
<ol>
<li><p><code>&lt;strong&gt;</code>, <code>&lt;b&gt;</code> 태그</p>
<p> strong : 중요한 목적을 가지고 굵은 표시</p>
<p> b: 중요한 목적은 없지만 굵은 표시</p>
</li>
<li><p><code>&lt;em&gt;</code>, <code>&lt;i&gt;</code> 태그</p>
<p> 이탤릭체</p>
</li>
<li><p><code>&lt;mark&gt;</code> 태그</p>
<p> 하이라이트</p>
</li>
</ol>
<h2 id="2-3-목록을-만드는-태그">2-3 목록을 만드는 태그</h2>
<hr>
<ol>
<li><p><code>&lt;ul&gt;</code> + <code>&lt;li&gt;</code> 태그</p>
<p> 순서 X</p>
</li>
<li><p><code>&lt;ol&gt;</code> +<code>&lt;li&gt;</code> 태그</p>
<p> 순서 O</p>
</li>
<li><p><code>&lt;dl&gt;</code>,<code>&lt;dt&gt;</code>.<code>&lt;dd&gt;</code> 태그</p>
</li>
</ol>
<h2 id="2-4-표를-만드는-태그">2-4 표를 만드는 태그</h2>
<hr>
<ol>
<li><code>&lt;table&gt;</code>, <code>&lt;tr&gt;</code>, <code>&lt;td&gt;</code>, <code>&lt;th&gt;</code> 태그<ul>
<li>colspan, rowspan 속성</li>
</ul>
</li>
<li><code>&lt;caption&gt;</code>, <code>&lt;figcaption&gt;</code> 태그<ul>
<li>aria-describedby 속성</li>
</ul>
</li>
<li><code>&lt;thead&gt;</code>,<code>&lt;tbody&gt;</code>,<code>&lt;tfoot&gt;</code> 태그</li>
<li><code>&lt;col&gt;</code>,<code>&lt;colgroup&gt;</code> 태그</li>
</ol>
<h1 id="3-이미지와-하이퍼링크">3. 이미지와 하이퍼링크</h1>
<h2 id="3-1-이미지-태그">3-1 이미지 태그</h2>
<hr>
<h3 id="사용가능한-이미지-형식">사용가능한 이미지 형식</h3>
<ul>
<li>GIF</li>
<li>JPG/JPEG</li>
<li>PNG</li>
</ul>
<h3 id="이미지-삽입할-수-있는-태그">이미지 삽입할 수 있는 태그</h3>
<ol>
<li><code>&lt;img&gt;</code> 태그<ul>
<li>src 속성</li>
<li>alt 속성</li>
<li>width, height 속성</li>
</ul>
</li>
<li><code>&lt;figure&gt;</code>, <code>&lt;figcaption&gt;</code> 태그</li>
</ol>
<h2 id="3-2-링크-만들기">3-2 링크 만들기</h2>
<hr>
<h3 id="링크-연결하는-태그">링크 연결하는 태그</h3>
<ol>
<li><p><code>&lt;a&gt;</code> 태그</p>
<ul>
<li>href 속성</li>
<li>target 속성</li>
<li>usemap 속성</li>
</ul>
</li>
<li><p><code>&lt;map&gt;</code>, <code>&lt;area&gt;</code> 태그 </p>
<p> 한 이미지에 여러개 링크를 걸 수 있다.</p>
<ul>
<li>shape 속성</li>
<li>coords 속성</li>
<li>href 속성</li>
<li>target 속성</li>
</ul>
</li>
</ol>
<h3 id="앵커">앵커</h3>
<p><code>&lt;a&gt;</code> 태그의 href 속성을 <strong>“# +id”</strong> 으로 설정하면 같은 문서에 위치하고 있는 해당 id의 단락으로 이동하게된다.</p>
<h2 id="3-3-svg-이미지">3-3 SVG 이미지</h2>
<hr>
<p>사이즈에 따라 <strong>이미지가 깨질 수 있는 비트 이미지</strong>와 달리 <strong>svg 이미지</strong>는 사이즈 변경에도 <strong>선명하게 유지</strong>되기에 로고나 아이콘에 많이 사용되는 <strong>이미지 파일 형식</strong>이다.</p>
<p><code>&lt;script&gt;</code>태그 안에서 <strong>modernizer.svg 함수</strong>를 이용해서 조건문으로 svg 이미지가 지원되는 지 아닌지에 따라 보여주는 이미지를 다르게 설정해줄 수 있다.</p>
<h1 id="4-폼-관련-태그들">4. 폼 관련 태그들</h1>
<h2 id="4-1-폼-만들기">4-1 폼 만들기</h2>
<hr>
<ol>
<li><code>&lt;form&gt;</code> 태그<ul>
<li>autocomplete 속성</li>
</ul>
</li>
<li><code>&lt;label&gt;</code> 태그<ul>
<li>label 태글를 통해서 폼 요소에 레이블을 붙일 수 있다</li>
<li>2가지 방식<ul>
<li><code>&lt;label&gt;</code> 태그 안에 폼 요소를 넣는 것</li>
<li><code>&lt;label&gt;</code> 요소와 폼 요소를 따로 사용하고 <code>&lt;label&gt;</code> 태그의 for 속성과 id 속성을 이용해 연결해준다.<ul>
<li>라디오 버튼이나 체크박스에서 사용하면 텍스트만 터치해도 선택되는 장점이 있다.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><code>&lt;fieldset&gt;</code>, <code>&lt;legend&gt;</code> 태그</li>
</ol>
<p>⇒ 요즘은 form 태그보다 js 이용을 더 많이 사용한다.</p>
<p>⇒ form의 get/post 사용 목적 좀 더 공부하기</p>
<h2 id="4-2-input-태그">4-2 <code>&lt;input&gt;</code> 태그</h2>
<h3 id="input-태그"><code>&lt;input&gt;</code> 태그</h3>
<ul>
<li>id 속성</li>
<li>type 속성</li>
<li>value 속성<ul>
<li>value 속성은 <code>&lt;input&gt;</code> 요소의 type 속성값에 따라 다른 용도로 사용됩니다.<ul>
<li>“button”, “reset”, “submit” : 버튼 내의 텍스트를 정의함.</li>
<li>“hidden”, “password”, “text” : 입력 필드의 초깃값을 정의함.</li>
<li>“checkbox”, “image”, “radio” : 해당 입력 필드를 선택 시 서버로 제출되는 값을 정의함.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="input의-type">input의 type</h3>
<ol>
<li>type=”hidden”</li>
<li>type=”text”</li>
<li>type=”password”</li>
<li>type=”search”,”url”,”email”,”tel”</li>
<li>type=”number”</li>
<li>type=”range”<ul>
<li>min</li>
<li>max</li>
<li>step</li>
<li>value</li>
</ul>
</li>
<li>type=”radio”,”checkbox”<ul>
<li>name</li>
<li>value</li>
<li>checked</li>
</ul>
</li>
<li>type=”color”</li>
<li>type=”date, “month”, “week”</li>
<li>type=”time, “datetime”,”datetime-local”<ul>
<li>min</li>
<li>max</li>
<li>step</li>
<li>value</li>
</ul>
</li>
<li>type=”submit”,”reset”</li>
<li>type=”image”</li>
<li>type=”button”</li>
<li>type=”file”</li>
</ol>
<h2 id="4-3-input-태그의-다양한-속성">4-3 <code>&lt;input&gt;</code> 태그의 다양한 속성</h2>
<hr>
<ol>
<li>autofocus</li>
<li>placeholder</li>
<li>readonly</li>
<li>required</li>
</ol>
<h2 id="4-4-여러-데이터-나열해-보여주기">4-4 여러 데이터 나열해 보여주기</h2>
<hr>
<h3 id="데이터-나열해-보여주는-태그">데이터 나열해 보여주는 태그</h3>
<ol>
<li><p><code>&lt;select&gt;</code>, <code>&lt;optgroup&gt;</code>, <code>&lt;option&gt;</code> 태그</p>
<p> 여러 옵션 중에서 선택할 수 있는 드롭다운</p>
</li>
<li><p><code>&lt;datalist&gt;</code>, <code>&lt;option&gt;</code> 태그</p>
</li>
</ol>
<h3 id="여러줄-입력-받기">여러줄 입력 받기</h3>
<ol>
<li><code>&lt;textarea&gt;</code> 태그</li>
</ol>
<h2 id="4-5-기타-다양한-폼-요소들">4-5 기타 다양한 폼 요소들</h2>
<hr>
<ul>
<li><code>&lt;button&gt;</code> 태그<ul>
<li>type → submit, reset, button</li>
</ul>
</li>
<li><code>&lt;output&gt;</code> 태그<ul>
<li><code>&lt;form&gt;</code> 태그에서  oninput에 output의 결과 계산 방법을 정의해둔다.</li>
</ul>
</li>
<li><code>&lt;progress&gt;</code> 태그</li>
<li><code>&lt;meter&gt;</code>태그</li>
</ul>
<h2 id="2️⃣-css">2️⃣ CSS</h2>
<ul>
<li><ol start="5">
<li><p>CSS 기초</p>
<h1 id="5-css-기초">5. CSS 기초</h1>
<hr>
<h2 id="5-1-스타일과-스타일-시트">5-1. 스타일과 스타일 시트</h2>
<h3 id="스타일-형식">스타일 형식</h3>
<pre><code class="language-css">선택자 { 스타일 속성 :  속성값}</code></pre>
<h3 id="스타일-적용하는-방법">스타일 적용하는 방법</h3>
<ol>
<li><code>&lt;style&gt;</code> 태그와 <code>&lt;/style&gt;</code> 태그 내부에 작성</li>
<li><code>&lt;link&gt;</code> 태그를 이용하여 외부 CSS 파일과 연결</li>
<li><code>&lt;body&gt;</code> 내에서 인라인 스타일 적용</li>
</ol>
<h2 id="5-2-주요-선택자">5-2 주요 선택자</h2>
<hr>
<h3 id="선택자">선택자</h3>
<ul>
<li><p>전체 선택자</p>
<pre><code class="language-css"> * {
     속성:속성값;
     속성:속성값;
     .
     .
 }</code></pre>
</li>
<li><p>태그 선택자</p>
<pre><code class="language-css"> 태그 {
     속성:속성값;
     속성:속성값;
     .
     .
 }</code></pre>
</li>
<li><p>클래스 선택자</p>
<pre><code class="language-css"> .클래스명 {
     속성:속성값;
     속성:속성값;
     .
     .
 }</code></pre>
<ul>
<li>둘 이상의 스타일 적용시 공백으로 구분해서 나란히 적는다.</li>
</ul>
</li>
<li><p>id 선택자</p>
<pre><code class="language-css"> #id명 {
     속성:속성값;
     속성:속성값;
     .
     .
 }</code></pre>
</li>
<li><p>그룹 선택자</p>
<pre><code class="language-css"> 선택자1, 선택자2, ... {
     속성:속성값;
     속성:속성값;
     .
     .
 }</code></pre>
</li>
</ul>
</li>
</ol>
</li>
</ul>
<pre><code>## 5-3. 캐스캐이딩 스타일 시트

---

### 캐스캐이딩이란?

Cascading Style Sheet(CSS): 위에서 아래로 흐르는 스타일 시트

위에서 아래로 흐르는 방식으로 스타일을 적용함으로 스타일간 충돌을 방지하는 방식의 스타일 규칙이다.

### (1) 스타일이 적용되는 방법1 : 스타일 우선순위

**스타일 우선순위**

1. 사용자 스타일 시트의 중요 스타일
2. 제작자가 만든 스타일 중 **!important**가 붙은 스타일
3. 제작자 스타일 시트의 일반 스타일
4. 기본적인 브라우저 스타일 시트

********************적용범위 우선순위********************

1. 인라인 스타일
2. id 스타일
3. 클래스 스타일
4. 태그 스타일

**소스에서의 작성되는 순서**

- 소스에서 나중에 온 스타일이 먼저 온 스타일을 덮는다.

### (2) 스타일이 적용되는 방법2 : 스타일 상속

포함하는 태그 ⇒ 부모 요소

포함된 태그 ⇒ 자식 요소

자식 요소에 별도로 스타일이 지정되지 않으면 부모 요소에 있는 스타일 속성들이 적용된다.

예) body(부모 요소) → h1, h2, h3 .. (자식 요소)

## 5-4 CSS3와 CSS 모듈

---

### CSS3란?

html5와 같이 표준화된 CSS 규칙이다. 

html5과 다르게 CSS3는 **조금씩 계속 변하고** 있고 특정 모듈들은 브라우저 별로 규약이 완성되지 않아서 적용되는 게 다르다. 그럴때는 **접두사를 사용**해서 브라우저별로 속성을 지정해줘야한다.

이때 **-prefix-freeze**라는 자바스크립트를 다운받아 연결해두면 편리하다.</code></pre><h1 id="6-텍스트-관련-스타일">6. 텍스트 관련 스타일</h1>
<h2 id="6-1-글꼴-관련-스타일">6-1 글꼴 관련 스타일</h2>
<hr>
<ol>
<li>font-family : 글꼴 <ul>
<li>‘,’으로 구분하여 여러 글꼴 지정 가능. 순차대로 적용후 가능한 글꼴 사용</li>
</ul>
</li>
<li>font-size<ul>
<li>단위<ul>
<li>px</li>
<li>em : M의 너비</li>
</ul>
</li>
</ul>
</li>
<li>font-weight : 굵기</li>
<li>font-variant <ul>
<li>small-caps : 작은 대문자표 표시</li>
</ul>
</li>
<li>font-style<ul>
<li>italic</li>
<li>normal</li>
</ul>
</li>
<li><strong>font</strong><ul>
<li>font- 로 시작하는 모든 속성을 한번에 묶어 약식으로 표현할 수 있다. 예시 다시 따라해보기</li>
<li>font-size와 font-height(줄 간격)는 15px/25px과 같이 슬래시로 연결해 같이 표현하기도 한다.</li>
</ul>
</li>
</ol>
<p><strong>기본형 기호</strong></p>
<ol>
<li><p>|  은 나열한 옵션 중 하나가 값이 되어야한다.</p>
<p> ex) font-size: 값1 | 값2 | 값3</p>
</li>
<li><p>속성 값을 나열할 때 키워드는 그대로 사용한다.</p>
</li>
<li><p>속성 값을 나열할 떄 값이 아닌 유형일때 꺽쇠&lt;&gt;로 감싸서 사용한다.</p>
<p> ex) font: <font-style><font-variant><font-weight></p>
</li>
</ol>
<h2 id="6-2-텍스트-스타일">6-2. 텍스트 스타일</h2>
<hr>
<h3 id="텍스트-스타일-속성">텍스트 스타일 속성</h3>
<ol>
<li>color</li>
<li>text-decoration: 텍스트 줄 표시</li>
<li>text-transform: 텍스트 대-소문자</li>
<li>text-shadow</li>
<li>white-space</li>
<li>letter-spacing, word-spacing: 텍스트 간격 조절</li>
</ol>
<h2 id="6-3-문단-스타일">6-3. 문단 스타일</h2>
<hr>
<h3 id="문단-스타일">문단 스타일</h3>
<ol>
<li>direction</li>
<li>text-align<ul>
<li>justify → 양쪽에 맞춰 문단을 정렬할 경우 <strong>text-justify 속성</strong>을 이용해서 정렬 시 공백 조절이 가능하다.</li>
</ul>
</li>
<li>text-indent : 텍스트 들여쓰기  </li>
<li>line-heiht</li>
<li>text-overflow</li>
</ol>
<h2 id="6-4-목록-스타일">6-4. 목록 스타일</h2>
<hr>
<h3 id="목록-스타일">목록 스타일</h3>
<ol>
<li>list-style-type<ul>
<li>순서 없는 목록 속성값<ul>
<li>square</li>
<li>circle</li>
<li>disc</li>
<li>none</li>
</ul>
</li>
<li>순서 있는 목록 속성값<ul>
<li>decimal</li>
<li>….</li>
</ul>
</li>
</ul>
</li>
<li>list-style-image<ul>
<li>불릿 대신 이미지 넣기</li>
</ul>
</li>
<li>list-style-position</li>
<li>list-style<ul>
<li>font-와 비슷</li>
</ul>
</li>
</ol>
<h1 id="7-색상과-배경을-위한-스타일">7. 색상과 배경을 위한 스타일</h1>
<h2 id="07-2-배경-색과-배경-이미지">07-2. 배경 색과 배경 이미지</h2>
<ol>
<li><p>background-color 속성</p>
</li>
<li><p>background-clip 솔성</p>
<p> 배경 적용 범위 조절</p>
</li>
<li><p>background-repeat</p>
</li>
<li><p>background-size</p>
</li>
<li><p>background-position</p>
</li>
<li><p>background-origin</p>
<p> 배경 이미지 배치할 기준 조절</p>
</li>
<li><p>background-attachment</p>
<p> 배경 이미지 고정하기</p>
</li>
<li><p>background</p>
<h1 id="8-css-박스-모델">8. CSS 박스 모델</h1>
</li>
</ol>
<h2 id="8-1-css와-박스-모델">8-1. CSS와 박스 모델</h2>
<hr>
<h3 id="블록-레벨-요소와-인라인-레벨-요소">블록 레벨 요소와 인라인 레벨 요소</h3>
<ul>
<li><p>블록 레벨 요소</p>
<p>  태그를 사용해 요소를 삽입했을 때 해당 요소의 너비가 100%인 것을 의미한다.</p>
<p>  너비나 마진 패딩 등을 이용해 크기나 위치를 지정하려면 블록 레벨 요소이여야한다.</p>
</li>
<li><p>인라인 레 요소</p>
<p>  줄을 차지하지 않는 요소이다. 화면에 표시되는만큼만 영역을 차지하고 나머지 공간에는 다른 요소가 올 수 있다.</p>
<p>  즉 한 줄에 여러가지 요소가 올 수 있다.</p>
</li>
</ul>
<h3 id="박스모델">박스모델</h3>
<p><strong>박스 모델 구성요소</strong></p>
<ol>
<li><p>컨텐츠 영역</p>
</li>
<li><p>패딩</p>
<p> 실제 컨텐츠와 박스 영역 사이의 여백</p>
</li>
<li><p>테두리</p>
<p> 박스의 테두리</p>
</li>
<li><p>마진</p>
<p> 다른 박스 모델 사이의 여백인</p>
</li>
</ol>
<h3 id="속성">속성</h3>
<ol>
<li><p>width, height</p>
</li>
<li><p>display</p>
<ul>
<li><p>block</p>
<p>  해당 요소를 블록 레벨로 지정</p>
<p>  인라인 레벨 요소도 블록 레벨 요소로 변경할 수 있다.</p>
</li>
<li><p>inline</p>
<p>  해당 요소를 인라인 레벨 요소로 변경한다.</p>
<p>  블록 레벨 요소를 인라인 레벨 요소로 변경할 수 잇다.</p>
</li>
<li><p>inline-block</p>
<p>  요소를 인라인 레벨로 배치하면서 블록 레벨의 속성을 지정할 수 있다.</p>
</li>
<li><p>none</p>
<p>  <code>visibility:hidden;</code> 과 비슷해보이지만 visibility는 보이지 않을 뿐 공간은 존재하지만 <code>disply:none;</code>은 아예 공간자체가 존재하지 않는다.</p>
</li>
</ul>
</li>
</ol>
<h2 id="8-2-테두리-관련-속성들">8-2 테두리 관련 속성들</h2>
<hr>
<h3 id="테두리-관련-속성">테두리 관련 속성</h3>
<ol>
<li>border-style</li>
<li>border-width</li>
<li>border-color</li>
<li>border</li>
<li>border-radius</li>
<li>border-shadow</li>
</ol>
<h2 id="8-3-여백을-조절하는-속성들">8-3. 여백을 조절하는 속성들</h2>
<hr>
<h3 id="여백-관련-속성">여백 관련 속성</h3>
<ol>
<li><p>margin</p>
<p> 속성값 순서 : 상 우 하 좌 </p>
</li>
<li><p>padding</p>
<p> 속성값 순서 : 상 우 하 좌</p>
<h1 id="9-css-레이아웃">9. CSS 레이아웃</h1>
</li>
</ol>
<h2 id="9-1-css-포지셔닝과-주요-속성들">9-1. CSS 포지셔닝과 주요 속성들</h2>
<hr>
<h3 id="박스-너비-기준-정하기">박스 너비 기준 정하기</h3>
<ul>
<li><p><code>box-sizing: content-box</code></p>
<p>  <strong>width = content width</strong></p>
</li>
<li><p><code>box-sizing: border-box</code></p>
<p>  <strong>width = content + padding + border</strong></p>
</li>
</ul>
<h3 id="float--clear-속성">float / clear 속성</h3>
<ul>
<li><p>float → 속성값을 기준으로 정렬되어 배치된다.</p>
<pre><code class="language-css">  float : left | right | none</code></pre>
</li>
<li><p>clear → float 속성을 해제한다.</p>
<pre><code class="language-css">  clear : none | left | right | both</code></pre>
</li>
</ul>
<h3 id="레이아웃-만들기">레이아웃 만들기</h3>
<ul>
<li>콘텐츠 전체를 감싸는 container 요소를 사용한다.<ul>
<li>contents만 감싸기도 하고 header부터 footer까지 감싸기도 한 것 같다.</li>
</ul>
</li>
</ul>
<ol>
<li>header</li>
<li>contents + sidebar → 여기서 side bar를 양쪽으로 만들면 3단이 된다.</li>
<li>footer</li>
</ol>
<h3 id="배치-방법-지정하기">배치 방법 지정하기</h3>
<ul>
<li><p><strong>position 속성</strong></p>
<ol>
<li>static : 문서 흐름대로</li>
<li>relative : 문서 흐름대로 배치하지만 top,right,bottom,left 속성을 이용해 기존 위치를 기준으로 위치 지정 가능 </li>
<li>absolute : 부모를 기준으로 위치 지정 ( 부모는 반드시 relative로 설정되어야함)</li>
<li>fixed : 브라우저 기준으로 위치 지정</li>
</ol>
</li>
<li><p><strong>visibility 속성</strong></p>
<ul>
<li>visible</li>
<li>hidden</li>
<li>collapse</li>
</ul>
</li>
<li><p><strong>z-index 속성</strong></p>
<ul>
<li>다른 요소를 쌓을때 사용할 수 있다.</li>
</ul>
</li>
</ul>
<h2 id="9-2-다단으로-편집하기">9-2. 다단으로 편집하기</h2>
<hr>
<h3 id="단-생성에-관련된-속성">단 생성에 관련된 속성</h3>
<ol>
<li>column-width</li>
<li>column-count</li>
<li>column-gap</li>
<li>column-rule</li>
<li>break-after</li>
<li>column-span</li>
</ol>
<h2 id="9-3-표-스타일">9-3 표 스타일</h2>
<hr>
<h3 id="표-스타일">표 스타일</h3>
<ol>
<li>caption-side</li>
<li>border</li>
<li>border-collapse :  테두리 통합, 분리</li>
<li>border-spacing : 셀 테두리 사이 거리 지정하기</li>
<li>empty-cells :빈 셀의 표시 여부 지정하기</li>
<li>width, height</li>
<li>table-layout : 콘텐츠에 맞게 셀 너비 지정하</li>
<li>text-align</li>
<li>vertical-align</li>
</ol>
<h1 id="3️⃣-html--css">3️⃣ HTML + CSS</h1>
<h1 id="10-html5와-시맨틱-태그">10. HTML5와 시맨틱 태그</h1>
<h2 id="10-1-html5-문서">10-1. HTML5 문서</h2>
<hr>
<h3 id="시맨틱-태그">시맨틱 태그</h3>
<ol>
<li><p><code>&lt;header&gt;</code> 태그</p>
</li>
<li><p><code>&lt;nav&gt;</code> 태그</p>
</li>
<li><p><code>&lt;section&gt;</code> 태그</p>
<p> ⇒ 내용 구분</p>
</li>
<li><p><code>&lt;article&gt;</code> 태그 </p>
<p> ⇒ 본문 영역</p>
</li>
<li><p><code>&lt;aside&gt;</code> 태그</p>
</li>
<li><p><code>&lt;iframe&gt;</code> 태그</p>
</li>
<li><p><code>&lt;footer&gt;</code> 태그</p>
</li>
<li><p><code>&lt;address&gt;</code> 태그</p>
</li>
</ol>
<h1 id="11-html5와-멀티미디어">11. HTML5와 멀티미디어</h1>
<h2 id="11-1-웹과-멀티미디어">11-1 웹과 멀티미디어</h2>
<hr>
<p>멀티미디어를 직접 재생할 수 없어 외부 프로그램인 플러그인을 적용해서 사용했다.</p>
<ol>
<li><p><code>&lt;object&gt;</code>, <code>&lt;embed&gt;</code> 태그</p>
<p> 외부 파일 삽입하기</p>
</li>
</ol>
<h2 id="11-2-오디오--비디오-재생하기">11-2 오디오 &amp; 비디오 재생하기</h2>
<hr>
<ol>
<li><code>&lt;audio&gt;</code> 태그</li>
<li><code>&lt;video&gt;</code> 태그</li>
<li><code>&lt;source&gt;</code> 태그</li>
</ol>
<h1 id="12-다재다능한-css3-선택자">12. 다재다능한 CSS3 선택자</h1>
<h2 id="12-1-연결-선택자">12-1. 연결 선택자</h2>
<hr>
<ul>
<li><p><strong>하위 선택자</strong></p>
<p>  <code>section p { color : blue;}</code></p>
<p>  부모 아래에 있는 자식 요소뿐만 아니라 모든 하위 요소까지 적용된다.</p>
</li>
<li><p>자식 선택자</p>
<p>  <code>section &gt; p { color : blue;}</code></p>
<p>  부모 바로 아래에 있는 자식 요소만 적용된다.</p>
</li>
<li><p>인접 형제 선택자</p>
<p>  <code>h1 + p { text-decoration: underline;}</code></p>
<p>  같은 부모  요소를 가진 형제 요소 중 요소1 다음에 바로 오는 동생 요소2에 스타일을 적용한다. 위 예시에서는 h1의 형제 중 첫번째 p에 스타일이 적용된다.</p>
</li>
<li><p>형재 선택자</p>
<p>  <code>h1 ~ p { text-decoration: underline; }</code></p>
<p>  첫번째 요소 뒤에 오는 모든 형제 두번째 요소에 스타일을 적용한다.</p>
<p>  위 예시에서는 h1의 형재 중 모든 p요소에 스타일을 적용한다.</p>
</li>
</ul>
<h2 id="12-2-속성-선택자">12-2 속성 선택자</h2>
<hr>
<ul>
<li><p>속성 선택자</p>
<p>  <code>a[href]</code></p>
</li>
<li><p>속성 = 값 선택자</p>
<p>  <code>a[target=”_blank”]</code></p>
</li>
<li><p>[속성 ~= 값]</p>
<p>  <code>class ~= “button”</code></p>
<p>  class 속성에서 button이라는 값이 포함 된 요소에 스타일을 지정한다.</p>
</li>
<li><p>[속성 |= 값]</p>
<p>  <code>a[title |= “us]</code></p>
<p>  특정 값이 포함된 속성에 스타일을 적용한다. 이때 값은 한 단어로 일치해야한다.</p>
</li>
<li><p>[속성 ^= 값]</p>
<p>  <code>a[title ^= “eng”]</code></p>
<p>  지정한 값으로 시작하는 속성 값에만 스타일을 적용한다.</p>
</li>
<li><p>[속성 $= 값]</p>
<p>  <code>a[href $= “hwp”</code></p>
<p>  지정한 값으로 끝나는 속성 값에만 스타일을 적용한다.</p>
</li>
<li><p>[속성 *= 값]</p>
<p>  <code>a[href *= “w3”]</code></p>
<p>  값이 어느위치에든 포함되어 있는 속성에 스타일을 적용한다.</p>
</li>
</ul>
<h2 id="12-3-가상-클래스와-가상-요소">12-3 가상 클래스와 가상 요소</h2>
<hr>
<h3 id="사용자-동작에-반응하는-가상-클래스">사용자 동작에 반응하는 가상 클래스</h3>
<ol>
<li><p>:link 가상 클래스 선택자</p>
<p> 방문하지 않은 링크</p>
</li>
<li><p>:visited 가상 클래스 선택자</p>
</li>
<li><p>:hover 가상 클래스 선택자</p>
<p> 링크나 이미지를 누르고 있을 때</p>
</li>
<li><p>:active 가상 클래스 선택자</p>
</li>
<li><p>:focus 가상 클래스 선택자</p>
<p> 포커스가 맞춰졌을때( 마우스 커서를 갖다 놓거나 초점을 이동햇을 때)</p>
</li>
</ol>
<h3 id="ui-요소-상태에-따른-가상-클래스">UI 요소 상태에 따른 가상 클래스</h3>
<ol>
<li>:enabled 와 :disabled 가상 클래스 선택자</li>
<li>:checked 가상 클래스 선택자</li>
</ol>
<h3 id="구조-가상-클래스">구조 가상 클래스</h3>
<ol>
<li>:root 가상 클래스 선택자</li>
<li>:nth-child(n)와 :nth-last-child(n) 가상 클래스 선택자</li>
<li>:nth-of-type(n), :nth-last-of-type(n) 가상 클래스 선택자</li>
<li>:first-child, :last-child 가상 클래스 선택자</li>
<li>:first-of-type, :last-of-type 가상 클래스 선택자</li>
<li>:only-chlid, : onlyp-of-type 가상 클래스 선택자</li>
</ol>
<h3 id="그-외-가상-클래스">그 외 가상 클래스</h3>
<ol>
<li><p>:target</p>
<p> 앵커의 목적지가 되는 부분의 스타일 지정</p>
</li>
<li><p>:not</p>
<p> 특정 요소가 아닐때 스타일 적용</p>
</li>
</ol>
<h3 id="가상요소">가상요소</h3>
<ol>
<li><p>::before, ::after 요소</p>
<p> 내용 앞뒤에 콘텐츠를 추가할 수 있다.</p>
</li>
<li><p>::first-line 요소와 ::first-letter 요소</p>
</li>
</ol>
<h1 id="13-css3와-애니메이션">13. CSS3와 애니메이션</h1>
<h2 id="13-1-변형">13-1. 변형</h2>
<hr>
<h3 id="변형을-위한-속성과-함수">변형을 위한 속성과 함수</h3>
<ol>
<li><p>transform 속성</p>
</li>
<li><p>translate 변형 함수</p>
<p> 요소 이동시키기</p>
<pre><code class="language-css"> .photo { transform: translate(50px, 100px); }</code></pre>
</li>
<li><p>scale 변형 함수</p>
<p> 요소 확대/축소시키기</p>
</li>
<li><p>rotate 변형 함수</p>
<p> 요소 회전하기</p>
</li>
<li><p>skew 변형 함수</p>
<p> 요소를 비틀어 왜곡하기</p>
</li>
</ol>
<h2 id="13-2-변형과-관련된-속성들">13-2. 변형과 관련된 속성들</h2>
<hr>
<ol>
<li><p>transform-origin 속성</p>
<p> 변형 기준점 설정하기</p>
</li>
<li><p>perspective, perspective-origin 속성</p>
<p> 원근감 표현하기</p>
</li>
<li><p>transform-style 속성</p>
<p> 3d 변형 적용하기</p>
</li>
<li><p>backface-visibility 속성</p>
<p> 요소의 뒷면 표시하기</p>
<h1 id="14-반응형-웹이란">14. 반응형 웹이란?</h1>
</li>
</ol>
<p>크롬 디바이스 모드를 사용하면 pc에서도 디바이스 환경을 확인할 수 있다.</p>
<h2 id="14-2-가변-그리드-레이아웃">14-2 가변 그리드 레이아웃</h2>
<hr>
<h3 id="가변-그리드-레이아웃-만들기">가변 그리드 레이아웃 만들기</h3>
<ol>
<li><p>전체 감싸는 요소 확인하기</p>
</li>
<li><p>각 요소의 너비 값 계산하기</p>
<p> (요소의 너비 / 콘텐츠 전체를 감싸는 요소의 너비 ) * 100</p>
</li>
</ol>
<h2 id="14-3-가변-레이아웃과-가변요소">14-3. 가변 레이아웃과 가변요소</h2>
<h3 id="가변글꼴">가변글꼴</h3>
<ul>
<li><p>em 단위</p>
<p>  부모 요소의 글꼴을 기준으로 하기 때문에 중첩된 부모 요소의 글자 크기의 영향을 받는다.</p>
</li>
<li><p>rem 단위</p>
<p>  처음부터 기본 크기를 지정하기 때문에 중간에 기본 값이 바뀌지 않는다.</p>
</li>
</ul>
<h3 id="가변-이미지">가변 이미지</h3>
<p>CSS에서 max-width 속성 값을 100%로 지정한다.</p>
<p>화면의 너비값이나 픽셀 밀도에 따라 <img>태그의 srcset 속성에서 해상도의 이미지를 지정해줄 수 있다.</p>
<h3 id="가변-비디오">가변 비디오</h3>
<p>CSS에서 max-width 속성 값을 100%로 지정한다.</p>
<h1 id="15-미디어-쿼리">15. 미디어 쿼리</h1>
<p>미디어 쿼리는 CSS3 모듈 중 하나로 브라우저에 접속하는 기기의 종류에 따라 특정한 CSS 스타일을 사용하도록 한다.</p>
<h3 id="미디어-쿼리-구문">미디어 쿼리 구문</h3>
<pre><code class="language-css">@media [only | not] 미디어 유형 [and (조건)]  [and (조건)]</code></pre>
<p>그리드 레이아웃을 기본으로 하여 여유있는 공간에 따라 플랙스 박스를 자유롭게 변형할 수 있다. 화면 크기에 따라 레이아웃의 배치나 크기를 조절해야 할 떄 편리하게 사용할 수 있다.</p>
<h2 id="16-1-플렉스-박스-레이아웃과-기본-속성들">16-1. 플렉스 박스 레이아웃과 기본 속성들</h2>
<hr>
<ol>
<li><strong>display 속성</strong></li>
</ol>
<pre><code class="language-css">display: flex | inline-flex</code></pre>
<ul>
<li>flex : 박스 레벨 요소로 정의</li>
<li>inline-flex: 인라인 레벨 요소로 정의</li>
</ul>
<p>브라우저마다 플렉스 박스를 지원하는 방법이 달라 브라우저 접두사를 붙어야 한다.</p>
<ol>
<li><p>flex-direction 속성</p>
</li>
<li><p>flex-wrap 속성</p>
<p> 플렉스 항목을 한 줄 또는 여러 줄로 배치하기</p>
</li>
<li><p>flex-flow 속성</p>
<p> flex-direction + flex-wrap 속성</p>
</li>
<li><p>order 속성</p>
</li>
<li><p>flex 속성</p>
<p> 플렉스 항목 크기 조절하기</p>
</li>
</ol>
<h2 id="16-2-플랙스-박스-항목-배치를-위한-속성들">16-2. 플랙스 박스 항목 배치를 위한 속성들</h2>
<ol>
<li><p>justify-content 속성</p>
<p> 플렉스 항목을 주축 방향으로 배치할때 배치 기준을 지정하는 속성</p>
</li>
<li><p>align-items 속성, align-self 속성</p>
<p> align-itmes ⇒ 교차축을 기준으로 배치 방법을 조절</p>
<p> align-self ⇒ 특정 플렉스 항목만 배치 방법을 바꿀 수 있다.</p>
</li>
<li><p>align-content 속성</p>
<p> 여러 줄일 때의 배치 방법 지정할 수 있다.</p>
</li>
</ol>
<blockquote>
<p> 참조 도서
Do it! HTML5+CSS3 웹 표준의 정석</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring @Mapper]]></title>
            <link>https://velog.io/@moon_dd/Spring-Mapper</link>
            <guid>https://velog.io/@moon_dd/Spring-Mapper</guid>
            <pubDate>Tue, 27 Jun 2023 12:42:22 GMT</pubDate>
            <description><![CDATA[<p>MapStruct를 사용하면서 알게 된 것들</p>
<pre><code>@Mapper(componentModel = &quot;spring&quot;, nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)
public interface UserMapper {
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    List&lt;TbUserResponseDTO&gt; toDtoList(List&lt;TbUserEntity&gt; entityList);

}</code></pre><ul>
<li><p>componentModel = &quot;spring&quot;
  -&gt; spring에서 bean으로 등록하게 해준다. Mapper를 생성하는 건 비싸기 때문</p>
</li>
<li><p>nullValueMappingStrategy
  -&gt; null인 값 매핑시 어떻게 해결할건지</p>
<ul>
<li>UserMapper INSTANCE
 -&gt; MapStruct에서 interface에서 INSTANCE로 선언하면 인스턴스를 새로 생성할 필요없이 싱글톤으로 생성된 인스턴스를 사용하게 된다.</li>
</ul>
</li>
<li><p>@Mapper로 등록해두면 interface를 나중에 MapperImple로 구현해주는 것 같다.
<img src="https://velog.velcdn.com/images/moon_dd/post/59a5574d-ba76-4826-adde-d4b3ea77a7f1/image.png" alt=""></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[다중 처리기 스케줄링]]></title>
            <link>https://velog.io/@moon_dd/%EB%8B%A4%EC%A4%91-%EC%B2%98%EB%A6%AC%EA%B8%B0-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</link>
            <guid>https://velog.io/@moon_dd/%EB%8B%A4%EC%A4%91-%EC%B2%98%EB%A6%AC%EA%B8%B0-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</guid>
            <pubDate>Mon, 15 May 2023 07:59:37 GMT</pubDate>
            <description><![CDATA[<h2 id="다중-처리기-스케줄링에-대한-접근-방법">다중 처리기 스케줄링에 대한 접근 방법</h2>
<ol>
<li><p><strong>비대칭 다중처리</strong> → 마스터 서버</p>
<p> 하나의 프로세서가 모든 스케줄링 결정과 I/O 처리 그리고 다른 시스템의 활동을 취급하는 것</p>
<p> 하나의 코어만 시스템 자료구조에 접근하여 <strong>자료 공유의 필요성이 없어</strong>지기에 간단하다. 하지만 모든 스케줄링 결정을 맡고 있는 마스터 서버가 일을 못 하면 <strong>전체 시스템 성능을 저하할 수 있는 병목</strong>이 될 수 있다.</p>
</li>
<li><p><strong>대칭 다중 처리 (Symmetric MulitiProcessing, SMP)</strong></p>
<p> <strong>거의 모든 최신 운영체제</strong>는 SMP를 사용한다. 대칭 다중 처리는 각 프로세서는 스스로 스케줄링을 할 수 있다. <strong>각 프로세서의 스케줄러가 준비 큐를 검사</strong>하고 <strong>실행할 스레드를 선택</strong>하여 스케줄링이 진행된다.</p>
<p> 스케줄 대상이 되는 스레드가 담기는 준비큐 전략</p>
<ul>
<li>공통 준비 큐</li>
<li>각 프로세서별로 스레드 준 큐</li>
</ul>
</li>
</ol>
<h2 id="다중-코어-프로세서">다중 코어 프로세서</h2>
<p>CPU는 프로세서 중 가장 중요한 역할을 하는 하드웨어이다. 이 <strong>CPU 안에는 물리적인 계산</strong>을 <strong>실제로 진행하는 유닛을 코어(Core)</strong>라고 한다.</p>
<p>CPU 안에는 한개 이상의 코어가 들어갈 수 있고 최근 하드웨어들은 <strong>점점 많은 코어</strong>를 탑재하는 추세이다.</p>
<p>한 프로세서에 여러 코어가 장착되어진 것을 다중 코어 프로세서라고 한다. <strong>각 코어는 구조적인 상태를 유지하고 있어서 운영체제 입장에서는 개별적인 논리적 CPU처럼 보이게 된다.</strong></p>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/81b1933e-8c19-4faa-b025-b7a57f95f675/image.png" alt=""></p>
<p>출처 : <a href="https://velog.io/@kanamycine/%EB%A9%98%ED%86%A0%EB%A7%81-1.-%EB%A9%80%ED%8B%B0%EC%BD%94%EC%96%B4-%ED%94%84%EB%A1%9C%EC%84%B8%EC%84%9C">https://velog.io/@kanamycine/멘토링-1.-멀티코어-프로세서</a></p>
<h3 id="하드웨어-스레드와-소프트웨어-스레드">하드웨어 스레드와 소프트웨어 스레드</h3>
<p>코어안에는 <strong>하드웨어 스래드</strong>가 장착되어 있는데 이 또한 각 코어에 여러개의 하드웨어 스래드가 장착될 수 있고, 이는 <strong>멀티 스레드 처리 코어</strong>라고 말한다.</p>
<ul>
<li>소프트웨어 스래드 → 우리가 계속 말하던 스레드</li>
<li>하드웨어 스래드 → OS가 스케줄 해줄 수 있는 최소 단위의 일</li>
</ul>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/16323849-f28c-4ab5-b128-f51365c71013/image.png" alt=""></p>
<p>출처 : <a href="https://juneyr.dev/thread">https://juneyr.dev/thread</a></p>
<p>이 하드웨어 스레드는 명령어 포인터 및 레지스터 집합과 같은 <strong>구조적 상태를 유지</strong>한다.</p>
<p>그래서 운영체제 입장에서는 소프트웨어 스래드를 실행할 수 있는 논리적 CPU로 보인다. 이를 <strong>칩 다중 스레딩(Chip Multi-Threading, CMT)</strong>이라고 한다.</p>
<p>아래 그림은 각 코어에 2개의 하드웨어 스레드가 있다. 운영체제 입장에서는 8개의 CPU가 있는 것으로 인지한다. </p>
<p>하나의 코어는 오직 하나의 스레드만 실행할 수 있다. 그래서 코어속 여러개의 하드웨어 스래드는 사실 동시에 실행되는 <strong>병렬성</strong>을 가지는 것이 아닌 시간에 따라 교대로 실행되어 동시에 실행되는 것처럼 보이는 <strong>동시성</strong>을 띄고 있다.</p>
<p>메모리를 기다리는 동안 하나의 하드웨어 스레드가 중단되면 코어가 다른 스레드로 전환할 수 있다. </p>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/8e8c171f-3b5b-4ab2-bf57-c4cd2c7b5e4c/image.png" alt=""></p>
<h3 id="다중-스레드화">다중 스레드화</h3>
<p>일반적으로 프로세서가 다중 스레드화 하는 데에는 2가지 방법이 있다.</p>
<ol>
<li><p><strong>거친 다중 스레딩 (coarse-grained)</strong></p>
<p> 매 사이클이 아닌 메모리 스톨과 같은 긴 지연시간을 가진 이벤트가 발생하면 그때 스래드를 변경한다.</p>
</li>
<li><p><strong>세밀한 스레딩 (fine-grained)</strong></p>
<p> 매 사이클마다 스레드를 변경한다.</p>
</li>
</ol>
<p><strong>결과적으로 다중 스레드 다중 코어 프로세스는 아래 그림과 같이 두 개의 다른 스케줄링 단계가 필요하다</strong></p>
<ol>
<li>하드웨어 스래드에 어떤 소프트웨어 스레드들을 실행시킬 지 결정</li>
<li>각 코어가 실행할 하드웨어 스래드 결정</li>
</ol>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/83c12195-59b9-4a09-a01b-d7ef327adce1/image.png" alt=""></p>
<h2 id="부하-균등화-load-balancing">부하 균등화 (Load Balancing)</h2>
<p>SMP 시스템 중 각 프로세서가 실행할 스레드를 결정하기위해 각자 준비 큐를 가지고 있는 시스템의 경우에는 <strong>부화 균등화 기능</strong>이 필요하다.</p>
<p>부화 균등화는 SMP 시스템이 모든 프로세서 사이에 부하가 고르게 배분되도록 도와주는 것이다. 이를 위한 방법으로는 2가지가 있다.</p>
<ol>
<li><p><strong>push migraion</strong> </p>
<p> 특정 태스크가 주기적으로 각 프로세서의 부하 여부를 검사하고 과부하인 처리기에서 덜 바쁜 처리기로 스레드를 이동(push) 시키는 방식</p>
</li>
<li><p><strong>pull migration</strong></p>
<p> 쉬고 있는 프로세서가 바쁜 프로세서를 기다리고 있는 프로세스를 가지고(pull)오는 방식</p>
</li>
</ol>
<h2 id="처리기-선호도-processor-affinity">처리기 선호도 (Processor Affinity)</h2>
<p>캐쉬 등의 리소스 관련 문제로 인해 스레드는 한 프로세서에서 다른 프로세서로 이주시키지 않고 대신 같은 프로세서에서 계속 실행시키면서 이용하려한다. 이를 <strong>프로세서 선호도</strong>라고 한다.</p>
<p><strong>프로세서 선호도 형태</strong></p>
<ul>
<li><strong>약한 선호도(soft affinity)</strong> : 운영체제는 프로세스를 원하는 특정 처리기에 실행시키려고 시도를 하나 프로세스가 처리기 사이에 이주하는 것이 가능ㅎ다.</li>
<li><strong>강한 선호도(hard affinity)</strong> : 운영체제는 시스템 콜을 사용해서 자신이 처리될 특정 처리기를 명시한다.</li>
</ul>
<p>많은 시스템에서 둘 다 모두 지원하고 있다.</p>
<p>위에서 말했던 Load Balancing 부하 균등화는 Processor Affinity 처리기 선호도를 상쇄한다.</p>
<p>동일한 프로세서에서 스레드를 계속 실행시키면 캐시 메모리에 있는 데이터를 활용할 수 있다. 하지만 부하 균동화를 통해 스레드를 이동시키면 이 이점이 사라진다.</p>
<p>그래서 자신의 문맥에 맞춰서 잘 활용하자</p>
<h2 id="이기종-다중처리">이기종 다중처리</h2>
<p>모바일 시스템에서는 다중 코어 아키텍처가 채택되어 있지만, 일부 시스템은 전력 소비를 조장하는 기능을 포함하여 클록 속도 및 전력 관리 측면에서 차이가 나는 코어를 사용하여 설계된다.</p>
<p>big 코어는 고성능이지만 많은 에너지를 사용하여 대화형 응용 프로그램을 할당하고,</p>
<p>little 코어는 더 적은 에너지를 사용하지만 저성능이여서 백그라운드 배치 프로그램을 할당한다.</p>
<h2 id="실시간-시스템-real-time-system">실시간 시스템 (Real-Time System)</h2>
<p>실시간 시스템에서는 <strong>작업 수행이 요청되었을 때 이를 제한된 시간 안에 처리해서</strong> 결과를 내주어야한다.</p>
<p>이 제한된 시간안에 처리하는 방식에 따라 2가지 실시간 시스템으로 분류할 수 있다.</p>
<ol>
<li><p><strong>연성 실시간 시스템 (Soft Real-Time System)</strong></p>
<p> 실시간 프로세스가 실시간이 아닌 프로세스들에 우선권을 가진다는 것을 보장</p>
<p> 하지만 이것이 스케줄 되는 시점에 대해서는 아무런 보장이 없다.</p>
</li>
<li><p><strong>경성 실시간 시스템 (Hard Real-Time System)</strong></p>
<p> 태스크를 반드시 마감시간까지 서비스를 받을 수 있게끔 보장한다.</p>
<p> 마감시간까지 서비스를 받지 못 하면 해당 태스크가 실행되지 않은 것과 같은 결과를 도출한다.</p>
</li>
</ol>
<h2 id="퀴즈">퀴즈</h2>
<hr>
<ul>
<li><p>다중 스레드 다중 코어 프로세서의 스케줄 단계에 대해 설명하라</p>
<ol>
<li>하드웨어 스래드에 어떤 소프트웨어 스레드들을 실행시킬 지 결정</li>
<li>각 코어가 실행할 하드웨어 스래드 결정</li>
</ol>
</li>
<li><p>하드웨어 스래드와 소프트웨어 스래드를 설명하라</p>
<p>  소프트웨어 스래드는 프로세스에서 실행되는 명령어들의 유닛이고</p>
<p>  하드웨어 스래드는 OS가 프로세서에게 스케줄해줄 수 있는 일의 유닛이다. 소프트웨어 스래드가 하드웨어 스래드에서 실행되는 것이다.</p>
</li>
<li><p>부하균등화와 처리기 선호도의 관계에 대해 설명하라</p>
<p>  동일한 프로세서에서 스레드를 계속 실행시키면 캐시 메모리에 있는 데이터를 활용할 수 있다. 하여 프로세스별로 특정 처리기에 실행되기 원하는 선호도가 있다. 하지만 부하 균동화를 통해 스레드를 이동시키면 이 이점이 사라진다.</p>
</li>
</ul>
<h2 id="참조">참조</h2>
<hr>
<p><a href="https://imbf.github.io/computer-science(cs)/2020/10/18/CPU-Scheduling.html">[Operating System - Chapter 5] CPU 스케줄링</a></p>
<p><a href="https://velog.io/@wilko97/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EA%B3%B5%EB%A3%A1%EC%B1%85-Chapter-06.-Thread-Concurrency">[운영체제 - 공룡책] Chapter 05. CPU Scheduling</a></p>
<p><a href="https://juneyr.dev/thread">하드웨어 스레드와 소프트웨어 스레드</a></p>
<p><a href="https://eunajung01.tistory.com/67">[Chapter 5. CPU 스케줄링] 실시간 시스템과 실시간 스케줄링 (RM, EDF)</a></p>
<p><a href="https://velog.io/@kanamycine/%EB%A9%98%ED%86%A0%EB%A7%81-1.-%EB%A9%80%ED%8B%B0%EC%BD%94%EC%96%B4-%ED%94%84%EB%A1%9C%EC%84%B8%EC%84%9C">멀티코어 프로세서</a></p>
<p><a href="https://velog.io/@crosstar1228/CS%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%93%B0%EB%A0%88%EB%93%9C-%EB%A9%80%ED%8B%B0%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EB%A9%80%ED%8B%B0%EC%93%B0%EB%A0%88%EB%93%9C%EB%A9%80%ED%8B%B0%EC%BD%94%EC%96%B4">[CS]프로세스와 쓰레드, 멀티프로세스와 멀티쓰레드(+멀티코어)</a></p>
<p><a href="https://chopby.tistory.com/14">컴퓨터구조 16 - Multithreading</a></p>
<p><a href="https://seamless.tistory.com/42">동시성(Concurrency) vs 병렬성(Parallelism)</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로세스 동기화]]></title>
            <link>https://velog.io/@moon_dd/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EB%8F%99%EA%B8%B0%ED%99%94</link>
            <guid>https://velog.io/@moon_dd/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EB%8F%99%EA%B8%B0%ED%99%94</guid>
            <pubDate>Mon, 15 May 2023 07:56:51 GMT</pubDate>
            <description><![CDATA[<h1 id="프로세스-동기화">프로세스 동기화</h1>
<h3 id="왜-프로세스-동기화가-필요한가">왜 프로세스 동기화가 필요한가?</h3>
<ul>
<li>협력적 프로세스 : 논리적 주소를 공유하고 있어 다른 프로세스에게 영향을 주거나 받는 프로세스</li>
</ul>
<p>협럭적 프로세스는 <strong>Race Condition</strong>의 위험이 있다.</p>
<h3 id="race-condition">Race Condition</h3>
<p>: 여러개의 프로세스가 동일한 데이터에 접근하고, 이 프로세스들이 실행되는 순서에 따라 실행결과가 달라지는 상황</p>
<p>Race Condition이 발생되지 않게 하기위해서는 협력적 프로세스들의 <strong>질서있는 실행을 보장</strong>하여 <strong>데이터 무결성을 보장이 필요하다</strong></p>
<p>데이터 무결성을 위해서는 프로세스끼리 데이터에 대한 동기화가 필요하다.</p>
<h3 id="임계구역-문제">임계구역 문제</h3>
<ul>
<li><strong>임계구역(Critical Section)</strong> : 다른 프로세스와 공유하고 있는 데이터에 접근하여 조작할 수 있는 구역</li>
<li><strong>임계구역 문제</strong> : 임계구역으로 지정되어야 할 코드 영역이 임계구역으로 지정되지 않았을 때 발생할 수 있는 문제</li>
</ul>
<h3 id="임계구역-문제-해결의-조건">임계구역 문제 해결의 조건</h3>
<ol>
<li><strong>상호배제,상호배타 Mutual exclusion</strong><ul>
<li>프로세스 P가 자기의 임계구역에서 실행된다면, 다른 프로세스들은 그들 자신의 임계구역에서 실행될 수 없다</li>
</ul>
</li>
<li><strong>진행 Progress</strong><ul>
<li>임계구역에 프로세스가 존재하지 않는 경우, 다른 프로세스가 접근할 수 있어야한다.</li>
<li>임계구역에 들어간 프로세스가 없는 상태에서 들어가려는 프로세스가 여러 개 있다면 어떤 프로세스가 들어갈지를 결정하는 것으로, 이것은 유한 시간 이내에 이루어져야 합니다.</li>
</ul>
</li>
<li><strong>유한 대기 Bounded waiting</strong> = 한정된 대기<ul>
<li>다른 프로세스의 <strong>*기아</strong>를 방지하기 위해, 한 번 임계 구역에 들어간 프로세스는 그 다음에 임계 구역에 들어갈 때 제한을 두어야 합니다.<ul>
<li>기아 : <strong>프로세스가 임계 영역에 들어가기 위해 무한정으로 기다리는 현상</strong>으로 여러 프로세스가 부족한 자원을 점유하기 위해 경쟁할 때 발생합니다</li>
</ul>
</li>
<li>임계구역으로 진입하기 위해서 대기하는 모든 스레드는 유한 시간이내에 해당 임계구역으로 진입할 수 있어야 합니다.</li>
<li>진행과 다른 점<ul>
<li>진행은 말 그래도 임계구역 해결을 위해 코드 실행이 멈추지 않는 것을 의미</li>
<li>유한대기는 임계구역 코드 실행에 들어간 프로세스 외 나머지 프로세스들이 기아 현상이 나타나지 않도록 하기 위해 이미 임계구역을 실행한 프로세스를 제한하는 것</li>
</ul>
</li>
</ul>
</li>
</ol>
<h3 id="critical-section--remainder-section">Critical Section &amp; Remainder Section</h3>
<p>각 프로세스는 자신의 임계구역으로 진입하려면 <strong>진입 구역(entry section)</strong>에서 진입 허가를 요청해야 하고, 임계구역 뒤에는 <strong>퇴출 구역(exit section)</strong>이 따라올 수 있다. 코드의 나머지 부분들을 총칭하여 <strong>나머지 구역(reaminder section)</strong>이라고 한다.</p>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/622db616-e50a-4568-a59b-90f940c42086/image.png" alt=""></p>
<h3 id="peterson-해결안">Peterson 해결안</h3>
<p>Peterson 해결안은 Critical Section과 Remainder Section을 번갈아 가며 실행하는 두 개의 프로세스로 한정된다.</p>
<pre><code class="language-c">int turn; 
boolean flag[2];</code></pre>
<ul>
<li>turn → 임계구역에 접근할 프로세스의 번호</li>
<li>flag → 해당 인덱스의 프로세스가 준비가 되었는지</li>
</ul>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/4951ae2a-a0b6-4499-85b3-3facd967555c/image.png" alt=""></p>
<p>Critical Section으로 진입하기 위해서는 Pi는 먼저 flag[i]를 참으로 만들고, turn을 j로 지정한다. 이렇게 함으로써 Pi는 Pj가 Critical Section으로 진입하기를 원한다면 진입 가능하다는 것을 보장한다. 만일 두 프로세스가 동시에 진입하기를 원한다면 진입 turn은 거의 동시에 i와 j로 지정될 것이다. 이 때의 경우 turn의 궁극적인 값이 둘 중 누가 먼저 Critical Section으로 진입할 것인가를 결정한다.</p>
<p><strong>flag[j]가 false(Pj가 remainder section 수행)가 되거나 turn이 i(Pj는 준비완료됬고, Pi가 Entry Section에서 대기하고 있음)일 경우 Pi는 Critical Section에 들어갈 수 있다.</strong></p>
<p>Peterson의 해결안이 Ciritical Section 문제를 해결하기 위해선 위에서 명시한 것 처럼 3가지 요구조건을 만족해야 한다. 같이 살펴보자.</p>
<ol>
<li>상호 배재(Mutual Exclusion)<ul>
<li>flag[2]와 turn 변수에 의해서 하나의 프로세스만 Critical Section에서 연산을 수행할 수 있음으로 Mutual Exclusion는 지켜진다.</li>
</ul>
</li>
<li>진행(Progress)<ul>
<li>각 프로세스가 자신이 Critical Section을 수행할 동안 while문에서 다른 프로세스를 유한하게 대기하도록 만드는 방법을 통하여 Progress를 지킬 수 있다.</li>
</ul>
</li>
<li>한정된 대기(bounded waiting)<ul>
<li>각 프로세스들은 Critical Section에 진입하려는 요청을 한 후부터 다른 프로세스가 Critical Section을 수행하는 동안 유한하게 대기함으로 bounded waiting 또한 지켜진다.</li>
</ul>
</li>
</ol>
<h3 id="3가지-하드웨어-명령어">3가지 하드웨어 명령어</h3>
<p>Critical Section 문제의 소프트웨어 기반 해결책은 최신 컴퓨터 아키텍처에서 작동하지 않을 수 있다.</p>
<p>읽고 쓰는 작업이 서로 다른 인스트럭션으로 이루어져 있기 때문이다. 인스트럭션이 수행되는 도중에는 인터럽트가 올 수 있기 때문에, 만약 읽기와 쓰기가 하나의 인스트럭션에서 이루어져 <strong>원자적인</strong> 명령어를 통해 Critical Section문제를 해결할 수 있다.</p>
<ul>
<li><p><strong>메모리 장벽</strong> : 컴퓨터 아키텍처는 메모리의 모든 변경 사항을 다른 모든 프로세서로 전파하는 명령어를 제공하여 다른 프로세서에서 <strong>실행 중인 스레드에 메모리 변경 사항이 보이는 것을 보장</strong>한다. 이러한 명령어를 <strong>메모리 장벽(Memory Barriers) 또는 메모리 펜스(Memory Fences)</strong>라고 한다.</p>
<ul>
<li>메모리 장벽은 매우 낮은 수준의 연산으로 간주하며 일반적으로 Mutual Exclusion을 보장하는 특수 코드를 작성할 때 커널 개발자만 사용한다.</li>
</ul>
</li>
<li><p><strong>하드웨어 명령어 : 원자적인 연산</strong></p>
<ul>
<li>test_and_set() : 파라미터로 온 변수의 내용을 검사해서 변경</li>
<li>compare_and_set() : 파라미터로 온 두가지의 변수를 비교하여 변경<ul>
<li>test_and_set() 명령어와 마찬가지로 두 개의 워드에 대해 원자적인 연산을 하지만 두 워드의 내용 교환에 기반을 둔 기법이다.</li>
<li>명령어를 직접 용하진 않고 <strong>원자적 변수</strong>를 활용한다.<ul>
<li>원자적 변수는 정수 및 부울과 같은 기본 데이터 유형에 대한 원자적 연산을 제공하는데, <strong>CAS</strong>는 이런 원자적 연산을 구현할 때 내부적으로 활용된다.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/244a7464-b526-4d6e-ba54-feca8ecf03c0/image.png" alt="">
<img src="https://velog.velcdn.com/images/moon_dd/post/1013ad87-1f0c-44f8-ab5f-61441aea8157/image.png" alt="">
<img src="https://velog.velcdn.com/images/moon_dd/post/6aef8f5f-ee59-4203-b6c1-7212e7d773f8/image.png" alt=""></p>
<h3 id="mutex-locks">Mutex Locks</h3>
<p>mutex lock은 mutual exclusion lock의 축약 형태로서 Critical Section을 해결하기위한 하드웨어 기반의 해결책보다 상위 수준의 해결책이다.</p>
<p>Mutex Lock의 기본 개념은 프로세스는 Critical Section에 <strong>들어가기 전에</strong> 반드시 <strong>lock을 획득</strong>해야 하고 Critical Section을 <strong>빠져나올 때 lock을 반환</strong>해야 한다.</p>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/3bffb989-c771-4726-944a-023928cafd8c/image.png" alt=""></p>
<p><strong>Mutex Lock에 필요한 3가지</strong></p>
<ol>
<li><p>acquire() : Lock을 획득하는 함수</p>
<pre><code class="language-c"> acquire() {
     while(!available)
         ; /* busy wait */
     available = false;
 }</code></pre>
<p> 단점은 <strong>바쁜 대기(busy waiting)</strong>를 해야 한다는 것이다. 이러한 busy waiting은 대기하는 다른 프로세스가 계속해서 acquire함수를 호출해서  다른 프로세스가 생산적으로 사용할 수 있는 CPU 주기를 낭비한다.</p>
<p> 프로세스가 락을 기다려야 하고 문맥 교환에 상당한 시간이 소요될 때 문맥 교환이 필요하지 않다는 장점이 있다.</p>
<p> 최신 다중 코어 컴퓨팅 시스템에서 스핀락은 많은 운영체제에서 널리 사용된다. <strong>일반적으로 락이 유지되는 기간이 문맥 교환을 두 번(1.스레드를 대기상태로 2.대기중인 스레드를 복원) 하는 시간보다 짧은 경우 Mutext Lock을 사용한다.</strong></p>
</li>
<li><p>release() : Lock을 반환하는 함수</p>
<pre><code class="language-c"> release() {
     available = true;
 }</code></pre>
</li>
<li><p>available : Lock을 사용할 수 있는 지 여부를 표시하는 변수 </p>
</li>
</ol>
<h3 id="세마포">세마포</h3>
<p>세마포 S는 정수 변수로 사용되는데, 두개의 <strong>원자적</strong> 연산 <strong>wait() 와 signal()</strong>로 접근할 수 있다.</p>
<ul>
<li><p><strong>wait()</strong> : 자원을 사용하려는 프로세스가 wait 연산을 수행한다. <strong>세마포의 값은 감소한다.</strong></p>
<pre><code class="language-c">  wait(S) {
      while (S &lt;= 0)
          ; // busy wait
      S--;
  }</code></pre>
</li>
<li><p><strong>signal()</strong> : 프로세스가 자원을 방출할떄 signal() 연산을 수행하고 <strong>세마포의 값은 증가한다</strong>. 세마포의 값이 <strong>0이 되면 모든 자원이 사용중</strong>임을 나타낸다. 이후 자원을 사용하려는 프로세스는 세모포값이 0보다 커질 때까지 봉쇄된다.</p>
<pre><code class="language-c">  signal(S) {
      S++;
  }</code></pre>
</li>
</ul>
<h3 id="세마포-구현">세마포 구현</h3>
<p>busy waiting을 피하기 위해 세마포 S를 대기하면서 일시 중지된 프로세스는 다른 프로세스가 signal() 연산을 실행하면 재시작되어야 한다. 프로세스는 s<strong>leep() 연산에 의해서 일시 중지</strong>되고 <strong>wakeup() 연산에 의하여 재시작된다.</strong> </p>
<ol>
<li><p><strong>세마포 구조</strong></p>
<pre><code class="language-c"> typedef struct {
     int value;
     struct process *list;
 }semaphore;</code></pre>
</li>
<li><p>wait() </p>
<pre><code class="language-c"> wait(semaphore *S) {
     S-&gt;value--;
     if (S-&gt;value &lt; 0) {
         add this process to S -&gt; list;
         sleep();
     }
 }</code></pre>
</li>
<li><p>signal()</p>
<pre><code class="language-c"> signal(semaphore *S) {
     S-&gt;value ++;
     if (S-&gt;value &lt;= 0) {
         remove a process P from S -&gt; list;
         wakeup(P);
     }
 }</code></pre>
</li>
</ol>
<h2 id="퀴즈">퀴즈</h2>
<hr>
<ul>
<li>하드웨어 명령어에는 어떤 것이 있는가?<ul>
<li>메모리 장벽 / 펜스</li>
<li>test_and_set</li>
<li>compare_and_set</li>
</ul>
</li>
<li>임계구역 문제 해결을 위한 조건 3가지<ol>
<li>상호 배재(Mutual Exclusion)</li>
<li>진행(Progress)</li>
<li>한정된 대기(bounded waiting)</li>
</ol>
</li>
<li>세마포에 접근할 수 있는 연산 2가지는 무엇이 있는가?<ul>
<li>wait() 와 signal()</li>
</ul>
</li>
</ul>
<h2 id="참조">참조</h2>
<p><a href="https://imbf.github.io/computer-science(cs)/2020/11/04/Synchronization-Tools.html">[Operating System - Chapter 6] 동기화 도구들</a></p>
<p><a href="https://sihyung92.oopy.io/os/6#682cd9bb-84fc-42e2-a265-316e5b287eae">프로세스 동기화</a></p>
<p><a href="https://galid1.tistory.com/479">운영체제 - 프로세스 동기화란?</a></p>
<p><a href="https://velog.io/@hayeon/%EB%8F%99%EA%B8%B0%ED%99%94-%EC%9E%84%EA%B3%84%EA%B5%AC%EC%97%AD-%EB%8D%B0%EB%93%9C%EB%9D%BD-%EC%83%81%ED%98%B8%EB%B0%B0%EC%A0%9C">동기화, 임계구역, 데드락, 상호배제</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CPU 스케줄링]]></title>
            <link>https://velog.io/@moon_dd/CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</link>
            <guid>https://velog.io/@moon_dd/CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</guid>
            <pubDate>Wed, 03 May 2023 12:59:58 GMT</pubDate>
            <description><![CDATA[<h1 id="cpu-스케줄링프로세스-스케줄링">CPU 스케줄링(=프로세스 스케줄링)</h1>
<h2 id="os-발전과정">OS 발전과정</h2>
<h3 id="serial-processing">Serial Processing</h3>
<ul>
<li>display lights, toggle switches, input device and printer과 같은 콘솔들로 기계가 작동했다.</li>
<li>운영체제가 프로세스를 생성하고 수행하는 것이 아닌 인간이 실행하는 것이였다.</li>
</ul>
<h3 id="simple-batch-systems">Simple Batch Systems</h3>
<ul>
<li>Serial Processing이 발전한 형태</li>
<li>비슷한 작업끼리 묶인 형태</li>
<li>Monitor에 의해 컨트롤되었다.<ul>
<li>Monitor : 일련의 events을 컨트롤하는 소프트웨어</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/aaa5e7ad-fe65-46ef-865b-779379f3fe11/image.png" alt=""></p>
<h3 id="uni-processing">Uni-processing</h3>
<ul>
<li>Monitor가 Program을 실행시키는 방법</li>
<li>프로세서는 입출력 명령이 완료될때까지 기다리고 다시 실행하고를 반복</li>
<li>성능이 매우 안 좋았음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/1e84d4d5-4dfb-40db-acab-8042ff67521b/image.png" alt=""></p>
<h2 id="multiprogramming-vs-timesharing">Multiprogramming vs Timesharing</h2>
<h3 id="muliprogramming-systems">Muliprogramming Systems</h3>
<p>한 작업이 입출력을 기다리고 있으면 프로세서가 다른 작업으로 switch한다. 그러기 위해서는 메모리에 실행되는 프로그램이 메모리에 모두 적재되어야하고, 큰 메모리 공간이 필요로하다. </p>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/16307168-40fd-46a3-be7f-cd20795e89b2/image.png" alt=""></p>
<p>작업 A, B, C가 모두 메모리에 적재되므로 메모리의 크기가 커야한다.</p>
<h3 id="time-sharing-systems-시분할-시스템">Time Sharing Systems (시분할 시스템)</h3>
<p>: 멀티프로그래밍을 논리적으로 확장한 개념으로 프로세서가 다중의 프로그래밍을 동일한 시간만큼 번갈아가면 실행한다. </p>
<p>하나의 CPU는 같은 시점에서 여러 개의 작업을 동시에 수행할 수 없기 때문에, CPU의 전체 사용시간을 작은 작업 시간량으로 쪼개어 그 시간량 동안만 번갈아가면서 CPU를 할당하여 각 작업을 처리한다.  동일 시간만큼 각 프로그램이 실행되므로 평균 응답시간이 줄어드는 특징이 있다.</p>
<p>(시간간격은 time slice, tiem quatum이라고 불린다.)</p>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/20852992-7ab8-473d-86ee-cb913c646022/image.png" alt=""></p>
<h3 id="multiprogramming-vs-timesharing-1">Multiprogramming VS Timesharing</h3>
<p>현대 컴퓨터에서는 둘 다 사용되고 장단점이 있다.</p>
<p><strong>Multiprogramming</strong></p>
<ul>
<li>timesharing보다 overhead가 적다</li>
<li>처리율(시간동안 처리되는 작업의 수)이 좋고 낭비되는 시간이 적다.</li>
<li>하지만 응답시간(프로그램 실행 명령 ~ 실제로 실행되는 시간)은 Timesharing에 비해 크다.</li>
</ul>
<p><strong>Timesharing</strong></p>
<ul>
<li>Multiprograing보다 overhead가 크다</li>
<li>응답시간이 적다.</li>
<li>낭비되는 시간이 많아진다. (시간간격보다 처리시간이 짧아도 시간간격만큼 해당 프로그램이 CPU 제어권을 가지고 있기때문)</li>
</ul>
<h2 id="cpu-스케줄링">CPU 스케줄링</h2>
<p><strong>다중 프로그래밍의 목적은 CPU 스케줄러를 통해 항상 실행 중인 프로세스를 가지게 하여 CPU 이용률을 최대화하는 것이다.</strong> 운영체제는 CPU 제어권을 프로세스끼리 넘겨주면서, 컴퓨터를 보다 효율적으로 만든다. 어떤 프로세스가 I/O 입출력을 기다리고 있을 경우, 운영체제는 CPU 제어권을 회수하고 다른 프로세스에게 할당한다.</p>
<p>Process Scheduling = CPU Scheduling = Job Scheduling</p>
<h3 id="스케줄링-단위">스케줄링 단위</h3>
<p><strong>프로세스 실행은 CPU 실행과 I/O 대기의 사이클로 구성된다.</strong> CPU Burst로 프로세스의 실행 시작되고 뒤이어 I/O Burst가 발생하고 CPU Burst와 I/O Burst가 반복되다. 마지막 CPU Burst는 실행을 종료하기 위한 시스템 요청과 함께 프로세스가 마무리된다.-</p>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/ad59291a-82c7-42d4-8a92-f5c40f499ef5/image.png" alt=""></p>
<ul>
<li>CPU Burst : 사용자 프로그램이 CPU를 직접 가지고 빠른 명령을 수행하는 단계. 즉 스케줄링 단위</li>
<li>I/O Burst : 커널에 의해 입출력 작업을 진행하는 비교적 느린 단계. 프로세스는 Block되는 구간</li>
</ul>
<p>이 CPU Burst의 지속시간을 확인해보면 컴퓨터 시스템 내에서 수행되는 프로세스의 대부분 은 CPU Burst기간이 짧고 극히 일부만 긴 CPU Burst를 가진다. </p>
<p><strong>CPU를 한번에 오래 사용하기보다는 잠깐 사용하고 I/O 작업을 수행하는 프로세스가 많다.</strong></p>
<p>사용자에게 빠른 응답을 주기 위해서는 CPU Burst가 짧은 프로세스에게 우선적으로 CPU를 할당하는 게 바람직하다. 이때 이러한 문제를 해결하기 위해 CPU 스케줄링이 필요하다..</p>
<h3 id="cpu-스케줄러">CPU 스케줄러</h3>
<p>CPU 스케줄러는 CPU 자원 관리를 담당하며, 프로세스 실행 우선순위를 결정하여 CPU 자원을 할당하는 역할을 수행한다. </p>
<p><strong>CPU 스케줄러가 CPU가 유휴 상태가 될 때마다, Ready Queue에 있는 프로세스 중 하나 선택해서 CPU를 할당한다.</strong></p>
<p>Ready Queue는 FIFO 방식일 수도 , 우선순위 큐 등등 으로 구현될 수 있다. 일반적으로 큐에 있는 레코드들은 프로세스의 프로세스 제어 블록(PCB)들 이다.</p>
<h2 id="스케줄링-기법">스케줄링 기법</h2>
<h3 id="선점-및-비선점-스케줄링">선점 및 비선점 스케줄링</h3>
<p>cpu 스케줄링 결정은 4가지 상황에서 발생할 수 있다.</p>
<ol>
<li>한 프로세스가 실행 상태에서 대기 상태로 전환될 때 (I/O 발생)</li>
<li>프로세스가 실행 상태에서 준비 완료 상태로 전환될 때 (인터럽트 발생)</li>
<li>프로세스가 대기 상태에서 준비 완료 상태로 전환될 때 (I/O 종료)</li>
<li>프로세스가 종료될 때</li>
</ol>
<p><strong>비선점 스케줄링</strong></p>
<p>: 일단 CPU가 한 프로세스에 할당되면 프로세스가 종료하든지, 또는 대기 상태로 전환해 CPU를 방출할 때까지 점유한다. 위에서 1,4번의 경우에 해당된다.</p>
<p>ex) FCFS(first come first service), SJF(shortest job first), 우선 순위, HRN(heighest response next)</p>
<p><strong>선점 스케줄링</strong></p>
<p>: 시분할 시스템에서 타임 슬라이스가 소진되었거나, 인터럽트나 시스템 호출 종료시에 더 높은 우선 순위 프로세스가 발생되었음을 알았을 때, 현 실행 프로세스로부터 강제로 CPU를 회수한다. 위에서 2,3번 경우에 해당된다.</p>
<p>ex) round robin, SRT, 선점 우선 순위 등의 알고리즘</p>
<h3 id="스케줄링-기준">스케줄링 기준</h3>
<p>여러 cpu 스케줄링 알고리즘 중 하나를 선택하기 위한 CPU 스케줄링 비교 기준</p>
<ul>
<li>CPU 이용률 : 특정 기간동안의 CPU 이용시간</li>
<li>처리량 : 단위 시간당 완료된 프로세스의 개수</li>
<li>총 처리시간 : 프로세스 제출 시간과 완료 시간의 간격</li>
<li>대기시간 : 프로세스가 준비 큐에서 대기하면서 보낸 시간의 합</li>
<li>응답시간 : 하나의 요청을 보낸 후 첫번째 응답이 나올 때까지의 시간</li>
</ul>
<p>대부분 알고리즘은 Trade-off 임으로 상황에 맞춰서 선택해야한다.</p>
<h3 id="디스패처dispatcher">디스패처(Dispatcher)</h3>
<p>: CPU 코어의 제어를 CPU 스케줄러가 선택한 프로세스에게 주는 모듈</p>
<p><strong>디스패처의 역할</strong></p>
<p>스케줄링 대상인 <strong>프로세스의 상태 전환을 수행</strong>하기도 하며, <strong>이전 실행 프로세스의 컨텍스트(context)를 저장</strong>하고 <strong>새로운 프로세스의 컨텍스트를 로드하는 등의 작업을 수행</strong>합니다.</p>
<ol>
<li>한 프로세스에서 다른 프로세스로 문맥 교환하는 일</li>
<li>사용자 모드로 전환하는 일</li>
<li>프로그램을 다시 시작하기 위해 사용자 프로그램의 적절한 위치로 이동하는 일 </li>
</ol>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/98de31da-74bd-4fb9-a926-6b99d0969416/image.png" alt=""></p>
<p><strong>디스패치 지연(Dispatch latency)</strong></p>
<p>: 디스패처가 하나의 프로세스를 정지하고 다른 프로세스를 수행하는 데 걸리는 시간</p>
<p><strong>문맥교환(Context Switch)</strong></p>
<ul>
<li>자발적 문맥 교환 : 현재 사용 불가능한 자원을 요청했을 때 프로세스가 CPU 제어를 포기한 경우 발생</li>
<li>복귀 문맥 교환 : 인터렙트나 예외 상황이 발생하여 프로세스가 CPU를 반환한 후, 이전에 실행되던 프로세스로 돌아가기 위한 문맥 교환이며, 대개 운영체제의 커널 모드에서 실행된다.</li>
<li>비자발적 문맥 교환 : 타임 슬라이스가 만료되었거나 우선순위가 높은 프로세스에 의해 선점되는 경우와 같이 CPU를 빼앗겼을 때 발생한다.</li>
</ul>
<h2 id="스레드-스케줄링">스레드 스케줄링</h2>
<p>현대 운영체제에서는 프로세스가 아닌 <strong>커널 수준 스레드가 스케줄링</strong>된다.</p>
<p>사용자 수준 스레드는 스레드 라이브러리에서 관리되고 커널은 사용자 수준의 스레드를 알 지 못한다.</p>
<p>그래서 사용자 수준 스래드도 CPU상에서 실행되기 위해서는 LWP(Light Weight Process)를 통한 간접적인 방식일지라도 커널 수준 스레드에 매핑되어야한다. </p>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/0450e2b7-1f40-49c8-a0f5-345be8336897/image.png" alt=""></p>
<h3 id="경쟁범위">경쟁범위</h3>
<ul>
<li><p>프로세스 경쟁 범위(Process Contention Scope, PCS)</p>
<ul>
<li><strong>다대일과 다대다 모델</strong>에서 <strong>사용자 수준 스래드</strong>를 가용한 LWP에 스케줄링한다. 이때 <strong>동일한 프로세스 내 스래드 간</strong> CPU를 경쟁하기 때문에 프로세스 경쟁범위라 한다.</li>
</ul>
</li>
<li><p>시스템 경쟁 범위(System Contention Scope, SCS)</p>
<ul>
<li><p><strong>일대일 모델</strong>에서 <strong>커널 수준 스래드</strong>를 CPU에 스케줄링한다. 이때 <strong>시스템상의 모든 스레드에서 CPU를 경쟁</strong>하기 떄문에 시스템 경쟁 범위라 한다.</p>
<blockquote>
<p>우리가 스레드 라이브러리가 사용자 수준 스레드를 가용한 LWP 상에서 스케줄 한다고 말하는 경우, 실제로 스레드가 CPU 상에서 실행중이라는 것을 의미하지 않는다. <strong>실제로 CPU상에서 실행되기 위해서는 운영체제가 LWP의 커널 스레드를 물리적인 CPU 코어로 스케줄링 하는 것을 필요로 한다.</strong> 이때, CPU상에 어느 커널 스레드를 스케줄 할 것인지 결정하기 위해서 커널은 시스템 경쟁 범위를 사용하여 커널 스레드를 스케줄링 한다.</p>
</blockquote>
</li>
</ul>
</li>
</ul>
<p><a href="https://wonsik.tistory.com/7">사용자 수준 스래드와 커널 수준 스래드의 연관관계</a></p>
<ul>
<li>ChatGPT에 질문한 것들 ( 정확한 정보가 아닐수도 있습니다,,,)<ul>
<li>스레드는 CPU이용의 기본단위야?<ul>
<li>네, 스레드는 CPU 이용의 기본 단위 중 하나입니다. CPU는 한 번에 하나의 작업만 처리할 수 있으므로, 멀티스레딩을 통해 여러 작업을 동시에 처리할 수 있습니다. 스레드는 하나의 프로세스 내에서 실행되는 실행 흐름으로, 각각의 스레드는 CPU 시간을 할당받아 작업을 수행합니다. 따라서, 스레드는 CPU 이용의 기본 단위 중 하나로 볼 수 있습니다.</li>
</ul>
</li>
<li>LWP가 뭐야?<ul>
<li>LWP는 Light-weight Process의 약어로, 가벼운 프로세스를 의미합니다. 이 용어는 주로 유닉스 및 유닉스 계열 운영 체제에서 사용되며, 스레드를 구현하는 방식 중 하나입니다. LWP는 스레드를 모방하여 구현되었으며, 사용자 수준에서 스케줄링되기 때문에 프로세스보다 빠르게 생성 및 종료될 수 있습니다. LWP는 쓰레드와 유사한 기능을 제공하며, 여러 개의 LWP가 하나의 프로세스 내에서 동작할 수 있습니다. 이렇게 하나의 프로세스 내에서 여러 개의 LWP가 동작하면, 각각의 LWP는 별도의 스레드처럼 동작하면서도 다른 LWP와 공유하는 자원(예: 메모리, 파일 등)에 접근할 수 있습니다.</li>
</ul>
</li>
<li>다대일과 다대다 모델에서 사용자 수준 스래드를 가용한 LWP에 스케줄링한다. 여기서 가용한 LWP가 무슨 뜻이야?<ul>
<li>여기서 가용한 LWP는 사용 가능한(lightweight process) LWP를 의미합니다. 다대일 모델에서는 하나의 프로세스에 여러 개의 사용자 수준 스레드가 존재하며, 이러한 스레드들은 하나의 LWP에 할당되어 실행됩니다. 반면에 다대다 모델에서는 여러 개의 프로세스가 있으며, 각 프로세스 내부에는 여러 개의 LWP가 존재할 수 있습니다. 여기서 사용 가능한 LWP란, 현재 시스템에 생성 가능한 LWP 중에서 이미 다른 스레드에 할당되어 실행 중이지 않은 LWP를 의미합니다. 이러한 LWP는 새로운 사용자 수준 스레드에게 할당될 수 있어, 프로세스의 병렬성과 처리 성능을 높일 수 있습니다.</li>
</ul>
</li>
<li>프로세스 경쟁범위에서 다대일과 다대다 모델이 뭐야?<ul>
<li>프로세스 경쟁 범위는 여러 개의 프로세스나 스레드가 동시에 실행되는 환경에서, 이들이 경쟁하는 범위를 의미합니다.</li>
<li>다대일 모델은 하나의 프로세스에 여러 개의 스레드가 존재하며, 이러한 스레드들이 하나의 중앙처리장치(CPU)를 공유하며 동작합니다. 이 모델에서는 프로세스의 주소공간과 자원을 스레드들이 공유하기 때문에, 프로세스 내부에서 스레드 간의 데이터 공유가 용이하고, 스레드 간의 커뮤니케이션도 비교적 쉽게 구현할 수 있습니다. 하지만, 스레드의 수가 증가하면 스레드 간의 경쟁이 치열해져 병목현상이 발생할 가능성이 높아집니다.</li>
<li>다대다 모델은 여러 개의 프로세스가 존재하며, 이들이 서로 다른 중앙처리장치(CPU)를 공유하면서 동시에 실행됩니다. 각 프로세스는 독립된 주소공간과 자원을 가지고 있어, 프로세스 간의 데이터 공유가 어렵고, 커뮤니케이션도 복잡하게 구현해야 합니다. 하지만, 다수의 CPU를 이용해 병렬 처리를 할 수 있기 때문에, 대규모 서버 시스템 등에서 많이 사용됩니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="다중-처리기-스케줄링multiple-processor-scheduling">다중 처리기 스케줄링(Multiple Processor Scheduling)</h2>
<p>여러개의 CPU가 사용 가능하면, 여러 스레드가 병렬로 실행될 수 있어 <strong>부하 공유(Load Sharing)</strong>가 가능해진다. 하지만 이에 따라 스케줄링 문제는 그에 상응해 더욱 복잡해진다.</p>
<ul>
<li><p><strong>비대칭 다중처리(asymmetric multiprocessing)</strong></p>
<ul>
<li><p><strong><strong><strong><strong><strong>**</strong></strong></strong></strong></strong>마스터 서버<strong><strong><strong><strong><strong>**</strong></strong></strong></strong></strong></p>
<p>  <strong><strong><strong><strong><strong>**</strong></strong></strong></strong></strong>:<strong><strong><strong><strong><strong>**</strong></strong></strong></strong></strong> 다중 처리기 시스템의 CPU 스케줄링에 관한 한 가지 해결방법은 <strong>마스터 서버</strong>라는 하나의 프로세서가 모든 스케줄링 결정과 I/O 처리 그리고 다른 시스템의 활동을 취급하게 하는 것이다.</p>
<p>  <strong>하나의 코어만 시스템 자료구조에 접근하여 자료 공유의 필요성을 배제하기 때문에 간단하다</strong></p>
<p>  하지만 마스터 서버가 전체 시스템 성능을 저하할 수 있는 병목이 된다.</p>
</li>
</ul>
</li>
<li><p><strong>대칭 다중 처리(symmetric multiprocessing, SMP)</strong></p>
<p>  <strong>다중 처리기를 지원하기 위한 표준 접근 방식이다.</strong> 거의 모든 최신 운영체제는 SMP를 사용한다.</p>
<p>  각 프로세서는 스스로 스케줄링 할 수 있다. 각 프로세서의 스케줄러가 준비 큐를 검사하고 실행할 스레드를 선택하여 스케줄이 진행된다.</p>
<p>  스케줄 대상이 되는 스레드를 관리하기 위해 2가지의 방식이 있다.</p>
<ul>
<li>공통 준비큐에 모든 스레드가 있다. (race condition이 발생할 수 있다.)</li>
<li>각 프로세스는 자신만의 스레드 큐를 가질 수 있다. (일반적인 방식)</li>
</ul>
</li>
<li><p>좀 깊게 알아보고 싶은 주제들</p>
<h3 id="다중-코어-프로세스">다중 코어 프로세스</h3>
<h3 id="부하-균등화">부하 균등화</h3>
<h3 id="처리기-선호도">처리기 선호도</h3>
<h3 id="이기종-다중처리">이기종 다중처리</h3>
</li>
</ul>
<h2 id="퀴즈">퀴즈</h2>
<hr>
<ul>
<li><p>Multiprogramming / Timesharing은 각각 어떤 프로그램에 적합할까?</p>
<p>  <strong>Multiprogramming :</strong> batch processing, background processing과 같이 사용자에게 보여지지 않은 프로그램에 적합하다.</p>
<ul>
<li><p>timesharing보다 overhead가 적다</p>
</li>
<li><p>처리율(시간동안 처리되는 작업의 수)이 좋고 낭비되는 시간이 적다.</p>
</li>
<li><p>하지만 응답시간(프로그램 실행 명령 ~ 실제로 실행되는 시간)은 Timesharing에 비해 크다.</p>
</li>
<li><p><em>Timesharing :*</em> interactive processing, foreground processing과 같이 사용자에게 보여지는 프로그램에 적합하다</p>
</li>
<li><p>Multiprograing보다 overhead가 크다</p>
</li>
<li><p>응답시간이 적다.</p>
</li>
<li><p>낭비되는 시간이 많아진다. (시간간격보다 처리시간이 짧아도 시간간격만큼 해당 프로그램이 CPU 제어권을 가지고 있기때문)</p>
</li>
</ul>
</li>
<li><p>CPU 스케줄러는 어디에 위치할까?</p>
<p>  CPU 스케줄러는 운영체제의 커널 내부에 위치합니다.커널은 운영체제의 핵심 부분으로, 시스템 자원 관리, 입출력 처리, 파일 시스템 등 다양한 기능을 담당합니다. CPU 스케줄러는 이 중에서도 CPU 자원 관리를 담당하며, 프로세스 실행 우선순위에 따라 CPU 자원을 할당하는 역할을 수행합니다.</p>
</li>
<li><p>문맥교환의 종류는 무엇이 있을까?</p>
<ul>
<li>자발적 문맥 교환 : 현재 사용 불가능한 자원을 요청했을 때 프로세스가 CPU 제어를 포기한 경우 발생</li>
<li>복귀 문맥 교환 : 인터렙트나 예외 상황이 발생하여 프로세스가 CPU를 반환한 후, 이전에 실행되던 프로세스로 돌아가기 위한 문맥 교환이며, 대개 운영체제의 커널 모드에서 실행된다.</li>
<li>비자발적 문맥 교환 : 타임 슬라이스가 만료되었거나 우선순위가 높은 프로세스에 의해 선점되는 경우와 같이 CPU를 빼앗겼을 때 발</li>
</ul>
</li>
</ul>
<h2 id="참조">참조</h2>
<p><a href="https://imbf.github.io/computer-science(cs)/2020/10/18/CPU-Scheduling.html">[Operating System - Chapter 5] CPU 스케줄링</a></p>
<p><a href="https://steady-coding.tistory.com/530">[반효경 운영체제] CPU Scheduling 1</a></p>
<p><a href="https://akdl911215.tistory.com/219">시분할 방식 및 시스템에 대하여</a></p>
<p><a href="https://helloinyong.tistory.com/293">[2020.09.16] (운영체제) 사용자 수준 스레드와 커널 수준 스레드의 차이</a></p>
<p><a href="https://velog.io/@koseyeon/%EA%B3%B5%EB%A3%A1%EC%B1%85-Chapter5-CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81">공룡책 Chapter5 CPU 스케줄링</a></p>
<p><a href="https://coding-gongbu.tistory.com/20">[운영체제] CPU 스케줄링: 스레드 스케줄링</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로세스와 스레드]]></title>
            <link>https://velog.io/@moon_dd/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C</link>
            <guid>https://velog.io/@moon_dd/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C</guid>
            <pubDate>Wed, 26 Apr 2023 05:48:01 GMT</pubDate>
            <description><![CDATA[<h2 id="프로세스">프로세스</h2>
<ul>
<li><strong>실행</strong>중인 프로그램</li>
<li>가상주소 공간을 가지고 있고 운영체제가 실행하고 스케줄링한다. 이 특징으로 인해 운영체제가 각각의 프로세스를 독립적으로 다룰 수 있다.</li>
<li>즉 운영체제로부터 자원을 할당받은 작업단위</li>
</ul>
<h3 id="쓰레드">쓰레드</h3>
<ul>
<li>프로세스에서 실행되는 명령어들의 유닛</li>
<li>프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위</li>
</ul>
<h2 id="프로세스의-구성">프로세스의 구성</h2>
<h3 id="pcb">PCB</h3>
<p>프로세스의 정보는 PCB(Process Control Block)에 저장됩니다.</p>
<ul>
<li>PCB는 프로세스의 여러가지 정보를 가지고 있는데, 프로세스 ID, 현재 상태, 큐에서의 우선순위, 프로세스가 메모리 어디에 저장되어 있는지, context 데이터들의 위치 등등을 포함하고 있습니다.</li>
<li>OS에 의해 생성되고 관리된다. Primary Process Table에 PCB의 리스트들이 존재한다.</li>
<li>프로세스당 한개씩 가지고 있다.
<img src="https://velog.velcdn.com/images/moon_dd/post/f9894765-0ac4-447f-97b3-a0b7523d48f4/image.png" alt=""></li>
</ul>
<h3 id="프로세스의-메모리-공간">프로세스의 메모리 공간</h3>
<p>PCB에서 프로세스가 메모리 공간 중에 어디에 위치하는 정보가 담겨있다고 했는데, 이 메모리는 어떻게 구성되어 있는지 살펴봅시다.</p>
<p>이 공간은</p>
<ul>
<li>Code</li>
<li>Data</li>
<li>Heap<ul>
<li>런타임시 발생되는 데이터 저장</li>
</ul>
</li>
<li>Stack<ul>
<li>호출한 함수의 수행을 마치고 복귀할 주소, 데이터(매개변수, 지역변수, 리턴값) 저장</li>
</ul>
</li>
<li>Memory for registers context<ul>
<li>실행되고 있는 명령어 주소와 스택의 최상단 위치를 저장하고 있다</li>
</ul>
</li>
</ul>
<p>로 이루어져 있고 이중 Stack와 registers 한쌍이 한개의 쓰레드가 가지게 된다.</p>
<h3 id="멀티스레드">멀티스레드</h3>
<ul>
<li>동시에 동작하고 있는 쓰레드로 구성되어진 프로세스를 의미</li>
<li>쓰레드는 속한 프로세스의 메모리와 자원들에 접근할 수 있다. 즉 같은 프로세스에 속한 쓰레드는 자원들을 공유하고 있다.</li>
<li>쓰레드는 지역변수를 저장하기 위한 stack, register 를 쓰레드별로 가지고 있기도 한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/moon_dd/post/57f8af75-6b45-4d8e-af88-dfea1784d2b0/image.png" alt="">
<img src="https://velog.velcdn.com/images/moon_dd/post/d2d75f74-a372-4e05-ae03-8f97cb263f8c/image.png" alt=""></p>
<h2 id="문맥전환">문맥전환</h2>
<p><strong>Context</strong> : 프로그램의 실행되던 환경</p>
<p><strong>Context Swith</strong> : 프로세스에서 다른 프로세스로 CPU의 제어권을 넘긴는 과정</p>
<ol>
<li>프로그램 카운터와 다른 레지스터들을 포함한 프로세서의 context를 저장한다.</li>
<li>현재 실행중인 프로세스의 pcb를 업데이트한다.</li>
<li>적절한 큐로 pcb를 옮긴다.</li>
<li>실행한 프로세스를 고른다</li>
<li>고른 프로세스의 pcb를 업데이트한다</li>
<li>고른 프로세스의 context를 저장한다.</li>
</ol>
<h3 id="쓰레드의-장점">쓰레드의 장점</h3>
<ul>
<li>프로세스보다 새로운 쓰레드를 만드는데 더 적은 시간이 걸린다.</li>
<li>프로세스보다 쓰레드를 terminate하는데 더 적은 시간이 걸린다.</li>
<li>같은 프로세스 내의 두개의 쓰래드 사이에서 전환속도가 바르다</li>
<li>프로세스까리 통신하는 것보다 쓰레드 사이에서 통신하는 것이 더 빠르다</li>
<li>쓰레드는 메모리와 파일들을 공유할 수 있기때문에 그들끼리 통신할때 커널을 통하지 않아도 된다.</li>
</ul>
<h2 id="퀴즈">퀴즈</h2>
<ul>
<li><p>프로세스는 실행중인 프로그램이라고 하였는데, 프로세스와 프로그램은 어떤 차이가 있는지?</p>
<p>  프로그램은 하드디스크에 저장된 코드와 정적 데이터들의 모음이고, 코드와 데이터들이 메모리에 적재되어 실행되면 프로세스라고 부른다.</p>
</li>
<li><p>프로세서는 무엇이며, CPU는 무엇일까?</p>
</li>
</ul>
<pre><code>컴퓨터 운영에 필요한 기본적인 명령어를 처리하고 반응하기 위한 논리회로를 프로세서라고 한다.

프로세스도 현재상태와 명령어의 모음이기때문에 이를 실행시키는 것도 프로세서가 하게 된다.

프로세서는 소프트웨어의 명령을 하드웨어에게 신호를 보내는 제어장치와 사칙연산,논리연산을 담당하는 연산장치로 구성된다.

이때 디바이스가 해야할 일을 총 지휘하는 프로세서를 CPU라고 하고 이를 보조하는 프로세서를 보조프로세서라고 한다. </code></pre><ul>
<li><p>운영체제가 프로세스를 만든다고 하였는데, 여기서 운영체제는 무엇을 의미하는가?</p>
<p>  여기서 운영체제는 커널을 의마하게 된다. 커널은 운영체제의 좁은 의미이다. 커널은 메모리에 항상 상주하고 있고 커널이 프로세스를 만들기때문에 프로세스 생성에서 운영체제는 정확히는  커널을 의미한다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TCP 3-way, 4-way handshack]]></title>
            <link>https://velog.io/@moon_dd/TCP-3-way-4-way-handshack</link>
            <guid>https://velog.io/@moon_dd/TCP-3-way-4-way-handshack</guid>
            <pubDate>Wed, 26 Apr 2023 05:47:24 GMT</pubDate>
            <description><![CDATA[<h1 id="tcp-3-way-4-way-handshack">TCP 3-way, 4-way handshack</h1>
<h3 id="tcp란">TCP란?</h3>
<p>통신계층에서 수신자와 송신자를 연결하는 통신 서비스를 제공하고 IP를 통해 전달되는 패킷을 검사해 오류가 있는지 검사하고 재전송 요청하는 역할을 하는 프로토콜이다.</p>
<p>TCP는 신뢰성있고 연결지향적인 서비스를 제공하고 있다. 반대되는 개념으로는 UDP가 있다.</p>
<p>TCP는 패킷을 보내고 해당 패킷을 잘 받았는 지에 대한 확인 패킷도 받는 과정을 거치면서 데이터가 손실되는 것을 막지만 그만큼 속도가 느리다.</p>
<p>그에 비해 UDP는 패킷을 보낸 후 확인 작업을 거치지 않기에 속도가 빠른 대신, 데이터가 손실되는 것을 확인하지 않는다. </p>
<h3 id="3-way-4-way-handshack란">3-way, 4-way handshack란?</h3>
<p>TCP가 신뢰성있고 연결지향적인 서비스이므로 Client와 Server와 논리적으로 연결되어 있어야하는데 이때 3-way handshack를 이용해서 논리적 연결을 성립한다.</p>
<p>연결이 되면 연결을 끊을수도 있어야하는데 이때 사용되는 것이 4-way handshack이다.</p>
<h3 id="flag의-종류">flag의 종류</h3>
<p>TCP 헤더에는 6bit로 해당 패킷이 어떤 패킷이 알려주는 제어 비트가 있다. 각 자리마다 의미하는 바는 <strong>&quot;URG-ACK-PSH-RST-SYN-FIN”</strong> 이다.</p>
<p>즉 010000이면 해당 패킷은 ACK 역할을 하는 패킷임을 알 수 있다.</p>
<ul>
<li>ACK는 <strong>Acknowledgement</strong>로 패킷을 받았다는 의미의 flag이다.</li>
<li>SYN는 <strong>Synchronize Sequence Number</strong>로 Connection을 생성할때 사용되는 flag이다. 랜덤으로 숫자가 생성되어 전송된다.</li>
<li>FIN은 <strong>Finish</strong>로 더 이상 데이터를 보낼 것이 없으니 연결을 해지하겠다는 의미의 flag이다.</li>
</ul>
<h3 id="tcp-state의-종류">TCP state의 종류</h3>
<p>netstate 명령어를 통해 알 수 있다.</p>
<ul>
<li>CLOSED : 연결이 해제된 상태</li>
<li>LISTEN : 접속 요청을 기다리는 상태</li>
<li>SYN-SENT : Client가 SYN 패킷을 전송하고 아직 Server로부터 ACK 패킷을 전송받기 전 상태</li>
<li>SYN-RECEIVED : Client에게 SYN 패킷을 전송받아 응답으로 ACK + SYN 패킷을 전송한 상태</li>
<li>ESTABLISHED : Client와 Server가 연결된 상태</li>
<li>FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, LAST-ACK: 연결을 종료하기위해 FIN flag를 보내고 응답을 받는 과정의 상태</li>
<li>TIME-WAIT: 종료되었지만 분실된 패킷을 기다리기위해 소켓은 열어둔 상태</li>
<li>CLOSING : 흔하지 않지만, 확인 메세지가 분실된 상태</li>
<li>CLOSED : 연결이 종료된 상태</li>
</ul>
<h3 id="3-way-handshack의-과정">3-way handshack의 과정</h3>
<ol>
<li>Client → SYN → Server<ul>
<li>Client가 SYN 패킷을 LISTEN 상태인 Server에게 보낸다.</li>
<li>Client는 SYN 패킷을 보낸 후 SYN-SENT 상태로 변경된다.</li>
</ul>
</li>
<li>Server → ACK + SYN → Client<ul>
<li>Server가 SYN 패킷을 받은 후 응답으로 Client에게 ACK + SYN 패킷을 전송한다.</li>
<li>Server는 ACK + SYN 패킷을 보낸 후 SYN-RECEIVED 상태로 변경된다.</li>
</ul>
</li>
<li>Client → ACK → Client<ul>
<li>Client가 ACK + SYN 패킷을 확인 후 Server에게 ACK 확인 패킷을 보낸다.</li>
<li>Client는 패킷을 보낸 후 Client와 Server가 ESTABLISHED 상태로 변경되면서 연결된 상태가 되다.</li>
</ul>
</li>
</ol>
<h3 id="4-way-handshack의-과정">4-way handshack의 과정</h3>
<ol>
<li>Client → FIN → Server<ul>
<li>Client가 더 이상 보낼 데이터가 없을 경우 FIN 패킷을 Server에게 보낸다.</li>
<li>Client가 패킷을 보낸후 Client는 FIN-WAIT-1 상태로 변경된다.</li>
</ul>
</li>
<li>Server → ACK → Client<ul>
<li>Server가 FIN 패킷을 받으면 확인했다는 의미로 ACK 패킷을 보낸다.</li>
<li>Server은 연결을 종료할 준비하며, CLOSE-WAIT 상태로 변경된다.</li>
<li>Client는 ACK 패킷을 받으면 FIN-WAIT-2 상태로 변경된다.</li>
</ul>
</li>
<li>Server → FIN → Client<ul>
<li>Server가 연결을 종료할 준비가 되면 Client에게 FIN 패킷을 보낸다.</li>
<li>Server는 LAST-ACK 상태로 변경된다.</li>
</ul>
</li>
<li>Client → ACK → Server<ul>
<li>Client가 FIN 패킷을 받으면 Server에게 확인의 의미로 ACK 패킷을 Server에게 전송한다.</li>
<li>이후 Client는 늦게 오는 패킷을 기다리기위해 TIME-WAIT 상태로 변경된다.</li>
<li>일정 시간(디폴트 240초)이 지난후 Client는 CLOSE 상태로 변경된다.</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[개발하면서 정리한 Express 웹 프레임워크]]></title>
            <link>https://velog.io/@moon_dd/%EA%B0%9C%EB%B0%9C%ED%95%98%EB%A9%B4%EC%84%9C-%EC%A0%95%EB%A6%AC%ED%95%9C-Express-%EC%9B%B9-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC</link>
            <guid>https://velog.io/@moon_dd/%EA%B0%9C%EB%B0%9C%ED%95%98%EB%A9%B4%EC%84%9C-%EC%A0%95%EB%A6%AC%ED%95%9C-Express-%EC%9B%B9-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC</guid>
            <pubDate>Thu, 23 Feb 2023 07:35:56 GMT</pubDate>
            <description><![CDATA[<h2 id="express-를-왜-사용하는-지">Express 를 왜 사용하는 지</h2>
<p>node js에서 http 요청을 처리하기 위해서는 귀찮은 설정들을 간단하게 처리해준다.</p>
<p>http 요청에 대해 라우팅과 미들웨어 기능을 제공하는 프레임워크이다.</p>
<p>NodeJS 런타임 환경에서 작동하는 웹 프레임워크</p>
<h2 id="express-generator는-왜-사용하지">Express-generator는 왜 사용하지?</h2>
<p>http 통신을 위해 이외에 필요한 구조를 자동으로 잡아주기때문!</p>
<h2 id="express-generator를-사용해서-만든-구조">Express-generator를 사용해서 만든 구조</h2>
<ul>
<li>bin/www ⇒ port 설정, 서버 실행, http 모듈에 express 모듈을 연결한다.</li>
<li>public ⇒ 외부(클라이언트)가 접근가능한 파일들</li>
<li>routes ⇒ 라우터들 관리 / index.js → 루트 / 서버 로직들을 작성 / MVC 중 Controller 역할</li>
<li>views ⇒ view 파일들을 관리</li>
<li>app.js ⇒ 핵심적인 서버 역할, 미들웨어를 관리</li>
<li>model ⇒ generator에서 만들어주진 않지만, db를 사용할 경우 db 관련된 파일들을 모아둔다.</li>
</ul>
<h2 id="nodemon">nodemon</h2>
<p>node에서 매번 서버 실행시키기 귀찮으닌껜 저장할때마다 리부팅해주는 도구</p>
<h2 id="import-vs-require">import vs require</h2>
<ul>
<li><strong>import</strong><ul>
<li>ES6</li>
<li>특정 모듈만 불러올 수 있다.</li>
</ul>
</li>
<li><strong>require</strong><ul>
<li>commonJS</li>
<li>전체 모듈을 불러옴 ⇒ 쓸데없는 모듈도 가져올 수 있다.</li>
</ul>
</li>
</ul>
<p>++ 모듈 : 독립된 기능을 하는 함수나 파일</p>
<h2 id="참조">참조</h2>
<hr>
<p><a href="https://velog.io/@new_wisdom/Node.js-6-Express-Express-generator%EB%A1%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0">[Node.js] #6 Express / Express-generator로 프로젝트 만들기</a></p>
<p><a href="https://velog.io/@dami/node-express-%EC%84%9C%EB%B2%84%EC%99%80-nodemon-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0">[Node.js] Express 서버와 Nodemon 설치하기</a></p>
<p><a href="https://code-designer.tistory.com/103">CommonJS 와 ES(6) 모듈 키워드 ( require vs import ) 차이</a></p>
<p><a href="https://velog.io/@juneverbena/Node.js-%ED%85%9C%ED%94%8C%EB%A6%BF%EC%97%94%EC%A7%84">[Node.js] 템플릿엔진</a></p>
<p><a href="https://hanamon.kr/javascript-%EB%9F%B0%ED%83%80%EC%9E%84-%EC%9E%91%EB%8F%99-%EB%B0%A9%EC%8B%9D-%EB%B9%84%EB%8F%99%EA%B8%B0%EC%99%80-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%A3%A8%ED%94%84/">[JavaScript] 런타임 작동 방식, 비동기와 이벤트 루프 - 하나몬</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[jpa save()에서 찾은 entity 생명주기와 entity manager의 기능]]></title>
            <link>https://velog.io/@moon_dd/jpa-save%EC%97%90%EC%84%9C-%EC%B0%BE%EC%9D%80-entity-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0%EC%99%80-entity-manager%EC%9D%98-%EA%B8%B0%EB%8A%A5</link>
            <guid>https://velog.io/@moon_dd/jpa-save%EC%97%90%EC%84%9C-%EC%B0%BE%EC%9D%80-entity-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0%EC%99%80-entity-manager%EC%9D%98-%EA%B8%B0%EB%8A%A5</guid>
            <pubDate>Wed, 15 Feb 2023 05:00:16 GMT</pubDate>
            <description><![CDATA[<p>jpa에서 객체를 save()할때</p>
<ul>
<li>해당 entity의 @id가 null이면 해당 entity의 생명주기는 <strong>Transient</strong>이다. → EntityManager가 persist()를 호출</li>
<li>해당 entity의 @id가 null이 아니면 해당 entity의 생명주기는 <strong>Detached</strong>이다. → EntityManger가 merge()를 호출</li>
<li><strong>Persistent</strong>는 persistent 컨텍스트가 관리하고 있는 상태이다.</li>
</ul>
<p>Class A</p>
<ul>
<li>id</li>
<li>name</li>
</ul>
<p>위와 같은 엔티티가 있다고 가정하면 (그냥 흐름 파악을 위해 문법에 안 맞는 코드로 작성하겠다.)</p>
<pre><code>
a = new A()
a.name = “name” 
B = save(a)</code></pre><p>위와 같이 A entity에 name만 정의하고 save를 하면 a 와 반환값 B는 EntityManger가 persist()를 호출하여 entitymange가 관리하고 있다. 그리고 두 객체는 동일한 값을 가르키고 있다. 그래서 save후에 a, b를 변경하면 그대로 db에 업데이트가 된다.</p>
<p>하지만</p>
<pre><code>
a = new A()
a.id = 1
a.name = “name” 
B = save(a)</code></pre><p>위와 같이 A entity에 a에 id, name을 정의하고 save를 하면 entitymanger는 merge()를 호출하여 B는 detached상태이고 a는 entitymanager가 관리하지 않는다. 그래서 나중에 a를 변경해도 쿼리에 영향이 안간다!</p>
<p>횡설수설하고 있고 잘못된 정보를 가지고 있을수도 있다!</p>
<p>아래 참조에 아주 잘 설명되어 있으니 나중에 다시 확인하고 리마인드하는 것이 좋을 것 같다.</p>
<h3 id="참조">참조</h3>
<hr>
<p><a href="https://minkukjo.github.io/framework/2020/07/05/Spring-130/">Spring Data JPA - save()</a></p>
<p><a href="https://velog.io/@albaneo0724/Spring-JPA-save%EC%9D%98-%EC%88%A8%EA%B2%A8%EC%A7%84-%EA%B8%B0%EB%8A%A5">[Spring] JPA save의 숨겨진 기능?? 😮</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[rabbitmq ack auto vs client aut]]></title>
            <link>https://velog.io/@moon_dd/rabbitmq-ack-auto-vs-client-aut</link>
            <guid>https://velog.io/@moon_dd/rabbitmq-ack-auto-vs-client-aut</guid>
            <pubDate>Wed, 15 Feb 2023 04:59:19 GMT</pubDate>
            <description><![CDATA[<p>java에서 rabbitmq를 사용하기 위한 amqp 라이브러이에서 큐를 매핑할때 auto-ack 와 client-ack 두가지 종류가 있다.</p>
<p><strong>auto-ack</strong>는 exchange에서 consumer에게 msg를 보내기위해 work-pool에 msg를 넣으면 auto-ack를 발행한다. 즉 consumer에게 msg를 전달하고 ack를 받기전에 이미 받았다고 처리해버리는 것이다.</p>
<p>이 과정에서 개발자는 ack를 명시적으로 관리하는 것에 자유로울 수 있지만 신뢰성이 떨어지는 단점이 있다.</p>
<p><strong>client-ack</strong>는 exchange에서 consumer에게 msg를 보내고 client가 ack를 보내고, 이를 받았을때  ready에 있는 msg를 제외한다.</p>
<h2 id="참조">참조</h2>
<hr>
<p><a href="https://wheleph.gitlab.io/posts/2015-06-27-on-rabbitmq-automatic-ack-and-reliable-message-processing/">On RabbitMQ automatic acknowledgement and reliable message processing | wheleph&#39;s blog</a></p>
<p><a href="https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;blogId=willygwu2003&amp;logNo=130171987216">9. RabbitMQ Persistence and Performance</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[비동기 함수 구현 (with Python, NodeJS)]]></title>
            <link>https://velog.io/@moon_dd/%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%95%A8%EC%88%98-%EA%B5%AC%ED%98%84-with-Python-NodeJS</link>
            <guid>https://velog.io/@moon_dd/%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%95%A8%EC%88%98-%EA%B5%AC%ED%98%84-with-Python-NodeJS</guid>
            <pubDate>Fri, 03 Feb 2023 09:25:09 GMT</pubDate>
            <description><![CDATA[<h3 id="비동기란">비동기란?</h3>
<p>가볍게 말하면 함수를 호출하고 결과값을 기다리지 않고 다음 일을 진행하는 것이다.</p>
<p>반면에 보통 내가 구현해왔던 동기함수는 호출하면 return을 기다리고 다음줄의 명령어를 진행하는 방식으로 진행해왔다.</p>
<p>그래서 파이썬으로 구현하면서 왜 비동기를 사용해야하는 지에 대해 알아보았다.</p>
<h2 id="핵심문법">핵심문법</h2>
<pre><code class="language-python">async def do_async(imarg)</code></pre>
<p>기존 def 키워드 앞에 <code>async</code>를 붙이면 해당 함수는 비동기 처리가 된다. 요것을 <strong>코루틴</strong>이라고 부른다.</p>
<p><a href="https://aaronryu.github.io/2019/05/27/coroutine-and-thread/">코루틴과 쓰레드의 차이 설명</a></p>
<p><strong>ansyncio</strong></p>
<pre><code class="language-python">import asyncio</code></pre>
<p>asyncio는 비동기 관련 기능을 담고 있는 모듈이다. 이걸 임포트하면 이벤트루프에 일거리를 넣어줄 수 있는 함수들을 사용할 수 있다.</p>
<p><strong>비동기 함수 호출방법</strong></p>
<p>코루틴을 일반 함수처럼 냅다 호출하면 결과값을 코루틴 객체가 리턴된다.</p>
<p><strong>asyncio.run()</strong></p>
<pre><code class="language-python">import asyncio

async def do_async():
    return

asyncio.run(do_async())</code></pre>
<p><strong>asyncio.get_event_loop()</strong></p>
<p><code>asyncio.get_event_loop()</code> 을 이용해 async로 선언하지 않은 동기함수안에서 호출할 수 있다.</p>
<p>이벤트 루프는 비동기 작업들을 등록하면 내부적으로 루프를 돌며 등록된 작업들을 하나씩 실행하고 완료 시 그 결과를 통보해준다.</p>
<pre><code class="language-python">def do_sync(imarg):
    event_loop = asyncio.get_event_loop()
    event_loop.run_in_executor(None, do_async, imarg)</code></pre>
<p><strong>await</strong></p>
<p><code>await</code> 를 사용해 async로 선언된 비동기함수안에서 호출할 수 있다.</p>
<pre><code class="language-python">async def do_other_async():
    await do_async()</code></pre>
<p><code>await</code>키워드는 “다음으로 바로 진행하지말고, 이벤트 루프에 있는 일거리 하면서 결과값 기다려!”라는 의미를 가지고 있다. 그러면 비동기가 아니지 않나? 라고 생각이 들었지만 await는 마냥 기다리는 것이 아닌 이벤트 루프에 있는 일거리를 하면서 기다리는 것라고 한다.</p>
<p><strong>asyncio.gather()</strong>
<code>gather()</code>을 이용해서 비동기 작업들을 이벤트 루프에 한번에 등록할 수 있다.</p>
<pre><code class="language-python">async def main() :
    await asyncio.gather(
        do_async(),
                do_async(),
                do_async()
    )</code></pre>
<p>하여튼 위에서 배운 걸 이용해서 비동기함수를 작성해보았다.</p>
<h3 id="코드-및-실행결과">코드 및 실행결과</h3>
<p><strong>동기함수</strong></p>
<p><img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/adb142c0-af61-4d92-9dd4-bf318645cb9e/Untitled.png" alt="Untitled"></p>
<p><img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/15d60072-fc72-498a-a578-c40ecd400142/Untitled.png" alt="Untitled"></p>
<p><strong>비동기함수</strong></p>
<p><img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/64a85c5a-ef2d-4744-bd5a-de03d769c7bf/Untitled.png" alt="Untitled"></p>
<p>위 코드 캡쳐본이 잘 안보일까봐 아래에 복붙함</p>
<pre><code class="language-python">import time
import requests
import asyncio

async def download_page(url):
    event_loop = asyncio.get_event_loop() #이벤프 루프 가져오기
    req = await event_loop.run_in_executor(None, requests.get, url) #request.get은 동기함수이니, 지정된 executer에서 request.get이 호출되도록 지정 
    html = req.text
    print(&quot; Success to download page : &quot;, url, &quot;and size of page ( &quot;, len(html), &quot; ) &quot;)

async def main():
    await asyncio.gather( #이벤트 루프에 비동기 작업들 넣기
        download_page(&quot;https://www.python.org/&quot;),
        download_page(&quot;https://www.python.org/&quot;),
        download_page(&quot;https://www.python.org/&quot;),
        download_page(&quot;https://www.python.org/&quot;),
        download_page(&quot;https://www.python.org/&quot;)
    )

print(f&quot;Start time : {time.strftime(&#39;%X&#39;)}&quot;)
start_time = time.time()
asyncio.run(main()) #비동기함수 호출
end_time = time.time()
print(f&quot;End time : {time.strftime(&#39;%X&#39;)}, Total:{end_time-start_time} sec(s)&quot;)</code></pre>
<p><img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/04f1d50a-82f7-4505-b47b-bcc267732cd3/Untitled.png" alt="Untitled"></p>
<h2 id="node-js로-구현">node js로 구현</h2>
<p><img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f06da890-7005-4108-9b00-7e14635534e4/Untitled.png" alt="Untitled"></p>
<pre><code class="language-jsx">function setTimeoutPromise(ms){
    //ms이후에 resolove함수 호출
    return new Promise((resolve, reject) =&gt; {
        setTimeout(() =&gt; resolve(), ms);
    });
}

async function fetchAge(id){
    await setTimeoutPromise(1000); //Promise가 완료될때까지 기다리기
    console.log(`${id} 사원 데이터 받아오기 완료!`);
    return parseInt(Math.random() * 20 , 10) + 25;
}

async function startsAsyncsJobs(){
    let promises = []
    for (let i = 0; i &lt; 10; i++){
        promises.push(fetchAge(i)); //promise를 배열에 쌓아두기
    }

    let ages = await Promise.all(promises); //배열로 받은 promise들이 성공하면 resolve를 호출, 실패하면 reject를 호출

    console.log(
        `평균 나이는 ? ==&gt; ${
            ages.reduce((prev, current) =&gt; prev + current, 0) / ages.length
        }`
    );
}

startsAsyncsJobs();</code></pre>
<p><img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/da4acf0f-e2d8-454f-8624-9009e293d8ce/Untitled.png" alt="Untitled"></p>
<h2 id="참조">참조</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[PubSub + MessageQueue]]></title>
            <link>https://velog.io/@moon_dd/Publish-Subscribe-%EB%B0%A9%EC%8B%9D</link>
            <guid>https://velog.io/@moon_dd/Publish-Subscribe-%EB%B0%A9%EC%8B%9D</guid>
            <pubDate>Mon, 30 Jan 2023 08:37:53 GMT</pubDate>
            <description><![CDATA[<h3 id="pubsub">Pub/Sub</h3>
<h4 id="특징">특징</h4>
<ul>
<li><p>publisher - message broker - subscriber 형식으로 이루어져 있다.</p>
</li>
<li><p>메세지 기반 미들웨어</p>
</li>
<li><p>publisher가 event 발생시 message broker 에게 알려주고 해당 토픽 혹인 컨텐츠를 구독하고 있는 subscriber에게 메세지를 전달하는 방식이다.</p>
<ul>
<li>publisher가 발행하는 모든 메세지를 받는 것이 아닌 subscriber가 원하는 event에 해당하는 메세지만 받게 된다. 
  ⇒ 필터링<ul>
<li>topic</li>
<li>content</li>
<li>hybrid</li>
</ul>
</li>
</ul>
</li>
<li><p>동기방식인 request, response 형식이 아닌 비동기형식이다.</p>
<ul>
<li>subscirber가 메세지를 쌓아둘 수 있기때문에 publisher가 계속 기다릴 필요가 없다.</li>
</ul>
</li>
<li><p>pull technology : client가 아닌 server에 의해 시작되는 communication이다.</p>
</li>
<li><p>publisher와 subscriber가 message broker를 통해 연결되어 있으므로 서로를 모른 상태로 메세지를 보내게 된다.</p>
<ul>
<li><p>장점</p>
<ul>
<li>publisher와 subscriber가 서로의 시스템을 파악하지 않아도 되서 간편하고 용이하다. <ul>
<li>또한 확장성이 좋고 동적인 네트워크 구조를 형성할 수 있어서 좋다</li>
</ul>
</li>
</ul>
</li>
<li><p>단점 : publisher가 의도한대로 메세지가 보내졌는 지 알 수 없다. crash가 발생하여 메세지를 전송받지 못해도 subscriber를 알 턱이 없다.</p>
</li>
<li><p>서버와 클라이언트 둘 중에 하나가 running이 아니여도 backlog를 사용하기에 메세지를 전달할 수 있다.</p>
<h4 id="단점">단점</h4>
</li>
</ul>
</li>
<li><p>시스템 규모가 커지면 pub/sub은 처리량에 있어서 불안정하게 된다. ⇒ 데이터 센터</p>
<ul>
<li>많은 트래픽이 몰리면 local area network를 shut down 해버리는 문제가 있다.</li>
</ul>
</li>
<li><p>broker를 사용하면 pub/sub일 경우 in-band 형식( 메인 데이터와 컨트롤 데이터를 같은 채널을 통해 전송한는 방식)을 사용하는데, 이때 악의적으로 데이터를 조작하면 보안에 문제가 생길 수 있다.</p>
</li>
</ul>
<h3 id="kafka-redis">kafka, redis</h3>
<ul>
<li><strong>kafka</strong> : group의 개념이 있다. event가 발생 시 group 내 한명의 subscriber만 메세지를 받아야하는 경우<ul>
<li>큐를 사용하지 않고 topic이라는 카테고리에 데이터 집합을 저장</li>
<li>ex ) 회원가입시 user api(publisher) 에서 coupon을 발행하라는 메세지를 coupon api (subscriber )에게 전송하는 경우</li>
</ul>
</li>
<li><strong>redis</strong> : group의 개념이 없다. message broker는 tv의 channel과 같은 개념으로 해당 channe을 구독하고 있는 모든 subscriber에게 메세지를 전달하게 된다.<ul>
<li>ex) 권한 api(publisher)에서 권한정보가 변경되어 유저의 권한을 변경하라는 메세지를 유저 api (subscriber )에게 전달하는 경우 → 모든 서버에 있는 유저의 권한이 같이 변경되어야한다.</li>
</ul>
</li>
</ul>
<h3 id="message-queue">Message Queue</h3>
<ul>
<li>Message Oriented Middelware(MOM) 개념을 구현한 시스템<h4 id="구조">구조</h4>
</li>
<li>publisher가 event 발생 시 queue에 메세지를 저장하고 해당 queue를 소비하려는 consumer 중 한명이 해당 message를 소비하게 된다.<ul>
<li>큐안에 messageA가 있고 messageA를 consumerB가 소비하면 consumerA는 messageA에 대해 아무것도 모르게 된다.</li>
</ul>
</li>
<li>pub/sub은 publisher가 event가 발생하면 해당 topic을 구독하고 있는 모든 subscriber에게 브로드캐스팅으로 메세지를 전달한다.</li>
</ul>
<h2 id="참조">참조</h2>
<hr>
<p><a href="https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;blogId=hisukdory&amp;logNo=50109265674">Publish/Subscrib (pub/sub) system</a></p>
<p><a href="https://velog.io/@minsuk/Publish-Subscribe-%ED%8C%A8%ED%84%B4%EC%95%8C%EB%A6%BC">Publish /Subscribe 패턴(알림), 메세지큐</a></p>
<p><a href="https://medium.com/frientrip/pub-sub-%EC%9E%98-%EC%95%8C%EA%B3%A0-%EC%93%B0%EC%9E%90-de9dc1b9f739">PUB/SUB, 잘 알고 쓰자!</a></p>
<p><a href="https://fierycoding.tistory.com/83">pub/sub 이해하기 (JS 예시)</a></p>
<p><a href="https://escapefromcoding.tistory.com/706">Message Queues vs Pub/Sub</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[22.01.01~22.02.26] Purdue University 해외단기연수 기록 (6기 글로벌인재)]]></title>
            <link>https://velog.io/@moon_dd/22.01.0122.02.26-Purdue-University-%ED%95%B4%EC%99%B8%EB%8B%A8%EA%B8%B0%EC%97%B0%EC%88%98-%EA%B8%B0%EB%A1%9D-6%EA%B8%B0-%EA%B8%80%EB%A1%9C%EB%B2%8C%EC%9D%B8%EC%9E%AC</link>
            <guid>https://velog.io/@moon_dd/22.01.0122.02.26-Purdue-University-%ED%95%B4%EC%99%B8%EB%8B%A8%EA%B8%B0%EC%97%B0%EC%88%98-%EA%B8%B0%EB%A1%9D-6%EA%B8%B0-%EA%B8%80%EB%A1%9C%EB%B2%8C%EC%9D%B8%EC%9E%AC</guid>
            <pubDate>Sun, 27 Mar 2022 12:32:48 GMT</pubDate>
            <description><![CDATA[<h1 id="숙소">숙소</h1>
<p>숙소로는 Hampton Inn &amp; Suites West Lafayette에 묵었다.
교수님 말로는 2성급의 그저그런 숙소라 하셔서 기대를 전혀 안 했다.
퀸사이즈의 침대가 2개 있어서 룸메랑 둘이서 쓰기엔 아주 충분했다.
하지만 왜 2성급인지는 알겠는게, 청소가 충분하지 않았다. 
욕조청소를 해주지 않았고, 시트도 따로 말하지 않으면 바꿔주지 않았다.
따로 말씀을 드리거나 쪽지를 붙이고 가면 해주시긴한다!
기본적인 조식으로는 스크럼블리이나 오믈렛, 햄이 기본으로 있고 식빵, 베이글, 와플이 빵류로 있었다. 요거트와 우유, 시리얼도 있었다!!</p>
<p>처음에 호텔에서 어색했던 건 호텔을 돌아다니며 직원들을 마주칠 때 인사를 하는 것이였다 굉장히 친근하게 먼저 인사를 건내주었다. 나는 혼자 돌아다닐때 혼자만의 세상에 빠져있는 편이라 그 인사에 답하려하면 이미 지나가시거나 말이 어버버하게 나왔다.
아마 영어로 대답해야해서 그랬던 게 가장 켰던 것 같다.</p>
<h1 id="purdue-life">Purdue Life</h1>
<p>퍼듀에서의 생활이라고 하기엔 난 두달밖에 없었고, 청강만 했기때문에 미국대학문화를 느끼기엔 부족했다. 코로나와 연구때문에 더 부족했었다.
그래도 지금 생각해보면 할 건 다 했고 재밌던 기억들이 더 많았다.
우선 학교는 정말 넓었고 예뻤다. 봄에는 더 예쁘다던데 나중에 퍼듀학생에게 사진을 받아 봐야겠다. 날씨가 좋은 날에는 최대한 많이 걸어다녔다.</p>
<ol>
<li><p>Photo Day📸
<img src="https://images.velog.io/images/moon_dd/post/0b5a9039-8a9f-4ce2-834d-eb5f14dea020/KakaoTalk_20220327_211354583.jpg" alt="">
한국가기 직전에 한번 날씨가 따뜻한 날이 있었는데
그 날 친구들과 점심을 먹고 오면서 친구의 DSLR으로 사진을 정말 왕창 찍었다. 지금 잠금화면으로 해놓을만큼 맘에 드는 사진들이였다.
좋은 추억을 예쁘게 사진으로 남길 수 있어서 사진 찍어준 씩씩이에게 너무너무 고맙다.
가장 최근의 좋은 기억이라 그런가 그 날이 제일 기억에 많이 남는다.</p>
</li>
<li><p>설날🗓️
<img src="https://images.velog.io/images/moon_dd/post/656b5140-b939-4b23-9404-6face59bfe49/KakaoTalk_20220327_211750514.jpg" alt="">
한국에서 설날일때 미국에서는 snow storm으로 학교가 다 닫았다. 작년에는 쉬는 날이 별로 없었는데 오랜만에 긴 명절이였는데, 우린 미국에 있어서 그걸 못 즐긴다고 징징거렸는데 학교가 닫아버려서 우리들은 모두 호텔에 갇혀있었다. 진짜로 갇혀있었다. snow storm 오기 전날에 교수님이 미리 내일부터 snow storm으로 아마 학교가 2~3일정도 닫을거다 그에 대비해 먹을 걸 챙겨두어라고 하셨다. 그래서 그 날 무슨 전쟁전에 사재기하듯이 먹을 걸 챙겼다. 우선 학식에서 togo하여 포장하고 아시안마트가서 컵라면, 전자레인지 음식들을 왕창 사고 세탁도 미리해두었다.
아주 진귀한 경험이였다.ㅋㅋㅋㅋㅋㅋ 삼일동안 글로벌 인재 사람들 모두 호텔로비에서 같이 공부하고 눈밭에서 놀았다.
그때 중간에 케인즈에서 finger chicken사겠다고 오빠 3명인가하고 같이 나갔는데 아주 개고생하였다.
우선 다들 다음끼니까지 먹으려고 큰 걸사고 다른 사람들것까지 포장해와야했왔다.
레몬에이드 하나가 1리터이니 음료 캐리어에 4개 들어가 총 4키로를 들고 눈때문에 무릎까지 발을 올려 걸어야했기때문에 정말 힘들었다.ㅋㅋㅋㅋㅋㅋ
지금 생각해보면 추억이다!
그리고 그때 중국도 설날을 챙기기때문에 dining court에 중국의 설날식으로 꾸며져있었는데, 살짝 속상했다. 한국도 설날인데!!! 한복을 챙겨갔어야했다,,,, 흥!</p>
</li>
<li><p>Wabash river 옆동네🏛️ 
<img src="https://images.velog.io/images/moon_dd/post/7f99e905-2156-4a68-9409-cc53e5a0c1a4/KakaoTalk_20220327_211349002.jpg" alt=""></p>
</li>
</ol>
<p>++ 추가</p>
<ol start="4">
<li>Corec🏸
<img src="https://images.velog.io/images/moon_dd/post/ff1bb456-9ce8-422d-b17f-5680bb9df96f/corec.jpg" alt="">
가장 신기했던 건 코렉 체육관이다.
들어가자마자 클라이밍과 진짜 많은 운동기구들, 온갖 경기장 심지어 수영장에 온천도 있었다.
나는 거기서 배드민턴장만 써봤다.
코로나로 인해 2월달에는 아예 가지 않았다. 또한 1월말에 한번 토하고 쓰러진 적이 있어서 그 이후로는 체력을 과하게 쓰는 활동은 하지 않았다.
거기서 아프면 정말 답이 없기때문이다.</li>
</ol>
<p>++ 추가할 내용
5.BWW🍗
<img src="https://images.velog.io/images/moon_dd/post/f3345a05-e9cc-464a-b386-f705afb42f7a/bww.jpg" alt=""></p>
<p>6.Nine Irish Brothers🥩
<img src="https://images.velog.io/images/moon_dd/post/dbf16c10-a539-4d45-9a18-104707d7c6bd/KakaoTalk_20220327_211349634.jpg" alt=""></p>
<p>7.호텔에서 놀기🎮
<img src="https://images.velog.io/images/moon_dd/post/369d3854-6480-431e-8213-b951a9552d84/KakaoTalk_20220327_211350218.jpg" alt=""></p>
<p>8.농구경기🏀
<img src="https://images.velog.io/images/moon_dd/post/4683b65a-2380-49fd-baf9-6a4374db743a/KakaoTalk_20220327_211350559.jpg" alt=""></p>
<p>9.드론으로 데이터셋 구하기!🚁 
<img src="https://images.velog.io/images/moon_dd/post/a029fbb0-3769-4027-a29f-857de84482cb/KakaoTalk_20220327_211351077.jpg" alt=""></p>
<p>10.walmart🏪
<img src="https://images.velog.io/images/moon_dd/post/f3569d1c-f1d1-4152-bc1c-15cbf9a0a4d2/KakaoTalk_20220327_211351646.jpg" alt=""></p>
<p>11.커피숍에서 쪽팔렸던 일,,☕
<img src="https://images.velog.io/images/moon_dd/post/54fad718-85c8-4410-b5fe-286c195fd324/KakaoTalk_20220327_211352328.jpg" alt=""></p>
<p>12.Candy Store🍭
<img src="https://images.velog.io/images/moon_dd/post/56bae4c2-75ae-41ff-a2ed-85b458a93d34/KakaoTalk_20220327_211352884.jpg" alt=""></p>
<p>13.Certificate🎟️ 
<img src="https://images.velog.io/images/moon_dd/post/dc8e2814-9492-449f-a759-2b070b716f34/KakaoTalk_20220327_211355300.jpg" alt=""></p>
<p>14.Shopping🛍️
<img src="https://images.velog.io/images/moon_dd/post/90167b8c-f5fe-4435-8b06-51d2e632d76e/KakaoTalk_20220327_211355862.jpg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2021 하계 백마인턴 1달차 후기]]></title>
            <link>https://velog.io/@moon_dd/2021-%ED%95%98%EA%B3%84-%EB%B0%B1%EB%A7%88%EC%9D%B8%ED%84%B4-1%EB%8B%AC%EC%B0%A8-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@moon_dd/2021-%ED%95%98%EA%B3%84-%EB%B0%B1%EB%A7%88%EC%9D%B8%ED%84%B4-1%EB%8B%AC%EC%B0%A8-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Mon, 26 Jul 2021 11:14:14 GMT</pubDate>
            <description><![CDATA[<p>3학년 1학기가 종강하고 나는 내가 이 학교생활에 익숙해졌다는 것을 느꼈다.
누군가에게 익숙해지는 것은 좋을 수 있지만 나에게는 그렇게 달가운 일은 아니다.
무언가에 익숙해지는만큼 나는 그 일에 흥미가 떨어지는 편이기때문인 것 같다.
그래서 학기말부터 계속 생각했다
아 방학에는 한번도 안해본 플로우에 담겨져있어야겠다라고 생각했다.
그러면 내가 정신을 차리지 않을까하는 마음으로 백마인턴을 신청하였다.</p>
<h3 id="어떤-업무를-맡았나면요">어떤 업무를 맡았나면요!</h3>
<p>회사에서 내가 해야할 일을 배정받았다.
신규아이이디어 기획 및 프로토타입 개발이였다.
첫 회의때 기획팀 과장님과 부서 부장님께서 </p>
<blockquote>
<p>&quot;우리 회사는 이런걸 만들고 있고 이런 방향으로 나아가고싶다 그래서 신규 서비스를 계획하고 있는데 20대의 아이디어가 필요하다&quot;</p>
</blockquote>
<p>라고 말씀해주셨다.
그래서 주신 방향에 맞게  같이 인턴을 하게 된 도현오빠랑 각각 아이디어를 구상했다.
그리고 아이디어를 최종 승인을 받고 아이디어 시나리오와 UI 구상을 하였다.
여기까지가 거의 4주가 걸렸다. 
4주동안 2-3일 간격으로 미팅이 있었고 피드백 받고 수정하고 다시 발표하고를 반복하였다.</p>
<p>4주 목요일날 개발팀 팀장님과 미팅을 거쳐 개발계획에 들어갔다. </p>
<h3 id="신기했던-점">신기했던 점!</h3>
<p>업무 중간중간 회사내부에 대해 알게되는 부분들이 있었는데
그게 은근 재미있게 만들어주었다.
우선 회사 메신저를 쓰고, 회사 출퇴근을 찍는게 신기했다.
(진짜 직장인 된 것 같아서 느낌이 이상했다,,,ㅋㅋㅋㅋ)
그리고 엑스키퍼 구매페이지가 이번에 업데이트가 되었는데
업데이트 되기전에 먼저 볼 기회가 있었는데</p>
<p>UI를 어떤식으로 바꾸어 원하는 방향으로 이끌 지, 왜 이렇게 만드는 지, 어떤 과정을 거치는 지를 보여주셨다.
되게 신기했다,,,</p>
<p>이런식으로 아직 공개되지 않아서 말할수는 없지만 
그 외의 아직 세상에 공개되지 않는 기획들을 보는 게 왠지 나만 비밀을 알고 있는 것 같아서 헤헷 했다,,,,ㅋㅋㅋㅋㅋㅋㅋㅋ </p>
<h3 id="일-어려웠나요">일 어려웠나요?</h3>
<p>어렵기보다는 헤맸다고 표현하는 게 맞다.</p>
<p>아마 나는 지란인턴이 아니였으면 평생 기획, 마케팅, 디자인쪽 일은 전혀 모르고 코딩만 하는 인생이였을 것이다.
인턴이라서 기획도 해보고 그럼으로써 회사에서 서비스가 어떤 플로우를 통해 기획, 개발되는 지 알게되었다.
그래서 &quot;이거 만들어줘!&quot;라고 해서 전달받은 사항만 코딩하는 게 아닌 서비스를 생각하면서 개발하는 관점을 조금이나마 가지게 되었다.</p>
<p>물론 하는 동안 회의에서 까이고 나면 좌절감을 느끼긴했다.
근데 솔직히! 내가 이걸 배워본 적도 경험해본 적도 없는데이걸 잘하는 건 말이 안된다고 생각한다.</p>
<p>제일 많이 무력감을 느낀 부분은 알맹이를 가지고 있더라도 그걸 어떻게 보여줘야하는 지 어떤 방향으로 말해야하는 지를 모르는 것이였다.
회사가 가지고 있는 플로우가 있을텐데 거기에 알맹이를 어떻게 넣어야하는 지 모른다는게 진짜 답답했다.</p>
<p>그래도 최소한 다음에는 이것보다는 잘 할 것 같다.
정말 실패해서 얻어지는 게 무엇인 지 알게되었던 것 같다.
그거면 충분하지 않을까</p>
<h3 id="회사분위기는-어땠나요">회사분위기는 어땠나요?</h3>
<p>우선 간식과 아침밥이 좋았다!
간식은 헬퍼가 매달 주문하고 탕비실과 간식서랍에 채워주는 방식이였고 아침은 매일 아침마다 김밥과 토스트가 나왔다.
그 중에 먹고싶은 거 골라먹으면 됬는데
마이 빼이보릿은 참치김밥과 치즈김밥이였다.
그리고 과자들!!! 졸리고 지친 나를 살게해주는 고마운 친구들이였다.</p>
<p>그리고 회사에 바디프렌드 마자시의자 있었다.
직원들이 원하는 시간에 예약하고 쉴 수 있는 공간이라한다.
원래는 마사지사가 있었는데 마사지의자로 바뀌었다고한다!
나는 아직 한번도 못 사용해봤다,,,
인턴 끝나기전에 꼭 사용해볼거야아아</p>
<p>회사분위기는 굉장히 자유로웠다.
복장도 호칭도 내가 느끼기엔 자유로웠다.
호칭이 언니, 오빠였던 분들이 많았다.</p>
<p>회사 선배들이 굉장히 잘 챙겨주셨다.
여자선배님들이 먼저 밥도 먹자고해주셔서 말도 트고 도움도 많이 받았다.
진짜 그냥 하는 말이 아니라 원래 있던 사람마냥 되게 편하게 대해주셨다. 진짜 사촌언니인줄,,,ㅋㅋㅋㅋㅋ
그리고 과장님이 회사에서 거의 인턴들 아빠마냥 많이 챙겨주셨다. 인턴 끝나고도 만나고싶은 분이다!
조언도 해주시고 장난도 많이 쳐주셔서 재밌는 분위기에서 일할 수 있었다. 제일 감사한 분이다!</p>
<h3 id="제일-어려웠던-점은">제일 어려웠던 점은?</h3>
<p>단연코 졸림과 출퇴근 그리고 더위였다.
비대면에 익숙해진 생활패턴에서 출퇴근을 하려니 죽을 맛이였다.
그리고 졸릴 때는 그냥 자버리는 편이라 그걸 견디느라 힘들었다.
진짜 카페인도 잘 안먹고 찬물도 안 먹는데
회사다니면서 다 배워버렸다.
내가 아메리카노, 인스턴트 커피, 찬물을 안 마시는데 진짜 살려고 마셨다,,,, 
외우자 잠올때는!</p>
<p>&quot;핫초코, 인스턴트 커피 아주 찌이이인하게 타서 얼음 잔뜩 넣고 2분후 마시기&quot;</p>
<p>ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
진짜 어이없지만 난 카페인보다 당으로 잠을 깨웠다.
그래서 저 방법이 진짜 잘 먹혔다.</p>
<h3 id="제일-좋았던-점은">제일 좋았던 점은?</h3>
<p>단연코 학교에서는 배울 수 없었던 회사 플로우와 그에 맞는 툴을 알 수 있어서 좋았다.
개발팀 팀장님이 정말 멋있었던 부분이 우리가 분명 못했을텐데
지적보다는 &#39;이럴때는 이러이러한게 있다. 보통 회사에서는 이렇게 사용한다.&#39; 이런식으로 우리에게 알려주시는 방식이였다. 이걸 왜 사용하는 지 장단점, 특징, 비슷한 다른 방법까지 알려주셨다. 그래서 바보같은 질문일지라도 편하게 물어보고 이해될때까지 물어볼 수 있었다. 
매번 느꼈지만 많은 걸 알고 계시고 정확한 포인트를 잡고 계신 분이라 정말 신기해하고 멋있었다.</p>
<h3 id="마무리">마무리</h3>
<p>쓰면서 느꼈는데 나 진짜 글은 못 쓰는 것 같다...
차라리 말하는 게 편하다,,,
그래도 기록을 남기고싶어서 남겨두지만 언제 비공개가 될 지는 모르겠다ㅋㅋㅋㅋㅋㅋㅋㅋ
3학년 1학기동안 동아리, 수업, 과제, 시험, 연애(?)까지 많은 일이 있었다.
그래서 매일매일 휴학을 입에 달고 살았는데 너무나도  감사하게 
좋은 사람들이 주위에서 나를 많이 응원해줬다.
종강하자마자 인턴하느라 바빠서 연락도 제대로 못 했는데도
먼저 연락해서 챙겨주고 이것저것 보내준 광주친구들, 언니들, 가족들 다 너무너무 감사하다아
나 은혜는 갚는 정현이야 알지? 인턴끝나면 다 갚을게
딱 기다려!
이제 본격적으로 개발에 들어가는데 남은 한달동안 만족할때까지 갈아넣고 싶다
인턴이 완전히 끝나면 이에 대한 후기도 남길 예정이다!
8월까지 화이티이잉!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[1주차 실습 OCaml언어]]></title>
            <link>https://velog.io/@moon_dd/1%EC%A3%BC%EC%B0%A8-%EC%8B%A4%EC%8A%B5-OCmal%EC%96%B8%EC%96%B4</link>
            <guid>https://velog.io/@moon_dd/1%EC%A3%BC%EC%B0%A8-%EC%8B%A4%EC%8A%B5-OCmal%EC%96%B8%EC%96%B4</guid>
            <pubDate>Fri, 05 Mar 2021 08:09:45 GMT</pubDate>
            <description><![CDATA[<p>1주차 실습때 Window Terminal을 이용하여 OCmal언어로 기본적인 함수를 작성해보았다.
이 기록은 이번 실습때 하도 오류가 많았고 해결하는 과정이 다음주에는 기억이 안 날 것 같아서 작성해둔다,,ㅠㅠ
다음주에는 부디 익숙해져서 안 쓰길바란다,,,ㅠㅠ
처음보는 함수형언어였기에 1학년때 처음 파이썬을 배울 때의 나같았다.
굉장히 버벅거리고 긴장한 상태로 실습을 진행하였다.</p>
<h3 id="check-version">Check Version</h3>
<p><img src="https://images.velog.io/images/moon_dd/post/b9b26fd5-32e6-4eeb-9d7c-14c332419e97/image.png" alt="">
루트로 먼저 들어간다.
<img src="https://images.velog.io/images/moon_dd/post/c52b3a43-ae7c-4309-a25a-16bf3ee13cfd/image.png" alt=""></p>
<p>ocmal opam dune의 버전을 확인했다.
하지만
<img src="https://images.velog.io/images/moon_dd/post/b63af548-4241-4ebc-8eed-eff4fced401f/image.png" alt="">
dune이 설치가 되어있지 않았다.
실습 당시에 많은 수강생들이 dune설치를 못 했던 것 같다
다행히 너무 친절하신 교수님과 조교님이 일일이 화면공유를 통해 이를 해결해주셨다</p>
<p>처음 오류는
<img src="https://images.velog.io/images/moon_dd/post/295e5a32-2b3d-41f6-9eda-73b654317706/image.png" alt="">
<img src="https://images.velog.io/images/moon_dd/post/496595f2-7dfa-439b-b1db-110fa1d60026/image.png" alt="">
이런 오류가 발생하였다.</p>
<p>그때 당시에는 몰랐지만 m4가 설치가 안되어있었다.
<img src="https://images.velog.io/images/moon_dd/post/959d8665-66a5-4f54-80c2-2d1074fb6833/image.png" alt="">
<img src="https://images.velog.io/images/moon_dd/post/eaf72405-a77a-4130-93e2-fce37084c62a/image.png" alt="">
이렇게 m4를 설치해주고 다시 dune을 설치하려했지만 또 오류가 발생하였다.
<img src="https://images.velog.io/images/moon_dd/post/88eaff42-ba9a-47b4-ab20-028b6540f5d7/image.png" alt="">
<img src="https://images.velog.io/images/moon_dd/post/e0b4872c-e00d-4461-a66b-d7b550862f87/image.png" alt="">
make가 설치되어 있지 않았다. 
<img src="https://images.velog.io/images/moon_dd/post/dd6f7874-6cff-472d-af32-20787e15ab27/image.png" alt="">
make를 설치하고
<img src="https://images.velog.io/images/moon_dd/post/539b215f-cd4f-4800-be86-0ee60e56cecb/image.png" alt="">
dune을 설치하니 정상적으로 설치되었다.
<img src="https://images.velog.io/images/moon_dd/post/210d0c3f-df6a-4c5a-9684-653719de1965/image.png" alt="">
helloworld 파일을 만들고 dune을 vi 편집기를 이용하여 만들어주었다.</p>
<p><img src="https://images.velog.io/images/moon_dd/post/9c6993da-30fe-4ded-957e-1addd6916432/image.png" alt="">
ml파일을 vi편집기로 작성후
빌드하고
실행한다.
--profile release는 build와 exec 둘 다 써줘야한다.
교수님이 이 언어는 굉장히 안전한 언어여서 warning이어도 오류가 난다고 --profile release로 이를 없애줘야??한다고 했던 것 같다.. 사실 잘 모르겠다!</p>
<p>++과제를 하면서 또 당황스러운 오류가 발생했다.
<img src="https://images.velog.io/images/moon_dd/post/9bcaa970-567f-4e6f-832c-c7a4b3eaf916/image.png" alt=""></p>
<p>build를 하기위해 dune명령어를 입력했는데
설치되어있지않다고 오류가 나길래
띠용?? 미융???하며 다시 설치하기 위해서
설치명령어를 입력하니 이미 설치되어 있다고 말하고 있다.
니기럴 뭔 개소리야 하면서 verison을 확인해보니
또 없댜,,,,고 말한다.
열받으려는 찰나 단톡에 질문을 하니 친절한 수강생분이 
eval $(opam env)를 해보라고해서 해봤다.
<img src="https://images.velog.io/images/moon_dd/post/db16d3f0-1ef4-4725-986e-c92778934b0e/image.png" alt="">
와웅,,, 뭐지 저 명령어는 매직인가,, (++ PATH를 업데이트 해주는 명령어라고 함!)
저번에도 이거하니 설치가 잘됐었는데,,,
하여튼 그러하다!</p>
]]></description>
        </item>
    </channel>
</rss>