<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>ky0_hw.log</title>
        <link>https://velog.io/</link>
        <description>https://fuzzy-hose-356.notion.site/1ee34212ee2d42bdbb3c4a258a672612</description>
        <lastBuildDate>Mon, 12 May 2025 07:41:31 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>ky0_hw.log</title>
            <url>https://velog.velcdn.com/images/ky0_hw/profile/69de21e0-1c89-4450-bc91-09ed818bc0fc/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. ky0_hw.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/ky0_hw" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Spring Batch] Quartz+Batch+OCR]]></title>
            <link>https://velog.io/@ky0_hw/Spring-Batch-QuartzBatchOCR</link>
            <guid>https://velog.io/@ky0_hw/Spring-Batch-QuartzBatchOCR</guid>
            <pubDate>Mon, 12 May 2025 07:41:31 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[[Spring] JUnit, Mock, Stub, 테스트 도구들]]></title>
            <link>https://velog.io/@ky0_hw/Spring-JUnit-Mock-Stub-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EB%8F%84%EA%B5%AC%EB%93%A4</link>
            <guid>https://velog.io/@ky0_hw/Spring-JUnit-Mock-Stub-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EB%8F%84%EA%B5%AC%EB%93%A4</guid>
            <pubDate>Mon, 07 Apr 2025 09:22:38 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="junit5란">JUnit5란?</h3>
<p>Java 애플리케이션을 테스트하기 위한 프레임워크</p>
</blockquote>
<h4 id="junit5의-구성">JUnit5의 구성</h4>
<p><strong>JUnit Platform</strong> : 테스트를 실행해주는 엔진
<strong>JUnit Jupiter</strong> : 우리가 직접 쓰는 어노테이션(@Test, @BeforeEach)과 API가 들어있어
<strong>JUnit Vintage</strong> : 예전 JUnit4 코드도 호환할 수 있게 해주는 모듈</p>
<h4 id="자주-사용하는-어노테이션">자주 사용하는 어노테이션</h4>
<p><strong>@Test</strong> : 테스트 메서드임을 표시
<strong>@BeforeEach</strong>: 각 테스트 전에 실행되는 코드
<strong>@AfterEach</strong> : 각 테스트 후에 실행되는 코드
<strong>@BeforeAll</strong> : 모든 테스트 전에 딱 한 번 실행됨 (static이어야 함)
<strong>@AfterAll</strong> : 모든 테스트 후에 딱 한 번 실행됨 (static이어야 함)</p>
<blockquote>
<h3 id="junit과-함께-사용하는-테스트-도구들">JUnit과 함께 사용하는 테스트 도구들</h3>
</blockquote>
<h4 id="1-springboottest">1. @SpringBootTest</h4>
<p>Spring 전체 컨텍스트를 로딩해서 테스트함 (진짜 어플리케이션 실행하듯)
@Autowired 등 다 잘 작동함
무거운 테스트라서 느릴 수 있음</p>
<h4 id="2-transactional">2. @Transactional</h4>
<p>테스트 안에서 DB에 insert/update/delete 한 거를 테스트 끝나면 자동 롤백해줌
실제 DB를 건드리면서 테스트할 때 매우 유용함</p>
<h4 id="3-webmvctest">3. @WebMvcTest</h4>
<p>컨트롤러만 테스트할 때 사용
컨트롤러 외의 빈들은 자동으로 mock 처리됨
실제 서비스나 리포지토리를 사용하려면 @MockBean으로 추가해야 함</p>
<blockquote>
<h3 id="mock이란">Mock이란?</h3>
<p>실제 객체를 대신해주는 테스트용 객체를 생성해 줄 때, mock을 사용</p>
</blockquote>
<h4 id="mockito란">Mockito란?</h4>
<p>자바에서 Mock 객체를 쉽게 만들고, 동작을 지정하고, 검증할 수 있게 해주는 테스트 전용 라이브러리
서비스 → 리포지토리, 컨트롤러 → 서비스 등 <strong>하위 계층을 직접 실행하지 않고, 흉내만 낼 때</strong> 사용
클래스에 <strong>@ExtendWith(MockitoExtension.class)</strong>를 붙여 @Mock 어노테이션 사용 가능</p>
<h4 id="mock-애노테이션">@Mock 애노테이션</h4>
<p>Mockito.mock() 메서드의 축약어, 테스트 클래스에서만 사용 가능
<strong>단위 테스트에서 사용되며, Mock 객체를 직접 생성하므로 Spring Context와 관련이 없다.</strong></p>
<h4 id="mockbean-애노테이션">@MockBean 애노테이션</h4>
<p><strong>통합 테스트에서 사용되며, Spring Context에 Mock객체를 직접 생성한다</strong>
@WebMvcTest와 함께 자주 사용한다.</p>
<h4 id="injectmocks">@InjectMocks</h4>
<p>Mocking된 객체를 자동으로 주입해주는 애노테이션. 테스트하려는 객체(예: 서비스 클래스)에서 필요로 하는 의존성 필드들을 자동으로 주입해 준다.</p>
<blockquote>
<h3 id="stub이란">Stub이란?</h3>
<pre><code>특정 동작을 미리 정의해둔 Mock</code></pre></blockquote>
<h4 id="쓰이는-메소드들">쓰이는 메소드들</h4>
<pre><code>when(userService.getName(1L)).thenReturn(&quot;철수&quot;);
when(orderService.placeOrder(any())).thenThrow(new RuntimeException(&quot;실패&quot;));
doReturn(100).when(mathService).add(50, 50);
when(userService.getGreeting(anyString()))
    .thenAnswer(invocation -&gt; &quot;Hello, &quot; + invocation.getArgument(0));</code></pre><p>thenAnswer은 동적으로 결과를 튜닝할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Redis] Sentinel/Cluster, ElastiCache/Local]]></title>
            <link>https://velog.io/@ky0_hw/j8wi9vu1</link>
            <guid>https://velog.io/@ky0_hw/j8wi9vu1</guid>
            <pubDate>Fri, 04 Apr 2025 00:55:46 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="1-sentinel-vs-cluster-요약">1. Sentinel vs Cluster 요약</h3>
<p><img src="https://velog.velcdn.com/images/ky0_hw/post/b93412d6-5380-463c-99be-266e5fe6e6a9/image.png" alt=""></p>
</blockquote>
<h4 id="sentinel이란--고가용성">Sentinel이란? : <strong>고가용성</strong></h4>
<p>Mater와 Slave를 감시하고 있다가 Master가 다운되면 이를 감지해서 <strong>관리자의 개입 없이 자동으로 Slave를 Master로 올려주는 기법</strong>
<img src="https://velog.velcdn.com/images/ky0_hw/post/bceddd0c-4300-42f2-a31b-82771848ee4e/image.jpg" alt="">
3개 이상의 Sentinel Node가 홀수개 존재해야 하며, 과반수가 Master Node에 장애가 있다고 판단할 시 Slave중 한개를 Master로 승격시킨다.</p>
<h4 id="cluster란--확장성">Cluster란? : <strong>확장성</strong></h4>
<p><img src="https://velog.velcdn.com/images/ky0_hw/post/97cf99a9-4e0e-4e1d-8b16-c395cc441431/image.png" alt="">
출처. <a href="https://rhgustmfrh.tistory.com/123">https://rhgustmfrh.tistory.com/123</a>
데이터를 다중 노드에 분산하여 저장하고, 각 슬롯에 장애 발생시 failover 진행
<strong>gossip</strong> : 분산 시스템에서 노드 간 정보를 교환하는 방식 중 하나로, 각 노드가 다른 노드들과 주기적으로 정보를 공유하여 네트워크 전체에 데이터를 전파하는 방식
gossip 프로토콜을 사용함으로써 <strong>노드 상태를 전파하고 장애 감지 및 복구를 자동화</strong>한다.</p>
<blockquote>
<h3 id="2-sentinel기준-ec2-운용법">2. (Sentinel기준) EC2 운용법</h3>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DX INSIGHT] 7. SECURITY, ERP]]></title>
            <link>https://velog.io/@ky0_hw/DX-INSIGHT-7.-SECURITY-ERP</link>
            <guid>https://velog.io/@ky0_hw/DX-INSIGHT-7.-SECURITY-ERP</guid>
            <pubDate>Mon, 10 Mar 2025 05:07:41 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="ch7-security">CH7. SECURITY</h3>
</blockquote>
<h4 id="section1-개요">Section1. 개요</h4>
<p><strong>정보보호</strong> : 정보 자산의 기밀성, 무결성, 가용성 유지하고 위협으로부터 보호하는 체계
<strong>기밀성</strong> : 인가된 사용자에게만 접근을 허용함
<strong>무결성</strong> : 데이터가 변조되거나 손상되지 않도록 보장하여 신뢰상태 유지
<strong>가용성</strong> : 시스템이 서비스를 정상적으로 제공할 수 있는 상태</p>
<h4 id="section2-웹보안시큐어-코딩">Section2. 웹보안/시큐어 코딩</h4>
<p><strong>XSS</strong> : 웹사이트에 악성 스크립트 코드 주입
<strong>SQL 인젝션</strong> : DB를 조작하거나 데이터를 탈취</p>
<h4 id="section3-erp">Section3. ERP</h4>
<p><strong>ERP(Enterprise Resource Planning)</strong> : 전사적 자원 관리
<strong>ERP 주요 5개 모듈</strong>
<strong>MM (Material Management)</strong> : 자재 관리 
<strong>PP (Production Planning)</strong> : 생산 관리
<strong>SD (Sales &amp; Distribution)</strong> : 영업 유통
<strong>FI (Finantial)</strong> : 재무 회계
<strong>CO (Controlling)</strong> : 관리 회계
<strong>SCM</strong> : MM + PP + SD
<strong>FCM</strong> : FI + CO</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DX INSIGHT] 6. 품질관리]]></title>
            <link>https://velog.io/@ky0_hw/DX-INSIGHT-6.-%ED%92%88%EC%A7%88%EA%B4%80%EB%A6%AC</link>
            <guid>https://velog.io/@ky0_hw/DX-INSIGHT-6.-%ED%92%88%EC%A7%88%EA%B4%80%EB%A6%AC</guid>
            <pubDate>Sun, 09 Mar 2025 14:07:51 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="ch6-품질관리">CH6. 품질관리</h3>
</blockquote>
<h4 id="section1-프로젝트-품질-관리">Section1. 프로젝트 품질 관리</h4>
<p><strong>프로젝트 수주 단계</strong> : CJ VRB (수주가치평가)
<strong>프로젝트 전반의 문제 관리</strong> : CJ CJ PRM (프로젝트 문제 관리)
<strong>프로젝트 환경</strong> : CJ PM 착수 가이드</p>
<h4 id="section2-cj-vrb">Section2. CJ VRB</h4>
<p>프로젝트 사전준비단계부터 Value, Risk 분석하여 요구사항에 최적화된 제안 제시
<strong>순서</strong> : 검색 -&gt; 정의 -&gt; 확인 -&gt; 계약
<strong>WBS</strong>기반의 예산 코드를 통해 손익관리</p>
<h4 id="section3-cj-prm">Section3. CJ PRM</h4>
<p>프로젝트 전체 과정에서 도출된 위험요소를 대장에 등록하고 관리, 해결하는 프로세스</p>
<h4 id="section4-프로젝트-swat">Section4. 프로젝트 SWAT</h4>
<p>프로젝트 등 주요 기술 이슈에 대응하는 조직
조치 결과를 보고하고, 분석 결과를 보고한다.</p>
<h4 id="section5-cj-pm-착수-가이드">Section5. CJ PM 착수 가이드</h4>
<p>착수/계획, 실행/통제, 종료 3단계로 프로젝트를 나누고, 상세 가이드를 PM에게 전달</p>
<h4 id="section6-운영품질관리itsm">Section6. 운영품질관리(ITSM)</h4>
<p><strong>ITIL</strong> : IT 서비스 관리 우수 사례 모음
<strong>ITSM</strong> : ITIL을 상세화하여 정책과 프로세스로 관리하는 방법론</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DX INSIGHT] 5. DATABASE]]></title>
            <link>https://velog.io/@ky0_hw/DX-INSIGHT-5.-DATABASE</link>
            <guid>https://velog.io/@ky0_hw/DX-INSIGHT-5.-DATABASE</guid>
            <pubDate>Sun, 09 Mar 2025 13:34:36 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="ch5-database">CH5. DATABASE</h3>
</blockquote>
<h4 id="section1-개요">Section1. 개요</h4>
<p><strong>데이터베이스</strong> : 구조화된 데이터를 저장하고 관리하는 시스템, 데이터를 테이블로 구조화하고 효율적으로 관리
<strong>저장되는 데이터 특징</strong> : 공용 데이터, 저장된 데이터, 통합된 데이터, 운영 데이터
<strong>DB 기능적 특징</strong> : 실시간 접근성, 지속적인 변화, 동시 공용, 내용 참조</p>
<h4 id="section2-dbms-종류">Section2. DBMS 종류</h4>
<p><strong>DBMS</strong> : 데이터베이스 관리 시스템
<strong>계층형(Hierarchical) DBMS ** : 데이터가 계층 구조를 이루며, DB 최상위 계층의 데이터부터 검색하는 트리 구조, **데이터 접근 속도가 빠르지만, 초기 세팅 후 변화가 어려움</strong>
<strong>망형(Network) DBMS</strong> : 계층 구조를 극복하기 위해 데이터 구조를 <strong>네트워크상의 노드 형태</strong>로 표현한 데이터 모델, <strong>각 노드가 대등한 관계</strong>
<strong>관계형(Relational) DBMS</strong> : 데이터를 <strong>테이블 형태</strong>로 구성, 각 테이블간의 상관관계를 정의
<strong>NO SQL</strong> : 고정된 스키마가 없거나 유연한 스키마 구조, <strong>수평적 확장과 스키마 변경이 용이</strong>하며, <strong>대규모 데이터 처리, 분산 환경</strong>에 유리. <strong>단점은 데이터 일관성과 무결성 보장 X</strong></p>
<h4 id="section3-1-상용-rdbms-비교">Section3-1. 상용 RDBMS 비교</h4>
<p><strong>오라클</strong></p>
<ol>
<li>비싸고 수평 및 수직확장 가능</li>
<li>모든 운영체제 호환</li>
</ol>
<p><strong>SQL Server</strong></p>
<ol>
<li>오라클보다 저렴하지만 수직 확장만 가능</li>
<li>윈도우 환경에 최적화<h4 id="section3-2-오픈소스-rdbms-비교">Section3-2. 오픈소스 RDBMS 비교</h4>
</li>
</ol>
<p><strong>MySQL</strong></p>
<ol>
<li>관계형 DBMS</li>
<li>기능이 제한적이며 데이터는 JSON 형식 사용</li>
<li>일부 엔진만 ACID 원칙 준수</li>
<li>트리 구조로 인덱싱 지원하여 읽기 작업에 유리</li>
</ol>
<p><strong>PostgreSQL</strong></p>
<ol>
<li>객체 관계형 DBMS</li>
<li>고급 기능을 여러 언어로 지원하며 XML 및 모든 MySQL 데이터 형식 지원</li>
<li>전부 ACID 원칙 준수</li>
<li>트리 외에도 해시 인덱싱 지원하여 쓰기 작업에 유리<h4 id="section3-3-nosql-rdbms-비교">Section3-3. NoSQL RDBMS 비교</h4>
</li>
</ol>
<p><strong>Mongo DB</strong></p>
<ol>
<li>Document 타입 DB</li>
<li>JSON 지원</li>
<li>고가용성, 자동 샤딩, 유연한 스키마 설계</li>
</ol>
<p><strong>Redis</strong></p>
<ol>
<li>Key-Value 타입 DB</li>
<li>문자열, 해시, Set 지원</li>
<li>인메모리 DB, 속도 매우 빠름, Pub/Sub 메시징, 트랜잭션<h4 id="section4-데이터-모델링">Section4. 데이터 모델링</h4>
</li>
</ol>
<p><strong>데이터 모델링</strong> : 데이터를 구조화하여 논리적으로 설계하는 과정으로, 데이터의 관계, 속성, 흐름을 시각적으로 표현하는 작업
<strong>장점</strong> : 개발 오류 감소, DB설계 효율성 증가, 시스템 일관성 유지, 커뮤니케이션 효율성
<strong>개념적 데이터 모델</strong> : DB 설계중 가장 먼저 <strong>개체관계 다이어그램(ERD)</strong>로 데이터의 주요 개념과 관계를 정의하는 모델
<strong>논리적 데이터 모델</strong> : 개념적 데이터 모델을 기반으로 DB를 실제 구현할 때 사용되는 구체적 데이터 구조. 따라서 <strong>DBMS에 종속적</strong>
<strong>물리적 데이터 모델</strong> : 논리적 데이터 모델을 구체적인 DBMS로 변환한 모델</p>
<h4 id="section5-sql-소개">Section5. SQL 소개</h4>
<p><strong>SQL</strong> : 관계형DB에서 데이터를 관리하고 조작하기 위해 사용되는 표준 언어
<strong>DML(데이터 조작어)</strong> : 데이터 관련 select, insert ...
<strong>DDL(데이터 정의어)</strong> : 데이터 구조 관련 create, alter ...
<strong>DCL(데이터 제어어)</strong> : DB 권한 관련 grant, revoke ...
<strong>TCL(트랜잭션 제어어)</strong> : 논리적 작업 단위 관련 commit, rollback...
<strong>SQL 실행 순서</strong></p>
<ol>
<li>FROM 테이블명</li>
<li>WHERE 조건식</li>
<li>GROUP BY 컬럼/표현식</li>
<li>HAVING 그룹조건식</li>
<li>SELECT 컬럼명</li>
<li>ORDER BY 컬럼/표현식</li>
</ol>
<p><strong>JOIN</strong> : 두개 이상의 테이블을 연결하여 데이터 결합
<strong>Inner Join</strong> : 두 테이블간 일치하는 행만 선택
<strong>Left/Right Outer Join</strong> : 왼쪽/오른쪽 테이블의 모든 행 선택, 반대쪽 테이블과 일치하는 행만 선택
<strong>Full Outer Join</strong> : 양쪽 모든 행 선택 후, 반대쪽에 없는 값은 NULL로 표현
<strong>INDEX</strong> : DB에서 검색 속도 향상을 위해 사용하는 데이터 구조, 검색이 잦은 특정 컬럼으로 정렬한 데이터 집합
<strong>INDEX 장단점</strong> : 검색 속도가 빨라지지만, 추가적인 저장 공간 필요 및 데이터 삽입/수정에 오버헤드 발생</p>
<h4 id="section6-데이터베이스-백업">Section6. 데이터베이스 백업</h4>
<p><strong>전체 백업</strong> : 단순하지만 사이즈가 크고 오래걸림
<strong>차등 백업</strong> : 마지막 전체 백업 이후 변경사항들만 백업
<strong>증분 백업</strong> : 아무거나 마지막 백업 이후 변경사항들 백업
<strong>RTO</strong> : 장애 후 복구되어 정상적으로 운영될 때까지 걸리는 최대 허용시간
<strong>RPO</strong> : 데이터 복구 시점과 사고 발생 시점 간의 최대 허용시간. EX) RPO가 30분이면, 장애 발생 시점으로부터 30분 이전까지의 데이터는 복구해야 함</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DX INSIGHT] 4. CLOUD]]></title>
            <link>https://velog.io/@ky0_hw/DX-INSIGHT-4.-CLOUD</link>
            <guid>https://velog.io/@ky0_hw/DX-INSIGHT-4.-CLOUD</guid>
            <pubDate>Sun, 09 Mar 2025 09:00:47 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="ch4-cloud">Ch4. CLOUD</h3>
</blockquote>
<h4 id="section1-개요">Section1. 개요</h4>
<p><strong>클라우드 컴퓨팅</strong> : 인터넷을 통해 컴퓨터 시스템 및 리소스에 대한 접근을 제공하는 기술
<strong>장점</strong> : 유연성, 확장성, 초기 비용 효율성, 접근성
<strong>단점</strong> : 보안, 의존성, 이관 비용
<strong>CSP(클라우드 서비스 제공업체)</strong> : 국가별로 구분된 데이터 센터인 <strong>리전</strong> 서비스 제공, 각 리전마다 하나 이상의 데이터 센터로 구성된 <strong>가용영역</strong> 서비스 제공
<strong>클라우드 네이티브</strong> : 애플리케이션 서비스를 <strong>클라우드 환경의 장점을 적극 활용</strong>해 개발하고 운영하는 방식, MSA/컨테이너화/자동화 등으로 클라우드 이점을 활용해야 한다.</p>
<h4 id="section2-클라우드-서비스-유형">Section2. 클라우드 서비스 유형</h4>
<p><strong>범위</strong> : SAAS &gt; PAAS &gt; IAAS
<strong>SAAS (Software-As-A-Service)</strong> : 인터넷을 통해 소프트웨어 제공 (Gmail, Dropbox, Microsoft 365)<br><strong>PAAS (Platform-As-A-Service)</strong> : 개발자가 앱을 배포할 수 있는 플랫폼 제공 (AWS Elastic Beanstalk, Heroku)
<strong>IAAS (Infrastructure-As-A-Service)</strong> : 서버, 네트워크, 스토리지 등 IT 인프라 제공    (AWS EC2, GCP Compute Engine)
<strong>FAAS (Function-As-A-Service)</strong> : 서버리스 방식으로 함수 단위 실행 (AWS Lambda, Google Cloud Functions)</p>
<h4 id="section3-클라우드-서비스-제공-형태">Section3. 클라우드 서비스 제공 형태</h4>
<p><strong>퍼블릭 클라우드</strong> : 여러 사용자가 공유하는 클라우드 인프라, 서비스 제공 업체가 인터넷을 통해 제공 (AWS, Azure, GCP)
<strong>프라이빗 클라우드</strong> : 단일 기관이 사용하는 클라우드 인프라, 해당 기관이나 조직 내부 데이터센터에 구축
<strong>하이브리드 클라우드</strong> : 프라이빗과 퍼블릭 클라우드를 결합하여 사용, 전용선 또는 VPN으로 퍼블릭 클라우드와 프라이빗 클라우드를 연결해 사용한다.
<strong>멀티 클라우드</strong> : 기업이나 조직이 2개 이상의 클라우드 서비스 제공 업체를 사용하는 것</p>
<h4 id="section4-클라우드-msp">Section4. 클라우드 MSP</h4>
<p><strong>MSP(클라우드 관리 서비스 제공업체)</strong> : 고객이 인프라 시스템을 효과적으로 관리하고 유지할 수 있도록 컨설팅, 인프라구축, 클라우드 운영 서비스를 제공하는 업체
<strong>제공 기능</strong> : 클라우드 컨설팅(아키텍처 설계), 클라우드 구축(인프라 구축, 마이그레이션), 클라우드 운영(통합 운영 관리, 모니터링)</p>
<h4 id="section5-클라우드-마이그레이션">Section5. 클라우드 마이그레이션</h4>
<p><strong>클라우드 마이그레이션</strong> : 온프레미스-&gt;클라우드로 데이터, 애플리케이션, IT 리소스와 같은 디지털 자산을 이전하는 프로세스
<strong>사용 이유</strong> : 초기 투자 및 관리 비용 절감, 비즈니스 유연성, 클라우드를 활용한 서비스 개선
<strong>순서</strong> : 평가 및 계획 -&gt; 준비 -&gt; 데이터 이전 -&gt; 테스트 및 검증 -&gt; 전환</p>
<h4 id="section6-cmp">Section6. CMP</h4>
<p><strong>CMP</strong> : 다양한 클라우드 환경을 통합하고 관리할 수 있는 플랫폼
<strong>기능</strong> : 
✅ 셀프 서비스 인터페이스 (Self-Service Interface)
👉 사용자가 직접 클라우드 자원을 생성, 관리할 수 있는 웹 포털 또는 API 기반 대시보드
✅ 자원 프로비저닝 (Resource Provisioning)
👉 필요할 때 자동 또는 수동으로 컴퓨팅, 스토리지, 네트워크 등의 클라우드 자원을 할당하는 과정
✅ 미터링 (Metering)
👉 클라우드 리소스 사용량을 측정하고 기록하여 과금 및 최적화를 위한 데이터 제공
✅ 빌링 (Billing)
👉 클라우드 사용량을 기반으로 비용을 계산하고 청구하는 시스템
✅ 워크로드 최적화 (Workload Optimization)
👉 애플리케이션의 성능을 유지하면서 비용을 최소화할 수 있도록 리소스를 자동 조정하는 프로세스</p>
<h4 id="section7-cmp-vs-msp">Section7. CMP vs MSP</h4>
<p><strong>CMP (Cloud Management Platform):</strong>
클라우드 자원을 효율적으로 관리하는 자동화된 플랫폼
기업이 직접 클라우드를 운영하면서 비용 절감, 모니터링, 자동화를 수행할 수 있도록 지원
<strong>MSP (Managed Service Provider):</strong>
클라우드 운영을 대신 관리해주는 서비스 제공업체
기업이 직접 클라우드를 운영하는 대신, MSP가 인프라 관리, 보안, 유지보수 등을 대행</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DX INSIGHT] 3. NETWORK]]></title>
            <link>https://velog.io/@ky0_hw/DX-INSIGHT-3.-NETWORK</link>
            <guid>https://velog.io/@ky0_hw/DX-INSIGHT-3.-NETWORK</guid>
            <pubDate>Sun, 09 Mar 2025 08:10:11 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="ch3-network">CH3. NETWORK</h3>
</blockquote>
<h4 id="section1-개요">Section1. 개요</h4>
<p><strong>컴퓨터 네트워크</strong> : 컴퓨터 간에 정보 또는 데이터를 전달하기 위해 컴퓨터를 연결한 것
<strong>LAN</strong> : 근거리 통신망
<strong>WAN</strong> : 거리 제한이 없는 원거리 통신망</p>
<h4 id="section2-라우터와-스위치">Section2. 라우터와 스위치</h4>
<p><strong>라우터</strong> : 네트워크에서 목적지로 가는 경로를 찾아주는 장치, 네트워크 계층에 속하며, <strong>IP 주소</strong>를 기반으로 디바이스 위치를 파악하고 통신한다.
<strong>스위치</strong> : 소규모 네트워크에서 컴퓨터, 프린터 등의 디바이스들을 서로 연결해주어 리소스 공유를 가능하게 함, 데이터링크 계층에 속하며 <strong>MAC주소</strong>로 통신한다.
<strong>라우터 특징</strong></p>
<ol>
<li>2개의 LAN, 혹은 WAN같은 네트워크를 연결</li>
<li>물리적 계층, 데이터 링크 계층 및 네트워크 계층에서 작동</li>
<li>주요 목적은 패킷이 대상에 도달할 수 있는 최단경로를 결정하는 것</li>
</ol>
<p><strong>스위치 특징</strong></p>
<ol>
<li>여러 장치를 연결하여 네트워크를 형성</li>
<li>데이터 링크 계층 및 네트워크 계층에서 작동</li>
<li>패킷을 수신하고 처리하여 목적지 주소를 결정하여 패킷 전달<h4 id="section3-데이터-통신">Section3. 데이터 통신</h4>
</li>
</ol>
<p><strong>OSI 7계층</strong> : 패킷(<strong>응용, 표현, 세션</strong>), 세그먼트(<strong>전송</strong>), 패킷(<strong>네트워크</strong>), 프레임(<strong>데이터링크</strong>), 비트(<strong>물리</strong>)
<strong>캡슐화</strong> : 물리 -&gt; 응용
<strong>역캡슐화</strong> : 응용 -&gt; 물리
<strong>응용(Application), L7</strong> : HTTP, SMTP 프로토콜로 사용자에게 서비스 제공
<strong>표현(Presentation)</strong> : 데이터 압축, 암호화, 복호화
<strong>세션(Session)</strong> : 시스템 간의 동기화와 데이터 교환 관리
<strong>전송(Transport)</strong> : TCP, UDP 프로토콜로 프로세스간 통신(포트 번호 이용)
<strong>네트워크(Network)</strong> : IP, ICMP 프로토콜 활용해 IP주소로 원거리 통신
<strong>데이터링크(DataLink)</strong> : MAC주소를 통해 로컬 통신
<strong>물리(Physical), L1</strong> : LAN, 동축케이블로 물리적인 통신</p>
<h4 id="section4-ip-서브넷-마스크">Section4. IP, 서브넷 마스크</h4>
<p><strong>IP 주소</strong> : 네트워크에 연결된 호스트들을 구분
<strong>서브넷 마스크</strong> : 주소의 네트워크 부분과 호스트 부분을 구분
<strong>Octet</strong> : IP주소를 구성하는 32비트중 8개의 비트를 가리티는 단위, 1번째 Octet은 IP주소의 Class를 나타냄
<strong>네트워크 주소, 브로드캐스트 주소</strong> : 호스트의 첫번째 주소와 마지막 주소로 할당되므로 모든 네트워크에서 사용할 수 있는 호스트는 2개씩 제외해야함
<strong>서브넷팅</strong> : 네트워크를 효율적으로 사용하기 위해 작은 네트워크로 분할하는 것</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DX INSIGHT] 2. INFRA]]></title>
            <link>https://velog.io/@ky0_hw/DX-INSIGHT-2.-INFRA</link>
            <guid>https://velog.io/@ky0_hw/DX-INSIGHT-2.-INFRA</guid>
            <pubDate>Sun, 09 Mar 2025 07:40:48 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="ch2-infra">CH2. INFRA</h3>
</blockquote>
<h4 id="section1-서버">Section1. 서버</h4>
<p><strong>서버</strong> : 다른 컴퓨터나 장치에 서비스를 제공하고, 데이터를 저장하거나 처리
<strong>PC</strong> : 개인 사용을 목적으로 다양한 일반적인 작업 수행
<strong>서버 작동 방식</strong> : 다수의 클라이언트로부터 요청을 받고 응답하는 데 중점
<strong>물리 서버</strong> : 물리적 자원을 독립적으로 사용하면서 다른 서버에 공유할 수 없다.
<strong>가상화 서버</strong> : 가상화 기술로 복수의 개별 서버를 사용</p>
<h4 id="section2-스토리지">Section2. 스토리지</h4>
<p><strong>휘발성 메모리(RAM)</strong> : 데이터를 실시간으로 처리하지만 휘발성
<strong>비휘발성 스토리지(Storage)</strong> : 전원이 꺼져도 데이터를 유지하고 보존
데이터는 HDD,SSD,테이프같은 스토리지에 저장
<strong>DAS</strong> : 컴퓨터나 서버에 직접 연결되는 스토리지 시스템, USB, SATA같은 외장 하드 드라이브나 내장 하드 드라이브
<strong>NAS</strong> : 네트워크에 연결되어 파일 공유와 데이터 스토리지 서비스 제공
<strong>SAN</strong> : 고성능 스토리지를 여러 컴퓨터나 서버에 연결하는 전용 네트워크, 대규모 DB 및 애플리케이션에 적합</p>
<h4 id="section3-os">Section3. OS</h4>
<p><strong>운영체제(OS)</strong> : 컴퓨터 시스템에서 하드웨어와 응용 소프트웨어간의 상호작용을 관리하고 제어하는 소프트웨어
<strong>주요 기능</strong> : 자원 관리, 작업 스케줄링, 파일 시스템 관리, 입출력 관리, 사용자 인터페이스
<strong>종류</strong> : <strong>WINDOWS</strong>, <strong>LINUX</strong>(오픈소스), <strong>UNIX</strong>(일부 상업용)</p>
<h4 id="section4-이중화와-고가용성">Section4. 이중화와 고가용성</h4>
<p><strong>NIC 이중화</strong> : 연결의 중단을 방지하기 위해 두개의 네트워크 인터페이스 카드(NIC) 사용
<strong>HBA 이중화</strong> : 스토리지 연결의 가용성을 향상시키고자 두개의 호스트 버스 어댑터(HBA) 사용
<strong>서버 이중화</strong> : 시스템의 가용성과 신뢰성을 높이고자 두개의 서버를 병렬 운영
<strong>고가용성(HA)</strong> : 시스템이 지속적으로 가용하고 신뢰성 있게 동작하는 능력
<strong>장애 허용 클러스터링</strong> : 여러대의 서버를 클러스터로 구성하여 장애 극복을 목표
<strong>LB, 스케일 아웃</strong> : 트래픽 처리 목표, 시스템 확장 가능</p>
<h4 id="section5-dr-disaster-recovery">Section5. DR (Disaster Recovery)</h4>
<p><strong>DR</strong> : 시스템이나 데이터가 손실될 때, 시스템을 복구하고 운영 가능 상태로 되돌리는 절차
<strong>DR 목표</strong> : 재해 대응, 재해 복구, 업무 연속성
<strong>재해</strong> : 예방할 수 없고, 피해규모가 큰 정보기술 외의 이슈</p>
<h4 id="section5-vdi-virtual-desktop-infrastructure">Section5. VDI (Virtual Desktop Infrastructure)</h4>
<p><strong>VDI</strong> : 가상 데스크톱 인프라, 사용자의 데스크톱 환경을 가상화하여 중앙 서버에서 실행하고 클라이언트 디바이스로 전송하는 기술
<strong>장점</strong> : 접근 가능성, 중앙 집중식 보안, 자원 효율성, 관리 용이성, 비용 절감</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DX INSIGHT] 1. AI]]></title>
            <link>https://velog.io/@ky0_hw/DX-INSIGHT-1.-AI</link>
            <guid>https://velog.io/@ky0_hw/DX-INSIGHT-1.-AI</guid>
            <pubDate>Sun, 09 Mar 2025 07:06:34 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="ch1-ai">CH1. AI</h3>
</blockquote>
<h4 id="section1-인공지능의-탄생">Section1. 인공지능의 탄생</h4>
<p><strong>전문가 시스템</strong> : 사람이 입력한 규칙에 따라 자동으로 판단
<strong>머신러닝</strong> : 컴퓨터가 스스로 데이터를 분석하고 학습
<strong>순서</strong> : 전문가 시스템 -&gt; 머신러닝 -&gt; 딥러닝 -&gt;GenAI</p>
<h4 id="section2-인공지능머신러닝딥러닝">Section2. 인공지능/머신러닝/딥러닝</h4>
<p><strong>인공지능</strong> : 인간의 지능을 기계가 모방하도록 하는 기술
<strong>머신러닝</strong> : 기계가 명시적인 프로그래밍 없이 데이터를 통해 스스로 학습하는 기술 (지도학습, 비지도학습, 강화학습)
<strong>딥러닝</strong> : 인공신경망을 이용해 데이터에서 복잡한 패턴을 학습하는 기술 (이미지 인식, 음성 인식, 자연어 처리)</p>
<h4 id="section3-인공신경망-다층-퍼셉트론">Section3. 인공신경망: 다층 퍼셉트론</h4>
<p><strong>다층 퍼셉트론(MLP)</strong> : 입력층, 은닉층, 출력층으로 구분된 인공신경망
<strong>퍼셉트론</strong> : 입력을 받아 출력으로 전달하는 <strong>뉴런</strong> 역할
<strong>MLP 동작원리</strong> : 입력받기 -&gt; 가중치 적용 -&gt; 활성화 함수로 값 변환 -&gt; 출력 생성</p>
<h4 id="section4-합성곱-신경망cnn">Section4. 합성곱 신경망(CNN)</h4>
<p><strong>MLP의 한계</strong> : 이미지같은 정적 2차원 데이터를 처리할 때 한계 존재
<strong>CNN</strong> : 합성곱 층, 풀링 층, 완전 연결 층으로 이미지의 중요 특징 추출
<strong>합성곱 층</strong> : 필터(커널)을 통해 이미지의 특징 맵 생성
<strong>풀링 층</strong> : 특징 맵의 크기를 줄여 중요한 정보만 남김
<strong>완전 연결 층</strong> : 최종 출력 생성 (이미지 분류)</p>
<h4 id="section5-순환-신경망rnn">Section5. 순환 신경망(RNN)</h4>
<p><strong>CNN의 한계</strong> : 연속적인 데이터 처리에 한계 존재
<strong>RNN</strong> : 시계열 데이터를 처리하기 위해 이전의 데이터를 바탕으로 다음 데이터를 예측 및 분석
<strong>동작 원리</strong> : 이전 단계의 출력을 다음 단계의 입력으로 사용
<strong>사용 사례</strong> : 텍스트 생성, 번역, 음성인식, 시간 시계열 예측, 동영상 분석</p>
<h4 id="section6-자연어처리nlp-소개">Section6. 자연어처리(NLP) 소개</h4>
<p><strong>NLP</strong> : 컴퓨터가 인간의 언어를 이해하고 처리할 수 있도록 하는 인공지능 분야
<strong>사용 사례</strong> : 음성인식, 자동번역, 감정분석, 챗봇, 스팸 필터링</p>
<h4 id="section7-자연어처리-기본개념">Section7. 자연어처리 기본개념</h4>
<p><strong>토큰화</strong> : 텍스트를 컴퓨터가 이해할 수 있도록 의미 있는 단위로 분해하는 과정. 
<strong>토큰화 이유</strong> : 컴퓨터는 텍스트를 그대로 이해할 수 없기 때문에 의미 있는 단위로 분해해야함
<strong>형태소 분석</strong> : 단어를 이해하기 위해 뿌리와 접사로 분해
<strong>구문 분석</strong> : 문장을 이해하기 위해 단어들의 순서와 관계를 분석
<strong>의미 분석</strong> : 정확한 정보를 이해하기 위해 단어와 문장의 표면적인 의미를 넘어, 깊은 의미를 이해하는 것
<strong>화용론 분석</strong> : 화자가 말하는 것 이상의 의도를 파악하는 과정
<strong>정보 추출</strong> : 정보 검색 및 분석을 위해 텍스트에서 특정 종류의 정보를 자동으로 추출하는 과정</p>
<h4 id="section8-자연어처리-기술의-응용">Section8. 자연어처리 기술의 응용</h4>
<p><strong>사용 사례</strong> : 챗봇, 감정분석, 기계 번역(파파고)</p>
<h4 id="section9-nlp와-머신러닝">Section9. NLP와 머신러닝</h4>
<p><strong>텍스트 데이터 전처리</strong> : 토큰화 -&gt; 불용어 제거 -&gt; 어간 추출 -&gt; 정규화
<strong>NLP에 딥러닝 활용</strong> : 트랜스포머, GenAI
<strong>NLP의 과제</strong> : 방언처럼 데이터가 부족한 <strong>저자원 언어</strong> 한계, 데이터의 <strong>편향</strong>, 개인정보 <strong>프라이버시</strong>, <strong>데이터 보안</strong></p>
<h4 id="section10-visionai-사례">Section10. VisionAI 사례</h4>
<p><strong>CGV AI 무비 필터 프로젝트</strong> : 포스터 이미지 내 배우 얼굴과 사용자 얼굴 간 고품질 페이스 스왑 모델 개발
<strong>활용 기술</strong> : 얼굴 정렬, 얼굴 탐지, 얼굴 나이 감지, 얼굴 랜드마크 탐지, 이미지 인페인팅, 페이스 스왑, 휴먼 파싱
<strong>얼굴 정렬</strong> : 이미지나 비디오에서 감지된 얼굴의 위치, 크기, 각도를 표준화된 형태로 변환
<strong>이미지 인페인팅</strong> : 이미지의 손상된 부분이나 누락된 부분을 복원
<strong>휴먼 파싱</strong> : 이미지에서 사람 신체 부위를 식별하고 분할하여 경계를 인식</p>
<h4 id="11-업무-효율화를-위한-genai">11. 업무 효율화를 위한 GenAI</h4>
<p><strong>코파일럭 스튜디오 활용</strong> : 반복적인 문의, 답변 내용을 식별하고 자동화
<strong>RAG + sLLM</strong>을 활용해 질문에 자동으로 답변</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접준비] SW Engineering, Spring]]></title>
            <link>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-SW-Engineering-Spring</link>
            <guid>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-SW-Engineering-Spring</guid>
            <pubDate>Thu, 24 Oct 2024 13:44:51 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="software-engineering">Software Engineering</h3>
</blockquote>
<h4 id="tdd-테스트-주도-개발">TDD (테스트 주도 개발)</h4>
<p>테스트케이스를 먼저 작성한 이후 실제 코드를 개발하는 기법
자바는 JUnit, C와 C++는 CppUnit라는 <strong>자동화 도구로 TDD 테스트케이스를 단위 테스트로 사용</strong>할 수 있다.</p>
<h4 id="애자일-agile">애자일 (Agile)</h4>
<p><strong>협력과 피드백</strong>을 더 자주하고, 일찍하고, 잘하는 것
개발 과정에 있어서 시스템 변경사항을 유연하게 대응할 수 있는 방법론
애자일을 통한 가장 많이 사용되는 개발 방법론이 <strong>스크럼</strong>이다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/31bf2e83-145a-420e-a5e1-2d07ea13e75b/image.png" alt="">
매일 짧은 스크럼 회의를 하고, 스프린트마다 테스트 제품을 통해 피드백을 받는 방법론이다.</p>
<h4 id="oop-객체지향-프로그래밍-핵심-개념">OOP (객체지향 프로그래밍) 핵심 개념</h4>
<p>객체간 독립성을 보장하고, 중복 코드를 줄이며 유지보수에 도움을 주는 프로그래밍으로, 4개의 특징이 존재한다.
<strong>1. 추상화</strong> : 사물들의 공통 특징을 하나의 집합으로 만드는 것
<strong>2. 캡슐화</strong> : private 접근자를 통해 낮은 결합도를 유지하는 것
<strong>3. 상속</strong> : 자식 클래스를 외부로부터 은닉하는 캡슐화의 일종
<strong>4. 다형성</strong> : 부모 클래스의 메소드를 자식 클래스에서 오버라이딩해 유연함을 갖추는 것
<strong>SOLID는 OOP 설계원칙</strong></p>
<h4 id="msa-마이크로-서비스-아키텍처">MSA (마이크로 서비스 아키텍처)</h4>
<p>MSA는 <strong>여러 개의 작은 서비스로 구성되어 각 서비스가 독립적으로 개발되고 배포</strong>되는 구조
 서비스 간 독립성으로 인해 확장성과 유연성이 높아진다.
 기능 고립성이라는 특징 때문에 일부 서비스가 실패하더라도 전체 시스템에 큰 영향을 미치지 않는다.</p>
<blockquote>
<h3 id="spring">Spring</h3>
</blockquote>
<h4 id="bean-scope">Bean Scope</h4>
<p>Spring Bean은 <strong>Spring Framework에서 관리되는 객체</strong>들이다.
<strong>DI(의존성 주입):</strong> Spring은 객체 간의 의존 관계를 설정하고, 이를 주입한다. 개발자는 Spring을 통해 필요한 <strong>객체(Bean)를 직접 생성하지 않고도 사용</strong>할 수 있다.
Spring 컨테이너에 의해 라이프사이클이 관리되며, <strong>디폴트 Scope는 싱글톤</strong>이지만, prototype, request, session등으로 설정 가능하다.</p>
<h4 id="mvc-framework">MVC Framework</h4>
<p><img src="https://velog.velcdn.com/images/ky0_hw/post/52c6d7b1-939c-4b9f-bf6b-35dd8c5b7520/image.png" alt=""></p>
<ol>
<li>클라이언트가 url로 요청한 request를 Dispatcher Selvlet이 수신</li>
<li>Handler Mapping으로 url을 담당하는 Controller 찾는다.</li>
<li>Controller가 Model과 View Name을 반환</li>
<li>View Resolver에서 View 받아오고, 해당 View에 모델 전달</li>
<li>완성된 View 파일을 클라이언트에 Response<h4 id="jpa">JPA</h4>
자바 ORM 기술의 명세로, 자바 어플리케이션에서 RDB를 사용하는 방식을 정의한 API다.</li>
</ol>
<p><strong>ORM</strong> : 객체지향언어의 객체를 RDB의 테이블와 매핑한다. SQL을 작성하지 않아도 직관적 메소드로 조작할 수 있다. (JAVA ORM 구현체는 Hibernate)
Entity Manager, 영속성 컨텍스트, JPQL로 구성된다.
<strong>Entity Manager</strong> : DB 구조와 맵핑된 JPA 엔티티들을 관리하는 역할 (CRUD) → 영속성 컨텍스트를 조작하는 인터페이스
<strong>영속성 컨텍스트</strong> : Entity Manager가 참조, 스프링에 1개만 존재, 영속화 된 Entity들을 저장하는 환경(DB에 가기전 저장되어 있는 곳) → 엔티티를 메모리(1차 캐시)에 캐시함으로서 DB에 접근할 때 생기는 오버헤드가 줄어듦 + 데이터 일관성 보장 , 1차 캐시는 트랜잭션 내에서만 사용하는 짧은 캐시 레이어 , 글로벌 캐시는 2차 캐시
한 트랜잭션에서 데이터의 변화가 일어나면 <strong>dirty check</strong> 해두고 커밋될 때 DB에 반영
쿼리들을 모았다가 트랜잭션이 커밋될 때 한번에 반영(flush)함 → <strong>쓰기 지연</strong>
스프링에서는 EntityManager가 프록시로 주입되어 있다가 실제로 사용될 때 호출 → <strong>동시성 해결</strong>
<strong>영속화</strong>란 영속성 컨텍스트에 엔티티를 추가하여 해당 엔티티가 DB와 동기화되도록 만드는 과정
<strong>최종 JPQL 작동순서</strong>
JPQL 작성 →Entity Manager를 통해 실행 → JPA가 SQL로 변환(Hibernate가 구현체이므로 실제론 Hibernate) → SQL이 JDBC를 통해 DB로 전달 → 결과가 JPA로 돌아오고, JPA가 다시 객체로 매핑하여 결과를 반영
<img src="https://velog.velcdn.com/images/ky0_hw/post/a65ce738-daba-4a15-a1d6-5fb93cdbe820/image.png" alt=""></p>
<blockquote>
<h3 id="reference">Reference</h3>
<p><a href="https://mozzi-devlog.tistory.com/34">https://mozzi-devlog.tistory.com/34</a>
<a href="https://gyoogle.dev/blog/web-knowledge/spring-knowledge/JPA.html">https://gyoogle.dev/blog/web-knowledge/spring-knowledge/JPA.html</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접준비] 자료구조]]></title>
            <link>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Thu, 24 Oct 2024 09:54:18 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h4 id="1-배열-array">1. 배열 (Array)</h4>
<p>설명: 동일한 자료형의 값들을 연속된 메모리 공간에 저장하는 자료구조.
특징: 인덱스를 통해 O(1) 시간 복잡도로 접근 가능하지만, 크기가 고정되어 있으며 삽입 및 삭제가 비효율적일 수 있음.</p>
</blockquote>
<h4 id="2-연결-리스트-linked-list">2. 연결 리스트 (Linked List)</h4>
<p>설명: 각 요소가 데이터와 다음 요소의 포인터로 이루어진 자료구조.
특징: 삽입과 삭제는 O(1)로 효율적이지만, 임의 접근은 O(n) 시간이 걸림.</p>
<h4 id="3-스택-stack">3. 스택 (Stack)</h4>
<p>설명: LIFO(Last In, First Out) 원칙을 따르는 자료구조.
특징: 삽입(push)과 삭제(pop)가 O(1) 시간에 이루어짐. 함수 호출 시의 호출 스택과 같은 곳에서 사용됨.</p>
<h4 id="4-큐-queue">4. 큐 (Queue)</h4>
<p>설명: FIFO(First In, First Out) 원칙을 따르는 자료구조.
특징: 삽입과 삭제가 O(1)로 이루어지며, 작업 예약이나 BFS와 같은 알고리즘에서 사용됨.</p>
<h4 id="5-해시-테이블-hash-table">5. 해시 테이블 (Hash Table)</h4>
<p>설명: 키와 값을 쌍으로 저장하는 자료구조로, 해시 함수를 통해 키를 인덱스로 변환.
특징: 평균적으로 O(1) 시간에 요소를 검색, 삽입, 삭제할 수 있지만, 해시 충돌이 발생하면 성능 저하가 있을 수 있음. (분리연결법, 개방 주소법 사용)
<img src="https://velog.velcdn.com/images/ky0_hw/post/69d3fd46-1a71-4d28-a98f-5dbff37a6094/image.png" alt=""></p>
<h4 id="6-트리-tree">6. 트리 (Tree)</h4>
<p>설명: 계층 구조를 표현하는 자료구조로, 노드들이 부모-자식 관계를 가짐.
특징: 이진 탐색 트리(BST)의 경우 평균적으로 O(log n)의 시간 복잡도로 탐색, 삽입, 삭제 가능.</p>
<h4 id="7-이진-탐색-트리-binary-search-tree">7. 이진 탐색 트리 (Binary Search Tree)</h4>
<p>설명: 이진트리+연결리스트 형태로, 탐색능력과 삽입삭제에 유리하게 구성
특징: 삽입, 검색, 삭제가 균등트리 O(logN), 편향트리 O(N)
<img src="https://velog.velcdn.com/images/ky0_hw/post/3625583e-fb6c-436f-8b53-f637ac822566/image.png" alt=""></p>
<h4 id="8-그래프-graph">8. 그래프 (Graph)</h4>
<p>설명: 정점(Vertex)과 간선(Edge)으로 이루어진 자료구조. 정점들 간의 관계를 나타냄.
특징: DFS, BFS와 같은 탐색 알고리즘을 사용할 수 있으며, 네트워크 구조나 경로 탐색에 사용됨.</p>
<h4 id="9-트라이-trie">9. 트라이 (Trie)</h4>
<p>설명: 문자열 집합을 저장하고 효율적으로 검색하기 위한 트리 기반 자료구조.
특징: 문자열 검색에 O(문자열길이) 시간복잡도를 가지며, 자동완성 기능 구현에 사용됨.
<img src="https://velog.velcdn.com/images/ky0_hw/post/280c457b-4930-4eb6-9ac4-986673b23c8a/image.png" alt=""></p>
<blockquote>
<h3 id="reference">Reference</h3>
<p><a href="https://inthiswork.com/archives/159726">https://inthiswork.com/archives/159726</a>
<a href="https://velog.io/@klloo/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%ED%8A%B8%EB%9D%BC%EC%9D%B4Trie-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0">https://velog.io/@klloo/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%ED%8A%B8%EB%9D%BC%EC%9D%B4Trie-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0</a>
<a href="https://gyoogle.dev/blog/computer-science/data-structure/Binary%20Search%20Tree.html">https://gyoogle.dev/blog/computer-science/data-structure/Binary%20Search%20Tree.html</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접 준비] 디자인 패턴, 알고리즘]]></title>
            <link>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91-%EC%A4%80%EB%B9%84-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</link>
            <guid>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91-%EC%A4%80%EB%B9%84-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</guid>
            <pubDate>Wed, 23 Oct 2024 17:17:10 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="디자인-패턴">디자인 패턴</h3>
</blockquote>
<h4 id="어댑터-패턴adapter-pattern">어댑터 패턴(Adapter Pattern):</h4>
<p>서로 호환되지 않는 인터페이스를 맞춰주는 패턴.
<strong>스프링 예시:</strong> HandlerAdapter는 다양한 컨트롤러를 처리하기 위해 사용됨.
다양한 컨트롤러를 처리할 수 있도록 호환성을 높여, 유연한 구조를 제공.</p>
<h4 id="싱글톤-패턴singleton-pattern">싱글톤 패턴(Singleton Pattern):</h4>
<p>하나의 인스턴스만 생성하여 사용하는 패턴.
<strong>스프링 예시</strong>: 스프링 빈은 기본적으로 싱글톤으로 관리됨.
메모리 효율성을 높이고, 전역적으로 동일한 객체를 재사용하여 리소스를 절약.</p>
<h4 id="템플릿-메소드-패턴template-method-pattern">템플릿 메소드 패턴(Template Method Pattern):</h4>
<p>알고리즘의 구조를 정의하고, 세부 구현을 하위 클래스에서 처리하는 패턴.
<strong>스프링 예시</strong>: JdbcTemplate 클래스는 데이터베이스 작업의 기본 흐름을 정의.
중복된 코드 없이 공통 로직을 재사용하고, 필요한 부분만 오버라이드 가능.</p>
<h4 id="팩토리-메소드-패턴factory-method-pattern">팩토리 메소드 패턴(Factory Method Pattern):</h4>
<p>객체 생성을 서브클래스에서 정의하는 패턴.
<strong>스프링 예시</strong>: BeanFactory는 빈 객체 생성을 관리.
객체 생성 로직을 캡슐화해 유연성을 증가시킴.</p>
<h4 id="옵저버-패턴observer-pattern">옵저버 패턴(Observer Pattern):</h4>
<p>객체 상태 변화를 구독자들에게 알리는 패턴.
<strong>스프링 예시</strong>: ApplicationListener로 이벤트 리스너를 구현.
이벤트 기반 시스템에서 확장성과 유지보수를 용이하게 함.</p>
<h4 id="스트레티지-패턴strategy-pattern">스트레티지 패턴(Strategy Pattern):</h4>
<p>실행 중에 알고리즘을 선택할 수 있게 하는 패턴.
<strong>스프링 예시</strong>: PlatformTransactionManager는 트랜잭션 전략을 변경 가능.
상황에 맞는 트랜잭션 전략을 선택하여 유연한 처리가 가능.</p>
<h4 id="컴포지트-패턴composite-pattern">컴포지트 패턴(Composite Pattern):</h4>
<p>객체를 트리 구조로 구성하여 부분-전체 계층을 표현하는 패턴.
<strong>스프링 예시</strong>: ViewResolverComposite는 여러 ViewResolver들을 조합하여 사용.
복잡한 뷰 처리 구조를 간결하게 유지하고 관리 가능.</p>
<h4 id="solid--객체지향-5원칙">SOLID : 객체지향 5원칙</h4>
<p><strong>SRP (단일 책임 원칙)</strong>: 
클래스는 하나의 책임만 가진다, 도메인간 영향을 주면 안된다.
<strong>OCP (개방-폐쇄 원칙)</strong>:
소프트웨어는 확장에는 열려있고, 주변의 변화에는 닫혀 있어야 한다, 기능 추가시 다른 코드들을 건드리지 않아도 된다.
<strong>LSP (리스코프 치환 원칙)</strong>: 
서브클래스는 부모 클래스를 대체할 수 있어야 한다, 코드의 재사용성을 위한 다형성을 지키기 위함
<strong>ISP (인터페이스 분리 원칙)</strong>: 
인터페이스를 사용에 맞게 끔 각기 분리해야 한다, 인터페이스에 불필요한 기능이 존재할 시 클라이언트가 불필요한 메소드를 구현해야 한다. 
<strong>DIP (의존성 역전 원칙)</strong>: 
고수준 모듈은 자기보다 변하기 쉬운 저수준 모듈에 의존하면 안 된다, 모듈간 결합도를 줄여 변경에 영향을 최대한 덜받는다.</p>
<blockquote>
<h3 id="sorting-알고리즘">sorting 알고리즘</h3>
<p>n: 입력 크기, k: 숫자의 최대값, d: 자릿수
<strong>거품 정렬</strong>: 
인접한 두 요소를 비교하여 자리를 바꿔가며 정렬하는 방식, 반복할수록 큰 값이 뒤로 이동.
시간 복잡도: O(n²)
공간 복잡도: O(1)
<strong>선택 정렬</strong>: 
배열에서 가장 작은 값을 찾아 맨 앞의 요소와 교환하는 방식.
시간 복잡도: O(n²)
공간 복잡도: O(1)
<strong>삽입 정렬</strong>: 
정렬된 부분에 새로운 요소를 삽입하여 정렬하는 방식.
시간 복잡도: O(n²) (최선: O(n))
공간 복잡도: O(1)
<strong>퀵 정렬</strong>: 
피벗을 기준으로 왼쪽은 작은 값, 오른쪽은 큰 값으로 분할 정렬.
시간 복잡도: O(n log n) (최악: O(n²))
공간 복잡도: O(log n)
<strong>병합 정렬</strong>: 
배열을 반으로 나누어 각각 정렬한 후 합치는 방식.
시간 복잡도: O(n log n)
공간 복잡도: O(n)
<strong>힙 정렬</strong>: 
힙 자료구조를 이용해 최대값이나 최소값을 정렬.
시간 복잡도: O(n log n)
공간 복잡도: O(1)
<strong>기수 정렬</strong>: 
자릿수를 기준으로 순차적으로 정렬.
시간 복잡도: O(d * (n + k))
공간 복잡도: O(n + k)
<strong>계수 정렬</strong>: 
배열 요소의 빈도를 계산해 정렬, 숫자 범위가 작을 때 효과적.
시간 복잡도: O(n + k)
공간 복잡도: O(n + k)</p>
</blockquote>
<blockquote>
<h3 id="reference">Reference</h3>
<p><a href="https://gyoogle.dev/blog/design-pattern/Overview.html">https://gyoogle.dev/blog/design-pattern/Overview.html</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접준비] OS]]></title>
            <link>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-OS</link>
            <guid>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-OS</guid>
            <pubDate>Tue, 22 Oct 2024 17:25:55 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="운영-체제란operating-system">운영 체제란?(Operating System)</h3>
<p>HW를 관리하고, 컴퓨터 시스템의 자원들을 효율적으로 관리하도록 도와주는 <strong>응용 프로그램과 HW간의 인터페이스</strong></p>
</blockquote>
<h4 id="역할">역할</h4>
<p><strong>1. 프로세스 관리</strong> : 프로세스, 스레드, 스케줄링, 동기화, IPC통신
<strong>2. 저장장치 관리</strong> : 메모리 관리, 가상메모리, 파일시스템
<strong>3. 네트워킹</strong> : TCP/IP, 기타 프로토콜
<strong>4. 사용자 관리</strong> : 계정관리, 접근권한 관리
<strong>5. 디바이스 드라이버</strong> : 순차접근 장치, 임의접근 장치, 네트워크 장치</p>
<h4 id="프로세스-관리">프로세스 관리</h4>
<p>OS에서 작동하는 응용프로그램을 관리하는 것
<strong>CPU를 점유할 프로세스를 결정하고 할당</strong>, 프로세스간 공유자원 접근, 통신 등을 관리한다.</p>
<h4 id="저장장치-관리">저장장치 관리</h4>
<p><strong>1차 저장장치</strong>인 메모리 영역의 할당과 해제, 가상메모리 등을 관리하고,
<strong>2차 저장장치</strong>인 하드디스크, NAND Flash Memory등을 관리한다.</p>
<h4 id="네트워킹">네트워킹</h4>
<p>응용 프로그램이 네트워크를 사용하려면 OS에서 <strong>네트워크 프로토콜을 지원</strong>해야한다.</p>
<h4 id="사용자-관리">사용자 관리</h4>
<p>한 컴퓨터를 여러명이 사용할 때, 사용자 별로 파일, 시스템 자원에 접근 권한을 지정해야 한다.</p>
<h4 id="디바이스-드라이버">디바이스 드라이버</h4>
<p>OS는 응용 프로그램이 HW를 사용할 수 있게 만들어야 한다.
따라서 <strong>디바이스 드라이버는 OS 안의 HW를 추상화하는 계층</strong>이다.</p>
<blockquote>
<h3 id="프로세스-스레드">프로세스, 스레드</h3>
<p><strong>프로세스</strong> : 프로그램을 메모리 상에서 실행중인 작업
<strong>스레드</strong> : 프로세스 안에서 실행되는 여러 흐름 단위</p>
</blockquote>
<h4 id="프로세스에서-주소공간-할당">프로세스에서 주소공간 할당</h4>
<p><strong>Code</strong> : 코드 자체를 구성하는 메모리 영역(프로세스간 공유)
<strong>Data</strong> : 전역변수, 정적변수, 배열 등(프로세스간 공유X)
<strong>Heap</strong> : 동적 할당 시 사용 (프로세스간 공유X)
<strong>Stack</strong> : 지역변수, 매개변수, 리턴 값 (임시 메모리 영역, 공유X)
스레드는 Stack만 따로 할당받고 나머지는 공유한다.
즉, 프로세스는 <strong>고유 공간과 자원을 할당받아 사용</strong>, 스레드는 <strong>다른 스레드와 공간, 자원을 공유하면서 사용</strong></p>
<h4 id="멀티프로세스">멀티프로세스</h4>
<p>여러 프로세스가 병렬적으로 작업을 수행하는것
<strong>각각 독립된 메모리를 가지고 있어</strong>, 안정적이지만 Context Switching Overhead를 감안해야됨
<strong>Context Switching</strong> : 동작중인 프로세스의 상태를 보관하고, 다음 순번 프로세스의 상태를 복구하는 과정</p>
<h4 id="멀티스레드">멀티스레드</h4>
<p>하나의 프로세스에 여러 스레드로 자원을 공유하며 작업을 나누어 수행하는 것
스레드들이 <strong>공유 메모리를 통해 다수의 작업을 동시에 처리</strong>
Context Switching 없지만, 한개의 스레드가 공유 메모리를 망가뜨리면 타 스레드들도 작동불능 -&gt; <strong>Critical Section</strong> 기법 사용</p>
<blockquote>
<h3 id="인터럽트interrupt">인터럽트(Interrupt)</h3>
<p>프로그램을 실행하는 중 예기치 못한 상황이 발생할 경우 현재 실행중인 작업을 즉시 중단하고, 발생한 상황에 대한 처리가 필요함을 CPU에게 알리는 것
<strong>외부 인터럽트</strong>
I/O장치, 전원등 외부적인 요인으로 발생
CPU의 하드웨어 신호에 의한 발생
<strong>내부 인터럽트</strong>
잘못된 명령이나 데이터 사용(0나누기, 오버플로우...)시 발생
CPU의 하드웨어 신호에 의한 발생
<strong>소프트웨어 인터럽트</strong>
프로그램 코드에서 명시적으로 발생시키는 인터럽트, 주로 <strong>시스템 콜에 의해 발생</strong></p>
</blockquote>
<h4 id="인터럽트-발생-처리-과정">인터럽트 발생 처리 과정</h4>
<p>인터럽트 발생시, 수행중인 프로그램의 <strong>상태 레지스터와 PC 등을 스택에 잠시 저장</strong>한 뒤, <strong>인터럽트 서비스 루틴</strong>으로 간다.
인터럽트가 아니라면 다른 프로그램의 상태를 주기적으로 점검하는 <strong>폴링</strong>을 사용해야 하는데, 이는 성능적으로 비효율적이다.
즉, 인터럽트는 <strong>발생시기를 예측하기 힘든 예외사항</strong>에 빠르게 대처하는 방법이다.</p>
<blockquote>
<h3 id="시스템-콜">시스템 콜</h3>
<p>응용 프로그램이 운영체제의 핵심 기능<strong>(커널)과 상호작용하기 위해 사용하는 인터페이스</strong>
<strong>인터럽트의 한 종류</strong>이며, 사용자가 동기적으로 발생시킨다.
평소 <strong>유저모드로 실행중인 응용 프로그램</strong>이 하드웨어 리소스에 접근하고 싶을 때 <strong>시스템 콜로 커널모드</strong>에 진입한다. 이렇게 리소스에 직접 접근을 막아둠으로써 안정성과 보안성을 높인다.
<strong>1. fork()</strong>:
fork()는 현재 프로세스(부모 프로세스)를 복사하여 새로운 프로세스(자식 프로세스)를 생성하는 시스템 콜이다.
부모 프로세스와 자식 프로세스는 동일한 메모리 공간을 공유하지 않으며, 자식은 부모의 복사본을 가진다.
자식 프로세스는 fork() 호출에서 0을 반환하고, 부모 프로세스는 자식의 PID를 반환받는다.
<strong>2. exec()</strong>:
exec()는 현재 프로세스를 새로운 프로그램으로 대체하는 시스템 콜이다.
fork()로 생성된 자식 프로세스는 exec()를 통해 새로운 프로그램을 실행할 수 있다.
프로세스의 메모리 공간이 완전히 새로운 프로그램으로 덮어쓰여진다.
<strong>3. wait()</strong>:
부모 프로세스가 자식 프로세스가 종료될 때까지 기다리게 하는 시스템 콜이다.
자식 프로세스가 종료되면 그 종료 상태를 부모에게 전달하며, 부모 프로세스가 자식 프로세스 종료까지 다른 작업을 하지 않고 대기하게 한다.</p>
</blockquote>
<blockquote>
<h3 id="pcb-context-switching">PCB, Context Switching</h3>
</blockquote>
<h4 id="pcbprocess-control-block">PCB(Process Control Block)</h4>
<p><strong>프로세스의 메타데이터들을 저장해두는 곳</strong>, 커널의 메모리에 저장된다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/a3ca1c8a-a9f1-4667-8a10-0713ae3eff5d/image.jpeg" alt="">
프로세스가 CPU에서 중단되거나 교체될 때(interrupt), <strong>현재 실행 중인 프로세스의 상태는 PCB에 저장되고, 다음에 수행할 프로세스의 정보는 PCB에서 불러와 CPU에 적용</strong>한다. 이 과정을 <strong>Context Switching</strong>이라고 한다.</p>
<blockquote>
<h3 id="ipcinter-process-communication">IPC(Inter Process Communication)</h3>
<p><strong>독립적으로 실행되는 프로세스간의 통신</strong>을 위해 커널이 제공하는 서비스
IPC 통신에서 프로세스 간 데이터를 동기화 및 보호하기 위해 세마포어와 뮤텍스를 사용한다.</p>
</blockquote>
<h4 id="1-익명-pipe--named-pipe">1. 익명 PIPE , Named PIPE</h4>
<p>한 프로세스는 데이터를 쓰고, 한 프로세스는 데이터를 읽는 구조
한쪽 방향으로만 통신이 가능한 반이중 통신이다.</p>
<h4 id="2-message-queue">2. Message Queue</h4>
<p>파이프처럼 데이터의 흐름이 아닌 <strong>메모리 공간</strong>이다.
사용할 데이터에 번호를 붙이면서 여러 프로세스가 동시에 데이터를 다룰 수 있게 한다.</p>
<h4 id="3-공유-메모리">3. 공유 메모리</h4>
<p>데이터 자체를 공유하도록 지원하는 메모리이다.
커널에 요청해 공유 메모리를 할당받고, 모든 프로세스가 접근할 수 있게 된다.
IPC중 가장 빠르다.</p>
<h4 id="4-소켓">4. 소켓</h4>
<p>네트워크 상에서 데이터를 주고받기 위해 필요한 인터페이스 역할을 하며, IP 주소와 포트 번호로 통신 상대를 식별한다.</p>
<blockquote>
<h3 id="cpu-scheduling">CPU Scheduling</h3>
<p>CPU를 잘 사용하기 위해 프로세스를 배정하는 알고리즘</p>
</blockquote>
<h4 id="선점preemptive">선점(preemptive)</h4>
<p>프로세스가 CPU를 사용하는 도중에도 운영체제가 <strong>강제로 프로세스를 중단시키고 다른 프로세스에 CPU를 할당</strong>할 수 있다.
<strong>1. Priority Scheduling</strong> :
우선순위가 높은 순서대로 처리하지만, <strong>Starvation 존재</strong>
<strong>Aging기법</strong>으로 Starvation 해결 가능
<strong>2. Round-Robin</strong> : 
각 프로세스에 <strong>동일한 Time Quantum</strong>만큼 CPU를 할당
Quantum이 클수록 FCFS와 비슷해지고, 작으면 Context Switching OH 증가
<strong>3. Multilevel-Queue, Multilevel-Feedback-Queue</strong> :
각자 다른 Time Quantum을 가진 우선순위 큐를 사용한다.
우선순위가 높은 큐는 작은 Time Quantum을 할당해 밸런스를 조절한다.
피드백을 통해 프로세스가 큐를 이동할 수 있다.</p>
<h4 id="비선점nonpreemptive">비선점(nonpreemptive)</h4>
<p>프로세스가 CPU를 할당받으면 자신의 작업을 끝낼 때까지 CPU를 사용한다.
즉, <strong>작업이 끝날 때까지 인터럽트가 발생하지 않는다</strong>.
ex) FCFS (First Come First Served), SJF(Shortest Job First)</p>
<h4 id="스케줄링-판단-기준">스케줄링 판단 기준</h4>
<p><strong>Response Time</strong> : 작업이 처음 실행될때까지 시간
<strong>Turnaround Time</strong> : 대기시간까지 합쳐 작업이 완료될때까지 걸린 총 시간</p>
<blockquote>
<h3 id="데드락교착상태">데드락(교착상태)</h3>
<p>두개 이상의 프로세스나 스레드가 서로 자원을 얻지 못한 채 무한히 기다리는 상태
총 4가지의 조건이 모두 성립해야 데드락이 발생한다.
<strong>1. 상호 배제 (Mutual Exclusion)</strong> :
자원은 한번에 한 프로세스만 사용할 수 있다.
<strong>2. 점유 대기 (Hold and Wait)</strong> :
자원을 점유한 상태에서 다른 자원을 대기하는 프로세스가 존재해야 한다.
<strong>3. 비선점 (No preemption)</strong> :
다른 프로세스에 할당한 자원은 강제로 빼앗을 수 없다.
<strong>4. 순환 대기 (Circular wait)</strong> :
프로세스의 집합에서 순환 형태로 자원을 대기해야 한다.</p>
</blockquote>
<h4 id="해결책">해결책</h4>
<p><strong>1. 예방 (prevention)</strong> :
데드락 조건중 한개를 제거해 해결한다. (자원 낭비가 심함)
<strong>상호배제</strong> - 여러 프로세스가 공유 자원 사용
<strong>점유대기</strong> - 프로세스 실행 전 모든 자원을 할당한다.
<strong>비선점</strong> - 타 프로세스가 자원 요청시 반납
<strong>순환대기</strong> - 프로세스에 순서대로 자원 배분
<strong>2. 회피 (avoidance)</strong> :
데드락 발생 자체를 피해가는 방법 (은행원 알고리즘)
프로세스가 자원을 요청할 때, <strong>요청을 받아들여도 시스템이 데드락에 빠지지 않으면 자원을 할당</strong>한다.
<strong>3. 탐지 (Detection) + 회복 (Recovery)</strong> :
<strong>자원 할당 그래프로 데드락을 탐지</strong>하고, 해당 프로세스를 종료시키거나 <strong>자원을 선점(preemption)</strong>한다.</p>
<blockquote>
<h3 id="경쟁-상태-race-condition">경쟁 상태 (Race Condition)</h3>
<p>공유 자원을 둘 이상의 스레드 혹은 프로세스가 읽거나 쓰면서 결과값이 의도와 달라질 수 있는 상태</p>
</blockquote>
<h4 id="race-codition-발생하는-경우">Race Codition 발생하는 경우</h4>
<p><strong>1. 커널 모드에서 인터럽트, context switching</strong> :
커널모드에서 데이터 수정 작업을 하다 인터럽트가 발생해 같은 데이터를 조작하는 경우
non-preemptive환경을 구성하거나, 커널 모드에서는 CPU 제어권을 넘기지 않게 구성해 해결할 수 있다.
<strong>2. 멀티 프로세스 환경에서 공유 메모리 사용</strong> :
2개 이상의 프로세스가 커널 내부의 공유 데이터를 조작하는 경우
공유 데이터에 접근하려면 Lock을 획득하게 하면 해결할 수 있다.</p>
<h4 id="임계구역-critical-section-">임계구역 (Critical Section) :</h4>
<p>각 <strong>프로세스에서 공유 데이터를 접근하는 코드</strong> 부분
한 프로세스에서 <strong>Critical Section을 수행할 때 다른 프로세스가 그 데이터 영역에 접근하지 못하도록</strong> 해야한다.</p>
<h4 id="해결책--세마포어-뮤텍스">해결책 : 세마포어, 뮤텍스</h4>
<p><strong>뮤텍스(Mutex)</strong>:
<strong>상호 배제를 보장하는 잠금 장치</strong>로, 하나의 스레드만 자원에 접근할 수 있도록 허용한다.
소유권을 가진 스레드만 잠금을 해제할 수 있다.
<strong>세마포어(Semaphore)</strong>:
자원 카운터 기반의 기법으로, 여러 스레드가 동시에 자원에 접근할 수 있다.
즉, <strong>세마포어는 여러 스레드가 동시 접근 가능한 자원의 개수</strong>이다.
소유권 개념이 없으며, wait와 signal로 동작을 제어한다.</p>
<blockquote>
<h3 id="페이징-세그멘테이션">페이징, 세그멘테이션</h3>
<p>메모리를 효율적으로 관리하기 위해 존재하는 <strong>메모리 관리 기법</strong>이다.</p>
</blockquote>
<h4 id="1-연속-메모리-관리">1. 연속 메모리 관리</h4>
<p>고정 분할 기법(내부 단편화 발생), 동적 분할 기법(외부 단편화 발생)</p>
<h4 id="2-불연속-메모리-관리">2. 불연속 메모리 관리</h4>
<p><strong>페이징(Paging)</strong>:
메모리를 동일한 크기의 블록(페이지)으로 나눈다.
각 페이지는 물리 메모리의 프레임에 매핑되며, 외부 단편화가 없다.
<strong>세그멘테이션(Segmentation)</strong>:
메모리를 가변적인 크기의 논리적 단위(세그먼트)로 나눈다.
외부 단편화가 발생할 수 있다.</p>
<blockquote>
<h3 id="페이지-교체-알고리즘">페이지 교체 알고리즘</h3>
<p>페이지 부재 발생시 기존에 존재하는 페이지 중 어느것을 교체할지 결정하는 법
<strong>1. FIFO ** :
먼저 메모리에 올라온 페이지(Victim Page)를 내보낸다.
*<em>2. OPT *</em> :
Optimal 알고리즘, 앞으로 가장 사용하지 않을 페이지를 Victim Page로 선정
실질적으로 카운트할 수 없기 때문에 구현하기 어렵다.
**3. LRU</strong> :
Least Recently Used, 최근에 사용하지 않은 페이지를 Victim Page로 선정</p>
</blockquote>
<blockquote>
<h3 id="메모리">메모리</h3>
<p><strong>메인 메모리(RAM)</strong>는 CPU가 직접 접근할 수 있는 물리적 메모리 공간이다.
<strong>가상 메모리(Virtual Memory)</strong>는 메인 메모리 크기보다 더 많은 메모리를 사용하기 위해 디스크의 일부를 메모리처럼 사용하는 방식이다. 즉, <strong>메인 메모리 + 스왑공간(디스크)</strong>이다.</p>
</blockquote>
<h4 id="mmu-memory-management-unit-메모리-관리-장치">MMU (Memory Management Unit: 메모리 관리 장치)</h4>
<p>가상 메모리의 논리 주소를 가지고 실제 데이터가 담겨 있는 곳에 접근하기 위해서는 빠르게 물리 주소로 변환해준다.
또한 각 프로세스가 가진 독립적 메모리 공간을 보호한다. (base와 limit을 활용해 잘못된 접근이 오면 trap 발생시킴)</p>
<h4 id="메모리-과할당-over-allocating">메모리 과할당 (over allocating)</h4>
<p>실제 메모리보다 큰 사이즈의 메모리를 프로세스에 할당한 상황
프로세스 실행 중 <strong>페이지 폴트</strong> 발생시, 디스크에 존재하는 페이지를 메모리에 올려야 하는데 이때 <strong>디스크의 페이지를 메인 메모리의 페이지와 교환하는 기법이 Swapping</strong>이다.
이때 메인 메모리에서 swap out 당하는 페이지를 고르는 기법이 paging이다.</p>
<h4 id="캐시-메모리">캐시 메모리</h4>
<p>CPU와 메인메모리의 속도차이로 인한 성능 저하를 방지 (메모리 병목 현상)
메인메모리에 저장된 내용의 일부를 임시로 저장해둔다.
메인 메모리보다 CPU에 가까운 곳에 존재하고, SRAM으로 메인메모리(DRAM)보다 속도가 빠르다.
<strong>캐시 HIT</strong> 비율을 늘리기 위해 <strong>지역성</strong>을 사용한다.</p>
<h4 id="지역성">지역성</h4>
<p>기억장치 내의 정보를 <strong>균일하게 액세스하지 않고</strong> 한순간 <strong>특정부분에 집중적으로 액세스</strong> 하는것
<strong>시간 지역성</strong> : 최근에 참조된 주소의 내용은 곧 다시 참조된다.
<strong>공간 지역성</strong> : 참조된 주소와 인접한 주소의 내용이 참조된다.</p>
<blockquote>
<h3 id="파일-시스템">파일 시스템</h3>
<p>컴퓨터에서 파일을 쉽게 발견할 수 있도록 유지관리하는 방법
커널 영역에서 동작하며, 계층적 디렉터리 구조를 가진다.
디스크와 메인 메모리 속도차를 줄이기 위해 사용한다.
순차접근, 직접접근, 인덱싱 등으로 존재할 수 있다.</p>
</blockquote>
<blockquote>
<h3 id="reference">Reference</h3>
<p><a href="https://gyoogle.dev/blog/computer-science/operating-system/Operation%20System.html">https://gyoogle.dev/blog/computer-science/operating-system/Operation%20System.html</a>
<a href="https://brightstarit.tistory.com/13">https://brightstarit.tistory.com/13</a>
<a href="https://jeong-pro.tistory.com/93">https://jeong-pro.tistory.com/93</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접준비] DataBase]]></title>
            <link>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-DataBase</link>
            <guid>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-DataBase</guid>
            <pubDate>Mon, 21 Oct 2024 05:38:29 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="용어정리">용어정리</h3>
<p><strong>데이터베이스 (Database)</strong>: 데이터를 체계적으로 저장하고 관리하는 시스템.
<strong>DBMS</strong>: 데이터베이스를 관리하고, 데이터를 저장, 수정, 삭제, 검색할 수 있게 해주는 소프트웨어.
<strong>RDB</strong> : 데이터를 <strong>테이블 형태(릴레이션)</strong>로 저장하는 데이터베이스
<strong>릴레이션</strong>: 테이블, 데이터를 행과 열로 저장하는 구조.
<strong>튜플</strong>: 릴레이션의 한 행, 즉 데이터의 한 레코드.
<strong>속성 (Attribute)</strong>: 릴레이션의 한 열, 즉 데이터 항목의 속성.
<strong>스키마 (Schema)</strong>: 데이터베이스의 구조를 정의하는 청사진, 테이블 간의 관계, 속성, 데이터 타입 등을 포함.
<strong>인덱스 (Index)</strong>: 데이터를 빠르게 검색할 수 있도록 도와주는 자료 구조.
<strong>정규화 (Normalization)</strong>: 데이터 중복을 최소화하고 데이터를 구조화하여 무결성을 유지하는 과정.
<strong>무결성 (Integrity)</strong>:
<strong>참조 무결성 (Referential Integrity)</strong>: 
외래 키가 참조하는 값이 항상 올바른 값을 갖도록 보장하는 제약 조건.
<strong>개체 무결성 (Entity Integrity)</strong>:
기본 키는 null 값을 가질 수 없으며, 중복될 수 없다는 제약 조건.
<strong>무결성과 정합성</strong>
무결성은 DB구조를 지키고 있는가, 정합성은 데이터의 일관성이 유지되고 있는가
<strong>데이터 아카이빙(Data Archiving)</strong>
사용하지 않거나 필요성이 줄어든 데이터를 별도로 보관하는 것
<strong>트랜잭션</strong>: 데이터베이스에서 하나의 논리적 작업 단위. 트랜잭션은 ACID 속성을 준수함.
<strong>ERD (Entity-Relationship Diagram)</strong>: 데이터베이스 설계를 시각적으로 표현한 다이어그램, 개체와 그들 간의 관계를 나타냄.
<strong>뷰 (View)</strong>: 실제 테이블에서 데이터를 가져와 보여주는 가상 테이블. 복잡한 쿼리를 간단하게 만들 수 있음.
<strong>SQL (Structured Query Language)</strong>: 데이터베이스와 상호작용하기 위한 표준 언어. 데이터 검색, 삽입, 수정, 삭제 등을 수행.
<strong>DML (Data Manipulation Language)</strong>: 데이터 조작 언어, 데이터를 조회하고 수정하는 데 사용됨 (SELECT, INSERT, UPDATE, DELETE).
<strong>DDL (Data Definition Language)</strong>: 데이터 정의 언어, 데이터베이스 구조를 정의하는 데 사용됨 (CREATE, ALTER, DROP).
<strong>DCL (Data Control Language)</strong>: 데이터 제어 언어, 권한 부여 및 회수에 사용됨 (GRANT, REVOKE).</p>
</blockquote>
<blockquote>
<h3 id="key">Key</h3>
<p><strong>후보키(Candidate Key)</strong> : 
튜플을 유일하게 식별하기 위해 사용할 수 있는 속성 집합, 즉 기본키로 사용할 수 있다.
<strong>유일성</strong> : Key로 한개의 튜플만 식별할 수 있다.
<strong>최소성</strong> : 쓸데없는 속성은 포함하지 않는다.
후보키는 유일성, 최소성 2가지 특성을 만족한다.
<strong>기본키(Primary Key)</strong> : 
후보키 중 선택한 메인 키
Null 값을 가질 수 없으며, 동일한 값이 중복될 수 없다.
<strong>보조키(Alternate Key)</strong> :
후보키 중 기본키를 제외한 나머지 키
<strong>슈퍼키(Super Key)</strong> :
유일성은 만족하지만, 최소성은 만족하지 못하는 키
<strong>외래키(Foreign Key)</strong> :
다른 릴레이션의 기본키를 그대로 참조하는 속성의 집합</p>
</blockquote>
<blockquote>
<h3 id="join">Join</h3>
<p><strong>Inner Join</strong> : 교집합
<strong>Left Outer Join, Right Outer Join</strong> :
기준 테이블의 모든 행 포함, 조인테이블에 일치하는 값 없는 경우 NULL로 채움
<strong>Full Outer Join</strong> : 두 테이블의 모든 행 포함, 반대 테이블에 일치하는 값 없으면 NULL로 채움
<strong>Cross Join(카르티시안 곱)</strong> :
두 테이블의 모든 가능한 행의 조합을 반환하는 연산
조인 조건이 없으며, NULL값 또한 포함되지 않는다.
<strong>Self Join</strong> : 자기 자신과 조인하는 것. 별칭을 다르게 두어 적용</p>
</blockquote>
<blockquote>
<h3 id="sql-injection">SQL Injection</h3>
<p>해커에 의해 조작된 SQL 쿼리문이 DB에 전달되어 비정상적 명령을 실행시키는 공격
<strong>정상적인 SQL</strong> :</p>
</blockquote>
<pre><code>SELECT * FROM users WHERE username = &#39;사용자입력값&#39; AND password = &#39;사용자입력값&#39;;</code></pre><p><strong>공격 SQL : username에 &#39; OR 1=1 --</strong> :</p>
<pre><code>SELECT * FROM users WHERE username = &#39;&#39; OR 1=1 --&#39; AND password = &#39;&#39;;</code></pre><p>이렇게 OR 조건을 넣고, 뒤에 password를 주석처리를 해버린다.
결국 <strong>데이터 유출, 데이터 조작, 시스템 손상</strong> 등의 문제가 발생할 수 있다.</p>
<h4 id="방어-방법">방어 방법</h4>
<ol>
<li><strong>input을 받을 때 특수문자 여부 검사</strong>하기</li>
<li><strong>SQL 에러 메시지 감추기</strong> : 공격자는 에러 메시지로 정보를 얻을 수 있다.</li>
<li><strong>Prepared Statement</strong> :  쿼리와 데이터를 분리하여, 입력 값이 SQL 문법으로 실행되지 않게 한다.<pre><code>PreparedStatement pstmt = conn.prepareStatement(&quot;SELECT * FROM users WHERE username = ? AND password = ?&quot;);
pstmt.setString(1, username);
pstmt.setString(2, password);</code></pre></li>
</ol>
<blockquote>
<h3 id="sql-nosql">SQL, NOSQL</h3>
</blockquote>
<h4 id="sql관계형-데이터베이스">SQL(관계형 데이터베이스)</h4>
<p>SQL을 사용하면 RDBMS(관계형DB 관리시스템)를 통해 데이터를 수정,삭제,저장,조회할 수 있다.</p>
<ol>
<li>데이터는 정해진 데이터 스키마에 따라 테이블에 저장된다.</li>
<li>데이터는 관계를 통해 여러 테이블에 분산된다.(정규화하기 위해)</li>
<li>하나의 테이블에서 중복 없이 하나의 데이터만을 관리한다.<h4 id="nosql비관계형-데이터베이스">NoSQL(비관계형 데이터베이스)</h4>
</li>
</ol>
<p><strong>스키마도 없고, 관계도 없다.</strong>
<img src="https://velog.velcdn.com/images/ky0_hw/post/cad5f8ab-3dd9-44d9-a5b2-20651057ad96/image.png" alt=""></p>
<h4 id="1-document">1. Document</h4>
<p>Key-Value Database와 같이 데이터 저장에 Key-Value Type를 사용
하지만 <strong>Value를 문서로 저장한다.</strong>
Value에 있는 문서의 필드에 따라 <strong>검색하거나 쿼리할 수 있다.</strong>
ex) MongoDB, CouchDB, Amazon DocumentDB</p>
<h4 id="2-graph">2. Graph</h4>
<p>노드(데이터)와 엣지(관계)로 구성되며, 소셜 네트워크, 추천 시스템, 경로 탐색 등에 유리하다.
ex) Neo4j, Amazon Neptune, OrientDB</p>
<h4 id="3-key-value">3. Key-Value</h4>
<p>데이터는 키-값 쌍으로 저장되며, <strong>고유한 키에 대응하는 값은 문자열, 객체, 리스트 등 어떤 형태든 가능</strong>하다.
Value에 있는 값의 필드에 따라 <strong>검색하거나 쿼리할 수 없다.</strong>
단순한 데이터 저장과 빠른 조회가 가능하며, 캐시나 세션 관리와 같은 용도로 사용한다.
ex) Redis, Amazon DynamoDB</p>
<h4 id="4-wide-column">4. Wide Column</h4>
<p>테이블 형식이지만 각 행은 수천 개의 열(컬럼)을 가질 수 있으며, 행마다 다른 열을 가질 수 있는 비정형 테이블 구조
ex) Apache Cassandra, HBase, ScyllaDB</p>
<h4 id="sql-vs-nosql">SQL vs NoSQL</h4>
<p><strong>SQL</strong> : 
명확하게 정의된 스키마, 데이터 무결성 보장
스키마를 수정하기 힘듦, 수직적 확장만 가능(DB 서버 성능향상)
<strong>NoSQL</strong> :
스키마가 없어서 유연하고, 저장된 데이터에 새로운 필드 추가가 쉬움
수직, 수평적 확장(서버를 추가해 DB를 분산시킴) 전부 가능
데이터 조회가 빠르지만, 데이터 변경은 오래걸림</p>
<blockquote>
<h3 id="anomaly">Anomaly</h3>
</blockquote>
<h4 id="1-삽입-이상-insertion-anomaly">1. 삽입 이상 (Insertion Anomaly)</h4>
<p>불필요한 데이터를 추가해야 삽입할 수 있는 상황
ex) 기본키에 NULL값을 가진 레코드가 존재할 때</p>
<h4 id="2-갱신-이상-update-anomaly">2. 갱신 이상 (Update Anomaly)</h4>
<p>일부만 변경해 데이터가 불일치하는 모순
ex) 한 학생의 필드를 수정하는데, 모든 DB에서 전부 수정하지 않은 경우</p>
<h4 id="3-삭제-이상-deletion-anomaly">3. 삭제 이상 (Deletion Anomaly)</h4>
<p>튜플 삭제로 필요한 데이터까지 함께 삭제되는 경우
ex) 한 학생이 수강을 취소할 때, 필요했던 학생의 다른 필드까지 삭제되는 경우</p>
<blockquote>
<h3 id="index">Index</h3>
<p><strong>RDBMS에서 검색 속도를 높이기 위한 기술로, B+ 트리 형식을 주로 가진다.</strong>
책의 색인처럼 데이터베이스 테이블의 특정 열을 별도의 자료 구조에 저장한 뒤, 검색할 때 해당 자료 구조를 먼저 탐색하여 데이터 위치를 빠르게 찾는 방법</p>
</blockquote>
<h4 id="b-tree">B-Tree</h4>
<p>이진 트리를 확장해 하나의 노드가 가질 수 있는 자식 노드의 최대 숫자가 2보다 큰 트리 구조이다(위키피디아).
한 노드에 여러개의 값을 저장할 수 있고, 좌우 노드들의 밸런스가 보장된다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/8bbc2fcb-7c50-490a-9dff-f29fdccb72bf/image.png" alt=""></p>
<h4 id="b-tree-1">B+ Tree</h4>
<p>모든 key와 data를 리프노드에 연결리스트로 저장해 선형탐색이 가능한 구조
<img src="https://velog.velcdn.com/images/ky0_hw/post/f9510643-d4bc-4232-b59f-4951508b8113/image.png" alt=""></p>
<h4 id="인덱싱-장점">인덱싱 장점</h4>
<p><strong>빠른 데이터 검색</strong>: 인덱스의 주된 목적입니다.
<strong>정렬된 데이터 액세스</strong>: 인덱스를 통해 정렬된 순서로 데이터에 액세스할 수 있습니다.</p>
<h4 id="인덱싱-단점">인덱싱 단점</h4>
<p><strong>저장 공간</strong>: 인덱스는 추가적인 저장 공간을 필요로 합니다.
<strong>삽입/삭제 오버헤드</strong>: 인덱스가 있는 테이블에 데이터를 삽입하거나 삭제할 때, 인덱스도 함께 업데이트해야 합니다.</p>
<h4 id="인덱싱-유불리">인덱싱 유불리</h4>
<p><strong>유리할 때</strong>: 대규모 데이터에서 조회가 중요할 때, Join이 자주 발생하는 열(테이블 전체 탐색이 아닌, 인덱스를 따라가서 조인하면됨)
<strong>불리할 때</strong>: 쓰기 작업이 많을 때, 소규모 테이블일 때, 인덱스가 매우 많을 때</p>
<blockquote>
<h3 id="정규화normalization">정규화(Normalization)</h3>
<p><strong>데이터 중복을 줄이고, 무결성을 향상</strong>시키는 기법</p>
</blockquote>
<h4 id="제-1정규화1nf">제 1정규화(1NF)</h4>
<p>모든 속성이 원자값(하나의 값)만 갖도록 테이블을 분리하는 것</p>
<h4 id="제-2정규화2nf">제 2정규화(2NF)</h4>
<p>기본키에 소속된 일부 column이 색인할 수 있는 column이 존재하면 안된다. </p>
<h4 id="제-3정규화3nf">제 3정규화(3NF)</h4>
<p>2정규화가 진행된 테이블에 이행적 종속을 없애기 위해 테이블을 분리하는 것
기본키가 아닌 속성들은 기본키에 의해서만 색인되어야 한다.</p>
<h4 id="역정규화">역정규화</h4>
<p>읽기 성능 개선을 위해 정규화 작업 이전으로 돌리는 것</p>
<h4 id="정규화-장단점">정규화 장단점</h4>
<p><strong>장점</strong></p>
<ol>
<li>데이터 중복이 최소화돼 한곳만 수정해도 시스템의 일관성 유지 가능</li>
<li>중복이 줄어드는 만큼 DB 공간을 아낄 수 있다.</li>
<li>무결성을 향상해 테이블간의 관계가 명확하게 정의된다. 이는 DB의 오류를 방지하고, 추후 삽입,삭제 등의 연산에 유리하다.</li>
</ol>
<p><strong>단점</strong></p>
<ol>
<li>Join연산이 필연적으로 늘어나며, 조회 성능이 저하되고 쿼리가 복잡해진다.</li>
<li>설계 및 유지보수에 복잡성이 늘어난다.</li>
</ol>
<blockquote>
<h3 id="트랜잭션">트랜잭션</h3>
<p><strong>DB의 상태를 변화시키기 위해 수행하는 작업단위</strong>
한개 이상의 SQL문장으로 구성, 트랜잭션 시작시 영속성 컨텍스트가 배정되고, 롤백시 쿼리들 취소, 커밋시 쿼리들 적용
A가 B에게 1000원을 송금할 때, A 계좌에서 1000원이 깎였지만 B계좌에 1000원이 늘어나있지 않을 때가 일관적이지 않은 상태이다.</p>
</blockquote>
<h4 id="트랜잭션-특징acid">트랜잭션 특징(ACID)</h4>
<p><strong>Atomicity (원자성)</strong>: 트랜잭션이 모두 실행되거나 전혀 실행되지 않는 것.
<strong>Consistency (일관성)</strong>: 트랜잭션 실행 전후에 데이터의 일관성이 유지되는 것.
<strong>Isolation (격리성)</strong>: 트랜잭션들이 독립적으로 실행되어야 함.
<strong>Durability (내구성)</strong>: 트랜잭션 완료 후, 데이터는 영구적으로 저장됨.</p>
<h4 id="트랜잭션-격리-수준isolation-level">트랜잭션 격리 수준(Isolation Level)</h4>
<p>트랜잭션에서 <strong>일관성 없는 데이터</strong>(트랜잭션 처리 중에 데이터베이스가 임시 상태에 있는 경우)를 허용하는 수준
Locking으로 트랜잭션들을 순서대로 처리하면, ACID원칙의 격리성은 지켜지지만 DB의 성능이 저하된다.
가장 효율적인 Locking 방법을 사용해야 한다.
<strong>Read Uncommitted (레벨0)</strong> :
SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock이 걸리지 않는 계층
즉, A를 B로 바꾸는 트랜잭션이 커밋되지 않아도, B를 타 트랜잭션이 읽을 수 있다.
DB의 일관성을 유지할 수 없다.
<strong>Read Committed (레벨1)</strong> :
SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock이 걸리는 계층
A를 B로 바꾸는 트랜잭션이 커밋되지 않았다면, B를 접근할 수 없다.
<strong>Repeatable Read (레벨2)</strong> :
하나의 트랜잭션이 시작된 시점에서 데이터를 읽으면, 그 트랜잭션이 종료될 때까지 다른 트랜잭션이 해당 데이터를 수정할 수 없다. 트랜잭션이 여러 번 같은 데이터를 읽더라도 그 값은 항상 동일합니다.
<strong>Serializable (레벨3)</strong> : 
트랜잭션들이 서로 완전히 독립적으로 실행되는 것처럼 보이도록, 트랜잭션을 직렬화하여 처리 (트랜잭션 간의 동시성 차단)</p>
<h4 id="각-레벨의-문제">각 레벨의 문제</h4>
<p><strong>Dirty Read</strong> : 커밋되지 않은 트랜잭션의 데이터를 읽는 것
<strong>Non-Repeatable</strong> : 동일한 트랜잭션에서 같은 데이터를 여러 번 읽을 때, 다른 트랜잭션이 데이터를 수정한 경우 읽을 때마다 값이 달라질 수 있다.
<strong>Phantom Read</strong> : 트랜잭션 중에 다른 트랜잭션이 새로운 데이터를 삽입하는 경우, 삽입된 데이터를 읽을 수 있어 데이터 집합이 달라질 수 있다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/339845da-4788-4bf3-bc2b-b86170a273a8/image.png" alt=""></p>
<blockquote>
<h3 id="redis">Redis</h3>
<p>key-value구조의 인메모리 데이터베이스
디스크가 아닌 메모리(RAM)에 저장하기 때문에 디스크 스캐닝이 필요하지 않아 속도가 빠르다.
RAM은 휘발성이기 때문에, snapshot,AOF를 통해 백업한다.
캐싱도 가능해 실시간 채팅에 적합하다.
<strong>AOF</strong> : 쿼리들을 저장해두고, 서버가 셧다운되면 재실행해서 다시 만들어 놓는 것
<strong>캐싱</strong> : 자주 사용하는 데이터를 빠르게 접근할 수 있는 위치에 임시로 저장하여, 원본 데이터에 반복적으로 접근하지 않고 더 빠르게 데이터를 제공하는 기술</p>
</blockquote>
<blockquote>
<h3 id="저장-프로시저">저장 프로시저</h3>
<p><strong>프로시저</strong> : 특정 작업을 수행하기 위해 재사용 가능한 코드 블록
<strong>저장 프로시저</strong> : DB 내에 미리 저장된 SQL 쿼리나 명령어의 집합. DB 서버에 저장돼 있으며, 쿼리문이 필요할 때 인자 값만 전달하면 된다.</p>
</blockquote>
<h4 id="장단점">장단점</h4>
<p><strong>장점</strong></p>
<ol>
<li>프로시저 최초 실행 시 캐시에 저장되고, 이후 컴파일 작업을 거치치 않고 캐시에서 꺼낸다.</li>
<li>프로시저에 매개변수만 담아 전달하면 되므로 클라이언트-서버 간의 트래픽 감소</li>
</ol>
<p><strong>단점</strong></p>
<ol>
<li>C나 JAVA보다 연산속도가 느리다.</li>
<li>SQL과 호환성이 낮아 코드를 재사용하기 힘들고, 디버깅하기 힘들다.</li>
</ol>
<blockquote>
<h3 id="hadoop-vs-샤딩-vs-클러스터링-vs-리플리케이션">Hadoop vs 샤딩 vs 클러스터링 vs 리플리케이션</h3>
<p><strong>Hadoop</strong>
하둡은 HDFS를 사용해 대용량 데이터를 여러 블록으로 물리적으로 나눈 뒤 각 노드에 저장. 또한 각 데이터 블록을 3개씩 복제해 안정성 보장
<strong>샤딩</strong>
테이블을 특정 기준으로 논리적 분할한 뒤 저장하고 검색하는 것을 의미한다. 데이터를 어떻게 분산시킬 것인지, 어떻게 읽을 것인지 결정하는 것이 중요
<strong>클러스터링</strong>
여러 개의 DB를 수평적인 구조로 구성하여 Failover하는 시스템을 구축하는 방식
동일한 DB 서버를 두 대를 묶고 active-active 상태로 운영하거나 active-stanby 상태로 운영하지만 동기화 시간이 들어간다.
<strong>리플리케이션</strong>
여러 개의 DB를 master-slave 형태로 구축하고, master에 DML(Write-only)을 하고 slave에 복제(Read-only)하는 방식이다.
비동기 방식으로 노드들 간의 데이터를 동기화하지만 일관성 보장이 힘들다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/a26f80c4-796a-4d67-947b-987ec92aba29/image.png" alt="">
<img src="https://velog.velcdn.com/images/ky0_hw/post/95e301e6-b1e3-408f-9c54-72d1bc27c197/image.png" alt=""></p>
</blockquote>
<blockquote>
<h3 id="reference">Reference</h3>
<p><a href="https://gyoogle.dev/blog/computer-science/data-base/SQL%20&amp;%20NOSQL.html">https://gyoogle.dev/blog/computer-science/data-base/SQL%20&amp;%20NOSQL.html</a>
<a href="https://velog.io/@leephoter/RDBMS-%EC%99%80-NoSQL">https://velog.io/@leephoter/RDBMS-%EC%99%80-NoSQL</a>
<a href="https://velog.io/@emplam27/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-B-Plus-Tree">https://velog.io/@emplam27/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-B-Plus-Tree</a>
<a href="https://velog.io/@calis_ws/DB-%EC%A0%95%EA%B7%9C%ED%99%94-%EC%97%AD%EC%A0%95%EA%B7%9C%ED%99%94">https://velog.io/@calis_ws/DB-%EC%A0%95%EA%B7%9C%ED%99%94-%EC%97%AD%EC%A0%95%EA%B7%9C%ED%99%94</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접준비] 컴퓨터 네트워크]]></title>
            <link>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-%EC%BB%B4%ED%93%A8%ED%84%B0-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC</link>
            <guid>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-%EC%BB%B4%ED%93%A8%ED%84%B0-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC</guid>
            <pubDate>Tue, 15 Oct 2024 11:34:02 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="osi-7계층">OSI 7계층</h3>
<p><strong>통신이 일어나는 7단계 과정을 정의한 국제 표준 모델</strong>
각 <strong>계층이 분리</strong>되어 있으므로, 유지관리가 편하다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/def447c3-bab7-4fd4-97b9-bbce0527e2fd/image.jpg" alt="">
예시의 상황을 통해 알아보면 다음과 같다.
사용자가 웹 주소를 입력하면 (<strong>응용 계층</strong>),
데이터를 압축하거나 암호화하여 (<strong>표현 계층</strong>),
서버와의 세션을 설정하고 유지하며 (<strong>세션 계층</strong>),
패킷으로 나누어 신뢰성 있게 전송하고 (<strong>전송 계층</strong>),
네트워크를 통해 목적지 IP로 라우팅하며 (<strong>네트워크 계층</strong>),
물리적인 네트워크 환경을 통해 프레임을 전송하고 (<strong>데이터 링크 계층</strong>),
전기/광 신호를 통해 데이터를 실제로 전송합니다 (<strong>물리 계층</strong>).
<strong>MAC주소</strong>(Media Access Control Address) : 
 (컴퓨터, 스마트폰, 프린터 등)에 <strong>고유하게 할당된 하드웨어 주소</strong>
데이터링크 레이어에서 데이터를 적절한 장치에 보내기 위해 사용한다.</p>
</blockquote>
<blockquote>
<h3 id="tcp-handshake">TCP handshake</h3>
<p><strong>애플리케이션 사이에서 안전성을 보장하며 데이터를 통신하는 규약</strong>
TCP는 기본적으로 unreliable network에서, <strong>reliable network를 보장</strong>할 수 있도록 하는 프로토콜</p>
</blockquote>
<h4 id="3way-handshake--연결-성립">3way handshake : 연결 성립</h4>
<p><strong>1. SYN (Synchronize):</strong>
클라이언트가 서버로 SYN 패킷을 전송하여 연결을 요청합니다. 이 패킷은 클라이언트의 초기 시퀀스 번호(ISN)를 포함합니다.
<strong>2. SYN-ACK (Synchronize-Acknowledge):</strong>
서버가 클라이언트의 요청을 수신하면, 클라이언트의 시퀀스 번호에 응답하는 ACK 패킷과 함께, 자신의 초기 시퀀스 번호를 담은 SYN-ACK 패킷을 클라이언트로 보냅니다.
<strong>3. ACK (Acknowledge):</strong>
클라이언트는 서버의 SYN-ACK에 대한 응답으로 ACK 패킷을 전송합니다. 이때 클라이언트는 서버의 시퀀스 번호에 1을 더하여 응답하며, 연결이 성립됩니다.</p>
<h4 id="클라이언트의-시퀀스-번호-">클라이언트의 시퀀스 번호 :</h4>
<p><strong>TCP 통신에서</strong> 데이터 전송의 순서를 추적하고 신뢰성을 보장하기 위해 사용하는 <strong>고유한 번호</strong>. <strong>TCP는 데이터를 패킷으로 나누어 전송</strong>하는데, 이때 각 <strong>패킷이 순서대로 전송되고 도착할 수 있도록 시퀀스 번호를 부여</strong>한다.</p>
<h4 id="4-way-handshake--연결-해제">4 way handshake : 연결 해제</h4>
<p><strong>FIN (Finish):</strong>
클라이언트(또는 서버)가 연결을 종료하고 싶을 때 FIN 패킷을 전송하여, 더 이상 데이터를 전송하지 않겠다고 알립니다.
<strong>ACK (Acknowledge):</strong>
서버(또는 클라이언트)는 FIN 패킷을 수신하면 ACK 패킷을 보내고, 해당 FIN 패킷을 확인합니다. 이때 일방향 연결 종료가 이루어집니다. 즉, 클라이언트는 데이터를 더 이상 보내지 않지만, 서버는 여전히 데이터를 보낼 수 있습니다.
<strong>FIN (Finish):</strong>
서버(또는 클라이언트)가 더 이상 데이터를 전송할 필요가 없을 때, FIN 패킷을 보내 연결을 종료하겠다고 알립니다.
<strong>ACK (Acknowledge):</strong>
클라이언트(또는 서버)는 서버의 FIN 패킷을 수신한 후, ACK 패킷을 보내 연결 종료 요청을 확인하고, 양쪽 모두 연결이 해제됩니다.</p>
<blockquote>
<h3 id="tcpip-흐름제어혼잡제어">TCP/IP 흐름제어/혼잡제어</h3>
<p>TCP 프로토콜이 보장하는 <strong>reliable network는 4가지 문제</strong>가 존재한다.
<strong>1. 손실</strong> : 데이터 패킷이 네트워크 전송 중 손실되는 것 (재전송으로 해결)
<strong>2. 순서바뀜</strong> : 패킷이 순서대로 도착하지 않는 것 (시퀀스 번호로 해결)
<strong>3. 혼잡(Congestion)</strong> : 트래픽 증가로 네트워크 혼잡(혼잡제어 알고리즘으로 해결)
<strong>4. 과부하(Overload)</strong> : receiver에 과한 트래픽으로 과부하(트래픽분산으로 해결)</p>
</blockquote>
<h4 id="흐름제어혼잡제어란">흐름제어/혼잡제어란?</h4>
<p><strong>송신측과 수신측의 데이터 처리 속도 차이를 해결하는 기법</strong>
receiver가 sender에게 자신의 <strong>상태를 feedback해 지나치게 많은 패킷을 받지 않도록 조절</strong>한다.</p>
<h4 id="전체-데이터-전송-과정">전체 데이터 전송 과정</h4>
<p><strong>Application Layer (응용 계층):</strong>
송신 측에서 응용 계층은 <strong>소켓(Socket)</strong>을 통해 데이터를 전송합니다. 데이터는 TCP 소켓에 쓰여집니다.
<strong>Transport Layer (전송 계층):</strong>
응용 계층에서 넘겨받은 데이터는 <strong>세그먼트(Segment)</strong>라는 단위로 감싸집니다. TCP 프로토콜은 이 데이터에 헤더를 추가하여 세그먼트를 구성합니다. 헤더에는 시퀀스 번호와 같은 정보가 포함되며, 이 세그먼트는 네트워크 계층으로 넘겨집니다.
<strong>Send Buffer와 Receive Buffer:</strong>
데이터를 전송하기 전에 <strong>송신 측(send buffer)</strong>에 데이터를 저장합니다. 이 버퍼는 송신 중에 <strong>데이터가 손실되거나 재전송이 필요한 경우를 대비하여 데이터를 잠시 저장</strong>해두는 공간입니다.
수신 측에서도 데이터를 받으면 <strong>수신 버퍼(receive buffer)</strong>에 저장합니다. 이 버퍼는 <strong>수신된 데이터를 저장해 두고, 응용 프로그램이 데이터를 읽어 처리할 준비가 되면 읽어들입니다.</strong></p>
<h4 id="흐름-제어-flow-control">흐름 제어 (Flow Control)</h4>
<p>receive buffer가 제한한 저장 용량을 초과하는 경우 데이터 손실이 생기기 때문에 데이터 전송량을 조절해야 한다.
<strong>해결 방법</strong>
<strong>1. Stop and Wait</strong> :
매번 전송한 패킷에 대해 확인 응답을 받아야 다음 패킷을 전송하는 방법
<strong>2. Sliding Window</strong>
receiver가 수신할 수 있는 데이터의 윈도우 크기만큼 sender가 세그먼트를 전송할 수 있게 하는 동적 데이터 흐름 조절 기법</p>
<h4 id="혼잡-제어-congestion-control">혼잡 제어 (Congestion Control)</h4>
<p><strong>네트워크 내에 패킷의 수가 과도하게 증가하는 혼잡 현상을 방지하거나 제거하는 기법</strong>
흐름제어가 송수신자의 전송 속도를 다루지만, 혼잡제어는 호스트와 라우터를 포함한 넓은 관점에서 문제를 다룬다.
<strong>해결 방법</strong>
<strong>1. AIMD</strong> :
패킷을 한개씩 보내면서 문제가 없으면 <strong>Window(단위시간에 보내는 패킷 수) 크기를 1씩 증가</strong>시키는 기법
패킷 전송에 <strong>실패하면 패킷 보내는 속도를 절반</strong>으로 줄인다.
<strong>2. Slow Start</strong> :
AIMD와 같은 방식으로 작동하며 <strong>Window 크기를 2배씩</strong> 늘려간다.
<strong>혼잡 발생시 Window 크기를 1</strong>로 떨어뜨린다.</p>
<blockquote>
<h3 id="udp-통신">UDP 통신</h3>
<p><strong>비연결형, 신뢰성 없는 전송 프로토콜</strong>
Transport Layer에서 사용하는 프로토콜이다.</p>
</blockquote>
<h4 id="tcp-udp-탄생-배경">TCP, UDP 탄생 배경</h4>
<ol>
<li><strong>IP는 Host to Host(장치-&gt;장치)만 지원</strong>한다. <strong>하나의 장비 안에서 수많은 프로그램이 통신할 경우를 위해 포트 번호</strong>가 탄생</li>
<li><strong>IP에서 패킷 전송 중 오류 발생시</strong>, ICMP에서 알려주지만 <strong>해결하지 못하기에 상위 프로토콜인 TCP와 UDP</strong>가 탄생</li>
</ol>
<p><strong>ICMP</strong> : 운영체제에서 오류 메시지를 전송받는 인터넷 제어 메시지 프로토콜</p>
<h4 id="tcp-vs-udp">TCP vs UDP</h4>
<p><strong>UDP</strong>:
TCP보다 <strong>헤더의 용량이 작아 데이터 처리가 빠르고</strong>, 가격이 저렴하다. (<strong>비연결성</strong>)
UDP는 <strong>IP의 기능 위에 포트 번호, 체크섬을 통한 오류 검출 등의 기능을 추가</strong>하여, 다중 애플리케이션 통신과 신뢰성 있는 데이터 전송을 일부 제공하며, 특히 실시간 애플리케이션에 적합(온라인 게임, 화상 회의)
<strong>TCP</strong>
데이터의 안정성을 보장하지만, 처리가 느리고 가격이 비싸다.(연결성)
이메일 전송, 파일 전송에 유리</p>
<h4 id="dns가-udp를-사용하는-이유">DNS가 UDP를 사용하는 이유</h4>
<ol>
<li>TCP가 3-way handshake를 사용하는 반면, UDP는 connection 을 유지할 필요가 없음.</li>
<li>DNS request는 UDP segment에 꼭 들어갈 정도로 작음.</li>
<li>UDP는 not reliable이나, reliability는 application layer에 추가될 수 있음. (Timeout 추가나, resend 작업을 통해)</li>
</ol>
<blockquote>
<h3 id="대칭키-공개키">대칭키, 공개키</h3>
</blockquote>
<h4 id="대칭키symmetric-key">대칭키(Symmetric Key)</h4>
<p>암호화와 복호화에 같은 암호키를 사용해서 빠르지만 해킹 위험 존재</p>
<h4 id="비대칭-키asymmetric-key--공개키public-key-개인키private-key">비대칭 키(Asymmetric key) : 공개키(public key), 개인키(private key)</h4>
<p>암호화와 복호화에 사용하는 암호키를 분리한 알고리즘
A의 공개키로 암호화한 데이터는 A의 개인키로만 복호화할 수 있다.
<strong>대칭키와 비대칭키 방식을 혼합하면 SSL 탄생의 시초가 된다.</strong>
<strong>디지털 서명</strong> : 개인키로 서명하고, 공개키로 복호화하면 데이터 전송자를 확인할 수 있으며, 데이터 변조 여부를 확인할 수 있다.</p>
<blockquote>
<h3 id="http-https">HTTP, HTTPS</h3>
<p><strong>HTTP(HyperText Transfer Protocol)</strong> : 인터넷에서 <strong>클라이언트와 서버가 자원을 주고받을 때 쓰는 통신 규약</strong>
HTTP는 <strong>텍스트 기반 프로토콜</strong>로 동작하며, <strong>텍스트 형식으로 데이터를 주고받는다</strong>.
<strong>HTTPS(HTTP Secure)</strong> : 인터넷에서 정보를 암호화하는 SSL 프로토콜을 사용해 텍스트를 암호화한다.</p>
</blockquote>
<h4 id="tlsssl-handshake">TLS/SSL Handshake</h4>
<p><img src="https://velog.velcdn.com/images/ky0_hw/post/57cdb283-4eb6-4d10-9c58-440457dfa67b/image.jpg" alt="">
Client Hello와 Server Hello를 통해 SSL 버전을 맞추고, 생성한 난수를 바탕으로 브라우저에서 대칭키를 만든다. 이 대칭키를 서버에서 암호화해 데이터를 전송하는 것이 SSL/TLS Handshake 과정이다.</p>
<blockquote>
<h3 id="loadbalancerlb">LoadBalancer(LB)</h3>
<p><strong>Scale-up</strong> : HW 사양을 올리는 것
<strong>Scale-out</strong> : 여러대의 서버로 부하를 나누는 것
HW 향상 비용이 비싸기에 Scale-out 기법을 선택하고, LB로 요청을 분산시키는 것이 효율적이다.</p>
</blockquote>
<h4 id="lb-알고리즘">LB 알고리즘</h4>
<p><strong>1. 라운드로빈(RR)</strong> : 각 대상에게 요청을 차례대로 전달하는 방식
<strong>2. Least Connection</strong> : 트래픽이 가장 적은 서버 선택
<strong>3. Source</strong> : 사용자 IP를 해싱해서 분배 (특정 사용자가 항상 같은 서버로 연결)</p>
<blockquote>
<h3 id="blockingnon-blocking--synchronousasynchronous">Blocking/Non-Blocking &amp; Synchronous/Asynchronous</h3>
<p><strong>Blocking</strong> : 함수 B는 내 할 일을 다 마칠 때까지 제어권을 가지고 있는다. A는 B가 다 마칠 때까지 기다려야 한다.
<strong>Non-blocking</strong> : 함수 B는 할 일을 마치지 않았어도 A에게 제어권을 바로 넘겨준다. A는 B를 기다리면서도 다른 일을 진행할 수 있다.
<strong>Synchronous</strong> : 함수 A는 함수 B가 일을 하는 중에 기다리면서, 현재 상태가 어떤지 계속 체크한다.
<strong>Asynchronous</strong> : 함수 B의 수행 상태를 B 혼자 직접 신경쓰면서 처리한다. B의 작업이 종료되면 A로 callback이 온다.
즉 <strong>블락은 주도권을 주는지 바로 받아오는지</strong>의 문제고, <strong>동기는 계속 상태를 체크하는지 안하는지</strong>의 문제이다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/85e81c28-36e8-4a42-81cd-e30f707ddba5/image.png" alt=""></p>
</blockquote>
<h4 id="non-blockasynchronous">Non-Block/Asynchronous</h4>
<p><strong>Non-blocking:</strong> 요청한 작업이 즉시 반환되고, 작업이 완료되지 않았으면 계속해서 다른 작업을 처리합니다. <strong>작업이 끝났는지 여부는 프로세스가 직접 확인</strong>해야 합니다(예: 폴링).
<strong>Asynchronous: *<em>작업이 비동기적으로 백그라운드에서 진행되며, *</em>작업이 완료되면 별도의 방식으로 완료 사실을 통보받습니다</strong>(callback)</p>
<blockquote>
<h3 id="reference">Reference</h3>
<p><a href="https://gyoogle.dev/blog/computer-science/network/OSI%207%EA%B3%84%EC%B8%B5.html">https://gyoogle.dev/blog/computer-science/network/OSI%207%EA%B3%84%EC%B8%B5.html</a>
<a href="https://jungeun960.tistory.com/181">https://jungeun960.tistory.com/181</a>
<a href="https://grip.news/archives/1304/">https://grip.news/archives/1304/</a>
GPT...</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접준비] 금융IT]]></title>
            <link>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-%EA%B8%88%EC%9C%B5IT</link>
            <guid>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-%EA%B8%88%EC%9C%B5IT</guid>
            <pubDate>Tue, 15 Oct 2024 07:30:33 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="0-it-ict-iot">0. IT, ICT, IoT</h3>
<p><strong>IT (Information Technology)</strong>: 
정보기술로, 로 하드웨어, 소프트웨어, 네트워크 인프라를 통해 조직의 업무를 자동화하고 지원하는 데 중점을 둔다.
<strong>ICT (Information and Communication Technology)</strong>:
정보 통신 기술은 정보 기술(IT)과 통신 기술을 결합한 더 포괄적인 개념으로, 정보의 수집, 저장, 처리 및 전송을 지원하는 모든 기술 (<strong>통신과 관련된 it기술</strong>)
ex) 디지털 뱅킹 : 인터넷과 모바일을 통해 금융 서비스 제공
ex) 빅데이터 분석 : 핀테크에서 고객의 금융 데이터를 분석하여 맞춤형 금융 상품을 제공
<strong>IoT (Internet of Things)</strong>:
사물 인터넷은 다양한 기기들이 인터넷에 연결되어 서로 데이터를 주고받을 수 있는 기술이다.
ex) 자동차 운전 데이터를 실시간으로 수집해 맞춤형 보험료를 산정하는 서비스
ex) 스마트 냉장고가 식료품이 부족할 때 자동으로 결제를 진행하는 등의 자동화된 금융 서비스</p>
</blockquote>
<blockquote>
<h3 id="1-금융-기초상식">1. 금융 기초상식</h3>
</blockquote>
<h4 id="금융이란">금융이란?</h4>
<p><strong>&quot;금전의 융통&quot;</strong>은 여유자금을 가진 사람이나 기업(자금운용자)과 자금이 부족한 사람이나 기업(자금조달자) 사이에서 돈을 융통해 주는 것</p>
<h4 id="금융의-기능">금융의 기능</h4>
<p><strong>결제</strong> : 금융주체 간에 자금을 이동하는 것
<strong>자금 공여</strong> : 자금을 모아 자금 조달자에게 빌려주는 것 (대출, 정기예금, 신용카드)
<strong>자금 운용</strong> : 자금운용자가 금융상품 구입 등을 통해 자금조달자에게 자금을 공급하는것(주식, 채권, 예금)
<strong>리스크 이전</strong> : 사망, 사고, 질병, 재해 등의 리스크에 대한 보전(보험, 선물, 옵션)</p>
<h4 id="금융시장">금융시장</h4>
<p>기업, 가계, 정부 등 경제주체가 금융상품을 거래하여 필요한 자금을 조달하고, 여유자금을 운용(투자)하는 조직화된 장소</p>
<h4 id="금융기관">금융기관</h4>
<p>여유자금을 운용(투자)하는 조직화된 장소, 돈의 융통을 중개하고 수수료를 받음
<strong>은행</strong> : 대출, 환업무(송금, 입금, 계좌이체 등)
<strong>보험회사</strong> : 보험료를 모아 특정 이벤트 발생 시 보험금 지급
<strong>주식시장</strong> : 유가증권 발행(언더라이팅), 발행된 유가증권의 거래.
<strong>투자신탁회사</strong> : 투자신탁을 운용, 발행</p>
<blockquote>
<h3 id="2-지급결제">2. 지급결제</h3>
<p><strong>경제활동 과정에서 돈을 주고받아야 하는 지급인(채무자)과 수취인(채권자) 간의 채권·채무관계를 화폐가치의 이전을 통해 해소하는 것</strong>
예를 들어, A가 B에게 계좌이체를 한다면 각 금융기관은 다음의 역할을 한다.
<strong>A의 은행</strong>: A의 계좌에서 금액을 차감하고 송금을 요청.
<strong>금융결제원</strong>: A의 은행과 B의 은행 간의 자금 이체를 중개.
<strong>B의 은행</strong>: B의 계좌로 금액을 입금.
<strong>한국은행</strong>: 두 은행 간의 자금 정산을 최종적으로 처리.
<strong>금융 IT 도입 목적</strong> : 현금은 운영비용이 비싼 통화 수단이기 때문에, 편리하고 효율적으로 금융거래를 하기 위해 도입됐다. 하지만, IT시스템의 다양화, 복잡화로 인한 운영리스크, 네트워크화로 인한 전산사고 리스크 등의 문제가 존재한다.</p>
</blockquote>
<blockquote>
<h3 id="3-금융it-시스템">3. 금융IT 시스템</h3>
<p><strong>금융시스템</strong>이란 금융시장, 금융기관을 형성하고 운영하는 금융 인프라를 모두 포괄하는 개념이다.
은행, 증권사 등 금융기관마다 구성하는 전산 시스템은 다르다.</p>
</blockquote>
<h4 id="금융기관-전산시스템">금융기관 전산시스템</h4>
<p><strong>계정계</strong> : 고객의 거래 데이터를 처리하는 시스템. 거래의 핵심요소인 통장을 계좌, 계정이라고도 부르는데 이러한 계정을 관리하는 시스템을 모아 &#39;계정계&#39;
<strong>정보계</strong> : 계정계에서 얻은 데이터를 바탕으로 거래 활동 및 성과를 측정하고 분석하는 업무를 처리
<strong>대외계</strong> : 은행 외부기관과의 연계업무를 위해 구축하는 시스템
<strong>채널계</strong> : End User (사용자)가 접속하는 다양한 채널의 데이터를 관리하는 시스템(ATM, 콜센터, 모바일뱅킹 ...)
<strong>운영계</strong> : 위의 시스템들이 올라간 서버를 기준으로 IT 인프라(H/W, S/W), 네트워크, 보안 영역을 운영하는 업무</p>
<h4 id="금융공동망">금융공동망</h4>
<p><strong>금융기관 간 각종 금융거래와 정보를 처리하는 네트워크</strong>
한국은행, 금융결제원, 한국거래소, 한국예탁결제원 등이 존재한다.</p>
<blockquote>
<h3 id="4-금융it의-미래">4. 금융IT의 미래</h3>
<p>금융산업은 현재 맞춤형 금융서비스, 금융플랫폼 구축 경쟁, 신용평가 체계의 고도화, 비대면 금융거래 확대, 지급결제 수단의 간편-다양화, 신용화폐의 범용화 등으로 발전하고 있다.</p>
</blockquote>
<h4 id="핀테크">핀테크</h4>
<p><strong>금융(Fin<del>ance</del>)+기술(Tech<del>nology</del>)</strong>를 지칭한다. 즉, 정보기술을 활용해 새로운 형태의 금융서비스를 제공하는 것이다.
<strong>비금융기관, ICT기업이 금융업에 진출</strong>하거나, <strong>기존 금융기관 IT 시스템의 확장</strong></p>
<h4 id="핀테크의-사업-영역">핀테크의 사업 영역</h4>
<p><strong>1. 송금+간편결제</strong> : &#39;카카오페이, 토스&#39;처럼 ICT 기업이 주
<strong>2. 크라우드 펀딩</strong> : &#39;와디즈&#39;처럼 대중이 함께 만드는 기금(후원, 기부, 대출)
<strong>3. P2P 대출</strong> : &#39;8퍼센트&#39;처럼 자금운용자와 자금조달자를 온라인에서 직접 연결 -&gt; 대출금리가 낮다.
<strong>4. 자산관리/소셜투자</strong> : &#39;뱅크샐러드&#39;처럼 투자 정보 제공, 공유
<strong>5. 보험</strong> : &#39;레모네이드&#39;는 IoT 및 인공지능(AI)을 활용한 보험 서비스를 제공합니다. 사용자가 보험금을 청구하면 AI가 자동으로 청구를 처리해 주며, 빠르고 간편한 보험 청구를 가능하게 합니다</p>
<h4 id="핀테크의-강점">핀테크의 강점</h4>
<p><strong>무점포 인터넷 은행</strong>이기 때문에, 점포 개설과 운영에 필요한 비용을 절감하여 <strong>예금 금리, 대출금리, 수수료</strong>등을 절감한다.
또한 IoT기술을 적극 활용해 고객 맞춤형 서비스를 제공하고, 시공간의 제약이 없다.</p>
<h4 id="시중은행의-핀테크-대응책gpt-답변">시중은행의 핀테크 대응책(GPT 답변)</h4>
<p><strong>디지털 전환 가속화</strong>: 시중은행들은 핀테크 기업들과의 경쟁에서 살아남기 위해 디지털 혁신을 가속화해야 합니다. 인터넷과 모바일 기반 금융 서비스를 더욱 발전시켜, 기존 오프라인 고객들을 온라인으로 자연스럽게 유도할 수 있습니다. 예를 들어, 신한은행은 SOL이라는 디지털 플랫폼을 통해 다양한 맞춤형 금융 상품을 제공하며 경쟁력을 강화하고 있습니다.
<strong>핀테크와의 협업</strong>: 시중은행들이 핀테크 기업들과 경쟁하는 대신, 협업하는 방안도 있습니다. 일부 시중은행들은 API 개방을 통해 핀테크 기업들이 은행의 금융 시스템을 활용할 수 있게 하고, 이를 통해 새로운 금융 서비스를 창출하도록 돕습니다. 이는 상생의 방식으로 핀테크와의 경쟁에서 시너지를 낼 수 있습니다.
<strong>차별화된 고객 서비스 제공</strong>: 기존 은행들은 IoT, AI 등 신기술을 활용한 맞춤형 서비스를 제공함으로써 경쟁력을 유지할 수 있습니다. 예를 들어, KB국민은행은 고객의 금융 데이터를 분석해 맞춤형 자산관리 서비스를 제공하고, 챗봇을 통해 24시간 고객 지원 서비스를 운영하고 있습니다.
<strong>비대면 서비스 확대</strong>: 핀테크 기업들이 강조하는 비대면 금융 서비스를 더욱 확대하여, 시공간의 제약을 뛰어넘는 금융 서비스를 제공해야 합니다. 하나은행의 하나원큐는 비대면 계좌 개설과 대출, 송금 서비스 등을 통해 비대면 금융 서비스를 강화하고 있습니다.
<strong>차별화된 금융상품 개발</strong>: 시중은행들은 고유의 신뢰성과 규모를 바탕으로, 핀테크 기업들이 쉽게 제공할 수 없는 차별화된 금융상품을 개발할 수 있습니다. 예를 들어, 장기적으로 안정적인 자산 운용이 필요한 고객들에게 맞춤형 장기 투자 상품이나 퇴직연금과 같은 특화 상품을 제공하여 경쟁력을 유지할 수 있습니다</p>
<blockquote>
<h3 id="reference">Reference</h3>
<p><a href="https://www.slideshare.net/slideshow/it-1-202201/250974315#2">https://www.slideshare.net/slideshow/it-1-202201/250974315#2</a>
<a href="https://smallrich.tistory.com/79">https://smallrich.tistory.com/79</a>
GPT...</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접준비] JAVA]]></title>
            <link>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-JAVA</link>
            <guid>https://velog.io/@ky0_hw/%EB%A9%B4%EC%A0%91%EC%A4%80%EB%B9%84-JAVA</guid>
            <pubDate>Tue, 01 Oct 2024 08:42:38 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="java-단골질문">JAVA 단골질문</h3>
<p><a href="https://dev-coco.tistory.com/153">Reference</a></p>
</blockquote>
<h3 id="컴파일-과정">컴파일 과정</h3>
<p><strong>JAVA는 OS에 독립적이다. JVM덕분</strong>
java코드 작성 -&gt; 자바 컴파일러가 class코드로 컴파일(JVM이 이해할수 있는 코드인 바이트코드)
-&gt;class코드를 JVM의 클래스로더로 전달 -&gt; 클래스로더가 동적로딩으로 필요한 클래스들을 로딩 및 링크하여 런타임 데이터 영역(JVM메모리)에 올린다 -&gt; 실행엔진이 JVM 메모리에 올라온 바이트 코드들을 명령어 단위로 가져와서 실행</p>
<blockquote>
<h3 id="call-by-value-call-by-reference">Call by value, Call by reference</h3>
<p><strong>JAVA는 오직 Call by value로 동작</strong>
JAVA는 참조를 직접 전달하는 것이 아닌, 값을 전달하는 방식으로만 동작한다.
변수를 선언하면 JVM메모리의 Stack에 변수가 저장되는데, Primitive Type(원시타입)은 값과 함께 저장되고, Reference Type(참조타입)은 객체는 Heap에 저장되고 Stack의 변수에 객체의 주소값을 저장한다.
즉, 객체를 넘겨도 <strong>그 객체의 주소값</strong>을 넘기므로, 파라미터에 선언되어 있는 변수가 스택에 잡히면서 해당 주소값을 가지고 있다. 따라서 해당 주소값에 접근해 값을 변경할 수는 있지만, 새로운 객체를 할당하면 함수가 종료되면서 가비지컬렉터가 메모리(Heap)에서 새롭게 할당된 객체를 제거한다.</p>
</blockquote>
<blockquote>
<h3 id="string-stringbuilder-stringbuffer">String, StringBuilder, StringBuffer</h3>
<p><strong>String은 참조타입이며, 불변하는 객체이다.</strong>
따라서 String객체간 비교는 .equals()메소드를 사용해야 한다.
불변이기 때문에, 문자열의 조작이 일어나면 새로운 객체를 Heap에 생성하고, Stack의 변수에 새롭게 할당하는 구조이다. 따라서 가비지 컬렉터의 업무가 합쳐져 성능 문제가 생긴다.
StringBuilder와 StringBuffer는 버퍼 크기가 유동적이기에, String처럼 문자열 조작에서 성능 문제가 생기지 않는다. StringBuffer는 동기화를 제공하고, StringBuilder는 동기화를 제공하지 않는다.
따라서 <strong>멀티스레드 환경에선 StringBuffer, 단일스레드 환경에선 StringBuilder</strong>가 유리하다.</p>
</blockquote>
<blockquote>
<h3 id="오토-박싱-언박싱">오토 박싱, 언박싱</h3>
<p><strong>기본타입</strong> : int, long, float, double...
<strong>Wrapper 클래스</strong> : Integer, Long, Float, Double, Boolean...
<strong>박싱</strong> : 기본타입 -&gt; Wrapper클래스
<strong>언박싱</strong> : Wrapper클래스 -&gt; 기본타입
<strong>오토 박싱, 언박싱</strong> : 자바 컴파일러가 박싱과 언박싱이 필요한 상황에 자동으로 처리해준다.</p>
</blockquote>
<blockquote>
<h3 id="직렬화">직렬화</h3>
<p>각자 PC의 OS마다 서로 다른 가상 메모리 주소 공간을 갖기 때문에, Reference Type의 데이터들은 인스턴스를 전달 할 수 없다.
따라서, <strong>주소값이 아닌 Byte 형태의 Primitive 타입으로 직렬화해 전송 및 저장이 가능한 데이터로 만드는 것</strong>이 직렬화다.
데이터 통신 상에서 전송 및 저장을 위해 사용하는 방법이다. 이 때, 직렬화 데이터는 사이즈가 크므로 JSON포맷으로 변경하는 것이 좋다.
<strong>JSON(JavaScript Object Notation)</strong> : 사용하는 언어에 관계 없이 텍스트를 기반으로 데이터를 교환,저장하도록 정한 데이터 교환 표준</p>
</blockquote>
<blockquote>
<h3 id="object-클래스">Object 클래스</h3>
<p><strong>JAVA의 최상위 클래스는 Object 클래스이다.</strong>
toString(), hashCode(), wait(), notify(), notifyAll() 등의 메소드를 공통으로 가지고 있다.
wait는 스레드를 잠들게 하며, notify는 임의의 스레드를 깨운다.</p>
</blockquote>
<blockquote>
<h3 id="캐스팅">캐스팅</h3>
<p><strong>변수가 원하는 정보를 다 갖고 있는 것</strong>
다형성과 상속을 지원하기 위해 묵시적 형변환(업캐스팅), 명시적 형변환(다운캐스팅)이 존재한다.</p>
</blockquote>
<blockquote>
<h3 id="스레드">스레드</h3>
<p><strong>프로세스는 운영체제로부터 시스템 자원을 할당받는 작업의 단위이고, 스레드는 프로세스 내에서 실행되는 여러 흐름의 단위</strong>이다. 
즉, 스레드는 프로세스가 할당받은 CPU와 리소스들을 사용한다.
JAVA에서 스레드는 Runnable 인터페이스 구현, Thread 클래스 상속으로 구현할 수 있다.
스레드를 이용하면, JVM이 다수의 콜 스택을 번갈아가며 실행하는 Context Switching 작업을 수행한다.
<strong>동기화</strong> : 멀티스레드 환경에서, 같은 프로세스 내의 자원을 공유하며 각 스레드의 작업들이 서로 영향을 주기 때문에 필수적이다.
<strong>임계 영역(critical section)</strong> : 공유 자원에 단 하나의 스레드만 접근하도록(하나의 프로세스에 속한 스레드만 가능)
<strong>뮤텍스(mutex)</strong> : 공유 자원에 단 하나의 스레드만 접근하도록(서로 다른 프로세스에 속한 스레드도 가능)
<strong>이벤트(event)</strong> : 특정한 사건 발생을 다른 스레드에게 알림
<strong>세마포어(semaphore)</strong> : 한정된 개수의 자원을 여러 스레드가 사용하려고 할 때 접근 제한
<strong>대기 가능 타이머(waitable timer)</strong> : 특정 시간이 되면 대기 중이던 스레드 깨움</p>
</blockquote>
<blockquote>
<h3 id="jvm">JVM</h3>
<p><strong>OS에 종속받지 않고 CPU가 JAVA를 인식, 실행할 수 있게 하는 가상 컴퓨터</strong>
<strong>프로그램 메모리를 관리하고 최적화하는 것이 목표</strong></p>
</blockquote>
<ol>
<li>프로그램이 실행되면 JVM은 OS로부터 필요한 메모리를 할당받음</li>
<li>자바 컴파일러가 자바 소스코드를 자바 바이트코드(.class)로 변환</li>
<li>class파일을 클래스 로더를 통해 JVM 메모리 영역으로 로딩</li>
<li>로딩된 class파일들을 Execution Engine으로 해석</li>
<li>해석된 바이트 코드를 메모리에 올림, 이 때 JVM에 의해 스레드 동기화, 가비지 컬렉션 등의 관리작업이 들어감</li>
</ol>
<p><strong>JVM 메모리의 스택, 힙을 구분하는 것이 가장 중요</strong></p>
<blockquote>
<h3 id="가비지-컬렉션gc">가비지 컬렉션(GC)</h3>
<p><strong>사용하지 않는 객체는 메모리(힙)에서 삭제하는 작업</strong>
<strong>Minor GC</strong> : Young Generation(생성된지 얼마 안된 객체)를 대상으로 빠르게 GC작업 수행
<strong>Major GC</strong> : Old Generation(생성된지 꽤 된 객체)를 대상으로 느리게 GC작업 수행
<strong>Eden Space</strong> : 새로 생성된 객체가 할당되는 영역. 가득차면 Minor GC가 발생하며, 참조되고 있는 객체는 <strong>Survivor</strong> 영역으로 보낸다.
<strong>Survivor Space</strong> : 2개의 영역이 존재하며, 1번 영역이 가득 차면 2번 영역으로 이동한다. 끝까지 살아남으면 Old Generation으로 이동한다.
<strong>Minor GC에서 살아남은 숫자를 Age라고 하고, Age Threshold를 넘으면 old generation으로 promotion된다.</strong></p>
</blockquote>
<blockquote>
<h3 id="error--exception">Error &amp; Exception</h3>
<p><strong>Error의 상황을 미리 미연에 방지하기 위해서 Exception 상황을 만들 수 있으며, java에서는 try-catch문으로 Exception handling을 할 수 있습니다.</strong>
<strong>Error</strong> : 컴파일에러와 런타임에러(메모리 부족 등)처럼 프로세스가 종료될 정도의 문제(복구시도 X)
<strong>Exception</strong> : Not Found같이 애플리케이션이 복구 가능한, 복구를 시도하는 문제
<strong>Checked Exception</strong> : RuntimeException을 제외한 모든 예외. 처리하지 않으면 컴파일되지 않는다. ex)IO, SQL 
<strong>Unchecked Exception</strong> : RuntimeException의 하위 예외 ex)NullPointer, IndexOutOfBound
<strong>Throwable 클래스</strong> : 예외처리 최상위 클래스. Exception과 Error 모두 Throwable 클래스를 상속받는다.
<strong>Exception Handling</strong> : try catch문을 사용하거나, throws Exception으로 호출한 쪽이 책임지도록 유도한다.</p>
</blockquote>
<blockquote>
<h3 id="java-stream">JAVA Stream</h3>
<p>Collection과 Stream은 <strong>데이터 계산 시점</strong>에 차이가 있다.
<strong>Collection</strong> : 모든 값을 메모리에 저장하며, 저장하기 전 미리 계산이 완료되어 있어야 한다. <strong>외부반복</strong>을 통해 요소를 가져온다.
<strong>Stream</strong> : 요청할 때 요소를 계산한다. <strong>내부반복</strong>을 통해 추출 요소를 선언해주면 알아서 반복처리한다. 요소를 따로 추가, 제거는 못한다.
<strong>내부연산</strong> : 작업을 병렬처리하며 최적화된 순서로 처리한다. 외부반복은 명시적으로 컬렉션의 항목을 한개씩 가져와 처리한다.
<strong>Stream 중간 연산</strong>
filter(Predicate) : Predicate를 인자로 받아 true인 요소를 포함한 스트림 반환
distinct() : 중복 필터링
limit(n) : 주어진 사이즈 이하 크기를 갖는 스트림 반환
skip(n) : 처음 요소 n개 제외한 스트림 반환
map(Function) : 매핑 함수의 result로 구성된 스트림 반환
flatMap() : 스트림의 콘텐츠로 매핑함. map과 달리 평면화된 스트림 반환
<strong>중간 연산은 모두 스트림을 반환한다.</strong>
<strong>Stream 최종 연산</strong>
(boolean) allMatch(Predicate) : 모든 스트림 요소가 Predicate와 일치하는지 검사
(boolean) anyMatch(Predicate) : 하나라도 일치하는 요소가 있는지 검사
(boolean) noneMatch(Predicate) : 매치되는 요소가 없는지 검사
(Optional) findAny() : 현재 스트림에서 임의의 요소 반환
(Optional) findFirst() : 스트림의 첫번째 요소
reduce() : 모든 스트림 요소를 처리해 값을 도출. 두 개의 인자를 가짐
collect() : 스트림을 reduce하여 list, map, 정수 형식 컬렉션을 만듬
(void) forEach() : 스트림 각 요소를 소비하며 람다 적용
(Long) count : 스트림 요소 개수 반환</p>
</blockquote>
<blockquote>
<h3 id="composition">Composition</h3>
<p><strong>기존 클래스가 새로운 클래스의 구성요소가 되는 것</strong></p>
</blockquote>
<blockquote>
<h1 id="solid">SOLID</h1>
<p>SRP - 단일 책임 원칙 : 한 클래스는 하나의 책임만 가져야 한다.
OCP - 개방-폐쇄 원칙 : 확장에는 열려있고, 수정에는 닫혀있어야 한다.
LSP - 리스코프 치환 원칙 : 하위 타입은 항상 상위 타입을 대체 할 수 있어야 한다.
ISP - 인터페이스 분리 원칙 : 인터페이스 내에 메소드는 최소한 일수록 좋다. (하나의 일반적인 인터페이스보다 여러 개의 구체적인 인터페이스가 낫다.) SRP와 같은 문제에 대한 두 가지 다른 해결책이다.
DIP - 의존관계 역전 원칙 : 구체적인 클래스보다 상위 클래스, 인터페이스, 추상클래스와 같이 변하지 않을 가능성이 높은 클래스와 관계를 맺어라. DIP 원칙을 따르는 가장 인기 있는 방법은 의존성 주입(DI)이다.
출처: <a href="https://dev-coco.tistory.com/153">https://dev-coco.tistory.com/153</a> [슬기로운 개발생활:티스토리]</p>
</blockquote>
<blockquote>
<h3 id="reference">Reference</h3>
<p><a href="https://gyoogle.dev/blog/computer-language/Java/%EC%BB%B4%ED%8C%8C%EC%9D%BC%20%EA%B3%BC%EC%A0%95.html">https://gyoogle.dev/blog/computer-language/Java/%EC%BB%B4%ED%8C%8C%EC%9D%BC%20%EA%B3%BC%EC%A0%95.html</a>
GPT</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[삼성SW] 고대 문명 유적 탐사]]></title>
            <link>https://velog.io/@ky0_hw/%EC%82%BC%EC%84%B1SW-%EA%B3%A0%EB%8C%80-%EB%AC%B8%EB%AA%85-%EC%9C%A0%EC%A0%81-%ED%83%90%EC%82%AC</link>
            <guid>https://velog.io/@ky0_hw/%EC%82%BC%EC%84%B1SW-%EA%B3%A0%EB%8C%80-%EB%AC%B8%EB%AA%85-%EC%9C%A0%EC%A0%81-%ED%83%90%EC%82%AC</guid>
            <pubDate>Wed, 11 Sep 2024 10:01:23 GMT</pubDate>
            <description><![CDATA[<p>문제 : <a href="https://www.codetree.ai/training-field/frequent-problems/problems/ancient-ruin-exploration/description?page=1&amp;pageSize=5">코드트리</a></p>
<blockquote>
<h3 id="풀이-방식">풀이 방식</h3>
<p>아래의 3개가 한 턴에 이루어지며, 총 K개의 턴을 반복해야 한다.</p>
</blockquote>
<ol>
<li>(1,1)<del>(1,3), ... , (3,1)</del>(3,3)까지 각각 3개의 각도로 회전해보며 조건에 맞는 적합한 회전 조건을 구한다.</li>
<li>조건에 맞게 회전한다.</li>
<li>유물이 찾아지지 않을 때까지 유물을 찾고, 리필하고를 반복한다.<blockquote>
<h3 id="배운-점">배운 점</h3>
</blockquote>
<h4 id="1회전시-좌표-구하기">1.회전시 좌표 구하기</h4>
<img src="https://velog.velcdn.com/images/ky0_hw/post/62b728f2-75b1-4cd2-853d-061c5460f07a/image.jpeg" alt="">
회전 후 (i,j)의 좌표에 들어갈 값을 기존 배열의 (x,y)로 가정한 후, 방정식을 풀어 (x,y)값을 구하는 식으로 계산하면 편하다.
그리고, copy[i][j]에 board[x][y] 값을 옮길 때, board에서 회전시킬 부분만 따로 복사해서 사용하는 것이 훨씬 편하다.
이문제에선 회전할 3x3 배열만 따로 복사해두었다.<h4 id="2-2차원-벡터는-fill보다-2중-for문으로-채우자">2. 2차원 벡터는 fill보다 2중 for문으로 채우자</h4>
2차원 벡터는 벡터 내부에 벡터들이 존재하기 때문에, 단일 시퀀스를 대상으로 동작하는 fill을 사용하려면 결국 for문을 돌아야한다. 그냥 2중 for문을 사용하자<h4 id="3-우선순위-큐의-비교연산자cmp를-커스텀-할-때는-무조건-struct로-만들어주어야-한다">3. 우선순위 큐의 비교연산자(cmp)를 커스텀 할 때는, 무조건 struct로 만들어주어야 한다.</h4>
<h4 id="4-큐와-벡터는-clear함수가-없다">4. 큐와 벡터는 clear()함수가 없다.</h4>
while(!큐.empty() {큐.pop();} 으로 처리하자.<h4 id="5-다른-함수로-큐나-벡터-등을-보내고-값을-넣고싶다면-함수를-선언할-때-파라미터에-주소선언을-하자">5. 다른 함수로 큐나 벡터 등을 보내고, 값을 넣고싶다면 함수를 선언할 때 파라미터에 주소선언을 하자</h4>
<pre><code>void dfs2(int index, int y, int x, vector&lt;vector&lt;bool&gt;&gt;&amp; visited, vector&lt;pair&lt;int, int&gt;&gt;&amp; pv) 
{
}</code></pre>이런식으로 파라미터에 <strong>&quot;타입&amp; 변수명&quot;</strong> 으로 받으면 받은 벡터나 큐에 값을 더하거나 뺀 후 반환해도 변화가 반영되어있다.<h4 id="6-nexty-nextx의-유효성을-체크할-때-순서주의">6. nextY, nextX의 유효성을 체크할 때 순서주의</h4>
<pre><code>if(nextY&lt;0||nextY&gt;4||nextX&lt;0||nextX&gt;4||visited[nextY][nextX]||copy[nextY][nextX]!=index)continue;</code></pre>이렇게 범위체크를 먼저 안해주면, visited 체크 때 outOfBounds 가 필연적으로 뜬다.<h4 id="7-배열에서-나처럼-yx를-사용한다면-y행-x열임을-잊지말자">7. 배열에서 나처럼 [y][x]를 사용한다면, y=행, x=열임을 잊지말자</h4>
종이 제일위에 적어두고 시작하는게 마음편하다.</li>
</ol>
<p>코드</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;queue&gt;
#include &lt;cstring&gt;
#include &lt;utility&gt;
using namespace std;
int moveY[4]={-1,1,0,0}, moveX[4]={0,0,-1,1}, K,M;
vector&lt;vector&lt;bool&gt;&gt; visited(5,vector&lt;bool&gt;(5, false));
vector&lt;int&gt; refill;
int refillIndex=0;
vector&lt;vector&lt;int&gt;&gt; board(5,vector&lt;int&gt;(5));

struct Rotate{
    int y,x, relic, angle; //중심 행, 열, 유물수, 회전각도
};
struct Compare{  //Rotate구조체 비교연산자
    bool operator()(const Rotate&amp; a, const Rotate&amp; b){
        if(a.relic!=b.relic) return a.relic&lt;b.relic;
        else if(a.angle!=b.angle) return a.angle&gt;b.angle;
        else if(a.x!=b.x) return a.x&gt;b.x;
        else return a.y&gt;b.y;
    }
};
struct Cmp{ //유물 리필 비교연산자
    bool operator()(pair&lt;int, int&gt;&amp; a, pair&lt;int, int&gt;&amp; b){
        if(a.second!=b.second) return a.second&gt;b.second;
        else return a.first&lt;b.first;
    }
};

Rotate makeRotate(int y, int x, int relic, int angle){
    Rotate rotate;
    rotate.y=y;
    rotate.x=x;
    rotate.relic=relic;
    rotate.angle=angle;
    return rotate;
}

Rotate makeNullRotate(){
    Rotate rotate;
    rotate.y=-1;
    return rotate;
}

int dfs(vector&lt;vector&lt;int&gt;&gt; copy, int y, int x, int index){
    int cnt=0;
    if(copy[y][x]==index) {
        cnt++;
        visited[y][x]=true;
    }
    for(int i=0;i&lt;4;i++){
        int nextY=y+moveY[i];
        int nextX=x+moveX[i];
        if(nextY&lt;0||nextY&gt;4||nextX&lt;0||nextX&gt;4||visited[nextY][nextX]||copy[nextY][nextX]!=index)continue;
        visited[nextY][nextX]=true;
        cnt+=dfs(copy, nextY, nextX,index);
    }
    return cnt;
}

Rotate findRotate(int y, int x, int angle){ //보드 돌려서 유물갯수 찾고, Rotate만들기
    vector&lt;vector&lt;int&gt;&gt; copy(5,vector&lt;int&gt;(5));
    //보드 복사
    for(int i=0;i&lt;5;i++){
        for(int j=0;j&lt;5;j++) copy[i][j]=board[i][j];
    }
    // 3x3 배열을 따로 저장
    int subBoard[3][3];
    for (int i = 0; i &lt; 3; ++i) {
        for (int j = 0; j &lt; 3; ++j) {
            subBoard[i][j] = board[y-1+i][x-1+j];
        }
    }
    // 회전된 3x3 배열을 copy로 복사
    if (angle == 1) {
        for (int i = 0; i &lt; 3; ++i) {
            for (int j = 0; j &lt; 3; ++j) {
                copy[y-1+i][x-1+j] = subBoard[2-j][i]; // 시계방향 90도 회전
            }
        }
    } else if (angle == 2) {
        for (int i = 0; i &lt; 3; ++i) {
            for (int j = 0; j &lt; 3; ++j) {
                copy[y-1+i][x-1+j] = subBoard[2-i][2-j]; // 180도 회전
            }
        }
    } else if (angle == 3) {
        for (int i = 0; i &lt; 3; ++i) {
            for (int j = 0; j &lt; 3; ++j) {
                copy[y-1+i][x-1+j] = subBoard[j][2-i]; // 시계방향 270도 회전
            }
        }
    }
    //현재 배열의 유물 수 찾기
    int relic=0;
    //fill(visited[0].begin(), visited[4].end(), false); //방문배열 초기화 다차원벡터는 fill하면안됨
    for(int i=0;i&lt;5;i++){
        for(int j=0;j&lt;5;j++) visited[i][j]=false;
    }
    for(int i=0;i&lt;5;i++){
        for(int j=0;j&lt;5;j++){
            if(visited[i][j]) continue;
            int nowRelic=dfs(copy,i,j,copy[i][j]);
            if(nowRelic&gt;=3) relic+=nowRelic;
        }
    }
    Rotate rotate=makeRotate(y,x,relic,angle);
    return rotate;
}

Rotate findRotate(){ //턴 시작 직후 회전해야 하는 각도와 중심점 찾기
    priority_queue&lt;Rotate, vector&lt;Rotate&gt;, Compare&gt; pq;
    for(int i=1;i&lt;=3;i++){ //행 (3x3배열 회전시켜야 하므로 중심점은 1,1~3,3까지 총 9개)
        for(int j=1;j&lt;=3;j++){ //열
            for(int k=1;k&lt;=3;k++){ //회전각도
                pq.push(findRotate(i,j,k));
            }
        }
    }
    if(pq.top().relic==0) return makeNullRotate();
    return pq.top();
}

void doRotate(int y, int x, int angle){
    int subBoard[3][3];
    for (int i = 0; i &lt; 3; ++i) {
        for (int j = 0; j &lt; 3; ++j) {
            subBoard[i][j] = board[y-1+i][x-1+j];
        }
    }
    // 회전된 3x3 배열을 copy로 복사
    if (angle == 1) {
        for (int i = 0; i &lt; 3; ++i) {
            for (int j = 0; j &lt; 3; ++j) {
                board[y-1+i][x-1+j] = subBoard[2-j][i]; // 시계방향 90도 회전
            }
        }
    } else if (angle == 2) {
        for (int i = 0; i &lt; 3; ++i) {
            for (int j = 0; j &lt; 3; ++j) {
                board[y-1+i][x-1+j] = subBoard[2-i][2-j]; // 180도 회전
            }
        }
    } else if (angle == 3) {
        for (int i = 0; i &lt; 3; ++i) {
            for (int j = 0; j &lt; 3; ++j) {
                board[y-1+i][x-1+j] = subBoard[j][2-i]; // 시계방향 270도 회전
            }
        }
    }
}

void dfs2(int index, int y, int x, vector&lt;vector&lt;bool&gt;&gt;&amp; visited, vector&lt;pair&lt;int, int&gt;&gt;&amp; pv) {
    // 방문 처리
    visited[y][x] = true;
    pv.push_back({y, x});  // 좌표 저장
    // 상하좌우로 이동
    for (int i = 0; i &lt; 4; i++) {
        int nextY = y + moveY[i];
        int nextX = x + moveX[i];
        // 경계 체크와 방문 체크
        if (nextY &lt; 0 || nextY &gt; 4 || nextX &lt; 0 || nextX &gt; 4 || visited[nextY][nextX] || board[nextY][nextX] != index)
            continue;
        // 재귀적으로 탐색
        dfs2(index, nextY, nextX, visited, pv);
    }
}

void refillRelic(priority_queue&lt;pair&lt;int, int&gt;, vector&lt;pair&lt;int, int&gt;&gt;, Cmp&gt;&amp; pq){
    while(!pq.empty()){
        int y=pq.top().first;
        int x=pq.top().second;
        pq.pop();
        board[y][x]=refill[refillIndex];
        refillIndex++;
    }
}

int relay(){ //보드가 회전한 상태에서, 유물들을 찾고 다시 리필하고 찾고 반복
    int result=0; //최종적으로 얻은 유물 수
    priority_queue&lt;pair&lt;int, int&gt;, vector&lt;pair&lt;int, int&gt;&gt;, Cmp&gt; pq; //유물을 찾은 좌표 큐, 우선순위대로 리필하면됨
    vector&lt;vector&lt;bool&gt;&gt; visited(5,vector&lt;bool&gt;(5, false)); 
    while(1){ //유물 찾고 리필하기
        vector&lt;pair&lt;int, int&gt;&gt; pv;
        for(int i=0;i&lt;5;i++){
            for(int j=0;j&lt;5;j++) visited[i][j]=false;
        }
        //pq.clear(); 우선순위큐는 clear없음
        while (!pq.empty()) pq.pop();
        //현재상황에서 유물 전부 찾고 좌표들 받기
        for(int i=0;i&lt;5;i++){
            for(int j=0;j&lt;5;j++) {
                if(visited[i][j]) continue;
                pv.clear();
                dfs2(board[i][j],i,j,visited, pv);
                if(pv.size()&gt;=3){
                    //cout&lt;&lt;i&lt;&lt;&quot;, &quot;&lt;&lt;j&lt;&lt;&quot;에서 &quot;&lt;&lt;pv.size()&lt;&lt;&quot; &quot;;
                    for(int i=0;i&lt;pv.size();i++) pq.push(pv[i]);
                }
            }
        }
        int relicCnt=pq.size(); //찾은 유물의 수
        result+=relicCnt; //유물 개수 결과에 추가
        if(relicCnt==0) return result;
        refillRelic(pq);
    }
    return -1;
}

int main() {
    cin&gt;&gt;K&gt;&gt;M;
    refill.resize(M+1);
    for(int i=0;i&lt;5;i++){
        for(int j=0;j&lt;5;j++) cin&gt;&gt;board[i][j];
    }
    for(int i=0;i&lt;M;i++) cin&gt;&gt;refill[i];
    while(K--){
        Rotate rotate=findRotate();
        if(rotate.y==-1) break; //유물을 찾을수없음
        doRotate(rotate.y, rotate.x, rotate.angle); //찾은 좌표와 각도로 회전
        int turnResult=relay();
        cout&lt;&lt;turnResult&lt;&lt;&quot; &quot;;
    }
    return 0;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[COGO] SQS+SES+Lambda로 비동기 처리 안정성 보완]]></title>
            <link>https://velog.io/@ky0_hw/COGO-SQSSES%EB%A1%9C-%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%A9%94%EC%9D%BC-%EC%A0%84%EC%86%A1-%EA%B8%B0%EB%8A%A5%EC%9D%98-%EC%95%88%EC%A0%95%EC%84%B1-%EB%B3%B4%EC%99%84</link>
            <guid>https://velog.io/@ky0_hw/COGO-SQSSES%EB%A1%9C-%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%A9%94%EC%9D%BC-%EC%A0%84%EC%86%A1-%EA%B8%B0%EB%8A%A5%EC%9D%98-%EC%95%88%EC%A0%95%EC%84%B1-%EB%B3%B4%EC%99%84</guid>
            <pubDate>Mon, 26 Aug 2024 21:12:58 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="결과-요약">결과 요약</h3>
<p><img src="https://velog.velcdn.com/images/ky0_hw/post/cdd8c184-74f1-4bb9-aa50-37afab461761/image.jpg" alt=""></p>
</blockquote>
<ol>
<li>메일 전송 비동기 처리를 AWS 아키텍처로 위임했다.</li>
<li>SQS로 전송된 요청 메시지는, 람다를 통해 SES로 전달된 후 클라이언트에 메일이 전송된다.</li>
<li>오류 발생시 SQS에 연결된 DLQ에 메시지가 전송되고, 4회 이상 이런 상황이 발생하면 나에게 알림이 오게 로직을 구성하였다.<blockquote>
<h3 id="문제-상황">문제 상황</h3>
<p>JavaMailSender를 통해 유저에게 인증 메일을 보내는데, 메인 스레드의 대기 시간이 너무 길어 비동기 처리로 전환한 바 있다. <a href="https://velog.io/@ky0_hw/COGO-%ED%94%84%EB%A1%9C%ED%8C%8C%EC%9D%BC%EB%9F%AC%EC%99%80-VisualVM-%EB%B9%84%EB%8F%99%EA%B8%B0%EC%B2%98%EB%A6%AC%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C%ED%92%80">(이전 게시물)</a>
하지만 <strong>메일 전송 결과를 확인하지 않고 응답을 반환하기 때문에, 안정성 차원에서 이슈가 생길 수 있다는 피드백</strong>을 받았다.
따라서 해당 상황이 발생할 수 있는지, 테스트 코드를 작성했다.</p>
</blockquote>
<pre><code>@Test
 void testSendAuthenticationEmailReturnsCodeAndHandlesException() throws MessagingException, InterruptedException {
     // given
     String receiver = &quot;test@example.com&quot;;
     // sendMail이 호출될 때 예외를 던지도록 설정(런타임)
     doThrow(new RuntimeException(&quot;Failed to send email&quot;))
             .when(javaMailSender).send(any(MimeMessage.class));
     // when
     String resultCode = null;
     try {
         resultCode = emailUtil.sendAuthenticationEmail(receiver);
     } catch (RuntimeException e) {
         // 예외가 발생해도 메서드가 종료되지 않고 정상적으로 처리되었는지 확인
         System.out.println(&quot;예외 발생: &quot; + e.getMessage());
     }
     // then
     //assertNotNull(resultCode);  // 반환된 코드가 null이 아닌지 확인
     assertEquals(6, resultCode.length());  // 반환된 코드의 길이가 6자리인지 확인
     assertTrue(resultCode.matches(&quot;\\d{6}&quot;));  // 반환된 코드가 6자리 숫자인지 확인
     System.out.println(&quot;resultCode = &quot; + resultCode);
     verify(javaMailSender, times(1)).send(any(MimeMessage.class));  // sendMail이 한 번만 호출되었는지 확인
 }</code></pre>내 메일전송 기능은 </li>
<li>인증메일 전송 메서드 호출 </li>
<li>해당 메소드에서 메일 전송 메서드에 메일 문구를 파라미터로 포함해 호출 
로 구성되어 있는데, 2번에서 메일 전송 메서드가 런타임에러를 던지는 경우를 가정하고, 1번에서 정상적으로 코드를 반환하며 2번 메서드는 재실행이 되지 않는다면 해당 비즈니스 로직에 문제점이 존재한다고 판단하였다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/41070918-ea7e-49e7-85de-069da75ae1cd/image.png" alt="">
늘 좋지 않은 예감은 적중한다.
현재 로직은 메일 전송에 실패하거나 오류가 발생해도, 어떠한 핸들링 과정 없이 생성한 인증 코드를 반환한다.
따라서 오류 발생시 메일 전송을 재시도할 수 있도록 로직을 추가할 예정이다.</li>
</ol>
<blockquote>
<h3 id="해결방법">해결방법</h3>
<p>고안한 해결방법은 3가지다.</p>
</blockquote>
<ol>
<li>오류 발생시 로그에 남기고, 메일을 n회(임의의 수) 재전송하도록 설정</li>
<li>AWS의 SQS+SES로 비동기 메일 전송 기능의 책임을 AWS로 넘기고, 메일 전송 실패시 재전송 로직 구성</li>
<li>그냥 SES로 메일 전송 기능의 책임만 넘기기
내가 선택한 방법은 2번인데, 1번은 간단하지만 메일 재전송 기능을 2번에 비하여 확실하게 책임지지 못할 것이라 판단하였고, 3번은 2번에 비하여 간단하지만, 마찬가지로 재전송 기능을 구축하는 데 어려움을 겪을 듯했다.</li>
</ol>
<p><strong>즉, 메시지 큐에 메일 전송 요청을 넣고, SQS에서 이 메시지를 읽으면 SES로 메일이 보내지는 식으로 구성한 것이다. 만약 메일 전송에 실패하면 Dead Letter Queue(DLQ)에서 별도의 처리를 할 예정이다.</strong>
메시지 큐는 다양하지만, 메일 전송 자체의 기능을 SES로 구현하기로 했고, 이와 호환성이 좋은 SQS를 연결하는 것이 하나의 아키텍처를 구축하는 데 깔끔하다고 생각하여 SQS+SES로 구성하였다.</p>
<blockquote>
<h3 id="해결-과정">해결 과정</h3>
<p>참고 reference 
<a href="https://velog.io/@choidongkuen/%EC%84%9C%EB%B2%84-%EB%A9%94%EC%84%B8%EC%A7%80-%ED%81%90Message-Queue-%EC%9D%84-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90">메시지 큐란?</a>
<a href="https://velog.io/@gmlstjq123/AWS-SQS-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0">SQS와 Springboot</a>
<a href="https://jibinary.tistory.com/97">SES란?</a></p>
</blockquote>
<h4 id="1-sqs-설정">1. SQS 설정</h4>
<p><img src="https://velog.velcdn.com/images/ky0_hw/post/a7fa0f26-be33-4f19-ae7e-5da3c68569e7/image.png" alt="">
먼저 SQS(WAS에서 이메일 전송 요청 메시지를 받는다)를 생성하고, SQS에서 SES로 전송하는데 실패한 메시지들을 저장하는 DLQ를 연결해주었다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/469e58ad-de84-41d4-9f65-3d8a7d35ac60/image.png" alt="">
이렇게 연결된 DLQ에 SES로 전송하는데 실패한 메시지들이 있는지 Lambda를 고의로 수정해 확인해보았다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/0df3b29c-c6be-4d37-8437-d0adc16630d4/image.png" alt="">
제대로 들어오는 것이 확인된다.
이로써 SES에 전송이 실패한 메시지가 DLQ에 들어오게 된다.
DLQ에서 메시지 처리는 고민해본 결과, 3번만 SQS에 재전송하고, 4번 이상 DLQ에 반환되면 내 개인 메일로 알림이 와서 직접 처리할 수 있게 하였다.
해당 로직은 SQS와 마찬가지로 람다를 연결해 주었다.</p>
<h4 id="2-트리거-lambda-적용">2. 트리거 Lambda 적용</h4>
<p><img src="https://velog.velcdn.com/images/ky0_hw/post/d960fc3b-3fab-4a78-8739-8afd82d1546f/image.png" alt="">
SQS에 메시지가 들어오면 바로 SES로 전달하기 위해 Lambda를 트리거로 적용해주었다.
적용 후, 테스트를 진행해보니 CloudWatch에서 성공 로그를 발견할 수 있었다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/962f9b86-79e0-4602-bcb8-a56248bb4d51/image.png" alt="">
Lambda는 SQS에서 트리거로 작동해 SES로 메시지를 보내므로, IAM에서 람다에 SQS와 SES의 access를 설정해주어야 한다.</p>
<h4 id="3-ses-설정">3. SES 설정</h4>
<p>SES에서 메일 발송자의 도메인 인증을 하고, 해당 도메인을 통해 사용자에게 메일을 보내도록 설정해주었다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/f89e348f-bfc3-4b6f-b54e-8528a0268d45/image.png" alt="">
마찬가지로, CloudWatch에서 요청이 들어왔고, 해당 요청을 처리했다는 내역들을 볼 수 있었다.
하지만 SES를 제대로 사용하기 위해서는 &#39;샌드박스 모드&#39;를 풀어야 하는데, 이 정보는 <a href="https://velog.io/@korea3611/aws-ses-%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EB%A9%94%EC%9D%BC%EC%9D%84-%EB%B3%B4%EB%82%B4%EB%B3%B4%EC%9E%90">reference</a>에서 확인할 수 있다.
샌드박스 모드를 풀기 위해 AWS측에 Support창에서 웹메일을 보냈고, 15시간가량 후에 샌드박스 모드가 풀렸다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/099db606-e70c-44ea-89f4-45544aca03a6/image.png" alt="">
메일은 위와 같이 SES사용 이유와, 메일을 보낼 대상, 메일 내용들을 첨부했다.</p>
<h4 id="4-테스트">4. 테스트</h4>
<p>먼저 스웨거로 메일 전송을 요청해보았다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/e2b0eb97-50e3-4164-a78e-1c544f316194/image.png" alt="">
<img src="https://velog.velcdn.com/images/ky0_hw/post/42d65750-6ef2-4dde-bf1d-ede1f68e3c06/image.png" alt="">
제대로 발송되는 것을 확인했고, 이제 에러 발생 상황을 가정하기 위해 SQS에 연결된 람다를 살짝 만지고 테스트 해보았다.
<img src="https://velog.velcdn.com/images/ky0_hw/post/f8d6ec09-5f27-4d73-ade1-db3d812db049/image.png" alt="">
이렇게 4번이상 DLQ로 들어온 메시지는 나에게 직접 메일이 날라오는 알림 로직을 구축해두었다.</p>
]]></description>
        </item>
    </channel>
</rss>