<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>martin_0610.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sat, 23 Nov 2024 14:57:17 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>martin_0610.log</title>
            <url>https://velog.velcdn.com/images/martin_0610/profile/bd768eaa-b8c0-4478-b89e-06a1aa392672/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. martin_0610.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/martin_0610" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[클린 아키텍처 (Clean Architecture)란?]]></title>
            <link>https://velog.io/@martin_0610/%ED%81%B4%EB%A6%B0-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-Clean-Architecture%EB%9E%80</link>
            <guid>https://velog.io/@martin_0610/%ED%81%B4%EB%A6%B0-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-Clean-Architecture%EB%9E%80</guid>
            <pubDate>Sat, 23 Nov 2024 14:57:17 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/martin_0610/post/3ed5070c-ec6b-4474-925f-e9af7019771d/image.png" alt="">
클린 아키텍처는 <strong>로버트 C. 마틴(Robert C. Martin)</strong> 의 책 클린 아키텍처에서 소개된 소프트웨어 설계 원칙으로, 코드의 유지보수성과 확장성을 높이는 것에 중점을 둔 구조이다. 클린 아키텍처에서 가장 중요하게 여겨지는 핵심은 의존성 규칙(Dependency Rule)이다.<br></p>
<ul>
<li>Data</li>
<li>Domain</li>
<li>Presentation</li>
</ul>
<p>클린 아키텍처에서는 크게 위의 바운더리로 레이어를 구분하고 있으며, 각 레이어는 다음의 요소를 포함하고 있다.</p>
<h3 id="data-layer">Data Layer</h3>
<p>Data Layer는 데이터의 저장, 조회, 외부 API 호출등 데이터와 관련된 모든 작업을 처리한다. Data Layer는 Domain Layer에 필요한 데이터를 제공하며, Presentation Layer나 Domain의 로직에 직접적으로 의존하지 않아야한다.<br>
<strong>주요 역할</strong></p>
<ul>
<li>데이터베이스와의 상호작용 (CRUD 작업)</li>
<li>REST API, GraphQL 등 외부 서비스와의 통신</li>
<li>데이터 포맷 변환 및 Domain Layer에 필요한 데이터 전달</li>
</ul>
<p><strong>구현 요소</strong></p>
<ul>
<li>Repository: 데이터베이스나 외부 서비스에서 데이터를 가져오고 전달하는 인터페이스 (Domain Layer와 의존성 문제를 해결하기 위해 구현체는 Domain에서 인터페이스를 상속한 클래스를 만들어 사용)</li>
<li>Data Source: 실제로 데이터를 가져오는 구현체 (SQLite, Firebase, Retrofit 등)</li>
</ul>
<p><strong>특징</strong></p>
<ul>
<li>외부 의존성이 많기 때문에 다른 레이어와 철저히 분리해야 함</li>
<li>도메인 레이어에 데이터를 전달하기 위해 변환 작업(Data Mapping)을 수행</li>
</ul>
<h3 id="domain-layer">Domain Layer</h3>
<p>Domain Layer는 서비스의 중심이 되는 레이어로, 핵심 비즈니스 로직을 처리한다. Domain Layer는 다른 모든 레이어로부터 독립적이어야 하며, 서비스에서 처리해야할 내용을 정의하는 역할을 한다.</p>
<p><strong>주요 역할</strong></p>
<ul>
<li>애플리케이션의 비즈니스 규칙 처리</li>
<li>유스케이스(Use Cases)를 정의하여 기능별 로직 구현</li>
<li>데이터의 흐름을 제어 (Data ↔ Presentation)</li>
</ul>
<p><strong>구현 요소</strong></p>
<ul>
<li>Entity: 서비스에서 지속적으로 사용되는 핵심 데이터 모델과 규칙</li>
<li>Use Cases: 특정 기능을 수행하는 비즈니스 로직</li>
</ul>
<p><strong>특징</strong></p>
<ul>
<li>독립적인 레이어로, 외부 프레임워크나 UI와 의존성을 가지지 않음</li>
<li>테스트 용이성(Testability)이 가장 높은 레이어</li>
</ul>
<h3 id="presentation-layer">Presentation Layer</h3>
<p>Presentation Layer는 사용자 인터페이스(UI)와 상호작용을 처리하는 Layer이다. 화면에 데이터를 보여주고, 사용자의 입력을 받아 도메인 레이어로 전달하는 역할을 한다.</p>
<p><strong>주요 역할</strong></p>
<ul>
<li>UI를 통해 데이터를 표시하고 사용자 입력을 수집</li>
<li>입력 데이터를 도메인 레이어에 전달</li>
<li>도메인 레이어로부터 받은 결과를 UI에 반영</li>
</ul>
<p><strong>구현 요소</strong></p>
<ul>
<li>View: 사용자와 직접 상호작용하는 UI 요소. 예: Android의 Activity/Fragment, 웹의 React Component.</li>
<li>State Management: View와 Domain Layer를 연결하며, UI에 필요한 데이터 준비 및 상태를 관리 (MVVM: ViewModel, MVC: Controller 등)</li>
</ul>
<p><strong>특징</strong></p>
<ul>
<li>도메인 레이어의 결과를 사용자에게 가장 적절하게 전달</li>
<li>도메인 레이어를 호출하지만 도메인 로직은 포함하지 않음</li>
<li>UI 변경에 따라 자주 수정되기 때문에 도메인 레이어와 분리되어야 함</li>
</ul>
<h3 id="정리">정리</h3>
<p>클린 아키텍처의 Data, Domain, Presentation Layer는 각자의 역할을 명확히 나눔으로써 코드 품질을 향상시키고, 유지보수와 코드 확장에 유연하게 대응할 수 있도록 한다. 그렇지만 모든 프로젝트에서 클린 아키텍처가 항상 정답인 것은 아니다. 각 프로젝트 별로 그 특징이 있고, 해당 환경에서 빛을 보일 수 있는 설계 방법을 찾기 위해 개발자들은 항상 노력해야한다. 이번 포스트는 클린 아키텍처를 그 노력들 중 한가지 인사이트로써 사용할 수 있게 미리 찾아보고 공부한 내용 정도로 정리하려 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[정보처리기능사 실기 준비]]></title>
            <link>https://velog.io/@martin_0610/%EC%A0%95%EB%B3%B4%EC%B2%98%EB%A6%AC%EA%B8%B0%EB%8A%A5%EC%82%AC-%EC%8B%A4%EA%B8%B0-%EC%A4%80%EB%B9%84</link>
            <guid>https://velog.io/@martin_0610/%EC%A0%95%EB%B3%B4%EC%B2%98%EB%A6%AC%EA%B8%B0%EB%8A%A5%EC%82%AC-%EC%8B%A4%EA%B8%B0-%EC%A4%80%EB%B9%84</guid>
            <pubDate>Sat, 09 Nov 2024 14:58:34 GMT</pubDate>
            <description><![CDATA[<h3 id="정보처리-기능사-배점">정보처리 기능사 배점</h3>
<p>기능사 시험의 파트별 출제율을 일반적으로 다음과 같다.</p>
<ul>
<li>운영체재 3문제</li>
<li>네트워크 3문제</li>
<li>데이터베이스 3문제</li>
<li>SQL 4문제</li>
<li>C언어 프로그래밍 3문제</li>
<li>Java언어 프로그래밍 3문제</li>
<li>애플리케이션 테스트 1문제</li>
</ul>
<p>총 20문항으로 100점 만점 60점(12문제 이상) 이상일 경우 합격할 수 있다.</p>
<h2 id="운영체재">운영체재</h2>
<p>해당 파트는 DOS, Windows, UNIX, 운영체재 이론으로 구분되며, Windows 운영체재의 출제율이 가장 높다.
각 운영체재별 특징, 단축키를 집중적으로 공부하는 방향으로 공부를 진행했다.</p>
<h3 id="1-dos-disk-operating-system">1. DOS (Disk Operating System)</h3>
<p>PC에서 디스크 장치를 외부기억장치로 사용하는 운영체제</p>
<ul>
<li><strong>DOS의 특징</strong><ul>
<li>단일 작업 처리 시스템</li>
<li>CUI(Character User Interface)환경 제공<ul>
<li>동일 용어 CLI(Command Line Interface)가 있음</li>
</ul>
</li>
</ul>
</li>
<li><strong>DOS의 명령어</strong><ul>
<li>cls : 화면에 표시된 내용 지움 [clear screen]</li>
<li>md : 디렉토리 생성 [make directory]</li>
<li>cd : 디렉토리 이동 [change directory]</li>
<li>dir : 현재 디렉토리 내용 출력 [directory]</li>
<li>copy : 파일 복사</li>
<li>type : 파일 내용 출력</li>
<li>del, erase : 파일 삭제</li>
<li>ren : 파일 이름 변경 [rename]</li>
<li>find : 파일에서 특정 문자열 검색</li>
<li>attrib : 파일 속성 지정 [attribute]<ul>
<li><ul>
<li>: 속성 부여</li>
</ul>
</li>
<li><ul>
<li>: 속성 해제</li>
</ul>
</li>
<li>R : 읽기 전용</li>
<li>A : 저장/백업</li>
<li>S : 시스템 파일</li>
<li>H : 숨김 파일</li>
</ul>
</li>
<li>chkdsk : 디스크 상태 점검 후 결과 출력</li>
<li>format : 디스크에 데이터 저장을 위해 시스템 파일을 복사하고 트랙, 섹터를 만드는 포멧 작업</li>
<li>fdisk : 파티션 설정, 디스크 나누기</li>
<li>ver : 현재 DOS 버전 출력</li>
<li>date : 날짜 변경 또는 확인</li>
<li>undelete : 삭제 취소</li>
<li>backup : 백업</li>
</ul>
</li>
</ul>
<h3 id="2-windows">2. Windows</h3>
<p>MS-DOS에서 멀티 태스킹, GUI환경 제공을 위해 출시된 운영체제</p>
<ul>
<li><strong>Windows의 특징</strong><ul>
<li>Multi-Tasking : 여러 작업을 동시 수행</li>
<li>GUI(Graphic User Interface) : 마우스 아이콘을 이용해 소프트웨어를 실행하는 인터페이스</li>
<li>PnP(Plug and Play) : 기기 설치 후 물리적인 설정 없이 바로 사용 가능하게 하는 기능</li>
<li>OLE(Object Link Embedding) : 예시로 그림판 파일을 한글에서 링크해 사용하는 기능이 있음</li>
<li>파일 시스템 지원 : 보조기억장치에 저장된 파일을 수정, 삭제, 추가, 검색 등 작업을 지원하는 관리 시스템<ul>
<li>NTFS (가장 우수)</li>
<li>FAT32</li>
<li>FAT</li>
</ul>
</li>
</ul>
</li>
<li><strong>Windows 10 에디션</strong><ul>
<li>Windows 10 Home<ul>
<li>일반 가정용</li>
<li>CPU 소켓 1개</li>
<li>RAM 최대 128GB 지원</li>
</ul>
</li>
<li>Windows 10 Pro<ul>
<li>BitLocker, WIP 보안 기능 제공</li>
<li>CPU 소켓 2개</li>
<li>RAM 최대 2TB 지원</li>
</ul>
</li>
<li>Windows 10 Enterprise<ul>
<li>기업용</li>
<li>Pro 기능 모두 보유</li>
</ul>
</li>
<li>Windows 10 Education<ul>
<li>교육기관용</li>
<li>Pro 기능 모두 보유</li>
</ul>
</li>
</ul>
</li>
<li><strong>Windows 단축키</strong><ul>
<li>Windows 또는 Ctrl + Esc : 시(CE)작 메뉴</li>
<li>Windows + A : 알람 센터</li>
<li>Windows + B : 작업 표시줄 시스템 아이콘으로 커서 이동</li>
<li>Windows + D : 바탕화면 표시, 원상태</li>
<li>Windows + E : 탐색기</li>
<li>Windows + F : 피드백 허브</li>
<li>Windows + G : 게임 툴바</li>
<li>Windows + I : 윈도우 설정</li>
<li>Windows + K : 연결 (블루투스와 같은 주변 기기 연결 창)</li>
<li>Windows + L : 잠금 화면 또는 사용자 전환</li>
<li>Windows + M : 모든 창 최소화</li>
<li>Windows + Shift + M : 최소화한 창 원상태</li>
<li>Windows + Q 또는 Windows + S : 검색 상자</li>
<li>Windows + R : 실행창</li>
<li>Windows + U : 접근성 센터</li>
<li>Windows + V : 클립보드</li>
<li>Windows + T : 작업 표시줄 앱을 차례대로 이동</li>
<li>Windows + 숫자 : 작업 표시줄 앱을 선택한 숫자로 이동 (중요)</li>
<li>Windows + P : 프로젝트 창 (중요)</li>
<li>Windows + Shift + S : 스크린샷 바 (중요)</li>
<li>Windows + Tab : 가상 데스크톱 확인</li>
<li>Windows + Ctrl + D : 가상 테스크톱 생성</li>
<li>Windows + Ctrl + F4 : 가상 데스크톱 제거</li>
</ul>
</li>
</ul>
<h3 id="3-unix-linux">3. UNIX (LINUX)</h3>
<p>유틸리티, 쉘, 커널로 구성된 운영체제</p>
<ul>
<li><p><strong>UNIX의 구성</strong></p>
<ul>
<li>커널 (Kernel)<ul>
<li>UNIX의 가장 핵심적인 부분</li>
<li>컴퓨터 부팅 시 보조기억장치에서 주기억장치로 적제된 후 상주하며 실행</li>
<li>프로세스, 기억장치, 파일의 입출력 관리 → 하드웨어 보호</li>
<li>프로그램↔하드웨어 프로그램과 하드웨어 간 인터페이스 역할 담당</li>
<li>운영체제의 핵심, 하드웨어 보호 등의 키워드</li>
</ul>
</li>
<li>쉘 (Shell)<ul>
<li>명령어 해석기</li>
<li>시스템↔사용자 시스템과 사용자 간 인터페이스 담당</li>
<li>명령어 해석, 명령어 인식 등의 키워드</li>
</ul>
</li>
<li>유틸리티 (Utillity) 프로그램<ul>
<li>일반 사용자가 작성한 응용 프로그램 처리</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>UNIX(LINUX) 명령어</strong></p>
<blockquote>
<p>프로세스란 주기억장치에 저장되어있는 즉, 실행되고 있는 프로그램을 이야기한다.</p>
</blockquote>
<ul>
<li>fork : 새 프로세스 생성, 복제 (자식 프로세스 생성, 부모 프로세스 복제)</li>
<li>exec : 프로세스 실행</li>
<li>kill : 프로세스 삭제, 종료</li>
<li>killall : 모든 프로세스 삭제, 종료</li>
<li>ps : 현재 실행중인 프로세스 상태 정보 표시</li>
<li>top : 프로세스, 메모리 사용 현황 표시</li>
<li>who : 현재 로그인 한 사용자 정보 (단말기명, 로그인명, 로그인 일시, 단말기번호 등)</li>
<li>mkdir : 디렉토리 생성</li>
<li>tar : 압축 해제</li>
<li>vi : 파일 편집 (파일이 없을 경우 생성)</li>
<li>rmdir : 디렉토리 삭제</li>
<li>cd : 디렉토리 이동</li>
<li>pwd : 현재 작업 중인 디렉토리 경로 출력</li>
<li>ls : 파일 및 디렉토리 출력</li>
<li>cp : 파일 복사</li>
<li>cat : 파일 내용 출력</li>
<li>rm : 파일 삭제</li>
<li>mv : 파일 이동</li>
<li>find : 파일 찾기</li>
<li>chmod : 파일 권한 모드 설정</li>
<li>chown : 파일 소유자 변경</li>
<li>fsck : 파일 시스템 점검 및 수리</li>
<li>finger : 현재 시스템에 등록된 사용자 정보 조회</li>
<li>ping : 네트워크 상의 문제 진단</li>
<li>comm : 두개 파일을 행 단위로 비교</li>
</ul>
</li>
</ul>
<h3 id="4-운영체제-기능">4. 운영체제 기능</h3>
<p>자원의 효율적인 스케줄링 (프로세스, 기억장치, 주변장치, 파일 관리)</p>
<ul>
<li><p><strong>프로세스</strong></p>
<ul>
<li>주기억장치에 저장된 (실행중인) 프로그램</li>
<li>작업(job) 또는 태스크(task)라고 한다.</li>
<li>운영체제가 관리하는 최소 단위 작업</li>
</ul>
</li>
<li><p><strong>프로세스 스케줄링 기법</strong></p>
<ul>
<li>비선점 스케줄링 (Non Preemptive): 비효율적, 비양보<ul>
<li>프로세스에게 이미 할당된 CPU를 강제로 빼앗을 수 없음, 사용 끝날 때 까지 대기</li>
<li>일괄 처리 (오버헤드 발생 X), 실시간 처리 안되니 중요한 작업 기다리는 문제 있음</li>
<li>대표적: FIFO, SJF, HRN</li>
</ul>
</li>
<li>선점 스케줄링: 효율적, 양보<ul>
<li>우선 순위가 높은 다른 프로세스가 할당된 CPU를 강제로 빼앗을 수 있음</li>
<li>실시간 처리, 대화식 시 분할 처리 (오버헤드 발생 O)</li>
<li>대표적: RR, SRT</li>
</ul>
</li>
<li>스풀링(Spooling)<ul>
<li>다중프로그래밍 환경에서 용량 크고, 신속한 엑세스가 가능한 디스크를 이용해 각 사용자 프로그램의 출력 데이터를 프린터로 보내지 않고 디스크에 모아 한번에 출력함으로 프린터 장치의 공유 및 프린터 처리 속도를 보완하는 기법<ol>
<li>큰 작업을 주기억장치(CPU) → 보조기억장치(디스크)로 넘김 (이 방법은 속도가 빠름)</li>
<li>보조기억장치에 모든 작업 데이터가 모아지면 주기억장치는 다른 작업이 가능함</li>
<li>주기억장치가 다른 일을 하는 동안 보조기억장치가 큰 작업을 대신 처리함</li>
</ol>
</li>
<li>버퍼링과의 관계<ul>
<li>공통점 : 저속의 입출력 장치와 고속의 CPU간 속도차이 해소를 위해 나온 방법</li>
<li>차이점<ul>
<li>스풀링 : 보조기억장치, 다중 작업</li>
<li>버퍼링 : 주기억장치, 단일 작업</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>기억장치</strong></p>
<blockquote>
<p>빠른 기억장치: 레지스터 → 연관 메모리 → 캐시 메모리 → 주기억장치 → 보조기억장치</p>
</blockquote>
<ul>
<li>레지스터(Register) : CPU 속에서 일시적으로 값을 기억하는 임시기억장소</li>
<li>연관 메모리(Associative Memory) : 저장된 내용의 일부를 이용하여 데이터를 읽어오는 기억장치 (주소 참조 X)</li>
<li>캐시 메모리 : CPU 속도와 주기억장치 속도 차이를 줄이기 위해 사용하는 고속 버퍼 메모리</li>
</ul>
</li>
<li><p><strong>운영체제 기능적 분류</strong></p>
<ul>
<li>제어 프로그램: 컴퓨터 전체의 작동 상태 감지, 작업 순서 지정, 작업 시 사용 데이터 관리 등 수행
(암기 → 감자데이터 제어)<ul>
<li>감시 프로그램<ul>
<li>각종 프로그램 실행, 시스템 전체 작동 상태 감시/감독</li>
</ul>
</li>
<li>작업 제어 프로그램<ul>
<li>업무 처리 후 다른 업무 이행을 자동 수행하기 위한 준비, 그 처리의 완료를 담당</li>
</ul>
</li>
<li>데이터 관리 프로그램<ul>
<li>파일과 데이터를 표준적인 방법으로 처리할 수 있도록 관리 (ex. 주기억장치 ↔ 보조기억장치 간 자료 전송, 파일 조작 및 처리, 입/출력 자료와 프로그램간 논리적 연결)</li>
</ul>
</li>
</ul>
</li>
<li>처리 프로그램: 제어 프로그램의 지시를 받아 처리하는 프로그램
(암기 → 선언문 처리)<ul>
<li>서비스 프로그램<ul>
<li>효율성을 위해 사용 빈도 높은 프로그램</li>
</ul>
</li>
<li>언어 번역 프로그램<ul>
<li>어셈블러, 컴파일러, 인터프리터</li>
</ul>
</li>
<li>문제 프로그램<ul>
<li>특정 업무 해결을 위해 사용자가 작성한 프로그램</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>운영체제 세대별 발달 과정 (순서대로 나열)</strong></p>
<ul>
<li>1세대<ul>
<li>일괄 처리 시스템 (Batch Processing System)<ul>
<li>가장 먼저 생긴 방식</li>
<li>유사 성격 작업 한번에 모아 처리</li>
</ul>
</li>
</ul>
</li>
<li>2세대<ul>
<li>다중 프로그래밍 (Multi Programming)<ul>
<li>처리량의 극대화 시작</li>
<li>한 대의 컴퓨터로 여러 프로그램 실행</li>
</ul>
</li>
<li>시분할 시스템 (Time Sharing System)<ul>
<li>사용자가 많은 경우 프로그램을 번갈아가며 처리해 각 사용자가 독립된 컴퓨터 사용 경험을 가진 시스템 (시간 슬롯 할당)</li>
</ul>
</li>
<li>다중 처리 (Multi Prosessing)<ul>
<li>한 대의 컴퓨터에 중앙처리장치를 2개 이상 설치</li>
<li>여러 프로그램 실행</li>
</ul>
</li>
<li>실시간 시스템 (Real-Time System)<ul>
<li>데이터 발생 즉시 처리 (좌석 예약, 비행기 제어, 교통 제어 등)</li>
</ul>
</li>
</ul>
</li>
<li>3세대<ul>
<li>다중 모드 시스템 (범용 시스템)<ul>
<li>1, 2세대가 혼합된 시스템</li>
</ul>
</li>
</ul>
</li>
<li>4세대<ul>
<li>분산 처리 시스템 (Distributed Processing System)<ul>
<li>여러대로 분산된 컴퓨터들을 연결해 사용</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Android 운영체제 버전</strong></p>
<ul>
<li>1.1 : 프리 푸르 (Petit Four)</li>
<li>1.5 : 컵케이크 (Cupcake)</li>
<li>1.6 : 도넛 (Donut)</li>
<li>2.0/2.1 : 에클레어 (Eclair)</li>
<li>2.2 : 프로요 (Froyo)</li>
<li>2.3 : 진저브레드 (GingerBread)</li>
<li>3.0/3.1/3.2 : 허니콤 (Honeycomb)</li>
<li>4.0 : 아이스크림샌드위치 (Ice Cream Sandwich)</li>
<li>4.1/4.2/4.3 : 젤리빈 (Jelly Bean)</li>
<li>4.4 : 킷캣 (KitKat)</li>
<li>5.0/5.1 : 롤리팝 (Lollipop)</li>
<li>6.0/6.1 : 마시멜로 (Marshmallow)</li>
<li>7.0/7.1 : 누가 (Nougat)</li>
<li>8.0/8.1 : 오레오 (Oreo)</li>
<li>9 : 파이 (Pie)</li>
</ul>
</li>
</ul>
<h2 id="네트워크">네트워크</h2>
<p>해당 파트는 OSI 7계층, IP주소, 데이터 포맷, 프로토콜, 기타 통신 용어로 구성되며, OSI 7계층은 시험마다 하나씩은 출제되니, 무조건 외우는 것이 좋다.</p>
<h3 id="1-ip-주소-및-데이터-포멧">1. IP 주소 및 데이터 포멧</h3>
<ul>
<li><strong>인터넷 :</strong> TCP/IP 프로토콜을 사용해 전 세계 PC와 네트워크들이 연결된 광범위한 컴퓨터 네트워크<ul>
<li>프로토콜 : 통신 시스템이 데이터를 교환하기 위해 사용하는 통신 규격<ul>
<li>TCP/IP : 서로 다른 기종의 컴퓨터들이 데이터 교환을 가능하게 하는 인터넷 표준 프로토콜<ul>
<li>TCP/IP 4계층<ul>
<li>응용 계층</li>
<li>전송 계층</li>
<li>네트워크 계층</li>
<li>데이터접속 계층</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>인터넷 서비스 (TCP/IP 상에서 운용되는 서비스)<ul>
<li>WWW (World Wide Web) 또는 HTTP (Hyper Text Transfer Protocol)서비스<ul>
<li>하이퍼텍스트를 기반으로 멀티미디어를 볼 수 있도록 하는 서비스</li>
<li>HTTPS : HTTP의 단점 보완 및 보안이 강화된 프로토콜</li>
</ul>
</li>
<li>E-Mail (전자우편)<ul>
<li>SMTP : 메일 전송에 사용되는 프로토콜</li>
<li>POP3 : 메일 수신에 사용되는 프로토콜</li>
</ul>
</li>
<li>FTP (File Transfer Protocol)<ul>
<li>인터넷에서 파일을 전송하는 서비스</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>IP 주소 (Internet Protocol Address) :</strong> 인터넷에 연결된 모든 컴퓨터의 자원을 구분하기 위한 고유한 주소<ul>
<li>서브넷 마스크<ul>
<li>AND연산자 계산을 통해 네트워크 주소를 구분하기 위한 비트</li>
<li>A 클래스에서는 네트워크 주소가 1부분이기에 255.0.0.0이고, B 클래스는 2부분이기에 255.255.0.0과 같은 식으로 사용</li>
</ul>
</li>
<li><strong>IPv4</strong><ul>
<li>전 세계적으로 관리되는 유한한 자원</li>
<li>8비트씩 4부분, 총 32비트로 구성 (약 43억개 = 2³²개)</li>
<li>각 부분을 ( . )으로 구분, 각 구분은 10진수로 표현</li>
<li>A~E 클래스까지 총 5개 클래스로 구분<ul>
<li>A 클래스<ul>
<li>국가 또는 대형 통신망에 사용</li>
<li>시작 주소 : 0~127</li>
<li>네트워크 주소 : 1부분, 1로 시작</li>
<li>연결 가능 호스트 : 3부분, 256<em>256</em>256</li>
<li>서브넷 마스크 : 255.0.0.0 = 11111111.00000000.00000000.00000000</li>
</ul>
</li>
<li>B 클래스<ul>
<li>중대형 통신망에 사용</li>
<li>시작 주소 : 128~191</li>
<li>네트워크 주소 : 2부분, 10으로 시작</li>
<li>연결 가능 호스트 : 2부분, 256*256</li>
<li>서브넷 마스크 : 255.255.0.0 = 11111111.11111111.00000000.00000000</li>
</ul>
</li>
<li>C 클래스<ul>
<li>소규모 통신망에 사용</li>
<li>시작 주소 : 192~223</li>
<li>네트워크 주소 : 3부분, 110으로 시작</li>
<li>연결 가능 호스트 : 256 (실제 연결 가능한 호스트는 다른 용도로 사용하는 000…, 111… 을 뺀 254개)</li>
<li>서브넷 마스크 : 255.255.255.0 = 11111111.11111111.11111111.00000000</li>
</ul>
</li>
<li>D 클래스, E 클래스 (기타)</li>
</ul>
</li>
</ul>
</li>
<li><strong>IPv6</strong><ul>
<li>IPv4의 주소 고갈 문제 해결을 위해 만들어진 32비트 → 128비트로 확장한 차세대 인터넷 프로토콜 주소</li>
<li>16비트씩 8부분, 총 128비트로 구성 (43억<em>43억</em>43억*43억개 = 2¹²⁸개)</li>
<li>각 부분을 ( : )으로 구분, 각 구분은 16진수로 표현</li>
<li>IPv6 주소체계<ul>
<li>유니캐스트 (Unicast)<ul>
<li>특정 1인에게 송신 (1:1)</li>
</ul>
</li>
<li>멀티캐스트 (Multicast)<ul>
<li>특정 다수에게 송신 (1:n)</li>
<li>IPv4의 브로드캐스트(Broadcast)와의 차이<ul>
<li>브로드캐스트 : 불특정 다수에게 송신, 네트워크 내의 모든 주소에 동일 메세지 송신 (TV 방송과 비슷)</li>
<li>멀티캐스트: 특정 다수에게 송신</li>
</ul>
</li>
</ul>
</li>
<li>애니캐스트 (Anycast)<ul>
<li>수신자들을 그룹으로 묶은 주소를 사용해 그룹내 가장 가까운 호스트에게 송신 (1:1)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>데이터 포멧</strong><ul>
<li>HTML : 웹페이지를 위한 마크업 언어</li>
<li>SGML : 전자문서가 시스템 환경에 따른 정보의 손실 없이 전송, 저장, 자동처리가 가능하도록 ISO(국제 표준화 기구)에서 정한 문서처리 표준</li>
<li>XML: 웹브라우저 간 HTML 문법 호환 문제와 SGML의 복잡함을 해결하기 위해 나오게 됨</li>
<li>JSON : XML의 대안으로 나오게 됨, 자바스크립트 기반의 기술, 속성-값이 쌍을 이룸</li>
<li>AJAX : HTML을 보완하기 위해 나온 기술로 필요한 일부분만 동적 업데이트 하는 기술</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="2-osi-7계층-및-프로토콜">2. OSI 7계층 및 프로토콜</h3>
<ul>
<li><strong>네트워크 장비</strong> (실제 시험에 나오는 파트는 아니지만 OSI 7계층과 연결되어 문제로 출제됨)<ul>
<li>LAN : Local Area Network, 근거리 네트워크로 동일 건물내에서 프로그램, 파일, 주변장치 등의 자원을 공유할 수 있는 컴퓨터 통신망</li>
<li>허브 : 컴퓨터 연결 장치 (LAN을 구성할 때 사용)</li>
<li>리피터 : 신호 증폭기 (허브에 연결할 장치가 물리적으로 먼 경우 사용)</li>
<li>브리지 : 동종 LAN 간 연결 (LAN1 ↔ LAN2 연결과 같이 통신망 사이의 연결이 필요할 때 사용)</li>
<li>라우터 : 네트워크 연결 + 경로 설정</li>
<li>게이트웨이 : 각 통신망의 프로토콜이 다를 때 네트워크 사이를 결합 (보통 라우터에 이 기능이 포함됨)</li>
<li>랜카드 : 컴퓨터에 설치하는 확장 카드로, 외부 네트워크와 가장 빠른 속도로 접속 및 데이터를 전달 받을 수 있게 하는 장치</li>
</ul>
</li>
<li><strong>OSI 7계층 :</strong> 다른 시스템 간 원할한 통신을 위해 ISO에서 제안한 7단계 표준화 프로토콜<ul>
<li>계층화(부품화, 모듈화)가 필요한 이유 : 독립성 유지, 의존 최소화, 효율적인 통신<ul>
<li>예를 들어 응용계층에서 카카오톡의 메세지 보내기 아이콘의 위치가 바뀐다고 하더라도 표현 계층의 메세지 암호화 기능은 영향을 받지 않을 수 있음</li>
</ul>
</li>
<li>프로토콜 : 컴퓨터 통신에서 컴퓨터 간 데이터를 송/수신하기 위한 통신 규약</li>
<li><strong>OSI 하위 계층</strong><ul>
<li><strong>물리 계층 (1계층) :</strong> 물리적인 연결 방식의 프로토콜 (케이블)<ul>
<li>역할 : 전송에 필요한 장치 간 접속/단절 등 기계적, 전기적 특성에 대한 규칙을 정의</li>
<li>장비<ul>
<li>리피터</li>
<li>허브</li>
</ul>
</li>
<li>프로토콜<ul>
<li>RS-232C (EIA에서 규정한 접속 규격)</li>
<li>V.24 (ITU-T에서 규정한 접속 규격)</li>
</ul>
</li>
</ul>
</li>
<li><strong>데이터 링크 계층 (2계층) :</strong> 컴퓨터 간 데이터 통신 프로토콜<ul>
<li>역할 : 흐름 제어, 프레임 동기화, 오류 제어, 에러 검출 및 정정, 순서 제어</li>
<li>장비<ul>
<li>랜카드</li>
<li>브리지 (S/W이며 저속), 스위치 (H/W이며 고속)<ul>
<li>두 개의 LAN이 데이터 링크 계층에서 결합될 때 이를 연결하기 위해 사용</li>
</ul>
</li>
</ul>
</li>
<li>프로토콜 (L이 포함된 경우 Link의 약자로 보통 여기에 속함)<ul>
<li>HDLC(High-level Data Link Control, 비트 프레임 동기 방식)</li>
<li>LAPB(Link Access Protocol Balanced, 평형 링크 접속 프로토콜)</li>
<li>LLC(Logical Link Control, 논리적 링크 제어)</li>
<li>MAC(Media Access Control, 매체 접근 제어)</li>
<li>PPP(Point-To-Point-Protocol, 점 대 점 통신 규약, 통신 노드 간 직접적인 연결)</li>
</ul>
</li>
</ul>
</li>
<li><strong>네트워크 계층 (3계층) :</strong> 컴퓨터 간 데이터 통신 프로토콜<ul>
<li>역할 : 개방 시스템 간 네트워크 연결 관리, 데이터 교환/중계, 경로 설정, 패킷 정보 전송<ul>
<li>패킷(Packet) : 메세지를 일정 비트수로 쪼개 송/수신측 주소와 제어 정보 등을 추가해 만든 데이터 블록</li>
</ul>
</li>
<li>장비<ul>
<li>라우터</li>
</ul>
</li>
<li>프로토콜<ul>
<li>IP(Internet Protocol) : 패킷 분해/조립, 주소 지정, 경로 선택, 비연결형 서비스 안정성 ↓</li>
<li>ICMP(Internet Control Message Protocol) : TCP/IP에서 신뢰성이 없는 IP를 대신해 송신 측으로 네트워크 IP 상태, 에러 메세지를 전달해주는 프로토콜</li>
<li>IPv4, IPv6</li>
<li>IPX(Internetwork Packet Exchange, 망간 패킷 교환)</li>
<li>X.25 : 패킷 교환망 프로토콜</li>
<li>ARP : 논리적 IP주소를 물리적 주소(MAC Address)로 바꾸는 역할</li>
<li>RARP : 물리적 주소(MAC Address)를 논리적 IP주소로 바꾸는 역할</li>
<li>라우팅(Routing) : 네트워크 안에서 통신 데이터를 보낼 때 최적의 경로를 선택하는 과정<ul>
<li>내부 라우팅 IGP(Interior Gateway Protocol) : 자율 시스템 내부 라우팅 프로토콜<ul>
<li>RIP(Routing Information Protocol, 경로 선택 정보 프로토콜)<ul>
<li>거리 벡터 기반, 경유하는 라우터의 홉수(개수)에 따른 최단 경로 동적 결정</li>
<li>최적이 아닌 최단 거리 (속도, 지연등을 고려하지 않음)</li>
<li>30초 주기로 전체 라우팅 정보 갱신 (변화 업데이트 속도 ↓)</li>
<li>최대 홉수는 16 미만으로 제한되어있음 → 대규모 네트워크 사용 불가</li>
<li>소규모 동종 네트워크에 적합</li>
</ul>
</li>
<li>IGRP(Interior Gateway Routing Protocol, 내부 경로 제어 프로토콜)<ul>
<li>RIP의 문제점 개선을 위해 시스코에서 개발</li>
<li>네트워크 상태를 고려해 라우팅 (대역폭, 속도 등)</li>
<li>중규모 네트워크에 적합</li>
</ul>
</li>
<li>OSPF(Open Shortest Path First, 최단 경로 우선 프로토콜)<ul>
<li>RIP보다 빠른 정보 갱신</li>
<li>노드 간 거리 정보, 링크 상태 정보를 실시간으로 조합해 최단 경로로 라우팅</li>
<li>경로수 제한이 없음</li>
<li>Link State 방식을 사용해 변경된 정보만 모든 라우터에게 알림</li>
<li>대규모 네트워크에 적합</li>
</ul>
</li>
</ul>
</li>
<li>외부 라우팅 EGP(Exterior Gateway Protocol) : 자율 시스템 간 라우팅 프로토콜<ul>
<li>BGP(Border Gateway Protocol, 경계 경로 프로토콜)<ul>
<li>보안과 제어가 목적인 EGP의 다른 도메인 간 라우팅시 속도 저하 문제 해결</li>
<li>여러 자율 시스템 간 라우팅 정보 교환</li>
<li>규모가 큰 네트워크 간 상호 연결이 가능</li>
<li>인터넷 서비스 업체 간 상호 라우팅 (KT, SKT 등)</li>
<li>발전된 거리 벡터 라우팅 프로토콜</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>OSI 상위 계층</strong><ul>
<li><strong>전송(트랜스포트) 계층 (4계층) :</strong> 실제 전송을 하기 위한 프로토콜<ul>
<li>역할 : 종단 시스템 간 신뢰성 있는 데이터 전송, 주소 설정, 다중화(여러 호스트의 데이터를 하나의 가상 회선에 실어 전송하는 것)</li>
<li>장비<ul>
<li>게이트웨이</li>
</ul>
</li>
<li>프로토콜<ul>
<li>TCP(Transmission Control Protocol) : 가상 회선 연결 형태 → 신뢰성(안전성)이 높음</li>
<li>UDP(User Datagram Protocol) : 비연결 형태 → 신뢰성이 낮은 대신 속도가 높음 (실시간 전송에 유리)</li>
</ul>
</li>
</ul>
</li>
<li><strong>세션 계층 (5계층) :</strong> 데이터 교환 관리를 위한 프로토콜<ul>
<li>역할 : 대화 제어, 통신 사용자 동기화, 동기 조절</li>
<li>장비<ul>
<li>PC</li>
</ul>
</li>
</ul>
</li>
<li><strong>표현(프리젠테이션) 계층 (6계층) :</strong> 데이터 표현 프로토콜 (암호화, 코드)<ul>
<li>역할 : 시스템 간 다른 데이터 형태 접속 지원, 코드 변환, 구문 검색, 암호화, 형식 변환, 압축</li>
<li>장비<ul>
<li>PC</li>
</ul>
</li>
<li>프로토콜<ul>
<li>JPG</li>
<li>MPEG-4</li>
</ul>
</li>
</ul>
</li>
<li><strong>응용 계층 (7계층) :</strong> 사용자 프로그램<ul>
<li>역할 : 사용자가 OSI 환경에 접근할 수 있도록 서비스 제공</li>
<li>장비<ul>
<li>PC</li>
</ul>
</li>
<li>프로토콜<ul>
<li>HTTP(Hyper Text Transfer Protocol) : 하이퍼텍스트 기반으로 멀티미디어(문자, 음성, 이미지, 영상)를 볼 수 있게하는 서비스, 클라이언트 ↔ 웹 서버(Web Server) 간 파일 전송</li>
<li>HTTPS(Hyper Text Transfer Protocol Secure) : HTTP에서 보안을 강화하기 위해 만들어진 프로토콜</li>
<li>TELNET : 원격 접속 (가상 터미널), 외부에서 컴퓨터에 접속할 때 사용</li>
<li>FTP(File Transfer Protocol) : 클라이언트 ↔ 서버(Server) 간 파일 전송</li>
<li>DNS(Domain Name System) : IP 주소와 호스트(도메인) 간 변환을 제공하는 시스템</li>
<li>DHCP(Dynamic Host Configuration Protocol, 동적 호스트 구성 프로토콜) : IP 주소 부족 문제 해결을 위해 만들어짐<ul>
<li>사용 가능 IP 주소보다 컴퓨터가 더 많은 경우 IP 주소의 임대 기간을 짧게 해 IP주소의 효율적인 사용이 가능</li>
</ul>
</li>
<li>SNMP(Simple Network Management Protocol, 간이 망 관리 프로토콜) : 네트워크 장비를 감시하기 위해 UDP상에 정의된 프로토콜 (신뢰성보다 실시간이 중요)</li>
<li>SMTP(Simple Mail Transfer Protocol, 간이 전자 우편 전송 프로토콜) : 메일 송신</li>
<li>POP3 : 메일 수신</li>
<li>SSH(Secure shell) : 네트워크상에서 안전하게 원격 접속 개시나 데이터 전송을 실현<ul>
<li>TELNET, FTP를 대체하는 네트워크 보안 도구 중 하나</li>
<li>네트워크상 다른 컴퓨터 접속, 파일 복사 기능 지원</li>
</ul>
</li>
</ul>
</li>
<li>프로토콜 포트 번호 : IP 주소가 가르키는 PC에 접속할 수 있는 통로<ul>
<li>21(FTP)</li>
<li>22(SSH)</li>
<li>23(TELNET)</li>
<li>25(SMTP)</li>
<li>53(DNS)</li>
<li>80(HTTP)</li>
<li>110(POP3)</li>
<li>143(IMAP)</li>
<li>194(IRC)</li>
<li>443(HTTPS)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>나머지 내용은 포스트가 너무 길어지는 관계로 추후에 다루겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[IoT 스마트 홈 생태계]]></title>
            <link>https://velog.io/@martin_0610/IoT-%EC%8A%A4%EB%A7%88%ED%8A%B8-%ED%99%88-%EC%83%9D%ED%83%9C%EA%B3%84</link>
            <guid>https://velog.io/@martin_0610/IoT-%EC%8A%A4%EB%A7%88%ED%8A%B8-%ED%99%88-%EC%83%9D%ED%83%9C%EA%B3%84</guid>
            <pubDate>Sat, 26 Oct 2024 14:59:36 GMT</pubDate>
            <description><![CDATA[<h3 id="스마트-홈이란">스마트 홈이란?</h3>
<p>인터넷에 연결된 다양한 IoT(사물인터넷) 기기들이 가정 내에서 서로 통신하고 데이터를 주고받아 자동화된 환경을 제공하는 주거 시스템이다. 주로 조명, 냉난방, 보안, 가전제품 등을 원격으로 제어하는데 사용한다.
<img src="https://velog.velcdn.com/images/martin_0610/post/9609384c-1a40-4c32-8dc5-f938eead38bc/image.webp" alt=""></p>
<h3 id="제어-방법">제어 방법</h3>
<p>IoT를 제어하는 방법은 크게 3가지 정도가 있다.</p>
<ul>
<li><p><strong>기기에 내장된 Wifi 모듈을 활용한 Wifi를 사용해 P2P 또는 클라우드 서버 제어</strong>
이 경우 Samsung Smart Things와 같은 플랫폼의 OpenApi를 사용하거나, 직접 Api를 만들어야한다. 보통의 경우 P2P보다는 지속적인 보안 업데이트 및 외부 접근의 모니터링에 유용한 클라우드를 사용한다.</p>
</li>
<li><p><strong>기기에 내장된 적외선 IR모듈을 통한 제어</strong>
IoT의 지원이 되지 않는 기존 기기들도 리모컨을 사용하는 경우 연결이 가능하다는 장점이 있다. 이 경우 서버 또는 허브와 기존 기기들을 연결시켜주는 리모컨이 필요하다.</p>
</li>
<li><p><strong>허브를 사용해 기기들을 통합하여 제어</strong>
Matter, Zigbee, Z-wave등 여러가지 모듈들 중 하나또는 복수 모듈을 사용한다.</p>
<br>

</li>
</ul>
<h3 id="각-허브의-특징">각 허브의 특징</h3>
<p><strong>Matter:</strong> CSA에서 만든 IoT규격으로, 여러 회사의 기기를 연동할 수 있게 한 방법, 이는 CSA의 연간 3000$를 지불해야하고, 심사를 통과해야하기 때문에 스타트업, 소규모 프로젝트에서 고려할만한 방법은 아니다.</p>
<p><strong>Zigbee:</strong> 2.4GHz 대역을 사용하여 전 세계적으로 호환 가능하다. 또한 데이터 전송 속도가 빠르고 저지연성이기 때문에 많은 기기와의 빠른 연결에 적합하다. 하지만 10~20미터의 짧은 커버리지를 가지고 있기에, 매쉬 네트워크를 사용한 확장이 필요하다.</p>
<p><strong>Z-Wave:</strong> 지역별로 전용 주파수 대역(미국 908MHz, 유럽 868MHz 등)을 사용하여 전파 간섭이 적다. 전송 속도는 Zigbee보다 느리지만 스마트 홈의 제어 신호로 사용하기에는 무리가 없다. 벽을 잘 통과하면 30미터 정도의 넓은 커버리지를 가지고 있다.</p>
<h3 id="제어-입력">제어 입력</h3>
<p>IoT 제품을 제어하기 위해 여러가지 입력 방식을 선택할 수 있다.</p>
<ul>
<li><strong>디바이스 입력 방식</strong>
가장 일반적이고 보편화된 방식으로 휴대폰, PC등을 사용해 기기를 제어한다.</li>
<li><strong>음성 입력 방식</strong>
자연어 처리 기술을 사용해 음성 명령을 통해 기기를 제어한다.</li>
<li><strong>제스처 입력 방식</strong>
카메라를 통해 손짓 등의 제스처를 입력받아 기기를 제어한다.<br>

</li>
</ul>
<h3 id="iot-리모컨이란">IoT 리모컨이란?</h3>
<p>IoT 리모컨은 기존 리모컨의 적외선 신호를 IoT 리모컨에 등록하여, 이를 통해 기기들을 제어하는 리모컨을 말한다. </p>
<p>일반적으로 IR소자를 사용해 적외선 신호를 Byte로 저장하며, 앱을 사용해 저장된 Byte값을 담아 적외선 신호를 쏘는 것으로 기기를 제어한다.
<img src="https://velog.velcdn.com/images/martin_0610/post/841762cc-11bd-454a-bb84-47b26a6cda6d/image.png" alt=""></p>
<p><strong>Arduino기반 IR 리모컨 라이브러리</strong>: 
<a href="https://github.com/Arduino-IRremote/Arduino-IRremote">https://github.com/Arduino-IRremote/Arduino-IRremote</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Flutter] Tensorflow 모델을 활용한 Hand gesture recognition 제작]]></title>
            <link>https://velog.io/@martin_0610/Flutter-Tensorflow-%EB%AA%A8%EB%8D%B8%EC%9D%84-%ED%99%9C%EC%9A%A9%ED%95%9C-Hand-gesture-recognition-%EC%A0%9C%EC%9E%91</link>
            <guid>https://velog.io/@martin_0610/Flutter-Tensorflow-%EB%AA%A8%EB%8D%B8%EC%9D%84-%ED%99%9C%EC%9A%A9%ED%95%9C-Hand-gesture-recognition-%EC%A0%9C%EC%9E%91</guid>
            <pubDate>Sat, 19 Oct 2024 14:58:11 GMT</pubDate>
            <description><![CDATA[<p>이 글에서는 내가 그로스로그 모임에서 추진하려는 프로젝트를 진행하기 전 먼저 기능을 사용해보는 것이 좋을 것 같아 시작하게 된 개인 프로젝트에서 Tensorflow를 사용한 경험과, 이후 해결 해야할 문제에 대해 정리해보려한다.</p>
<h3 id="tensorflow란">Tensorflow란?</h3>
<p>Tensorflow는 수치 계산, 대규모 머신 러닝, 딥러닝, 기타 통계 및 예측 분석 워크로드를 위한 오픈 소스 라이브러리이다. 이를 통해 개발자들이 머신 러닝 모델을 구현하는 것을 더 빠르고 쉽게 만드는 기술이다.</p>
<h3 id="프로젝트-진행-과정">프로젝트 진행 과정</h3>
<p>프로젝트의 목적은 손을 모을 때와 폈을 때 0~100 사이의 실수값이 변수에 담기도록 하는 것이다. 간단하게 프로젝트를 살펴보면  다음과 같이 구성되어있다.</p>
<ul>
<li><strong>tflite Model:</strong> assets/models/hand_landmark.tflite에 위치한 학습되어있는 모델을 사용해 hand landmark를 추적</li>
<li><strong>IsolateUtils:</strong> 반복되는 추론 작업을 처리하기 위해 메모리 공간 분리</li>
<li><strong>TensorflowProvider:</strong> IsolateUtils 클래스를 활용한 추론 및 데이터 가공 작업 (추후 domain/use_case로 분리 할 것)</li>
<li><strong>CameraProvider:</strong> 내장 카메라를 사용하여 이미지를 프레임당 callback하는 함수를 호출 Ui Boundary에서 TensorflowProvider로 CameraImage 객체 전달</li>
</ul>
<p>위와 같이 개발된 프로젝트를 기반으로 TensorflowProvider에서 추론을 통해 가공되지않은 데이터를 전달받으면 데이터를 다음과 같이 가공한다.
<img src="https://velog.velcdn.com/images/martin_0610/post/d377e677-6144-4e67-b9b0-ebdb1eae30ee/image.png" alt=""></p>
<p>4, 8, 12, 16, 20 번 landmark의 좌표값을 가져와 해당 좌표들이 가깝게 위치할 경우 손을 모았다고 판단, 떨어져 있을 때 손을 폈다고 판단해 0~100 사이의 실수값을 반환하는 로직을 만들었다.</p>
<pre><code class="language-dart">double _calculateHandFoldPercentage(List&lt;Offset&gt; points) {
    if (state.initialDistance == 0.0) {
      state = state.copyWith(initialDistance: (points[1] - points[0]).distance);
    }

    final indicesToCheck = [4, 8, 12, 16, 20];

    final currentDistance = (points[1] - points[0]).distance;

    final distanceFactor = state.initialDistance / currentDistance;

    double weightedDistanceSum = 0.0;
    double weightSum = 0.0;
    double interpolationFactor = 0.5;

    for (int i = 0; i &lt; indicesToCheck.length - 1; i++) {
      int index1 = indicesToCheck[i];
      int index2 = indicesToCheck[i + 1];

      double segmentDistance = (points[index1] - points[index2]).distance * distanceFactor;
      double weight = 1.0 / (1.0 + interpolationFactor * segmentDistance);

      weightedDistanceSum += segmentDistance * weight;
      weightSum += weight;
    }

    double averageWeightedDistance = weightedDistanceSum / weightSum;

    double maxDistance = 500.0;
    double foldPercentage = (1 - (averageWeightedDistance / maxDistance)) * 100.0;
    return foldPercentage.clamp(0.0, 100.0);
  }</code></pre>
<p>해당 로직으로 가공을 진행한 이후 로그를 출력하면 아래와 같이 출력된다.
<img src="https://velog.velcdn.com/images/martin_0610/post/b015e912-002a-4686-90ae-c1728521d04f/image.png" alt=""></p>
<h3 id="프로젝트-진행-도중-마주한-문제점">프로젝트 진행 도중 마주한 문제점</h3>
<p>프로젝트를 진행하며 문제점이 몇가지 있었다.</p>
<ol>
<li>거리에 따라 224*224 픽셀의 이미지에서 손이 차지하는 비율의 차이가 있고, landmark 사이의 좌표값이 멀거나 가까워지게 된다.</li>
<li>위 문제를 해결하기 위해 0번 1번 landmark의 거리를 보간으로 사용하였지만 손의 각도가 달라지면 이 값도 신뢰도가 떨어진다.</li>
<li>손의 떨림으로 인해 1.0 이상의 유의미한 값의 변화가 지속적으로 있다.</li>
</ol>
<p>위와 같은 문제를 해결하기 위해 Mediapipe 모델을 직접 학습시켜, 데이터 가공을 내부에서 처리하거나 처리하기에 쉬운 다른 제스쳐를 고안해보는 방법을 생각해야 되겠다.
<br>
<strong>Hand-Gesture-Recognition Project:</strong> <a href="https://github.com/Yeseung0610/Hand-Gesture-Recognition">https://github.com/Yeseung0610/Hand-Gesture-Recognition</a>
<strong>Google Mediapipe:</strong> <a href="https://github.com/google-ai-edge/mediapipe">https://github.com/google-ai-edge/mediapipe</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Flutter] Future<Flutter> 컨퍼런스 참여 후기 ]]></title>
            <link>https://velog.io/@martin_0610/FutureFlutter-%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-%EC%B0%B8%EC%97%AC-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@martin_0610/FutureFlutter-%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-%EC%B0%B8%EC%97%AC-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Sat, 28 Sep 2024 14:55:04 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/martin_0610/post/48c524e1-6c1f-439a-8bc0-6802f8b802ae/image.jpg" alt="">
오늘 Flutter Seoul과 Flutter Incheon에서 주관하는 <strong>Future&lt;Flutter&gt;</strong> 컨퍼런스에 참여하기위해 인천 송도 컨벤시아를 방문했다. 컨퍼런스의 세션은 총 10개로 구성되어있었고, 모두 알찬 내용들로 구성되어있어 7시간이 넘는 시간동안 지루함을 느낄 틈이 없었다.</p>
<ul>
<li><strong>Session 01:</strong> FFI로 연결하는 고(GO)와 플러터</li>
<li><strong>Session 02:</strong> WebRTC</li>
<li><strong>Session 03:</strong> 쇼어버드 작동 방식</li>
<li><strong>Session 04:</strong> 풍성한 디자인 요청사항에 대응하기</li>
<li><strong>Session 05:</strong> 플러터 렌더링 해부학</li>
<li><strong>Session 06:</strong> Flutter Web을 활용하여 제품 개발 환경 개선하기</li>
<li><strong>Session 07:</strong> 어느날 갑자기 앱이 터졌을 때</li>
<li><strong>Session 08:</strong> Flutter Bloc을 제품 개발에 야무지게 적용하기</li>
<li><strong>Session 09:</strong> Empathetic Flutter</li>
<li><strong>Session 10:</strong> webOS TV에 Flutter 적용하기</li>
</ul>
<p>모든 세션을 포스트에 담기는 어려우니, 몇 가지 세션에서 내가 얻은 인사이트를 공유해보고자 한다. (얻은 인사이트는 추후 심도깊게 공부하여, 개별 포스트를 작성할 예정이다.)</p>
<h3 id="session-02-webrtc">Session 02. WebRTC</h3>
<p>해당 세션에서는 WebRTC 기술을 사용해 화상통화를 구현한 경험을 공유했다. 이야기에 앞서 WebRTC란 무엇일까?
WebRTC란 <strong>Web Real-Time Communication</strong>의 약자로, 웹 브라우저간 중간자 없이 실시간 미디어 스트리밍을 하기위한 표준 규격이다.
같은 공유기를 사용하는 것이 아닌 경우 P2P(Peer to Peer) 통신으로 클라이언트를 연결시켜야하는데 사이에 방화벽이 있거나, NAT환경에 있는 경우에는 P2P 통신이 불가하다. 이 때 STUN, TURN 서버를 사용해 사용자 기기의 외부 IP를 얻어오고, 시그널링하는 것으로 P2P 연결을 할 수 있다. 추가로 해당 프로젝트 개발 시 Flutter에서 WebSocket을 사용해 실시간으로 시그널링을 했다는 말씀도 들었다.</p>
<p>마무리를 하시며 화상통화가 연결되기 전 통화가 종료될 경우, 수신자쪽에 Push 알림을 전송해 통화 알람 및 진동이 울리지 않도록 처리했다는 예시와 함께 <strong>전혀 관련이 없어보이던 지식들이 연결되는 경험을 했다</strong>고 말씀하셨다.</p>
<p>이런 경험들이 개발자로 일하며 가장 짜릿한 경험이 아닐까라는 생각이들었다. (부럽다)</p>
<pre><code>관련 키워드: RTCPeerConnection, ICE, TURN, STUN, MDN</code></pre><h3 id="session-07-어느날-갑자기-앱이-터졌을-때">Session 07. 어느날 갑자기 앱이 터졌을 때</h3>
<p>개발자의 짜릿한 경험을 이야기했으면 가장 저릿한 경험도 같이 이야기해봐야하지 않을까?
주제만 봐도 가슴이 무거워지는 내용이다. 해당 세션에서는 개발환경에서는 재현이 안되고, 고객의 기기에서만 재현되는 문제를 겪은 사례와 재현 경로 확보 및 재발 방지를 한 경험을 공유해주셨다.</p>
<p><em>앱을 실행하자마자 꺼진다는 이슈를 보고 받은 뒤, 배포 시점의 커밋으로 돌아가 빌드 및 실행을 진행했다. 하지만 앱은 어떠한 문제도 없이 정상 동작하였으며, Firebase Crashtics, Datadog등에도 보고된 문제가 없었다.</em></p>
<p><em>모든 이슈는 iOS에서 보고되었고, 이에 Xcode에서 Console창을 열어 로그를 확인한 결과, 충돌이 발생하는 것을 확인했다.</em></p>
<p><em>충돌이 발생하지 않도록 해결 후 재배포를 진행했다.</em></p>
<p><em>하지만 이는 이슈와 관련되지 않은 별개의 이슈라, 결론적으로 이슈 해결은 되지 않았다.</em></p>
<p><em>장애 발생 고객들의 마지막 접속 기록을 활용해 특정 OS 버전의 문제인 것을 인지, 해당 버전의 기기에서 이슈를 재현해 크래시 로그를 확보했다.</em></p>
<p><em>로그를 분석해 Native에서 발생한 초기화 문제인 것을 확인하고 해당 초기화 기능의 의존성 제거 및 핫픽스 배포를 진행했다.</em></p>
<p><em>급한 불이 꺼진 후 다시 원점으로 돌아가 문제를 해결 후 재배포를 진행했다.</em></p>
<p>이 같은 경험을 하면서 초기화 단계 Native에서 발생한 이슈는 Flutter Engine이 정상적으로 초기화되기 이전 시점이기에 Flutter에서 작성한 모니터링 도구에 기록되지 않으니, 생각해보아야한다고 말씀해주셨다. </p>
<p>발표를 마무리하시며 이전에 Arm cpu 아키텍처의 공부가 crash log를 분석하는데 도움이 되었다고 하셨으며, 이를 통해 cs지식이 평소에는 도움이 되지 않는 것 같지만, 긴급한 상황에서 문제 해결 능력을 높히는데 큰 도움이 된다는 몸소 느낀 귀중한 경험을 공유해주셨다.</p>
<h3 id="마무리">마무리</h3>
<p>세션들에서 공통적으로 FFI를 사용해 다른 언어의 라이브러리를 사용한 경험을 많이 공유해주셨다. 아직까지 Flutter에서 기본적으로 지원하는 라이브러리가 부족한 것일까? 라는 생각이 들어 아쉽긴 하다. 어떻게 보면 아직 발전 가능성이 많은 프레임워크가 아닌가!라는 긍정적인 생각을 가져야겠다. </p>
<p>다음에도 이러한 컨퍼런스가 있으면 참여할 의향이 강하게 드는 하루였다. 그 자리에서 모든 것을 이해하지 못하더라도 새롭게 얻고 가는 인사이트의 가치가 매우 크게 느껴졌기 때문이다. 다시 한번 컨퍼런스를 주관해주신 Flutter Seoul과 Flutter Incheon 관계자 분들께 감사를 느끼며 포스트를 마무리하겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Flutter] Android Project에 Flutter Module 사용하기]]></title>
            <link>https://velog.io/@martin_0610/Android-Project%EC%97%90-Flutter-Module-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@martin_0610/Android-Project%EC%97%90-Flutter-Module-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 14 Sep 2024 14:43:04 GMT</pubDate>
            <description><![CDATA[<h2 id="크로스-플랫폼의-장단점">크로스 플랫폼의 장단점</h2>
<h4 id="장점">장점</h4>
<ul>
<li><strong>[개발 비용 절감]</strong>
  하나의 코드베이스에서 iOS, Android 등 여러 플랫폼을 한번에 개발해 비용 절감 및 시간 단축이 가능하다.</li>
<li><strong>[디자인 일관성]</strong>
  각 플랫폼 별로 UI/UX를 설계 또는 수정하지 않아 유지보수에 용이하다.</li>
<li><strong>[범용성]</strong>
  다른 플랫폼으로의 서비스 확장이 용이하다.</li>
</ul>
<p>위와 같이 기업들은 다양한 이유로 크로스 플랫폼을 선택한다. 이 같이 크로스 플랫폼으로 개발했을 때의 장점은 명확하지만, 무시할 수 없는 단점 또한 가지고 있다.</p>
<h4 id="단점">단점</h4>
<ul>
<li><strong>[프레임워크 제약]</strong>
  Sensor, Bluetooth 등, 플랫폼 별 구현해야하는 기능이 다를 경우 Native에서 처리해야한다.</li>
<li><strong>[성능 이슈]</strong>
  플랫폼 별 최적화된 언어로 개발하는 것이 아니기 때문에 퍼포먼스가 떨어진다.<br>

</li>
</ul>
<p>위 문제와 더불어 기업에서 크로스 플랫폼을 도입하기 어려운 이유는 기존에 잘 만들어진 플랫폼 별 Native 프로젝트가 있기 때문일 것이다. 때문에 이 글에서는 Flutter를 사용하여 조금 더 라이트하게 기존 프로젝트에 크로스 플랫폼을 도입할 수 있는 방법을 설명하려한다. </p>
<h2 id="flutter-module-설정">Flutter Module 설정</h2>
<p>기존 Android Native 프로젝트에 Flutter를 사용하려면 Flutter Module을 만들어 연결하는 방법이 있다.</p>
<p>먼저 Android Studio에서 <strong>New Flutter Project &gt; Flutter &gt; Set Flutter Sdk &gt; Flutter Module</strong>을 선택해 모듈을 생성해준다.</p>
<p>생성된 모듈은 aar을 빌드해 사용하는 방법과 소스 코드를 그대로 사용하는 방법이 있다. 이번 글에서는 aar을 빌드해 사용하는 방법을 소개하겠다.</p>
<p>aar을 빌드하기 위해서는 Flutter 모듈 위치에서 terminal을 실행해 다음을 실행한다.</p>
<pre><code>cd some/path/flutter_module
flutter build aar</code></pre><p>이후 Android 프로젝트의 settings.gradle 파일을 다음과 같이 수정한다.</p>
<pre><code>dependencyResolutionManagement {
    // 이 모드가 설정되면 프로젝트에서 직접 또는 플러그인을 통해 직접 선언된 모든 저장소가 무시된다.
    repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
    repositories {
        google()
        mavenCentral()
        maven {
            // 적용할 Flutter 모듈의 repo 위치를 등록한다.
            url = uri(&quot;android_with_flutter_module/build/host/outputs/repo&quot;)
        }
        maven {
            url = uri(&quot;https://storage.googleapis.com/download.flutter.io&quot;)
        }
    }
}</code></pre><p>또한 Android 프로젝트의 app/build.gradle 파일에 다음 코드를 추가한다.</p>
<pre><code>dependencies {
    // libs.flutter.* 는 gradle/libs.versions.toml 파일에 기록되어있다.
    debugImplementation(libs.flutter.debug)
    releaseImplementation(libs.flutter.release)
}</code></pre><p>추가로 profile 환경 분리가 필요하다면 아래 코드를 추가한다.</p>
<pre><code>android {
    buildTypes {
        release {
          ...
        }
        debug {
          ...
        }
        create(&quot;profile&quot;) {
            initWith(getByName(&quot;debug&quot;))
        }
}

dependencies {
  // ...
  add(&quot;profileImplementation&quot;, &quot;com.example.flutter_module:flutter_profile:1.0&quot;)
}</code></pre><h2 id="flutter-프로젝트-연결">Flutter 프로젝트 연결</h2>
<p>AndroidManifest.xml 파일을 열어 application 태그에 아래 코드를 추가한다.</p>
<pre><code>&lt;activity
  android:name=&quot;io.flutter.embedding.android.FlutterActivity&quot;
  android:theme=&quot;@style/LaunchTheme&quot;
  android:configChanges=&quot;orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode&quot;
  android:hardwareAccelerated=&quot;true&quot;
  android:windowSoftInputMode=&quot;adjustResize&quot;
  /&gt;</code></pre><p>이 프로젝트에서는 두가지 방법으로 Flutter 엔진을 사용한다.</p>
<ol>
<li>페이지가 열릴 때 마다 Flutter engine 초기화</li>
<li>Flutter engine을 캐싱하여 앱 종료전까지 메모리 유지</li>
</ol>
<p>1번의 경우 비교적 간단한 코드를 사용해 Flutter engine을 실행한다.</p>
<pre><code>val createFlutterEngineButton: Button = findViewById(R.id.create_flutter_engine_button)
createFlutterEngineButton.setOnClickListener {
    startActivity(
        FlutterActivity.createDefaultIntent(this)
    )
}</code></pre><p><img src="https://velog.velcdn.com/images/martin_0610/post/5ffbe1cb-5c54-4d03-b1b0-a2c4b4ca218e/image.gif" alt="">
이렇게 실행된 페이지는 페이지를 다시 실행할 경우 정보가 초기화된다.</p>
<p>2번의 경우 아래의 코드를 사용해 Flutter engine을 실행한다.</p>
<pre><code>flutterEngine = FlutterEngine(this)
flutterEngine.dartExecutor.executeDartEntrypoint(
    DartExecutor.DartEntrypoint.createDefault()
)

FlutterEngineCache.getInstance().put(CACHED_ENGINE, flutterEngine)

val cacheFlutterEngineButton: Button = findViewById(R.id.cache_flutter_engine_button)
cacheFlutterEngineButton.setOnClickListener {
    startActivity(
        FlutterActivity.withCachedEngine(CACHED_ENGINE).build(this)
    )
}</code></pre><p><img src="https://velog.velcdn.com/images/martin_0610/post/8e1c292e-1ea1-43f3-9f69-c9efe94b7028/image.gif" alt="">
이렇게 실행된 페이지는 페이지를 다시 실행해도 정보를 캐싱하고 있다.
<br></p>
<p>이번 글에서는 간단한 예제를 통해 Flutter Module을 연결하는 법을 사용해보았다. 단순히 모듈을 사용하는 예제라 필요할지 모르겠지만, 확인해보고 싶은 사람들을 위해 프로젝트 링크를 아래에 포함했다.</p>
<p><a href="https://github.com/Yeseung0610/Android_With_Flutter">Android With Flutter Project</a></p>
<p>참고한 문서
<a href="https://docs.flutter.dev/add-to-app/android/add-flutter-screen">https://docs.flutter.dev/add-to-app/android/add-flutter-screen</a></p>
]]></description>
        </item>
    </channel>
</rss>