<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Woojin Devlog RSS Feed]]></title><description><![CDATA[구조적으로 사고하고, 근거 있게 구현하기 위해 기록합니다.]]></description><link>https://woojin-devv.github.io</link><generator>GatsbyJS</generator><lastBuildDate>Sun, 21 Jun 2026 13:27:53 GMT</lastBuildDate><item><title><![CDATA[[Spring] Spring Security]]></title><description><![CDATA[Spring Security 1. Spring 기반 보안 설정 처리 Spring Security 는 Spring 기반 애플리케이션에서 인증(Authentication) 과 권한/인가(Authorization) 를 처리하기 위한 보안 프레임워크이다. 웹 애플리케이션에서 사용자는 단순히 로]]></description><link>https://woojin-devv.github.io/posts/Springmvc_Spring_Security/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Springmvc_Spring_Security/</guid><pubDate>Fri, 19 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;spring-security&quot;&gt;Spring Security&lt;/h2&gt;
&lt;h3 id=&quot;1-spring-기반-보안-설정-처리&quot;&gt;1. Spring 기반 보안 설정 처리&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Spring Security&lt;/strong&gt;는 Spring 기반 애플리케이션에서 &lt;strong&gt;인증(Authentication)&lt;/strong&gt; 과 &lt;strong&gt;권한/인가(Authorization)&lt;/strong&gt; 를 처리하기 위한 보안 프레임워크이다.
웹 애플리케이션에서 사용자는 단순히 로그인만 하는 것이 아니라, 로그인 이후 자신이 가진 권한에 따라 접근 가능한 기능이 달라져야 한다.
예를 들어 일반 사용자는 게시글 조회만 가능하고, 관리자는 게시글 등록, 수정, 삭제까지 가능해야 한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;2-인증과-권한&quot;&gt;2. 인증과 권한&lt;/h3&gt;
&lt;h4 id=&quot;21-인증-authentication&quot;&gt;2.1 인증 Authentication&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;인증이란 - 사용자가 누구인지 확인하는 과정이다.
&lt;ul&gt;
&lt;li&gt;아이디 &amp;#x26; 비밀번호 입력&lt;/li&gt;
&lt;li&gt;로그인 성공&lt;/li&gt;
&lt;li&gt;서버가 해당 사용자를 인증된 사용자로 판단&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;22-권한-authorization&quot;&gt;2.2 권한 Authorization&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;권한은 인증된 사용자가 어떤 기능을 사용할 수 있는지 판단하는 과정
&lt;ul&gt;
&lt;li&gt;로그인한 사용자가 게시판 상세 페이지에 접근할 수 있는가?&lt;/li&gt;
&lt;li&gt;로그인한 사용자가 글쓰기 페이지에 접근할 수 있는가?&lt;/li&gt;
&lt;li&gt;로그인한 사용자가 관리자 페이지에 접근할 수 있는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;사용자의 권한(ROLE)에 따라 접근 가능한 프로세스를 제어하는 것이 권한 처리&lt;/strong&gt;&lt;/em&gt; 이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-security를-사용하지-않는-전통적인-인증권한-처리&quot;&gt;3. Security를 사용하지 않는 전통적인 인증/권한 처리&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Spring Security를 사용하지 않는 경우에는 보통 session을 직접 사용한다.&lt;/li&gt;
&lt;li&gt;세션기반 방식에 대한 설명은 아래 링크 참조
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://woojin-devv.github.io/posts/Spring-JWT/&quot;&gt;세션과 JWT 방식&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;기존-방식의-문제&quot;&gt;기존 방식의 문제&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;모든 페이지마다 session 체크 코드가 반복된다.&lt;/li&gt;
&lt;li&gt;권한 변경 시 여러 JSP와 Controller를 수정해야 한다.&lt;/li&gt;
&lt;li&gt;URL 접근 제어가 분산된다.&lt;/li&gt;
&lt;li&gt;권한이 많아지면 관리가 복잡해진다.&lt;/li&gt;
&lt;li&gt;보안 관련 처리가 개발자 코드에 흩어진다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;4-spring-security를-사용하는-이유&quot;&gt;4. Spring Security를 사용하는 이유&lt;/h3&gt;
&lt;p&gt;Spring Security를 사용하면 인증과 권한 처리를 하나의 설정 파일에서 통합적으로 관리할 수 있음.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;즉, Spring Security는 보안 처리를 Controller나 JSP에 흩어놓지 않고, 보안 설정 파일에서 중앙 집중식으로 관리하게 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;통합-관리의-의미&quot;&gt;통합 관리의 의미&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Spring Security를 사용하면 다음 항목을 한 곳에서 관리할 수 있음.
&lt;ul&gt;
&lt;li&gt;사용자 인증, 권한 관리&lt;/li&gt;
&lt;li&gt;URL 접근 관리&lt;/li&gt;
&lt;li&gt;로그인 페이지 설정&lt;/li&gt;
&lt;li&gt;로그아웃 처리&lt;/li&gt;
&lt;li&gt;세션 만료 처리&lt;/li&gt;
&lt;li&gt;권한 없는 사용자 접근 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;flowchart&lt;/span&gt; LR
    A&lt;span class=&quot;token text string&quot;&gt;[로그인 성공]&lt;/span&gt; &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; B&lt;span class=&quot;token text string&quot;&gt;[Authentication 객체 생성]&lt;/span&gt;
    B &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; C&lt;span class=&quot;token text string&quot;&gt;[SecurityContext에 저장]&lt;/span&gt;
    C &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; D&lt;span class=&quot;token text string&quot;&gt;[Session을 통해 인증 상태 유지]&lt;/span&gt;
    D &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; E&lt;span class=&quot;token text string&quot;&gt;[요청마다 Security Filter가 권한 확인]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[Spring] Maven 기반 Spring MVC 프로젝트에 MyBatis 연동하기]]></title><description><![CDATA[1. 개요 이번 글에서는 Maven 원형 기반의 Spring MVC 프로젝트에 Mybatis를 연동하는 과정을 정리한다. Spring MVC 프로젝트에서 DB 접근 코드를 직접 JDBC로 작성하면 Connection, PreparedStatement, ResultSet과 같은 처리 관련]]></description><link>https://woojin-devv.github.io/posts/Springmvc_mybatis/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Springmvc_mybatis/</guid><pubDate>Thu, 18 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;1-개요&quot;&gt;1. 개요&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;이번 글에서는 Maven 원형 기반의 Spring MVC 프로젝트에 Mybatis를 연동하는 과정을 정리한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Spring MVC 프로젝트에서 DB 접근 코드를 직접 JDBC로 작성하면 Connection, PreparedStatement, ResultSet과 같은&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;처리 관련 BoilerPlate가 생긴다. MyBatis를 활용하면 SQL의 경우 직접 XML Mapper에 분리할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;11-프로젝트-구조&quot;&gt;1.1 프로젝트 구조&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Maven 기반 Spring MVC 프로젝트의 기본 구조는 다음과 같다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;SpringMVC_Basic05_Maven
├── pom.xml
└── src
    └── main
        ├── java
        │   ├── controller
        │   ├── service
        │   ├── dao
        │   │   └── NoticeDao.java
        │   └── vo
        │       └── Notice.java
        ├── resources
        │   └── mapper
        │       └── NoticeDao.xml
        └── webapp
            └── WEB-INF
                ├── web.xml
                ├── views
                └── spring
                    ├── root-context.xml
                    └── servlet-context.xml&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;MyBatis Mapper XML 파일은 일반적으로 src/main/resources/mapper 아래에 둔다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;2-pomxml에-의존성-추가&quot;&gt;2. pom.xml에 의존성 추가&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Spring MVC 프로젝트에서 MyBatis를 사용하려면 다음과 같은 의존성이 필요하다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Spring MVC --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;org.springframework&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;spring-webmvc&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;5.3.39&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- MyBatis --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;org.mybatis&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;mybatis&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;3.5.16&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- MyBatis Spring 연동 --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;org.mybatis&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;mybatis-spring&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;2.1.2&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Spring JDBC --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;org.springframework&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;spring-jdbc&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;5.3.39&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Oracle JDBC Driver --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;com.oracle.database.jdbc&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;ojdbc11&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;23.3.0.23.09&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Servlet API: Tomcat이 제공하므로 provided --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;javax.servlet&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;javax.servlet-api&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;4.0.1&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;scope&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;provided&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;scope&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- JSTL --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;javax.servlet&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;groupId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;jstl&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;artifactId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;1.2&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dependency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dependencies&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Tomcat 9버전과 Spring 5 기반의 프로젝트의 경우 javax.servlet 계열을 사용해야한다.
&lt;ul&gt;
&lt;li&gt;Tomcat 10 이상은 jakarta.servlet 계열을 사용하므로 기존 Spring MVC Legacy 프로젝트와 충돌할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;21-db-연결-설정&quot;&gt;2.1 DB 연결 설정&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#spring-%EC%84%A4%EC%A0%95%ED%8C%8C%EC%9D%BC&quot;&gt;Spring 설정 파일&lt;/a&gt;에 DataSource를 등록해야한다.
&lt;ul&gt;
&lt;li&gt;아래 예시는 Oracle DB 기준이다.
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;bean&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;dataSource&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;org.springframework.jdbc.datasource.DriverManagerDataSource&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;property&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;driverClassName&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;oracle.jdbc.OracleDriver&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;property&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;jdbc:oracle:thin:@//localhost:1521/FREEPDB1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;property&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;username&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;username&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;property&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;password&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;password&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;bean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;22-sqlsessionfactorybean-설정&quot;&gt;2.2 SqlSessionFactoryBean 설정&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;MyBatis는 SqlSessionFactory를 통해 SQL 실행 객체를 생성한다.&lt;/li&gt;
&lt;li&gt;Spring 에서는 SqlSessionFactoryBean을 등록하여 MyBatis와 Spring을 연결한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;bean&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;sqlSessionFactory&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;org.mybatis.spring.SqlSessionFactoryBean&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;property&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;dataSource&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;dataSource&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;property&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;mapperLocations&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;classpath:/mapper/*.xml&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;bean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;spring-설정파일&quot;&gt;Spring 설정파일&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;일반적인 Spring 설정파일은 아래와 같다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;src/main/webapp/WEB-INF/spring/root-context.xml&lt;/li&gt;
&lt;li&gt;src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[Spring] MVC 어노테이션 기반 요청 처리 흐름 정리]]></title><description><![CDATA[1. 개요 이 글에서는 Spring MVC에서 어노테이션을 이용해 컨트롤러와 서비스 객체를 등록하고, 하나의 URL에 대해 GET 요청과 POST 요청을 분리해서 처리하는 흐름을 정리한다. 또한 JSP form에서 전달된 요청 파라미터가 NewArticleCommand 객체에 자동으로 ]]></description><link>https://woojin-devv.github.io/posts/Springmvc_basic/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Springmvc_basic/</guid><pubDate>Tue, 16 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;1-개요&quot;&gt;1. 개요&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;이 글에서는 Spring MVC에서 어노테이션을 이용해 컨트롤러와 서비스 객체를 등록하고, 하나의 URL에 대해 GET 요청과 POST 요청을 분리해서 처리하는 흐름을 정리한다.
또한 JSP form에서 전달된 요청 파라미터가 NewArticleCommand 객체에 자동으로 바인딩되는 과정과, 기존 Servlet 방식과의 차이도 함께 정리한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;2-controller-어노테이션&quot;&gt;2. Controller 어노테이션&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Controller&lt;/span&gt;
&lt;span class=&quot;token annotation punctuation&quot;&gt;@RequestMapping&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/article/newArticle.do&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NewArticleController&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token annotation punctuation&quot;&gt;@GetMapping&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;article/newArticleForm&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token annotation punctuation&quot;&gt;@PostMapping&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NewArticleCommand&lt;/span&gt; command&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;article/newArticleSubmitted&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;@Controller는 해당 클래스를 Spring MVC의 컨트롤러로 등록하는 어노테이션이다.&lt;/li&gt;
&lt;li&gt;@RequestMapping은 컨트롤러가 처리할 공통 요청 URL을 지정한다.&lt;/li&gt;
&lt;li&gt;이 예제에서는 /article/newArticle.do 요청을 NewArticleController가 처리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;3-get-요청과-post-요청-분리&quot;&gt;3. GET 요청과 POST 요청 분리&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Spring MVC에서는 하나의 URL을 기준으로 하더라도 HTTP Method에 따라 서로 다른 메서드가 실행되도록 분리할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;getmapping&quot;&gt;@GetMapping&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@GetMapping&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;article/newArticleForm&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;@GetMapping은 GET 방식 요청을 처리한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;사용자가 브라우저에서 /article/newArticle.do 주소로 처음 접근하면 GET 요청이 발생한다. 이때 form() 메서드가 실행되고, 게시글 작성 폼 화면을 반환한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;postmapping&quot;&gt;@PostMapping&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@PostMapping&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NewArticleCommand&lt;/span&gt; command&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;article/newArticleSubmitted&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;@PostMapping은 POST 방식 요청을 처리한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;사용자가 게시글 작성 폼에서 제목과 내용을 입력한 뒤 전송 버튼을 누르면 POST 요청이 발생한다. 이때 submit() 메서드가 실행되고, 입력된 데이터를 처리한 뒤 작성 완료 화면을 반환한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;즉, 같은 URL인 /article/newArticle.do를 사용하더라도 요청 방식에 따라 다음과 같이 동작이 분리된다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;4-view-이름-반환과-viewresolver&quot;&gt;4. View 이름 반환과 ViewResolver&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Controller 메서드의 반환 타입이 String이면, Spring MVC는 반환값을 &lt;strong&gt;View 이름&lt;/strong&gt;으로 해석한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@GetMapping&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;article/newArticleForm&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;주의
&lt;ul&gt;
&lt;li&gt;위 코드에서 반환한 문자열은 실제 JSP 파일의 전체 경로가 아니다. 단순한 View 이름이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Spring MVC에서는 InternalResourceViewResolver가 View 이름을 실제 JSP 경로로 변환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;bean&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;internalResourceViewResolver&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;org.springframework.web.servlet.view.InternalResourceViewResolver&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;property&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;prefix&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/WEB-INF/views/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;property&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;suffix&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;.jsp&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;bean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;위 설정이 있을 경우, Controller에서 반환한 View 이름은 다음과 같이 변환됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;article/newArticleForm
↓
/WEB-INF/views/article/newArticleForm.jsp&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;5-service-계층--service&quot;&gt;5. Service 계층 &amp;#x26; @Service&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;게시글 작성, 회원가입, 주문 처리와 같은 핵심 로직은 Service 계층에서 처리하는 것이 일반적임.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;
&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;com&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token import&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;com&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NewArticleCommand&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token import&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;org&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;springframework&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;stereotype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Service&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token annotation punctuation&quot;&gt;@Service&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ArticleService&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ArticleService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ArticleService 생성자 호출&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;writeArticle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NewArticleCommand&lt;/span&gt; command&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// DAO가 있다고 가정한다.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// DAO dao = new DAO();&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// dao.insert(command);&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;글쓰기 작업 완료 : &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; command&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;@Service는 해당 클래스가 Service 계층의 클래스임을 나타내는 어노테이션이다.&lt;/li&gt;
&lt;li&gt;Spring은 컴포넌트 스캔 범위 안에서 @Service가 붙은 클래스를 찾아 Bean 객체로 등록한다.
&lt;ul&gt;
&lt;li&gt;단, &lt;code class=&quot;language-text&quot;&gt;@Service&lt;/code&gt;를 붙였다고 무조건 Bean으로 등록되는 것은 아니다. 반드시 컴포넌트 스캔 대상 패키지 안에 있어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;context:&lt;/span&gt;component-scan&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;base-package&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;com&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 설정이 있다면 com 패키지 아래에 있는 @Controller, @Service, @Repository, @Component가 붙은 클래스를 Spring이 자동으로 탐색한다.&lt;/p&gt;
&lt;p&gt;따라서 ArticleService는 직접 new ArticleService()로 생성하지 않아도 Spring Container 안에 Bean 객체로 생성된다.&lt;/p&gt;
&lt;h2 id=&quot;6-기존-servlet-방식과-spring-mvc-방식-비교&quot;&gt;6. 기존 Servlet 방식과 Spring MVC 방식 비교&lt;/h2&gt;
&lt;h3 id=&quot;기존-servlet&quot;&gt;기존 Servlet&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;NewArticleCommand&lt;/span&gt; article &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NewArticleCommand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

article&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setParentId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getParameter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;parentId&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
article&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setTitle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getParameter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
article&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setContent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getParameter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;기존 Servlet 방식에서는 요청 파라미터를 직접 꺼내고, 객체를 생성한 뒤 setter를 이용해 값을 넣어야 했다.&lt;/li&gt;
&lt;li&gt;또한 JSP로 데이터를 전달할 때도 직접 request 영역에 데이터를 저장해야 했다.&lt;/li&gt;
&lt;li&gt;View로 이동할 때도 RequestDispatcher를 직접 사용했다.
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;RequestDispatcher&lt;/span&gt; dispatcher &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
  request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getRequestDispatcher&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/WEB-INF/views/article/newArticleSubmitted.jsp&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  dispatcher&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;spring-mvc-방식&quot;&gt;Spring MVC 방식&lt;/h3&gt;
&lt;h3 id=&quot;newarticlecommand-model-정의&quot;&gt;NewArticleCommand Model 정의&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;com&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token import&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;lombok&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Data&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token annotation punctuation&quot;&gt;@Data&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NewArticleCommand&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; parentId&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; title&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;service단&quot;&gt;Service단&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@PostMapping&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NewArticleCommand&lt;/span&gt; command&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  articleService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeArticle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;command&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;article/newArticleSubmitted&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Spring MVC는 요청 파라미터 이름과 NewArticleCommand 객체의 필드 이름을 비교해서 값을 자동으로 넣어준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;흐름-정리&quot;&gt;흐름 정리&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;
&lt;span class=&quot;token keyword&quot;&gt;flowchart&lt;/span&gt; LR
    A&lt;span class=&quot;token text string&quot;&gt;[&quot;사용자 GET 요청&amp;lt;br/&gt;/article/newArticle.do&quot;]&lt;/span&gt; &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; B&lt;span class=&quot;token text string&quot;&gt;[&quot;NewArticleController form 메서드 실행&quot;]&lt;/span&gt;
    B &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; C&lt;span class=&quot;token text string&quot;&gt;[&quot;View 이름 반환&amp;lt;br/&gt;article/newArticleForm&quot;]&lt;/span&gt;
    C &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; D&lt;span class=&quot;token text string&quot;&gt;[&quot;ViewResolver&quot;]&lt;/span&gt;
    D &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; E&lt;span class=&quot;token text string&quot;&gt;[&quot;/WEB-INF/views/article/newArticleForm.jsp&quot;]&lt;/span&gt;
    E &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; F&lt;span class=&quot;token text string&quot;&gt;[&quot;사용자 form 입력 후 POST 전송&quot;]&lt;/span&gt;
    F &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; G&lt;span class=&quot;token text string&quot;&gt;[&quot;NewArticleController submit 메서드 실행&quot;]&lt;/span&gt;
    G &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; H&lt;span class=&quot;token text string&quot;&gt;[&quot;NewArticleCommand 객체 자동 바인딩&quot;]&lt;/span&gt;
    H &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; I&lt;span class=&quot;token text string&quot;&gt;[&quot;ArticleService writeArticle 호출&quot;]&lt;/span&gt;
    I &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; J&lt;span class=&quot;token text string&quot;&gt;[&quot;View 이름 반환&amp;lt;br/&gt;article/newArticleSubmitted&quot;]&lt;/span&gt;
    J &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; K&lt;span class=&quot;token text string&quot;&gt;[&quot;/WEB-INF/views/article/newArticleSubmitted.jsp&quot;]&lt;/span&gt;
    &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;정리&quot;&gt;정리&lt;/h2&gt;
&lt;p&gt;Spring MVC의 어노테이션 기반 설정을 사용하면 요청 처리 흐름을 선언적으로 작성할 수 있다.&lt;/p&gt;
&lt;p&gt;@Controller는 요청을 처리하는 컨트롤러 클래스를 등록한다.&lt;/p&gt;
&lt;p&gt;@RequestMapping은 공통 요청 URL을 지정한다.&lt;/p&gt;
&lt;p&gt;@GetMapping과 @PostMapping은 HTTP Method에 따라 실행될 메서드를 분리한다.&lt;/p&gt;
&lt;p&gt;@Service는 비즈니스 로직을 담당하는 Service 계층의 클래스를 Bean으로 등록하기 위해 사용한다.&lt;/p&gt;
&lt;p&gt;Controller는 생성자 주입을 통해 Service 객체를 전달받는다. 이를 통해 Controller와 Service의 역할을 분리할 수 있다.&lt;/p&gt;
&lt;p&gt;또한 Spring MVC는 form에서 전달된 요청 파라미터를 Command 객체에 자동으로 바인딩한다. 따라서 기존 Servlet 방식처럼 request.getParameter(), 객체 생성, setter 호출, RequestDispatcher.forward()를 반복해서 작성하지 않아도 된다.&lt;/p&gt;
&lt;p&gt;결과적으로 Spring MVC는 요청 매핑, 객체 생성, 의존성 주입, 데이터 바인딩, View 이동을 프레임워크 차원에서 처리해준다. 이를 통해 개발자는 핵심 로직과 계층 간 역할 분리에 더 집중할 수 있다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[Spring] MVC 파일 업로드 처리 흐름 정리]]></title><description><![CDATA[1. 개요 게시판 기능을 구현하다 보면 글 작성과 함께 이미지를 업로드해야 하는 경우가 있다. 예를 들어, 사용자가 게시글을 작성하면서 사진을 첨부하면, 서버는 사용자가 입력한 내용, 작성자 정보뿐만 아니라 첨부한 파일도 함께 처리해야 한다. 주의할 점: DB에 직접 저장하지 않을 것 ]]></description><link>https://woojin-devv.github.io/posts/Springmvc_basic_2/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Springmvc_basic_2/</guid><pubDate>Tue, 16 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;1-개요&quot;&gt;1. 개요&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;게시판 기능을 구현하다 보면 글 작성과 함께 이미지를 업로드해야 하는 경우가 있다. 예를 들어,
사용자가 게시글을 작성하면서 사진을 첨부하면, 서버는 사용자가 입력한 내용, 작성자 정보뿐만 아니라 첨부한 파일도
함께 처리해야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;주의할 점: DB에 직접 저장하지 않을 것&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;11-일반적인-파일-업로드-처리&quot;&gt;1.1 일반적인 파일 업로드 처리&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;실제 파일 -&gt; 웹 서버의 특정 폴더 혹은 AWS s3와 같은 파일 저장소에 저장&lt;/li&gt;
&lt;li&gt;파일 관련 정보 -&gt; DB에 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;예를 들어, 사용자가 1.jpg 파일을 업로드했다고 가정한다.
실제 이미지 파일은 서버의 &lt;code class=&quot;language-text&quot;&gt;/upload&lt;/code&gt; 폴더에 저장하고, DB에는 다음과 같은 정보만 저장한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;파일명&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;jpg
파일 크기&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12500&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;
파일 타입&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; image&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;jpeg
저장 경로&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;upload&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;jpg&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;즉, DB에는 파일 자체가 아니라 파일을 찾기 위한 정보를 저장한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;12-파일-업로드-처리-구조&quot;&gt;1.2 파일 업로드 처리 구조&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;파일 업로드 기능은 두 가지로 나눌 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;I/O 작업
&lt;ul&gt;
&lt;li&gt;업로드된 파일을 서버의 특정 경로에 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DB 작업
&lt;ul&gt;
&lt;li&gt;저장된 파일의 이름, 경로, 크기, 타입 등을 DB에 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이때 파일이 서버에 정상적으로 저장되어야 하고, 그 후에 DB에 파일 정보를 insert 해야 한다.&lt;/p&gt;
&lt;h3 id=&quot;13-파일-업로드-처리-흐름&quot;&gt;1.3 파일 업로드 처리 흐름&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;flowchart&lt;/span&gt; LR
    A&lt;span class=&quot;token text string&quot;&gt;[사용자 파일 업로드]&lt;/span&gt; &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; B&lt;span class=&quot;token text string&quot;&gt;[Spring MVC Controller에서&amp;lt;br&gt;파일 객체 받기]&lt;/span&gt;
    B &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; C&lt;span class=&quot;token text string&quot;&gt;[파일명, 크기, 타입 등&amp;lt;br&gt;파일 정보 추출]&lt;/span&gt;
    C &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; D&lt;span class=&quot;token text string&quot;&gt;[웹 서버의 upload 폴더에&amp;lt;br&gt;실제 파일 저장]&lt;/span&gt;
    D &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; E&lt;span class=&quot;token text string&quot;&gt;[DB에 파일 정보 저장]&lt;/span&gt;
    E &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt; F&lt;span class=&quot;token text string&quot;&gt;[결과 페이지 이동]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;14-파일에-직접-저장하지-않는-이유&quot;&gt;1.4 파일에 직접 저장하지 않는 이유&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파일을 DB에 직접 저장할 수 있다. 예를 들어 BLOB 타입을 사용하면 이미지나 파일 데이터를 DB에 저장할 수 있다.&lt;/li&gt;
&lt;li&gt;하지만, 일반적인 게시판에서는 파일 자체를 DB에 저장하기보다는, 파일은 별도의 저장소에 저장하고 DB에는 파일 정보만 저장하는 방식을 많이 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;2-spring-mvc에서-파일-업로드를-위한-dto&quot;&gt;2. Spring MVC에서 파일 업로드를 위한 DTO&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Spring MVC에서는 일반 form 데이터뿐만 아니라 파일 객체도 DTO로 받을 수 있다.&lt;/li&gt;
&lt;li&gt;예를 들어 다음과 같은 Photo DTO를 만들 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;com&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token import&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;org&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;springframework&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;web&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;multipart&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;commons&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;CommonsMultipartFile&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token annotation punctuation&quot;&gt;@Data&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Photo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; age&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// DB에 저장할 파일명&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; image&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 실제 업로드된 파일 객체&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CommonsMultipartFile&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;21--file-멤버-필드의-역할&quot;&gt;2.1  file 멤버 필드의 역할&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CommonsMultipartFile&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;file은 사용자가 업로드한 실제 파일 데이터를 받기 위한 필드이다.
&lt;ul&gt;
&lt;li&gt;JSP form에 다음과 같은 input이 존재한다고 가정하자.
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsp&quot;&gt;&lt;pre class=&quot;language-jsp&quot;&gt;&lt;code class=&quot;language-jsp&quot;&gt;  private CommonsMultipartFile file;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;이때, name = &quot;file&quot;과 DTO의 필드명 file이 동일하기 때문에 Spring이 자동으로 파일 객체를 바인딩해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;22-controller-자동-바인딩&quot;&gt;2.2 Controller 자동 바인딩&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@PostMapping&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Photo&lt;/span&gt; photo&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;CommonsMultipartFile&lt;/span&gt; file &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; photo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;컨트롤러에서 다음과 같이 받을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;23-jsp-form-작성&quot;&gt;2.3 JSP form 작성&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;파일 업로드를 하기 위해서는 form 태그에 반드시 enctype=&quot;multipart/form-data&quot;를 설정해야한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsp&quot;&gt;&lt;pre class=&quot;language-jsp&quot;&gt;&lt;code class=&quot;language-jsp&quot;&gt;&amp;lt;form action=&amp;quot;${pageContext.request.contextPath}/image/upload.do&amp;quot;
      method=&amp;quot;post&amp;quot;
      enctype=&amp;quot;multipart/form-data&amp;quot;&amp;gt;

    이름: &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;
    나이: &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;age&amp;quot;&amp;gt;&amp;lt;br&amp;gt;
    이미지: &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;file&amp;quot;&amp;gt;&amp;lt;br&amp;gt;

    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;업로드&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;전체-흐름&quot;&gt;전체 흐름&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;사용자가 form에서 파일 선택&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;multipart/form-data 방식으로 서버에 전송&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Spring이 DTO의 CommonsMultipartFile 필드에 파일 객체 자동 바인딩&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Controller에서 파일 객체 추출&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;서버의 upload 폴더에 실제 파일 저장&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;저장된 파일명을 DTO의 image 필드에 세팅&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DB에는 파일명, 경로, 크기, 타입 등 메타데이터 저장&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[[Spring] 소프트웨어 개발과 관심사의 분리]]></title><description><![CDATA[소프트웨어 개발과 관심사의 분리 1. 소프트웨어 설계의 핵심 소프트웨어 설계는 미래의 변화에 대비하는 작업 이다. 애플리케이션은 시간이 지나면서 계속 변화한다. 요구사항 변경 DB 변경 고객사별 환경 차이 기능 추가 및 수정 유지보수 비용 증가 따라서 좋은 코드는 변화에 대응하기 쉬운 ]]></description><link>https://woojin-devv.github.io/posts/Spring-preview/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Spring-preview/</guid><pubDate>Thu, 11 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h3 id=&quot;소프트웨어-개발과-관심사의-분리&quot;&gt;소프트웨어 개발과 관심사의 분리&lt;/h3&gt;
&lt;h3 id=&quot;1-소프트웨어-설계의-핵심&quot;&gt;1. 소프트웨어 설계의 핵심&lt;/h3&gt;
&lt;p&gt;소프트웨어 설계는 &lt;strong&gt;미래의 변화에 대비하는 작업&lt;/strong&gt;이다.&lt;/p&gt;
&lt;p&gt;애플리케이션은 시간이 지나면서 계속 변화한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;요구사항 변경&lt;/li&gt;
&lt;li&gt;DB 변경&lt;/li&gt;
&lt;li&gt;고객사별 환경 차이&lt;/li&gt;
&lt;li&gt;기능 추가 및 수정&lt;/li&gt;
&lt;li&gt;유지보수 비용 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;따라서 좋은 코드는 &lt;strong&gt;변화에 대응하기 쉬운 코드&lt;/strong&gt;여야 한다.&lt;/p&gt;
&lt;h3 id=&quot;2-관심사의-분리&quot;&gt;2. 관심사의 분리&lt;/h3&gt;
&lt;h3 id=&quot;관심사란&quot;&gt;관심사란?&lt;/h3&gt;
&lt;p&gt;관심사는 클래스나 메서드가 담당하는 &lt;strong&gt;역할 또는 책임&lt;/strong&gt;을 의미한다.&lt;/p&gt;
&lt;p&gt;예를 들어 &lt;code class=&quot;language-text&quot;&gt;UserDao&lt;/code&gt; 클래스에는 다음과 같은 관심사가 섞여 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;UserDao
├── DB 연결 작업
├── 데이터 작업(add, get)
└── 자원 해제 작업&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-기존-userdao의-문제점&quot;&gt;3. 기존 UserDao의 문제점&lt;/h3&gt;
&lt;h3 id=&quot;문제-1-db-연결-코드-중복&quot;&gt;문제 1. DB 연결 코드 중복&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;add()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;get()&lt;/code&gt; 메서드마다 DB 연결 코드가 반복된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;oracle.jdbc.OracleDriver&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;Connection&lt;/span&gt; c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DriverManager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getConnection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이런 코드가 여러 메서드에 중복되면 다음과 같은 문제가 생긴다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DB 접속 정보가 바뀌면 여러 곳을 수정해야 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;코드가 길어지고 가독성이 떨어진다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;유지보수가 어려워진다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;실수로 일부 메서드만 수정하지 못할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;4-해결-방법-1-리팩토링&quot;&gt;4. 해결 방법 1: 리팩토링&lt;/h3&gt;
&lt;p&gt;중복된 관심사는 하나로 모은다.&lt;/p&gt;
&lt;p&gt;DB 연결 코드를 &lt;code class=&quot;language-text&quot;&gt;getConnection()&lt;/code&gt; 메서드로 분리한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Connection&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getConnection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassNotFoundException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SQLException&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;oracle.jdbc.OracleDriver&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DriverManager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getConnection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; user&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이후 &lt;code class=&quot;language-text&quot;&gt;add()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;get()&lt;/code&gt;에서는 공통 메서드를 사용한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Connection&lt;/span&gt; c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getConnection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;5-리팩토링이란&quot;&gt;5. 리팩토링이란?&lt;/h3&gt;
&lt;p&gt;리팩토링은 &lt;strong&gt;외부 동작은 그대로 유지하면서 내부 구조를 개선하는 작업&lt;/strong&gt;이다.&lt;/p&gt;
&lt;p&gt;즉, 사용자가 보는 기능은 변하지 않지만 코드 구조를 더 좋게 바꾸는 것이다.&lt;/p&gt;
&lt;h3 id=&quot;리팩토링-목적&quot;&gt;리팩토링 목적&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;중복 제거&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;가독성 향상&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;유지보수성 향상&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;변경에 강한 구조 만들기&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;6-예외-처리와-자원-해제&quot;&gt;6. 예외 처리와 자원 해제&lt;/h3&gt;
&lt;p&gt;DB 연결, &lt;code class=&quot;language-text&quot;&gt;PreparedStatement&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;ResultSet&lt;/code&gt; 같은 자원은 사용 후 반드시 해제해야 한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;rs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ps&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;자원을 사용하는 쪽에서 예외를 강제 처리하도록 하는 것이 일반적이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassNotFoundException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SQLException&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;12-요구사항-변화&quot;&gt;1.2 요구사항 변화&lt;/h2&gt;
&lt;h3 id=&quot;새로운-요구사항&quot;&gt;새로운 요구사항&lt;/h3&gt;
&lt;p&gt;소프트웨어를 여러 고객사에 판매해야 하는 상황이 발생했다.&lt;/p&gt;
&lt;p&gt;고객사마다 사용하는 DB가 다르다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;N사 -&gt; Oracle 사용
D사 -&gt; MySQL 사용&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;문제는 DB마다 연결 방식이 다르다는 점이다.&lt;/p&gt;
&lt;p&gt;또한 사장님(가상 시나리오)의 요구사항은 다음과 같다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;UserDao 클래스의 핵심 소스는 외부에 노출되면 안 된다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;변경되는-부분과-유지되는-부분&quot;&gt;변경되는 부분과 유지되는 부분&lt;/h3&gt;
&lt;h3 id=&quot;유지되어야-하는-코드&quot;&gt;유지되어야 하는 코드&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;UserDao&lt;/code&gt;의 핵심 기능은 그대로 유지되어야 한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;변경되는-코드&quot;&gt;변경되는 코드&lt;/h3&gt;
&lt;p&gt;DB 연결 방식만 고객사마다 달라진다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token function&quot;&gt;getConnection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;즉, 변화하는 부분은 &lt;strong&gt;DB 연결 코드&lt;/strong&gt;이고, 변화하지 않는 부분은 &lt;strong&gt;데이터 처리 로직&lt;/strong&gt;이다.&lt;/p&gt;
&lt;h2 id=&quot;해결-방법-2-상속-사용&quot;&gt;해결 방법 2: 상속 사용&lt;/h2&gt;
&lt;h3 id=&quot;구조&quot;&gt;구조&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;UserDao&lt;/code&gt;를 추상 클래스로 만들고, DB 연결 메서드를 추상 메서드로 만든다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;UserDao 추상 클래스
├── add()
├── get()
└── getConnection() 추상 메서드&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;각 고객사는 &lt;code class=&quot;language-text&quot;&gt;UserDao&lt;/code&gt;를 상속받아 자신에게 맞는 DB 연결 방식을 구현한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;NUserDao -&gt; Oracle 연결 구현
DUserDao -&gt; MySQL 연결 구현&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;예시-구조&quot;&gt;예시 구조&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;UserDao
├── NUserDao
└── DUserDao&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;UserDao&lt;/code&gt;는 공통 로직을 담당한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;add()
get()&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;각 하위 클래스는 DB 연결 로직만 담당한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;getConnection()&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;program-코드-변경&quot;&gt;Program 코드 변경&lt;/h3&gt;
&lt;p&gt;사용자는 필요한 DB에 맞는 DAO 객체를 선택해서 사용한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;UserDao&lt;/span&gt; dao &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NUserDao&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;또는&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;UserDao&lt;/span&gt; dao &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DUserDao&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;상속-방식의-문제점&quot;&gt;상속 방식의 문제점&lt;/h2&gt;
&lt;h3 id=&quot;문제-1-자바는-단일-상속만-지원한다&quot;&gt;문제 1. 자바는 단일 상속만 지원한다&lt;/h3&gt;
&lt;p&gt;자바 클래스는 하나의 클래스만 상속할 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NUserDao&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UserDao&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이미 &lt;code class=&quot;language-text&quot;&gt;UserDao&lt;/code&gt;를 상속하고 있으면 다른 클래스를 추가로 상속할 수 없다.&lt;/p&gt;
&lt;h3 id=&quot;문제-2-부모와-자식-클래스의-결합도가-높다&quot;&gt;문제 2. 부모와 자식 클래스의 결합도가 높다&lt;/h3&gt;
&lt;p&gt;상속 관계에서는 부모 클래스와 자식 클래스가 강하게 연결된다.&lt;/p&gt;
&lt;p&gt;부모 클래스가 변경되면 자식 클래스도 영향을 받을 가능성이 높다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;부모 클래스 변경
-&gt; 자식 클래스 영향
-&gt; 유지보수 부담 증가&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;즉, 상속은 코드 재사용에는 도움이 되지만, 구조가 강하게 묶이는 문제가 있다.&lt;/p&gt;
&lt;h2 id=&quot;다음-개선-방향&quot;&gt;다음 개선 방향&lt;/h2&gt;
&lt;p&gt;상속 관계를 줄이고, 더 유연한 구조로 바꿔야 한다.&lt;/p&gt;
&lt;p&gt;핵심은 다음과 같다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;상속 관계를 파괴하자.
그러면서도 고객사별 DB 연결 요구사항은 만족하자.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이를 위해 생각해야 할 개념은 다음 두 가지다.&lt;/p&gt;
&lt;h3 id=&quot;is-a-관계&quot;&gt;is-a 관계&lt;/h3&gt;
&lt;p&gt;상속 관계이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;NUserDao is a UserDao&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;즉, &lt;code class=&quot;language-text&quot;&gt;NUserDao&lt;/code&gt;는 &lt;code class=&quot;language-text&quot;&gt;UserDao&lt;/code&gt;의 한 종류라는 의미이다.&lt;/p&gt;
&lt;h3 id=&quot;has-a-관계&quot;&gt;has-a 관계&lt;/h3&gt;
&lt;p&gt;포함 관계이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;UserDao has a ConnectionMaker&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;즉, &lt;code class=&quot;language-text&quot;&gt;UserDao&lt;/code&gt;가 DB 연결 기능을 직접 상속받는 것이 아니라, DB 연결 객체를 내부에 가지고 사용하는 구조이다.&lt;/p&gt;
&lt;h1 id=&quot;spring이-선호하는-구조&quot;&gt;Spring이 선호하는 구조&lt;/h1&gt;
&lt;p&gt;Spring은 상속보다 다음 구조를 선호한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;인터페이스 + 다형성 + 조합&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;즉, 변하는 부분을 인터페이스로 분리하고, 실제 구현체는 외부에서 주입받는 방식이다.&lt;/p&gt;
&lt;p&gt;이 구조는 이후 Spring의 핵심 개념인 다음 내용으로 이어진다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;DI, Dependency Injection
의존성 주입&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;정리&quot;&gt;정리&lt;/h2&gt;
&lt;h3 id=&quot;현재까지의-흐름&quot;&gt;현재까지의 흐름&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;1. UserDao 안에 DB 연결 코드가 중복됨
2. getConnection() 메서드로 분리하여 리팩토링
3. 고객사마다 DB 연결 방식이 달라지는 요구사항 발생
4. 상속을 이용해 고객사별 DAO 구현
5. 하지만 상속은 단일 상속과 강한 결합 문제가 있음
6. 상속 대신 인터페이스와 다형성을 사용하는 구조로 개선 필요&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[Project Review] Zustand 활용기]]></title><description><![CDATA[들어가며 RentSignal은 왼쪽 패널에서 지역과 지표를 선택하면 오른쪽 Kakao Map이 즉시 반응하는 구조다. 예를 들어 다음과 같은 상호작용이 있다. 홈의 추천 지역을 클릭하면 해당 동의 폴리곤을 지도에 표시한다. 지하철 접근성 순위를 클릭하면 해당 구를 확대하고 강조한다. 정]]></description><link>https://woojin-devv.github.io/posts/zustand-1/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/zustand-1/</guid><pubDate>Sun, 07 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;들어가며&quot;&gt;들어가며&lt;/h2&gt;
&lt;p&gt;RentSignal은 왼쪽 패널에서 지역과 지표를 선택하면 오른쪽 Kakao Map이 즉시 반응하는 구조다.&lt;/p&gt;
&lt;p&gt;예를 들어 다음과 같은 상호작용이 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;홈의 추천 지역을 클릭하면 해당 동의 폴리곤을 지도에 표시한다.&lt;/li&gt;
&lt;li&gt;지하철 접근성 순위를 클릭하면 해당 구를 확대하고 강조한다.&lt;/li&gt;
&lt;li&gt;정보 탭에서 전월세 지수, 안전도, 편의시설을 선택하면 지도 오버레이가 변경된다.&lt;/li&gt;
&lt;li&gt;프로필과 추천 페이지는 동일한 로그인 사용자 정보를 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 상태를 각 컴포넌트의 &lt;code class=&quot;language-text&quot;&gt;useState&lt;/code&gt;와 props만으로 관리하면 패널, 레이아웃, 지도 사이에 긴 props 전달 구조가 생긴다. RentSignal에서는 이런 문제를 줄이기 위해 Zustand를 사용했다.&lt;/p&gt;
&lt;p&gt;현재 프로젝트의 Zustand 스토어는 크게 두 가지다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;스토어&lt;/th&gt;
&lt;th&gt;역할&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;userStore&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;로그인 사용자 정보 조회, 저장, 초기화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;mapOverlayStore&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;지도에 표시할 폴리곤, 마커, 노선, 선택 지역 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;zustand를-선택한-이유&quot;&gt;Zustand를 선택한 이유&lt;/h2&gt;
&lt;p&gt;이 프로젝트에서 필요한 전역 상태 관리는 복잡한 비즈니스 로직보다 &lt;strong&gt;멀리 떨어진 컴포넌트 사이의 상태 공유&lt;/strong&gt;에 가깝다.&lt;/p&gt;
&lt;p&gt;Zustand는 다음 이유로 현재 구조에 잘 맞았다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;별도의 Provider 없이 어디서든 스토어를 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;상태와 액션을 하나의 파일에 간결하게 정의할 수 있다.&lt;/li&gt;
&lt;li&gt;selector를 사용해 필요한 상태만 구독할 수 있다.&lt;/li&gt;
&lt;li&gt;TypeScript 타입을 스토어 계약으로 활용하기 쉽다.&lt;/li&gt;
&lt;li&gt;지도처럼 React 외부 객체를 제어할 때 명령을 전달하는 중간 계층으로 사용하기 좋다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;프로젝트에서는 &lt;code class=&quot;language-text&quot;&gt;zustand@5&lt;/code&gt;와 React 19를 사용하고 있다.&lt;/p&gt;
&lt;h2 id=&quot;전체-데이터-흐름&quot;&gt;전체 데이터 흐름&lt;/h2&gt;
&lt;p&gt;지도 관련 상태는 패널 컴포넌트가 변경하고, &lt;code class=&quot;language-text&quot;&gt;Map&lt;/code&gt; 컴포넌트가 이를 구독하여 실제 Kakao Map 객체에 반영한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;flowchart&lt;/span&gt; LR
  A&lt;span class=&quot;token text string&quot;&gt;[&quot;Home / Info 패널&quot;]&lt;/span&gt; &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;&lt;span class=&quot;token label property&quot;&gt;|&quot;액션 호출&quot;|&lt;/span&gt; B&lt;span class=&quot;token text string&quot;&gt;[&quot;mapOverlayStore&quot;]&lt;/span&gt;
  B &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;&lt;span class=&quot;token label property&quot;&gt;|&quot;selector 구독&quot;|&lt;/span&gt; C&lt;span class=&quot;token text string&quot;&gt;[&quot;Map 컴포넌트&quot;]&lt;/span&gt;
  C &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;&lt;span class=&quot;token label property&quot;&gt;|&quot;Polygon / Marker 생성&quot;|&lt;/span&gt; D&lt;span class=&quot;token text string&quot;&gt;[&quot;Kakao Map&quot;]&lt;/span&gt;
  C &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;&lt;span class=&quot;token label property&quot;&gt;|&quot;effect cleanup&quot;|&lt;/span&gt; E&lt;span class=&quot;token text string&quot;&gt;[&quot;기존 오버레이 제거&quot;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;핵심은 Zustand에 Kakao Map 인스턴스나 폴리곤 객체 자체를 저장하지 않는다는 점이다.&lt;/p&gt;
&lt;p&gt;스토어에는 아래처럼 &lt;strong&gt;지도에 무엇을 표현할지 설명하는 직렬화 가능한 데이터&lt;/strong&gt;를 저장한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ConvenienceMapPin&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  latitude&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  longitude&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SubwayLinePolyline&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  lineName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  color&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  path&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    latitude&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    longitude&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;실제 &lt;code class=&quot;language-text&quot;&gt;kakao.maps.Polygon&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;kakao.maps.Marker&lt;/code&gt; 등의 객체는 &lt;code class=&quot;language-text&quot;&gt;Map&lt;/code&gt; 컴포넌트의 ref에서 관리한다.&lt;/p&gt;
&lt;h2 id=&quot;1-사용자-상태-관리&quot;&gt;1. 사용자 상태 관리&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;userStore&lt;/code&gt;는 사용자 정보와 사용자 정보를 갱신하는 액션을 함께 관리한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  imageUrl&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  role&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UserStore&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  user&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; User &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;fetchUser&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;clearUser&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; useUserStore &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token generic-function&quot;&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;UserStore&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;set&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  user&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;token function-variable function&quot;&gt;fetchUser&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; profile &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getMyProfile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; user&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; profile &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;token function-variable function&quot;&gt;clearUser&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; user&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;비동기-액션을-스토어에-둔-이유&quot;&gt;비동기 액션을 스토어에 둔 이유&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;fetchUser&lt;/code&gt; 내부에서 사용자 조회 API를 호출하고 결과를 바로 저장한다. 사용하는 컴포넌트는 API 응답 구조나 저장 방식을 알 필요가 없다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; user &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useUserStore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fetchUser &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useUserStore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fetchUser&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; clearUser &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useUserStore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clearUser&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이 패턴은 다음 화면에서 재사용된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Profile&lt;/code&gt;: 사용자 정보를 표시하고 로그아웃 시 상태를 초기화한다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Recommend&lt;/code&gt;: 사용자 권한을 확인해 로그인 또는 휴대전화 인증 모달을 연다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PhoneModal&lt;/code&gt;: 인증 완료 후 사용자 정보를 다시 조회한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;로그아웃 흐름도 단순하다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;handleLogout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;logout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;clearUser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;navigate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;서버의 로그아웃 처리와 클라이언트 사용자 상태 초기화를 분리하면서도, UI에서는 하나의 명확한 흐름으로 사용할 수 있다.&lt;/p&gt;
&lt;h2 id=&quot;2-지도-오버레이-상태-관리&quot;&gt;2. 지도 오버레이 상태 관리&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;mapOverlayStore&lt;/code&gt;는 사용자 인터페이스와 지도 사이의 통신 채널 역할을 한다.&lt;/p&gt;
&lt;p&gt;대표 상태는 다음과 같다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;상태&lt;/th&gt;
&lt;th&gt;지도 표현&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;rentIndexItems&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;전월세 지수 오버레이&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;consumerIndexItem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;소비자 심리지수 권역 폴리곤&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;subwayIndexItems&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;구별 지하철 역세권 지수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;safetyIndexItems&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;구별 안전도 오버레이&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;selectedHomeRecommendationName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;홈 추천 동 폴리곤&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;selectedHomeSubwayRanking&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;홈 지하철 순위 구 폴리곤&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;selectedTransportNeighborhoodName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;선택한 교통 추천 동&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;subwayLinePolylines&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;지하철 노선&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;subwayStationMarkers&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;지하철역 마커&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;conveniencePins&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;편의시설 위치 마커&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;스토어 액션 이름은 &lt;code class=&quot;language-text&quot;&gt;set&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;select&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;clear&lt;/code&gt;로 역할을 구분했다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token function-variable function&quot;&gt;setSubwayIndexItems&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;items&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; subwayIndexItems&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; items &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token function-variable function&quot;&gt;clearSubwayIndexItems&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; subwayIndexItems&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

&lt;span class=&quot;token function-variable function&quot;&gt;selectTransportNeighborhood&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; selectedTransportNeighborhoodName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; name &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token function-variable function&quot;&gt;clearSelectedTransportNeighborhood&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; selectedTransportNeighborhoodName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이름만 보아도 목록 전체를 설정하는지, 하나를 선택하는지, 상태를 정리하는지 알 수 있다.&lt;/p&gt;
&lt;h2 id=&quot;3-패널에서-지도에-명령-전달하기&quot;&gt;3. 패널에서 지도에 명령 전달하기&lt;/h2&gt;
&lt;p&gt;홈의 추천 지역 카드를 클릭하면 컴포넌트가 직접 Kakao Map을 조작하지 않는다. 대신 선택한 지역명을 스토어에 저장한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; selectHomeRecommendation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useMapOverlayStore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selectHomeRecommendation&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;RecommendationCard
  neighborhoodName&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;recommendation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dongName&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  onClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;selectHomeRecommendation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;recommendation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dongName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Map&lt;/code&gt; 컴포넌트는 선택 상태만 구독한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; selectedHomeRecommendationName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useMapOverlayStore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selectedHomeRecommendationName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;상태가 바뀌면 effect에서 GeoJSON을 기준으로 폴리곤을 생성하고 지도를 이동한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;isMapReady &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;mapRefInstance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;drawSelectedHomeRecommendationPolygon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    mapRefInstance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    selectedHomeRecommendationName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;clearSelectedHomeRecommendationPolygons&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;isMapReady&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; selectedHomeRecommendationName&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이 구조 덕분에 패널은 &lt;strong&gt;무엇을 선택했는지&lt;/strong&gt;만 알고, 지도는 &lt;strong&gt;어떻게 그릴지&lt;/strong&gt;만 책임진다.&lt;/p&gt;
&lt;h2 id=&quot;4-상호-배타적인-선택-상태&quot;&gt;4. 상호 배타적인 선택 상태&lt;/h2&gt;
&lt;p&gt;홈에서는 추천 동 폴리곤과 지하철 순위 구 폴리곤이 동시에 남아 있으면 사용자에게 혼란을 줄 수 있다.&lt;/p&gt;
&lt;p&gt;이를 컴포넌트에서 각각 정리하지 않고 스토어 액션에서 처리했다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token function-variable function&quot;&gt;selectHomeRecommendation&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    selectedHomeRecommendationName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    selectedHomeSubwayRanking&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

&lt;span class=&quot;token function-variable function&quot;&gt;selectHomeSubwayRanking&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    selectedHomeSubwayRanking&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    selectedHomeRecommendationName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;추천 지역을 선택하면 지하철 순위 선택이 해제되고, 지하철 순위를 선택하면 추천 지역 선택이 해제된다.&lt;/p&gt;
&lt;p&gt;이처럼 서로 영향을 주는 상태는 액션 내부에서 함께 변경하면 UI 컴포넌트마다 동일한 정리 로직을 반복하지 않아도 된다.&lt;/p&gt;
&lt;h2 id=&quot;5-selector로-필요한-상태만-구독하기&quot;&gt;5. selector로 필요한 상태만 구독하기&lt;/h2&gt;
&lt;p&gt;스토어 전체를 가져오는 대신 각 컴포넌트가 필요한 값이나 액션만 selector로 구독한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; conveniencePins &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useMapOverlayStore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;conveniencePins&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; clearConveniencePins &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useMapOverlayStore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clearConveniencePins&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이 방식의 장점은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컴포넌트의 의존성이 코드에 명확하게 드러난다.&lt;/li&gt;
&lt;li&gt;관련 없는 상태 변경으로 인한 렌더링을 줄일 수 있다.&lt;/li&gt;
&lt;li&gt;테스트하거나 리팩터링할 때 사용하는 상태 범위를 빠르게 파악할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;특히 여러 지도 기능을 한 컴포넌트에서 처리하는 현재 구조에서는 선택적 구독이 중요하다.&lt;/p&gt;
&lt;h2 id=&quot;6-화면-상태와-전역-상태를-구분하기&quot;&gt;6. 화면 상태와 전역 상태를 구분하기&lt;/h2&gt;
&lt;p&gt;모든 상태를 Zustand에 넣지는 않았다.&lt;/p&gt;
&lt;p&gt;예를 들어 API 로딩 여부, 에러 메시지, 현재 탭처럼 특정 화면에서만 사용하는 상태는 로컬 &lt;code class=&quot;language-text&quot;&gt;useState&lt;/code&gt;로 관리한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;isLoading&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setIsLoading&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;errorMessage&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setErrorMessage&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;currentRankings&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setCurrentRankings&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;반면 조회 결과를 지도에서도 사용해야 할 때만 필요한 데이터 형태로 변환해 전역 스토어에 전달한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; rankings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetchRentIndexRankings&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;residenceType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;setCurrentRankings&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rankings&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;setRentIndexMapItems&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  rankings&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;CURRENT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;정리하면 기준은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;한 컴포넌트 안에서만 필요하다면 &lt;code class=&quot;language-text&quot;&gt;useState&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;서로 멀리 떨어진 패널과 지도에서 공유한다면 Zustand&lt;/li&gt;
&lt;li&gt;URL로 표현해야 하는 화면 상태라면 React Router&lt;/li&gt;
&lt;li&gt;서버 캐시, 재시도, stale 관리가 중요하다면 서버 상태 라이브러리 검토&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Zustand를 모든 상태의 저장소로 사용하지 않고, 컴포넌트 경계를 넘는 클라이언트 상태에 집중했다.&lt;/p&gt;
&lt;h2 id=&quot;7-cleanup이-중요한-이유&quot;&gt;7. cleanup이 중요한 이유&lt;/h2&gt;
&lt;p&gt;지도 오버레이는 React DOM 요소가 아니기 때문에 컴포넌트가 사라진다고 자동으로 제거되지 않는다.&lt;/p&gt;
&lt;p&gt;따라서 상태를 초기화하는 것과 실제 Kakao Map 객체를 제거하는 작업이 모두 필요하다.&lt;/p&gt;
&lt;h3 id=&quot;스토어-상태-정리&quot;&gt;스토어 상태 정리&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;clearSubwayIndexMapItems&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;clearSubwayIndexMapItems&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;지도-객체-정리&quot;&gt;지도 객체 정리&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;clearSubwayIndexOverlays&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  subwayIndexOverlaysRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;overlay&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  subwayIndexOverlaysRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;drawSubwayIndexOverlays&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mapRefInstance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; subwayIndexItems&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;clearSubwayIndexOverlays&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;isMapReady&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; subwayIndexItems&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이 cleanup이 빠지면 탭을 이동하거나 다른 지역을 선택했을 때 이전 폴리곤과 마커가 지도에 계속 남을 수 있다.&lt;/p&gt;
&lt;h2 id=&quot;8-zustand를-사용하며-얻은-효과&quot;&gt;8. Zustand를 사용하며 얻은 효과&lt;/h2&gt;
&lt;h3 id=&quot;props-drilling-제거&quot;&gt;Props drilling 제거&lt;/h3&gt;
&lt;p&gt;패널에서 발생한 클릭 이벤트를 &lt;code class=&quot;language-text&quot;&gt;MainLayout&lt;/code&gt;을 거쳐 &lt;code class=&quot;language-text&quot;&gt;Map&lt;/code&gt;까지 전달할 필요가 없어졌다.&lt;/p&gt;
&lt;h3 id=&quot;ui와-지도-구현-분리&quot;&gt;UI와 지도 구현 분리&lt;/h3&gt;
&lt;p&gt;패널은 선택 상태를 만들고, 지도는 해당 상태를 시각화한다. 두 영역의 책임이 분리됐다.&lt;/p&gt;
&lt;h3 id=&quot;지도-기능-확장-용이&quot;&gt;지도 기능 확장 용이&lt;/h3&gt;
&lt;p&gt;새로운 지도 기능을 추가할 때 아래 흐름으로 확장할 수 있다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;스토어에 표현 데이터를 위한 타입과 상태를 추가한다.&lt;/li&gt;
&lt;li&gt;상태를 변경하는 액션과 초기화 액션을 추가한다.&lt;/li&gt;
&lt;li&gt;패널에서 액션을 호출한다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Map&lt;/code&gt;에서 상태를 구독하고 effect로 오버레이를 그린다.&lt;/li&gt;
&lt;li&gt;effect cleanup에서 기존 지도 객체를 제거한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;상태-변화-추적-용이&quot;&gt;상태 변화 추적 용이&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;selectHomeRecommendation&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;setConveniencePins&lt;/code&gt;처럼 도메인이 드러나는 액션명을 사용해 어떤 사용자 행동이 지도 변경으로 이어지는지 파악하기 쉬워졌다.&lt;/p&gt;
&lt;h2 id=&quot;9-현재-구조에서-개선할-점&quot;&gt;9. 현재 구조에서 개선할 점&lt;/h2&gt;
&lt;p&gt;현재 방식은 잘 동작하지만 기능이 늘면서 &lt;code class=&quot;language-text&quot;&gt;mapOverlayStore&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;Map.tsx&lt;/code&gt;가 커지고 있다.&lt;/p&gt;
&lt;h3 id=&quot;지도-도메인별-slice-분리&quot;&gt;지도 도메인별 slice 분리&lt;/h3&gt;
&lt;p&gt;다음처럼 역할별 slice로 나누는 방식을 고려할 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;mapOverlayStore
├── homeOverlaySlice
├── rentIndexOverlaySlice
├── transportOverlaySlice
├── safetyOverlaySlice
└── convenienceOverlaySlice&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;하나의 스토어를 유지하더라도 타입과 액션 생성 로직을 파일별로 나누면 변경 범위를 줄일 수 있다.&lt;/p&gt;
&lt;h3 id=&quot;전체-초기화-액션-추가&quot;&gt;전체 초기화 액션 추가&lt;/h3&gt;
&lt;p&gt;라우트 이동 시 여러 clear 액션을 각각 호출하는 대신 아래와 같은 액션을 둘 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token function-variable function&quot;&gt;clearAllMapOverlays&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    rentIndexItems&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    subwayIndexItems&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    safetyIndexItems&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    selectedHomeRecommendationName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    selectedHomeSubwayRanking&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    conveniencePins&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;다만 모든 화면 전환에서 전체 초기화가 필요한 것은 아니므로, 실제 라우트 정책을 정한 뒤 도입하는 편이 좋다.&lt;/p&gt;
&lt;h3 id=&quot;서버-상태와-클라이언트-상태-분리&quot;&gt;서버 상태와 클라이언트 상태 분리&lt;/h3&gt;
&lt;p&gt;현재 &lt;code class=&quot;language-text&quot;&gt;userStore&lt;/code&gt;의 &lt;code class=&quot;language-text&quot;&gt;fetchUser&lt;/code&gt;는 API 호출과 전역 상태 저장을 함께 처리한다. 규모가 커져 캐싱, 중복 요청 제거, 재시도가 필요해지면 TanStack Query 같은 서버 상태 도구와 역할을 나눌 수 있다.&lt;/p&gt;
&lt;p&gt;이 경우 Zustand는 로그인 사용자 스냅샷이나 UI 선택 상태를 담당하고, 서버 응답 캐시는 Query가 담당하게 된다.&lt;/p&gt;
&lt;h3 id=&quot;지도-렌더링-훅-분리&quot;&gt;지도 렌더링 훅 분리&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Map.tsx&lt;/code&gt;의 effect와 draw 함수가 계속 늘어난다면 아래처럼 기능별 훅으로 분리할 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;useHomeMapOverlay
useRentIndexMapOverlay
useTransportMapOverlay
useConvenienceMapOverlay&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Zustand 구독과 Kakao Map 객체 생명주기를 기능 단위로 묶으면 &lt;code class=&quot;language-text&quot;&gt;Map&lt;/code&gt; 컴포넌트는 지도 초기화와 조합에 집중할 수 있다.&lt;/p&gt;
&lt;h2 id=&quot;마무리&quot;&gt;마무리&lt;/h2&gt;
&lt;p&gt;RentSignal에서 Zustand는 단순한 전역 변수 저장소보다 &lt;strong&gt;패널의 사용자 선택을 지도 렌더링 명령으로 전달하는 연결 계층&lt;/strong&gt;에 가깝다.&lt;/p&gt;
&lt;p&gt;이번 구조에서 중요했던 원칙은 다음과 같다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;스토어에는 Kakao Map 객체가 아니라 표현에 필요한 데이터를 저장한다.&lt;/li&gt;
&lt;li&gt;컴포넌트는 selector로 필요한 상태만 구독한다.&lt;/li&gt;
&lt;li&gt;화면 전용 상태와 전역 공유 상태를 구분한다.&lt;/li&gt;
&lt;li&gt;상호 배타 상태는 스토어 액션에서 함께 처리한다.&lt;/li&gt;
&lt;li&gt;상태 초기화와 지도 객체 cleanup을 모두 구현한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Zustand의 장점은 코드가 짧다는 데만 있지 않다. 어떤 상태가 컴포넌트 경계를 넘어야 하는지 정하고, 상태를 만드는 영역과 사용하는 영역의 책임을 분리할 때 가장 큰 효과를 얻을 수 있었다.&lt;/p&gt;
&lt;h2 id=&quot;관련-코드&quot;&gt;관련 코드&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;src/store/userStore.ts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;src/store/mapOverlayStore.ts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;src/components/Map.tsx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;src/pages/Home.tsx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;src/pages/Profile.tsx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;src/pages/Recommend.tsx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;src/components/Info/InfoSection.tsx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;src/hooks/useRentIndexRankings.ts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;src/hooks/useConsumerIndex.ts&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[JS] Event]]></title><description><![CDATA[JavaScript Event 정리 JavaScript에서 이벤트(Event) 는 사용자의 동작이나 브라우저의 상태 변화에 반응하여 특정 코드를 실행하는 방식이다. 예를 들어 사용자가 버튼을 클릭하거나, input에 커서를 올리거나, 페이지 로딩이 끝났을 때 JavaScript 함수를 ]]></description><link>https://woojin-devv.github.io/posts/js-event/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/js-event/</guid><pubDate>Tue, 26 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;javascript-event-정리&quot;&gt;JavaScript Event 정리&lt;/h1&gt;
&lt;p&gt;JavaScript에서 **이벤트(Event)**는 사용자의 동작이나 브라우저의 상태 변화에 반응하여 특정 코드를 실행하는 방식이다.&lt;/p&gt;
&lt;p&gt;예를 들어 사용자가 버튼을 클릭하거나, input에 커서를 올리거나, 페이지 로딩이 끝났을 때 JavaScript 함수를 실행할 수 있다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;참고: &lt;a href=&quot;https://www.w3schools.com/js/js_events.asp&quot;&gt;W3Schools - JavaScript Events&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&quot;1-대표적인-html-events&quot;&gt;1. 대표적인 HTML Events&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;Event&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;발생 시점&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;onchange&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;HTML 요소의 값이 변경되었을 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;onclick&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;사용자가 HTML 요소를 클릭했을 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;onmouseover&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;마우스가 HTML 요소 위로 올라갔을 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;onmouseout&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;마우스가 HTML 요소 밖으로 나갔을 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;onkeydown&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;사용자가 키보드 키를 눌렀을 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;onload&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;브라우저가 페이지 로딩을 완료했을 때&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;onload&lt;/code&gt; 이벤트가 발생한 이후에는 HTML의 정적 요소들이 메모리에 올라와 있다고 볼 수 있다. 따라서 페이지가 모두 준비된 뒤 실행해야 하는 초기 작업을 처리할 때 사용한다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;2-주요-event-예제&quot;&gt;2. 주요 Event 예제&lt;/h2&gt;
&lt;h3 id=&quot;1-onload&quot;&gt;1) &lt;code class=&quot;language-text&quot;&gt;onload&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;onload&lt;/code&gt;는 페이지 로딩이 끝난 뒤 실행된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onload&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bodyLoad&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bodyLoad&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;loading ....&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;myform&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;money&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isNaN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 코드에서는 페이지가 모두 로딩된 후 &lt;code class=&quot;language-text&quot;&gt;bodyLoad()&lt;/code&gt; 함수가 실행된다. 이후 &lt;code class=&quot;language-text&quot;&gt;name=&quot;money&quot;&lt;/code&gt;인 input 값을 가져와 숫자인지 확인한다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;2-onfocus&quot;&gt;2) &lt;code class=&quot;language-text&quot;&gt;onfocus&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;onfocus&lt;/code&gt;는 input 요소에 커서가 들어왔을 때 발생한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;myinput&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onfocus&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;focusFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;focusFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;myinput&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;background &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gold&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;입력창을 클릭하거나 선택하면 해당 input의 배경색이 &lt;code class=&quot;language-text&quot;&gt;gold&lt;/code&gt;로 변경된다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;3-onblur&quot;&gt;3) &lt;code class=&quot;language-text&quot;&gt;onblur&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;onblur&lt;/code&gt;는 input 요소에서 커서가 빠져나갔을 때 발생한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;myinput&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onblur&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;blurFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;blurFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;myinput&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;background &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;white&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;선택이 해제되면 input의 배경색이 다시 &lt;code class=&quot;language-text&quot;&gt;white&lt;/code&gt;로 변경된다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;4-onchange&quot;&gt;4) &lt;code class=&quot;language-text&quot;&gt;onchange&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;onchange&lt;/code&gt;는 select, input 등의 값이 변경되었을 때 발생한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;select&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;sel&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onchange&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;selectTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;selectTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;myform&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;select 태그에서 다른 option을 선택하면 &lt;code class=&quot;language-text&quot;&gt;selectTag()&lt;/code&gt; 함수가 실행되고, 현재 선택된 값이 alert로 출력된다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;3-this의-활용&quot;&gt;3. &lt;code class=&quot;language-text&quot;&gt;this&lt;/code&gt;의 활용&lt;/h2&gt;
&lt;p&gt;이벤트 함수에 &lt;code class=&quot;language-text&quot;&gt;this&lt;/code&gt;를 전달하면 이벤트가 발생한 &lt;strong&gt;요소 자신&lt;/strong&gt;을 함수의 인자로 넘길 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onmouseover&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;changeColor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onmouseout&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;changeColor2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;changeColor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;obj&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;backgroundColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gold&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;changeColor2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;obj&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;backgroundColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;white&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;동작 흐름은 다음과 같다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;input 위에 마우스를 올리면 &lt;code class=&quot;language-text&quot;&gt;onmouseover&lt;/code&gt; 이벤트가 발생한다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;changeColor(this)&lt;/code&gt;가 실행된다.&lt;/li&gt;
&lt;li&gt;여기서 &lt;code class=&quot;language-text&quot;&gt;this&lt;/code&gt;는 현재 이벤트가 발생한 input 태그를 의미한다.&lt;/li&gt;
&lt;li&gt;input 태그가 &lt;code class=&quot;language-text&quot;&gt;obj&lt;/code&gt; 매개변수로 전달된다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;obj.style.backgroundColor = &quot;gold&quot;&lt;/code&gt;가 실행되어 배경색이 변경된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&quot;4-핵심-요약&quot;&gt;4. 핵심 요약&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;Event&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;발생 시점&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;실행 함수&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;역할&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;onload&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;페이지 로딩 완료&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;bodyLoad()&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;초기 실행 작업&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;onfocus&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;input에 커서 진입&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;focusFunc()&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;배경색 변경&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;onblur&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;input에서 커서 이탈&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;blurFunc()&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;배경색 원복&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;onchange&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;select 값 변경&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;selectTag()&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;선택값 출력&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;onmouseover&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;마우스가 요소 위로 진입&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;changeColor(this)&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;이벤트 대상 스타일 변경&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;onmouseout&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;마우스가 요소 밖으로 이탈&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;changeColor2(this)&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;이벤트 대상 스타일 원복&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&quot;5-전체-코드&quot;&gt;5. 전체 코드&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token doctype&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;token doctype-tag&quot;&gt;DOCTYPE&lt;/span&gt; &lt;span class=&quot;token name&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;en&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;UTF-8&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;JavaScript Event&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
    &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bodyLoad&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;loading ....&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;myform&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;money&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isNaN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;focusFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;myinput&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;background &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gold&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;blurFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;myinput&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;background &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;white&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;selectTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;myform&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;changeColor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;obj&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;backgroundColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gold&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;changeColor2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;obj&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;style&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;backgroundColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;white&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onload&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;bodyLoad&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;#&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;myform&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;myinput&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;myinput&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onfocus&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;focusFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onblur&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;blurFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;br&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;select&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;sel&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onchange&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;selectTag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;A&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;AA&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;B&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;BB&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;C&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;CC&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;D&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;DD&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;select&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;br&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onmouseover&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;changeColor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onmouseout&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;changeColor2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;br&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;br&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;1000&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;money&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id=&quot;정리&quot;&gt;정리&lt;/h2&gt;
&lt;p&gt;JavaScript 이벤트는 HTML 요소에서 발생하는 동작을 감지하고, 그에 맞는 함수를 실행하기 위해 사용한다.&lt;/p&gt;
&lt;p&gt;특히 &lt;code class=&quot;language-text&quot;&gt;this&lt;/code&gt;를 함께 사용하면 이벤트가 발생한 요소를 직접 제어할 수 있기 때문에, 여러 요소에 같은 함수를 적용할 때 유용하다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[Spring] JWT란? (세션과 비교)]]></title><description><![CDATA[1. JWT란? JWT는 JSON Web Token 의 약어로, JSON 형식의 정보를 안전하게 주고받기 위한 토큰이다. 웹 애플리케이션에서는 주로 로그인 이후 사용자를 식별하기 위한 인증 수단으로 사용된다. 서버는 사용자가 로그인에 성공하면 JWT를 발급하고, 클라이언트는 이후 요청마]]></description><link>https://woojin-devv.github.io/posts/Spring-JWT/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Spring-JWT/</guid><pubDate>Sun, 24 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;1-jwt란&quot;&gt;1. JWT란?&lt;/h2&gt;
&lt;p&gt;JWT는 &lt;code class=&quot;language-text&quot;&gt;JSON Web Token&lt;/code&gt;의 약어로, JSON 형식의 정보를 안전하게 주고받기 위한 토큰이다.
웹 애플리케이션에서는 주로 로그인 이후 사용자를 식별하기 위한 인증 수단으로 사용된다.&lt;/p&gt;
&lt;p&gt;서버는 사용자가 로그인에 성공하면 JWT를 발급하고, 클라이언트는 이후 요청마다 이 토큰을 함께 보낸다.
서버는 전달받은 토큰의 서명을 검증한 뒤, 해당 요청이 인증된 사용자의 요청인지 판단한다.&lt;/p&gt;
&lt;h2 id=&quot;2-jwt를-편지에-비유하기&quot;&gt;2. JWT를 편지에 비유하기&lt;/h2&gt;
&lt;p&gt;JWT는 편지에 비유하면 이해하기 쉽다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Header: 편지 봉투&lt;/li&gt;
&lt;li&gt;Payload: 편지의 내용&lt;/li&gt;
&lt;li&gt;Signature: 누가 작성했는지 확인할 수 있는 서명&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;편지 봉투에는 이 편지가 어떤 형식인지, 어떤 방식으로 서명되었는지가 적혀 있다.
편지 내용에는 전달하고 싶은 정보가 들어 있다.
마지막으로 서명은 이 편지가 중간에 조작되지 않았는지 확인하는 역할을 한다.&lt;/p&gt;
&lt;h2 id=&quot;3-jwt의-구조&quot;&gt;3. JWT의 구조&lt;/h2&gt;
&lt;p&gt;JWT는 &lt;code class=&quot;language-text&quot;&gt;.&lt;/code&gt;을 기준으로 세 부분으로 나뉜다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Header.Payload.Signature&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;각 부분은 Base64Url 방식으로 인코딩된다.
즉, JWT는 암호화된 값이 아니라 인코딩된 값이다.
따라서 Payload에 비밀번호나 주민번호 같은 민감한 정보를 넣으면 안 된다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/jwt/1.png&quot; alt=&quot;JWT 구조&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;4-header&quot;&gt;4. Header&lt;/h2&gt;
&lt;p&gt;Header에는 토큰의 타입과 서명 알고리즘 정보가 들어간다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;alg&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HS256&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;typ&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;JWT&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;alg&lt;/code&gt;: 서명에 사용할 알고리즘&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;typ&lt;/code&gt;: 토큰 타입&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;JWT는 서명 알고리즘을 하나로 강제하지 않는다.
따라서 어떤 알고리즘으로 서명했는지 Header에 명시해야 한다.
이것이 JWT에 Header가 필요한 이유다.&lt;/p&gt;
&lt;h2 id=&quot;5-payload&quot;&gt;5. Payload&lt;/h2&gt;
&lt;p&gt;Payload에는 서버와 클라이언트가 주고받을 데이터가 들어간다.
Payload에 들어가는 각각의 값을 Claim이라고 한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;sub&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;woojin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;USER&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;iat&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1716537600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;exp&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1716541200&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Claim은 말 그대로 &quot;주장&quot;이라는 의미다.
Payload에 적혀 있는 정보는 누구나 디코딩해서 볼 수 있기 때문에, 그 내용을 곧이곧대로 믿으면 안 된다.
서버는 반드시 Signature를 검증한 뒤에 Payload의 내용을 신뢰해야 한다.&lt;/p&gt;
&lt;p&gt;자주 사용되는 Claim은 다음과 같다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Claim&lt;/th&gt;
&lt;th&gt;의미&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;sub&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;토큰의 주체, 보통 사용자 ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;iat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;토큰 발급 시간&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;exp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;토큰 만료 시간&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;iss&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;토큰 발급자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;aud&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;토큰 대상자&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;6-signature&quot;&gt;6. Signature&lt;/h2&gt;
&lt;p&gt;Signature는 Header와 Payload가 변조되지 않았는지 검증하기 위한 값이다.&lt;/p&gt;
&lt;p&gt;예를 들어 HMAC SHA256 방식을 사용하면 다음과 같은 흐름으로 서명을 만든다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;HMACSHA256(
  base64UrlEncode(header) + &quot;.&quot; + base64UrlEncode(payload),
  secret
)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;클라이언트가 토큰을 서버로 보내면, 서버는 같은 방식으로 다시 서명을 계산한다.
그리고 토큰에 포함된 Signature와 서버가 계산한 Signature가 일치하는지 비교한다.&lt;/p&gt;
&lt;p&gt;일치하면 토큰이 변조되지 않았다고 판단할 수 있고, 일치하지 않으면 잘못된 토큰으로 처리한다.&lt;/p&gt;
&lt;h2 id=&quot;7-jwt는-어디에서-사용될까&quot;&gt;7. JWT는 어디에서 사용될까?&lt;/h2&gt;
&lt;p&gt;JWT는 다음과 같은 상황에서 사용할 수 있다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Information Exchange&lt;/li&gt;
&lt;li&gt;Authorization&lt;/li&gt;
&lt;li&gt;Single Sign-On&lt;/li&gt;
&lt;li&gt;Server-to-server communication&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이 중에서 가장 많이 사용되는 분야는 Authentication, 즉 인증이다.&lt;/p&gt;
&lt;h2 id=&quot;8-authentication-방식&quot;&gt;8. Authentication 방식&lt;/h2&gt;
&lt;p&gt;웹 애플리케이션에서 인증 상태를 유지하는 대표적인 방식은 Cookie 기반 Session 방식과 JWT 방식이다.&lt;/p&gt;
&lt;h3 id=&quot;81-cookie-based-session-management&quot;&gt;8.1 Cookie-based Session Management&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/jwt/2.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;p&gt;Cookie 기반 Session 방식은 서버가 인증 상태를 Session Table에 저장하고, 클라이언트는 Session ID를 Cookie로 보관하는 방식이다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Client에서 사용자가 로그인을 시도한다.&lt;/li&gt;
&lt;li&gt;Application Server는 로그인한 사용자에 대한 Session 정보를 저장한다.&lt;/li&gt;
&lt;li&gt;Server는 생성된 Session ID를 응답으로 반환한다.&lt;/li&gt;
&lt;li&gt;Client는 Session ID를 Cookie에 저장하고, 이후 요청마다 Cookie를 함께 보낸다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이 방식은 서버가 세션 상태를 직접 관리하기 때문에 구현이 직관적이다.
하지만 다음과 같은 문제가 생길 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;사용자 정보를 얻기 위해 매 요청마다 Session ID를 기준으로 Session Table을 다시 조회해야 한다.&lt;/li&gt;
&lt;li&gt;사용자가 여러 기기에서 로그인할수록 Session Table의 데이터가 증가한다.&lt;/li&gt;
&lt;li&gt;서버가 여러 대로 늘어나면 세션 공유를 위해 별도 저장소나 Sticky Session 전략이 필요해질 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;82-jwt-authentication&quot;&gt;8.2 JWT Authentication&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/jwt/3.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;p&gt;JWT 방식은 서버가 세션 상태를 저장하지 않고, 인증에 필요한 정보를 토큰에 담아 클라이언트에게 전달하는 방식이다.
클라이언트는 이후 요청마다 JWT를 &lt;code class=&quot;language-text&quot;&gt;Authorization&lt;/code&gt; 헤더에 담아 보낸다.&lt;/p&gt;
&lt;p&gt;서버는 토큰의 Signature와 만료 시간을 검증한 뒤, Payload에 담긴 Claim을 바탕으로 사용자를 식별한다.
이 방식은 서버가 세션을 저장하지 않아도 되기 때문에 Stateless 인증에 적합하다.&lt;/p&gt;
&lt;h2 id=&quot;9-spring에서-jwt를-사용하는-흐름&quot;&gt;9. Spring에서 JWT를 사용하는 흐름&lt;/h2&gt;
&lt;p&gt;Spring Security 기반 애플리케이션에서 JWT 인증은 보통 다음 흐름으로 동작한다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;사용자가 아이디와 비밀번호로 로그인 요청을 보낸다.&lt;/li&gt;
&lt;li&gt;서버는 사용자 정보를 확인한다.&lt;/li&gt;
&lt;li&gt;인증에 성공하면 Access Token을 발급한다.&lt;/li&gt;
&lt;li&gt;클라이언트는 이후 요청마다 &lt;code class=&quot;language-text&quot;&gt;Authorization&lt;/code&gt; 헤더에 토큰을 담아 보낸다.&lt;/li&gt;
&lt;li&gt;서버는 JWT 필터에서 토큰을 추출하고 검증한다.&lt;/li&gt;
&lt;li&gt;토큰이 유효하면 SecurityContext에 인증 정보를 저장한다.&lt;/li&gt;
&lt;li&gt;Controller에서는 인증된 사용자로 요청을 처리한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;http&quot;&gt;&lt;pre class=&quot;language-http&quot;&gt;&lt;code class=&quot;language-http&quot;&gt;&lt;span class=&quot;token header&quot;&gt;&lt;span class=&quot;token header-name keyword&quot;&gt;Authorization&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token header-value&quot;&gt;Bearer &amp;lt;access-token&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;JWT는 세션을 서버에 저장하지 않아도 되기 때문에 Stateless 인증 방식에 적합하다.
특히 SPA, 모바일 앱, MSA 구조에서 자주 사용된다.&lt;/p&gt;
&lt;h2 id=&quot;10-jwt-사용-시-주의할-점&quot;&gt;10. JWT 사용 시 주의할 점&lt;/h2&gt;
&lt;p&gt;JWT는 편리하지만 몇 가지 주의할 점이 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Payload는 암호화가 아니라 인코딩이므로 민감 정보를 넣지 않는다.&lt;/li&gt;
&lt;li&gt;Access Token의 만료 시간을 너무 길게 잡지 않는다.&lt;/li&gt;
&lt;li&gt;토큰 탈취에 대비해 Refresh Token 전략을 함께 고려한다.&lt;/li&gt;
&lt;li&gt;서버는 반드시 Signature와 만료 시간을 검증해야 한다.&lt;/li&gt;
&lt;li&gt;로그아웃과 강제 만료 처리가 필요한 경우 별도 저장소나 블랙리스트 전략이 필요할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;11-정리&quot;&gt;11. 정리&lt;/h2&gt;
&lt;p&gt;JWT는 Header, Payload, Signature로 구성된 토큰이다.
Header는 서명 방식, Payload는 Claim, Signature는 변조 여부 검증을 담당한다.&lt;/p&gt;
&lt;p&gt;Spring Security에서 JWT를 사용하면 서버가 세션을 저장하지 않아도 인증 상태를 처리할 수 있다.
다만 JWT는 한 번 발급되면 만료 전까지 유효하므로, 만료 시간과 Refresh Token, 토큰 폐기 전략을 함께 설계해야 한다.&lt;/p&gt;
&lt;h2 id=&quot;️-참고자료--사이트&quot;&gt;🗒️ 참고자료 &amp;#x26; 사이트&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jwt.io/&quot;&gt;jwt.io 사이트&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;참고영상&quot;&gt;참고영상&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=36lpDzQzVXs&quot;&gt;JWT | 생활코딩&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[001] Front-Back 정리]]></title><description><![CDATA[Front Back 구조 정리 1. Client Client는 사용자가 직접 보는 화면을 담당한다. 현대 웹에서는 React, Vue, Angular 같은 프레임워크를 사용해 SPA 방식으로 구현하는 경우가 많다. 2. SPA 방식 SPA(Single Page Application) S]]></description><link>https://woojin-devv.github.io/posts/front-back/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/front-back/</guid><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;front-back-구조-정리&quot;&gt;Front-Back 구조 정리&lt;/h1&gt;
&lt;h2 id=&quot;1-client&quot;&gt;1. Client&lt;/h2&gt;
&lt;p&gt;Client는 사용자가 직접 보는 화면을 담당한다.&lt;br&gt;
현대 웹에서는 React, Vue, Angular 같은 프레임워크를 사용해 SPA 방식으로 구현하는 경우가 많다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;2-spa-방식&quot;&gt;2. SPA 방식&lt;/h2&gt;
&lt;h3 id=&quot;spasingle-page-application&quot;&gt;SPA(Single Page Application)&lt;/h3&gt;
&lt;p&gt;SPA는 최초에 하나의 HTML 페이지를 로드한 뒤, 필요한 데이터만 서버에서 받아와 화면 일부를 동적으로 갱신하는 방식이다.&lt;/p&gt;
&lt;p&gt;대표 기술은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vue&lt;/li&gt;
&lt;li&gt;Angular&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;spa의-특징&quot;&gt;SPA의 특징&lt;/h3&gt;
&lt;h4 id=&quot;1-동적-콘텐츠-로딩&quot;&gt;1. 동적 콘텐츠 로딩&lt;/h4&gt;
&lt;p&gt;필요한 데이터만 서버에서 비동기적으로 가져와 화면을 업데이트한다.&lt;br&gt;
페이지 전체를 새로고침하지 않기 때문에 빠른 사용자 경험을 제공할 수 있다.&lt;/p&gt;
&lt;h4 id=&quot;2-클라이언트-사이드-라우팅&quot;&gt;2. 클라이언트 사이드 라우팅&lt;/h4&gt;
&lt;p&gt;화면 이동을 서버가 아닌 클라이언트의 JavaScript가 처리한다.&lt;br&gt;
즉, URL은 바뀌지만 서버에서 새로운 HTML 페이지를 매번 받아오지는 않는다.&lt;/p&gt;
&lt;h4 id=&quot;3-상태-관리&quot;&gt;3. 상태 관리&lt;/h4&gt;
&lt;p&gt;사용자 인터페이스의 상태를 클라이언트에서 관리한다.&lt;br&gt;
예를 들어 로그인 상태, 입력값, 선택된 메뉴, 장바구니 상태 등을 클라이언트에서 유지할 수 있다.&lt;/p&gt;
&lt;h4 id=&quot;4-재사용-가능한-컴포넌트&quot;&gt;4. 재사용 가능한 컴포넌트&lt;/h4&gt;
&lt;p&gt;SPA는 컴포넌트 단위로 화면을 구성한다.&lt;br&gt;
따라서 UI를 재사용하기 쉽고, 유지보수성과 확장성이 높다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;3-mpa-방식&quot;&gt;3. MPA 방식&lt;/h2&gt;
&lt;h3 id=&quot;mpamulti-page-application&quot;&gt;MPA(Multi Page Application)&lt;/h3&gt;
&lt;p&gt;MPA는 사용자가 페이지를 이동할 때마다 서버가 새로운 HTML 페이지를 렌더링해서 클라이언트에게 전달하는 방식이다.&lt;/p&gt;
&lt;p&gt;전통적인 서버 사이드 렌더링 방식에 가깝다.&lt;/p&gt;
&lt;p&gt;대표 기술은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JSP&lt;/li&gt;
&lt;li&gt;FreeMarker&lt;/li&gt;
&lt;li&gt;Mustache&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;mpa의-특징&quot;&gt;MPA의 특징&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;페이지 이동 시 서버에 새로운 페이지를 요청한다.&lt;/li&gt;
&lt;li&gt;서버가 View를 생성해서 응답한다.&lt;/li&gt;
&lt;li&gt;페이지마다 HTML을 새로 받아오기 때문에 화면 전환 시 새로고침이 발생한다.&lt;/li&gt;
&lt;li&gt;MVC 모델에서 View 단을 담당하는 역할을 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;4-spa와-mpa의-차이&quot;&gt;4. SPA와 MPA의 차이&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구분&lt;/th&gt;
&lt;th&gt;SPA&lt;/th&gt;
&lt;th&gt;MPA&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;화면 처리&lt;/td&gt;
&lt;td&gt;클라이언트에서 처리&lt;/td&gt;
&lt;td&gt;서버에서 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;페이지 이동&lt;/td&gt;
&lt;td&gt;JavaScript 라우팅&lt;/td&gt;
&lt;td&gt;서버에 새 페이지 요청&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;렌더링 위치&lt;/td&gt;
&lt;td&gt;주로 클라이언트&lt;/td&gt;
&lt;td&gt;주로 서버&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;서버 역할&lt;/td&gt;
&lt;td&gt;API 제공 중심&lt;/td&gt;
&lt;td&gt;HTML 렌더링 포함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;사용자 경험&lt;/td&gt;
&lt;td&gt;빠르고 부드러움&lt;/td&gt;
&lt;td&gt;페이지 전환 시 새로고침&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;대표 기술&lt;/td&gt;
&lt;td&gt;React, Vue, Angular&lt;/td&gt;
&lt;td&gt;JSP, FreeMarker, Mustache&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&quot;5-spa-도입-이후-was의-역할-변화&quot;&gt;5. SPA 도입 이후 WAS의 역할 변화&lt;/h2&gt;
&lt;p&gt;SPA 방식에서는 View 처리를 클라이언트가 담당한다.&lt;br&gt;
따라서 서버는 HTML 페이지를 직접 만들어주는 역할보다 데이터를 제공하는 API 서버 역할에 집중하게 된다.&lt;/p&gt;
&lt;p&gt;즉, WAS의 역할이 단순해진다.&lt;/p&gt;
&lt;p&gt;주요 역할은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;데이터 조회&lt;/li&gt;
&lt;li&gt;데이터 생성&lt;/li&gt;
&lt;li&gt;데이터 수정&lt;/li&gt;
&lt;li&gt;데이터 삭제&lt;/li&gt;
&lt;li&gt;인증 및 인가 처리&lt;/li&gt;
&lt;li&gt;비즈니스 로직 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;결국 서버는 CRUD 중심의 API를 제공하게 된다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;6-server-구조&quot;&gt;6. Server 구조&lt;/h2&gt;
&lt;p&gt;서버 구조는 크게 Monolithic 방식과 MSA 방식으로 나눌 수 있다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구분&lt;/th&gt;
&lt;th&gt;Monolithic&lt;/th&gt;
&lt;th&gt;MSA&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;구조&lt;/td&gt;
&lt;td&gt;하나의 거대한 애플리케이션&lt;/td&gt;
&lt;td&gt;기능별로 분리된 독립 서비스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;배포&lt;/td&gt;
&lt;td&gt;전체 시스템을 한 번에 배포&lt;/td&gt;
&lt;td&gt;서비스별 독립 배포&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;확장성&lt;/td&gt;
&lt;td&gt;전체 애플리케이션을 복제&lt;/td&gt;
&lt;td&gt;특정 서비스만 개별 확장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;데이터베이스&lt;/td&gt;
&lt;td&gt;단일 DB 공유&lt;/td&gt;
&lt;td&gt;서비스별 독립 DB 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;장애 격리&lt;/td&gt;
&lt;td&gt;하나의 장애가 전체 장애로 이어질 수 있음&lt;/td&gt;
&lt;td&gt;장애 전파 가능성이 상대적으로 낮음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;초기 개발&lt;/td&gt;
&lt;td&gt;구조가 단순하고 빠름&lt;/td&gt;
&lt;td&gt;설계와 인프라가 복잡함&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&quot;7-monolithic-architecture&quot;&gt;7. Monolithic Architecture&lt;/h2&gt;
&lt;p&gt;Monolithic은 하나의 애플리케이션 안에 모든 기능이 포함된 구조이다.&lt;/p&gt;
&lt;p&gt;예를 들어 다음 기능들이 하나의 프로젝트 안에 모두 들어간다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;회원 관리&lt;/li&gt;
&lt;li&gt;상품 관리&lt;/li&gt;
&lt;li&gt;주문 관리&lt;/li&gt;
&lt;li&gt;결제 관리&lt;/li&gt;
&lt;li&gt;배송 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;장점&quot;&gt;장점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;초기 개발이 쉽다.&lt;/li&gt;
&lt;li&gt;구조가 단순하다.&lt;/li&gt;
&lt;li&gt;배포 과정이 비교적 간단하다.&lt;/li&gt;
&lt;li&gt;서비스 간 통신 비용이 적다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;단점&quot;&gt;단점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;프로젝트가 커질수록 유지보수가 어려워진다.&lt;/li&gt;
&lt;li&gt;일부 기능 수정도 전체 애플리케이션 배포가 필요할 수 있다.&lt;/li&gt;
&lt;li&gt;특정 기능에 장애가 발생하면 전체 시스템에 영향을 줄 수 있다.&lt;/li&gt;
&lt;li&gt;기능별 독립 확장이 어렵다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;8-msa-architecture&quot;&gt;8. MSA Architecture&lt;/h2&gt;
&lt;p&gt;MSA는 하나의 큰 애플리케이션을 여러 개의 작은 서비스로 분리하는 구조이다.&lt;/p&gt;
&lt;p&gt;예를 들어 다음과 같이 나눌 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;회원 서비스&lt;/li&gt;
&lt;li&gt;상품 서비스&lt;/li&gt;
&lt;li&gt;주문 서비스&lt;/li&gt;
&lt;li&gt;결제 서비스&lt;/li&gt;
&lt;li&gt;배송 서비스&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;각 서비스는 독립적으로 개발, 배포, 운영될 수 있다.&lt;/p&gt;
&lt;h3 id=&quot;장점-1&quot;&gt;장점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;서비스별 독립 배포가 가능하다.&lt;/li&gt;
&lt;li&gt;특정 서비스만 확장할 수 있다.&lt;/li&gt;
&lt;li&gt;장애 격리가 가능하다.&lt;/li&gt;
&lt;li&gt;팀별로 서비스를 나누어 개발하기 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;단점-1&quot;&gt;단점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;서비스 간 통신 구조가 복잡하다.&lt;/li&gt;
&lt;li&gt;트랜잭션 관리가 어렵다.&lt;/li&gt;
&lt;li&gt;인증/인가 처리가 복잡해질 수 있다.&lt;/li&gt;
&lt;li&gt;인프라 운영 난이도가 높다.&lt;/li&gt;
&lt;li&gt;로그 추적과 장애 분석이 어려워질 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;9-msa의-주요-문제점&quot;&gt;9. MSA의 주요 문제점&lt;/h2&gt;
&lt;h3 id=&quot;1-트랜잭션-문제&quot;&gt;1. 트랜잭션 문제&lt;/h3&gt;
&lt;p&gt;Monolithic 구조에서는 하나의 DB를 사용하기 때문에 하나의 트랜잭션으로 여러 작업을 처리하기 쉽다.&lt;/p&gt;
&lt;p&gt;하지만 MSA에서는 서비스마다 DB가 분리되어 있기 때문에 하나의 요청이 여러 서비스에 걸쳐 처리될 경우 트랜잭션 관리가 어려워진다.&lt;/p&gt;
&lt;p&gt;예를 들어 주문 서비스와 결제 서비스가 분리되어 있다면 다음 문제가 발생할 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;주문은 생성되었지만 결제는 실패한 경우&lt;/li&gt;
&lt;li&gt;결제는 성공했지만 주문 상태 변경이 실패한 경우&lt;/li&gt;
&lt;li&gt;배송 요청은 생성되었지만 재고 차감이 실패한 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이런 문제를 해결하기 위해 Saga 패턴, 보상 트랜잭션, 이벤트 기반 처리 등을 사용할 수 있다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;2-인증-문제&quot;&gt;2. 인증 문제&lt;/h3&gt;
&lt;p&gt;MSA에서는 여러 서비스가 분리되어 있기 때문에 사용자 인증 정보를 각 서비스에서 어떻게 검증할지가 중요하다.&lt;/p&gt;
&lt;p&gt;일반적으로 JWT를 사용해 인증 정보를 전달한다.&lt;/p&gt;
&lt;p&gt;JWT 기반 인증 흐름은 다음과 같다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;사용자가 로그인한다.&lt;/li&gt;
&lt;li&gt;인증 서버가 JWT를 발급한다.&lt;/li&gt;
&lt;li&gt;클라이언트는 요청마다 JWT를 함께 보낸다.&lt;/li&gt;
&lt;li&gt;각 서비스는 JWT를 검증한 뒤 요청을 처리한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;하지만 서비스가 많아지면 다음 문제가 생길 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;각 서비스마다 JWT 검증 로직이 중복될 수 있다.&lt;/li&gt;
&lt;li&gt;토큰 만료 처리와 재발급 처리가 복잡해질 수 있다.&lt;/li&gt;
&lt;li&gt;권한 정보가 변경되었을 때 기존 토큰과 불일치가 발생할 수 있다.&lt;/li&gt;
&lt;li&gt;API Gateway에서 인증을 처리할지, 각 서비스에서 처리할지 설계가 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&quot;핵심-요약&quot;&gt;핵심 요약&lt;/h1&gt;
&lt;p&gt;SPA 구조에서는 View를 Client가 담당하고, Server는 데이터 API 제공에 집중한다.&lt;br&gt;
따라서 WAS는 CRUD 중심의 API 서버 역할을 하게 된다.&lt;/p&gt;
&lt;p&gt;Server 구조는 크게 Monolithic과 MSA로 나뉜다.&lt;br&gt;
Monolithic은 구조가 단순하고 초기 개발이 빠르지만, 규모가 커질수록 유지보수가 어렵다.&lt;br&gt;
MSA는 서비스별 독립 배포와 확장이 가능하지만, 트랜잭션과 인증 같은 분산 시스템 문제가 발생한다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[JPA] Intellij Dynamic Web project 생성]]></title><description><![CDATA[서론 IntelliJ IDEA에서 JSP/Servlet 기반의 Dynamic Web Project를 생성하는 과정을 정리한다. Eclipse에서는 Dynamic Web Project 메뉴를 통해 바로 생성할 수 있지만, IntelliJ에서는 Jakarta EE 템플릿과 Tomcat 실행]]></description><link>https://woojin-devv.github.io/posts/intellij-dynamic-web-project/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/intellij-dynamic-web-project/</guid><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;서론&quot;&gt;서론&lt;/h2&gt;
&lt;p&gt;IntelliJ IDEA에서 JSP/Servlet 기반의 Dynamic Web Project를 생성하는 과정을 정리한다.
Eclipse에서는 &lt;code class=&quot;language-text&quot;&gt;Dynamic Web Project&lt;/code&gt; 메뉴를 통해 바로 생성할 수 있지만, IntelliJ에서는 Jakarta EE 템플릿과 Tomcat 실행 설정을 함께 잡아줘야 한다.&lt;/p&gt;
&lt;h3 id=&quot;환경&quot;&gt;환경&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;IntelliJ IDEA 2025.3.1.1&lt;/li&gt;
&lt;li&gt;JDK 11&lt;/li&gt;
&lt;li&gt;Apache Tomcat 10.1.55&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;프로젝트-생성&quot;&gt;프로젝트 생성&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/jpa-01/1.png&quot; alt=&quot;새 프로젝트 생성 화면&quot;&gt;&lt;/p&gt;
&lt;p&gt;새 프로젝트를 생성할 때 &lt;code class=&quot;language-text&quot;&gt;Jakarta EE&lt;/code&gt;를 선택하고 템플릿은 &lt;code class=&quot;language-text&quot;&gt;웹 애플리케이션&lt;/code&gt;으로 지정한다.
Servlet, &lt;code class=&quot;language-text&quot;&gt;web.xml&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;index.jsp&lt;/code&gt;가 포함된 기본 웹 프로젝트 구조를 만들 수 있다.&lt;/p&gt;
&lt;p&gt;애플리케이션 서버는 미리 연동해 둔 &lt;code class=&quot;language-text&quot;&gt;Tomcat 10.1.55&lt;/code&gt;를 선택한다.
Tomcat이 아직 등록되어 있지 않다면 &lt;code class=&quot;language-text&quot;&gt;새로 만들기&lt;/code&gt;를 눌러 Tomcat 설치 경로를 지정한 뒤 다음 단계로 넘어간다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/jpa-01/2.png&quot; alt=&quot;Jakarta EE 버전 선택 화면&quot;&gt;&lt;/p&gt;
&lt;p&gt;Jakarta EE 버전은 JDK 11과 호환되는 버전으로 선택한다.
여기서는 &lt;code class=&quot;language-text&quot;&gt;Jakarta EE 10&lt;/code&gt;을 기준으로 진행하고, 설정이 끝나면 &lt;code class=&quot;language-text&quot;&gt;생성&lt;/code&gt; 버튼을 눌러 프로젝트를 만든다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/jpa-01/3.png&quot; alt=&quot;프로젝트 실행 화면&quot;&gt;&lt;/p&gt;
&lt;p&gt;프로젝트가 생성되면 우측 상단의 실행 버튼을 눌러 Tomcat 서버를 실행한다.
기본 애플리케이션 컨텍스트는 보통 &lt;code class=&quot;language-text&quot;&gt;/{프로젝트명}_war_exploded&lt;/code&gt; 형태로 잡힌다.&lt;/p&gt;
&lt;h2 id=&quot;애플리케이션-컨텍스트-경로-수정&quot;&gt;애플리케이션 컨텍스트 경로 수정&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/jpa-01/4.png&quot; alt=&quot;실행 구성 편집 메뉴&quot;&gt;&lt;/p&gt;
&lt;p&gt;컨텍스트 경로를 변경하려면 상단 메뉴에서 &lt;code class=&quot;language-text&quot;&gt;실행&lt;/code&gt; &gt; &lt;code class=&quot;language-text&quot;&gt;구성 편집&lt;/code&gt;으로 이동한다.
이후 등록된 Tomcat 서버 설정을 선택하고 &lt;code class=&quot;language-text&quot;&gt;서버&lt;/code&gt; 탭을 확인한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/jpa-01/5.png&quot; alt=&quot;Tomcat 서버 설정 화면&quot;&gt;&lt;/p&gt;
&lt;p&gt;배포 설정에서 애플리케이션 컨텍스트 값을 원하는 경로로 수정한다.
예를 들어 &lt;code class=&quot;language-text&quot;&gt;/&lt;/code&gt;로 설정하면 &lt;code class=&quot;language-text&quot;&gt;http://localhost:8080/&lt;/code&gt;에서 바로 프로젝트를 확인할 수 있다.&lt;/p&gt;
&lt;h2 id=&quot;정리&quot;&gt;정리&lt;/h2&gt;
&lt;p&gt;IntelliJ에서 Dynamic Web Project를 만들 때는 &lt;code class=&quot;language-text&quot;&gt;Jakarta EE&lt;/code&gt; 템플릿을 사용하고, Tomcat 서버와 배포 아티팩트를 함께 설정해야 한다.
기본 컨텍스트 경로가 길게 생성될 수 있으므로, 실습이나 테스트 목적이라면 실행 구성에서 컨텍스트 경로를 간단하게 바꿔두는 것이 편하다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[Data Modeling] 데이터 모델링 2일차 - 정규화, 반정규화]]></title><description><![CDATA[📍 연관 포스팅 [[Data Modeling] 데이터 모델링 1일차 개념/논리/물리 모델링과 ERD 기초](https://woojin devv.github.io/posts/DataModeling 1/) [[Data Modeling] 데이터 모델링 2일차 정규화, 반정규화](https:/]]></description><link>https://woojin-devv.github.io/posts/DataModeling-2/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/DataModeling-2/</guid><pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h3 id=&quot;-연관-포스팅&quot;&gt;📍 연관 포스팅&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://woojin-devv.github.io/posts/DataModeling-1/&quot;&gt;[Data Modeling] 데이터 모델링 1일차 - 개념/논리/물리 모델링과 ERD 기초&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://woojin-devv.github.io/posts/DataModeling-2/&quot;&gt;[Data Modeling] 데이터 모델링 2일차 - 정규화, 반정규화&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;1-들어가며&quot;&gt;1. 들어가며&lt;/h2&gt;
&lt;p&gt;이번 글에서는 데이터 모델링에서 속성과 식별자를 정의하는 방법을 복습하고, 정규화와 반정규화의 핵심 개념을 정리한다.
1일차에서 엔티티와 관계를 도출하는 흐름을 봤다면, 2일차에서는 테이블 구조를 더 안정적으로 만드는 방법과 성능을 위해 의도적으로 구조를 바꾸는 방법을 다룬다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;속성의 유형&lt;/li&gt;
&lt;li&gt;슈퍼타입과 서브타입&lt;/li&gt;
&lt;li&gt;재귀적 관계&lt;/li&gt;
&lt;li&gt;복합키와 대체키&lt;/li&gt;
&lt;li&gt;정규화&lt;/li&gt;
&lt;li&gt;반정규화&lt;/li&gt;
&lt;li&gt;컬럼/테이블 반정규화 패턴&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;2-모델링-속성과-식별자-복습&quot;&gt;2. 모델링 속성과 식별자 복습&lt;/h2&gt;
&lt;p&gt;데이터 모델링에서 엔티티를 도출한 뒤에는 각 엔티티가 가져야 할 속성과 식별자를 정의해야 한다.
속성은 엔티티를 설명하는 세부 데이터이고, 식별자는 엔티티의 인스턴스를 유일하게 구분하는 기준이다.&lt;/p&gt;
&lt;h3 id=&quot;21-attribute&quot;&gt;2.1 Attribute&lt;/h3&gt;
&lt;p&gt;속성은 크게 기초 속성, 추출 속성, 설계 속성으로 나눌 수 있다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;유형&lt;/th&gt;
&lt;th&gt;의미&lt;/th&gt;
&lt;th&gt;예시&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;기초 속성&lt;/td&gt;
&lt;td&gt;엔티티가 업무적으로 원래 가지고 있는 속성&lt;/td&gt;
&lt;td&gt;이름, 생년월일, 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;추출 속성&lt;/td&gt;
&lt;td&gt;기초 속성으로부터 계산, 집계, 가공해서 얻을 수 있는 속성&lt;/td&gt;
&lt;td&gt;총금액, 평균점수, 누적금액&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;설계 속성&lt;/td&gt;
&lt;td&gt;실제 업무에는 없지만 시스템 효율을 위해 설계자가 부여하는 속성&lt;/td&gt;
&lt;td&gt;순번, 코드, 상태값&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;추출 속성과 설계 속성은 편리하지만 데이터 중복과 무결성 문제를 만들 수 있다.
따라서 단순히 조회가 편하다는 이유만으로 추가하기보다는, 정합성을 유지할 방법까지 함께 설계해야 한다.&lt;/p&gt;
&lt;h3 id=&quot;22-데이터-모델링-과정&quot;&gt;2.2 데이터 모델링 과정&lt;/h3&gt;
&lt;p&gt;데이터 모델링은 보통 다음 흐름으로 진행된다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;업무 요구사항 분석&lt;/li&gt;
&lt;li&gt;핵심 엔티티 도출&lt;/li&gt;
&lt;li&gt;엔티티 간 관계 정의&lt;/li&gt;
&lt;li&gt;속성 정의&lt;/li&gt;
&lt;li&gt;식별자 정의&lt;/li&gt;
&lt;li&gt;정규화 수행&lt;/li&gt;
&lt;li&gt;물리 모델 변환&lt;/li&gt;
&lt;li&gt;성능 요구사항에 따른 반정규화 검토&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;3-슈퍼타입과-서브타입&quot;&gt;3. 슈퍼타입과 서브타입&lt;/h2&gt;
&lt;p&gt;슈퍼타입과 서브타입은 공통 속성과 개별 속성을 분리해서 표현하는 모델링 방식이다.
슈퍼타입은 공통 속성을 가지는 상위 엔티티이고, 서브타입은 특정 유형에만 필요한 속성을 가지는 하위 엔티티다.&lt;/p&gt;
&lt;p&gt;예를 들어 상품이라는 공통 개념 아래에 온라인상품, 오프라인상품, B2B상품 같은 유형이 있을 수 있다.
이때 상품명, 가격, 재고처럼 공통으로 필요한 속성은 &lt;code class=&quot;language-text&quot;&gt;상품&lt;/code&gt;에 두고, 유형별 속성은 각 서브타입에 둔다.&lt;/p&gt;
&lt;h3 id=&quot;31-포함-관계-제약조건&quot;&gt;3.1 포함 관계 제약조건&lt;/h3&gt;
&lt;p&gt;서브타입 관계를 실제 테이블에 반영할 때는 제약조건을 통해 최소 하나의 유형에 속하도록 강제할 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;TABLE&lt;/span&gt; product &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  product_id   &lt;span class=&quot;token keyword&quot;&gt;VARCHAR&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;KEY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  product_name &lt;span class=&quot;token keyword&quot;&gt;VARCHAR&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  price        &lt;span class=&quot;token keyword&quot;&gt;DECIMAL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  stock        &lt;span class=&quot;token keyword&quot;&gt;INT&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;DEFAULT&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  online_yn    &lt;span class=&quot;token keyword&quot;&gt;CHAR&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;DEFAULT&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;N&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  offline_yn   &lt;span class=&quot;token keyword&quot;&gt;CHAR&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;DEFAULT&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;N&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  b2b_yn       &lt;span class=&quot;token keyword&quot;&gt;CHAR&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;DEFAULT&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;N&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;CONSTRAINT&lt;/span&gt; chk_at_least_one
    &lt;span class=&quot;token keyword&quot;&gt;CHECK&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;online_yn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Y&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;OR&lt;/span&gt; offline_yn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Y&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;OR&lt;/span&gt; b2b_yn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Y&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위 제약조건은 하나의 상품이 온라인, 오프라인, B2B 중 최소 하나의 채널에는 반드시 속하도록 보장한다.&lt;/p&gt;
&lt;h2 id=&quot;4-재귀적-관계&quot;&gt;4. 재귀적 관계&lt;/h2&gt;
&lt;p&gt;재귀적 관계는 하나의 엔티티가 자기 자신과 관계를 맺는 구조다.
같은 테이블 안에서 특정 행의 FK가 다시 같은 테이블의 PK를 참조한다.&lt;/p&gt;
&lt;p&gt;대표적인 예시는 직원과 직속 상사의 관계다.
직원도 같은 직원 테이블에 존재하고, 직속 상사도 같은 직원 테이블에 존재한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    EMPLOYEE &lt;span class=&quot;token arrow operator&quot;&gt;||..o{&lt;/span&gt; EMPLOYEE &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;감독&quot;&lt;/span&gt;

    EMPLOYEE&lt;span class=&quot;token text string&quot;&gt;[&quot;직원&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int employee_id PK &lt;span class=&quot;token string&quot;&gt;&quot;직원번호&quot;&lt;/span&gt;
        int manager_employee_id FK &lt;span class=&quot;token string&quot;&gt;&quot;직속상사직원번호&quot;&lt;/span&gt;
        string employee_name &lt;span class=&quot;token string&quot;&gt;&quot;직원명&quot;&lt;/span&gt;
        date hired_at &lt;span class=&quot;token string&quot;&gt;&quot;입사일&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;재귀적 관계를 설계할 때는 최상위 데이터의 FK를 &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt;로 허용할지, 별도의 루트 데이터를 둘지 같은 규칙도 함께 정해야 한다.&lt;/p&gt;
&lt;h2 id=&quot;5-복합키와-대체키&quot;&gt;5. 복합키와 대체키&lt;/h2&gt;
&lt;p&gt;식별자를 설계할 때는 복합키를 사용할지, 순번 기반의 대체키를 사용할지 결정해야 한다.
실무에서는 &lt;code class=&quot;language-text&quot;&gt;순번키 + UNIQUE 복합키&lt;/code&gt; 패턴을 많이 사용한다.
순번키로 참조를 단순하게 만들고, 업무적으로 중복되면 안 되는 조합은 UNIQUE 제약조건으로 보장하는 방식이다.&lt;/p&gt;
&lt;h3 id=&quot;51-복합키를-고려할-때&quot;&gt;5.1 복합키를 고려할 때&lt;/h3&gt;
&lt;p&gt;복합키는 관계 자체가 식별자가 되는 경우에 적합하다.
특히 M:N 관계를 해소하기 위한 중간 테이블에서 자주 사용한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;관계 자체가 키인 경우&lt;/li&gt;
&lt;li&gt;중간 테이블&lt;/li&gt;
&lt;li&gt;변경 가능성이 거의 없는 경우&lt;/li&gt;
&lt;li&gt;좋아요, 수강신청, 주문상세 같은 데이터&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    MEMBER &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; COURSE_ENROLLMENT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;신청&quot;&lt;/span&gt;
    COURSE &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; COURSE_ENROLLMENT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;포함&quot;&lt;/span&gt;

    MEMBER&lt;span class=&quot;token text string&quot;&gt;[&quot;회원&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int member_id PK &lt;span class=&quot;token string&quot;&gt;&quot;회원번호&quot;&lt;/span&gt;
        string member_name &lt;span class=&quot;token string&quot;&gt;&quot;회원명&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    COURSE&lt;span class=&quot;token text string&quot;&gt;[&quot;강의&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int course_id PK &lt;span class=&quot;token string&quot;&gt;&quot;강의번호&quot;&lt;/span&gt;
        string course_name &lt;span class=&quot;token string&quot;&gt;&quot;강의명&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    COURSE_ENROLLMENT&lt;span class=&quot;token text string&quot;&gt;[&quot;수강신청&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int member_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;회원번호&quot;&lt;/span&gt;
        int course_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;강의번호&quot;&lt;/span&gt;
        date enrolled_at &lt;span class=&quot;token string&quot;&gt;&quot;신청일&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;52-순번키를-고려할-때&quot;&gt;5.2 순번키를 고려할 때&lt;/h3&gt;
&lt;p&gt;순번키는 대부분의 일반 엔티티에 적합하다.
업무 속성이 바뀔 가능성이 있거나, 외부 테이블에서 자주 참조되는 테이블이라면 대체키를 두는 편이 관리하기 쉽다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;대부분의 일반 테이블&lt;/li&gt;
&lt;li&gt;식별 속성 변경 가능성이 있는 경우&lt;/li&gt;
&lt;li&gt;확장 가능성을 고려해야 하는 경우&lt;/li&gt;
&lt;li&gt;회원, 주문, 게시판, 상품 같은 데이터&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;6-정규화&quot;&gt;6. 정규화&lt;/h2&gt;
&lt;p&gt;정규화는 1972년 E. F. Codd가 제안한 이론으로, 데이터를 체계적으로 구조화해서 중복을 줄이고 이상현상을 제거하기 위한 방법이다.
정규화는 데이터 무결성을 높이는 방향의 설계다.&lt;/p&gt;
&lt;h3 id=&quot;61-정규화가-필요한-이유&quot;&gt;6.1 정규화가 필요한 이유&lt;/h3&gt;
&lt;p&gt;정규화가 필요한 이유는 크게 두 가지다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;엔티티를 구성하는 속성 간 중복을 제거해 데이터베이스를 최적화한다.&lt;/li&gt;
&lt;li&gt;속성 간 함수 종속성 때문에 발생하는 이상현상을 제거한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이상현상은 다음 세 가지로 나눌 수 있다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;이상현상&lt;/th&gt;
&lt;th&gt;의미&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;입력 이상&lt;/td&gt;
&lt;td&gt;불필요한 데이터가 있어야만 원하는 데이터를 입력할 수 있는 문제&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;수정 이상&lt;/td&gt;
&lt;td&gt;같은 의미의 데이터를 여러 곳에서 모두 수정해야 하는 문제&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;삭제 이상&lt;/td&gt;
&lt;td&gt;특정 데이터를 삭제할 때 보존해야 할 정보까지 함께 사라지는 문제&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;예를 들어 주문 테이블에 제품 정보까지 함께 저장되어 있다면, 주문이 발생해야만 제품 정보를 등록할 수 있다.
또한 제품의 재고 수량이 여러 주문 행에 중복 저장되어 있다면, 재고를 바꿀 때 여러 행을 모두 수정해야 한다.
특정 제품의 마지막 주문 내역을 삭제하면 제품 정보까지 사라지는 문제도 생길 수 있다.&lt;/p&gt;
&lt;h3 id=&quot;62-제1정규형&quot;&gt;6.2 제1정규형&lt;/h3&gt;
&lt;p&gt;제1정규형은 모든 속성이 원자값을 가져야 한다는 규칙이다.
하나의 컬럼에 여러 값을 넣거나 반복 속성을 두면 안 된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모든 속성은 하나의 값만 가진다.&lt;/li&gt;
&lt;li&gt;복수 값을 가지는 속성은 별도 엔티티로 분리한다.&lt;/li&gt;
&lt;li&gt;반복되는 컬럼은 행으로 전환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;63-제2정규형&quot;&gt;6.3 제2정규형&lt;/h3&gt;
&lt;p&gt;제2정규형은 기본키 전체에 종속되지 않는 속성을 분리하는 단계다.
특히 복합키를 사용하는 테이블에서 부분 종속이 발생할 수 있다.&lt;/p&gt;
&lt;p&gt;예를 들어 &lt;code class=&quot;language-text&quot;&gt;주문번호 + 제품번호&lt;/code&gt;가 PK인 주문상세 테이블에 제품명이 들어 있다면, 제품명은 전체 키가 아니라 제품번호에만 종속된다.
이 경우 제품명은 제품 테이블로 분리해야 한다.&lt;/p&gt;
&lt;h3 id=&quot;64-제3정규형&quot;&gt;6.4 제3정규형&lt;/h3&gt;
&lt;p&gt;제3정규형은 일반 속성에 종속되는 속성을 분리하는 단계다.
즉, 기본키가 아닌 속성에 다른 속성이 종속되는 이행 종속을 제거한다.&lt;/p&gt;
&lt;p&gt;현업에서는 보통 제3정규형까지 진행한 뒤, 성능 요구사항에 따라 반정규화를 검토하는 경우가 많다.&lt;/p&gt;
&lt;h3 id=&quot;65-bcnf&quot;&gt;6.5 BCNF&lt;/h3&gt;
&lt;p&gt;BCNF는 결정자가 후보키가 아닌 경우를 제거하는 더 강한 정규화 형태다.
다수의 주식별자가 복잡하게 얽힌 경우 추가로 검토할 수 있다.&lt;/p&gt;
&lt;h2 id=&quot;7-반정규화&quot;&gt;7. 반정규화&lt;/h2&gt;
&lt;p&gt;반정규화는 조회 성능을 높이거나 운영 편의성을 확보하기 위해 정규화된 구조를 의도적으로 일부 중복시키는 설계다.
정규화가 무결성을 우선한다면, 반정규화는 성능과 사용성을 위해 무결성 관리 비용을 감수하는 선택이다.&lt;/p&gt;
&lt;p&gt;반정규화를 적용할 때는 반드시 다음 질문을 해야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;어떤 조회 성능 문제가 있는가?&lt;/li&gt;
&lt;li&gt;조인을 줄이는 것 외에 인덱스로 해결할 수 있는가?&lt;/li&gt;
&lt;li&gt;중복 데이터의 정합성은 어떻게 보장할 것인가?&lt;/li&gt;
&lt;li&gt;Trigger, 계산 컬럼, 배치, 애플리케이션 로직 중 어떤 방식으로 동기화할 것인가?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;8-컬럼-반정규화&quot;&gt;8. 컬럼 반정규화&lt;/h2&gt;
&lt;p&gt;컬럼 반정규화는 테이블은 유지하되, 조회 성능이나 복구 편의성을 위해 컬럼을 추가하는 방식이다.&lt;/p&gt;
&lt;p&gt;대표적인 유형은 다음과 같다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;중복 컬럼 추가&lt;/li&gt;
&lt;li&gt;파생 컬럼 추가&lt;/li&gt;
&lt;li&gt;이력 컬럼 추가&lt;/li&gt;
&lt;li&gt;PK 컬럼 분리&lt;/li&gt;
&lt;li&gt;데이터 복구를 위한 컬럼 추가&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;81-중복-컬럼-추가&quot;&gt;8.1 중복 컬럼 추가&lt;/h3&gt;
&lt;p&gt;지점명은 업무지점 테이블에 존재하지만, 사원정보를 조회할 때마다 지점명까지 자주 필요하다면 사원정보에 지점명을 중복 저장하는 방식을 검토할 수 있다.&lt;/p&gt;
&lt;p&gt;정규화된 구조는 다음과 같다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    BRANCH &lt;span class=&quot;token arrow operator&quot;&gt;||..o{&lt;/span&gt; EMPLOYEE_INFO &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;소속&quot;&lt;/span&gt;

    BRANCH&lt;span class=&quot;token text string&quot;&gt;[&quot;업무지점&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int branch_id PK &lt;span class=&quot;token string&quot;&gt;&quot;지점번호&quot;&lt;/span&gt;
        string branch_name &lt;span class=&quot;token string&quot;&gt;&quot;지점명&quot;&lt;/span&gt;
        string location &lt;span class=&quot;token string&quot;&gt;&quot;지점위치&quot;&lt;/span&gt;
        string phone_number &lt;span class=&quot;token string&quot;&gt;&quot;전화번호&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    EMPLOYEE_INFO&lt;span class=&quot;token text string&quot;&gt;[&quot;사원정보&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int employee_id PK &lt;span class=&quot;token string&quot;&gt;&quot;사원번호&quot;&lt;/span&gt;
        string employee_name &lt;span class=&quot;token string&quot;&gt;&quot;이름&quot;&lt;/span&gt;
        string phone_number &lt;span class=&quot;token string&quot;&gt;&quot;연락처&quot;&lt;/span&gt;
        int branch_id FK &lt;span class=&quot;token string&quot;&gt;&quot;지점번호&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;반정규화를 적용하면 사원정보에 지점명을 중복 저장한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    BRANCH &lt;span class=&quot;token arrow operator&quot;&gt;||..o{&lt;/span&gt; EMPLOYEE_INFO &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;소속&quot;&lt;/span&gt;

    BRANCH&lt;span class=&quot;token text string&quot;&gt;[&quot;업무지점&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int branch_id PK &lt;span class=&quot;token string&quot;&gt;&quot;지점번호&quot;&lt;/span&gt;
        string branch_name &lt;span class=&quot;token string&quot;&gt;&quot;지점명&quot;&lt;/span&gt;
        string location &lt;span class=&quot;token string&quot;&gt;&quot;지점위치&quot;&lt;/span&gt;
        string phone_number &lt;span class=&quot;token string&quot;&gt;&quot;전화번호&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    EMPLOYEE_INFO&lt;span class=&quot;token text string&quot;&gt;[&quot;사원정보&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int employee_id PK &lt;span class=&quot;token string&quot;&gt;&quot;사원번호&quot;&lt;/span&gt;
        string employee_name &lt;span class=&quot;token string&quot;&gt;&quot;이름&quot;&lt;/span&gt;
        string phone_number &lt;span class=&quot;token string&quot;&gt;&quot;연락처&quot;&lt;/span&gt;
        int branch_id FK &lt;span class=&quot;token string&quot;&gt;&quot;지점번호&quot;&lt;/span&gt;
        string branch_name &lt;span class=&quot;token string&quot;&gt;&quot;지점명&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이렇게 하면 조회 시 조인을 줄일 수 있지만, 업무지점의 지점명이 변경될 때 사원정보의 지점명도 함께 갱신해야 한다.&lt;/p&gt;
&lt;h3 id=&quot;82-파생-컬럼-추가&quot;&gt;8.2 파생 컬럼 추가&lt;/h3&gt;
&lt;p&gt;주문 총금액은 주문상세의 수량과 제품 단가를 통해 계산할 수 있다.
원칙적으로는 조회 시 계산할 수 있지만, 대부분의 조회에서 총금액이 필요하고 계산 비용이 크다면 주문 테이블에 총금액을 저장할 수 있다.&lt;/p&gt;
&lt;p&gt;정규화된 구조는 다음과 같다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    ORD &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; ORDER_PRODUCT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;포함&quot;&lt;/span&gt;
    PRODUCT &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; ORDER_PRODUCT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;주문됨&quot;&lt;/span&gt;

    ORD&lt;span class=&quot;token text string&quot;&gt;[&quot;주문&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int order_id PK &lt;span class=&quot;token string&quot;&gt;&quot;주문번호&quot;&lt;/span&gt;
        date ordered_at &lt;span class=&quot;token string&quot;&gt;&quot;주문날짜&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    ORDER_PRODUCT&lt;span class=&quot;token text string&quot;&gt;[&quot;주문제품상세&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int order_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;주문번호&quot;&lt;/span&gt;
        int product_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;제품번호&quot;&lt;/span&gt;
        int quantity &lt;span class=&quot;token string&quot;&gt;&quot;수량&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    PRODUCT&lt;span class=&quot;token text string&quot;&gt;[&quot;제품&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int product_id PK &lt;span class=&quot;token string&quot;&gt;&quot;제품번호&quot;&lt;/span&gt;
        string product_name &lt;span class=&quot;token string&quot;&gt;&quot;제품이름&quot;&lt;/span&gt;
        int unit_price &lt;span class=&quot;token string&quot;&gt;&quot;단가&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;반정규화를 적용하면 주문 테이블에 총금액 컬럼을 추가한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    ORD &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; ORDER_PRODUCT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;포함&quot;&lt;/span&gt;
    PRODUCT &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; ORDER_PRODUCT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;주문됨&quot;&lt;/span&gt;

    ORD&lt;span class=&quot;token text string&quot;&gt;[&quot;주문&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int order_id PK &lt;span class=&quot;token string&quot;&gt;&quot;주문번호&quot;&lt;/span&gt;
        date ordered_at &lt;span class=&quot;token string&quot;&gt;&quot;주문날짜&quot;&lt;/span&gt;
        int total_amount &lt;span class=&quot;token string&quot;&gt;&quot;총금액&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    ORDER_PRODUCT&lt;span class=&quot;token text string&quot;&gt;[&quot;주문제품상세&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int order_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;주문번호&quot;&lt;/span&gt;
        int product_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;제품번호&quot;&lt;/span&gt;
        int quantity &lt;span class=&quot;token string&quot;&gt;&quot;수량&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    PRODUCT&lt;span class=&quot;token text string&quot;&gt;[&quot;제품&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int product_id PK &lt;span class=&quot;token string&quot;&gt;&quot;제품번호&quot;&lt;/span&gt;
        string product_name &lt;span class=&quot;token string&quot;&gt;&quot;제품이름&quot;&lt;/span&gt;
        int unit_price &lt;span class=&quot;token string&quot;&gt;&quot;단가&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;파생 컬럼을 저장할 때는 계산된 컬럼을 사용해 정합성을 확보할 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ALTER&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;TABLE&lt;/span&gt; emp &lt;span class=&quot;token keyword&quot;&gt;ADD&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;totalsum NUMBER&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
GENERATED ALWAYS &lt;span class=&quot;token keyword&quot;&gt;AS&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sal &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; NVL&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;comm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;83-누적합-컬럼-주의&quot;&gt;8.3 누적합 컬럼 주의&lt;/h3&gt;
&lt;p&gt;공사비 누적처럼 행 단위로 누적합을 저장하는 방식은 RDB 설계에서는 피하는 것이 좋다.
특정 중간 행의 공사비가 변경되면 이후 모든 누적값을 다시 계산해야 하기 때문이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    CONSTRUCTION_WORK&lt;span class=&quot;token text string&quot;&gt;[&quot;공사내역&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int work_id PK &lt;span class=&quot;token string&quot;&gt;&quot;공사번호&quot;&lt;/span&gt;
        date worked_at &lt;span class=&quot;token string&quot;&gt;&quot;공사일자&quot;&lt;/span&gt;
        int cost &lt;span class=&quot;token string&quot;&gt;&quot;공사비&quot;&lt;/span&gt;
        int accumulated_cost &lt;span class=&quot;token string&quot;&gt;&quot;공사비누적&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;누적합은 조회 시 윈도우 함수나 집계 쿼리로 계산하는 편이 안전하다.&lt;/p&gt;
&lt;h3 id=&quot;84-최근-등록-여부-컬럼&quot;&gt;8.4 최근 등록 여부 컬럼&lt;/h3&gt;
&lt;p&gt;직원의 차량 이력을 관리할 때 최근 등록 차량만 자주 조회한다면, 매번 Top N Query를 사용하는 대신 &lt;code class=&quot;language-text&quot;&gt;최근등록여부&lt;/code&gt; 컬럼을 둘 수 있다.
새 차량 이력이 등록되면 기존 최근 값은 &lt;code class=&quot;language-text&quot;&gt;N&lt;/code&gt;으로 바꾸고, 새 이력은 &lt;code class=&quot;language-text&quot;&gt;Y&lt;/code&gt;로 저장한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    COMPANY_EMPLOYEE &lt;span class=&quot;token arrow operator&quot;&gt;||..o{&lt;/span&gt; EMPLOYEE_CAR_HISTORY &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;보유이력&quot;&lt;/span&gt;

    COMPANY_EMPLOYEE&lt;span class=&quot;token text string&quot;&gt;[&quot;회사직원&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int employee_id PK &lt;span class=&quot;token string&quot;&gt;&quot;직원번호&quot;&lt;/span&gt;
        string employee_name &lt;span class=&quot;token string&quot;&gt;&quot;직원명&quot;&lt;/span&gt;
        date hired_at &lt;span class=&quot;token string&quot;&gt;&quot;입사일&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    EMPLOYEE_CAR_HISTORY&lt;span class=&quot;token text string&quot;&gt;[&quot;직원차량이력&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int car_history_id PK &lt;span class=&quot;token string&quot;&gt;&quot;차량이력번호&quot;&lt;/span&gt;
        int employee_id FK &lt;span class=&quot;token string&quot;&gt;&quot;직원번호&quot;&lt;/span&gt;
        string car_number &lt;span class=&quot;token string&quot;&gt;&quot;차량번호&quot;&lt;/span&gt;
        string car_year &lt;span class=&quot;token string&quot;&gt;&quot;연식&quot;&lt;/span&gt;
        string car_type &lt;span class=&quot;token string&quot;&gt;&quot;차종&quot;&lt;/span&gt;
        date registered_at &lt;span class=&quot;token string&quot;&gt;&quot;등록일자&quot;&lt;/span&gt;
        string latest_yn &lt;span class=&quot;token string&quot;&gt;&quot;최근등록여부&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이 방식도 조회 성능은 좋아지지만, 최신 여부를 갱신하는 로직이 반드시 필요하다.&lt;/p&gt;
&lt;h3 id=&quot;85-pk-분리-컬럼-반정규화&quot;&gt;8.5 PK 분리 컬럼 반정규화&lt;/h3&gt;
&lt;p&gt;차량번호 안에 지역 정보가 포함되어 있더라도, 지역별 조회가 자주 발생한다면 지역을 별도 컬럼으로 분리할 수 있다.
이는 PK에 포함된 의미를 조회 성능을 위해 컬럼으로 분리하는 반정규화다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    CAR&lt;span class=&quot;token text string&quot;&gt;[&quot;차량&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        string car_number PK &lt;span class=&quot;token string&quot;&gt;&quot;차량번호&quot;&lt;/span&gt;
        string car_type &lt;span class=&quot;token string&quot;&gt;&quot;차종&quot;&lt;/span&gt;
        string car_year &lt;span class=&quot;token string&quot;&gt;&quot;연식&quot;&lt;/span&gt;
        string color &lt;span class=&quot;token string&quot;&gt;&quot;색상&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    CAR_WITH_REGION&lt;span class=&quot;token text string&quot;&gt;[&quot;차량2&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        string car_number PK &lt;span class=&quot;token string&quot;&gt;&quot;차량번호&quot;&lt;/span&gt;
        string car_type &lt;span class=&quot;token string&quot;&gt;&quot;차종&quot;&lt;/span&gt;
        string car_year &lt;span class=&quot;token string&quot;&gt;&quot;연식&quot;&lt;/span&gt;
        string color &lt;span class=&quot;token string&quot;&gt;&quot;색상&quot;&lt;/span&gt;
        string region &lt;span class=&quot;token string&quot;&gt;&quot;지역&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;86-데이터-복구를-위한-컬럼-추가&quot;&gt;8.6 데이터 복구를 위한 컬럼 추가&lt;/h3&gt;
&lt;p&gt;현재 주소만 저장하면 주소 변경 이력을 복구하기 어렵다.
이전 값을 보관해야 하는 요구사항이 있다면 이전주소 같은 컬럼을 추가할 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    CUSTOMER&lt;span class=&quot;token text string&quot;&gt;[&quot;고객&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int customer_id PK &lt;span class=&quot;token string&quot;&gt;&quot;고객번호&quot;&lt;/span&gt;
        string customer_name &lt;span class=&quot;token string&quot;&gt;&quot;고객명&quot;&lt;/span&gt;
        string grade &lt;span class=&quot;token string&quot;&gt;&quot;등급&quot;&lt;/span&gt;
        string address &lt;span class=&quot;token string&quot;&gt;&quot;주소&quot;&lt;/span&gt;
        string previous_address &lt;span class=&quot;token string&quot;&gt;&quot;이전주소&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;단, 이력이 여러 건 필요하다면 &lt;code class=&quot;language-text&quot;&gt;이전주소&lt;/code&gt; 컬럼 하나를 추가하기보다 주소 이력 테이블을 별도로 두는 방식이 더 적절하다.&lt;/p&gt;
&lt;h2 id=&quot;9-테이블-반정규화&quot;&gt;9. 테이블 반정규화&lt;/h2&gt;
&lt;p&gt;테이블 반정규화는 컬럼이 아니라 테이블 구조 자체를 조정하는 방식이다.&lt;/p&gt;
&lt;p&gt;대표적인 방식은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;관계 병합&lt;/li&gt;
&lt;li&gt;테이블 분할&lt;/li&gt;
&lt;li&gt;중복 테이블 추가&lt;/li&gt;
&lt;li&gt;통계 테이블 추가&lt;/li&gt;
&lt;li&gt;이력 테이블 추가&lt;/li&gt;
&lt;li&gt;부분 테이블 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;91-슈퍼타입과-서브타입-유지&quot;&gt;9.1 슈퍼타입과 서브타입 유지&lt;/h3&gt;
&lt;p&gt;슈퍼타입과 서브타입을 그대로 분리하면 공통 속성과 개별 속성을 명확히 나눌 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    STUDENT &lt;span class=&quot;token arrow operator&quot;&gt;||..o|&lt;/span&gt; UNDERGRADUATE &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;구체화&quot;&lt;/span&gt;
    STUDENT &lt;span class=&quot;token arrow operator&quot;&gt;||..o|&lt;/span&gt; GRADUATE &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;구체화&quot;&lt;/span&gt;

    STUDENT&lt;span class=&quot;token text string&quot;&gt;[&quot;학생&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int student_id PK &lt;span class=&quot;token string&quot;&gt;&quot;학번&quot;&lt;/span&gt;
        string student_name &lt;span class=&quot;token string&quot;&gt;&quot;이름&quot;&lt;/span&gt;
        date birth_date &lt;span class=&quot;token string&quot;&gt;&quot;생년월일&quot;&lt;/span&gt;
        string phone_number &lt;span class=&quot;token string&quot;&gt;&quot;전화번호&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    UNDERGRADUATE&lt;span class=&quot;token text string&quot;&gt;[&quot;학부생&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int student_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;학번&quot;&lt;/span&gt;
        int grade &lt;span class=&quot;token string&quot;&gt;&quot;학년&quot;&lt;/span&gt;
        string student_club &lt;span class=&quot;token string&quot;&gt;&quot;학회&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    GRADUATE&lt;span class=&quot;token text string&quot;&gt;[&quot;대학원생&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int student_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;학번&quot;&lt;/span&gt;
        string advisor &lt;span class=&quot;token string&quot;&gt;&quot;지도교수&quot;&lt;/span&gt;
        string research_area &lt;span class=&quot;token string&quot;&gt;&quot;연구분야&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이 방식은 정규화 관점에서 명확하지만, 학생의 전체 정보를 조회할 때 조인이 필요하다.&lt;/p&gt;
&lt;h3 id=&quot;92-11-one-to-one&quot;&gt;9.2 1:1 One To One&lt;/h3&gt;
&lt;p&gt;서브타입별 테이블에 공통 속성까지 모두 포함하는 방식이다.
학부생과 대학원생을 완전히 별도 테이블로 관리한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    UNDERGRADUATE&lt;span class=&quot;token text string&quot;&gt;[&quot;학부생&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int student_id PK &lt;span class=&quot;token string&quot;&gt;&quot;학번&quot;&lt;/span&gt;
        string student_name &lt;span class=&quot;token string&quot;&gt;&quot;이름&quot;&lt;/span&gt;
        date birth_date &lt;span class=&quot;token string&quot;&gt;&quot;생년월일&quot;&lt;/span&gt;
        string phone_number &lt;span class=&quot;token string&quot;&gt;&quot;전화번호&quot;&lt;/span&gt;
        int grade &lt;span class=&quot;token string&quot;&gt;&quot;학년&quot;&lt;/span&gt;
        string student_club &lt;span class=&quot;token string&quot;&gt;&quot;학회&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    GRADUATE&lt;span class=&quot;token text string&quot;&gt;[&quot;대학원생&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int student_id PK &lt;span class=&quot;token string&quot;&gt;&quot;학번&quot;&lt;/span&gt;
        string student_name &lt;span class=&quot;token string&quot;&gt;&quot;이름&quot;&lt;/span&gt;
        date birth_date &lt;span class=&quot;token string&quot;&gt;&quot;생년월일&quot;&lt;/span&gt;
        string phone_number &lt;span class=&quot;token string&quot;&gt;&quot;전화번호&quot;&lt;/span&gt;
        string advisor &lt;span class=&quot;token string&quot;&gt;&quot;지도교수&quot;&lt;/span&gt;
        string research_area &lt;span class=&quot;token string&quot;&gt;&quot;연구분야&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;유형별 조회는 단순하지만, 공통 속성이 중복된다.&lt;/p&gt;
&lt;h3 id=&quot;93-all-in-one-single-type&quot;&gt;9.3 All In One Single Type&lt;/h3&gt;
&lt;p&gt;모든 속성을 하나의 테이블에 넣고 학생 유형에 따라 필요한 컬럼만 사용하는 방식이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    STUDENT&lt;span class=&quot;token text string&quot;&gt;[&quot;학생&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int student_id PK &lt;span class=&quot;token string&quot;&gt;&quot;학번&quot;&lt;/span&gt;
        string student_type &lt;span class=&quot;token string&quot;&gt;&quot;학생유형&quot;&lt;/span&gt;
        string student_name &lt;span class=&quot;token string&quot;&gt;&quot;이름&quot;&lt;/span&gt;
        date birth_date &lt;span class=&quot;token string&quot;&gt;&quot;생년월일&quot;&lt;/span&gt;
        string phone_number &lt;span class=&quot;token string&quot;&gt;&quot;전화번호&quot;&lt;/span&gt;
        int grade &lt;span class=&quot;token string&quot;&gt;&quot;학년&quot;&lt;/span&gt;
        string student_club &lt;span class=&quot;token string&quot;&gt;&quot;학회&quot;&lt;/span&gt;
        string advisor &lt;span class=&quot;token string&quot;&gt;&quot;지도교수&quot;&lt;/span&gt;
        string research_area &lt;span class=&quot;token string&quot;&gt;&quot;연구분야&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;조인이 없어 조회가 단순하지만, 특정 유형에만 필요한 컬럼은 &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt;이 많아질 수 있다.&lt;/p&gt;
&lt;h2 id=&quot;10-정리&quot;&gt;10. 정리&lt;/h2&gt;
&lt;p&gt;정규화는 데이터 중복과 이상현상을 줄이기 위한 기본 원칙이다.
반정규화는 정규화 원칙을 일부 깨더라도 조회 성능이나 운영 편의성을 확보해야 할 때 선택하는 설계다.&lt;/p&gt;
&lt;p&gt;중요한 것은 반정규화를 적용할 때마다 데이터 무결성을 어떻게 유지할 것인지 함께 결정하는 것이다.
중복 컬럼, 파생 컬럼, 최근 여부 컬럼은 모두 성능에는 도움이 될 수 있지만, 갱신 로직이 없으면 데이터 정합성을 깨뜨릴 수 있다.&lt;/p&gt;
&lt;p&gt;따라서 모델링 단계에서는 정규화를 먼저 적용하고, 실제 조회 패턴과 성능 요구사항을 확인한 뒤 필요한 부분에만 반정규화를 적용하는 것이 좋다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[Data Modeling] 데이터 모델링 1일차 - 개념/논리/물리 모델링과 ERD 기초]]></title><description><![CDATA[📍 연관 포스팅 [[Data Modeling] 데이터 모델링 1일차 개념/논리/물리 모델링과 ERD 기초](https://woojin devv.github.io/posts/DataModeling 1/) [[Data Modeling] 데이터 모델링 2일차 정규화, 반정규화](https:/]]></description><link>https://woojin-devv.github.io/posts/DataModeling-1/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/DataModeling-1/</guid><pubDate>Wed, 06 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h3 id=&quot;-연관-포스팅&quot;&gt;📍 연관 포스팅&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://woojin-devv.github.io/posts/DataModeling-1/&quot;&gt;[Data Modeling] 데이터 모델링 1일차 - 개념/논리/물리 모델링과 ERD 기초&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://woojin-devv.github.io/posts/DataModeling-2/&quot;&gt;[Data Modeling] 데이터 모델링 2일차 - 정규화, 반정규화&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;1-들어가며&quot;&gt;1. 들어가며&lt;/h2&gt;
&lt;p&gt;이번 글에서는 데이터 모델링의 기본 흐름과 ERD를 작성할 때 자주 만나는 설계 포인트를 정리한다.
데이터 모델링은 단순히 테이블을 만드는 작업이 아니라, 업무에서 관리해야 하는 데이터를 구조화하고 관계를 명확히 정의하는 과정이다.&lt;/p&gt;
&lt;p&gt;실습 도구는 자유롭게 선택해도 되지만, 수업에서는 ERD Cloud와 ERD Editor를 기준으로 개념을 정리했다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;데이터 모델링의 단계&lt;/li&gt;
&lt;li&gt;식별 관계와 비식별 관계&lt;/li&gt;
&lt;li&gt;M:N 관계 해소&lt;/li&gt;
&lt;li&gt;속성의 유형&lt;/li&gt;
&lt;li&gt;설계 속성과 파생 속성&lt;/li&gt;
&lt;li&gt;슈퍼타입과 서브타입&lt;/li&gt;
&lt;li&gt;회사/직원/프로젝트 예제와 설문지 프로젝트 예제&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;2-데이터-모델링의-전체-흐름&quot;&gt;2. 데이터 모델링의 전체 흐름&lt;/h2&gt;
&lt;p&gt;데이터 모델링은 보통 개념 데이터 모델링, 논리 데이터 모델링, 물리 데이터 모델링 순서로 진행된다.
각 단계는 목적이 다르기 때문에 처음부터 컬럼 타입이나 인덱스를 고민하기보다, 먼저 업무에서 어떤 데이터가 필요한지 파악하는 것이 중요하다.&lt;/p&gt;
&lt;h3 id=&quot;21-개념-데이터-모델링&quot;&gt;2.1 개념 데이터 모델링&lt;/h3&gt;
&lt;p&gt;개념 데이터 모델링은 업무에서 관리해야 하는 핵심 엔티티를 추출하고, 전체 데이터 모델의 골격을 만드는 단계다.
이 단계에서는 상세 컬럼보다는 엔티티와 엔티티 사이의 관계를 파악하는 데 집중한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;핵심 엔티티 추출&lt;/li&gt;
&lt;li&gt;전체 데이터 모델의 골격 생성&lt;/li&gt;
&lt;li&gt;개체-관계 다이어그램 작성&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;22-논리-데이터-모델링&quot;&gt;2.2 논리 데이터 모델링&lt;/h3&gt;
&lt;p&gt;논리 데이터 모델링은 개념 모델링에서 정의한 엔티티와 관계를 바탕으로 상세 속성을 정의하는 단계다.
이 단계에서는 식별자를 확정하고, 정규화와 같은 상세화 과정을 수행한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;엔티티별 상세 속성 정의&lt;/li&gt;
&lt;li&gt;식별자 확정&lt;/li&gt;
&lt;li&gt;정규화 수행&lt;/li&gt;
&lt;li&gt;트랜잭션 인터페이스 설계&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;23-물리-데이터-모델링&quot;&gt;2.3 물리 데이터 모델링&lt;/h3&gt;
&lt;p&gt;물리 데이터 모델링은 실제 사용할 DBMS의 특성과 구현 환경을 고려해 스키마를 구체화하는 단계다.
논리 모델을 실제 테이블, 컬럼, 인덱스 구조로 변환한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컬럼의 데이터 타입과 크기 정의&lt;/li&gt;
&lt;li&gt;인덱스 정의&lt;/li&gt;
&lt;li&gt;성능을 고려한 역정규화 검토&lt;/li&gt;
&lt;li&gt;목표 DBMS에 맞는 스키마 도출&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;3-entity와-relationship-설계&quot;&gt;3. Entity와 Relationship 설계&lt;/h2&gt;
&lt;h3 id=&quot;31-entity-도출&quot;&gt;3.1 Entity 도출&lt;/h3&gt;
&lt;p&gt;엔티티는 업무에서 독립적으로 관리할 필요가 있는 데이터의 집합이다.
예를 들어 회사 관리 시스템에서는 회사, 부서, 직원, 프로젝트, 부양가족 등이 엔티티 후보가 될 수 있다.&lt;/p&gt;
&lt;p&gt;엔티티를 도출할 때는 다음 질문을 기준으로 판단하면 좋다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;업무에서 독립적으로 관리해야 하는 대상인가?&lt;/li&gt;
&lt;li&gt;여러 개의 인스턴스가 존재할 수 있는가?&lt;/li&gt;
&lt;li&gt;속성을 가질 수 있는가?&lt;/li&gt;
&lt;li&gt;다른 엔티티와 관계를 맺는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;32-식별-관계와-비식별-관계&quot;&gt;3.2 식별 관계와 비식별 관계&lt;/h3&gt;
&lt;p&gt;식별 관계와 비식별 관계는 부모 엔티티의 키가 자식 엔티티에서 어떤 역할을 하는지에 따라 구분된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;식별 관계: 부모 테이블의 키가 자식 테이블로 전이되었을 때, 자식 테이블의 기본키에 포함되는 관계&lt;/li&gt;
&lt;li&gt;비식별 관계: 부모 테이블의 키가 자식 테이블로 전이되었지만, 자식 테이블의 일반 외래키로만 사용되는 관계&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ERD에서는 보통 식별 관계를 실선, 비식별 관계를 점선으로 표현한다.
예를 들어 부서와 사원이 있을 때, 사원이 반드시 부서의 키를 자신의 기본키로 포함해야 하는 구조라면 식별 관계가 된다.
반대로 사원 테이블이 별도의 사원번호를 기본키로 가지고, 부서번호는 소속을 나타내는 외래키로만 사용된다면 비식별 관계가 된다.&lt;/p&gt;
&lt;h3 id=&quot;33-mn-관계-해소&quot;&gt;3.3 M:N 관계 해소&lt;/h3&gt;
&lt;p&gt;관계형 데이터베이스에서는 M:N 관계를 직접 표현하기 어렵기 때문에, 보통 중간 테이블을 만들어 1:N 관계 두 개로 분해한다.&lt;/p&gt;
&lt;p&gt;예를 들어 책과 저자의 관계를 생각해보면, 한 권의 책은 여러 저자를 가질 수 있고 한 명의 저자도 여러 책을 쓸 수 있다.
이 경우 책과 저자 사이에 &lt;code class=&quot;language-text&quot;&gt;책_저자&lt;/code&gt; 같은 연결 테이블을 둔다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    BOOK &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; BOOK_AUTHOR &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;포함&quot;&lt;/span&gt;
    AUTHOR &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; BOOK_AUTHOR &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;참여&quot;&lt;/span&gt;

    BOOK&lt;span class=&quot;token text string&quot;&gt;[&quot;책&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int book_id PK &lt;span class=&quot;token string&quot;&gt;&quot;책ID&quot;&lt;/span&gt;
        string book_name &lt;span class=&quot;token string&quot;&gt;&quot;책이름&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    AUTHOR&lt;span class=&quot;token text string&quot;&gt;[&quot;저자&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int author_id PK &lt;span class=&quot;token string&quot;&gt;&quot;저자ID&quot;&lt;/span&gt;
        string author_name &lt;span class=&quot;token string&quot;&gt;&quot;저자이름&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    BOOK_AUTHOR&lt;span class=&quot;token text string&quot;&gt;[&quot;책_저자&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int book_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;책ID&quot;&lt;/span&gt;
        int author_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;저자ID&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;다만 조회 성능을 이유로 연결 테이블에 &lt;code class=&quot;language-text&quot;&gt;책이름&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;저자이름&lt;/code&gt; 같은 값을 함께 저장하고 싶어질 수 있다.
하지만 이는 책 이름이 책 ID에 종속되고, 저자 이름이 저자 ID에 종속되는 구조이므로 2정규형을 위반한다.&lt;/p&gt;
&lt;p&gt;성능 때문에 반정규화를 선택할 수는 있지만, 이 경우 데이터 중복과 무결성 문제가 발생한다.
저자 이름이 변경되었을 때 중복 저장된 값이 함께 변경되지 않으면 데이터 정합성이 깨진다.
반정규화를 적용해야 한다면 Trigger, 계산 컬럼, 배치 작업 등으로 정합성을 유지할 방법을 함께 설계해야 한다.&lt;/p&gt;
&lt;h2 id=&quot;4-attribute-설계&quot;&gt;4. Attribute 설계&lt;/h2&gt;
&lt;p&gt;속성은 엔티티의 성질, 분류, 수량, 상태, 특성 등을 나타내는 세부 항목이다.
엔티티가 어떤 데이터를 보관해야 하는지 구체화하는 단계에서 속성을 정의한다.&lt;/p&gt;
&lt;h3 id=&quot;41-기본-속성&quot;&gt;4.1 기본 속성&lt;/h3&gt;
&lt;p&gt;기본 속성은 해당 엔티티가 업무적으로 원래 가지고 있는 속성이다.
예를 들어 직원 엔티티의 직원명, 주소, 급여, 성별, 생년월일 등은 기본 속성에 해당한다.&lt;/p&gt;
&lt;h3 id=&quot;42-설계-속성&quot;&gt;4.2 설계 속성&lt;/h3&gt;
&lt;p&gt;설계 속성은 원래 업무에는 존재하지 않지만, 시스템의 효율성이나 식별을 위해 임의로 추가하는 속성이다.
대표적으로 코드, 일련번호, 순번 같은 값이 있다.&lt;/p&gt;
&lt;p&gt;예를 들어 고객센터 장애 조치 이력을 관리한다고 가정해보자.
한 고객에게 여러 번 방문할 수 있는데, 방문일자를 기본키에 포함하면 같은 날 여러 번 방문하는 경우를 표현하기 어렵다.
방문일시를 분 단위까지 늘릴 수도 있지만, 키 값이 길어지고 관리가 복잡해진다.&lt;/p&gt;
&lt;p&gt;이럴 때 방문 순번 같은 설계 속성을 추가하면 중복을 방지하면서 방문 이력을 안정적으로 식별할 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    CUSTOMER &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; VISIT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;요청&quot;&lt;/span&gt;

    CUSTOMER&lt;span class=&quot;token text string&quot;&gt;[&quot;고객&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int customer_id PK &lt;span class=&quot;token string&quot;&gt;&quot;고객번호&quot;&lt;/span&gt;
        string customer_name &lt;span class=&quot;token string&quot;&gt;&quot;고객명&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    VISIT&lt;span class=&quot;token text string&quot;&gt;[&quot;방문&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int customer_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;고객번호&quot;&lt;/span&gt;
        int visit_seq PK &lt;span class=&quot;token string&quot;&gt;&quot;방문순번&quot;&lt;/span&gt;
        datetime visited_at &lt;span class=&quot;token string&quot;&gt;&quot;방문일시&quot;&lt;/span&gt;
        string visit_content &lt;span class=&quot;token string&quot;&gt;&quot;방문내용&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;43-파생-속성&quot;&gt;4.3 파생 속성&lt;/h3&gt;
&lt;p&gt;파생 속성은 다른 속성이나 다른 테이블의 데이터로부터 계산하거나 변형해서 얻을 수 있는 속성이다.
파생 속성은 데이터 중복과 무결성 문제를 만들 수 있기 때문에 가급적 적게 정의하는 것이 좋다.&lt;/p&gt;
&lt;p&gt;예를 들어 사원 테이블에 &lt;code class=&quot;language-text&quot;&gt;부양자수&lt;/code&gt; 컬럼을 저장하는 경우를 생각해볼 수 있다.
부양자수는 부양가족 테이블에서 &lt;code class=&quot;language-text&quot;&gt;COUNT(*)&lt;/code&gt;로 계산할 수 있는 값이므로 파생 속성이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    EMPLOYEE &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; DEPENDENT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;가짐&quot;&lt;/span&gt;

    EMPLOYEE&lt;span class=&quot;token text string&quot;&gt;[&quot;사원&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int employee_id PK &lt;span class=&quot;token string&quot;&gt;&quot;사원번호&quot;&lt;/span&gt;
        string employee_name &lt;span class=&quot;token string&quot;&gt;&quot;사원명&quot;&lt;/span&gt;
        int dependent_count &lt;span class=&quot;token string&quot;&gt;&quot;부양자수&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    DEPENDENT&lt;span class=&quot;token text string&quot;&gt;[&quot;부양가족&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int employee_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;사원번호&quot;&lt;/span&gt;
        string dependent_name PK &lt;span class=&quot;token string&quot;&gt;&quot;부양가족명&quot;&lt;/span&gt;
        string relationship &lt;span class=&quot;token string&quot;&gt;&quot;관계&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;사원.부양자수&lt;/code&gt;를 별도 컬럼으로 저장하면 부양가족 데이터가 추가, 수정, 삭제될 때마다 함께 갱신해야 한다.
만약 실제 부양가족은 3명인데 사원 테이블의 부양자수가 2명이라면 데이터 정합성이 깨진 상태가 된다.&lt;/p&gt;
&lt;p&gt;따라서 부양자수는 기본적으로 조회 시점에 계산하는 것이 적절하다.
성능상 반드시 저장해야 한다면 Trigger, Computed Column, 배치 작업 등을 통해 정합성을 유지해야 한다.&lt;/p&gt;
&lt;h2 id=&quot;5-설계-시-주의해야-할-문제&quot;&gt;5. 설계 시 주의해야 할 문제&lt;/h2&gt;
&lt;h3 id=&quot;51-중복-속성-문제&quot;&gt;5.1 중복 속성 문제&lt;/h3&gt;
&lt;p&gt;방문1일시, 방문1내용, 방문2일시, 방문2내용처럼 반복되는 속성을 컬럼으로 계속 추가하는 방식은 좋지 않다.
방문 횟수가 늘어날 때마다 테이블 구조를 변경해야 하고, 조회와 관리도 어려워진다.&lt;/p&gt;
&lt;p&gt;이런 경우 반복되는 속성을 별도의 엔티티로 분리해야 한다.
방문은 고객에 종속된 반복 데이터이므로 방문 테이블을 따로 만들고, 고객과 방문을 1:N 관계로 설계하는 것이 적절하다.&lt;/p&gt;
&lt;h3 id=&quot;52-파생-속성의-정합성-문제&quot;&gt;5.2 파생 속성의 정합성 문제&lt;/h3&gt;
&lt;p&gt;파생 속성은 편리하지만 정합성 문제가 발생하기 쉽다.
다른 테이블에서 계산 가능한 값을 컬럼으로 저장하면, 원본 데이터가 변경될 때 파생 컬럼도 함께 갱신되어야 한다.&lt;/p&gt;
&lt;p&gt;따라서 파생 속성을 저장할 때는 다음 기준을 함께 검토해야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;조회 성능상 정말 저장이 필요한가?&lt;/li&gt;
&lt;li&gt;원본 데이터 변경 시 파생 값을 어떻게 갱신할 것인가?&lt;/li&gt;
&lt;li&gt;Trigger, 계산 컬럼, 배치 작업 중 어떤 방식이 적절한가?&lt;/li&gt;
&lt;li&gt;데이터 불일치가 발생했을 때 검증할 수 있는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;53-반정규화와-성능-사이의-균형&quot;&gt;5.3 반정규화와 성능 사이의 균형&lt;/h3&gt;
&lt;p&gt;정규화는 데이터 중복을 줄이고 무결성을 높이는 데 도움이 된다.
하지만 모든 조회에서 여러 테이블 조인이 반복되면 성능 문제가 발생할 수 있다.&lt;/p&gt;
&lt;p&gt;예를 들어 책 ID, 저자 ID, 책 이름, 저자 이름을 자주 조회해야 한다면 책, 저자, 책_저자 세 테이블을 매번 조인해야 한다.
이 경우 성능 요구사항에 따라 일부 값을 중복 저장하는 반정규화를 검토할 수 있다.&lt;/p&gt;
&lt;p&gt;다만 반정규화는 정규화 위반을 의도적으로 감수하는 설계다.
따라서 성능 이점과 데이터 무결성 비용을 함께 판단해야 한다.&lt;/p&gt;
&lt;h2 id=&quot;6-슈퍼타입과-서브타입&quot;&gt;6. 슈퍼타입과 서브타입&lt;/h2&gt;
&lt;p&gt;슈퍼타입과 서브타입은 공통 속성과 개별 속성을 분리하기 위한 모델링 방식이다.
슈퍼타입은 공통사항을 추상화한 부모 엔티티이고, 서브타입은 구체적인 유형을 나타내는 자식 엔티티다.&lt;/p&gt;
&lt;p&gt;예를 들어 사원이라는 공통 개념 아래에 기술직과 관리직이 있을 수 있다.
사원 테이블에는 모든 사원이 공통으로 가지는 속성을 두고, 기술직과 관리직 테이블에는 각 유형만 가지는 속성을 둔다.&lt;/p&gt;
&lt;p&gt;배타적 관계는 슈퍼타입의 하나의 인스턴스가 여러 서브타입 중 반드시 하나의 서브타입에만 속하는 관계를 말한다.
즉, 어떤 사원은 기술직이거나 관리직이며 동시에 두 유형에 속하지 않는 구조다.&lt;/p&gt;
&lt;h2 id=&quot;7-실습-erd-정리&quot;&gt;7. 실습 ERD 정리&lt;/h2&gt;
&lt;h3 id=&quot;71-회사-부서-직원-프로젝트-예제&quot;&gt;7.1 회사-부서-직원-프로젝트 예제&lt;/h3&gt;
&lt;p&gt;다음은 회사, 부서, 직원, 프로젝트, 지역, 부양가족을 기준으로 정리한 ERD 예제다.
직원과 프로젝트는 M:N 관계이므로 &lt;code class=&quot;language-text&quot;&gt;직원_프로젝트&lt;/code&gt; 연결 테이블로 해소한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    COMPANY &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; DEPARTMENT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;구성&quot;&lt;/span&gt;
    DEPARTMENT &lt;span class=&quot;token arrow operator&quot;&gt;||..o{&lt;/span&gt; EMPLOYEE &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;소속&quot;&lt;/span&gt;
    EMPLOYEE &lt;span class=&quot;token arrow operator&quot;&gt;||..o|&lt;/span&gt; DEPARTMENT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;관리&quot;&lt;/span&gt;
    DEPARTMENT &lt;span class=&quot;token arrow operator&quot;&gt;||..o{&lt;/span&gt; LOCATION &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;위치&quot;&lt;/span&gt;
    DEPARTMENT &lt;span class=&quot;token arrow operator&quot;&gt;||..o{&lt;/span&gt; PROJECT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;관리&quot;&lt;/span&gt;
    EMPLOYEE &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; EMPLOYEE_PROJECT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;참여&quot;&lt;/span&gt;
    PROJECT &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; EMPLOYEE_PROJECT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;포함&quot;&lt;/span&gt;
    EMPLOYEE &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; DEPENDENT &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;가짐&quot;&lt;/span&gt;
    EMPLOYEE &lt;span class=&quot;token arrow operator&quot;&gt;||..o{&lt;/span&gt; EMPLOYEE &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;감독&quot;&lt;/span&gt;
    PROJECT &lt;span class=&quot;token arrow operator&quot;&gt;||..||&lt;/span&gt; LOCATION &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;위치&quot;&lt;/span&gt;

    COMPANY&lt;span class=&quot;token text string&quot;&gt;[&quot;회사&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int company_id PK &lt;span class=&quot;token string&quot;&gt;&quot;회사번호&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    DEPARTMENT&lt;span class=&quot;token text string&quot;&gt;[&quot;부서&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int department_id PK &lt;span class=&quot;token string&quot;&gt;&quot;부서번호&quot;&lt;/span&gt;
        int company_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;회사번호&quot;&lt;/span&gt;
        int manager_employee_id FK &lt;span class=&quot;token string&quot;&gt;&quot;관리자직원번호&quot;&lt;/span&gt;
        string department_name &lt;span class=&quot;token string&quot;&gt;&quot;부서명&quot;&lt;/span&gt;
        int employee_count &lt;span class=&quot;token string&quot;&gt;&quot;부서내직원수&quot;&lt;/span&gt;
        date manager_started_at &lt;span class=&quot;token string&quot;&gt;&quot;관리자근무시작일&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    LOCATION&lt;span class=&quot;token text string&quot;&gt;[&quot;지역&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int location_id PK &lt;span class=&quot;token string&quot;&gt;&quot;지역ID&quot;&lt;/span&gt;
        int department_id FK &lt;span class=&quot;token string&quot;&gt;&quot;부서번호&quot;&lt;/span&gt;
        string location_name &lt;span class=&quot;token string&quot;&gt;&quot;지역명&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    PROJECT&lt;span class=&quot;token text string&quot;&gt;[&quot;프로젝트&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int project_id PK &lt;span class=&quot;token string&quot;&gt;&quot;프로젝트번호&quot;&lt;/span&gt;
        int department_id FK &lt;span class=&quot;token string&quot;&gt;&quot;부서번호&quot;&lt;/span&gt;
        int location_id FK &lt;span class=&quot;token string&quot;&gt;&quot;지역ID&quot;&lt;/span&gt;
        string project_name &lt;span class=&quot;token string&quot;&gt;&quot;프로젝트명&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    EMPLOYEE&lt;span class=&quot;token text string&quot;&gt;[&quot;직원&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int employee_id PK &lt;span class=&quot;token string&quot;&gt;&quot;직원번호&quot;&lt;/span&gt;
        int supervisor_employee_id FK &lt;span class=&quot;token string&quot;&gt;&quot;직속상사직원번호&quot;&lt;/span&gt;
        int department_id FK &lt;span class=&quot;token string&quot;&gt;&quot;부서번호&quot;&lt;/span&gt;
        string resident_number &lt;span class=&quot;token string&quot;&gt;&quot;주민번호&quot;&lt;/span&gt;
        string employee_name &lt;span class=&quot;token string&quot;&gt;&quot;직원명&quot;&lt;/span&gt;
        string address &lt;span class=&quot;token string&quot;&gt;&quot;주소&quot;&lt;/span&gt;
        int salary &lt;span class=&quot;token string&quot;&gt;&quot;급여&quot;&lt;/span&gt;
        string gender &lt;span class=&quot;token string&quot;&gt;&quot;성별&quot;&lt;/span&gt;
        date birth_date &lt;span class=&quot;token string&quot;&gt;&quot;생년월일&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    EMPLOYEE_PROJECT&lt;span class=&quot;token text string&quot;&gt;[&quot;직원_프로젝트&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int employee_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;직원번호&quot;&lt;/span&gt;
        int project_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;프로젝트번호&quot;&lt;/span&gt;
        int work_hours &lt;span class=&quot;token string&quot;&gt;&quot;근무시간&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    DEPENDENT&lt;span class=&quot;token text string&quot;&gt;[&quot;부양가족&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        string dependent_name PK &lt;span class=&quot;token string&quot;&gt;&quot;부양가족명&quot;&lt;/span&gt;
        int employee_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;직원번호&quot;&lt;/span&gt;
        string gender &lt;span class=&quot;token string&quot;&gt;&quot;성별&quot;&lt;/span&gt;
        date birth_date &lt;span class=&quot;token string&quot;&gt;&quot;생년월일&quot;&lt;/span&gt;
        string relationship &lt;span class=&quot;token string&quot;&gt;&quot;관계&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;72-설문지-프로젝트-예제&quot;&gt;7.2 설문지 프로젝트 예제&lt;/h3&gt;
&lt;p&gt;설문지 프로젝트에서는 설문지, 설문지항목, 설문지문항을 엔티티로 도출할 수 있다.
하나의 설문지는 여러 항목을 가지고, 하나의 항목은 여러 문항을 가진다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre class=&quot;language-mermaid&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;erDiagram&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;direction&lt;/span&gt; LR
    SURVEY &lt;span class=&quot;token arrow operator&quot;&gt;||--o{&lt;/span&gt; SURVEY_ITEM &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;포함&quot;&lt;/span&gt;
    SURVEY_ITEM &lt;span class=&quot;token arrow operator&quot;&gt;||--|{&lt;/span&gt; SURVEY_OPTION &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;구성&quot;&lt;/span&gt;

    SURVEY&lt;span class=&quot;token text string&quot;&gt;[&quot;설문지&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int survey_id PK &lt;span class=&quot;token string&quot;&gt;&quot;설문지번호&quot;&lt;/span&gt;
        string title &lt;span class=&quot;token string&quot;&gt;&quot;제목&quot;&lt;/span&gt;
        date created_at &lt;span class=&quot;token string&quot;&gt;&quot;작성일자&quot;&lt;/span&gt;
        date started_at &lt;span class=&quot;token string&quot;&gt;&quot;설문지시작일&quot;&lt;/span&gt;
        date ended_at &lt;span class=&quot;token string&quot;&gt;&quot;설문지종료일&quot;&lt;/span&gt;
        string is_closed &lt;span class=&quot;token string&quot;&gt;&quot;설문지작성마감여부&quot;&lt;/span&gt;
        string description &lt;span class=&quot;token string&quot;&gt;&quot;설명&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    SURVEY_ITEM&lt;span class=&quot;token text string&quot;&gt;[&quot;설문지항목&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int question_id PK &lt;span class=&quot;token string&quot;&gt;&quot;문제번호&quot;&lt;/span&gt;
        string question &lt;span class=&quot;token string&quot;&gt;&quot;문제&quot;&lt;/span&gt;
        int survey_id FK &lt;span class=&quot;token string&quot;&gt;&quot;설문지번호&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    SURVEY_OPTION&lt;span class=&quot;token text string&quot;&gt;[&quot;설문지문항&quot;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        int survey_id PK, FK &lt;span class=&quot;token string&quot;&gt;&quot;설문지번호&quot;&lt;/span&gt;
        int question_id FK &lt;span class=&quot;token string&quot;&gt;&quot;문제번호&quot;&lt;/span&gt;
        int option_id &lt;span class=&quot;token string&quot;&gt;&quot;문항번호&quot;&lt;/span&gt;
        string option_content &lt;span class=&quot;token string&quot;&gt;&quot;문항내용&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;8-오늘의-회고&quot;&gt;8. 오늘의 회고&lt;/h2&gt;
&lt;p&gt;데이터 모델링에서 중요한 것은 테이블을 빠르게 만드는 것이 아니라, 업무 규칙을 데이터 구조로 정확하게 표현하는 것이다.
특히 M:N 관계 해소, 식별 관계와 비식별 관계 구분, 파생 속성의 저장 여부는 실제 설계에서 자주 고민해야 하는 부분이다.&lt;/p&gt;
&lt;p&gt;정규화는 데이터 무결성을 지키기 위한 기본 원칙이고, 반정규화는 성능 요구사항 때문에 선택하는 예외적인 설계다.
따라서 반정규화를 적용할 때는 중복 데이터의 정합성을 어떻게 유지할지까지 함께 설계해야 한다.&lt;/p&gt;
&lt;h2 id=&quot;참고자료&quot;&gt;참고자료&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/@atmega328mu/db-%EA%B0%9C%EC%B2%B4-%EA%B0%84%EC%9D%98-%EA%B4%80%EA%B3%84%EB%93%A4-e712303b76fb&quot;&gt;DB - 개체 간의 관계들&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[008] 자바 인터페이스 정리]]></title><description><![CDATA[개선된 for문 인터페이스 인터페이스는 소프트웨어 설계 최상위 단계 인터페이스는 무에서 유를 창조 인터페이스란? 약속, 규칙, 규약, 표준 을 만드는 행위를 말함 표준이란? 아이폰의 C타입 충전 볼트를 조일 때 오른쪽 엘리베이터의 상승 버튼 (삼각형)등 ISO(International ]]></description><link>https://woojin-devv.github.io/posts/java-interface/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/java-interface/</guid><pubDate>Mon, 13 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;개선된-for문&quot;&gt;개선된 for문&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;타입 변수명 &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; 배열이나컬렉션&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 반복 실행할 코드&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 1차원 배열 &lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; scores &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; sum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; score &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; scores&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    sum &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; score&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 다차원 배열 &lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; matrix &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; row &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; matrix&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;// 1. matrix에서 1차원 배열(행)을 꺼냄&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; value &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; row&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// 2. 꺼낸 행에서 실제 값(int)을 꺼냄&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;인터페이스&quot;&gt;인터페이스&lt;/h2&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;인터페이스는 소프트웨어 설계 최상위 단계&lt;/li&gt;
&lt;li&gt;인터페이스는 무에서 유를 창조&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;인터페이스란?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;약속, 규칙, 규약, 표준&lt;/strong&gt;을 만드는 행위를 말함&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;표준이란?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;아이폰의 C타입 충전&lt;/li&gt;
&lt;li&gt;볼트를 조일 때 오른쪽&lt;/li&gt;
&lt;li&gt;엘리베이터의 상승 버튼 (삼각형)등&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;ISO(International Organization for Standardization) 표준 : 국가&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;인터페이스는 약속(규약)만 존재하며, 구현부는 존재하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;추상클래스와-인터페이스의-공통점&quot;&gt;추상클래스와 인터페이스의 공통점&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;스스로 객체를 만들 수 없다. (구현부가 존재하지 않는다.  - new 연산자 사용 불가 )&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;차이점 ?&lt;/p&gt;
&lt;p&gt;추상 (완성 + 미완성의 결합) , 인터페이스 (미완성 자원)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;추상클래스 &lt;code class=&quot;language-text&quot;&gt;extends&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;인터페이스 &lt;code class=&quot;language-text&quot;&gt;implements&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Car&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AbClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;//상속&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Car&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Object&lt;/span&gt; implemenets &lt;span class=&quot;token class-name&quot;&gt;Ia&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// 구현&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Car는 Object를 상속하고, Ia를 구현한다. &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;둘 다 추상자원 (실행 블럭이 없다) → 미완성 자원&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;⇒ 강제적 구현&lt;/strong&gt;&lt;/em&gt; 이 목적이다.  → 재정의 (override) 해야 함.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;다른점&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;다중상속 : 인터페이스는 다중 상속(구현)&lt;/p&gt;
&lt;p&gt;약속의 범위는 작게 하는 것이 좋다 . (재사용성 높게 하기 위함)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;인터페이스끼리는 서로 상속이 가능 ⇒ 약속을 더 크게(?)&lt;/li&gt;
&lt;li&gt;인터페이스 구현하는 입장에서 보면 다중 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Ia, Ib, Ic&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Ia&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Ib&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Ic&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;인터페이스는 (상수를 제외한 나머지는 추상함수 ) &gt; JDK8 (default, static)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;초급 개발자의 시선에서 바라보면,
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;인터페이스는 [다형성] 입장으로 접근 (70 ~ 80 % 해결) ; 인터페이스는 부모 타입&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;서로 연관성이 없는 클래스를 하나로 묶어주는 역할⭐️⭐️⭐️&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;같은 부모를 가지므로..&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자바 만든 아저씨 &gt;&gt; JAVA API 당신이 설계한 왠만한 것들을 만들어줄게 &gt;&gt; 수많은 인터페이스 활용&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;인터페이스의 해석은 (~able ; ~할 수 있는)으로 해석됨.&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;날 수 있는&lt;/li&gt;
&lt;li&gt;수리할 수 있는&lt;/li&gt;
&lt;li&gt;먹을 수 있는&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;객체간 연결 고리 (객체간 소통의 역할 ) : 다형성의 원리로 접근&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;interface-summary&quot;&gt;interface summary&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;실제 구현부를 가지고 있지 않다. &gt; 실행 블럭이 없다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Interfacte Iable { void move(int x, int y); }&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;JAVA API → Collection &gt; List, Set, Map을 이해해야 함&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;1-interface-생성&quot;&gt;#1 Interface 생성&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Ia&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 상수 구현 &lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// public static final int VERSION = 1; -&gt; 컴파일러는 인터페이스가 가지고 있는 모든 자원을 상수로 취급함&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;VERSION&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 앞에 public static final이 생략됨. &lt;/span&gt;
	
	&lt;span class=&quot;token comment&quot;&gt;// 추상 함수 &lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// public abstract void run();&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 앞에 public abstract 컴파일러가 자동으로 붙임 &lt;/span&gt;
	
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-ia와-ib는-같음&quot;&gt;#2 Ia와 Ib는 같음&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Ia&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;AGE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;GENDER&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;남&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; str&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Ib&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;AGE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Gender&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;남&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; str&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-interface-구현부--상속--override&quot;&gt;#3 Interface 구현부 &gt; 상속 &amp;#x26; Override&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Test2&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Ib&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Ic&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// TODO Auto-generated method stub&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; str&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// TODO Auto-generated method stub&lt;/span&gt;

	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Ex03_Interface&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;Test2&lt;/span&gt; test2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Test2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;token class-name&quot;&gt;Ib&lt;/span&gt; ib &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; test2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ib&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;AGE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;ib&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;Gender&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ib&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/java-study/08/1.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;quiz--인터페이스에서&quot;&gt;Quiz.  인터페이스에서&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;정답&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;p&gt;해설 : 모든 참조 타입은 Object 메서드를 사용할 수 있도록 허용한다.&lt;/p&gt;
&lt;p&gt;인터페이스 타입도 자바의 참조 타입이기 때문에, Object의 자원을 사용할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[OOP] 템플릿 메서드 패턴 정리]]></title><description><![CDATA[1. 템플릿 메서드 패턴이란? 작업의 뼈대는 미리 정해두고 구체적인 단계는 자식 클래스에서 구현하게 만든 패턴. 상위 클래스에서 실행 프로세스의 순서를 정의하고, 그 일부 단계를 abstract 메서드나 상속 가능한 메서드로 비워둔다. 알고리즘의 뼈대 자식이 건들이지 못하도록 final]]></description><link>https://woojin-devv.github.io/posts/template-method-pattern/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/template-method-pattern/</guid><pubDate>Mon, 13 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;1-템플릿-메서드-패턴이란&quot;&gt;1. 템플릿 메서드 패턴이란?&lt;/h2&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;작업의 뼈대는 미리 정해두고 구체적인 단계는 자식 클래스에서 구현하게 만든 패턴.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;상위 클래스에서 실행 프로세스의 순서를 정의하고, 그 일부 단계를 &lt;code class=&quot;language-text&quot;&gt;abstract&lt;/code&gt; 메서드나 상속 가능한 메서드로 비워둔다.
&lt;ul&gt;
&lt;li&gt;알고리즘의 뼈대&lt;/li&gt;
&lt;li&gt;자식이 건들이지 못하도록 &lt;code class=&quot;language-text&quot;&gt;final&lt;/code&gt; 로 선언함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;하위 클래스에서는 해당 상위 클래스를 오버라이딩 세부 로직을 채우는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;구조&quot;&gt;구조&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Template Method&lt;/strong&gt; : 알고리즘의 전체 흐름을 정의 (변경 불가)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Primitive Operations (추상 메서드)&lt;/strong&gt;: 하위 클래스가 구현해야 하는 부분&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hook (선택적 메서드)&lt;/strong&gt; : 기본 구현이 있지만, 필요시 오버라이드 가능&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;2-언제-사용하나&quot;&gt;2. 언제 사용하나?&lt;/h2&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li&gt;알고리즘 구조가 동일할 때 but. 일부 단계만 다를때&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;순서를 강제해야할 때&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;파일 처리 로직 (열기 → 읽기 → 닫기)&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;게임 턴 처리&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;[턴 시작] → [행동 선택] → [행동 수행] → [결과 처리] → [턴 종료]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Spring Framework의 &lt;code class=&quot;language-text&quot;&gt;JdbcTemplate&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;커넥션 생성&lt;/li&gt;
&lt;li&gt;쿼리 실행 (개발자가 정의)&lt;/li&gt;
&lt;li&gt;ResultSet 처리 (개발자가 정의)&lt;/li&gt;
&lt;li&gt;커넥션 반환&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;API 요청 처리&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;요청 검증&lt;/li&gt;
&lt;li&gt;인증 / 인가 체크&lt;/li&gt;
&lt;li&gt;비즈니스 로직 실행&lt;/li&gt;
&lt;li&gt;응답 생성&lt;/li&gt;
&lt;li&gt;로깅&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;로그 / 트랜잭션 처리&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;트랜잭션 시작&lt;/li&gt;
&lt;li&gt;비즈니스 로직 실행&lt;/li&gt;
&lt;li&gt;커밋 or 롤백&lt;/li&gt;
&lt;li&gt;로그 기록&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;코드의 중복을 줄이고 싶을 때&lt;/li&gt;
&lt;li&gt;확장을 제어하고 싶을 때&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;1-추상-클래스-부모&quot;&gt;1. 추상 클래스 (부모)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;알고리즘의 뼈대를 정의함.&lt;/p&gt;
&lt;p&gt;공통 로직은 직접 구현하고, 달라지는 로직은 추상 메서드로 비워둠&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CaffeineBeverage&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 템플릿 메서드: 실행 순서를 정의하며, 자식이 오버라이드 하지 못하도록 final 선언&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;prepareRecipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;boilWater&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;brew&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;pourInCup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;addCondiments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 공통 로직&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;boilWater&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;물 끓이는 중...&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pourInCup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;컵에 붓는 중...&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 상세 구현은 자식에게 맡김&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;brew&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addCondiments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-구체-클래스-자식&quot;&gt;2. 구체 클래스 (자식)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;부모가 비워든 메서드를 상황에 맞게 구현&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Coffee&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CaffeineBeverage&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 자식은 추상화(부모) 클래스를 상속 받음&lt;/span&gt;
    
    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;brew&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;필터를 통해 커피를 우려내는 중...&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addCondiments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;설탕과 우유를 추가하는 중...&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Tea&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CaffeineBeverage&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;brew&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;찻잎을 우려내는 중...&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addCondiments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;레몬을 추가하는 중...&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-메인-실행부&quot;&gt;3. 메인 실행부&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Main&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;CaffeineBeverage&lt;/span&gt; coffee &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Coffee&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;CaffeineBeverage&lt;/span&gt; tea &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Tea&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;--- 커피 준비 ---&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        coffee&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;prepareRecipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &lt;/span&gt;

        &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;\n--- 차 준비 ---&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        tea&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;prepareRecipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;3-템플릿-메서드의-장단점&quot;&gt;3. 템플릿 메서드의 장/단점&lt;/h2&gt;
&lt;h3 id=&quot;장점&quot;&gt;장점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;코드 중복 제거&lt;/li&gt;
&lt;li&gt;알고리즘 구조 통일&lt;/li&gt;
&lt;li&gt;확장성 용이 (OCP 만족)&lt;/li&gt;
&lt;li&gt;상위 클래스가 흐름 통제&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;단점&quot;&gt;단점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;상속 기반 → 유연성 제한&lt;/li&gt;
&lt;li&gt;클래스 수 증가&lt;/li&gt;
&lt;li&gt;런타임 변경 어려움 (컴파일 시 결정됨)&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[4주차 - 네트워크]]></title><description><![CDATA[🌐 HTTP 상태 코드(Status Code) 핵심 요약 HTTP 상태 코드는 클라이언트가 보낸 요청에 대해 서버가 어떤 상태인지 알려주는 3자리 숫자이다. 각 앞자리에 따라 대략적인 상태를 파악할 수 있다. 1xx (Informational) : 정보 전달 서버가 요청을 받았으며, 해]]></description><link>https://woojin-devv.github.io/posts/cs-interview-study-4/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/cs-interview-study-4/</guid><pubDate>Sun, 12 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;-http-상태-코드status-code-핵심-요약&quot;&gt;🌐 HTTP 상태 코드(Status Code) 핵심 요약&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;HTTP 상태 코드는 클라이언트가 보낸 요청에 대해 서버가 어떤 상태인지 알려주는 3자리 숫자이다. 각 앞자리에 따라 대략적인 상태를 파악할 수 있다.&lt;/p&gt;
&lt;h3 id=&quot;1xx-informational--정보-전달&quot;&gt;1xx (Informational) : 정보 전달&lt;/h3&gt;
&lt;p&gt;서버가 요청을 받았으며, 해당 프로세스를 계속 진행 중임을 의미한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;100 Continue&lt;/strong&gt;: 요청의 시작 부분이 서버에 수용되었으니, 나머지 요청을 계속 보내도 좋다는 것을 뜻한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2xx-successful--성공&quot;&gt;2xx (Successful) : 성공&lt;/h3&gt;
&lt;p&gt;서버가 클라이언트의 요청을 성공적으로 수신하고 처리했음을 의미한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;200 OK&lt;/strong&gt;: 요청이 성공적으로 완료되었음을 나타낸다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;201 Created&lt;/strong&gt;: 요청이 성공적이었으며, 그 결과로 새로운 리소스가 서버에 생성되었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3xx-redirection--리다이렉션&quot;&gt;3xx (Redirection) : 리다이렉션&lt;/h3&gt;
&lt;p&gt;요청을 완료하기 위해 클라이언트 측에서 추가적인 조치가 필요함을 의미한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;301 Moved Permanently&lt;/strong&gt;: 요청한 리소스의 URI가 영구적으로 변경되었음을 의미한다.
&lt;ul&gt;
&lt;li&gt;예: 서버가 &lt;code class=&quot;language-text&quot;&gt;/api&lt;/code&gt;에서 제공하던 서비스를 &lt;code class=&quot;language-text&quot;&gt;/api2&lt;/code&gt;로 변경했을 때, 기존 경로로 들어온 요청에 이 코드를 반환하여 새 주소를 안내한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;4xx-client-error--클라이언트-오류&quot;&gt;4xx (Client Error) : 클라이언트 오류&lt;/h3&gt;
&lt;p&gt;클라이언트의 요청에 잘못된 문법이 있거나 요청을 처리할 수 없는 경우 발생한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;400 Bad Request&lt;/strong&gt;: 서버가 클라이언트의 요청을 이해할 수 없음을 뜻한다. (잘못된 파라미터 등)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;401 Unauthorized&lt;/strong&gt;: 해당 요청을 위해 클라이언트의 인증(ID/PW 등) 절차가 필요함을 의미한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;404 Not Found&lt;/strong&gt;: 요청받은 콘텐츠를 서버에서 찾을 수 없음을 나타낸다. (잘못된 URL 경로 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;5xx-server-error--서버-오류&quot;&gt;5xx (Server Error) : 서버 오류&lt;/h3&gt;
&lt;p&gt;클라이언트의 요청은 유효했으나, 서버가 요청을 처리하는 과정에서 오류가 발생했음을 의미한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;500 Internal Server Error&lt;/strong&gt;: 서버 내부의 문제로 인해 요청을 처리할 수 없는 범용적인 에러 상황이다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;502 Bad Gateway&lt;/strong&gt;: 게이트웨이 또는 프록시서버가 정해진 Timeout 시간동안 클라이언트의 요청을 처리하지 못함&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;503 Service Unavailable&lt;/strong&gt;: 서버가 현재 점검 중이거나 과부하로 인해 일시적으로 응답을 할 수 없는 상태이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;http-메서드&quot;&gt;HTTP 메서드&lt;/h2&gt;
&lt;hr&gt;
&lt;h3 id=&quot;get--데이터-조회-retrieve&quot;&gt;GET : 데이터 조회 (Retrieve)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;주로 서버로부터 &lt;strong&gt;정보를 조회하기&lt;/strong&gt; 위해 사용하며, 모든 요청 데이터가 URL에 노출되는 특징을 가진다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;데이터 전달 방식&lt;/strong&gt;: URL의 쿼리 스트링(Query String)을 통해 데이터를 전달한다.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;길이 제한&lt;/strong&gt;: URL을 기반으로 하기 때문에 약 &lt;strong&gt;2,000자의 길이 제한&lt;/strong&gt;이 존재한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;상태 코드&lt;/strong&gt;: 요청 성공 시 일반적으로 &lt;strong&gt;200 OK&lt;/strong&gt;를 반환한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;캐싱 가능&lt;/strong&gt;: 동일한 요청에 대해 브라우저가 결과를 캐싱할 수 있어 응답 속도가 빠르다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;보안성&lt;/strong&gt;: URL에 파라미터가 그대로 노출되어 브라우저 기록(History)에 남으므로, 비밀번호 등 민감한 정보 전달에는 적합하지 않다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터 타입&lt;/strong&gt;: ASCII 문자열 형식의 데이터만 보낼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;post--데이터-처리-및-생성-create&quot;&gt;POST : 데이터 처리 및 생성 (Create)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;새로운 리소스를 생성하거나 업데이트할 때 사용하며, 대량의 데이터를 안전하게 보낼 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;데이터 전달 방식&lt;/strong&gt;: URL이 아닌 HTTP 메시지의 &lt;strong&gt;Body&lt;/strong&gt;에 데이터를 담아 전달한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;길이 제한&lt;/strong&gt;: 데이터 크기에 대한 별도의 제한이 없어 대용량 파일 전송도 가능하다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;보안성&lt;/strong&gt;: 요청 파라미터가 URL에 노출되지 않아 브라우저 기록에 남지 않는다. (단, 암호화를 하지 않으면 패킷 분석을 통해 내용을 볼 수 있으므로 HTTPS 사용이 권장된다.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터 타입&lt;/strong&gt;: 문자열뿐만 아니라 바이너리 데이터, JSON, 이미지 등 모든 유형의 데이터를 보낼 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;캐싱 불가&lt;/strong&gt;: 서버의 상태를 변경하는 작업이 많으므로 기본적으로 캐싱을 하지 않는다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;사용 사례&lt;/strong&gt;: 사용자 가입, 로그인, 게시글 작성 등 민감한 정보나 큰 데이터를 보낼 때 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;put--리소스의-전체-교체&quot;&gt;PUT : 리소스의 전체 교체&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;대상 리소스를 새로운 데이터로 완전히 대체하는 방식&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;전체 데이터 전송:&lt;/strong&gt; 업데이트하려는 리소스의 모든 필드값을 보내야함.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;덮어쓰기: 만약 요청 시에 특정 필드를 생략하고 보낼 경우,&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;서버에 따라 해당 필드가 삭제되거나 null로 업데이트 될 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;리소스 생성&lt;/strong&gt;: 요청한 URI에 리소스가 존재하지 않을 경우, 서버 설정에 따라 새로운 리소스를 생성하기도 함.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;멱등성(Idempotent)&lt;/strong&gt;: 동일한 요청을 여러 번 보내도 결과가 항상 같음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;patch-리소스의-부분수정&quot;&gt;PATCH: 리소스의 부분수정&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;리소스를 전체 교체하지 않고, 변경이 필요한 특정 필드만을 수정하는 방식&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;일부 데이터 전송 : 수정하고 싶은 데이터만 담아서 보냄&lt;/li&gt;
&lt;li&gt;효율성: 전체 데이터를 보낼 필요가 없으므로 네트워크 대역폭을 절약할 수 있음&lt;/li&gt;
&lt;li&gt;비멱등성 가능성: 구현 방식에 따라 여러 번 요청했을 때 결과가 달라질 수 있어 주의가 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;비교-예시&quot;&gt;비교 예시&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;만약 사용자 데이터가 &lt;code class=&quot;language-text&quot;&gt;&quot;id&quot;: 1, &quot;name&quot;: &quot;woojin&quot;, &quot;age&quot;: 25&quot;}&lt;/code&gt; 일 때,&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;메서드&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;요청 데이터 (Body)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;결과&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PUT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;{ &quot;name&quot;: &quot;Flash&quot; }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;{ &quot;id&quot;: 1, &quot;name&quot;: &quot;Flash&quot; }&lt;/code&gt; (나머지 정보 삭제/초기화 위험)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PATCH&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;{ &quot;name&quot;: &quot;Flash&quot; }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;{ &quot;id&quot;: 1, &quot;name&quot;: &quot;Flash&quot;, &quot;age&quot;: 20 }&lt;/code&gt; (이름만 변경됨)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;따라서,&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;리소스의 전체를 갈아치우고 싶다면 PUT, 특정 일부만을 고치고 싶다면 PATCH를 사용해야 한다.&lt;/p&gt;
&lt;h2 id=&quot;네트워크를-이루는-장치의-이해&quot;&gt;네트워크를 이루는 장치의 이해&lt;/h2&gt;
&lt;hr&gt;
&lt;h3 id=&quot;레이어별-네트워크-장치&quot;&gt;레이어별 네트워크 장치&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;어플리케이션 계층 : L7 스위치&lt;/li&gt;
&lt;li&gt;전송 계층: L4 스위치&lt;/li&gt;
&lt;li&gt;인터넷 계층(네트워크 계층) : 라우터, L3 스위치&lt;/li&gt;
&lt;li&gt;데이터 링크 계층 : L2 스위치, 브리지&lt;/li&gt;
&lt;li&gt;물리 계층 : NIC, 리피터, AP&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-1-어플리케이션-계층---l7-스위치&quot;&gt;# 1 어플리케이션 계층 - L7 스위치&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;L7 스위치란?&lt;/strong&gt;
로드밸런서라고도 하며, 서버의 부하를 분산하는 기기다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-4/1.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;서버 이중화, 보안에 강점이 있다.&lt;/li&gt;
&lt;li&gt;IP, Port, url, 헤더, 쿠키 등을 기반으로 트래픽을 분산한다.&lt;/li&gt;
&lt;li&gt;헬스 체크를 통해 장애가 발생한 서버를 확인하고 해당 서버로 트래픽을 보내지 못하게 하는 역할을 한다.
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;헬스 체크란?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;TCP를 일정 시간 마다 전송하여, 응답을 확인함.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;참고)&lt;/strong&gt; AWS에서 L7 스위치를 이용한 로드 밸런싱은 ALB라는 컴포넌트를 통해서 하며 L4 스위치를 이용한 로드밸런싱은 NLB 컴포넌트를 통해 구축한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-2-전송-계층---l4-스위치&quot;&gt;# 2 전송 계층 - L4 스위치&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;L4 스위치란?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;앞서 설명한 로드밸런서의 특징인 트래픽 분산 등을 할 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;패킷의 IP 주소와 Port 번호를 참고하여 적절히 트래픽 분산을 할 수 있다.&lt;/li&gt;
&lt;li&gt;전송계층의 TCP, UDP 등의 헤더를 기반으로 우선순위를 판단해서 분산이 가능하다.&lt;/li&gt;
&lt;li&gt;L7와 같이 헬스체크가 가능함.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-3-인터넷-계층---라우터-l3-스위치&quot;&gt;# 3 인터넷 계층 - 라우터, L3 스위치&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;라우팅이란?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;하나 이상의 네트워크 경로를 선택하는 프로세스를 말함.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이 라우팅을 하는 장비를 라우터(Router)라고 함.&lt;/li&gt;
&lt;li&gt;다른 네트워크에 존재하는 장치끼리 서로 데이터를 주고 받을 때 **“패킷소모 최적화”, “경로 최적화”**하는 장비&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;L3 스위치란?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;L2 스위치의 기능과 라우팅을 하는 장비이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;라우팅 테이블을 참조해서 IP 패킷에 IP주소를 담아 보낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-2-전송-계층---l4-스위치-1&quot;&gt;# 2 전송 계층 - L4 스위치&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;L4 스위치란?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;앞서 설명한 로드밸런서의 특징인 트래픽 분산 등을 할 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;패킷의 IP 주소와 Port 번호를 참고하여 적절히 트래픽 분산을 할 수 있다.&lt;/li&gt;
&lt;li&gt;전송계층의 TCP, UDP 등의 헤더를 기반으로 우선순위를 판단해서 분산이 가능하다.&lt;/li&gt;
&lt;li&gt;L7와 같이 헬스체크가 가능함.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-3-인터넷-계층---라우터-l3-스위치-1&quot;&gt;# 3 인터넷 계층 - 라우터, L3 스위치&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;라우팅이란?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;하나 이상의 네트워크 경로를 선택하는 프로세스를 말함.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이 라우팅을 하는 장비를 라우터(Router)라고 함.&lt;/li&gt;
&lt;li&gt;다른 네트워크에 존재하는 장치끼리 서로 데이터를 주고 받을 때 **“패킷소모 최적화”, “경로 최적화”**하는 장비&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;L3 스위치란?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;L2 스위치의 기능과 라우팅을 하는 장비이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;라우팅 테이블을 참조해서 IP 패킷에 IP주소를 담아 보낸다.
&lt;ul&gt;
&lt;li&gt;라우팅 테이블&lt;/li&gt;
&lt;li&gt;IP 주소&lt;/li&gt;
&lt;li&gt;IP 패킷&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-4-데이터-링크-계층&quot;&gt;# 4 데이터 링크 계층&lt;/h3&gt;
&lt;p&gt;데이터 링크 계층은 이더넷 프레임을 통해 에러 확인, 흐름 제어, 접근 제어를 담당하는 계층을 말한다.&lt;/p&gt;
&lt;h3 id=&quot;l2-스위치&quot;&gt;L2 스위치&lt;/h3&gt;
&lt;p&gt;L2 스위치는 장치들의 MAC 주소를 MAC 주소 테이블을 통해 관리함.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;해당 테이블을 기반으로 인터넷 계층에서 받은 패킷을 기반으로 이더넷 프레임을 만들어 목적지 MAC 주소로 패킷을 보내주는 역하을 한다.
&lt;ul&gt;
&lt;li&gt;MAC 주소 테이블&lt;/li&gt;
&lt;li&gt;MAC 주소&lt;/li&gt;
&lt;li&gt;이더넷 프레임&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;브리지&quot;&gt;브리지&lt;/h3&gt;
&lt;p&gt;브리지(bridge)는 두 개의 근거리 통신망(LAN)을 상호 접속할 수 있도록 하는 통신망 연결 장치를 말한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;통신망의 범위를 확장하고 LAN을 기반으로 하나의 통신망을 구축할 때 쓰임.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;유선-lan-1-전이중화-통신-csmacd&quot;&gt;유선 LAN #1. 전이중화 통신, CSMA/CD&lt;/h2&gt;
&lt;h3 id=&quot;전이중화full-duplex란&quot;&gt;전이중화(full duplex)란?&lt;/h3&gt;
&lt;p&gt;양쪽 장치가 동시에 송수신할 수 있는 방식을 말한다. 동축케이블, 광케이블 등을 기반으로 만들어진 유선 LAN을 이루는 이더넷은 IEEE802.3 프로토콜을 기반으로 전이중화 통신을 쓴다.&lt;/p&gt;
&lt;h3 id=&quot;ieee8023&quot;&gt;IEEE802.3&lt;/h3&gt;
&lt;p&gt;이더넷프레임은 어떤 구조를 기반으로 할 것인지, 케이블의 최대 전송량, 어떤 케이블만이 가능하도록 할 것인지 등을 정한 규칙을 말함.&lt;/p&gt;
&lt;h3 id=&quot;전이중화-통신&quot;&gt;전이중화 통신&lt;/h3&gt;
&lt;p&gt;양쪽 장치가 동시에 송수신할 수 있는 방식, 송신로와 수신로를 나눠서 데이터를 주고 받을 수 있다.&lt;/p&gt;
&lt;h3 id=&quot;csmacd&quot;&gt;CSMA/CD&lt;/h3&gt;
&lt;p&gt;이전에는 유선 LAN에 ‘반이중화 통신’ 중 하나인 CSMA/CD(Carrier Sense Multiple Access with Collision Detection) 방식을 썼다. 이 방식은 회선을 사용하는 지를 파악한 후 사용하지 않는 다면 데이터를 보내고 충돌이 발생한다면 일정 시간 이후 재전송 하는 방식을 말한다.&lt;/p&gt;
&lt;h2 id=&quot;유선-lan-2-케이블&quot;&gt;유선 LAN #2 케이블&lt;/h2&gt;
&lt;h3 id=&quot;트위스트페어-케이블&quot;&gt;트위스트페어 케이블&lt;/h3&gt;
&lt;p&gt;트위스트 페어 케이블은 2가지로 나뉜다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;STP: 실드처리 한 케이블&lt;/li&gt;
&lt;li&gt;UTP: 실드처리를 안한 케이블&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;광섬유-케이블&quot;&gt;광섬유 케이블&lt;/h3&gt;
&lt;p&gt;레이저를 이용해 통신하며 보통 100Gbps의 데이터를 전송하는 케이블&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;코어 : 빛의 굴절률이 높은 부분&lt;/li&gt;
&lt;li&gt;클래딩 : 빛의 굴절률이 낮은 부분
&lt;ul&gt;
&lt;li&gt;다른 밀도를 가지는 유리나 플라스틱 섬유 기반으로 제작&lt;/li&gt;
&lt;li&gt;한번 들어간 빛이 내부에서 계속 반사하며 전진하여 반대편 끝까지 가는 원리를 이용함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;무선-lan-1-반이중화통신-csmaca-와이파이&quot;&gt;무선 LAN #1 반이중화통신, CSMA/CA, 와이파이&lt;/h2&gt;
&lt;p&gt;무선랜은 IEEE802.11 표준 규격을 따르며 반이중화 통신을 사용한다.&lt;/p&gt;
&lt;h3 id=&quot;반이중화-통신&quot;&gt;반이중화 통신&lt;/h3&gt;
&lt;p&gt;반이중화 통신은 양쪽 장치는 서로 통신할 수 있지만, 동시에는 통신할 수 없으며 한 번에 한 방향만 통신할 수 있는 방식을 말함.&lt;/p&gt;
&lt;h3 id=&quot;csmaca&quot;&gt;CSMA/CA&lt;/h3&gt;
&lt;p&gt;반이중화 통신 중 하나로 장치에서 데이터를 보내기 전에 일련의 과정을 기반으로 사전에 최대한 충돌을 방지하는 방식을 말함.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;반이중화 통신 과정&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;사용중인 채널이 있다면, 다른 채널을 감지하다 유후 상태인 채널 발견&lt;/li&gt;
&lt;li&gt;프레임 간 공간 시간인 IFS(InterFrame Space)시간만큼 기다림&lt;/li&gt;
&lt;li&gt;프레임을 보내기 전 &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;0&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; ~  &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mrow&gt;&lt;mi&gt;K&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;2^{K-1}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8413em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.8413em;&quot;&gt;&lt;span style=&quot;top:-3.063em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;margin-right:0.07153em;&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;mbin mtight&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mtight&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 사이에서 결정된 랜덤 상수를 기반으로 결정된 시간만큼 기다린 뒤 프레임을 보냄
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;프레임을 보낸 뒤 제대로 송신되었고 ACK 세그먼트를 받았다면 마무리&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;받지 못하였을 경우,&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;k=k+1&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7778em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;을 하며 이 과정을 반복함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;반복하다가 k가 정해진 Kmax보다 더 커지면, 해당 프레임 전송은 abort&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[[알고리즘] 투포인터 정리]]></title><description><![CDATA[투포인터(Two Pointers) 패턴 정리 참고자료 Two Pointers in 7 minutes LeetCode Pattern Sliding Window in 7 minutes LeetCode Pattern 1. 투포인터란 무엇인가? 투 포인터는 데이터 구조(주로 배열이나 연결 리스]]></description><link>https://woojin-devv.github.io/posts/two-pointer/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/two-pointer/</guid><pubDate>Fri, 03 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;투포인터two-pointers-패턴-정리&quot;&gt;투포인터(Two Pointers) 패턴 정리&lt;/h1&gt;
&lt;hr&gt;
&lt;h3 id=&quot;참고자료&quot;&gt;참고자료&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=QzZ7nmouLTI&quot;&gt;Two Pointers in 7 minutes | LeetCode Pattern&lt;/a&gt;
&lt;a href=&quot;https://www.youtube.com/watch?v=y2d0VHdvfd&quot;&gt;Sliding Window in 7 minutes | LeetCode Pattern&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;1-투포인터란-무엇인가&quot;&gt;1. 투포인터란 무엇인가?&lt;/h2&gt;
&lt;p&gt;투 포인터는 데이터 구조(주로 배열이나 연결 리스트)에서 두 개의 변수(포인터)를 사용하여 데이터의 위치를 가리키고, 특정 조건에 따라 이 포인터를 이동시키며 문제를 해결하는 기법&lt;/p&gt;
&lt;h2 id=&quot;2-투포인터의-3가지-주요-전략&quot;&gt;2. 투포인터의 3가지 주요 전략&lt;/h2&gt;
&lt;h3 id=&quot;1-수렴형-포인터converging-pointers&quot;&gt;1) 수렴형 포인터(Converging Pointers)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/algorithm/two-pointers/1.gif&quot; alt=&quot;1.gif&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;방향 : 양 끝에서 시작하여 가운데로 이동&lt;/li&gt;
&lt;li&gt;용도 : 양 끝 요소를 비교해야할 때 유용&lt;/li&gt;
&lt;li&gt;대표 예
&lt;ul&gt;
&lt;li&gt;회문(Palindrome) 체크, 양 끝 문자를 비교하며 같으면 안으로 이동, 다르면 즉시 종료&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;수렴형-포인터-템플릿&quot;&gt;수렴형 포인터 템플릿&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;converging_pointers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;arr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# 1. 배열 정렬 (원본 배열을 변경하거나 sorted(arr) 사용)&lt;/span&gt;
    arr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sort&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# 2. 포인터 초기화&lt;/span&gt;
    left &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    right &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;arr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# 3. 두 포인터가 만날 때까지 반복&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; left &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; right&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        current_sum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;left&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;right&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; current_sum &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;# 정답을 찾은 경우&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;Found: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;left&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;right&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;left&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;right&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; current_sum &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;# 합이 타겟보다 작으면 값을 키우기 위해 left를 오른쪽으로 이동&lt;/span&gt;
            left &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;# 합이 타겟보다 크면 값을 줄이기 위해 right를 왼쪽으로 이동&lt;/span&gt;
            right &lt;span class=&quot;token operator&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
            
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;No pair found.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;백준---3273-두-수의-합&quot;&gt;백준 - 3273 두 수의 합&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;n &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
arr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

arr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sort&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# print(arr)&lt;/span&gt;

left &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
right &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; n &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
count &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; right&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# print(&quot;left&quot;, left, &quot;right&quot;, right)&lt;/span&gt;
    currentSum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;left&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;right&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# print(&quot;currentSum&quot;, currentSum)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentSum &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        count &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        left &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        right &lt;span class=&quot;token operator&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; currentSum &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        left &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        right &lt;span class=&quot;token operator&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-평행-포인터parallel-pointers&quot;&gt;2) 평행 포인터(Parallel Pointers)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/algorithm/two-pointers/2.gif&quot; alt=&quot;2.gif&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;방향 : 같은 시점에서 같은 방향으로 이동&lt;/li&gt;
&lt;li&gt;용도 : &lt;strong&gt;슬라이딩 윈도우&lt;/strong&gt;가 대표적 예시
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;포인터 중 하나는 탐색(Right)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;다른 하나는 제약 조건 유지(Left)의 역할&lt;/p&gt;
&lt;p&gt;⇒ 하위 배열이나 하위 문자열을 찾을 때 사용&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-트리거-기반-포인터-trigger-based-pointers&quot;&gt;3) 트리거 기반 포인터 (Trigger-based Pointers)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;방향 : 한 포인터가 먼저 움직이고, 특정 조건이 충족되면 두 번째 포인터가 움직이기 시작&lt;/li&gt;
&lt;li&gt;대표 예시 : 연결 리스트에서 ‘뒤에서 n번째 노드’ 찾기
&lt;ul&gt;
&lt;li&gt;첫 번째 포인터를 n만큼 먼저 보낸 후, 두 포인터를 이동시키면 첫 포인터가 끝에 도달했을 때 두 번째 포인터가 목표 지점에 있게 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;3-슬라이딩-윈도우&quot;&gt;3. 슬라이딩 윈도우&lt;/h2&gt;
&lt;p&gt;두 개의 포인터를 사용하여 데이터 구조 위에서 윈도우를 정의하고 이 윈도우를 옆으로 밀어가며 하위 배열이나 하위 문자열을 효율적으로 탐색하는 기법&lt;/p&gt;
&lt;h3 id=&quot;1-fixed-sliding-window&quot;&gt;1) Fixed Sliding Window&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;특징 : 윈도우의 크기 (&lt;code class=&quot;language-text&quot;&gt;K&lt;/code&gt;)가 미리 정해져 있으며 탐색 내내 일정하게 유지됨&lt;/li&gt;
&lt;li&gt;작동 방식
&lt;ol&gt;
&lt;li&gt;처음 K 개의 요소로 초기 윈도우 설정&lt;/li&gt;
&lt;li&gt;한 칸씩 이동하며 새로운 요소는 추가하고, 윈도우를 벗어나는 옛날 요소는 제거&lt;/li&gt;
&lt;li&gt;결과를 업데이트&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;백준---2559-수열&quot;&gt;백준 - 2559 수열&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;n&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; k &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
arr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

curret_val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;k&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
max_val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; curret_val

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;k&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    curret_val &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;k&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    max_val &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;max_val&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; curret_val&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;max_val&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-dynamic-sliding-window&quot;&gt;2) Dynamic Sliding Window&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;문제의 조건에 따라 윈도우의 크기가 늘어나거나 줄어듦&lt;/li&gt;
&lt;li&gt;작동 방식
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;right&lt;/code&gt; 포인터를 이동하며 윈도우를 확장&lt;/li&gt;
&lt;li&gt;만약 조건을 위반할 경우,
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;left&lt;/code&gt; 포인터를 이동시켜 조건이 만족될 때까지 윈도우를 축소시킴&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;윈도우 내에서 최대/최소 길이등을 계산함&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[3주차 - 네트워크]]></title><description><![CDATA[참고자료 HTTP 1 Vs HTTP 2 Vs HTTP 3! HTTP 헤더(Header) 사용자가 HTTP 요청을 하게 되면 헤더와 바디를 주고 받는다. 헤더: 바디를 설명하는 정보를 포함한 정보 묶음 헤더는 콜론(:)으로 구분되는 key value 형태로 설정됨 HTTP 요청을 할 때 ]]></description><link>https://woojin-devv.github.io/posts/cs-interview-study-3/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/cs-interview-study-3/</guid><pubDate>Thu, 02 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;참고자료&quot;&gt;참고자료&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=UMwQjFzTQXw&quot;&gt;HTTP 1 Vs HTTP 2 Vs HTTP 3!&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;http-헤더header&quot;&gt;HTTP 헤더(Header)&lt;/h1&gt;
&lt;p&gt;사용자가 HTTP 요청을 하게 되면 헤더와 바디를 주고 받는다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-3/1.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;헤더: 바디를 설명하는 정보를 포함한 정보 묶음
&lt;ul&gt;
&lt;li&gt;헤더는 콜론(:)으로 구분되는 key-value 형태로 설정됨&lt;/li&gt;
&lt;li&gt;HTTP 요청을 할 때 3가지 헤더인 &lt;strong&gt;일반헤더, 요청헤더, 응답헤더&lt;/strong&gt;가 자동으로 생김&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;바디 : 주고받고자 하는 컨텐츠 본문 (json, html, image)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;일반헤더-general-header&quot;&gt;일반헤더 (General Header)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-3/2.png&quot; alt=&quot;alt text&quot;&gt;
요청한 URL, 요청 메서드, 해당 자원을 요청할 때 해당 자원의 출처를 나타내는 URL을 노출시킬 지 말지를 정하는 보안정도가 설정되어 있는 Referrer Policy 등이 들어감.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Request URL : 요청한 대상의 주소&lt;/li&gt;
&lt;li&gt;Request Method : 요청 방식 (GET, POST, PUT, DELETE 등)&lt;/li&gt;
&lt;li&gt;Status Code : 서버의 처리 결과 상태
&lt;ul&gt;
&lt;li&gt;Status Code&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Referrer Policy : 보안을 위해 이전 페이지의 주소를 어디까지 노출할지 결정하는 정책&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;요청헤더-request-header&quot;&gt;요청헤더 (Request Header)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-3/3.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Host : 요청이 전송되는 도메인 명&lt;/li&gt;
&lt;li&gt;User-Agent : 요청을 보내는 클라이언트의 정보&lt;/li&gt;
&lt;li&gt;Accept: 클라이언트가 처리할 수 있는 미디어 타입
&lt;ul&gt;
&lt;li&gt;예: &lt;code class=&quot;language-text&quot;&gt;text/html&lt;/code&gt; , &lt;code class=&quot;language-text&quot;&gt;application/json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;응답헤더-response-header&quot;&gt;응답헤더 (Response Header)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-3/4.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;p&gt;서버가 클라이언트에게 보낼 때, 서버 자체의 정보나 응답 데이터의 특성을 설명함&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Content-Type : 바디에 담긴 컨텐츠의 종류
&lt;ul&gt;
&lt;li&gt;예: &lt;code class=&quot;language-text&quot;&gt;text/html&lt;/code&gt; ; &lt;code class=&quot;language-text&quot;&gt;charset=utf-8&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;이를 통해 브라우저는 데이터를 어떻게 렌더링할 지 결정함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Set-Cookie : 서버가 클라이언트에 쿠키를 저장하라고 명령할 때 사용&lt;/li&gt;
&lt;li&gt;Cache-Control : 해당 응답을 얼마나 오랫동안 캐시(임시 저장)해도 되는 지 지시&lt;/li&gt;
&lt;li&gt;Server: 응답을 처리한 서버 소프트웨어의 정보 (예: &lt;code class=&quot;language-text&quot;&gt;Apache&lt;/code&gt; , &lt;code class=&quot;language-text&quot;&gt;nginx&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Access-Control-Allow-Origin: CORS(Cross-Origin Resource Sharing)와 관련된 보안 정책으로, 어떤 도메인의 접근을 허용할지 명시.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;http10과-11의-차이&quot;&gt;HTTP/1.0과 1.1의 차이&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-3/5.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;http10-단기-커넥션short-lived-connections&quot;&gt;HTTP/1.0: 단기 커넥션(Short-lived Connections)&lt;/h3&gt;
&lt;p&gt;HTTP/1.0은 기본적으로 한 번의 연결에 하나의 요청만 처리한다는 원칙을 가지고 설계되었다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;작동방식 (3-way handshake → 데이터 요청 / 응답 → 연결 종료)&lt;/strong&gt;
&lt;ol&gt;
&lt;li&gt;TCP 연결 : 클라이언트와 서버가 3-Way Handshake를 통해 연결을 맺는다.&lt;/li&gt;
&lt;li&gt;요청/응답: 클라이언트가 HTML 파일을 요청하고, 서버가 응답한다.&lt;/li&gt;
&lt;li&gt;연결 종료: 응답이 끝나면 즉시 TCP 연결을 끊는다.&lt;/li&gt;
&lt;li&gt;반복: 만약 HTML 안에 이미지가 3개가 있다면, 해당 과정을 3번 더 반복함&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;문제점 : RTT의 증가&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;**RTT(Round Trip Time)**란? 패킷이 왕복하는데 걸리는 시간을 의미함&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;지연시간(Latency) 발생&lt;/strong&gt; : 매번 연결을 새로 맺어야함, 따라서 실제 데이터를 주고 받는 시간보다 연결을 설정(Handshake)하는데 드는 시간이 더 길어지는 상황이 발생함&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;서버 부하&lt;/strong&gt; : 수 많은 클라이언트가 매번 연결을 맺고 끊으면 서버의 CPU와 메모리 자원들을 빠르게 소모하게 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;정리&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;HTTP/1.0은 수명이 짧은 연결이다.&lt;/li&gt;
&lt;li&gt;HTTP 요청은 자체 요청에서 완료된다&lt;/li&gt;
&lt;li&gt;각 HTTP 요청당 TCP 핸드셰이크가 발생되며 기본적으로 한 연결당 하나의 요청을 처리하도록 설계되었다.&lt;/li&gt;
&lt;li&gt;한 번 연결할 때마다 TCP 연결을 계속해야하므로 RTT가 늘어나는 문제점이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;http11&quot;&gt;HTTP/1.1&lt;/h2&gt;
&lt;p&gt;HTTP/1.0의 RTT 증가 문제점을 해결하기 위해 HTTP/1.1이 나오게 됨&lt;/p&gt;
&lt;h3 id=&quot;1-keep-alive-default&quot;&gt;1. Keep-alive default&lt;/h3&gt;
&lt;p&gt;데이터를 요청할 때마다 TCP 연결을 하는게 아닌 한번 연결 하면, 계속 데이터를 주고 받을 수 있도록 함.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;keep-alive 옵션을 기본 옵션으로 유지&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2-호스트-헤더&quot;&gt;2. 호스트 헤더&lt;/h3&gt;
&lt;p&gt;HTTP/1.0은 서버가 하나의 호스트만 가진다고 가정하기 때문에 HTTP/1.0은 헤더에 호스트를 포함하지 않음&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;때문에, HTTP/1.0은 IP 하나당 하나의 호스트만 가질 수 있었음&lt;/li&gt;
&lt;li&gt;하지만, HTTP/1.1은 헤더에 특정 호스트를 포함할 수 있게 변경되었고 항상 호스트를 포함해서 요청하도록 변경됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-대역폭-최소화-chunking--다운로드-이어받기-가능&quot;&gt;3. 대역폭 최소화 (Chunking) : 다운로드 이어받기 가능&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-3/6.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP/1.0은 어떠한 파일을 다운로드 받다가 연결이 끊기면 다시 다운로드 받는 것이 불가능 했음
&lt;ul&gt;
&lt;li&gt;예를 들어, HTTP/1.0에서는 10KB 파일을 다운로드 받는다고 했을 때, 5KB까지 다운 받고 이후의 데이터를 받는 것은 불가능했음.
&lt;ul&gt;
&lt;li&gt;하지만, HTTP/1.1에서는 &lt;code class=&quot;language-text&quot;&gt;Ragne:bytes=5000-&lt;/code&gt; 라는 헤더를 추가하여 다운로드 재개 요청을 할 수 있도록 바뀜&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;4-파이프라이닝pipelining&quot;&gt;4. 파이프라이닝(Pipelining)&lt;/h3&gt;
&lt;p&gt;응답을 기다리지 않고 여러 요청을 연속해서 보낼 수 있게 됨&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-3/7.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;p&gt;예시)&lt;/p&gt;
&lt;p&gt;Client가 Server단에 이미지를 2개를 요청할 때, 응답에 관계없이 GET요청을 보낼 수 있음&lt;/p&gt;
&lt;h3 id=&quot;but-http11의-한계--holhead-of-line-blocking-문제&quot;&gt;But. HTTP/1.1의 한계 : HOL(Head-of-Line) Blocking 문제&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-3/8.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;왜 발생하나?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;HTTP/1.1은 이전 버전의 비효율을 해결하기 위해 파이프라이닝(Pipelining)을 도입하였음. 응답을 기다리지 않고 여러 요청을 연속해서 보내는 방식.&lt;/p&gt;
&lt;p&gt;하지만,&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;응답은 반드시 요청받은 순서대로 보내야한다.&lt;/strong&gt; 라는 제약사항이 존재함&lt;/p&gt;
&lt;p&gt;서버는 클라이언트가 요청한 순서를 기억했다가 그 순서에 맞춰 응답을 돌려줘야하기 때문&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;어떻게 해결했나?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Domaing Sharding (도메인 분할)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;브라우저는 한 도메인당 연결 수 (보통 6개)를 제한함
&lt;ul&gt;
&lt;li&gt;이를 우회하기 위해 &lt;code class=&quot;language-text&quot;&gt;static1.example.com&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;static2.example.com&lt;/code&gt; 처럼 여러 서브도메인을 만들어 연결 개수를 강제로 늘림&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Image Sprite (이미지 스프라이트)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;수십개의 작은 아이콘을 하나의 커다란 이미지 파일로 합쳐서 요청 횟수 자체를 1번으로 줄임&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code Bundling&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;여러 개의 JS/CSS 파일을 하나로 합쳐서 전송 효율을 높임&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;http2와-http3의-차이&quot;&gt;HTTP/2와 HTTP/3의 차이&lt;/h2&gt;
&lt;h3 id=&quot;http2&quot;&gt;HTTP/2&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-3/9.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;http2의-도입-배경--http11의-한계&quot;&gt;HTTP/2의 도입 배경 &amp;#x26; HTTP/1.1의 한계&lt;/h3&gt;
&lt;p&gt;HTTP/1.1의 성능 저하 문제(HOL)를 해결하기 위해, 구글의 SPDY 프로토콜을 바탕으로 탄생&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HOL : 네트워크에서 같은 큐에 있는 패킷이 그 첫번째 패킷에 의해 지연될 때 발생하는 성능저하 현상을 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;어떻게-해결했나&quot;&gt;&lt;strong&gt;어떻게 해결했나?&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;바이너리 포맷 계층 (Binary Framing)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;텍스트 대신 이진 형식(Binary)으로 프레임 단위로 데이터를 쪼개어 전달하여 처리 속도가 빨라짐&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multiplexing (다중화)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;하나의 연결에서 여러 요청과 응답을 동시에 주고 받을 수 있어 HOLB 문제를 소프트웨어 수준에서 해결&lt;/li&gt;
&lt;li&gt;단일 TCP연결의 여러 스트림에서 여러 HTTP 요청과 응답을 보낼 수 있다.
&lt;ul&gt;
&lt;li&gt;HTTP/1.1에서는 병렬 요청을 하려면 다중 TCP 연결을 통해 진행하고, TCP 연결 하나당 병렬 요청은 불가능했다.&lt;/li&gt;
&lt;li&gt;HTTP/2.0에서는 리소스를 작은 &lt;strong&gt;프레임&lt;/strong&gt; 단위로 나누고 이를 스트림으로 프레임을 전달한다.
&lt;ul&gt;
&lt;li&gt;각각의 프레임은 (스트림 ID / 청크 크기를 나타내는 프레임이 추가)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Header Compression (HPACK)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;중복되는 헤더 정보를 압축하여 전송 데이터량을 크게 줄임&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Server Push&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트가 요청하지 않아도 서버가 필요한 리소스를 미리 밀어넣어 줄 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;http3&quot;&gt;HTTP/3&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-3/10.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TCP의 태생적 한계&lt;/strong&gt;를 극복하기 위해 구글이 개발한 QUIC 프로토콜을 사용&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;→ TCP를 여전히 사용하기 때문에 RTT로 인한 지연시간 문제는 여전히..(HTTP/2)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UDP 기반(QUIC) 연결 설정 과정을 대폭 단축하여 첫 패킷 전송까지의 시간을 줄임&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HOLD 문제 해결&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;TCP 패킷 하나만 유실되어도 전체가 멈추지만, HTTP/3는 유실된 패킷이 포함된 스트림만 영향을 받고 나머지는 정상 작동&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;연결 유지&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;와이파이에서 LTE로 네트워크 환경이 바뀌어도 IP주소가 아닌 ‘Connection ID’를 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;https와-tls-1-암호화대칭-비대칭&quot;&gt;HTTPS와 TLS #1. 암호화(대칭, 비대칭)&lt;/h2&gt;
&lt;hr&gt;
&lt;h3 id=&quot;암호화란&quot;&gt;암호화란?&lt;/h3&gt;
&lt;p&gt;평문을 암호문으로 바꾸어 데이터의 기밀성과 무결성을 보장하는 기술&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;대칭 암호화 (Symmetric)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;특징: 암호화와 복호화에 같은 키를 사용&lt;/li&gt;
&lt;li&gt;장점 : 속도가 빠름&lt;/li&gt;
&lt;li&gt;단점 : 탈취 위험&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;대표 알고리즘 : AES-128&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;비대칭 암호화 (Asymmetric)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;특징 : 공개키와 개인키의 쌍을 사용&lt;/li&gt;
&lt;li&gt;공식 : 공개키 암호화 → 개인키로만 복호화 가능&lt;/li&gt;
&lt;li&gt;장점 : 키 전달 문제 해결&lt;/li&gt;
&lt;li&gt;단점 : 계산 복잡도가 높은 편이라 속도가 느림&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;대표 알고리즘 : RSA, DH(Diffie–Hellman), ECDHE&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;aes-대칭-암호화&quot;&gt;AES (대칭 암호화)&lt;/h3&gt;
&lt;p&gt;AES(Advanced Encryption Standard)는 스크램블을 사용한 대칭키 암호화 알고리즘&lt;/p&gt;
&lt;p&gt;→ 10 라운드에 걸쳐 각 라운드마다 스크램블 등의 연산으로 데이터 암호화&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;스크램블?&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;현재 상태의 키를 XOR 연산으로 더하는 단계&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[참고] AES는 AES-128, AES-192, AES-256이 있고 그 중 AES-128가 가장 빠르고 가벼우며 많이 쓰이는 알고리즘이다. AES-128는 HTTPS, TLS 통신, 파일 암호화 (ZIP, RAR) 등에 사용됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;rsa-dhdiffiehellman--비대칭-암호화&quot;&gt;RSA, DH(Diffie–Hellman) ; 비대칭 암호화&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-3/11.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ex)&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A가 B에게 비밀 메시지를 보내려면 → B의 공개키로 암호화&lt;/li&gt;
&lt;li&gt;이 메시지는 오직 B의 개인키로만 복호화할 수 있음 즉, A는 암호화만 하고, B만 읽을 수 있음&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&quot;https와-tls-2-tls-핸드셰이크&quot;&gt;HTTPS와 TLS #2. TLS 핸드셰이크&lt;/h1&gt;
&lt;h3 id=&quot;tls-핸드셰이크-과정&quot;&gt;TLS 핸드셰이크 과정&lt;/h3&gt;
&lt;p&gt;크게 두 가지 핵심 역할을 수행함&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;키 교환 (Key Exchange)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트와 서버가 만난 적 없지만, 똑같은 대칭키를 나누어 가져야할 때 사용
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ECDHE(Elliptic Curve Diffie–Hellman Ephemeral)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;전자 서명 (Digital Signature)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;해당 서버가 진짜가 맞음 (인증서 위조되지 않음)을 증명할 때사용
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ECDSA&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-3/12.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;1-clienthello&quot;&gt;1. ClientHello&lt;/h3&gt;
&lt;p&gt;클라이언트는 서버에게 먼저 ClientHello 메시지를 보낸다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;클라이언트가 지원하는 TLS 버전 목록&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;클라이언트가 지원하는 Cipher Suites 목록&lt;/p&gt;
&lt;p&gt;클라이언트 랜덤값 (난수로 세션 키 생성에 사용됨)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;클라이언트 측 ECDHE 공개키&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2-serverhello&quot;&gt;2. ServerHello&lt;/h3&gt;
&lt;p&gt;서버는 클라이언트의 메시지를 분석한 후 다음과 같은 과정을 진행&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트와 공통으로 지원하는 TLS 버전 중 가장 높은 버전 선택&lt;/li&gt;
&lt;li&gt;클라이언트가 제안한 Cipher Suites 중 서버가 지원하는 Cipher Suites 선택&lt;/li&gt;
&lt;li&gt;ServerHello 메시지를 보내면서 다음을 포함
&lt;ul&gt;
&lt;li&gt;선택된 TLS 버전&lt;/li&gt;
&lt;li&gt;선택된 Cipher Suites&lt;/li&gt;
&lt;li&gt;서버 랜덤값&lt;/li&gt;
&lt;li&gt;서버측 ECDHE 공개키&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-그-후-메시지들이-이어짐&quot;&gt;3. 그 후 메시지들이 이어짐&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Encrypted Extensions: SNI, ALPN&lt;/li&gt;
&lt;li&gt;Certificate&lt;/li&gt;
&lt;li&gt;CertificateVertify&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;4-finished&quot;&gt;4. Finished&lt;/h3&gt;
&lt;p&gt;클라이언트와 서버는 각각 Finished 메시지를 교환합니다. 이후의 통신은 세션키로 암호화되며, 이후 모든 통신은 AES 같은 대칭 암호화 방식으로 보호&lt;/p&gt;
&lt;h3 id=&quot;ecdhe-타원곡선-암호화&quot;&gt;ECDHE – 타원곡선 암호화&lt;/h3&gt;
&lt;p&gt;ECDHE에서 먼저 DH는 Diffie-Hellman을 의미&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Diffie-Hellman 알고리즘은 서로 공개값 공유, 비밀값과 혼합, 혼합값과 공유, 각자의 비밀값과 혼합해서 공통의 암호키를 만드는 알고리즘&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;diffie--hellman-키-교환-방식&quot;&gt;Diffie – Hellman 키 교환 방식&lt;/h3&gt;
&lt;div class=&quot;math math-display&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;/msup&gt;&lt;mtext&gt; mod &lt;/mtext&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;A = g^a \text{ mod }  p&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.9088em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.7144em;&quot;&gt;&lt;span style=&quot;top:-3.113em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot;&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord text&quot;&gt;&lt;span class=&quot;mord&quot;&gt; mod &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;p&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;해당 식으로부터 &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;A, g, p&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8778em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;p&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;를 알아도 &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;를 계산하는 것 힘듦
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;예)&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;23&lt;/mn&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;8&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;g=5, p=23, A= 8&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8389em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8778em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;8&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;이라고 할 때,&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;를 찾기 위해서는 brute force로 전부 연산해야함.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;tls에서-ecc를-사용하는-이유-rsa와-비교&quot;&gt;TLS에서 ECC를 사용하는 이유 (RSA와 비교)&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;비교 항목&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;RSA (과거 표준)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;ECC (현대 표준)&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;보안 원리&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;큰 수의 소인수분해&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;타원곡선 이산로그 문제&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;키 사이즈&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3072 bit&lt;/strong&gt; (매우 큼)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;256 bit&lt;/strong&gt; (매우 작음)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;보안 강도&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;보통&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;매우 높음&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;연산 속도&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;무거움 (배터리 소모↑)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;가볍고 빠름 (모바일 최적화)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content:encoded></item><item><title><![CDATA[<현대퓨처넷 11기 채용연계형 부캠> 지원 & 합격 후기]]></title><description><![CDATA[서론 교육 후기나, 면접 후기가 많이 없는 것 같아서 조금이나마 도움이 될 수 있지 않을까 하고 적게 되는 후기. 졸업을 앞두고 취준에 대한 고민이 많았는데 사실 도메인을 정하지 않아서 어떤 회사로 가면 좋을지, 내가 회사를 골라가는게 맞는 지에 대한 걱정이 많았다. 또, 프로젝트를 하]]></description><link>https://woojin-devv.github.io/posts/hyundaifuturenet-1/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/hyundaifuturenet-1/</guid><pubDate>Tue, 31 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;서론&quot;&gt;서론&lt;/h2&gt;
&lt;p&gt;교육 후기나, 면접 후기가 많이 없는 것 같아서 조금이나마 도움이 될 수 있지 않을까 하고 적게 되는 후기.&lt;/p&gt;
&lt;p&gt;졸업을 앞두고 취준에 대한 고민이 많았는데 사실 도메인을 정하지 않아서 어떤 회사로 가면 좋을지, 내가 회사를 골라가는게 맞는 지에 대한 걱정이 많았다.&lt;/p&gt;
&lt;p&gt;또, 프로젝트를 하나의 기술 스택으로 정한게 아니라 내 입맛대로 골라서하다보니.. 특출나게 1군이라고 할만한 기술스택이 없었다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;서류작성&quot;&gt;서류작성&lt;/h2&gt;
&lt;p&gt;최종 면접 때 작성해둔 자기소개서를 바탕으로 이루어지기 떄문에 &apos;특기&apos; 문항까지도 고려해서 작성하는 것이 좋을 것 같다.&lt;/p&gt;
&lt;h3 id=&quot;문항&quot;&gt;문항&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[React] useRef와 상태 끌어올리기 (#09-2)]]></title><description><![CDATA[📍 연관 포스팅 React 객체 상태를 활용한 조건부 렌더링 구현 ( 09 1) React useRef와 상태 끌어올리기 ( 09 2) Github 🔗 09 project management app 서론 입력 폼에서 데이터를 가져올 때, 모든 키 입력마다 상태를 업데이트하는 대신 "저장]]></description><link>https://woojin-devv.github.io/posts/react-useref/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/react-useref/</guid><pubDate>Tue, 31 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h3 id=&quot;-연관-포스팅&quot;&gt;📍 연관 포스팅&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://woojin-devv.github.io/posts/react-usestate/&quot;&gt;React - 객체 상태를 활용한 조건부 렌더링 구현 (#09-1)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://woojin-devv.github.io/posts/react-useref/&quot;&gt;React - useRef와 상태 끌어올리기 (#09-2)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;github&quot;&gt;Github&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/woojin-devv/react-study/tree/main/09-project-management-app&quot;&gt;🔗 09-project-management-app&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&quot;서론&quot;&gt;서론&lt;/h2&gt;
&lt;p&gt;입력 폼에서 데이터를 가져올 때, 모든 키 입력마다 상태를 업데이트하는 대신 &quot;저장&quot; 버튼을 누르는 시점에만 값을 읽어오고 싶다면 Ref 사용하자&lt;/p&gt;
&lt;p&gt;-&gt; 왜냐면 상태 변화를 계속 팔로업할 필요가 없으니까..&lt;/p&gt;
&lt;p&gt;사실 useState로도 구현 가능하지만 왜 useRef를 사용해야할까?&lt;/p&gt;
&lt;h3 id=&quot;usestate-와-useref의-차이&quot;&gt;useState 와 useRef의 차이&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;비교 항목&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;useState (제어 컴포넌트)&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;useRef (비제어 컴포넌트)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;리렌더링&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;값이 바뀔 때마다 발생 (매 키입력 시)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;발생하지 않음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;실시간 검사&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;가능 (글자 수 제한, 입력 즉시 경고 등)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;불가능 (버튼을 누르는 시점에만 확인 가능)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;UI 동기화&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;입력값에 따라 UI가 즉시 변함&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;저장 전까지 UI 변화 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;추천 상황&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;복잡한 유효성 검사, 실시간 피드백 필요 시&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;단순한 데이터 수집, 성능 최적화 필요 시&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;1-useref를-이용한-입력값-수집&quot;&gt;1. useRef를 이용한 입력값 수집&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;useState&lt;/code&gt;를 쓰면 코드가 복잡해질 수 있는 상황에서 &lt;code class=&quot;language-text&quot;&gt;useRef&lt;/code&gt;를 사용하면 DOM 요소에 직접 접근하여 필요할 때만 값을 가져올 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; useRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; title &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; description &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; dueDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleSave&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; enteredTitle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; title&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; enteredDescription &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; description&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; enteredDueDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dueDate&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;// 수집된 데이터를 상위 컴포넌트로 전달&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;onAdd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; enteredTitle&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; enteredDescription&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;dueDate&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; enteredDueDate
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;2-커스텀-컴포넌트에-ref-전달하기-forwardref&quot;&gt;2. 커스텀 컴포넌트에 Ref 전달하기 (&lt;code class=&quot;language-text&quot;&gt;forwardRef&lt;/code&gt;)&lt;/h2&gt;
&lt;p&gt;내장 HTML 태그(&lt;code class=&quot;language-text&quot;&gt;input&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;textarea&lt;/code&gt;)가 아닌 &lt;strong&gt;커스텀 컴포넌트&lt;/strong&gt;에 &lt;code class=&quot;language-text&quot;&gt;ref&lt;/code&gt; 속성을 넘기려면 React의 &lt;code class=&quot;language-text&quot;&gt;forwardRef&lt;/code&gt;를 사용해야 한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; forwardRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Input &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;forwardRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; label&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; textarea&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ref&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;label&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;label&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;textarea &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;textarea ref&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ref&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input ref&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ref&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;forwardRef&lt;/code&gt;로 감싼 컴포넌트는 두 번째 인자로 &lt;code class=&quot;language-text&quot;&gt;ref&lt;/code&gt;를 전달받으며, 이를 내부의 실제 DOM 요소에 연결할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;3-상태-끌어올리기-app에서-데이터-관리&quot;&gt;3. 상태 끌어올리기: App에서 데이터 관리&lt;/h2&gt;
&lt;p&gt;생성된 프로젝트 데이터는 사이드바와 상세 화면 모두에서 필요하므로, 가장 공통 분모인 &lt;code class=&quot;language-text&quot;&gt;App&lt;/code&gt; 컴포넌트에서 상태를 관리한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// App.jsx&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleAddProject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;projectData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;setProjectsState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;prevState&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; newProject &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;projectData&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 간단한 ID 생성&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;prevState&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;projects&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;prevState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;projects&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; newProject&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 기존 배열 복사 후 새 프로젝트 추가&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...렌더링 부분&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;NewProject onAdd&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handleAddProject&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;4-입력-타입-최적화-date-picker&quot;&gt;4. 입력 타입 최적화 (Date Picker)&lt;/h2&gt;
&lt;p&gt;사용자로부터 정확한 날짜 형식을 받기 위해 &lt;code class=&quot;language-text&quot;&gt;input&lt;/code&gt;의 &lt;code class=&quot;language-text&quot;&gt;type&lt;/code&gt; 속성을 활용한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Input type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text&quot;&lt;/span&gt; ref&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; label&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Title&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Input textarea ref&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;description&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; label&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Description&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Input type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt; ref&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dueDate&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; label&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Due Date&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;type=&quot;date&quot;&lt;/code&gt;를 설정하면 브라우저 내장 데이트 피커(Date Picker)가 활성화되어 편리하게 날짜를 선택할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;-요약-및-핵심-포인트&quot;&gt;💡 요약 및 핵심 포인트&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ref vs State&lt;/strong&gt;: 실시간 유효성 검사가 필요 없다면 &lt;code class=&quot;language-text&quot;&gt;useRef&lt;/code&gt;가 렌더링 최적화와 코드 간결성 면에서 유리하다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;forwardRef&lt;/strong&gt;: 커스텀 컴포넌트를 설계할 때 외부에서 제어할 수 있도록 &lt;code class=&quot;language-text&quot;&gt;forwardRef&lt;/code&gt;를 적용하는 습관을 들이자.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;불변성 유지&lt;/strong&gt;: 상태 배열을 업데이트할 때는 &lt;code class=&quot;language-text&quot;&gt;[...prevState.projects, newProject]&lt;/code&gt;와 같이 기존 데이터를 복사하여 불변성을 지켜야 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;5-데모&quot;&gt;5. 데모&lt;/h2&gt;
&lt;h2 id=&quot;데모&quot;&gt;&lt;img src=&quot;/assets/img/react/state/2.gif&quot; alt=&quot;데모&quot;&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;다음 단계:&lt;/strong&gt;
데이터 저장 로직은 완성되었다. 다음에는 입력값이 비어있을 때 경고를 띄우는 **유효성 검사(Validation)**와 &lt;strong&gt;모달(Modal)&lt;/strong&gt; 창 구현 방법을 알아보자.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[React] 객체 상태를 활용한 조건부 렌더링 구현 (#09-1)]]></title><description><![CDATA[📍 연관 포스팅 React 객체 상태를 활용한 조건부 렌더링 구현 ( 09 1) React useRef와 상태 끌어올리기 ( 09 2) Github 🔗 09 project management app 새로운 프로젝트를 생성하거나 목록을 보여주는 등의 복잡한 UI 전환을 효과적으로 관리하기]]></description><link>https://woojin-devv.github.io/posts/react-usestate/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/react-usestate/</guid><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h3 id=&quot;-연관-포스팅&quot;&gt;📍 연관 포스팅&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://woojin-devv.github.io/posts/react-usestate/&quot;&gt;React - 객체 상태를 활용한 조건부 렌더링 구현 (#09-1)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://woojin-devv.github.io/posts/react-useref/&quot;&gt;React - useRef와 상태 끌어올리기 (#09-2)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;github&quot;&gt;Github&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/woojin-devv/react-study/tree/main/09-project-management-app&quot;&gt;🔗 09-project-management-app&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;새로운 프로젝트를 생성하거나 목록을 보여주는 등의 복잡한 UI 전환을 효과적으로 관리하기 위해서는 &lt;strong&gt;상태(State) 설계&lt;/strong&gt;가 매우 중요하다. 이번 포스팅에서는 &lt;code class=&quot;language-text&quot;&gt;useState&lt;/code&gt;를 사용해 여러 상태를 하나의 객체로 관리하고, 이를 바탕으로 화면을 조건부로 렌더링하는 방법을 정리한다.&lt;/p&gt;
&lt;h2 id=&quot;1-usestate의-핵심-개념&quot;&gt;1. useState의 핵심 개념&lt;/h2&gt;
&lt;h3 id=&quot;usestate란-무엇인가&quot;&gt;useState란 무엇인가?&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;useState&lt;/code&gt;는 함수형 컴포넌트에서 **상태(State)**를 관리할 수 있게 해주는 React Hook이다. 상태가 변하면 React는 해당 컴포넌트를 **리렌더링(Re-rendering)**하여 변경된 UI를 화면에 즉시 반영한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setState&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;initialValue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;state&lt;/code&gt;&lt;/strong&gt;: 현재 상태 값.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;setState&lt;/code&gt;&lt;/strong&gt;: 상태를 업데이트하는 함수.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;initialValue&lt;/code&gt;&lt;/strong&gt;: 상태의 초기값.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-왜-상태를-객체로-관리할까&quot;&gt;🧐 왜 상태를 &apos;객체&apos;로 관리할까?&lt;/h3&gt;
&lt;p&gt;단순히 &lt;code class=&quot;language-text&quot;&gt;boolean&lt;/code&gt; 값을 여러 개 만드는 대신, 하나의 상위 컴포넌트(&lt;code class=&quot;language-text&quot;&gt;App&lt;/code&gt;)에서 객체 형태의 상태를 관리하면 데이터의 흐름을 파악하기 훨씬 수월하다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;연관 데이터의 그룹화&lt;/strong&gt;: 프로젝트 목록(&lt;code class=&quot;language-text&quot;&gt;projects&lt;/code&gt;)과 현재 선택된 프로젝트(&lt;code class=&quot;language-text&quot;&gt;selectedProjectId&lt;/code&gt;)는 논리적으로 연결된 데이터이다. 이를 하나로 묶으면 상태 관리의 흐름이 명확해진다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;상태 업데이트의 효율성&lt;/strong&gt;: 여러 개의 &lt;code class=&quot;language-text&quot;&gt;useState&lt;/code&gt;를 개별적으로 쓰는 대신, 하나의 객체만 업데이트하여 관련 데이터를 한 번에 제어할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;2-상태-설계-undefined-vs-null-전략&quot;&gt;2. 상태 설계: undefined vs null 전략&lt;/h2&gt;
&lt;p&gt;이번 구현에서는 &lt;code class=&quot;language-text&quot;&gt;selectedProjectId&lt;/code&gt;의 상태값에 따라 앱의 현재 &quot;모드&quot;를 결정한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;projectsState&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setProjectsState&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;selectedProjectId&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
  &lt;span class=&quot;token literal-property property&quot;&gt;projects&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; 
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;undefined&lt;/code&gt;&lt;/strong&gt;: 초기 상태. 아무 프로젝트도 선택되지 않았고, 추가 중도 아닌 대기 화면(Fallback) 상태를 의미한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;null&lt;/code&gt;&lt;/strong&gt;: &apos;Add Project&apos; 버튼을 눌러 새로운 프로젝트를 생성하려는 입력 폼 상태를 의미한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;ID (string/number)&lt;/code&gt;&lt;/strong&gt;: 특정 프로젝트를 클릭하여 상세 내용을 보고 있는 상태를 의미한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;단순히 &lt;code class=&quot;language-text&quot;&gt;true/false&lt;/code&gt;만 사용했다면 세 가지 이상의 상태를 표현하기 어려웠겠지만, 이처럼 값의 타입을 다르게 가져감으로써 화면 제어를 깔끔하게 처리할 수 있다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;3-상태-변경과-함수형-업데이트&quot;&gt;3. 상태 변경과 함수형 업데이트&lt;/h2&gt;
&lt;p&gt;상태를 업데이트할 때는 이전 상태(&lt;code class=&quot;language-text&quot;&gt;prevState&lt;/code&gt;)를 보존하는 것이 핵심이다.&lt;/p&gt;
&lt;h3 id=&quot;함수형-업데이트가-필요한-이유&quot;&gt;&apos;함수형 업데이트&apos;가 필요한 이유&lt;/h3&gt;
&lt;p&gt;React에서 상태 업데이트는 &lt;strong&gt;비동기적&lt;/strong&gt;으로 일어날 수 있다. 따라서 최신 상태를 안전하게 가져와 다음 상태를 계산하기 위해서는 &lt;code class=&quot;language-text&quot;&gt;prevState&lt;/code&gt;를 인자로 받는 콜백 함수를 사용하는 것이 가장 안전하다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleStartAddProject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;setProjectsState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;prevState&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;prevState&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 기존의 projects 배열 등 이전 상태 복사&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;selectedProjectId&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 새 프로젝트 작성 모드로 전환&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id=&quot;4-컴포넌트-간-통신과-조건부-렌더링&quot;&gt;4. 컴포넌트 간 통신과 조건부 렌더링&lt;/h2&gt;
&lt;h3 id=&quot;props를-통한-함수-전달&quot;&gt;Props를 통한 함수 전달&lt;/h3&gt;
&lt;p&gt;상태를 변경하는 함수(&lt;code class=&quot;language-text&quot;&gt;handleStartAddProject&lt;/code&gt;)를 하위 컴포넌트로 전달하여 버튼 클릭 시 상위 컴포넌트의 상태가 바뀌도록 연결한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// App.jsx 내부&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ProjectSidebar onStartAddProject&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handleStartAddProject&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;NoProjectSelected onStartAddProject&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handleStartAddProject&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;조건부-렌더링-로직&quot;&gt;조건부 렌더링 로직&lt;/h3&gt;
&lt;p&gt;상태값에 따라 어떤 컴포넌트를 변수에 담을지 결정한다. &lt;code class=&quot;language-text&quot;&gt;if-else&lt;/code&gt; 문을 사용하여 가독성을 높인다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;projectsState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selectedProjectId &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  content &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;NewProject &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;projectsState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selectedProjectId &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  content &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;NoProjectSelected onStartAddProject&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handleStartAddProject&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;main className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;h-screen my-8 flex gap-8&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ProjectSidebar onStartAddProject&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handleStartAddProject&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;main&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id=&quot;5-핵심-요약&quot;&gt;5. 핵심 요약&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;상태의 의미 분화&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;undefined&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;null&lt;/code&gt;을 구분하여 앱의 다중 모드(대기, 생성, 상세)를 효과적으로 제어한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;함수형 업데이트와 전개 연산자&lt;/strong&gt;: 객체 상태를 변경할 때는 &lt;code class=&quot;language-text&quot;&gt;...prevState&lt;/code&gt;를 통해 기존 데이터를 유지해야 한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;컴포넌트 구조화&lt;/strong&gt;: 부모의 상태 변경 함수를 자식에게 전달함으로써 UI의 일관성을 유지한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;6-코드&quot;&gt;6. 코드&lt;/h2&gt;
&lt;h3 id=&quot;appjsx&quot;&gt;App.jsx&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; useState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;react&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; NewProject &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./component/NewProject&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; ProjectSidebar &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./component/ProjectSidebar&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; NoProjectSelected &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./component/NoProjectSelected.jsx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;projectsState&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setProjectsState&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;selectedProjectId&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// neither adding a new project nor have a project selected&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleStartAddProject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;setProjectsState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;prevState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;prevState&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;selectedProjectId&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;projectsState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selectedProjectId &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    content &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;NewProject &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;projectsState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selectedProjectId &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    content &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;NoProjectSelected onStartAddProject&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handleStartAddProject&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;main className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;flex flex-row h-screen gap-8 my-8&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* &amp;lt;h1 className=&quot;my-8 text-5xl font-bold text-center&quot;&gt;Hello World&amp;lt;/h1&gt;
       */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ProjectSidebar onStartAddProject&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handleStartAddProject&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* &amp;lt;NoProjectSelected onStartAddProject={handleStartAddProject} /&gt; */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;main&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; App&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;데모&quot;&gt;데모&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/react/state/1.gif&quot; alt=&quot;데모&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Project가 Selected 되지 않은 상태면
&lt;ul&gt;
&lt;li&gt;NoProjectSelected 화면&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&apos;Create new project&apos; 버튼을 클릭
&lt;ul&gt;
&lt;li&gt;selectedProjectId가 null : 새프로젝트 추가&lt;/li&gt;
&lt;li&gt;selectedProjectId가 {어떤 값} : {어떤 값} 프로젝트 상세 보기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Javascript Core Concept]]></title><description><![CDATA[JavaScript 핵심 개념 및 실행 환경 정리 1. JavaScript의 다양한 실행 환경 JavaScript는 더 이상 브라우저에만 국한되지 않는 강력하고 유연한 언어입니다. 브라우저 (Browser): JS가 처음 만들어진 고전적인 환경 (90년대 시작). 서버 사이드 (Node]]></description><link>https://woojin-devv.github.io/posts/js-review/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/js-review/</guid><pubDate>Sun, 29 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;javascript-핵심-개념-및-실행-환경-정리&quot;&gt;JavaScript 핵심 개념 및 실행 환경 정리&lt;/h1&gt;
&lt;h2 id=&quot;1-javascript의-다양한-실행-환경&quot;&gt;1. JavaScript의 다양한 실행 환경&lt;/h2&gt;
&lt;p&gt;JavaScript는 더 이상 브라우저에만 국한되지 않는 강력하고 유연한 언어입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;브라우저 (Browser):&lt;/strong&gt; JS가 처음 만들어진 고전적인 환경 (90년대 시작).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;서버 사이드 (Node.js / Deno):&lt;/strong&gt; 브라우저 외부에서도 JS 코드를 실행할 수 있게 해주는 런타임 환경.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;모바일 앱 (Mobile):&lt;/strong&gt; &lt;strong&gt;React Native&lt;/strong&gt;나 &lt;strong&gt;Capacitor&lt;/strong&gt; 같은 기술을 사용하여 iOS 및 Android 앱 제작 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;2-html에-javascript를-추가하는-방법&quot;&gt;2. HTML에 JavaScript를 추가하는 방법&lt;/h2&gt;
&lt;p&gt;HTML 문서 내에서 &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script&gt;&lt;/code&gt; 태그를 사용하는 방식은 크게 두 가지로 나뉩니다.&lt;/p&gt;
&lt;h3 id=&quot;1-인라인-방식-inline-approach&quot;&gt;1) 인라인 방식 (Inline Approach)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;특징:&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script&gt;&lt;/code&gt; 태그 사이에 직접 코드를 작성.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;단점:&lt;/strong&gt; 코드가 길어지면 HTML 파일이 복잡해지고 유지보수가 어려움. 주로 아주 짧은 스크립트에만 사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2-외부-파일-임포트-방식-external-files---권장&quot;&gt;2) 외부 파일 임포트 방식 (External Files) - &lt;strong&gt;권장&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;특징:&lt;/strong&gt; 별도의 &lt;code class=&quot;language-text&quot;&gt;.js&lt;/code&gt; 파일을 만들고 HTML에서 불러오는 방식.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;장점:&lt;/strong&gt; 프로젝트 유지보수가 쉽고 코드가 깔끔해짐.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;방법:&lt;/strong&gt; ```html
  &lt;script src=&quot;assets/scripts/app.js&quot;&gt;&lt;/script&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;3-script-태그의-주요-속성-attributes&quot;&gt;3. &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script&gt;&lt;/code&gt; 태그의 주요 속성 (Attributes)&lt;/h2&gt;
&lt;p&gt;브라우저가 스크립트를 처리하는 방식을 제어하기 위해 중요한 속성들이 있습니다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;속성&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;src&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;불러올 JavaScript 파일의 경로를 지정합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;defer&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;HTML 파싱이 모두 끝난 후 스크립트를 실행하도록 합니다. HTML 요소가 로드되기 전에 스크립트가 실행되어 에러가 발생하는 것을 방지합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;type=&quot;module&quot;&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;파일을 &lt;strong&gt;자바스크립트 모듈&lt;/strong&gt;로 취급합니다. 이 설정을 통해 &lt;code class=&quot;language-text&quot;&gt;import&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;export&lt;/code&gt; 구문을 사용할 수 있게 됩니다. (현대적인 프로젝트에서 필수)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&quot;4-react와-빌드-프로세스-build-process&quot;&gt;4. React와 빌드 프로세스 (Build Process)&lt;/h2&gt;
&lt;p&gt;실제 React 프로젝트를 진행할 때는 우리가 직접 HTML에 &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script&gt;&lt;/code&gt; 태그를 일일이 추가하는 일이 거의 없습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;이유:&lt;/strong&gt; React 프로젝트는 보통 &lt;strong&gt;빌드 프로세스&lt;/strong&gt;를 거치기 때문입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자동화:&lt;/strong&gt; 빌드 도구가 우리가 작성한 여러 JS 파일들을 최적화하고, 최종 HTML 파일에 필요한 &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script&gt;&lt;/code&gt; 태그를 **자동으로 주입(Inject)**해 줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;-요약-및-다음-단계&quot;&gt;💡 요약 및 다음 단계&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;JS는 브라우저뿐만 아니라 서버, 모바일에서도 쓰이는 범용 언어다.&lt;/li&gt;
&lt;li&gt;HTML에 스크립트를 넣을 때는 유지보수를 위해 외부 파일 형식을 사용한다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;type=&quot;module&quot;&lt;/code&gt;을 사용하면 파일 간에 코드를 주고받는 &lt;code class=&quot;language-text&quot;&gt;import/export&lt;/code&gt;가 가능해진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;강의 내용을 바탕으로 JavaScript의 &lt;code class=&quot;language-text&quot;&gt;import&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;export&lt;/code&gt; 핵심 개념을 블로그에 올리기 좋게 &lt;strong&gt;Markdown&lt;/strong&gt; 형식으로 정리해 드립니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;5-import--export-정리&quot;&gt;5. Import &amp;#x26; Export 정리&lt;/h2&gt;
&lt;p&gt;React와 같은 현대적인 자바스크립트 프로젝트에서는 코드를 유지보수하기 쉽게 여러 파일로 나누어 관리합니다. 이때 파일 간에 변수나 함수를 공유하기 위해 사용하는 핵심 키워드가 바로 &lt;code class=&quot;language-text&quot;&gt;export&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;import&lt;/code&gt;입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;1-named-export-이름을-내보내기&quot;&gt;1. Named Export (이름을 내보내기)&lt;/h3&gt;
&lt;p&gt;가장 기본적인 방식입니다. 한 파일에서 &lt;strong&gt;여러 개의 변수나 함수&lt;/strong&gt;를 내보낼 때 유용합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;내보낼 때 (&lt;code class=&quot;language-text&quot;&gt;util.js&lt;/code&gt;):&lt;/strong&gt; 변수나 함수 앞에 &lt;code class=&quot;language-text&quot;&gt;export&lt;/code&gt; 키워드를 붙입니다.
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; apiKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;abc123cryptic&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; abc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;someValue&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;가져올 때 (&lt;code class=&quot;language-text&quot;&gt;app.js&lt;/code&gt;):&lt;/strong&gt; 중괄호 &lt;code class=&quot;language-text&quot;&gt;{ }&lt;/code&gt; 안에 내보낸 이름을 그대로 적습니다.
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; apiKey&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; abc &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./util.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 참고:&lt;/strong&gt; React 빌드 시스템을 사용하면 확장자(&lt;code class=&quot;language-text&quot;&gt;.js&lt;/code&gt;)를 생략할 수 있지만, 순수 자바스크립트 환경(Vanilla JS)에서는 파일 경로 뒤에 &lt;code class=&quot;language-text&quot;&gt;.js&lt;/code&gt;를 반드시 붙여야 한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;2-default-export-기본-내보내기&quot;&gt;2. Default Export (기본 내보내기)&lt;/h3&gt;
&lt;p&gt;한 파일당 &lt;strong&gt;단 하나&lt;/strong&gt;만 존재할 수 있는 특별한 내보내기 방식입니다. 주로 파일의 메인 기능을 내보낼 때 사용합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;내보낼 때 (&lt;code class=&quot;language-text&quot;&gt;util.js&lt;/code&gt;):&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;default&lt;/code&gt; 키워드를 사용하며, 이름 없이 값만 전달할 수 있습니다.
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;abc123cryptic&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;가져올 때 (&lt;code class=&quot;language-text&quot;&gt;app.js&lt;/code&gt;):&lt;/strong&gt; 중괄호 &lt;code class=&quot;language-text&quot;&gt;{ }&lt;/code&gt; 없이 &lt;strong&gt;원하는 이름&lt;/strong&gt;으로 자유롭게 정의하여 가져옵니다.
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; apiKey &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./util.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 이름을 myKey 등으로 바꿔도 무방함&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;3-유용한-활용-팁&quot;&gt;3. 유용한 활용 팁&lt;/h3&gt;
&lt;h4 id=&quot;alias-사용하기-이름-변경&quot;&gt;Alias 사용하기 (이름 변경)&lt;/h4&gt;
&lt;p&gt;가져오는 파일 내에서 변수명이 중복되거나 마음에 들지 않을 때 &lt;code class=&quot;language-text&quot;&gt;as&lt;/code&gt; 키워드로 이름을 바꿀 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; abc &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; content &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./util.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// util.js의 abc 값을 출력&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;모든-요소를-객체로-묶어서-가져오기&quot;&gt;모든 요소를 객체로 묶어서 가져오기&lt;/h4&gt;
&lt;p&gt;파일 안의 모든 &lt;code class=&quot;language-text&quot;&gt;export&lt;/code&gt; 항목을 하나의 객체로 그룹화하여 가져올 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; util &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./util.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;util&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;apiKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;util&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;default&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// default export는 .default로 접근&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h3 id=&quot;4-주의사항-type-module&quot;&gt;4. 주의사항 (Type Module)&lt;/h3&gt;
&lt;p&gt;브라우저에서 직접 이 문법을 사용할 때는 &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script&gt;&lt;/code&gt; 태그에 &lt;code class=&quot;language-text&quot;&gt;type=&quot;module&quot;&lt;/code&gt; 속성을 추가해야 합니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;app.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;module&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;React 프로젝트에서는 빌드 도구(Webpack, Vite 등)가 파일을 하나로 합쳐주기 때문에 이 속성을 직접 관리할 필요가 없습니다.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;정리하자면:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;여러 개를 내보낼 땐 &lt;strong&gt;Named Export&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;{ }&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;하나의 메인을 내보낼 땐 &lt;strong&gt;Default Export&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;가져올 때 이름 변경은 &lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;as&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;모두 한 번에 가져올 땐 &lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;* as&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[2주차 - 네트워크]]></title><description><![CDATA[38. 네트워크 기초 1 네트워크란? 노드와 링크가 서로 연결되어 있으며 리소스를 공유하는 집합을 의미함. 노드 : 서버, 라우터, 스위치 등 네트워크 장치 링크 : 유선 또는 무선과 같은 연결매체 (와이파이나 LAN) 트래픽 특정 시점에 링크 내에 흐르는 데이터의 양 트래픽이 많아졌다]]></description><link>https://woojin-devv.github.io/posts/cs-interview-study-2/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/cs-interview-study-2/</guid><pubDate>Sat, 28 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;38-네트워크-기초-1&quot;&gt;38. 네트워크 기초 #1&lt;/h2&gt;
&lt;hr&gt;
&lt;h2 id=&quot;네트워크란&quot;&gt;네트워크란?&lt;/h2&gt;
&lt;p&gt;노드와 링크가 서로 연결되어 있으며 리소스를 공유하는 집합을 의미함.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;노드 : 서버, 라우터, 스위치 등 네트워크 장치&lt;/li&gt;
&lt;li&gt;링크 : 유선 또는 무선과 같은 연결매체 (와이파이나 LAN)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;트래픽&quot;&gt;트래픽&lt;/h3&gt;
&lt;p&gt;특정 시점에 링크 내에 흐르는 데이터의 양&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;트래픽이 많아졌다 → 흐르는 데이터가 많아졌다.&lt;/li&gt;
&lt;li&gt;처리량이 많아졌다. → 처리되는 트래픽이 많아졌다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;대역폭bandwidth&quot;&gt;대역폭(bandwidth)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;주어진 시간 동안 네트워크 연결을 통해 흐를 수 있는 최대 비트 수 (최대 트래픽)
&lt;ul&gt;
&lt;li&gt;대역폭이 높을 수록
&lt;ul&gt;
&lt;li&gt;사용자에게 빠른 서비스를 서빙할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;대략적인 최대 동시 접속자 수 유추의 척도가 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;q-100mbps-라는-대역폭을-가진-서버가-존재하고-한-사용자당-100kbps로-동영상-파일을-요청한다고-가정할-때-최대-동시-접속자-수는&quot;&gt;Q. 100Mbps 라는 대역폭을 가진 서버가 존재하고, 한 사용자당 100kbps로 동영상 파일을 요청한다고 가정할 때, 최대 동시 접속자 수는?&lt;/h3&gt;
&lt;div class=&quot;math math-display&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mn&gt;100&lt;/mn&gt;&lt;mtext&gt; Mbps&lt;/mtext&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mn&gt;100&lt;/mn&gt;&lt;mtext&gt; kbps&lt;/mtext&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mtext&gt;약 1000명&lt;/mtext&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\frac{100 \text{ Mbps}}{100 \text{ kbps}} = {\text{약 1000명}}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:2.2519em;vertical-align:-0.8804em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mopen nulldelimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:1.3714em;&quot;&gt;&lt;span style=&quot;top:-2.314em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;mord text&quot;&gt;&lt;span class=&quot;mord&quot;&gt; kbps&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.23em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;frac-line&quot; style=&quot;border-bottom-width:0.04em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-3.677em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:3em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;mord text&quot;&gt;&lt;span class=&quot;mord&quot;&gt; Mbps&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.8804em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose nulldelimiter&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord text&quot;&gt;&lt;span class=&quot;mord hangul_fallback&quot;&gt;약&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt; 1000&lt;/span&gt;&lt;span class=&quot;mord hangul_fallback&quot;&gt;명&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h3 id=&quot;rttround-trip-time&quot;&gt;RTT(Round Trip Time)&lt;/h3&gt;
&lt;p&gt;왕복지연시간은 신호를 전송하고 해당 신호를 수신확인에 걸린 시간을 더한 값이자 어떤 메시지가 두 장치 사이를 왕복하는 데 걸린 시간&lt;/p&gt;
&lt;h2 id=&quot;39-40-네트워크-기초-23-네트워크-토폴로지&quot;&gt;39-40. 네트워크 기초 #2~3. 네트워크 토폴로지&lt;/h2&gt;
&lt;hr&gt;
&lt;h2 id=&quot;네트워크-토폴로지&quot;&gt;네트워크 토폴로지&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/14.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;p&gt;토폴로지란? 노드와 링크가 어떠한 구조로 연결되어 있는 지를 도식화한 것.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;버스-토폴로지&quot;&gt;버스 토폴로지&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;회선 하나에 여러 개의 노드가 연결된 구조&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;하나의 중앙 통신 회선을 &lt;strong&gt;백본&lt;/strong&gt; 또는 &lt;strong&gt;버스&lt;/strong&gt;라고 부름&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;설치 비용 적음&lt;/li&gt;
&lt;li&gt;유지보수 쉬움&lt;/li&gt;
&lt;li&gt;한 노드에 장애 발생해도 전체 네트워크에 영향 안줌&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;회선에 많은 트래픽이 생기면 정체 현상 발생 가능 (패킷 손실율 높음)&lt;/li&gt;
&lt;li&gt;회선이 망가지먼 전체 네트워크에 영향을 줌&lt;/li&gt;
&lt;li&gt;패킷 도청(스니핑)이나 위조(스푸핑) 등의 보안 위협에 취약&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;스타-토폴로지&quot;&gt;스타 토폴로지&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;하나의 중앙 노드(허브나 스위치)를 중심으로 여러 개의 말단 노드가 별 모양 처럼 각각 독립적인 구조로 연결 된 구조&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모든 통신은 항상 중앙 노드를 통해서만 이루어짐&lt;/li&gt;
&lt;li&gt;노드의 추가 및 삭제가 간단&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;모든 통신이 중앙 노드를 통과하므로 방화벽, 침입 탐지 시스템(IDS)등 보안 장비를 중앙에 집중 적용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;중앙 노드 에러 시에 큰 문제 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;트리-토폴로지&quot;&gt;트리 토폴로지&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;계층 구조를 가진 토폴로지 → 트리형태&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;리프 노드로의 확장 용이&lt;/li&gt;
&lt;li&gt;리프노드의 에러는 나머지 부분의 영향을 미치지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;특정 노드 트래픽 집중시 그 하위 모든 노드이 병목 현상 발생 가능&lt;/li&gt;
&lt;li&gt;로프 노드에 문제 생기면 전체 네트워크 문제 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;링-토폴로지&quot;&gt;링 토폴로지&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;노드 고장 위치 쉽게 파악 가능&lt;/li&gt;
&lt;li&gt;각 노드가 앞 뒤 두 노드랑만 연결되므로 이론상으로 추가 및 삭제가 용이하지만
&lt;ul&gt;
&lt;li&gt;실제 물리적 네트워크에서는 일시적 중단 발생할 수 있으므로 이중 링 설계 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;데이터 전송시 다른 노드들을 거쳐야하므로 전송지연(latency)가 발생 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;메시-토폴로지&quot;&gt;메시 토폴로지&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Full Mesh : 모든 노드가 서로 1:1로 연결된 구조&lt;/li&gt;
&lt;li&gt;Partial Mesh: 일부 노드만 연결된 구조&lt;/li&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;안정성이 높음&lt;/p&gt;
&lt;p&gt;→ 한 노드에 장애가 나도 다른 노드에 영향을 주지 않음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;트래픽 분산 가능&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;기본적으로 연결되는 회선(링크)가 많기 때문에 초기 구축 비용, 설계 비용, 관리 비용이 많아짐&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;41-네트워크-기초-4-병목-현상과-네트워크-토폴로지의-필요성&quot;&gt;41. 네트워크 기초 #4. 병목 현상과 네트워크 토폴로지의 필요성&lt;/h2&gt;
&lt;hr&gt;
&lt;h3 id=&quot;병목현상&quot;&gt;병목현상&lt;/h3&gt;
&lt;p&gt;병목(bottleneck)현상은 네트워크에서 트래픽이 특정 구간에 집중되어 데이터 흐름 속도가 제한되는 상황을 말한다. → 핫스팟이라고도 함.&lt;/p&gt;
&lt;h3 id=&quot;병목현상-원인&quot;&gt;병목현상 원인&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;대역폭 부족 : 라우터, 스위치, 특정 링크가 감당할 수 있는 트래픽보다 많은 데이터가 몰릴 때
&lt;ul&gt;
&lt;li&gt;예) 본사와 지사 간 연결 선이 100Mbps로 제한되어 있는데, 동시에 여러 지사에서 대용량 파일을 전송하면 포화상태 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;서버/애플리케이션 처리 능력 한계 : 서버 CPU, 메모리, 스레드 풀 부족으로 패킷 처리가 지연&lt;/li&gt;
&lt;li&gt;네트워크 토폴로지 문제(구조 문제): 여러 클라이언트가 하나의 경로를 공유할 때 특정 구간에서 발생&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;토폴로지의-필요성&quot;&gt;토폴로지의 필요성&lt;/h3&gt;
&lt;p&gt;토폴로지를 파악함으로써 병목현상을 해결하는 척도&lt;/p&gt;
&lt;h3 id=&quot;어떻게-해결&quot;&gt;💬 어떻게 해결?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/15.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;위 그림처럼 중간에 로드 밸런서 부분에서 병목현상이 일어난다는 것을 파악, 서버, DB로 부터 회선을 더 추가하여 병목현상 해결 가능&lt;/p&gt;
&lt;h2 id=&quot;42-네트워크-기초-5-유니캐스트--멀티캐스트--브로드-캐스트&quot;&gt;42. 네트워크 기초 #5. 유니캐스트 / 멀티캐스트 / 브로드 캐스트&lt;/h2&gt;
&lt;hr&gt;
&lt;h3 id=&quot;유니캐스트&quot;&gt;유니캐스트&lt;/h3&gt;
&lt;p&gt;1:1 통신을 말함. (가장 일반적인 통신)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;예 ) HTTP&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/16.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;멀티캐스트&quot;&gt;멀티캐스트&lt;/h3&gt;
&lt;p&gt;1:N 통신,&lt;/p&gt;
&lt;p&gt;다만 연결된 모든 노드들에게 데이터를 전달하지는 않고 특정 그룹에게만 데이터를 전달함&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/17.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;브로드캐스트&quot;&gt;브로드캐스트&lt;/h3&gt;
&lt;p&gt;1:N 통신,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;그룹이 아닌 연결되어있는 모든 노드에게 데이터를 전달함.
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;예) ARP&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/18.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;43-네트워크-분류--lan-man-wan&quot;&gt;43. 네트워크 분류 : LAN, MAN, WAN&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;네트워크는 LAN, MAN, WAN 순으로 분류됩니다. LAN이 가장 작은 단위, WAN이 가장 큰 단위이며 보통은 반경, 속도의 크기를 기반으로 분류&lt;/p&gt;
&lt;h3 id=&quot;lan&quot;&gt;LAN&lt;/h3&gt;
&lt;p&gt;LAN(local area network, 근거리 통신망)은 MAN, WAN보다 높은 안정성, 속도를 가짐.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;보통 허브나 스위치로 연결된 네트워크&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;man&quot;&gt;MAN&lt;/h3&gt;
&lt;p&gt;MAN(metropolitan area network, 대도시 통신망)은 도시와 도시의 통신망을 뜻하며 2개 이상의 LAN이 연결되어 구성됨&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;라우터, 브리지 등으로 연결됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;wan&quot;&gt;WAN&lt;/h3&gt;
&lt;p&gt;WAN(wide area network)은 국가와 국가와의 통신망을 뜻함.&lt;/p&gt;
&lt;p&gt;→ 인터넷이라고도 함.&lt;/p&gt;
&lt;p&gt;→ 수많은 라우터를 거쳐 다른 국가와도 연결되는 범위를 말함.&lt;/p&gt;
&lt;h2 id=&quot;44-tcpip-4계층-1-개요&quot;&gt;44. TCP/IP 4계층 #1 개요&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;TCP / IP 4계층은 장치들이 인터넷 상에서 데이터를 주고받을 때 쓰는 프로토콜의 집합입니다. 4계층 혹은 7계층으로 나누어집니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/1.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;애플리케이션-계층application&quot;&gt;애플리케이션 계층(Application)&lt;/h3&gt;
&lt;p&gt;애플리케이션 계층은 OSI 7계층 또는 TCP/IP 4계층 모델에서 &lt;strong&gt;가장 최상단에 위치한 계층&lt;/strong&gt;이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;사용자가 웹사이트를 열거나 이메일을 보내는 등의 작업을 수행할 때, 그 데이터를 어떻게 보내야 하는지 결정하는 프로토콜들이 모여있는 계층&lt;/li&gt;
&lt;li&gt;HTTP, HTTPS, SMTP, SSH, FTP, SSH가 대표적&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;전송-계층transport&quot;&gt;전송 계층(Transport)&lt;/h3&gt;
&lt;p&gt;TCP, UDP가 대표적이며 애플리케이션계층에서 받은 메시지를 기반으로 &lt;strong&gt;세그먼트(TCP)&lt;/strong&gt; 또는 **데이터그램(UDP)**으로 데이터를 쪼개고 데이터가 오류없이 순서대로 전달되도록 도움을 주는 계층&lt;/p&gt;
&lt;h3 id=&quot;인터넷-계층network&quot;&gt;인터넷 계층(network)&lt;/h3&gt;
&lt;p&gt;IP, ICMP, ARP가 대표적이며 한 노드에서 다른 노드로 전송 계층에서 받은 &lt;strong&gt;세그먼트 또는 데이터그램을 패킷화&lt;/strong&gt;하여 목적지로 전송하는 역할&lt;/p&gt;
&lt;h3 id=&quot;링크-계층link-network-access-계층&quot;&gt;링크 계층(link) – Network Access 계층&lt;/h3&gt;
&lt;p&gt;링크 계층은 전선, 광섬유, 무선 등으로 데이터가 네트워크를 통해 물리적으로 전송되는 방식을 정의&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;데이터링크 + 물리 계층&lt;/strong&gt;을 합친 계층&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;메시지-전송과정-예시&quot;&gt;메시지 전송과정 예시&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/2.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;checksum-체크섬&quot;&gt;Checksum (체크섬)&lt;/h3&gt;
&lt;p&gt;체크섬은 데이터를 전송할 때 &lt;strong&gt;오류가 발생했는지 확인하기 위해&lt;/strong&gt; 덧붙이는 추가 데이터 조각이며 “받은 데이터가 손상됐는지 판별하는 값&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;각 계층에 따라 사용되는 체크섬 알고리즘이 다름&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;사용 위치&lt;/th&gt;
&lt;th&gt;체크섬 알고리즘&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;IPv4 헤더&lt;/td&gt;
&lt;td&gt;1의 보수합&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TCP/UDP 헤더&lt;/td&gt;
&lt;td&gt;1의 보수합&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ethernet 프레임(FCS)&lt;/td&gt;
&lt;td&gt;CRC-32&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;1의-보수합&quot;&gt;1의 보수합&lt;/h3&gt;
&lt;p&gt;모든 데이터를 16비트 단위로 더한 뒤, 그 합의 1의 보수를 취해 체크섬으로 사용한다는 것.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;수신 측은 데이터 + 체크섬의 합이 0xFFFF가 되는지 검사하여, 데이터가 손상되었는 지를 판별&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;1의-보수란&quot;&gt;🧐 1의 보수란?&lt;/h3&gt;
&lt;p&gt;1의 보수는 이진수의 모든 비트를 반전 시킨 값&lt;/p&gt;
&lt;p&gt;0 → 1로, 1 → 0으로 바꿈&lt;/p&gt;
&lt;div class=&quot;math math-display&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;01001011&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;01001011&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;01001011&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;math math-display&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;10110100&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;10110100&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;10110100&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h3 id=&quot;순환캐리&quot;&gt;🧐 순환캐리&lt;/h3&gt;
&lt;p&gt;1의 보수합을 계산할 때는 단순히 16비트 이상으로 넘치는 값을 잘라내는 것이 아닐, 넘친 비트(carry)를 다시 아래쪽으로 더해줌. 이것을 순환 캐리(end-around carry)라고 함.&lt;/p&gt;
&lt;p&gt;16진수 0xFFFF는 10진수로는 65535이며 2진수로는 16비트가 모두 1인 1111 1111 1111 1111를 의미한다.&lt;/p&gt;
&lt;h3 id=&quot;crccyclic-redundancy-check&quot;&gt;🧐 CRC(Cyclic Redundancy Check)&lt;/h3&gt;
&lt;p&gt;원본 데이터에 0을 다항식 차수만큼 덧붙이고 해당 비트를 왼쪽부터 차례대로 XOR 기반 이진 나눗셈을 수행한다.&lt;/p&gt;
&lt;h2 id=&quot;45-tcpip-4계층-2-mtu--mss&quot;&gt;45. TCP/IP 4계층 #2. MTU &amp;#x26; MSS&lt;/h2&gt;
&lt;hr&gt;
&lt;h3 id=&quot;mtu&quot;&gt;MTU&lt;/h3&gt;
&lt;p&gt;MTU는 네트워크 계층에서 IP 패킷 전체 크기(헤더 + 데이터)의 최대값이고 보통 1500바이트임.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MSS(Maximum Segment Size)는 TCP에서 페이로드 최대 크기만을 가리킴.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/3.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;p&gt;데이터는 전송 전에 패킷 단위로 쪼개진다. 이때 MTU를 기준으로 크기가 결정된다.&lt;/p&gt;
&lt;p&gt;따라서 네트워크 경로에 있는 어떤 장치의 MTU보다 패킷의 크기가 클 경우, 해당 패킷은 더 작은 단위로 분할되어 전송된다.&lt;/p&gt;
&lt;h3 id=&quot;패킷이-분할-되지-않는-경우&quot;&gt;패킷이 분할 되지 않는 경우&lt;/h3&gt;
&lt;p&gt;패킷은 항상 분할되지는 않음.&lt;/p&gt;
&lt;p&gt;→ IP 버전에 따라 MTU에 따라 분할되거나 분할되지 않을 수 있음&lt;/p&gt;
&lt;h3 id=&quot;ipv6&quot;&gt;IPv6&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;패킷의 크기가 MTU보다 클 경우, 라우터가 해당 패킷을 폐기하고 Packet Too Big ICMPv6 메시지를 보냄&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;ipv4&quot;&gt;IPv4&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;IPv4 헤더에는 flags라는 필드가 있는데 여기서 bit이 1이되면 “Don’t Fragment” 플래그가 활성화된다는 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;46-애플리케이션-계층-application&quot;&gt;46. 애플리케이션 계층 (application)&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;HTTP, SMTP, SSH, FTP가 대표적이며 웹 서비스, 이메일 등 서비스를 실질적으로 사람에게 제공하는 층이다.&lt;/p&gt;
&lt;h3 id=&quot;http&quot;&gt;HTTP&lt;/h3&gt;
&lt;p&gt;HTTP(Hypertext Transfer Protocol)은 처음에는 서버와 브라우저 간에 데이터를 주고 받기 위해 설계된 프로토콜이다. 하지만 지금은 브라우저 뿐 아니라 서버간의 통신할 때도 사용한다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;HTTP는 헤더를 통한 확장이 쉽다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HTTP는 Stateless&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/4.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;ssh&quot;&gt;SSH&lt;/h3&gt;
&lt;p&gt;SSH(Secure Shell Protocol)은 보안되지 않은 네트워크에서 네트워크 서비스를 안전하기 위한 암호화 네트워크 프로토콜&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;pem&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;user&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;@&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;serverIP&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;보통 프라이빗 키가 있는 경로에서 이런 식으로 키를 명시하고 실행함.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;ftp-file-transfer-protocol&quot;&gt;FTP (File Transfer Protocol)&lt;/h3&gt;
&lt;p&gt;노드와 노드간의 파일을 전송하는데 사용하는 프로토콜&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FileZilla (예시)&lt;/li&gt;
&lt;li&gt;로컬 PC에서 원격 PC로 파일을 전송할 때 사용하는 프로토콜&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;smtp&quot;&gt;SMTP&lt;/h3&gt;
&lt;p&gt;인터넷을 통해 메일을 보낼 때 사용되는 프로토콜(Simple Mail Transfer Protocol)&lt;/p&gt;
&lt;h2 id=&quot;47-전송계층-transport&quot;&gt;47. 전송계층 (Transport)&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;애플리케이션 계층에서 받은 메시지를 기반으로 세그먼트 혹은 데이터그램으로 데이터를 쪼개고 데이터가 오류없이 순서대로 전달되도록 도움을 주는 층&lt;/p&gt;
&lt;h2 id=&quot;tcp--udp-차이점&quot;&gt;TCP / UDP 차이점&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th&gt;TCP (전송 제어 프로토콜)&lt;/th&gt;
&lt;th&gt;UDP (사용자 데이터그램 프로토콜)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;패킷 교환방식&lt;/td&gt;
&lt;td&gt;가상회선 방식&lt;/td&gt;
&lt;td&gt;데이터그램 방식&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;신뢰성&lt;/td&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;오류검사&lt;/td&gt;
&lt;td&gt;재전송, 체크섬&lt;/td&gt;
&lt;td&gt;체크섬&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;순서 보장&lt;/td&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;헤더 길이&lt;/td&gt;
&lt;td&gt;20~60 바이트 (가변)&lt;/td&gt;
&lt;td&gt;8 바이트 (고정)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;연결&lt;/td&gt;
&lt;td&gt;연결 지향 (3-way / 4-way handshake)&lt;/td&gt;
&lt;td&gt;비연결&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;브로드캐스트&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;속도&lt;/td&gt;
&lt;td&gt;느림&lt;/td&gt;
&lt;td&gt;빠름&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;48-인터넷-계층network&quot;&gt;48. 인터넷 계층(network)&lt;/h2&gt;
&lt;hr&gt;
&lt;h2 id=&quot;인터넷-계층&quot;&gt;인터넷 계층&lt;/h2&gt;
&lt;p&gt;IP, ICMP, ARP가 대표적이며 한 노드에서 다른 노드로 전송 계층에서 받은 세그먼트 또는 데이터 그램을 패킷화하여 전송&lt;/p&gt;
&lt;h3 id=&quot;icmp&quot;&gt;ICMP&lt;/h3&gt;
&lt;p&gt;ICMP는 노드와 노드 사이에서 통신이 잘되나를 확인할 때 쓰는 프로토콜&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;데이터를 교환하는 데 사용되지 않음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;일반적으로 테스팅에 사용됨&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/5.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;49-tcp--3-way-handshake&quot;&gt;49. TCP : 3-way handshake&lt;/h2&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li&gt;SYN 단계: 클라이언트는 서버에 클라이언트의 ISN을 담아 SYN을 보낸다.&lt;/li&gt;
&lt;li&gt;SYN + ACK 단계: 서버는 클라이언트의 SYN을 수신하고 서버의 ISN을 보내며 승인번호로 클라이언트의 ISN + 1을 보낸다.&lt;/li&gt;
&lt;li&gt;ACK 단계: 클라이언트는 서버의 ISN + 1한 값인 승인번호를 담아 ACK를 서버에 보낸다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;isn이란&quot;&gt;🧐 ISN이란?&lt;/h3&gt;
&lt;p&gt;TCP(Transmission Control Protocol) 기반 데이터 통신에서 각각의 새 연결에 할당된 고유한 32비트 시퀀스 번호&lt;/p&gt;
&lt;h3 id=&quot;syn&quot;&gt;SYN&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Synchronization의 약자 - &lt;strong&gt;연결 요청&lt;/strong&gt; 플래그&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;ack&quot;&gt;ACK&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;acknowledgement의 약자 - &lt;strong&gt;응답&lt;/strong&gt; 플래그&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;50-tcp-4-way-handshake--time_wait&quot;&gt;50. TCP: 4-way handshake &amp;#x26; TIME_WAIT&lt;/h2&gt;
&lt;hr&gt;
&lt;h3 id=&quot;time_wait이-필요한-이유&quot;&gt;TIME_WAIT이 필요한 이유&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;지연 패킷을 받기 위함 → 데이터의 무결성을 지킴&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;51--라우팅-1--개념&quot;&gt;51.  라우팅 #1 . 개념&lt;/h2&gt;
&lt;hr&gt;
&lt;h3 id=&quot;라우팅routing이란&quot;&gt;라우팅(routing)이란?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/6.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;네트워크에서 데이터를 전송할 때 최적의 경로를 선택하는 과정&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;라우터가 이를 수행함.&lt;/li&gt;
&lt;li&gt;데이터는 보통 출발지에서 목적지로 가는 동안 여러 개의 라우터를 거치며 여러 번의 라우팅을 수행
&lt;ul&gt;
&lt;li&gt;보통 초당 수백만번 일어남.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;라우터router&quot;&gt;라우터(router)&lt;/h3&gt;
&lt;p&gt;라우터는 네트워크 사이에서 데이터를 전달하는 장치&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;보통 둘 이상의 서로 다른 네트워크에 연결됨&lt;/li&gt;
&lt;li&gt;데이터를 목적지로 보낼 때 최적의 경로를 결정하고, 경로가 결정되면 해당 경로로 데이터를 넘겨주는 일(라우팅)을 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;라우팅-테이블&quot;&gt;라우팅 테이블&lt;/h3&gt;
&lt;p&gt;라우팅 테이블은 IP 주소를 기반으로 라우터의 위치를 저장한 테이블 또는 데이터베이스 이며 다양한 네트워크에 대한 정보와 해당 네트워크에 연결하는 방법이 포함되어 있음&lt;/p&gt;
&lt;h2 id=&quot;52-라우팅-2--라우팅테이블&quot;&gt;52. 라우팅 #2.  라우팅테이블&lt;/h2&gt;
&lt;hr&gt;
&lt;h3 id=&quot;라우팅-테이블-1&quot;&gt;라우팅 테이블&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/7.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;p&gt;예) PC 1 → &lt;strong&gt;101.25.67.7&lt;/strong&gt;로 데이터를 보내려고 할 때&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;101.25.67.7은&lt;/strong&gt; 101.25.67.0 과 같은 클래스 내의 네트워크임&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;라우팅 테이블은 IP 주소를 기반으로 라우터의 위치를 저장한 테이블 또는 데이터베이스 이며 다양한 네트워크에 대한 정보와 해당 네트워크에 연결하는 방법이 포함되어 있음&lt;/p&gt;
&lt;h3 id=&quot;라우팅-테이블의-구성요소&quot;&gt;라우팅 테이블의 구성요소&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;네트워크 대상 (Network Destination)&lt;/strong&gt;: 목적지 네트워크의 IP 주소&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;서브넷 마스크(Netmask)&lt;/strong&gt;: 대상 주소를 설명할 때 쓰이는 값.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;게이트웨이(Gateway)&lt;/strong&gt;: 이 장치와 연결되어 있는 홉, 패킷이 전달되는 다음 IP 주소(외부 네트워크와 연결된 장치)
&lt;ul&gt;
&lt;li&gt;만약 목적지가 로컬 네트워크라면 연결됨(connected)라고 표기되며, 다른 네트워크라면 해당 네트워크의 게이트웨이를 가리킴&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;인터페이스(Interface)&lt;/strong&gt;: 게이트웨이로 가기 위해 거치는 장치
&lt;ul&gt;
&lt;li&gt;10.0.0.2는 eth3을 통해 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;메트릭(Metric)&lt;/strong&gt;: 우선순위라고도 불리며 패킷 전송을 위해 최적의 경로가 선택되도록 참고되는 값
&lt;ul&gt;
&lt;li&gt;일반적으로 홉 수(hop count), 처리량이 들어감&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;게이트웨이gateway&quot;&gt;게이트웨이(Gateway)&lt;/h3&gt;
&lt;p&gt;게이트웨이는 프로토콜 변환기라고도 하며 네트워크와 네트워크를 잇는 장치이다. 라우터와 하는 기능 자체가 비슷&lt;/p&gt;
&lt;h3 id=&quot;홉hop&quot;&gt;홉(hop)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/8.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WorkStation 1 → 2로 이동한다고 가정할 때,
&lt;ul&gt;
&lt;li&gt;hop count = 2 (→ 건너 뛴 Router의 개수)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Q) hopcount가 낮은게 좋을까?
&lt;ul&gt;
&lt;li&gt;YES (적을 수록 빠름)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;홉(hop)은 네트워크에서 출발지와 목적지 사이에 위치한 장치를 의미함&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;홉 카운트(hop count)는 데이터가 출발지와 목적지 사이에서 통과해야 하는 홉의 개수를 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;라우팅-테이블-실습&quot;&gt;라우팅 테이블 실습&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/9.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;netstat&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;53-ip주소-mac주소-arp-rarp&quot;&gt;53. IP주소, MAC주소, ARP, RARP&lt;/h2&gt;
&lt;hr&gt;
&lt;h3 id=&quot;ip-주소&quot;&gt;IP 주소&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;논리적 주소&lt;/strong&gt;이며 컴퓨터 네트워크에서 장치들이 서로를 인식하고 통신을 하기 위해서 사용하는 특수한 번호&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;논리적? (⇒ 변한다)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;mac-주소&quot;&gt;MAC 주소&lt;/h3&gt;
&lt;p&gt;MAC 주소(Media Access Control Address)는 네트워크 인터페이스에 할당된 고유
식별자이며 보통 장치의 NIC에 할당됩니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/10.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;p&gt;48비트로 이루어져있으며 24비트의 OUI와 24비트의 UAA로 이루어져있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OUI: IEEE에서 할당한 제조사 코드&lt;/li&gt;
&lt;li&gt;UAA: 제조사에서 구별되는 코드&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;windows 명령어&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;ipconfig /all&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;mac 명령어&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ifconfig&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;ifconfig&lt;/span&gt; en0 &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt; ether&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;en&lt;/code&gt; : 네트워크 인터페이스 prefix&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;인터페이스&lt;/th&gt;
&lt;th&gt;의미&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;en0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;보통 Wi-Fi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;en1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;유선 Ethernet (또는 반대일 수도 있음)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;en2+&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;추가 네트워크 (USB 랜, 가상 어댑터 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;arp와-rarp&quot;&gt;ARP와 RARP&lt;/h3&gt;
&lt;p&gt;MAC주소는 어떻게 찾아야할까?&lt;/p&gt;
&lt;p&gt;→ ARP (프로토콜)을 통해 확인&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/11.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;arp의-과정&quot;&gt;ARP의 과정&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;IP주소에 맞는 MAC주소를 찾기 위해 해당 데이터를 ‘브로드캐스팅’을 통해 연결된 네트워크에 있는 장치한테 모두 보냄&lt;/li&gt;
&lt;li&gt;맞는 장치가 있다면 해당 장치는 보낸 장치에게 유니캐스트로 데이터를 전달하여 주소를 찾게됨&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;54-ip주소-체계-1-이진수-이해하기&quot;&gt;54. IP주소 체계 #1: 이진수 이해하기&lt;/h2&gt;
&lt;hr&gt;
&lt;h3 id=&quot;십진법-표현&quot;&gt;십진법 표현&lt;/h3&gt;
&lt;div class=&quot;math math-display&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;12&lt;/mn&gt;&lt;msub&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mn&gt;10&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;msup&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;msup&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/msup&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;msup&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;123_{10} = 1 \times 10^2 + 2 \times 10^1 +3\times 10^0&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7944em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.3011em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7278em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;×&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.9474em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.8641em;&quot;&gt;&lt;span style=&quot;top:-3.113em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7278em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;×&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.9474em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.8641em;&quot;&gt;&lt;span style=&quot;top:-3.113em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7278em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;×&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8641em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.8641em;&quot;&gt;&lt;span style=&quot;top:-3.113em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h3 id=&quot;이진법-표기&quot;&gt;이진법 표기&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;b&lt;/mi&gt;&lt;mn&gt;100101&lt;/mn&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;0\rm{b}100101&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;b&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;100101&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;10010&lt;/mn&gt;&lt;msub&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;100101_{2}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7944em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;10010&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.3011em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;10010&lt;/mn&gt;&lt;msub&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;b&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;100101_{\rm b}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7944em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;10010&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.3361em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mathrm mtight&quot;&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;55-ip주소체계-2-ipv4와-ipv6&quot;&gt;55. IP주소체계 #2: IPv4와 IPv6&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;IP주소 체계는 IPv4와 IPv6로 나누어짐&lt;/p&gt;
&lt;h3 id=&quot;ipv4-1&quot;&gt;IPv4&lt;/h3&gt;
&lt;p&gt;IPv4는 &lt;strong&gt;32비트&lt;/strong&gt;로 표현되는 주소체계이며  &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mn&gt;128&lt;/mn&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;2^{128}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8141em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.8141em;&quot;&gt;&lt;span style=&quot;top:-3.063em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;128&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;개의 주소(41억 9천만 주소)를 표현할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/12.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;ipv6-1&quot;&gt;IPv6&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/13.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;p&gt;IPv6는 &lt;strong&gt;128비트&lt;/strong&gt;로 표현되는 주소체계이며 &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mn&gt;128&lt;/mn&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;2^{128}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8141em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.8141em;&quot;&gt;&lt;span style=&quot;top:-3.063em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;128&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;개의 주소&lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mn&gt;3.4&lt;/mn&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;msup&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mn&gt;38&lt;/mn&gt;&lt;/msup&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;(3.4 * 10^{38})&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;3.4&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.0641em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.8141em;&quot;&gt;&lt;span style=&quot;top:-3.063em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;38&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;를 표현&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IPv4보다 더 넓은 주소 체계를 가짐
&lt;ul&gt;
&lt;li&gt;IPv4에서 쓰였던 NAT, 서브네팅이 필요하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;콜론(:)으로 구분함
&lt;ul&gt;
&lt;li&gt;연속되는 0(zero)는 &lt;code class=&quot;language-text&quot;&gt;:&lt;/code&gt; (콜론으로 치환가능)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;보안&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;IPv6에는 데이터통신을 암호화할 수 있는 IPSec이 내장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;q-ipv4와-ipv6-중-어떤게-더-나을까&quot;&gt;Q. IPv4와 IPv6 중 어떤게 더 나을까?&lt;/h3&gt;
&lt;p&gt;IPv6는  IPv4보다 많은 주소를 표현할 수 있다. 또 불필요한 헤더가 삭제되어서 빠르고 IPSec도 있어 보안적인 측면에서도 좋다. 보통은 IPv6를 사용하는 것이 IPv4보다 속도가 더 빠르지만 일부 사례는 그렇지 않을 수도 있다.&lt;/p&gt;
&lt;h2 id=&quot;56-ip주소체계-3-classful-ip-addressing&quot;&gt;56. IP주소체계 #3 Classful IP Addressing&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;IP주소는 인터넷 주소로 네트워크 주소, 호스트주소 즉, 두 부분으로 나뉜다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;네트워크 주소 → 호스트들을 모은 네트워크 지칭
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;호스트(Host)란?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;컴퓨터 네트워크에 연결된 컴퓨터나 기타 장치&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;classful-ip-addressing-정의&quot;&gt;Classful IP Addressing 정의&lt;/h3&gt;
&lt;p&gt;네트워크 주소를 매기고 그에 따라 네트워크의 크기를 다르게 구분하여 클래스를 할당하는 주소체계&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;구분 기준 ⇒ 서브넷마스크(Netmask)&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;th&gt;First Octet (decimal range)&lt;/th&gt;
&lt;th&gt;First Octet (binary range)&lt;/th&gt;
&lt;th&gt;IP range&lt;/th&gt;
&lt;th&gt;Subnet Mask&lt;/th&gt;
&lt;th&gt;Hosts per Network ID&lt;/th&gt;
&lt;th&gt;# of networks&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Class A&lt;/td&gt;
&lt;td&gt;0–127&lt;/td&gt;
&lt;td&gt;0XXXXXXX&lt;/td&gt;
&lt;td&gt;0.0.0.0–127.255.255.255&lt;/td&gt;
&lt;td&gt;255.0.0.0&lt;/td&gt;
&lt;td&gt;2^24 - 2&lt;/td&gt;
&lt;td&gt;2^7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class B&lt;/td&gt;
&lt;td&gt;128–191&lt;/td&gt;
&lt;td&gt;10XXXXXX&lt;/td&gt;
&lt;td&gt;128.0.0.0–191.255.255.255&lt;/td&gt;
&lt;td&gt;255.255.0.0&lt;/td&gt;
&lt;td&gt;2^16 - 2&lt;/td&gt;
&lt;td&gt;2^14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class C&lt;/td&gt;
&lt;td&gt;192–223&lt;/td&gt;
&lt;td&gt;110XXXXX&lt;/td&gt;
&lt;td&gt;192.0.0.0–223.255.255.255&lt;/td&gt;
&lt;td&gt;255.255.255.0&lt;/td&gt;
&lt;td&gt;2^8 - 2&lt;/td&gt;
&lt;td&gt;2^21&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class D&lt;/td&gt;
&lt;td&gt;224–239&lt;/td&gt;
&lt;td&gt;1110XXXX&lt;/td&gt;
&lt;td&gt;224.0.0.0–239.255.255.255&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class E&lt;/td&gt;
&lt;td&gt;240–255&lt;/td&gt;
&lt;td&gt;1111XXXX&lt;/td&gt;
&lt;td&gt;240.0.0.0–255.255.255.255&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;class-a&quot;&gt;Class A&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;한 네트워크당 16,777,214 호스트 ID(약 1600만개)&lt;/li&gt;
&lt;li&gt;0.0.0.0은 특수 주소&lt;/li&gt;
&lt;li&gt;127.x.x.x은 루프백 주소임
&lt;ul&gt;
&lt;li&gt;루프백 주소 : 자기 자신(로컬 호스트)을 가리키는 IP 주소
&lt;ul&gt;
&lt;li&gt;예) 127.0.01&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;class-b&quot;&gt;Class B&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2^16 &lt;strong&gt;– 2&lt;/strong&gt; = 한 네트워크당 65534 호스트 ID(6만 5천개)&lt;/li&gt;
&lt;li&gt;네트워크 주소 범위 : 128 ~ 191 로 시작&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;class-c&quot;&gt;Class C&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2^8 &lt;strong&gt;– 2&lt;/strong&gt; = 한 네트워크당 254 호스트 ID&lt;/li&gt;
&lt;li&gt;네트워크 주소 범위 : 192 ~ 223 로 시작&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-2를-왜하나&quot;&gt;🧐 ‘-2’를 왜하나?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;맨 앞자리는 네트워크 주소(&lt;strong&gt;n&lt;/strong&gt;.x.x.x)로 남겨두며 마지막 주소는 브로드캐스팅(x.x.x.&lt;strong&gt;255&lt;/strong&gt;) 주소&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;클래스풀의-문제점&quot;&gt;🧐 클래스풀의 문제점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;네트워크의 크기가 작은 경우 큰 네트워크를 필요로 하는 조직은 여러개를 확보해야 하는&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;어려움&lt;/p&gt;
&lt;h2 id=&quot;57-ip주소체계-4-클래스리스와-서브넷마스크-서브네팅&quot;&gt;57. IP주소체계 #4. 클래스리스와 서브넷마스크, 서브네팅&lt;/h2&gt;
&lt;hr&gt;
&lt;h3 id=&quot;기존-classful의-문제점&quot;&gt;기존 Classful의 문제점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;네트워크 크기가 작은 경우 큰 네트워크로 필요로하는 조직은 여러 개 확보 필요
&lt;ul&gt;
&lt;li&gt;또, 남는 네트워크가 생김&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-classless-등장&quot;&gt;⇒ Classless 등장&lt;/h3&gt;
&lt;p&gt;서브넷마스크를 중심으로 어디까지가 네트워크 주소고 어디까지가 호스트주소인지를 나눔&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;서브네팅 : 네트워크를 나눈다는 의미&lt;/li&gt;
&lt;li&gt;서브넷 : 서브네트워크, 쪼개진 네트워크&lt;/li&gt;
&lt;li&gt;서브넷마스크 : 서브네트워크를 위한 비트마스크&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;58-ip주소-체계-5-public-ip-와-private-ip&quot;&gt;58. IP주소 체계 #5 Public IP 와 Private IP&lt;/h1&gt;
&lt;hr&gt;
&lt;p&gt;IP주소의 부족을 해결하기 위해 Public IP와 Private IP로 나누고 중간에 NAT라는 기술을 통해 해결한다.&lt;/p&gt;
&lt;h2 id=&quot;nat&quot;&gt;NAT&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview-2/19.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;NAT(Network Address Translation)은 패킷이 트래픽 라우팅 장치를 통해 전송되는 동안 패킷의 IP 주소를 변경, IP주소를 다른 IP주소로 매핑하는 방법
&lt;ul&gt;
&lt;li&gt;NAT를 통해 내부 네트워크 IP가 노출되지 않는다는 점 (장점)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[1주차 - CS 스터디]]></title><description><![CDATA[1. 디자인 패턴이란? 디자인 패턴은 소프트웨어 설계 과정에서 반복적으로 발생하는 문제를 해결하기 위해 정리된 설계 규약이다. 객체 간 관계와 역할을 구조화함으로써 코드의 재사용성과 유지보수성을 높일 수 있다. 디자인 패턴의 종류 디자인 패턴은 크게 생성패턴, 구조패턴, 행동패턴 3가지]]></description><link>https://woojin-devv.github.io/posts/cs-interview-study-1/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/cs-interview-study-1/</guid><pubDate>Tue, 24 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;1-디자인-패턴이란&quot;&gt;1. 디자인 패턴이란?&lt;/h1&gt;
&lt;p&gt;디자인 패턴은 소프트웨어 설계 과정에서 반복적으로 발생하는 문제를 해결하기 위해 정리된 설계 규약이다. 객체 간 관계와 역할을 구조화함으로써 코드의 재사용성과 유지보수성을 높일 수 있다.&lt;/p&gt;
&lt;h2 id=&quot;디자인-패턴의-종류&quot;&gt;디자인 패턴의 종류&lt;/h2&gt;
&lt;p&gt;디자인 패턴은 크게 &lt;strong&gt;생성패턴, 구조패턴, 행동패턴&lt;/strong&gt; 3가지로 나누어짐&lt;/p&gt;
&lt;h3 id=&quot;1-생성-패턴&quot;&gt;1) 생성 패턴&lt;/h3&gt;
&lt;p&gt;생성패턴은 객체 생성 방법이 들어간 디자인 패턴&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;싱글톤&lt;/strong&gt;, 팩토리, 추상팩토리, 빌더, 프로토타입 패턴이 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2-구조-패턴&quot;&gt;2) 구조 패턴&lt;/h3&gt;
&lt;p&gt;객체, 클래스 등으로 큰 구조를 만들 때 유용한.&lt;/p&gt;
&lt;h3 id=&quot;3-행동-패턴&quot;&gt;3) 행동 패턴&lt;/h3&gt;
&lt;p&gt;객체나 클래스 간의 알고리즘, 책임 할당에 관한 디자인 패턴&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;eterator, observer, strategy..&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;22-라이브러리와-프레임워크의-차이&quot;&gt;22. 라이브러리와 프레임워크의 차이&lt;/h1&gt;
&lt;h2 id=&quot;221-라이브러리&quot;&gt;22.1 라이브러리&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;공통으로 사용될 수 있는 특정한 기능들을 모듈화한 것이며 폴더명, 파일명 등에 대한 규칙이 없고 프레임워크에 비해 자유롭다.&lt;/p&gt;
&lt;p&gt;예) axios&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;222-프레임워크&quot;&gt;22.2 프레임워크&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;공통으로 사용될 수 있는 특정한 기능들을 모듈화한 것을 말한다. 폴더명, 파일명 등에 대한 규칙이 있으며 라이브러리에 비해 좀 더 엄격한 특징을 지닌다.&lt;/p&gt;
&lt;p&gt;예) vue.js , Django&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;23-싱글톤-패턴&quot;&gt;23. 싱글톤 패턴&lt;/h1&gt;
&lt;h3 id=&quot;싱글톤-패턴singleton-pattern이란&quot;&gt;싱글톤 패턴(Singleton pattern)이란?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;하나의 클래스의 오직 하나의 인스턴스&lt;/strong&gt;만 가지는 패턴&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;하나의 클래스를 기반으로 여러 개의 개별적인 인스턴스를 만들 수 있지만 그렇게 하지 않고, 하나의 클래스를 기반으로 하나의 인스턴스를 만들어 이를 기반으로 로직을 만드는데 쓰이며 보통 &lt;strong&gt;데이터베이스 연결 모듈에 많이 사용됨&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;왜-사용하는-걸까요&quot;&gt;왜 사용하는 걸까요?&lt;/h3&gt;
&lt;p&gt;보통 클래스를 만들면 필요할 때마다 &lt;code class=&quot;language-text&quot;&gt;new&lt;/code&gt; 연산자로 인스턴스를 여러 개 만들 수 있다. 하지만, 자원관리, 상태 공유 등의 상황에서는 인스턴스가 여러 개면 오히려 문제가 발생할 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;자원관리&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;데이터베이스 연결 객체(Connection Pool)&lt;/li&gt;
&lt;li&gt;로그 기록 객체 (Logger)등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;상태 공유&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;설정 정보(Config) 처럼 프로그램 전체에서 동일한 데이터를 참조해야할 때 유용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;싱글톤-패턴의-특징&quot;&gt;싱글톤 패턴의 특징&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;private 생성자 : 클래스 외부에서 &lt;code class=&quot;language-text&quot;&gt;new&lt;/code&gt; 를 통해 인스턴스를 생성하지 못하도록 막는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;장점&quot;&gt;장점&lt;/h3&gt;
&lt;p&gt;하나의 인스턴스를 기반으로 해당 인스턴스를 다른 모듈들이 공유하여 사용하기 때문에 인스턴스를 생성할 때 드는 비용이 줄어듦&lt;/p&gt;
&lt;h3 id=&quot;단점&quot;&gt;단점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;의존성이 높아짐&lt;/li&gt;
&lt;li&gt;TDD(Test Driven Development)를 할 때 걸림돌이 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;멀티스레드-환경에서-동시성-문제-방지&quot;&gt;멀티스레드 환경에서 동시성 문제 방지&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;synchronized나 double-checked locking등을 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;코드-예시-js&quot;&gt;코드 예시 (JS)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Singleton&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;Singleton&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;instance&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            Singleton&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;instance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Singleton&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;instance
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt; 
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Singleton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Singleton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// true &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;2425-싱글톤-패턴을-구현하는-7가지-방법-12&quot;&gt;24–25. 싱글톤 패턴을 구현하는 7가지 방법 #1,2&lt;/h1&gt;
&lt;h2 id=&quot;1-단순한-메서드-호출&quot;&gt;1. 단순한 메서드 호출&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;싱글톤 패턴 생성 여부 확인
&lt;ul&gt;
&lt;li&gt;싱글톤이 없으면 → 새로 생성&lt;/li&gt;
&lt;li&gt;새로 만들고 있다면 → 인스턴스 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Singleton&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Singleton&lt;/span&gt; instance&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Singleton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Singleton&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;instance &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;  
            instance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Singleton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; instance&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;해당-코드의-문제점&quot;&gt;해당 코드의 문제점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;원자성 결여&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;2-synchronized&quot;&gt;2. synchronized&lt;/h2&gt;
&lt;h2 id=&quot;3-정적-멤버즉시-초기화-eager-initialization&quot;&gt;3. 정적 멤버(즉시 초기화, Eager Initialization)&lt;/h2&gt;
&lt;h2 id=&quot;4-정적-블록&quot;&gt;4. 정적 블록&lt;/h2&gt;
&lt;h2 id=&quot;5-정적-멤버와-lazy-holder중첩-클래스&quot;&gt;5. 정적 멤버와 Lazy Holder(중첩 클래스)&lt;/h2&gt;
&lt;h2 id=&quot;6-이중-확인-잠금dcl&quot;&gt;6. 이중 확인 잠금(DCL)&lt;/h2&gt;
&lt;h2 id=&quot;7-enum&quot;&gt;7. Enum&lt;/h2&gt;
&lt;h1 id=&quot;26-팩토리-패턴&quot;&gt;26. 팩토리 패턴&lt;/h1&gt;
&lt;h3 id=&quot;팩토리-패턴이란&quot;&gt;팩토리 패턴이란?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;상속 관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결정하고, 하위 클래스에서 객체 생성에 관한 구체적인 내용을 결정하는 패턴&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;상위 클래스에서는 객체 생성방식에 대해 알 필요가 없어져 &lt;strong&gt;유연성을 갖게 되며&lt;/strong&gt; 객체 생성
로직은 하위클래스에서만 관리 되기 때문에 유지보수성이 증가&lt;/p&gt;
&lt;h1 id=&quot;27-이터레이터iterator-패턴&quot;&gt;27. 이터레이터(iterator) 패턴&lt;/h1&gt;
&lt;h3 id=&quot;이터레이터-패턴이란&quot;&gt;이터레이터 패턴이란?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;이터레이터(iterator)를 사용하여 &lt;strong&gt;컨테이너&lt;/strong&gt;의 요소에 접근하는 디자인 패턴이다. 각기 다른 자료구조들을 똑같은 인터페이스로 순회를 쉽게할 수 있다는 장점이 있다.&lt;/p&gt;
&lt;p&gt;*컨테이너란 동일한 요소들을 담아놓는 집합을 말한다. &lt;strong&gt;배열과 맵&lt;/strong&gt;이 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;28-di와-dip&quot;&gt;28. DI와 DIP&lt;/h1&gt;
&lt;h2 id=&quot;의존성-주입di과-의존-관계역전원칙dip&quot;&gt;의존성 주입(DI)과 의존 관계역전원칙(DIP)&lt;/h2&gt;
&lt;h3 id=&quot;의존성-주입dependency-injection이란&quot;&gt;의존성 주입(Dependency Injection)이란?&lt;/h3&gt;
&lt;p&gt;메인 모듈(main module)이 ‘직접’ 다른 하위 모듈에 대한 의존성을 주기보다 중간에 &lt;em&gt;&lt;strong&gt;의존성 주입자(dependency injector)가 이 부분을 가로채 메인 모듈이 ‘간접’적으로 의존성을 주입하는 방식.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;의존-관계역전원칙dip이란&quot;&gt;의존 관계역전원칙(DIP)이란?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;DIP; Dependency Inversion Principle&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;자신보다 변하기 쉬운 것에 의존하던 것을 추상화된 인터페이스나 상위 클래스를 두어 변하기 쉬운 것의 변화에 영향받지 않게 하는 원칙을 말합니다.&lt;/p&gt;
&lt;p&gt;이는 2가지의 규칙을 지키는 상태를 의미함.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;상위 모듈은 하위 모듈에 의존해서는 안됨&lt;/li&gt;
&lt;li&gt;추상화는 세부사항에 의존해서는 안됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;의존성-주입의-장점&quot;&gt;의존성 주입의 장점&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;외부에서 모듈을 생성하여 모듈을 쉽게 교체할 수 있는 구조가 됨.&lt;/li&gt;
&lt;li&gt;단위 테스팅과 마이그레이션이 쉬워짐&lt;/li&gt;
&lt;li&gt;애플리케이션 의존성 방향이 좀 더 일관되어 코드를 추론하기 쉬워짐&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;의존성-주입의-단점&quot;&gt;의존성 주입의 단점&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;결국에는 모듈이 더 생기게 되므로 &lt;strong&gt;복잡도가 증가&lt;/strong&gt;하게 됨&lt;/li&gt;
&lt;li&gt;종속성 주입 자체가 컴파일을 할 때가 아닌 &lt;strong&gt;런타임 시에 일어나기 때문에&lt;/strong&gt; 컴파일할 때 종속성 주입에 관한 에러를 잡기가 어려워짐&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&quot;29-전략-패턴&quot;&gt;29. 전략 패턴&lt;/h1&gt;
&lt;h3 id=&quot;전략패턴이란&quot;&gt;전략패턴이란?&lt;/h3&gt;
&lt;p&gt;전략(Strategy)라고 부르는 ‘캡슐화한 알고리즘’을 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 디자인 패턴이다.&lt;/p&gt;
&lt;h1 id=&quot;30-옵저버-패턴&quot;&gt;30. 옵저버 패턴&lt;/h1&gt;
&lt;h3 id=&quot;옵저버-패턴이란&quot;&gt;옵저버 패턴이란?&lt;/h3&gt;
&lt;p&gt;주체가 어떤 객체(subject)의 상태 변화를 관찰하다가 상태 변화가 있을 때마다 메서드 등을 통해 옵서버 목록에 있는 옵저버들에게 변화를 알려주는 디자인 패턴이다.&lt;/p&gt;
&lt;h1 id=&quot;31-proxy-패턴&quot;&gt;31. Proxy 패턴&lt;/h1&gt;
&lt;h3 id=&quot;프록시패턴이란&quot;&gt;프록시패턴이란?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;객체가 어떤 대상 객체에 접근하기 전, 그 접근에 대한 흐름을 가로채서 해당 접근을 필더링하거나 수정하는 등의 역할을 하는 계층이 있는 디자인 패턴이다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview/proxy.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;프록시-서버-예시&quot;&gt;프록시 서버 예시&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cloud Flare&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;32-mvc--mvp--mvvm-패턴&quot;&gt;32. MVC / MVP / MVVM 패턴&lt;/h1&gt;
&lt;h2 id=&quot;1-mvc-패턴&quot;&gt;1) MVC 패턴&lt;/h2&gt;
&lt;p&gt;MVC패턴은 Model, View, Controller로 이루어진 디자인 패턴&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview/mvc.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;모델model&quot;&gt;모델(Model)&lt;/h3&gt;
&lt;p&gt;모델은 애플리케이션의 데이터인 데이터베이스, 상수, 변수등을 의미&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;뷰에서 데이터를 생성하거나 수정할 때 컨트롤러를 통해 모델이 생성 또는 업데이트 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;뷰view&quot;&gt;뷰(View)&lt;/h3&gt;
&lt;p&gt;뷰(view)는 inputbox, checkbox, textarea등 사용자 인터페이스 요소를 나타내며 모델을 기반으로 사용자가 볼 수 있는 화면을 뜻함.&lt;/p&gt;
&lt;h3 id=&quot;컨트롤러controller&quot;&gt;컨트롤러(Controller)&lt;/h3&gt;
&lt;p&gt;컨트롤러(Controller)는 하나 이상의 모델과 하나 이상의 뷰를 잇는 다리역할을 하며 이벤트등 메인 로직을 담당함.&lt;/p&gt;
&lt;h3 id=&quot;mvc-패턴의-장점&quot;&gt;MVC 패턴의 장점&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;애플리케이션의 구성 요소를 세 가지 역할로 구분하여 개발 프로세스에서 각각의 구성요소에만 집중해서 개발할 수 있음&lt;/li&gt;
&lt;li&gt;재사용성과 확장성이 용이하다는 장점&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;mvc-패턴의-단점&quot;&gt;MVC 패턴의 단점&lt;/h3&gt;
&lt;p&gt;애플리케이션이 복잡해질수록 모델과 뷰의 관계가 복잡해지는 단점 존재&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;폭포수 효과&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;MVC패턴은 규모가 커질 수록 &lt;strong&gt;Model과 View가 서로를 복잡하게 참조하는 양방향 데이터 흐름을 갖게됨.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;예시) 페이스북의 Markseen&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;2-mvp-패턴&quot;&gt;2) MVP 패턴&lt;/h2&gt;
&lt;h2 id=&quot;3-mvvm-패턴&quot;&gt;3) MVVM 패턴&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;대표적인 프레임워크 뷰(Vue.js)&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;33-flux-패턴&quot;&gt;33. Flux 패턴&lt;/h1&gt;
&lt;p&gt;단방향을 가지기 때문에 일관성이 증가함.&lt;/p&gt;
&lt;p&gt;일관성이 증가하기 때문에 테스팅이 쉬워짐&lt;/p&gt;
&lt;h3 id=&quot;flux의-4가지-핵심-요소&quot;&gt;Flux의 4가지 핵심 요소&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Action
&lt;ul&gt;
&lt;li&gt;무엇이 일어날지 정의하는 객체&lt;/li&gt;
&lt;li&gt;사용자의 이벤트 처리
&lt;ul&gt;
&lt;li&gt;마우스 클릭, 스크롤 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dispatcher
&lt;ul&gt;
&lt;li&gt;어떤 action을 관리하는 객체&lt;/li&gt;
&lt;li&gt;모든 action을 받아서 Store에 저장하는 중앙 통제실&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Store
&lt;ul&gt;
&lt;li&gt;애플리케이션의 상태와 이를 변경하는 로직을 담고 있음&lt;/li&gt;
&lt;li&gt;Dispatcher를 통해서만 상태 변경이 가능함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;View
&lt;ul&gt;
&lt;li&gt;Store에서 데이터를 가져와 화면에 렌더링하고, 사용자 입력이 들어오면 새로운 Action을 생성함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;flux-패턴이-적용된-redux&quot;&gt;Flux 패턴이 적용된 Redux&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cs-interview/flux.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[알고리즘] 구간합 / 누적합]]></title><description><![CDATA[1. 1차원 구간합 1) 합 배열 정의 $$ S[i] = A[0] + A[1] + ... + A[i 1] + A[i] $$ 2) 합 배열 구하기 $$ S[i] = S[i 1] + A[i] $$ 3) 구간합 구하기 예: i j 까지의 구간합? $$ S[j] S[i 1] $$ 백준 1165]]></description><link>https://woojin-devv.github.io/posts/prefix-sum/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/prefix-sum/</guid><pubDate>Mon, 09 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;1-1차원-구간합&quot;&gt;1. 1차원 구간합&lt;/h1&gt;
&lt;h2 id=&quot;1-합-배열-정의&quot;&gt;1) 합 배열 정의&lt;/h2&gt;
&lt;div class=&quot;math math-display&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;S&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;S[i] = A[0] + A[1] + ... + A[i-1] + A[i]&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05764em;&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2 id=&quot;2-합-배열-구하기&quot;&gt;2) 합 배열 구하기&lt;/h2&gt;
&lt;div class=&quot;math math-display&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;S&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;S&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;S[i] = S[i-1] + A[i]&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05764em;&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05764em;&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2 id=&quot;3-구간합-구하기&quot;&gt;3) 구간합 구하기&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;예: i ~ j 까지의 구간합?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;math math-display&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;S&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mi&gt;j&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;S&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;[&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo stretchy=&quot;false&quot;&gt;]&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;S[j] - S[i-1]&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05764em;&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05724em;&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05764em;&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2 id=&quot;백준-11659--구간합-구하기-4&quot;&gt;백준 11659 – 구간합 구하기 4&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;수 N개가 주어졌을 때, i번째 수부터 j번째 수까지 합을 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; sys
&lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sys&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;stdin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;readline

n&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; m &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
arr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
arr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;insert&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 구간합 배열&lt;/span&gt;
prefix_s &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
prefix_s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; prefix_s&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    prefix_s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;m&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; j &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; prefix_s&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; prefix_s&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h1 id=&quot;2-2차원-구간합&quot;&gt;2. 2차원 구간합&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/prefix_sum.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;백준-2167-2차원-배열의-합&quot;&gt;백준 2167 – 2차원 배열의 합&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;n&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; m &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

arr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;m&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 0번째 행 추가&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    row &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    arr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;row&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# prefix_sum 초기화 &lt;/span&gt;
prefix_sum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;m&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# prefix_sum[1][1] 시작 추가&lt;/span&gt;
prefix_sum&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# prefix_sum 순회하면서 각각의 값 채워넣기 &lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; j &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; m&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; j &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            prefix_sum&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; prefix_sum&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; j &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            prefix_sum&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; prefix_sum&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            prefix_sum&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; prefix_sum&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; prefix_sum&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; prefix_sum&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

k &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;k&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; j&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;split&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; prefix_sum&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; prefix_sum&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; prefix_sum&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; prefix_sum&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[React] props와 state의 차이]]></title><description><![CDATA[props vs state props와 state의 정확한 차이는 무엇인가요? Context 컴포넌트의 주요 책임은 원시 데이터(raw data)를 풍부한 HTML로 변환하는 것이다. 해당 관점에서 보면 props와 state는 HTML출력이 생성되는 원시데이터를 구성한다. 즉, pro]]></description><link>https://woojin-devv.github.io/posts/React-props-state/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/React-props-state/</guid><pubDate>Sun, 08 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;props-vs-state&quot;&gt;props vs state&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;props와 state의 정확한 차이는 무엇인가요?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;context&quot;&gt;Context&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;컴포넌트의 주요 책임은 원시 데이터(raw data)를 풍부한 HTML로 변환하는 것이다. 해당 관점에서 보면 props와 state는 HTML출력이 생성되는 원시데이터를 구성한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;즉, props와 state는 컴포넌트의 render()함수에 들어가는 입력 데이터다. 따라서 각 데이터가 무엇을 의미하는지 그리고 어디에서 오는지 자세히 살펴봐야 한다.
또한 우리는 React Cosmos를 사용하고 있는데, 해당 환경에서 props는 초기 state를 포함할 수 있기 때문에 해당 개념을 이해하는 것이 중요하다.&lt;/p&gt;
&lt;h2 id=&quot;-공통점&quot;&gt;💬 공통점&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;props와 state는 모두 일반적인 JavaScript 객체&lt;/li&gt;
&lt;li&gt;props와 state는 변경되면 컴포넌트는 다시 렌더링 됨.&lt;/li&gt;
&lt;li&gt;props와 state는 결정적임.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;-예시를-고려해보자&quot;&gt;🧐 예시를 고려해보자.&lt;/h2&gt;
&lt;h3 id=&quot;q-어떤-컴포넌트가-시간이-지나면서-자신의-속성을-변경해야-한다면-props-state-어디에&quot;&gt;Q) 어떤 컴포넌트가 시간이 지나면서 자신의 속성을 변경해야 한다면? props? state? 어디에?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;어떤 컴포넌트가 시간이 지나면서 자신의 속성을 변경해야한다면 state에 있어야함.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;props&quot;&gt;props&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;props는 properties의 줄임말이다.
&lt;ul&gt;
&lt;li&gt;props는 컴포넌트의 설정이라고 볼 수 있다.&lt;/li&gt;
&lt;li&gt;즉, 컴포넌트에 전달되는 옵션이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;state&quot;&gt;state&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;state는 컴포넌트가 마운트될 때 기본값으로 시작한다.
&lt;ul&gt;
&lt;li&gt;그리고 시간이 지나면서 값이 변경될 수 있음&lt;/li&gt;
&lt;li&gt;해당 변화(변경)는 사용자 이벤트로 인해 발생함&lt;/li&gt;
&lt;li&gt;state는 특정 시점의 상태를 나타내는 스냅샷이라고 볼 수 있음&lt;/li&gt;
&lt;li&gt;컴포넌트는 자신의 state를 내부적으로 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;props와-state-변경-가능-여부&quot;&gt;props와 state 변경 가능 여부&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;props&lt;/th&gt;
&lt;th&gt;state&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;부모 컴포넌트로부터 초기값 받을 수 있는가&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;부모 컴포넌트가 값을 변경할 수 있는가&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;컴포넌트 내부에서 기본값 설정 가능&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;컴포넌트 내부에서 변경 가능&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;자식 컴포넌트 초기값 설정 가능&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;자식 컴포넌트에서 변경 가능&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;그렇다면-state는-다다익선인가&quot;&gt;그렇다면 State는 다다익선인가?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;state는 선택사항이다.
&lt;ul&gt;
&lt;li&gt;결국 상태의 변화는 컴포넌트의 복잡도를 증가시키고 예측 가능성을 낮출 수 있기 때문에 가능하면 state가 없는 정적 컴포넌트가 낫긴 하다.&lt;/li&gt;
&lt;li&gt;물론 인터랙티브한 애플리케이션에서는 state 없이 구현한다는 것은 말이 안된다.&lt;/li&gt;
&lt;li&gt;하지만 stateful한 컴포넌트를 너무 많이 만드는 것은 피하는 것이 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;레퍼런스&quot;&gt;레퍼런스&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/uberVU/react-guide/blob/master/props-vs-state.md&quot;&gt;github – uberVU/react-guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ko.legacy.reactjs.org/docs/faq-state.html&quot;&gt;React공식문서 - 컴포넌트 State&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[SOP, CORS, CSRF란 무엇인가?]]></title><description><![CDATA[CORS란? Cross Origin Resource Sharing의 약자, 교차 출처 리소스 공유는 웹 브라우저가 보안상 다른 도메인으로의 API 요청을 제한하는 정책(SOP)을 예외적으로 허용해주는 HTTP 기반 메커니즘 입니다. 🧐 정확히 풀어서 설명하자면.. 브라우저는 보안을 위해]]></description><link>https://woojin-devv.github.io/posts/CORS/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/CORS/</guid><pubDate>Sat, 07 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;cors란&quot;&gt;CORS란?&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://static.tosspayments.com/docs/glossary/cors-url.png&quot; alt=&quot;이미지 설명&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Cross-Origin Resource Sharing의 약자, 교차 출처 리소스 공유는 웹 브라우저가 보안상 다른 도메인으로의 API 요청을 제한하는 정책(SOP)을 예외적으로 허용해주는 HTTP 기반 메커니즘 입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;-정확히-풀어서-설명하자면&quot;&gt;🧐 정확히 풀어서 설명하자면..&lt;/h2&gt;
&lt;p&gt;브라우저는 보안을 위해 현재 페이지의 출처(origin)와 다른 출처의 리소스에 접근하지 못하도록 제한하는 정책을 가지고 있다. 이를 동일 출처 정책(Same-Origin Policy, SOP)이라고 함.&lt;/p&gt;
&lt;p&gt;하지만, 현대 웹사이트는 내 서버 뿐만 아니라 네이버 지도 API, 구글 폰트, 공공데이터 등의 남의 서버에서 데이터를 가져와야할 일이 많음.&lt;/p&gt;
&lt;p&gt;외부 API아니더라도 당장 개인 프젝을 할 때에도 프론트엔드단과 서버단의 출처가 다른 경우가 존재함&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;그렇다면, 이 사이트는 안전하니까 데이터를 주고 받을 수 있게 해줄게 라고 서버가 허락해주는 규칙이 CORS (교차 출처 리소스 공유)인 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;-왜-이렇게-복잡하게-해놨을까&quot;&gt;😩 왜 이렇게 복잡하게 해놨을까?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;만약 이런 제한이 없었다면,,
&lt;ul&gt;
&lt;li&gt;브라우저에 쿠키가 남아있을 때, CSRF 혹은 세션 하이재킹에 대한 위험이 존재함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;origin출처은-무엇인가&quot;&gt;Origin(출처)은 무엇인가?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;브라우저가 **&apos;서로 다른 출처&apos;**라고 판단하는 기준은 세 가지이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Protocol (http vs https)&lt;/li&gt;
&lt;li&gt;Host (example.come vs api.exmaple.com)&lt;/li&gt;
&lt;li&gt;Port (80 vs 8080)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;발생원인&quot;&gt;발생원인&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;웹사이트 (예: A 도메인)에서 다른 API 서버 (B 도메인)로 리소스를 요청할 때 브라우저가 보안상 기본적으로 차단하여 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;작동-방식&quot;&gt;작동 방식&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;브라우저는 서버에 Preflight를 보내 허용된 출처인지 확인하고, 서버가 헤더를 통해 허용하면 데이터 교환이 가능함.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;해결-방법&quot;&gt;해결 방법&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;서버 측에서 응답 헤더(Access-Control-Allow-Origin)를 설정하거나, 프록시 서버를 사용하여 도메인을 맞추는 방식을 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;주의&quot;&gt;주의&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CORS&lt;/strong&gt;는 브라우저 보안 정책일 뿐, 서버 기능이 아니다.
&lt;ul&gt;
&lt;li&gt;따라서, Postman에서는 잘 되는데, 브라우저에서 막히는 이유 또한 위와 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;레퍼런스&quot;&gt;레퍼런스&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.tosspayments.com/resources/glossary/cors&quot;&gt;토스 페이먼츠 - CORS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/HTTP/Guides/CORS&quot;&gt;MDN 교차 출처 리소스 공유 (CORS)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[맥북에 Claude Code 설치]]></title><link>https://woojin-devv.github.io/posts/Claud-code/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Claud-code/</guid><pubDate>Sat, 07 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/assets/img/installation/claude-01.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://claude.ai/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[HTTP?]]></title><description><![CDATA[HTTP? 하이퍼텍스트 전송 프로토콜(HTTP)은 HTML과 같은 하이퍼미디어 문서를 전송하기 위한 애플리케이션 계층 프로토콜이다. 웹 브라우저와 웹 서버간의 통신을 위해 설계되었지만 다른 목적으로도 사용할 수 있다. HTTP는 무상태 프로토콜이고, 서버가 두 요청 간에 어떠한 데이터도]]></description><link>https://woojin-devv.github.io/posts/HTTP/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/HTTP/</guid><pubDate>Fri, 06 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;http&quot;&gt;HTTP?&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;하이퍼텍스트 전송 프로토콜(HTTP)은 HTML과 같은 하이퍼미디어 문서를 전송하기 위한 애플리케이션 계층 프로토콜이다. 웹 브라우저와 웹 서버간의 통신을 위해 설계되었지만 다른 목적으로도 사용할 수 있다. HTTP는 무상태 프로토콜이고, 서버가 두 요청 간에 어떠한 데이터도 유지하지 않는다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://mdn.github.io/shared-assets/images/diagrams/http/overview/http-layers.svg&quot; alt=&quot;OSI 7 Layers&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;http를-왜-알아야할까&quot;&gt;HTTP를 왜 알아야할까?&lt;/h2&gt;
&lt;p&gt;현재 개발에서 API를 받아올 때 대부분 HTTP로 받아오기 때문.
물론 시스템 개발자도 일정 부분 당연히 알아둬야하겠지만..서도&lt;/p&gt;
&lt;h2 id=&quot;-http로-제어-가능한-것&quot;&gt;🧐 HTTP로 제어 가능한 것?&lt;/h2&gt;
&lt;h2 id=&quot;레퍼런스&quot;&gt;레퍼런스&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/HTTP/Guides/Overview&quot;&gt;HTTP 개요&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[법정동 기준 상권 데이터 수집 구현기 (Kakao Local API)]]></title><link>https://woojin-devv.github.io/posts/encoding/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/encoding/</guid><pubDate>Tue, 03 Feb 2026 00:00:00 GMT</pubDate><content:encoded></content:encoded></item><item><title><![CDATA[법정동 기준 상권 데이터 수집 구현기 (Kakao Local API)]]></title><description><![CDATA[일단, 수집하고자하는 데이터는 다음과 같다. 법정동 코드 (한 구역에) CATEGORIES에 포함된 편의시설의 개수이다. Table Header & 예시 법정동코드 category group code count 1111010100 CS2 2 1111010100 MT1 0 1. Kakao]]></description><link>https://woojin-devv.github.io/posts/kakao-map-api/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/kakao-map-api/</guid><pubDate>Tue, 03 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;일단, 수집하고자하는 데이터는 다음과 같다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;법정동 코드 (한 구역에) CATEGORIES에 포함된 편의시설의 개수이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;CATEGORIES &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;CS2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;편의점&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;MT1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;대형마트&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;PK6&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;주차장&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;BK9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;은행&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;FD6&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;음식점&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;CE7&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;카페&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;HP8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;병원&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;PM9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;약국&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Table Header &amp;#x26; 예시&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;법정동코드&lt;/th&gt;
&lt;th&gt;category_group_code&lt;/th&gt;
&lt;th&gt;count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1111010100&lt;/td&gt;
&lt;td&gt;CS2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1111010100&lt;/td&gt;
&lt;td&gt;MT1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id=&quot;1-kakao-api-key-발급&quot;&gt;1. Kakao api key 발급&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Kakao map api를 활용할 예정이기 때문에, 앱을 등록하고 kakao api key를 발급하도록 한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/woojin-devv/woojin-devv.github.io/blob/master/assets/img/etc/kakao-map-01.png?raw=true&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/woojin-devv/woojin-devv.github.io/blob/master/assets/img/etc/kakao-map-02.png?raw=true&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이미지 중 &lt;strong&gt;C. 호출 허용 IP 주소&lt;/strong&gt;에 내 Public ip 주소를 입력해야 한다.&lt;/li&gt;
&lt;li&gt;가장 간단한 방법은,
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;네이버&lt;/strong&gt; &gt; “내 아이피 주소 확인”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/woojin-devv/woojin-devv.github.io/blob/master/assets/img/etc/kakao-map-03.png?raw=true&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;- Private ip를 입력하지 않도록 주의하자.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;11-notauthorizederror-에러&quot;&gt;1.1 NotAuthorizedError 에러&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;초반에 앱에 플랫폼 REST API 키로 사용하다가 다음과 같은 인증 에러를 마주했다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;{&apos;errorType&apos;: &apos;NotAuthorizedError&apos;, &apos;message&apos;: &apos;App(QuadS) disabled OPEN_MAP_AND_LOCAL service.&apos;}
수집된 장소 수: 0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;11-에러-해결&quot;&gt;1.1 에러 해결&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/woojin-devv/woojin-devv.github.io/blob/master/assets/img/etc/kakao-map-04.png?raw=true&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.kakao.com/console/app&quot;&gt;앱&lt;/a&gt; &gt; 제품 설정 &gt; 카카오맵 에서 사용 설정을 ON 해주면 해결 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;2-구성&quot;&gt;2. 구성&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;전체 구성은 다음과 같다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;설정 및 공통 상수 정의&lt;/li&gt;
&lt;li&gt;좌표 기반 행정구역정보 변환 함수&lt;/li&gt;
&lt;li&gt;좌표 to 법정동 코드 함수&lt;/li&gt;
&lt;li&gt;카테고리기반 장소 수집 함수&lt;/li&gt;
&lt;li&gt;동 주소 기반 좌표 변환 함수&lt;/li&gt;
&lt;li&gt;실행&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;1-설정-및-공통-상수-정의&quot;&gt;1. 설정 및 공통 상수 정의&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; pandas &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; pd
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; requests
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; time
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; dotenv &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; load_dotenv

load_dotenv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

KAKAO_REST_API_KEY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;getenv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;KAKAO_REST_API_KEY&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

HEADERS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;Authorization&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;KakaoAK &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;KAKAO_REST_API_KEY&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

ADDRESS_URL &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://dapi.kakao.com/v2/local/search/address.json&quot;&lt;/span&gt;
CATEGORY_URL &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://dapi.kakao.com/v2/local/search/category.json&quot;&lt;/span&gt;
COORD2REGION_URL &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://dapi.kakao.com/v2/local/geo/coord2regioncode.json&quot;&lt;/span&gt;

CATEGORIES &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;CS2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;편의점&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;MT1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;대형마트&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;PK6&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;주차장&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;BK9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;은행&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;FD6&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;음식점&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;CE7&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;카페&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;HP8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;병원&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;PM9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;약국&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

OUTPUT_PATH &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;../output/seoul_legal_dong_category_count.csv&quot;&lt;/span&gt;
RADIUS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;800&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;KAKAO_REST_API_KEY&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-좌표-기반-행정구역정보-변환-함수&quot;&gt;2. 좌표 기반 행정구역정보 변환 함수&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://developers.kakao.com/docs/latest/ko/local/dev-guide&quot;&gt;Kakao developers | 문서 &gt; 로컬 &gt; REST API &gt; 좌표로 행정구역정보 변환&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;좌표계에 대한 좌표값을 받아 해당 좌표에 부합하는 &lt;strong&gt;행정동, 법정동&lt;/strong&gt;을 얻는 API
&lt;ul&gt;
&lt;li&gt;행정동 (region_type == &quot;H&quot;)&lt;/li&gt;
&lt;li&gt;법정동 (region_type == &quot;B&quot;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;coord_to_bcode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sleep&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        COORD2REGION_URL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;HEADERS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        params&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;input_coord&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WGS84&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status_code &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; doc &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;documents&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;region_type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;B&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;code&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-좌표-to-법정동-코드-함수&quot;&gt;3. 좌표 to 법정동 코드 함수&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;coord_to_bcode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sleep&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        COORD2REGION_URL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;HEADERS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        params&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;input_coord&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WGS84&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status_code &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; doc &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;documents&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;region_type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;B&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;code&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-카테고리-별-장소-수집&quot;&gt;4. 카테고리 별 장소 수집&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch_places&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;category&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    rows &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            CATEGORY_URL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;HEADERS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            params&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;category_group_code&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; category&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;radius&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;page&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;size&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        rows&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;extend&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;documents&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;meta&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;is_end&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;

        page &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; rows&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;5-동-주소----좌표-변환&quot;&gt;5. 동 주소 -&gt;  좌표 변환&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dong_to_coord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;address&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sleep&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        ADDRESS_URL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;HEADERS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        params&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;query&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; address&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status_code &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;

    docs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;documents&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; docs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;

    time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;docs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;docs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;6-실행&quot;&gt;6. 실행&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;법정동별 카테고리 시설 수 계산 &amp;#x26; 즉시 저장&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;커널이 종료 되더라도 이어서 실행할 수 있도록 분기 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;python&quot;&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;dong_df &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pd&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;read_csv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;../raw/legal_dong.csv&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

seoul_dong_df &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dong_df&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dong_df&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;시도명&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;서울특별시&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dong_df&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;시군구명&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;notna&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dong_df&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;읍면동명&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;notna&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dong_df&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;읍면동명&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;copy&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

done_bcodes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exists&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OUTPUT_PATH&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;getsize&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OUTPUT_PATH&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    done_df &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pd&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;read_csv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OUTPUT_PATH&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    done_bcodes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;done_df&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;법정동코드&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;astype&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;이미 처리된 법정동 수:&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;done_bcodes&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;기존 결과 없음 (처음 실행)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# CSV 헤더 최초 1회만 작성&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exists&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OUTPUT_PATH&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    pd&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DataFrame&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        columns&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;법정동코드&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;category_group_code&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;count&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to_csv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OUTPUT_PATH&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; row &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; seoul_dong_df&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;iterrows&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    bcode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;row&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;법정동코드&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; bcode &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; done_bcodes&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;continue&lt;/span&gt;

    address &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;서울특별시 &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;row&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;시군구명&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;row&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;읍면동명&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;

    x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dong_to_coord&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;address&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; x &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;continue&lt;/span&gt;

    rows_to_save &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; category &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; CATEGORIES&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keys&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        places &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; fetch_places&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;category&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; RADIUS&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        count &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; p &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; places&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            place_bcode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; coord_to_bcode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; place_bcode &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; bcode&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                count &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;

        rows_to_save&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;법정동코드&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; bcode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;category_group_code&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; category&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;count&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; count
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    pd&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DataFrame&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rows_to_save&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to_csv&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        OUTPUT_PATH&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        mode&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        header&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        index&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[React - SVGR 설치]]></title><description><![CDATA[1. Vite project에서 SVGR 설치 2. vite.config.ts 설정 3. 타입 선언 추가 (TypeScript 사용 시) 4. 사용 방법 1. Vite 방식 ?react 를 붙여야 하는 이유 Vite는 기본적으로 SVG를 URL으로 처리함 따라서 ?react를 붙여야 R]]></description><link>https://woojin-devv.github.io/posts/react-svgr/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/react-svgr/</guid><pubDate>Tue, 03 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h3 id=&quot;1-vite-project에서-svgr-설치&quot;&gt;1. Vite project에서 SVGR 설치&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;npm install &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;D&lt;/span&gt; vite&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;plugin&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;svgr&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-viteconfigts-설정&quot;&gt;2. vite.config.ts 설정&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; defineConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;vite&apos;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; react &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@vitejs/plugin-react&apos;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; svgr &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;vite-plugin-svgr&apos;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;defineConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;react&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;svgr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;3-타입-선언-추가-typescript-사용-시&quot;&gt;3. 타입 선언 추가 (TypeScript 사용 시)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/// &amp;lt;reference types=&quot;vite-plugin-svgr/client&quot; /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-사용-방법&quot;&gt;4. 사용 방법&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Vite 방식&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Icon &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@/assets/icon.svg?react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Icon&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;?react&lt;/code&gt; 를 붙여야 하는 이유
&lt;ul&gt;
&lt;li&gt;Vite는 기본적으로 SVG를 URL으로 처리함&lt;/li&gt;
&lt;li&gt;따라서 ?react를 붙여야 React Component로 변환됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;CRA(Create React App) 방식&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ReactComponent &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; Icon &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./icon.svg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구분&lt;/th&gt;
&lt;th&gt;CRA&lt;/th&gt;
&lt;th&gt;Vite&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SVG React 변환&lt;/td&gt;
&lt;td&gt;기본 내장&lt;/td&gt;
&lt;td&gt;별도 plugin 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;import 방식&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;{ ReactComponent as Icon }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;?react&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;설정 접근&lt;/td&gt;
&lt;td&gt;Webpack 숨김&lt;/td&gt;
&lt;td&gt;설정 파일 명시적&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content:encoded></item><item><title><![CDATA[딥러닝 | Agentic AI개요]]></title><description><![CDATA[Agentic AI란? 주어진 상황에서 문제 해결을 하기 위해 스스로 목표를 설정하고, 재조정하며 적응적 의사결정을 하는 AI를 말한다. Agentic AI vs AI Agent Agentic AI : 스스로 목표 설정을하고 실행 능력을 갖춘 AI AI Agent : 특정 작업 중심으로]]></description><link>https://woojin-devv.github.io/posts/Agentic-AI/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Agentic-AI/</guid><pubDate>Sun, 19 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;agentic-ai란&quot;&gt;Agentic AI란?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;주어진 상황에서 문제 해결을 하기 위해 스스로 목표를 설정하고, 재조정하며 적응적 의사결정을 하는 AI를 말한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;agentic-ai-vs-ai-agent&quot;&gt;Agentic AI vs AI Agent&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Agentic AI : 스스로 목표 설정을하고 실행 능력을 갖춘 AI&lt;/li&gt;
&lt;li&gt;AI Agent : 특정 작업 중심으로 사전에 정의된 범위 내에서만 자율적으로 작동&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;특징&lt;/th&gt;
&lt;th&gt;Agentic AI&lt;/th&gt;
&lt;th&gt;AI Agent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;정의&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;스스로 목표를 설정하고, 재조정하며 적응적 의사결정을 하는 AI 시스템&lt;/td&gt;
&lt;td&gt;환경을 인식하고, 결정하며, 사전에 정해진 목표를 달성하기 위해 자율적으로 행동하는 개별 소프트웨어 프로그램 또는 시스템&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;범위&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;여러 AI Agent를 조율하여 복잡한 고수준 목표 달성 (상위 개념)&lt;/td&gt;
&lt;td&gt;특정 목표 달성을 위한 기본 구성 요소 (하위 개념)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;목표 설정&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;스스로 목표를 설정하고 재조정&lt;/td&gt;
&lt;td&gt;사전에 정해진 목표를 따름&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;행동&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;적응적 의사결정 및 AI Agent들의 협업을 통한 복잡한 문제 해결&lt;/td&gt;
&lt;td&gt;환경에 따라 결정하고 자율적으로 행동&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;agent-system은-다음과-같이-나눌-수-있다&quot;&gt;Agent System은 다음과 같이 나눌 수 있다.&lt;/h2&gt;
&lt;h3 id=&quot;1-single-agent-system&quot;&gt;1. Single Agent System&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;하나의 AI system이 환경과 상호작용하며 문제 해결을 함&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(+) : 단순구조&lt;/li&gt;
&lt;li&gt;(+) : 의사결정 속도가 빠름&lt;/li&gt;
&lt;li&gt;(-) : 복잡한 문제 해결 불가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;2-multi-agent-system&quot;&gt;2. Multi Agent System&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;여러 Agent들이 동일한 환경에서 상호작용하며 문제 해결을 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(+) : 복잡한 문제 해결 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;mas의-특징&quot;&gt;MAS의 특징&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;분산성 (decentralization)
&lt;ul&gt;
&lt;li&gt;의사결정과 제어가 중앙 집중적이지 않고, 각 에이전트들이 독립적으로 동작한다.&lt;/li&gt;
&lt;li&gt;단일 실패 지점을 제거하여, 시스템 안정성을 향상시켰다.&lt;/li&gt;
&lt;li&gt;P2P network, 블록체인, 자율 드론 분산 제어&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;자율성 (Autonomy)
&lt;ul&gt;
&lt;li&gt;외부의 개입 없이, 스스로 목표 달성을 위한 의사결정 수행&lt;/li&gt;
&lt;li&gt;환경 변화에 대응, 인간의 개입 최소화&lt;/li&gt;
&lt;li&gt;예) 로봇이 스스로 경로 탐색, 에이전트가 자원 사용 결정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;상호작용 (Interaction)
&lt;ul&gt;
&lt;li&gt;에이전트들 간 정보 교환과 협력을 통해 집단적으로 문제 해결&lt;/li&gt;
&lt;li&gt;시너지 효과&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;적응성 (Adaptivity)
&lt;ul&gt;
&lt;li&gt;에이전트가 환경 변화 및 다른 에이전트의 행동에 맞게 전략을 수정&lt;/li&gt;
&lt;li&gt;동적 및 불확실한 환경에서도 유효하게 동작 가능&lt;/li&gt;
&lt;li&gt;예) 주식 거래에서 시장 변화에 따라 매매 전략 조정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;다음과-같이-세분화-할-수-있다&quot;&gt;다음과 같이 세분화 할 수 있다.&lt;/h3&gt;
&lt;h3 id=&quot;2-1-계층기반-mas-hierarchy-mas&quot;&gt;2-1. 계층기반 MAS (Hierarchy MAS)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;하나의 관리 Agent와 여러 개의 Agent들로 구성 되어 있다.
&lt;ul&gt;
&lt;li&gt;관리 Agent는 전체 프로세스를 조율, 하위 Agent들을 제어하고 업무 조정&lt;/li&gt;
&lt;li&gt;(+) : 통제 용이, 의사결정 속도 빠름&lt;/li&gt;
&lt;li&gt;(-) : 중앙 에이전트 의존성, 병목 가능성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2-2-collaborative-mas-협력-기반-mas&quot;&gt;2-2. Collaborative MAS (협력 기반 MAS)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;여러 Agent들이 정보를 공유하며 협력적으로 문제해결한다.
&lt;ul&gt;
&lt;li&gt;(+) : 시너지 효과 -&gt; 문제 해결 능력이 높아짐&lt;/li&gt;
&lt;li&gt;(-) : 협상과 조율이 필요&lt;/li&gt;
&lt;li&gt;협력 전략
&lt;ul&gt;
&lt;li&gt;Task Sharing&lt;/li&gt;
&lt;li&gt;Result Sharing&lt;/li&gt;
&lt;li&gt;CNP(Contract Net Protocol)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;응용 사례
&lt;ul&gt;
&lt;li&gt;자율주행 : 차량들이 서로 협력하여 교통의 혼잡도를 완화시킴&lt;/li&gt;
&lt;li&gt;로보틱스 : 다수의 드론이 협력하여 탐사, 재난 구조 수행&lt;/li&gt;
&lt;li&gt;스마트 그리드: 에이전트 기반 전력 거래와 분배를 최적화&lt;/li&gt;
&lt;li&gt;전자상거래: 자동 협상 / 경매 에이전트&lt;/li&gt;
&lt;li&gt;사회 시뮬레이션 : 인구 이동, 질병확산등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2-3-competitive-mas-경쟁기반-mas&quot;&gt;2-3. Competitive MAS (경쟁기반 MAS)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Agent들이 자신의 이익을 극대화하기 위해 경쟁
&lt;ul&gt;
&lt;li&gt;주식 시장 시뮬레이션, 경매 시스템&lt;/li&gt;
&lt;li&gt;(+) : 현실성 반영&lt;/li&gt;
&lt;li&gt;(-) : 갈등이 발생 -&gt; 전체 효율이 저하됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;agent간-통신-프로토콜&quot;&gt;Agent간 통신 프로토콜&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Agent간 정보 교환을 위해 프로토콜 필요&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;통신 방식
&lt;ul&gt;
&lt;li&gt;직접통신&lt;/li&gt;
&lt;li&gt;브로드캐스트 / 멀티캐스트&lt;/li&gt;
&lt;li&gt;중앙 매개체 기반&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;fipa-foundation-for-intelligent-physical-agents&quot;&gt;FIPA (Foundation for Intelligent Physical Agents)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;MAS의 상호운용성 확보를 위한 국제 표준 제정&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FIPA-ACL(Agent Communication Language)
&lt;ul&gt;
&lt;li&gt;에이전트 간 메시지 교환을 위한 언어&lt;/li&gt;
&lt;li&gt;메시지 구성: Performative, Content, Sender, Receiver, Ontology, Protocol&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[딥러닝 | CNN(합성곱신경망) 개요]]></title><description><![CDATA[1. CNN 이란? Convolutional Neural Network의 줄임말로, 격자 이미지와 같은 데이터를 설계하기 위해 고안된 인공 신경망 합성곱(convolution) 연산을 통해 이미지의 공간적 특징을 추출(feature map)한다. 특징 vision 분야에서 성능 우수 이]]></description><link>https://woojin-devv.github.io/posts/CNN/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/CNN/</guid><pubDate>Fri, 17 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;1-cnn-이란&quot;&gt;1. CNN 이란?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Convolutional Neural Network의 줄임말로, 격자 이미지와 같은 데이터를 설계하기 위해 고안된 인공 신경망&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;합성곱(convolution) 연산을 통해 이미지의 공간적 특징을 추출(feature map)한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;특징&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;vision 분야에서 성능 우수&lt;/li&gt;
&lt;li&gt;이미지 데이터를 인식하고 패턴을 찾는데 유용&lt;/li&gt;
&lt;li&gt;데이터를 학습하고 패턴을 사용하여 이미지를 분류함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;1-1-cnn-모델-발전&quot;&gt;1-1 CNN 모델 발전&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;LeNet&lt;/li&gt;
&lt;li&gt;AlexNet&lt;/li&gt;
&lt;li&gt;VGGNet&lt;/li&gt;
&lt;li&gt;ResNet&lt;/li&gt;
&lt;li&gt;EfficientNet&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;2-cnn의-구조&quot;&gt;2. CNN의 구조&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Convolution과 Pooling을 반복하면서 특징을 찾고, 그 특징을 fully connected NN의 입력 데이터로 사용함으로써 Classification을 수행함&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;2-1-cnn-layer&quot;&gt;2-1 CNN Layer&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;CNN의 Layer는 크게 3가지로 나눌 수 있다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Convolutional Layer&lt;/li&gt;
&lt;li&gt;Pooling Layer&lt;/li&gt;
&lt;li&gt;Fully-connected Layer&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;2-1-1-convolutional-layer&quot;&gt;2-1-1. Convolutional Layer&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://miro.medium.com/1*MQIAAntN5tYgKEDNTcpZmg.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이미지 데이터는 3차원 tensor로 표현됨&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;이미지 input을 받아, 필터와 합성곱 연산을 통해 특징이 두드러지도록 feature map을 생성한다.
&lt;img src=&quot;https://wikidocs.net/images/page/164365/Fig_04_cnn_filter.png&quot; alt=&quot;위키독스에서 가져옴&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;filter(kernel) : 필터를 통과한 이미지는 &lt;strong&gt;선, 색상, 형태, 경계&lt;/strong&gt;등 이미지를 구분지을 수 있는 요소가 뚜렷해짐
&lt;ul&gt;
&lt;li&gt;필터가 많을 수록 더 많은 이미지 feature를 추출할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;stride : 필터의 이동량&lt;/li&gt;
&lt;li&gt;padding : 이미지에 합성곱 연산을 수행하면 출력 이미지의 크기가 입력이미지의 크기보다 작아지는 문제 발생 -&gt; 이미지 가장자리에 특정 값으로 픽셀 추가
&lt;ul&gt;
&lt;li&gt;예) Zero-padding : 가장 자리를 0 pixel로 채움&lt;/li&gt;
&lt;li&gt;&lt;img src=&quot;https://www.researchgate.net/publication/323351195/figure/fig4/AS:941734410350602@1601538388097/Zero-padding-of-different-sizes.gif&quot; alt=&quot;alt text&quot;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;feature map(=activation map이라고도 함)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://miro.medium.com/1*ixuhX9vaf1kUQTWicVYiyg.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;2-1-2-pooling-layer&quot;&gt;2-1-2. Pooling Layer&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;feature map의 feature를 유지하면서, 이미지의 크기를 줄이는 다운사이징 기법&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;일반적으로, 이미지 데이터는 인접 픽셀들 간 유사도가 높다는 특징을 이용&lt;/li&gt;
&lt;li&gt;기법 3가지
&lt;ul&gt;
&lt;li&gt;Max Pooling : 가장 큰 신호에 값으로 반응 -&gt; 노이즈 감소, 속도가 빠름, 영상의 분별력이 좋아짐&lt;/li&gt;
&lt;li&gt;Average Pooling&lt;/li&gt;
&lt;li&gt;Min Pooling&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;2-1-3-activation-function&quot;&gt;2-1-3. Activation Function&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;각 뉴런(노드)의 입력 값을 처리한 후에 출력값을 결정하는 함수&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;입력 값을 다음 층으로 출력을 전달할 지를 결정함&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;math&quot;&gt;&lt;pre class=&quot;language-math&quot;&gt;&lt;code class=&quot;language-math&quot;&gt; a=f(z) 
 \\ z = w \times X + b &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;활성화 함수 종류: ReLU, Sigmoid, Tanh, Leaky ReLU 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;활성화 함수 사용 이유?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;비선형성: 신경망에 비선형성을 도입하여 단순한 선형 변환으로는 해결할 수 없는 문제 해결&lt;/li&gt;
&lt;li&gt;출력 범위 조정&lt;/li&gt;
&lt;li&gt;신경망의 학습 속도에 영향&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[리버싱 핵심 원리 | PE 파일 구조]]></title><description><![CDATA[PE 파일 형식 (Portable Executable) PE(Portable Executable) 는 실행 파일, DLL, 오브젝트 코드 등을 위한 파일 형식이다. 이름처럼 다른 곳으로 옮겨도 실행이 가능하도록 이식성을 염두에 두고 설계되었다. PE 파일은 크게 PE 헤더 와 섹션 으로]]></description><link>https://woojin-devv.github.io/posts/Cyber-Security-PE/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Cyber-Security-PE/</guid><pubDate>Fri, 10 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;pe-파일-형식-portable-executable&quot;&gt;PE 파일 형식 (Portable Executable)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;PE(Portable Executable)&lt;/strong&gt; 는 실행 파일, DLL, 오브젝트 코드 등을 위한 파일 형식이다. 이름처럼 다른 곳으로 옮겨도 실행이 가능하도록 이식성을 염두에 두고 설계되었다. PE 파일은 크게 &lt;strong&gt;PE 헤더&lt;/strong&gt;와 &lt;strong&gt;섹션&lt;/strong&gt;으로 구성된다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;pe-헤더-pe-header&quot;&gt;PE 헤더 (PE Header)&lt;/h3&gt;
&lt;p&gt;PE 헤더는 파일의 메타데이터를 담고 있으며, 운영체제가 파일을 메모리에 어떻게 매핑하고 실행할지에 대한 정보를 제공한다.&lt;/p&gt;
&lt;h4 id=&quot;1-dos-헤더-dos-header&quot;&gt;1. DOS 헤더 (DOS Header)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;모든 PE 파일의 시작은 &lt;code class=&quot;language-text&quot;&gt;IMAGE_DOS_HEADER&lt;/code&gt; 구조체로 시작한다. 이는 MS-DOS와의 하위 호환성을 위한 부분이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;c&quot;&gt;&lt;pre class=&quot;language-c&quot;&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;_IMAGE_DOS_HEADER&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// DOS .EXE header&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    WORD e_magic&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;       &lt;span class=&quot;token comment&quot;&gt;// Magic number&lt;/span&gt;
    WORD e_cblp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;        &lt;span class=&quot;token comment&quot;&gt;// Byte on last page of file&lt;/span&gt;
    WORD e_cp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;          &lt;span class=&quot;token comment&quot;&gt;// Pages in file&lt;/span&gt;
    WORD e_crlc&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;        &lt;span class=&quot;token comment&quot;&gt;// Relocations&lt;/span&gt;
    WORD e_cparhdr&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;// Size of header in paragraphs&lt;/span&gt;
    WORD e_minalloc&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Minimum extra paragraphs needed&lt;/span&gt;
    WORD e_maxalloc&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Maximum extra paragraphs needed&lt;/span&gt;
    WORD e_ss&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;          &lt;span class=&quot;token comment&quot;&gt;// Initial (relative) SS value&lt;/span&gt;
    WORD e_sp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;          &lt;span class=&quot;token comment&quot;&gt;// Checksum&lt;/span&gt;
    WORD e_ip&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;          &lt;span class=&quot;token comment&quot;&gt;// Initial IP value&lt;/span&gt;
    WORD e_cs&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;          &lt;span class=&quot;token comment&quot;&gt;// Initial (relative) CS value&lt;/span&gt;
    WORD e_lfarlc&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;token comment&quot;&gt;// File address of relocation table&lt;/span&gt;
    WORD e_ovno&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;        &lt;span class=&quot;token comment&quot;&gt;// Overlay number&lt;/span&gt;
    WORD e_res&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;token comment&quot;&gt;// Reserved words&lt;/span&gt;
    WORD e_oemid&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;       &lt;span class=&quot;token comment&quot;&gt;// OEM identifier (for e_oeminfo)&lt;/span&gt;
    WORD e_oeminfo&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;// OEM information; e_oemid specific&lt;/span&gt;
    WORD e_res2&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;// Reserved words&lt;/span&gt;
    LONG e_lfanew&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;token comment&quot;&gt;// File address of new exe header&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; IMAGE_DOS_HEADER&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;PIMAGE_DOS_HEADER&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;주요 멤버 변수는 다음과 같다.
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;e_magic&lt;/code&gt;: DOS signature로 항상 &quot;MZ&quot; (0x5A4D) 값을 가진다. 파일이 유효한 PE 파일인지 확인하는 첫 번째 지표이다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;e_lfanew&lt;/code&gt;: NT 헤더의 시작 위치를 알려주는 오프셋 값이다. 이 값을 통해 NT 헤더로 바로 이동할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;2-dos-스텁-dos-stub&quot;&gt;2. DOS 스텁 (DOS Stub)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;DOS 헤더 바로 뒤에 위치하며, PE 파일을 DOS 환경에서 실행했을 때 &quot;This program cannot be run in DOS mode&quot;와 같은 메시지를 출력하는 작은 프로그램이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;3-nt-헤더-nt-headers&quot;&gt;3. NT 헤더 (NT Headers)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;e_lfanew&lt;/code&gt;가 가리키는 위치에 있으며, PE 파일의 핵심 정보를 담고 있다. &lt;code class=&quot;language-text&quot;&gt;Signature&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;File Header&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Optional Header&lt;/code&gt; 세 부분으로 나뉜다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Signature&lt;/strong&gt;: PE 포맷임을 나타내는 시그니처로, &quot;PE\0\0&quot; (0x00004550) 값을 가진다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;파일 헤더 (File Header)&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;IMAGE_FILE_HEADER&lt;/code&gt; 구조체이며, 파일의 개략적인 정보를 담는다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Machine&lt;/code&gt;: 대상 CPU 아키텍처 (e.g., x86, x64).&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;NumberOfSections&lt;/code&gt;: 파일에 존재하는 섹션의 개수.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;TimeDateStamp&lt;/code&gt;: 파일이 생성된 시간.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Characteristics&lt;/code&gt;: 파일의 속성 (e.g., 실행 파일인지, DLL인지).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;옵셔널 헤더 (Optional Header)&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;IMAGE_OPTIONAL_HEADER&lt;/code&gt; 구조체이며, 이름과 달리 실행 파일에서는 &lt;strong&gt;필수적인&lt;/strong&gt; 헤더이다. 프로그램 실행에 필요한 핵심 정보를 포함한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Magic&lt;/code&gt;: PE32(0x10b) 또는 PE32+(0x20b, 64비트)를 구분한다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;AddressOfEntryPoint&lt;/code&gt;: 프로그램이 처음 시작되는 코드의 주소(RVA).&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ImageBase&lt;/code&gt;: PE 파일이 메모리에 로드되는 시작 주소.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;DataDirectory&lt;/code&gt;: &lt;code class=&quot;language-text&quot;&gt;IMAGE_DATA_DIRECTORY&lt;/code&gt; 구조체 배열로, Import/Export 테이블, 리소스, TLS 등 중요한 데이터 구조의 위치와 크기 정보를 담고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;섹션-sections&quot;&gt;섹션 (Sections)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;헤더 다음에 위치하며, 코드, 데이터, 리소스 등 파일의 실제 내용을 담고 있다. 각 섹션은 자신의 속성을 정의하는 &lt;strong&gt;섹션 헤더&lt;/strong&gt;를 가진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;주요-섹션-종류&quot;&gt;주요 섹션 종류&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;.text&lt;/strong&gt;: 실행 가능한 코드를 포함하는 섹션. 일반적으로 실행/읽기 전용 권한을 가진다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.data&lt;/strong&gt;: 초기화된 전역 변수 및 정적 변수를 저장하는 섹션.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.rdata&lt;/strong&gt;: 읽기 전용 데이터 (e.g., 문자열 리터럴, 상수)를 저장한다. Import/Export 테이블 정보도 이 곳에 위치할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.bss&lt;/strong&gt;: 초기화되지 않은 데이터 섹션. 파일 내에서는 공간을 차지하지 않지만, 메모리에 로드될 때 할당된다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.rsrc&lt;/strong&gt;: 아이콘, 이미지, 메뉴 등 프로그램에서 사용하는 리소스를 저장한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.idata&lt;/strong&gt;: 다른 DLL에서 가져오는 함수 정보를 담은 Import Address Table (IAT) 등이 위치하는 섹션이다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.edata&lt;/strong&gt;: 다른 프로그램에서 사용할 수 있도록 함수를 노출하는 Export 정보가 담긴 섹션이다. (주로 DLL)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.reloc&lt;/strong&gt;: ImageBase에 로드할 수 없는 경우, 코드 내의 주소를 수정하기 위한 재배치 정보를 담고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;pe-viewer로-확인&quot;&gt;PE Viewer로 확인&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;사용한 PE Viewer -&gt; VX PE Viewer ver 1.0&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;Dos header signature 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Dos Header &gt; Magic number 부분을 클릭하면 아래 HEX DUMP 창에 해당 영역에 하이라이트가 칠해진 부분을 확인할 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Magic Number가 차지하는 부분은 총 2bytes이고 signature는 &lt;code class=&quot;language-text&quot;&gt;MZ&lt;/code&gt;이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cyber_security/mz.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;pe-파일-로딩과-메모리&quot;&gt;PE 파일 로딩과 메모리&lt;/h2&gt;
&lt;p&gt;Windows가 프로세스를 메모리에 로드할 때, PE 파일의 정보를 사용하여 가상 메모리 공간에 내용을 매핑한다. 이때 운영체제는 가상 메모리의 어느 위치에, 어떤 크기로 공간을 할당해야 할지 어떻게 알 수 있을까?&lt;/p&gt;
&lt;p&gt;그 해답은 &lt;strong&gt;옵셔널 헤더(Optional Header)&lt;/strong&gt; 에 있다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cyber_security/imagebase.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;ImageBase&lt;/code&gt;&lt;/strong&gt;: PE 파일이 메모리에 로드될 가상 주소(VA)의 시작점을 지정한다. 예를 들어 &lt;code class=&quot;language-text&quot;&gt;ImageBase&lt;/code&gt;가 &lt;code class=&quot;language-text&quot;&gt;0x00400000&lt;/code&gt;이라면, 로더는 이 주소부터 PE 이미지를 배치하려고 시도한다.&lt;/li&gt;
&lt;li&gt;Hex Dump에서 이 값은 &lt;code class=&quot;language-text&quot;&gt;00 00 40 00&lt;/code&gt;처럼 보이는데, 이는 intel x86 아키텍처가 사용하는 &lt;strong&gt;리틀 엔디안(Little Endian)&lt;/strong&gt; 바이트 순서 때문이다. 낮은 주소에 데이터의 가장 낮은 바이트(Least Significant Byte)부터 저장하므로, 실제 값은 &lt;code class=&quot;language-text&quot;&gt;0x00400000&lt;/code&gt;이 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;ImageBase&lt;/code&gt;에 지정된 주소는 희망 사항(preferred address)일 뿐, 항상 그 주소에 로드된다는 보장은 없다. 만약 해당 프로세스의 가상 주소 공간에서 &lt;code class=&quot;language-text&quot;&gt;ImageBase&lt;/code&gt; 주소가 이미 다른 모듈(e.g., 다른 DLL)에 의해 사용 중이라면, PE 로더는 다른 비어있는 주소에 파일을 로드하게 된다. 이 과정을 &lt;strong&gt;재배치(Rebasing)&lt;/strong&gt; 라고 하며, 이를 위해 &lt;code class=&quot;language-text&quot;&gt;.reloc&lt;/code&gt; 섹션의 정보가 사용된다.&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Operating System | 병행성의 개념]]></title><description><![CDATA[병행성(concurrency)의 원리 OS는 멀티프로세스 를 처리해야함. 멀티프로세스를 처리해야하는 OS의 공통 주제는 아래와 같음 Multiprogramming : 단일 프로세서 시스템 + 여러 개 프로세스 Multiprocessing : 멀티 프로세서 + 멀티 프로세스 Distrib]]></description><link>https://woojin-devv.github.io/posts/병행성/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/병행성/</guid><pubDate>Thu, 09 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;병행성concurrency의-원리&quot;&gt;병행성(concurrency)의 원리&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;OS는 &lt;strong&gt;멀티프로세스&lt;/strong&gt;를 처리해야함. 멀티프로세스를 처리해야하는 OS의 공통 주제는 아래와 같음
&lt;ul&gt;
&lt;li&gt;Multiprogramming : 단일 프로세서 시스템 + 여러 개 프로세스&lt;/li&gt;
&lt;li&gt;Multiprocessing : 멀티 프로세서 + 멀티 프로세스&lt;/li&gt;
&lt;li&gt;Distributed Processing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;공유자원(such as memory, files, and I/O access)을 나누고 점유하는데 있어서 방법론이 필요함.
&lt;ul&gt;
&lt;li&gt;병행성(concurrency)라는 개념 등장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;병행성은 다음과 같은 3가지 상황에서 발생한다&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;다수의 응용: 다수의 활동 중인 응용들 간에 처리시간의 동적 공유를 위해 멀티 프로그래밍이 발전&lt;/li&gt;
&lt;li&gt;구조화된 응용: 모듈화된 설계 원칙과 구조적인 프로그램이 발전되면서 일부 응용이 병행 프로세스의 집합&lt;/li&gt;
&lt;li&gt;운영체제 구조: 운영체제도 다수의 프로세스와 쓰레드의 집합으로 구현&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;병행 처리의 문제점&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;전역 자원의 공유가 어려움&lt;/li&gt;
&lt;li&gt;운영체제가 자원을 최적으로 할당하기 어려움&lt;/li&gt;
&lt;li&gt;프로그래밍 오류 찾기가 어려움&lt;/li&gt;
&lt;li&gt;인터리빙이나 오버래핑으로 인해 발생하는 문제점 -&gt; 단일처리기 시스템에서나 다중처리시스템에서 동일
&lt;ul&gt;
&lt;li&gt;다른 프로세스의 행동에 종속&lt;/li&gt;
&lt;li&gt;OS의 스케줄링 정책에 의존&lt;/li&gt;
&lt;li&gt;OS의 인터럽트 처리 방법에 따라 달라짐&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;병행성과-관련된-주요-용어-정리&quot;&gt;병행성과 관련된 주요 용어 정리&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;용어&lt;/th&gt;
&lt;th&gt;정의&lt;/th&gt;
&lt;th&gt;주요 특징 / 핵심 포인트&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Atomic Operation (원자적 연산)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;수행 도중 중단되거나 다른 프로세스가 중간 상태를 볼 수 없는 연산&lt;/td&gt;
&lt;td&gt;- 불가분성(Indivisibility)&lt;br&gt;- 중간 상태 노출 불가&lt;br&gt;- 병행 프로세스 간 고립 보장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Critical Section (임계영역)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;공유 자원에 접근하는 코드 영역&lt;/td&gt;
&lt;td&gt;- 동시에 하나의 프로세스만 접근 가능&lt;br&gt;- 동기화 기법으로 보호 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deadlock (교착상태)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;프로세스들이 서로의 자원을 기다리며 무한 대기하는 상태&lt;/td&gt;
&lt;td&gt;- 자원 대기 순환 구조&lt;br&gt;- 시스템 진행 정지&lt;br&gt;- 예방/회피/탐지 기법 존재&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Livelock (라이브락)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;프로세스들이 상태를 계속 바꾸지만 실제로는 아무 작업도 수행하지 않는 상태&lt;/td&gt;
&lt;td&gt;- Deadlock과 달리 상태 변화는 존재&lt;br&gt;- 실질적 진전 없음&lt;br&gt;- 과도한 재시도 루프 발생 시 흔함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mutual Exclusion (상호배제)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;한 시점에 오직 하나의 프로세스만 임계영역 실행 가능&lt;/td&gt;
&lt;td&gt;- 경쟁 방지&lt;br&gt;- 세마포어, 뮤텍스 등으로 구현&lt;br&gt;- 임계영역 문제 해결 조건 중 하나&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Race Condition (경쟁상태)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;여러 프로세스가 동시에 공유 자원에 접근해 결과가 실행 순서에 따라 달라지는 상태&lt;/td&gt;
&lt;td&gt;- 비결정적 결과 발생 가능&lt;br&gt;- 원자성 보장 실패&lt;br&gt;- 동기화 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Starvation (기아)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;프로세스가 실행 가능한 상태임에도 스케줄링에서 계속 배제되어 실행되지 못하는 상황&lt;/td&gt;
&lt;td&gt;- 우선순위 스케줄링에서 자주 발생&lt;br&gt;- 공정성(Fairness) 문제&lt;br&gt;- Aging 기법으로 완화 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Shared Resource (공유 자원)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;여러 프로세스가 함께 사용하는 자원 (메모리, 파일 등)&lt;/td&gt;
&lt;td&gt;- 동기화 필요&lt;br&gt;- 경쟁 상태의 원인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Synchronization (동기화)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;여러 프로세스의 실행 순서를 제어하여 일관성을 유지하는 기법&lt;/td&gt;
&lt;td&gt;- Mutual Exclusion 구현 수단&lt;br&gt;- 세마포어, 모니터, 조건 변수 등 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;자원경쟁&quot;&gt;자원경쟁&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;병렬 프로세스들은 같은 자원을 사용하려고 경쟁하면 충돌이 발생한다.
&lt;ul&gt;
&lt;li&gt;프로세스들이 경쟁(race)하면 다음 3가지 제어 문제가 발생함&lt;/li&gt;
&lt;li&gt;상호배제, 교착상태, 기아&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;eg. memory, files, and I/O access, clock&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Operating System | 상호배제]]></title><description><![CDATA[상호배제 (Mutual Exclusion)란? 한 번에 하나의 프로세스만 임계 구역(critical section)을 실행할 수 있도록 하는 원리. 상호 배제를 보장하기 위해서는 프로세스가 인터럽트(interrupt) 되지 않도록 해야 한다. 단일 프로세서 시스템에서는 여러 프로세스가 ]]></description><link>https://woojin-devv.github.io/posts/상호배제/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/상호배제/</guid><pubDate>Thu, 09 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h3 id=&quot;상호배제-mutual-exclusion란&quot;&gt;상호배제 (Mutual Exclusion)란?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;한 번에 하나의 프로세스만 임계 구역(critical section)을 실행할 수 있도록 하는 원리.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;상호 배제를 보장하기 위해서는 프로세스가 &lt;strong&gt;인터럽트(interrupt)&lt;/strong&gt; 되지 않도록 해야 한다.&lt;/li&gt;
&lt;li&gt;단일 프로세서 시스템에서는 여러 프로세스가 동시에 실행되지 않고 &lt;strong&gt;인터리빙(interleaving)&lt;/strong&gt; 방식으로 번갈아 실행된다.&lt;/li&gt;
&lt;li&gt;실행 중인 프로세스는 OS 서비스를 호출하거나 인터럽트를 받을 때까지 계속 실행된다.&lt;/li&gt;
&lt;li&gt;OS 커널은 인터럽트 비활성화(&lt;code class=&quot;language-text&quot;&gt;disable interrupts&lt;/code&gt;) 및 활성화(&lt;code class=&quot;language-text&quot;&gt;enable interrupts&lt;/code&gt;) 기능을 제공한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;while (true) {
    /* 인터럽트 비활성화 */
    /* 임계 구역 */
    /* 인터럽트 활성화 */
    /* 나머지 코드 */
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;위 방식은 임계 구역이 인터럽트를 받지 않으므로 상호 배제가 보장된다.&lt;/li&gt;
&lt;li&gt;그러나 다음과 같은 단점이 존재한다.
&lt;ul&gt;
&lt;li&gt;실행 효율 저하 (프로세스 인터리빙 제한)&lt;/li&gt;
&lt;li&gt;다중 프로세서(multiprocessor) 환경에서는 동작하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;따라서 이러한 한계를 보완하기 위해 다른 상호 배제 알고리즘(예: Peterson’s algorithm, Test-and-Set 등)이 사용된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;상호배제-해결방법&quot;&gt;상호배제 해결방법&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/os/concurrency1.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;연습문제-51&quot;&gt;연습문제 5.1&lt;/h2&gt;
&lt;p&gt;With respect to mutual exclusion using interrupt disabling&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Mention &lt;strong&gt;the requirements for this exclusion and state&lt;/strong&gt; which of them are met when interrupts are disabled.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;임계영역에 접근하고자 하는 프로세스의 수행이 무한히 미루어져서는 안됨.&lt;/li&gt;
&lt;li&gt;임계영역이 empty일 때, 임계영역에 진입하려고 하는 프로세스가 지연되어서는 안 됨&lt;/li&gt;
&lt;li&gt;프로세서의 개수나 상대적인 프로세스 수행 속도에 대한 가정은 없어야 함.&lt;/li&gt;
&lt;li&gt;프로세스는 유한 시간 동안만 임계영역에 존재할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Identify the problems associated with this mechanism.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;연습문제-53&quot;&gt;연습문제 5.3&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/os/example5_3.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;a해설&quot;&gt;(a)해설&lt;/h3&gt;
&lt;p&gt;initial values &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;와 &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;의 값이 각각 2와 3이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;P_1&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8333em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.13889em;&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.3011em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;에서 &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x =&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;2 \times 3&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7278em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;×&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 이므로  &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;6&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x = 6&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;6&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;이다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;P_1&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8333em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.13889em;&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.3011em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;에서 &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y + 1&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7778em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;이므로 &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y=4&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;이다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;P_2&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8333em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.13889em;&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.3011em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;에서 &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x +1 &lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 이므로  &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;7&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x=7&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;7&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;이다.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;P_2&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8333em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.13889em;&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.3011em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;에서 &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;6&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y = x  \times y = 6 \times 4&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;×&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7278em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;×&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;이므로 &lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;28&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y=28&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;28&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;b해설&quot;&gt;(b)해설&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/os/example5_3_solution.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;assembly 코드를 확인해야 interleaved concurrent schedule을 확인할 수 있다.&lt;/li&gt;
&lt;li&gt;교행 수행 되었을 때 가지 수는 많음 -&gt; 순차 실행 되었을 때와 x, y갱신된 값이 다르다 정도만 알고 넘어가면 됨.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;P_1&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8333em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.13889em;&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.3011em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;에서
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;x := x * y&lt;/code&gt; 에서
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;LOAD R1, X&lt;/code&gt; X의 값을 R1(레지스터)에 로드&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;LOAD R2, Y&lt;/code&gt; Y의 값을 R2(레지스터)에 로드&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;MUL R1, R2&lt;/code&gt; R1에 R2의 값을 곱하여 R1에 갱신&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;STORE X, R1&lt;/code&gt; R1의 값을 X에 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;y++&lt;/code&gt; 에서
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;INC R2&lt;/code&gt; R2의 값을 1만큼 증가&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;STORE Y, R2&lt;/code&gt;(증가된) R2의 값을 Y에 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;P_2&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8333em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.13889em;&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.3011em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[리버싱 핵심 원리 | DLL]]></title><description><![CDATA[Windows Library, DLL 라이브러리(Library)란? 함수, 변수, 데이터, 타입 리소스등 여러 가지 프로그래밍 요소들의 집합 windows 운영체제에서는 주로 .lib , .dll 과 같은 확장자를 가진다. 표준화할 수 있는 함수 집합 C 표준 함수 : printf(),]]></description><link>https://woojin-devv.github.io/posts/Cyber-Security-dll/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Cyber-Security-dll/</guid><pubDate>Tue, 07 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;windows-library-dll&quot;&gt;Windows Library, DLL&lt;/h1&gt;
&lt;h2 id=&quot;라이브러리library란&quot;&gt;라이브러리(Library)란?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;함수, 변수, 데이터, 타입 리소스등 여러 가지 프로그래밍 요소들의 집합&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;windows 운영체제에서는 주로 &lt;code class=&quot;language-text&quot;&gt;*.lib&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;*.dll&lt;/code&gt;과 같은 확장자를 가진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;표준화할 수 있는 함수 집합&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C 표준 함수 : printf(), scanf() 등&lt;/li&gt;
&lt;li&gt;Win32 API : LoadLibraryA(), GetProcAddress(), MessageBox(), ...&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;라이브러리-링킹이란&quot;&gt;라이브러리 링킹이란?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;누군가가 만들어놓은 라이브러리를 자신의 프로그램에서 활용하는 방안&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;정적링킹과 동적링킹으로 구분된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;정적-링킹static-linking&quot;&gt;정적 링킹(Static Linking)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;빌드 중 링커가 라이크러리 컨텐츠를 바이너리(exe) 실행파일에 통합하는 방식&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;실행 파일에 라이브러리 코드가 복제되기 때문에 실행 파일의 크기가 커짐&lt;/li&gt;
&lt;li&gt;실행 파일은 단독 실행 파일이 되기 때문에 빌드만 성공하면 런타임에 실패하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;동적-링킹dynamic-linking&quot;&gt;동적 링킹(Dynamic Linking)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;빌드 시 라이브러리 함수 코드가 실행 파일에 통합되지 않고, 런타임에 라이브러리 로드 및 함수 호출이 수행되는 방식&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;프로그램 실행 시에 함수가 실행 파일과 연결됨&lt;/li&gt;
&lt;li&gt;호출할 함수 정보를 IAT(Import Address Table)에 적재되므로 실행 파일의 크기가 작다는 장점이 있음&lt;/li&gt;
&lt;li&gt;PATH 또는 시스템 폴더에 DLL이 없으면 프로그램 실행 불가 (런타임 시에 오류 발생)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[리버싱 핵심 원리 | Stack Frame]]></title><description><![CDATA[스택 프레임 x64dbg에서 main caller에 break point를 걸고 확인 main함수도 누군가에게 호출 됨 EBP 레지스터를 이용하여 스택 내의 로컬 변수, 파라미터, RET에 접근하는 기법 EBP를 사용하는 이유: ESP 레지스터의 값은 프로그램 안에서 수시로 변경되기 때]]></description><link>https://woojin-devv.github.io/posts/Cyber-Security-stack/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Cyber-Security-stack/</guid><pubDate>Mon, 06 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;스택-프레임&quot;&gt;스택 프레임&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;x64dbg에서 main caller에 break point를 걸고 확인&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;main함수도 누군가에게 호출 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;EBP 레지스터를 이용하여 스택 내의 로컬 변수, 파라미터, RET에 접근하는 기법&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;EBP를 사용하는 이유: ESP 레지스터의 값은 프로그램 안에서 수시로 변경되기 때문에 스택에 저장된 변수, 파라미터에 접근하고자 할 때는 EBP를 사용하는 것이 효율적임&lt;/li&gt;
&lt;li&gt;EBP: 베이스 포인터, ESP: 스택의 최상단 주소를 가리키는 레지스터&lt;/li&gt;
&lt;li&gt;함수가 호출될 때마다 스택 프레임이 만들어진다.
&lt;ul&gt;
&lt;li&gt;스택 프레임 안에는 함수의 매개변수(파라미터), 복귀 주소(RET), 지역 변수 등이 포함됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;스택-프레임의-구조&quot;&gt;스택 프레임의 구조&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;(함수의 프롤로그)
PUSH EBP
MOV EBP, ESP
-------
(함수 본체)
...

-------
(함수의 에필로그)
MOV ESP, EBP
POP EBP
RET&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;일단 기존의 EBP값을 어딘가에 저장해둬야하기 떄문에 EBP값을 스택에 저장해둠 (나중에 복구해야함)&lt;/li&gt;
&lt;li&gt;EBP는 함수가 종료될 때까지 유지됨 (함수 실행 중에는 ESP가 계속 변함)
&lt;ul&gt;
&lt;li&gt;그 다음 현재 ESP가 가리키는 값을 EBP에 갱신함&lt;/li&gt;
&lt;li&gt;함수 실행&lt;/li&gt;
&lt;li&gt;함수 실행이 종료되면 EBP가 가리키는 값을 다시 ESP에 저장&lt;/li&gt;
&lt;li&gt;EBP값을 pop하여, 함수 시작 전에 저장해둔 이전 함수의 프레임 포인터(EBP)를 되돌려줘서 스택 프레임을 원복함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;스택-예제&quot;&gt;스택 예제&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cpp&quot;&gt;&lt;pre class=&quot;language-cpp&quot;&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;char&lt;/span&gt; buffer&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;스택-예제--main-함수의-prologue&quot;&gt;스택 예제 | main 함수의 prologue&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;nasm&quot;&gt;&lt;pre class=&quot;language-nasm&quot;&gt;&lt;code class=&quot;language-nasm&quot;&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;메모리-연산자&quot;&gt;메모리 연산자&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;특정 주소의 값을 참조하기 사용하는 연산자&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;BYTE PTR[...]
WORD PTR[...]
DWORD PTR[...]
QWORD PTR[...]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;BYTE는 1바이트,&lt;/li&gt;
&lt;li&gt;WORD는 2바이트,&lt;/li&gt;
&lt;li&gt;DWORD(Double WORD)는 4바이트&lt;/li&gt;
&lt;li&gt;QWORD(Quad WORD)는 8바이트.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Operating System | 쓰레드(Thread)]]></title><description><![CDATA[프로세스와 쓰레드 쓰레드 = 실행흐름 쓰레드의 장점(benefits) 프로세스에 비해 새로운 쓰레드 생성 시간/비용이 절약됨 프로세스 종료 시간보다 쓰레드 종료 시간이 짧다. 한 프로세스 내의 두 쓰레드들 사이의 교환 및 교체 시간이 짧다. 동일 프로세스 내의 쓰레드들은 메모리 및 파일]]></description><link>https://woojin-devv.github.io/posts/Thread/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Thread/</guid><pubDate>Sun, 05 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;프로세스와-쓰레드&quot;&gt;프로세스와 쓰레드&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;쓰레드 = 실행흐름&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;쓰레드의 장점(benefits)
&lt;ul&gt;
&lt;li&gt;프로세스에 비해 새로운 쓰레드 생성 시간/비용이 절약됨&lt;/li&gt;
&lt;li&gt;프로세스 종료 시간보다 쓰레드 종료 시간이 짧다.&lt;/li&gt;
&lt;li&gt;한 프로세스 내의 두 쓰레드들 사이의 교환 및 교체 시간이 짧다.&lt;/li&gt;
&lt;li&gt;동일 프로세스 내의 쓰레드들은 메모리 및 파일을 공유하기 때문에, 이들 쓰레드들은 커널의 개입 없이 서로 통신 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;단일쓰레딩threading--멀티쓰레딩multithreading&quot;&gt;단일쓰레딩(threading) &amp;#x26; 멀티쓰레딩(Multithreading)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;UNIX 계열의 여러 운영체제는 다중 사용자 프로세스를 지원하지만, 프로세스 당 하나의 쓰레드만을 지원한다.
&lt;ul&gt;
&lt;li&gt;JAVA 수행시간 환경은 하나의 프로세스가 멀티 쓰레드를 지원한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단일 프로세스 내에 멀티 쓰레드 실행을 지원 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;현존하는 멀티 프로세서 -&gt; 다수의 프로세스 &amp;#x26; 프로세스 당 다수의 쓰레드&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;쓰레드의-기능&quot;&gt;쓰레드의 기능&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;쓰레드 동기화(synchronization)
&lt;ul&gt;
&lt;li&gt;한 프로세스 내의 모든 쓰레드들은 동일 주소 공간 및 자원들을 공유&lt;/li&gt;
&lt;li&gt;공유 자원: 전역 변수, 파일, 힙(heap)duddur&lt;/li&gt;
&lt;li&gt;공유 자원에 대해 동시 접근 시, 일관성 유지 기법 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Agentic AI (1)]]></title><description><![CDATA[📌 AI 시스템의 사회적 영향 경제적 영향 산업 구조 변화 : 제조·물류·금융·의료 전반에서 자동화·효율성 증대 혁신 가속 : 자율주행, 맞춤형 헬스케어, 스마트시티 등 신산업 창출 노동시장 재편 : 단순 업무 감소, 고급 기술·데이터 일자리 증가 → 일자리 양극화 부의 불평등 : 대기]]></description><link>https://woojin-devv.github.io/posts/AI-in-practice/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/AI-in-practice/</guid><pubDate>Fri, 03 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;-ai-시스템의-사회적-영향&quot;&gt;📌 AI 시스템의 사회적 영향&lt;/h1&gt;
&lt;h2 id=&quot;경제적-영향&quot;&gt;경제적 영향&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;산업 구조 변화&lt;/strong&gt;: 제조·물류·금융·의료 전반에서 자동화·효율성 증대&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;혁신 가속&lt;/strong&gt;: 자율주행, 맞춤형 헬스케어, 스마트시티 등 신산업 창출&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;노동시장 재편&lt;/strong&gt;: 단순 업무 감소, 고급 기술·데이터 일자리 증가 → 일자리 양극화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;부의 불평등&lt;/strong&gt;: 대기업 중심 시장 집중 심화&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;사회적-영향&quot;&gt;사회적 영향&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;생활 편의 향상&lt;/strong&gt;: 추천·교육·헬스케어 개인화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;문화 변화&lt;/strong&gt;: 콘텐츠 제작 자동화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;디지털 격차&lt;/strong&gt;: 활용 능력 차이로 불평등 확대&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;신뢰 문제&lt;/strong&gt;: 딥페이크·허위정보로 정보 신뢰 하락&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&quot;-ai-규제-필요성과-프레임워크&quot;&gt;📌 AI 규제 필요성과 프레임워크&lt;/h1&gt;
&lt;h2 id=&quot;필요성&quot;&gt;필요성&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;사회 전반 영향 (일자리 구조, 저작권·진위성 문제)&lt;/li&gt;
&lt;li&gt;새로운 위험 (의료 AI, 자율주행 등)&lt;/li&gt;
&lt;li&gt;보안 위협 (딥페이크, AI 활용 사이버 공격)&lt;/li&gt;
&lt;li&gt;설명가능성 부족 (책임·법적 문제)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;국가별-접근&quot;&gt;국가별 접근&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;미국&lt;/strong&gt;: 산업경쟁력 유지 + 위험 완화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;EU&lt;/strong&gt;: 위험기반 규제, 강력한 법적 구속력 (EU AI Act)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;중국&lt;/strong&gt;: 사회통제 중심 규제&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;한국&lt;/strong&gt;: 균형적·진흥지향적 법제&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&quot;-eu-ai-act-유럽연합-인공지능법&quot;&gt;📌 EU AI Act (유럽연합 인공지능법)&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;2024년 3월에 통과된 AI 기술의 급속한 발전과 광범위한 적용에 따른 윤리적, 법적, 사회적 영향에 대응하기 위해 마련된 포괄적인 AI 규제 법안&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;위험 기반 분류&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[Level 1] 수용 불가 위험 → 사용 전면 금지&lt;/li&gt;
&lt;li&gt;[Level 2] 고위험 → 인프라, 교육, 필수 서비스 → 강한 규제&lt;/li&gt;
&lt;li&gt;[Level 3] 제한적 위험 → 딥페이크 등 → 투명성 의무 부과&lt;/li&gt;
&lt;li&gt;[Level 4] 저위험 → 상업·개인용 → 규제 최소&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;투명성 의무&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI와 상호작용 중임을 고지&lt;/li&gt;
&lt;li&gt;합성 콘텐츠 결과물 표시 의무&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&quot;-미국-nist-ai-rmf-위험관리-프레임워크-2023&quot;&gt;📌 미국 NIST AI RMF (위험관리 프레임워크, 2023)&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;목적&lt;/strong&gt;: AI 이점 극대화 + 위험 최소화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;적용대상&lt;/strong&gt;: 모든 분야·규모의 조직&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;ai-신뢰성-7대-특성&quot;&gt;AI 신뢰성 7대 특성&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;유효성·신뢰성&lt;/li&gt;
&lt;li&gt;안전성&lt;/li&gt;
&lt;li&gt;보안성·회복탄력성&lt;/li&gt;
&lt;li&gt;책임성·투명성&lt;/li&gt;
&lt;li&gt;설명가능성&lt;/li&gt;
&lt;li&gt;프라이버시&lt;/li&gt;
&lt;li&gt;공정성·편향 완화&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;📌 Traditional AI vs. Agentic AI&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;구분&lt;/th&gt;
      &lt;th&gt;Traditional AI&lt;/th&gt;
      &lt;th&gt;Agentic AI&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;목표&lt;/td&gt;
      &lt;td&gt;외부 명령 수행&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;목표 설정·재조정&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;상호작용&lt;/td&gt;
      &lt;td&gt;입력-출력 중심&lt;/td&gt;
      &lt;td&gt;환경·에이전트·인간과 지속적 상호작용&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;의사결정&lt;/td&gt;
      &lt;td&gt;사전학습 모델 기반&lt;/td&gt;
      &lt;td&gt;적응적·협력적 의사결정&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;자율성&lt;/td&gt;
      &lt;td&gt;제한적&lt;/td&gt;
      &lt;td&gt;예측불가 상황에서도 자율 대응&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;협력&lt;/td&gt;
      &lt;td&gt;개별 성능 최적화&lt;/td&gt;
      &lt;td&gt;전체 성능 최적화&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;📌 Generative AI vs. Agentic AI&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;구분&lt;/th&gt;
      &lt;th&gt;Generative AI&lt;/th&gt;
      &lt;th&gt;Agentic AI&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;핵심 개념&lt;/td&gt;
      &lt;td&gt;콘텐츠 생성 (텍스트·이미지 등)&lt;/td&gt;
      &lt;td&gt;목표 설정·의사결정 수행&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;출력&lt;/td&gt;
      &lt;td&gt;프롬프트 기반 결과&lt;/td&gt;
      &lt;td&gt;의사결정 + 행동 수행&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;상호작용&lt;/td&gt;
      &lt;td&gt;단발적 입력-출력&lt;/td&gt;
      &lt;td&gt;지속적 협력/협상&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;자율성&lt;/td&gt;
      &lt;td&gt;외부 지시 의존&lt;/td&gt;
      &lt;td&gt;스스로 목표·전략 수립&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;활용 예&lt;/td&gt;
      &lt;td&gt;텍스트 작성, 이미지 생성&lt;/td&gt;
      &lt;td&gt;교통 신호 제어, 위급상황 자율 대응&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h1 id=&quot;-agentic-ai-특징&quot;&gt;📌 Agentic AI 특징&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;자율성(Autonomy)&lt;/strong&gt;: 목표·의사결정 스스로&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;적응성(Adaptability)&lt;/strong&gt;: 환경 변화 대응&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;협력성(Cooperation)&lt;/strong&gt;: 타 에이전트·인간과 상호작용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;설명가능성(Transparency)&lt;/strong&gt;: 의사결정 근거 제공&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;확장성(Scalability)&lt;/strong&gt;: 모듈형 확장 가능&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;맥락인식(Context-awareness)&lt;/strong&gt;: 상황 기반 의사결정&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&quot;-동작-단계&quot;&gt;📌 동작 단계&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;인식 (Perception)&lt;/strong&gt;: IoT, DB, SNS 등에서 데이터 수집&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;추론 (Reasoning)&lt;/strong&gt;: 계획·의사결정 수행&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;행동 (Action)&lt;/strong&gt;: 작업 실행 및 수정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;학습 (Learning)&lt;/strong&gt;: 경험 축적, 성능 개선&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h1 id=&quot;-기술-스택&quot;&gt;📌 기술 스택&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LLM + RAG&lt;/strong&gt;: 정보 검색 강화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;강화학습&lt;/strong&gt;: 전략적 계획 수립&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;멀티에이전트 시스템&lt;/strong&gt;: 분산 환경 협력&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&quot;-agentic-ai-유형&quot;&gt;📌 Agentic AI 유형&lt;/h1&gt;
&lt;h3 id=&quot;cooperative&quot;&gt;Cooperative&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;역할 분담 → 전체 목표 최적화&lt;/li&gt;
&lt;li&gt;예: 교통신호 제어, 스마트팩토리, 디지털포렌식&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;collaborative&quot;&gt;Collaborative&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;목표를 동적으로 협상·조율&lt;/li&gt;
&lt;li&gt;예: 출퇴근 시간 교통 처리량 vs 주말 안전성, 사건 유형별 디지털포렌식&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&quot;-도전과제&quot;&gt;📌 도전과제&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;연동 복잡성&lt;/strong&gt;: 기존 시스템 통합 문제&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;정확성&lt;/strong&gt;: 데이터 품질 의존&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;설명가능성 부족&lt;/strong&gt;: 블랙박스 의사결정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;리스크 관리&lt;/strong&gt;: 개인정보, 보안, 법적 리스크&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;유지보수&lt;/strong&gt;: 지속적인 감독·테스트 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&quot;-dark-ai--dark-llm&quot;&gt;📌 Dark AI / Dark LLM&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Dark AI&lt;/strong&gt;: 딥페이크, 사이버 범죄, 감시·프라이버시 침해, 무기화 등&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dark LLM&lt;/strong&gt;: WormGPT, FraudGPT → 악성코드, 피싱, 랜섬웨어 자동화&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;방어 기술&lt;/strong&gt;: DarkBERT(다크웹 분석), FakeCheck(딥페이크 탐지)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&quot;-the-30-rule&quot;&gt;📌 The 30% Rule&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AI 70% + 인간 30%&lt;/strong&gt; 역할 분담&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;이유&quot;&gt;이유&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;윤리적 안전장치 (사회적 가치·법 기준 충족)&lt;/li&gt;
&lt;li&gt;AI 한계 보완 (편향, 오류 방지)&lt;/li&gt;
&lt;li&gt;인간의 창의성, 공감, 도덕적 판단 보존&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[리버싱 핵심 원리 | 1부 기초 리버싱]]></title><description><![CDATA[1. 리버싱 분석 방법 1.1 정적 분석 파일의 겉모습을 분석하는 방법 파일을 실행하지 않음 파일의 종류, 크기, 헤더, 정보, 디지털 인증서 등의 다양한 내용을 확인 디스어셈블러를 이용해 내부 코드와 그 구조를 확인 1.2 동적 분석 파일을 직접 실행시켜서 그 행위를 분석하고, 디버깅]]></description><link>https://woojin-devv.github.io/posts/Cyber-Security-1/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Cyber-Security-1/</guid><pubDate>Fri, 03 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;1-리버싱-분석-방법&quot;&gt;1. 리버싱 분석 방법&lt;/h2&gt;
&lt;h3 id=&quot;11-정적-분석&quot;&gt;1.1 정적 분석&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파일의 겉모습을 분석하는 방법
&lt;ul&gt;
&lt;li&gt;파일을 실행하지 않음&lt;/li&gt;
&lt;li&gt;파일의 종류, 크기, 헤더, 정보, 디지털 인증서 등의 다양한 내용을 확인&lt;/li&gt;
&lt;li&gt;디스어셈블러를 이용해 내부 코드와 그 구조를 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;12-동적-분석&quot;&gt;1.2 동적 분석&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파일을 직접 실행시켜서 그 행위를 분석하고, 디버깅을 통해 코드 흐름과 메모리 상태를 자세히 살펴보는 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;2-리틀-엔디언-표기법&quot;&gt;2. 리틀 엔디언 표기법&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;컴퓨터에서 메모리에 데이터를 저장하는 방식을 의미 (바이트 오더링; Byte Ordering)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;21-바이트-오더링byte-ordering&quot;&gt;2.1 바이트 오더링(Byte Ordering)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;일련의 데이터를 저장하는 방식
&lt;ul&gt;
&lt;li&gt;바이트 오더링에는 **빅 엔디언(Big Endian)**과 **리틀 엔디언(Little Endian)**표기 두가지가 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;BYTE b = 0x12;
hr0RD w = 0xL234:&apos;
DTORD dt/ = 0x12345678;
char str[] = &quot;abcde&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;**빅 엔디언(Big Endian)**은 데이터를 저장할 때 사람이 보는 방식과 동일하게 앞에서부터 순차적으로 저장함
&lt;ul&gt;
&lt;li&gt;사람이 보기엔 직관적인 편&lt;/li&gt;
&lt;li&gt;사용예시
&lt;ul&gt;
&lt;li&gt;UNIX 서버에 사용되는 RISC 계열의 CPU에서 사용됨&lt;/li&gt;
&lt;li&gt;네트워크 프로토콜&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;**리틀 엔디언(Little Endian)**은 데이터를 저장할 때 역순으로 저장함
&lt;ul&gt;
&lt;li&gt;Intel x86 CPU에서 리틀 엔디언 방식을 사용함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;3-visual-studio-디버깅-방법&quot;&gt;3. Visual Studio 디버깅 방법&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cyber_security/vs_dbg1.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;의심 함수 앞에 breakpoint.&lt;/li&gt;
&lt;li&gt;변수 Watch에 추가.&lt;/li&gt;
&lt;li&gt;처음엔 Step Over로 큰 그림 파악.&lt;/li&gt;
&lt;li&gt;이상 징후가 보이는 호출 지점에서 Step Into.&lt;/li&gt;
&lt;li&gt;내부가 괜찮다? Step Out으로 상위로 복귀.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;nasm&quot;&gt;&lt;pre class=&quot;language-nasm&quot;&gt;&lt;code class=&quot;language-nasm&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;; --- C:\Users\최우진\source\repos\WEEK03\WEEK03\week03.cpp -------------------------&lt;/span&gt;

int main(void) {
004010A0 &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;                   push        &lt;span class=&quot;token register variable&quot;&gt;ebp&lt;/span&gt;
004010A1 8B EC                mov         &lt;span class=&quot;token register variable&quot;&gt;ebp&lt;/span&gt;,&lt;span class=&quot;token register variable&quot;&gt;esp&lt;/span&gt;
004010A3 &lt;span class=&quot;token number&quot;&gt;83&lt;/span&gt; EC 0C             sub         &lt;span class=&quot;token register variable&quot;&gt;esp&lt;/span&gt;,&lt;span class=&quot;token number&quot;&gt;0Ch&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;; int retval;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;; int a = 0x10;&lt;/span&gt;
004010A6 C7 &lt;span class=&quot;token number&quot;&gt;45&lt;/span&gt; F8 &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;00&lt;/span&gt; mov         dword ptr &lt;span class=&quot;token operator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token register variable&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;token number&quot;&gt;10h&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;; int b = 0x20;&lt;/span&gt;
004010AD C7 &lt;span class=&quot;token number&quot;&gt;45&lt;/span&gt; FC &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;00&lt;/span&gt; mov         dword ptr &lt;span class=&quot;token operator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token register variable&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;token number&quot;&gt;20h&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;; printf(&quot;Program Started!\n&quot;);&lt;/span&gt;
004010B4 &lt;span class=&quot;token number&quot;&gt;68&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;21&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;00&lt;/span&gt;       push        &lt;span class=&quot;token number&quot;&gt;402100h&lt;/span&gt;
004010B9 E8 &lt;span class=&quot;token number&quot;&gt;82&lt;/span&gt; FF FF FF       call        &lt;span class=&quot;token number&quot;&gt;00401040&lt;/span&gt;
004010BE &lt;span class=&quot;token number&quot;&gt;83&lt;/span&gt; C4 &lt;span class=&quot;token number&quot;&gt;04&lt;/span&gt;             add         &lt;span class=&quot;token register variable&quot;&gt;esp&lt;/span&gt;,&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;; retval = add(a, b);&lt;/span&gt;
004010C1 8B &lt;span class=&quot;token number&quot;&gt;45&lt;/span&gt; FC             mov         &lt;span class=&quot;token register variable&quot;&gt;eax&lt;/span&gt;,dword ptr &lt;span class=&quot;token operator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token register variable&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;]&lt;/span&gt;
004010C4 &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;                   push        &lt;span class=&quot;token register variable&quot;&gt;eax&lt;/span&gt;
004010C5 8B &lt;span class=&quot;token number&quot;&gt;4D&lt;/span&gt; F8             mov         &lt;span class=&quot;token register variable&quot;&gt;ecx&lt;/span&gt;,dword ptr &lt;span class=&quot;token operator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token register variable&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;]&lt;/span&gt;
004010C8 &lt;span class=&quot;token number&quot;&gt;51&lt;/span&gt;                   push        &lt;span class=&quot;token register variable&quot;&gt;ecx&lt;/span&gt;
004010C9 E8 B2 FF FF FF       call        &lt;span class=&quot;token number&quot;&gt;00401080&lt;/span&gt;
004010CE &lt;span class=&quot;token number&quot;&gt;83&lt;/span&gt; C4 &lt;span class=&quot;token number&quot;&gt;08&lt;/span&gt;             add         &lt;span class=&quot;token register variable&quot;&gt;esp&lt;/span&gt;,&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;
004010D1 &lt;span class=&quot;token number&quot;&gt;89&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;45&lt;/span&gt; F4             mov         dword ptr &lt;span class=&quot;token operator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token register variable&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0Ch&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;token register variable&quot;&gt;eax&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;; printf(&quot;%d\n&quot;, retval);&lt;/span&gt;
004010D4 8B &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt; F4             mov         &lt;span class=&quot;token register variable&quot;&gt;edx&lt;/span&gt;,dword ptr &lt;span class=&quot;token operator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token register variable&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0Ch&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;]&lt;/span&gt;
004010D7 &lt;span class=&quot;token number&quot;&gt;52&lt;/span&gt;                   push        &lt;span class=&quot;token register variable&quot;&gt;edx&lt;/span&gt;
004010D8 &lt;span class=&quot;token number&quot;&gt;68&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;21&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;00&lt;/span&gt;       push        &lt;span class=&quot;token number&quot;&gt;402114h&lt;/span&gt;
004010DD E8 5E FF FF FF       call        &lt;span class=&quot;token number&quot;&gt;00401040&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;004010E2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;83&lt;/span&gt; C4 &lt;span class=&quot;token number&quot;&gt;08&lt;/span&gt;             add         &lt;span class=&quot;token register variable&quot;&gt;esp&lt;/span&gt;,&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;; printf(&quot;End of Program! \n&quot;);&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;004010E5&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;68&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;18&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;21&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;00&lt;/span&gt;       push        &lt;span class=&quot;token number&quot;&gt;402118h&lt;/span&gt;
004010EA E8 &lt;span class=&quot;token number&quot;&gt;51&lt;/span&gt; FF FF FF       call        &lt;span class=&quot;token number&quot;&gt;00401040&lt;/span&gt;
004010EF &lt;span class=&quot;token number&quot;&gt;83&lt;/span&gt; C4 &lt;span class=&quot;token number&quot;&gt;04&lt;/span&gt;             add         &lt;span class=&quot;token register variable&quot;&gt;esp&lt;/span&gt;,&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;; return 0;&lt;/span&gt;
004010F2 &lt;span class=&quot;token number&quot;&gt;33&lt;/span&gt; C0                xor         &lt;span class=&quot;token register variable&quot;&gt;eax&lt;/span&gt;,&lt;span class=&quot;token register variable&quot;&gt;eax&lt;/span&gt;
}
004010F4 8B E5                mov         &lt;span class=&quot;token register variable&quot;&gt;esp&lt;/span&gt;,&lt;span class=&quot;token register variable&quot;&gt;ebp&lt;/span&gt;
004010F6 &lt;span class=&quot;token number&quot;&gt;5D&lt;/span&gt;                   pop         &lt;span class=&quot;token register variable&quot;&gt;ebp&lt;/span&gt;
004010F7 C3                   ret

&lt;span class=&quot;token comment&quot;&gt;; --- D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl --------&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;라인별-해설&quot;&gt;라인별 해설&lt;/h2&gt;
&lt;h3 id=&quot;함수-프롤로그--스택-프레임-생성&quot;&gt;함수 프롤로그 &amp;#x26; 스택 프레임 생성&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;nasm&quot;&gt;&lt;pre class=&quot;language-nasm&quot;&gt;&lt;code class=&quot;language-nasm&quot;&gt;004010A0 &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;                push &lt;span class=&quot;token register variable&quot;&gt;ebp&lt;/span&gt;          &lt;span class=&quot;token comment&quot;&gt;; 이전 프레임 포인터 저장&lt;/span&gt;
004010A1 8B EC             mov  &lt;span class=&quot;token register variable&quot;&gt;ebp&lt;/span&gt;, &lt;span class=&quot;token register variable&quot;&gt;esp&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;; ebp를 현재 스택 꼭대기로 설정&lt;/span&gt;
004010A3 &lt;span class=&quot;token number&quot;&gt;83&lt;/span&gt; EC 0C          sub  &lt;span class=&quot;token register variable&quot;&gt;esp&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;0Ch&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;; 지역변수 12바이트 확보&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;retval, a, b의 type이 int(4bytes) 3개 -&gt; 12바이트(0x0C) 공간 확보
&lt;ul&gt;
&lt;li&gt;stack은 &lt;strong&gt;높은 주소에서 낮은 주소 방향&lt;/strong&gt;으로 확장됨&lt;/li&gt;
&lt;li&gt;sub esp, 0Ch → esp = esp - 0Ch
&lt;ul&gt;
&lt;li&gt;esp는 스택 포인터&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;지역변수 배치
&lt;ul&gt;
&lt;li&gt;[ebp-8] = a&lt;/li&gt;
&lt;li&gt;[ebp-4] = b&lt;/li&gt;
&lt;li&gt;[ebp-0Ch] = retval&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;31-step-over--step-into-차이&quot;&gt;3.1 Step over &amp;#x26; Step Into 차이&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/cyber_security/x64dbg.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Step Over&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;현재 줄을 실행하되, 그 줄의 함수 안으로 들어가지 않음
&lt;ul&gt;
&lt;li&gt;결과만 받아서 다음 줄로 이동&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Step Into&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;현재 줄에서 호출한 함수의 &quot;첫 줄&quot;로 들어감
&lt;ul&gt;
&lt;li&gt;함수 내부 흐름을 한 줄씩 추적함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Operating System | Process]]></title><description><![CDATA[Chapter 3 프로세스 기술과 제어 3.1 프로세스란? 프로세스의 정의 수행중인 프로그램 컴퓨터 상에 수행 중인 프로그램의 인스턴스 처리기에 할당되어 수행될 수 있는 개체(entity) 명령들의 순차 수행, 현재 상태, 연계된 시스템 자원들의 집합 PCB(Process Control]]></description><link>https://woojin-devv.github.io/posts/process/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/process/</guid><pubDate>Sat, 27 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;chapter-3-프로세스-기술과-제어&quot;&gt;Chapter 3 프로세스 기술과 제어&lt;/h1&gt;
&lt;h2 id=&quot;31-프로세스란&quot;&gt;3.1 프로세스란?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;프로세스의 정의&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;수행중인 프로그램&lt;/li&gt;
&lt;li&gt;컴퓨터 상에 수행 중인 프로그램의 인스턴스&lt;/li&gt;
&lt;li&gt;처리기에 할당되어 수행될 수 있는 개체(entity)&lt;/li&gt;
&lt;li&gt;명령들의 순차 수행, 현재 상태, 연계된 시스템 자원들의 집합&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;PCB(Process Control Block)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Running 중인 Process를 interrupt한 이후에, 다시 Running을 재개할 수 있도록 충분한 정보를 유지해야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;PCB 블록의 구성요소&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;identifier&lt;/li&gt;
&lt;li&gt;status&lt;/li&gt;
&lt;li&gt;priority&lt;/li&gt;
&lt;li&gt;program counter&lt;/li&gt;
&lt;li&gt;context data&lt;/li&gt;
&lt;li&gt;I/O status information&lt;/li&gt;
&lt;li&gt;accounting information&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;32-프로세스-상태&quot;&gt;3.2 프로세스 상태&lt;/h2&gt;
&lt;h3 id=&quot;two-state-프로세스-모델&quot;&gt;two-state 프로세스 모델&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/os/two_state_process_model.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;작업 큐를 구성하는 각 요소는 특정 프로세스의 PCB를 가리키는 pointer이다.&lt;/li&gt;
&lt;li&gt;수행 중이 인터럽트를 당한 프로세스는 다시 큐로 옮겨진다.
&lt;ul&gt;
&lt;li&gt;만일 프로세스의 수행이 완료되었거나 도중에 취소된다면, 프로세스는 폐기된다. (Exit)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;five-state-프로세스-모델&quot;&gt;five-state 프로세스 모델&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/os/five_state_process_model.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;two-state 프로세스 모델에서는 실행 중인 프로세스에 인터럽트가 발생하면 Not Running 상태로 전환된다. 그런데 단일 큐(single queue)를 사용하는 경우, 디스패처가 어떤 프로세스를 우선 실행시킬지 판단하기가 까다로워진다.
&lt;ul&gt;
&lt;li&gt;이러한 상황을 보다 자연스럽게 처리하기 위해서는 Not Running 상태를 Ready와 Blocked 상태로 분할하는게 효과적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;suspended-state-프로세스-모델&quot;&gt;suspended-state 프로세스 모델&lt;/h3&gt;
&lt;h2 id=&quot;33-프로세스-기술-process-description&quot;&gt;3.3 프로세스 기술 (Process Description)&lt;/h2&gt;
&lt;h3 id=&quot;운영체제-제어구조&quot;&gt;&lt;strong&gt;운영체제 제어구조&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;운영체제가 프로세스와 자원들을 관리하기 위해서는 상태를 나타내는 정보를 가지고 있어야한다.
&lt;img src=&quot;/assets/img/os/os_control_tables.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;각 개체에 대한 정보를 테이블로 구성하여 유지한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;1-memory-tables&quot;&gt;1. Memory tables&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;주기억 장치와 보조기억장치 모두의 track을 유지하기 위해 사용&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;주기억장치의 일부는 운영체제가 사용할 수 있도록 예약됨&lt;/li&gt;
&lt;li&gt;예약되지 않은 나머지는 프로세스들이 사용할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;1-memory-tables이-가진-정보&quot;&gt;1. Memory tables이 가진 정보&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;프로세스에게 할당된 main memory&lt;/li&gt;
&lt;li&gt;프로세스에게 할당된 secondary memory
&lt;ul&gt;
&lt;li&gt;such as which processes may access certain shared memory regions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;주기억장치 또는 가상메모리 블록들에 대한 보호속성&lt;/li&gt;
&lt;li&gt;가상 메모리 관리를 위한 정보&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;2-io-tables&quot;&gt;2. I/O tables&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;입출력 장치와 컴퓨터 시스템의 채널들을 관리하기 위해 사용된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;입출력 테이블은 chapter 11에서 다룰 예정&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;3-file-tables&quot;&gt;3. file tables&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;파일 존재 여부와 secondary memory에 저장된 파일의 위치, 현재 상태등에 대한 정보 저장용&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;chapter 12에서 다룰 예정&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;34-프로세스-제어&quot;&gt;3.4 프로세스 제어&lt;/h2&gt;</content:encoded></item><item><title><![CDATA[Operating System | Computer System Overview | Interrupt]]></title><description><![CDATA[Interrupt란? Interrupt의 정의 CPU의 정상적인 흐름을 방해하는 동작을 말한다 → 대부분의 I/O 디바이스는 CPU보다 느림 CPU는 디바이스가 작업을 완료 할 때까지 기다려야 함 Blocking I/O의 문제점 Interrupt의 분류 CPU는 디바이스의 작업 완료를 ]]></description><link>https://woojin-devv.github.io/posts/Computer-System-Overview-Interrupt/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Computer-System-Overview-Interrupt/</guid><pubDate>Thu, 25 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;interrupt란&quot;&gt;&lt;strong&gt;Interrupt란?&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id=&quot;interrupt의-정의&quot;&gt;&lt;strong&gt;Interrupt의 정의&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;CPU의 정상적인 흐름을 방해하는 동작을 말한다&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;→ 대부분의 I/O 디바이스는 CPU보다 느림&lt;/p&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;CPU는 디바이스가 작업을 완료 할 때까지 기다려야 함&lt;/li&gt;
&lt;li&gt;Blocking I/O의 문제점&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;interrupt의-분류&quot;&gt;&lt;strong&gt;Interrupt의 분류&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;CPU는 디바이스의 작업 완료를 위해 기다릴 수 있음&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;→ 하지만 이는 처리기의 성능 저하 유발의 원인이 됨
→ 이를 위해 디바이스가 작업이 완료되면 CPU에게 인터럽트를 걸 수 있도록 허용함&lt;/p&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;프로그램
&lt;ul&gt;
&lt;li&gt;exception(응답없음) : 보통 프로세스 죽었을때&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;타이머&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I/O (주된 인터럽트)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;연산의 정상적인 종료&lt;/li&gt;
&lt;li&gt;다양한 에러조건을 알려줌&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;하드웨어 실패&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;interrupt의-단계&quot;&gt;&lt;strong&gt;Interrupt의 단계&lt;/strong&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;CPU가 인터럽트가 발생했는지 여부를 검사함&lt;/li&gt;
&lt;li&gt;인터럽트가 발생한 경우
&lt;ul&gt;
&lt;li&gt;프로그램의 실행을 보류&lt;/li&gt;
&lt;li&gt;인터럽트-처리 루틴 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;interrupt의-처리-루틴&quot;&gt;&lt;strong&gt;Interrupt의 처리 루틴&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;특정 I/O 디바이스를 서비스하기 위한 프로그램&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;일반적으로 운영체제 시스템에 포함됨&lt;/li&gt;
&lt;li&gt;인터럽트를 처리하기 위한 오버헤드 존재
&lt;ul&gt;
&lt;li&gt;입출력 연산이 완료되기를 기다리며 낭비하는 시간에 비해 상대적으로 짧음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;프로세스의 나머지 상태 정보를 저장&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;인터럽트 처리&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;프로세스의 상태 정보 복구&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;이전 PSW와 PC를 복구&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;interrupt의-종류&quot;&gt;&lt;strong&gt;Interrupt의 종류&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id=&quot;1-순차적-인터럽트-처리&quot;&gt;&lt;strong&gt;1. 순차적 인터럽트 처리&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;하나의 인터럽트가 처리 중에는 다른 인터럽트가 발생하더라도, 실행하지 않음&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;→ 상대적 우선순위 및 시간 긴급도를 고려하지 않음&lt;/p&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;2-다중-인터럽트&quot;&gt;&lt;strong&gt;2. 다중 인터럽트&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;인터럽트 간의 우선 순위를 지정함&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;CPU는 실행 가능한 하나 이상의 프로그램을 보유&lt;/li&gt;
&lt;li&gt;프로그램이 실행되는 순서는 프로그램의 상대적인 우선 순위와 입출력 대기 여부에 따라 달라짐&lt;/li&gt;
&lt;li&gt;인터럽트 처리 루틴이 실행을 마치면, 인터럽트가 발생한 당시에 수행 중이던 프로그램으로 돌아가지 않을 수 있음
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PC 복구 → 무조건 원래 프로그램 실행&lt;/strong&gt;되는 게 아니라, 운영체제가 개입해서 &lt;strong&gt;다른 프로그램(프로세스&lt;/strong&gt;을 실행할 수도 있음.&lt;/li&gt;
&lt;li&gt;예시 ) 타이머 인터럽트, I/O 완료 인터럽트&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Operating System | Computer System Overview]]></title><description><![CDATA[ch 1 학습목표 시스템의 기본 요소와 그 사이 관계 설명 프로세서에 의해 명령어가 수행 되는 처리 단계를 설명 인터럽트의 개념 이해 및 프로세서가 인터럽트를 사용하는 이유를 설명 컴퓨터 메모리 계층 구조 나열 및 설명층 구조 나열 멀티프로세서의 기본 특성과 멀티코어의 구조에 대해 설명]]></description><link>https://woojin-devv.github.io/posts/Computer-System-Overview/</link><guid isPermaLink="false">https://woojin-devv.github.io/posts/Computer-System-Overview/</guid><pubDate>Thu, 25 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;ch-1-학습목표&quot;&gt;ch 1 학습목표&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;시스템의 기본 요소와 그 사이 관계 설명&lt;/li&gt;
&lt;li&gt;프로세서에 의해 &lt;strong&gt;명령어가 수행&lt;/strong&gt;되는 처리 단계를 설명&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;인터럽트의 개념&lt;/strong&gt; 이해 및 프로세서가 인터럽트를 사용하는 이유를 설명&lt;/li&gt;
&lt;li&gt;컴퓨터 메모리 계층 구조 나열 및 설명층 구조 나열&lt;/li&gt;
&lt;li&gt;멀티프로세서의 기본 특성과 멀티코어의 구조에 대해 설명&lt;/li&gt;
&lt;li&gt;스택 연산과 프로시저 호출 및 리턴 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;11-컴퓨터-기본-구성-요소hw&quot;&gt;1.1 컴퓨터 기본 구성 요소(HW)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;처리기cpu-central-processing-unit&quot;&gt;&lt;strong&gt;처리기(CPU; Central Processing Unit)&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;컴퓨터의 두뇌: 데이터 연산, 논리 연산(ALU), 제어(control Unit)&lt;/li&gt;
&lt;li&gt;레지스터 (register)&lt;/li&gt;
&lt;li&gt;x86, ARM, PPC, Sparc, Alpha, MIPS, SH4, Xscale&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;주기억장치main-memory--휘발성volatile&quot;&gt;&lt;strong&gt;주기억장치(main memory) | 휘발성(volatile)&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;메모리 셀: 메모리 내의 개별적인 저장 공간&lt;/li&gt;
&lt;li&gt;데이터와 프로그램 저장 (실 메모리라고도 불림)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;저장-장치storage-device--비휘발성non-volatile&quot;&gt;&lt;strong&gt;저장 장치(storage device) | 비휘발성(non-volatile)&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;디스크, CD-ROM, 플로피, Flash Memory(NOR, NAND 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;입출력-장치&quot;&gt;&lt;strong&gt;입출력 장치&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;입력 장치: 키보드, 마우스, Key Pad, Touch Screen&lt;/li&gt;
&lt;li&gt;출력 장치: 모니터, 프린터, LCD&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;h3 id=&quot;통신-장치&quot;&gt;&lt;strong&gt;통신 장치&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;모뎀(modem), 이더넷(Ethernet), IrDA, CDMA, Bluetooth&lt;/li&gt;
&lt;li&gt;CPU의 비트 수가 커질수록 한 번에 전송 가능한 데이터의 양(버스 폭)이 커져 병렬 처리량이 많아진다&lt;/li&gt;
&lt;li&gt;시스템 전체 성능은 CPU, 메모리, I/O 장치 중 가장 느린 구성 요소의 영향을 크게 받는다&lt;/li&gt;
&lt;li&gt;CPU와 I/O 모듈은 시스템 버스를 통해 데이터를 교환하며, 필요에 따라 메모리 매핑 I/O나 DMA 방식이 활용된다&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;111-cpu-레지스터&quot;&gt;&lt;strong&gt;1.1.1 CPU 레지스터&lt;/strong&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;메모리 주소 레지스터 (MAR)
&lt;ol&gt;
&lt;li&gt;다음 번에 읽거나 쓸 주소를 명시&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;메모리 버퍼 레지스터 (MBR)
&lt;ol&gt;
&lt;li&gt;메모리에 쓸 데이터, 수신된 데이터 포함&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;I/O 주소 레지스터(I/O AR)&lt;/li&gt;
&lt;li&gt;I/O 버퍼 레지스터(I/O BR)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;112-마이크로-프로세서&quot;&gt;&lt;strong&gt;1.1.2 마이크로 프로세서&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;과거) 단일 칩에 하나의 프로세서를 직접 (CPU)
→ 하나의 칩에 코어라고 불리는 여러 개의 프로세서 포함&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;113-주요-처리기-레지스터-processor-registers&quot;&gt;1.1.3 주요 처리기 레지스터 (Processor Registers)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;CPU 내부에 있고, 프로그램 실행에 필요한 정보를 저장하는 레지스터이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;크게 두 그룹으로 나눌 수 있다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;제어 및 상태 레지스터 (Control and status registers)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;처리기의 작동을 제어하기 위해 사용&lt;/li&gt;
&lt;li&gt;프로그램의 실행을 제어하기 위한 특권 모드의 운영체제 루틴에 의해 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;strong&gt;종류&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Program Counter
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%EB%B0%98%EC%9E%85fetch-cpu%EA%B0%80-%EB%A9%94%EB%AA%A8%EB%A6%AC%EC%97%90%EC%84%9C-%EB%AA%85%EB%A0%B9%EC%96%B4%EB%A5%BC-%EC%9D%BD%EC%96%B4%EC%98%A4%EB%8A%94-%EA%B3%BC%EC%A0%95&quot;&gt;&lt;strong&gt;반입&lt;/strong&gt;*&lt;/a&gt;할 명령어의 주소 포함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Instruction Register
&lt;ul&gt;
&lt;li&gt;최근에 반입된 명령어 포함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Program Status Word (PSW)
&lt;ul&gt;
&lt;li&gt;interrupt enable / disable&lt;/li&gt;
&lt;li&gt;supervisor / user mode&lt;/li&gt;
&lt;li&gt;condition codes or flags
&lt;ul&gt;
&lt;li&gt;positive result, negative result, zero, overflow&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;114-명령어-실행-instruction-cycle&quot;&gt;1.1.4 명령어 실행 (instruction cycle)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;처리기가 메모리로부터 명령어를 읽거나(fetch) 수행(execution)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;fetch → execution → store → fetch (loop)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;CPU는 Main Memory로부터 Instruction을 Fetch 한다.&lt;/li&gt;
&lt;li&gt;Program Counter가 다음에 fetch할 명령어의 주소를 저장한다.&lt;/li&gt;
&lt;li&gt;fetch이후, Program Counter의 증가&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;115-instruction-register&quot;&gt;1.1.5 Instruction Register&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Fetched instruction은 IR에 적재된다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;범주
&lt;ul&gt;
&lt;li&gt;처리기 ~ 메모리
&lt;ul&gt;
&lt;li&gt;CPU와 메모리간 데이터 전달&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CPU ~ I/O
&lt;ul&gt;
&lt;li&gt;주변장치로 데이터 전달&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;데이터 처리
&lt;ul&gt;
&lt;li&gt;데이터 산술 또는 논리연산&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;제어
&lt;ul&gt;
&lt;li&gt;실행 순서의 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;116-instruction-register의-구조-가상&quot;&gt;1.1.6 Instruction Register의 구조 (가상)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;16bit라고 가정&lt;/li&gt;
&lt;li&gt;통상적으로 왼쪽을 상위 비트, 오른쪽을 하위 비트라고 한다.&lt;/li&gt;
&lt;li&gt;opcode(4bit) : 연산코드 → 연산자로 16개의 연산 가능
&lt;ul&gt;
&lt;li&gt;0001 = 메모리에 저장된 값을 &lt;a href=&quot;#%EB%88%84%EC%82%B0%EA%B8%B0accumulator-%EC%82%B0%EC%88%A0-%EB%85%BC%EB%A6%AC-%EC%97%B0%EC%82%B0%EC%9D%98-%EC%A4%91%EA%B0%84-%EA%B2%B0%EA%B3%BC%EA%B0%92%EC%9D%84-%EC%9E%84%EC%8B%9C%EB%A1%9C-%EC%A0%80%EC%9E%A5%ED%95%98%EB%8A%94-%EB%A0%88%EC%A7%80%EC%8A%A4%ED%84%B0%EB%A1%9C-%EA%B3%84%EC%82%B0-%EA%B3%BC%EC%A0%95%EC%97%90%EC%84%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A5%BC-%EB%88%84%EC%A0%81%ED%95%98%EA%B3%A0-%EC%B2%98%EB%A6%AC%ED%95%98%EB%8A%94-%EC%97%AD%ED%95%A0%EC%9D%84-%EB%8B%B4%EB%8B%B9%ED%95%9C%EB%8B%A4-cpu-%EB%82%B4%EB%B6%80%EC%97%90-%EC%9C%84%EC%B9%98%ED%95%98%EB%A9%B0-%EC%97%B0%EC%82%B0-%EC%86%8D%EB%8F%84%EB%A5%BC-%EB%86%92%EC%9D%B4%EA%B8%B0-%EC%9C%84%ED%95%B4-%EC%82%AC%EC%9A%A9%EB%90%9C%EB%8B%A4&quot;&gt;AC*&lt;/a&gt;에 적재&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;- 0010 = AC에 저장된 값을 메모리에 저장
- 0101 = 메모리에 저장된 값을 AC에 더함&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;address (12bit): 2^12 -1 = 4096 -1&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&quot;프로그램-실행-예시&quot;&gt;프로그램 실행 예시&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/assets/img/os/program_execution.png&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;1단계-fetch&quot;&gt;1단계 (fetch)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;PC에 저장된 값 = [300](다음에 실행할 명령어의 메모리주소 )&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MAR ← PC&lt;/strong&gt; : 300번지를 MAR에 적재&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;메모리[300] → MBR&lt;/strong&gt; : 300번지 메모리에서 명령어 0x1940을 읽어 MBR에 저장&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MBR → IR&lt;/strong&gt; : 명령어 0x1940을 IR에 저장&lt;/li&gt;
&lt;li&gt;PC++ : 다음 명령어(301번지)를 가리키도록 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;2단계-execution&quot;&gt;2단계 (execution)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;IR에 저장된 값 0x1940를 실행&lt;/li&gt;
&lt;li&gt;상위비트 0001(2), 하위비트 0x940
&lt;ul&gt;
&lt;li&gt;[940] 메모리에 저장된 값을 AC에 적재&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;[0 0 0 3] AC&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;3단계-fetch&quot;&gt;3단계 (fetch)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;PC에 저장된 값 = 다음에 실행할 명령어의 메모리주소 [301]&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;0x5941&lt;/code&gt;을 IR에 적재&lt;/li&gt;
&lt;li&gt;PC++&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;4단계-execution&quot;&gt;4단계 (execution)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;상위비트 0101(2), 하위비트 0x941
&lt;ul&gt;
&lt;li&gt;[941] 메모리에 저장된 값을 AC에 누적&lt;/li&gt;
&lt;li&gt;[0 0 0 3] + [0 0 0 2] = [0 0 0 5] AC&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;5단계-fetch&quot;&gt;5단계 (fetch)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;PC에 저장된 값 = 다음에 실행할 명령어의 메모리주소 [302]
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;0x2941&lt;/code&gt;을 IR에 적재&lt;/li&gt;
&lt;li&gt;PC++&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;6단계-execution&quot;&gt;6단계 (execution)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;상위비트 0010(2), 하위비트 0x941
[941] AC에 저장된 값을 메모리에 저장
941번지 &gt;&gt; [0 0 0 5]&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&quot;미주&quot;&gt;미주&lt;/h2&gt;
&lt;h3 id=&quot;반입fetch-cpu가-메모리에서-명령어를-읽어오는-과정&quot;&gt;&lt;strong&gt;반입(fetch)&lt;/strong&gt;: CPU가 &lt;strong&gt;메모리에서 명령어를 읽어오는 과정&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PC(Program Counter)&lt;/strong&gt; 에 저장된 값 = “다음에 실행할 명령어의 메모리 주소”&lt;/li&gt;
&lt;li&gt;이 주소가 &lt;strong&gt;MAR(Memory Address Register)&lt;/strong&gt; 로 전달됨&lt;/li&gt;
&lt;li&gt;해당 메모리에서 명령어를 읽어와서 &lt;strong&gt;MBR(Memory Buffer Register)&lt;/strong&gt; 에 저장&lt;/li&gt;
&lt;li&gt;그 명령어가 &lt;strong&gt;IR(Instruction Register)&lt;/strong&gt; 로 옮겨짐 → 해석/실행&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;누산기accumulator&quot;&gt;&lt;strong&gt;누산기(Accumulator)&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;산술 논리 연산의 중간 결과값을 임시로 저장하는 레지스터로, 계산 과정에서 데이터를 누적하고 처리하는 역할을 담당한다. CPU 내부에 위치하며 연산 속도를 높이기 위해 사용된다.&lt;/p&gt;</content:encoded></item></channel></rss>