<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>minjeong.log</title>
        <link>https://velog.io/</link>
        <description>프론트엔드 개발자 👩‍💻</description>
        <lastBuildDate>Fri, 11 Jul 2025 22:48:14 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>minjeong.log</title>
            <url>https://velog.velcdn.com/images/minjeong-dev/profile/9382ca7d-8547-4448-b6f9-05a3d65a84e1/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. minjeong.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/minjeong-dev" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[2-3. AWS Cloud Practitioner Essentials 공부하기 (Module 5~6)]]></title>
            <link>https://velog.io/@minjeong-dev/2-3.-AWS-Cloud-Practitioner-Essentials-%EA%B3%B5%EB%B6%80%ED%95%98%EA%B8%B0-Module-67</link>
            <guid>https://velog.io/@minjeong-dev/2-3.-AWS-Cloud-Practitioner-Essentials-%EA%B3%B5%EB%B6%80%ED%95%98%EA%B8%B0-Module-67</guid>
            <pubDate>Fri, 11 Jul 2025 22:48:14 GMT</pubDate>
            <description><![CDATA[<ul>
<li>Module 5: Storage And Databases</li>
<li>Module 6: Security</li>
</ul>
<hr>
<h1 id="module-5">Module 5</h1>
<h2 id="amazon-ec2-instance-store">Amazon EC2 instance store</h2>
<p>&quot;no data persistence&quot;</p>
<blockquote>
<p>Block-level storage = a place to store files</p>
</blockquote>
<p>instanse store는 EC2 인스턴스에게 임시적인 block-level storage이다. 만약 EC2 인스턴스가 정지/중단되면 연결된 instance store에 있던 모든 데이터도 삭제된다. EC2 인스턴스는 virtual 서버이기 대문에 정지/중단 후 다시 시작할 때 다른 host에서 시작하게 된다. 따라서 장기로 저장하여 관리할 필요 없는 임시 데이터만 사용해야 한다.</p>
<p>장점</p>
<ul>
<li>Automatically available: EC2 타입에 맞게 자동으로 연결되어 사용 가능</li>
<li>Cost effective: 별도의 추가 비용 없음</li>
<li>High performance: 임시 저장 공간의 빠른 프로세싱 속도</li>
</ul>
<h2 id="amazon-ebs">Amazon EBS</h2>
<p>Block-level storage volumes behave like physical hard drives.
virtual hard drive라는 표현이 나왔다... 신기하다.</p>
<p>EC2 인스턴스가 정지/중단 되더라도 EBS 내의 모든 데이터는 사용 가능한 상태로 유지된다. 사이즈, 타입 등을 결정하여 구성한 뒤 EC2 인스턴스와 연결해주면 된다.</p>
<p>장점</p>
<ul>
<li>데이터 마이그레이션: 스냅샷을 이용해 다른 AZ 간 데이터 이동 및 복사가 간단하고 쉽다.</li>
<li>인스턴스 타입 변경: EC2 인스턴스로부터 독립적으로 구성, 유지되므로 EC2 인스턴스의 타입에 영향을 받지 않을 수 있다. 이런 유연함이 업/다운그레이드 하여 운용하기도 좋다.</li>
<li>재해 복구: EBS 스냅샷이라는 백업 솔루션.</li>
<li>비용 개선: 실제 사용량에 따라 스토리지 타입이나 용량을 조절할 수 있어 비용 최적화 가능.</li>
<li>성능 튜닝: 크기 뿐만 아니라 워크로드 요구사항, IOPS(스토리지 입출력 성능 지수) 등을 조절함으로써 성능 개선 가능.</li>
</ul>
<p><strong>Amazon EBS snapshot</strong></p>
<blockquote>
<p>snapshot = incremental backup</p>
</blockquote>
<p>서서히 증가하는 백업? 무슨 의미인가 봤더니 첫 백업에는 모든 데이터를 백업, 그 이후로는 백업할 때 바뀐 데이터들만 백업한다고. full backup과는 다르다.</p>
<p>Amazon Data Lifecycle Manager Workflow</p>
<ol>
<li>Create an EBS snapshots policy</li>
<li>Select target resource type: 스냅샷의 대상으로 EBS나 EC2 인스턴스를 선택</li>
<li>Exclude volumns: 스냅샷이 차지할 저장 용량 구성.</li>
<li>Set custom schedules: 스냅샷 자동 생성, 보존, 삭제 스케쥴 세팅</li>
<li>Apply additional actions: 스냅샷 아카이빙이나 태깅(분류), 스냅샷 타 리전에 복사 등의 추가 동작을 명시할 수 있다.</li>
</ol>
<h2 id="amazon-s3">Amazon S3</h2>
<p>Object-level storage. 유니크한 키를 통해 데이터에 접근한다.</p>
<ul>
<li>store data as objects.</li>
<li>store objects in buckets.</li>
<li>upload a maximum object size of 5 TB.</li>
<li>version objects. (버전 트래킹?)</li>
<li>create multiple buckets.</li>
</ul>
<blockquote>
<p><em>Amazon S3 Lifecycle management:
Move data automatically between tiers</em></p>
</blockquote>
<h3 id="amazon-s3-storage-classes">Amazon S3 Storage Classes</h3>
<p>어떤 유형의 S3를 사용할 때 고려할 수 있는 2개의 요인:</p>
<ul>
<li>데이터를 얼마나 잦은 빈도로 검색하려고 하는가?</li>
<li>데이터(의 가용성) 얼마나 필요한가?</li>
</ul>
<h4 id="s3-standard">S3 Standard</h4>
<ul>
<li>자주 데이터 엑세스가 이루어질 경우</li>
<li>최소 3개의 AZ에 데이터를 저장할 경우</li>
</ul>
<p>high availability. 웹사이트 처럼 유즈케이스의 범위가 넓거나 컨텐츠가 여러 지역으로 분산되는 경우 적합하다.</p>
<h4 id="s3-standard-ia">S3 Standard-IA</h4>
<p>= Amazon S3 Standard Infrequent Access</p>
<ul>
<li>데이터 엑세스가 뜸하게 이루어질 경우(로 예상되는)</li>
<li>S3 Standard와 비슷하지만 더 적은 storage 비용, 더 높은 데이터 검색 비용</li>
</ul>
<p>S3 Standard와 같은 수준의 가용성이 보장된다. 동일하게 최소 3개의 AZ에 데이터를 저장해야 한다.</p>
<h4 id="s3-one-zone-ia">S3 One Zone-IA</h4>
<p>= Amazon S3 One Zone Infrequent Access</p>
<ul>
<li>S3 Standard-IA 보다 저렴한 storage 비용으로 사용할 경우</li>
<li>1개의 AZ에 데이터를 저장할 경우</li>
</ul>
<h4 id="s3-express-one-zone">S3 Express One Zone</h4>
<ul>
<li>1개의 AZ에 데이터를 저장.</li>
<li>n &lt; 10 ms 내에 데이터를 액세스할 수 있다.</li>
<li>S3 Standard보다 최대 10배 속도가 빠르면서 최대 80% 더 저렴하다.</li>
</ul>
<h4 id="s3-intelligent-tiering">S3 Intelligent-Tiering</h4>
<ul>
<li>데이터 엑세스 하는 패턴이 계속 바뀌거나 추정할 수 없는 경우</li>
<li>각 객체 당 월별 모니터링과 자동화가 필요한 경우</li>
</ul>
<p>모니터링을 통해 30일 이상 엑세스 되지 않은 데이터는 S3 Standard-IA로 옮기고, 엑세스 된 데이터는 S3 Standard에 옮긴다.</p>
<h4 id="s3-glacier-instance-retrieval">S3 Glacier Instance Retrieval</h4>
<ul>
<li>가끔 접근하는 데이터지만 데이터에 즉각적인 접근이 필요한 경우</li>
<li>S3 Standard와 동일한 성능으로 수행되는데 1초 미만 (ms 단위) 소요된다고 한다.</li>
</ul>
<h4 id="s3-glacier-flexible-retrieval">S3 Glacier Flexible Retrieval</h4>
<ul>
<li>데이터 아카이빙 등 저비용으로 설계해야 하는 경우</li>
<li>데이터 접근 자체에 1분 ~ 12시간이 걸려도 되는 경우</li>
<li>1년에 1~2회 정도 엑세스 하는 데이터에 권장</li>
</ul>
<h4 id="s3-glacier-deep-archive">S3 Glacier Deep Archive</h4>
<ul>
<li>가능한 최저비용으로 설계해야 하는 경우</li>
<li>데이터 접근 자체에 12시간 ~ 48시간까지 걸려도 되는 경우</li>
</ul>
<h4 id="s3-outposts">S3 Outposts</h4>
<ul>
<li>Amazon S3 Outpost에 S3 Bucket을 만든다.</li>
<li>데이터에 검색, 저장, 접근하기를 더욱 쉽게 만든다고 한다.</li>
</ul>
<h3 id="s3-lifecycle">S3 Lifecycle</h3>
<p>A feature used to define rules to automatically transition objects between different storage classes, or delete them based on age or usage patterns.
객체 생성 후 일정 시간이 지나면 다른 클래스가 되도록 지정할 수 있다.
객체의 클래스 변경도 가능하고, 데이터의 삭제도 정의할 수 있다.</p>
<h2 id="amazon-efs">Amazon EFS</h2>
<p>File storage에는 여러 클라이언트가 공유되는 파일 폴더의 데이터를 접근할 수 있다. storage server는 block storage를 사용하고, 클라이언트는 path를 통해 데이터에 접근한다.</p>
<p>Amazon EFS is a scalable file system used with AWS Cloud services and on-premises resources.</p>
<ul>
<li>Multiple instances reading and writing simultaneously.</li>
<li>Linux file system.</li>
<li>Regional resource.</li>
</ul>
<h3 id="amazon-ebs-↔-amazon-efs">Amazon EBS ↔ Amazon EFS</h3>
<table>
<thead>
<tr>
<th></th>
<th>Amazon EBS</th>
<th>Amazon EFS</th>
</tr>
</thead>
<tbody><tr>
<td>AZ</td>
<td>Single AZ</td>
<td>Multiple AZ</td>
</tr>
</tbody></table>
<p>Amazon EBS는 연결된 EC2 인스턴트와 같은 AZ 내에 위치해야 한다. Amazon EFS는 여러 AZ에 걸쳐 동시성이 보장된 데이터에 접근할 수 있고, on-premise 서버는 AWS Direct Connect를 이용해 데이터를 요청할 수 있다.</p>
<h2 id="amazon-fsx">Amazon FSx</h2>
<p>File system 구성 및 관리 운영 서비스. 스케일 업/다운 가능하고 비용도 낮다?
Windows, NetApp ONTAP, OpenZFS, Lustre</p>
<h2 id="amazon-rds">Amazon RDS</h2>
<p>AWS Cloud에서 관계형 데이터베이스를 사용할 수 있도록 해주는 서비스다.</p>
<h3 id="amazon-aurora">Amazon Aurora</h3>
<p>Enterprise-class relational database. high availability가 요구되는 경우 적합하다. 3개의 AZ에 걸쳐 (S3에 백업을 통해) 6개의 복제본을 둔다.</p>
<ul>
<li>MySQL, PostgreSQL을 지원한다.</li>
<li>standard MySQL DB보다 5배, standard PostgreSQL DB보다 3배 빠르다.</li>
<li>1/10의 비용.</li>
<li>S3에 데이터 백업.</li>
</ul>
<h2 id="amazon-dynamodb">Amazon DynamoDB</h2>
<p>Serverless, Non-Relational (NoSQL) Database. key-value의 쌍으로 된 데이터로 구성되어 있어 add/remove할 때 아주 간단하다. 어떤 스케일이어도 10 ms도 걸리지 않는 성능을 보장한다.</p>
<ul>
<li>Serverless</li>
<li>Automatic Scaling</li>
</ul>
<h2 id="amazon-redshift">Amazon Redshift</h2>
<p>Amazon Redshift is a data warehousing service that you can use for big data analytics.</p>
<h2 id="aws-database-services">AWS Database Services</h2>
<h3 id="aws-database-migration-service-dms">AWS Database Migration Service (=DMS)</h3>
<ul>
<li>테스트 혹은 백업 목적의 데이터 복사, 이동.</li>
<li>Database Consolidation: 여러 개의 데이터베이스의 데이터를 한 개의 데이터베이스로 결합.</li>
<li>Continuous Replication: 한 개의 데이터베이스를 여러 개의 데이터베이스로 분산.</li>
</ul>
<h4 id="homogenous-databases">Homogenous Databases</h4>
<p>동일한 DB 엔진으로 마이그레이션하는 것. 스키마 구조, 데이터 타입, DB 코드 자체도 source와 target이 같게 된다.</p>
<p>On-Premise / AWS EC2 / AWS RDS ---&gt; AWS EC2 / AWS RDS</p>
<p>1) DMS를 사용해 마이그레이션을 완료한다.</p>
<h4 id="heterogeneous-databases">Heterogeneous Databases</h4>
<p>다른 DB 엔진으로 마이그레이션하는 것. 스키마 구조, 데이터 타입, DB 코드 자체가 source와 target이 다르게 된다.</p>
<p>1) AWS Schema Conversion Tool을 통해 source를 target에 맞게 변형한다.
2) DMS를 사용해 마이그레이션을 완료한다.</p>
<h3 id="additional-database-services">Additional Database Services</h3>
<p>사업적 필요와 목적, 비용 등을 고려하여 적절한 Database 서비스를 선택하여 개발해야 한다.</p>
<h4 id="amazon-documentdb">Amazon DocumentDB</h4>
<p><strong>document</strong> database service that supports MongoDB workloads. <em>(MongoDB = document database program)</em></p>
<h4 id="amazon-neptune">Amazon Neptune</h4>
<p><strong>graph</strong> database service.</p>
<h4 id="amazon-quantum-ledger-database">Amazon Quantum Ledger Database</h4>
<p><strong>ledger</strong> database service.</p>
<h4 id="amazon-managed-blockchain">Amazon Managed Blockchain</h4>
<p>manage blockchain networks with open-source frameworks.</p>
<h4 id="amazon-elasticache">Amazon ElastiCache</h4>
<p>Redis and Memcached. database에 caching layer를 추가하여 공통적인 요청의 읽기 시간을 개선한다?</p>
<h4 id="amazon-dynamodb-accelerator">Amazon DynamoDB Accelerator</h4>
<p>in-memmory cache for DynamoDB. n milliseconds -&gt; n milesconds...</p>
<h2 id="그-외-스토리지-서비스">그 외 스토리지 서비스</h2>
<h3 id="aws-storage-gateway">AWS Storage Gateway</h3>
<p>완전 관리형. 하이브리드 클라우드 스토리지 서비스. 온프레미스 서버에 클라우드 스토리지를 제공할 때 유용.
자주 사용하는 데이터를 낮은 지연을 유지하면서 로컬 스토리지에서 클라우드로 확장.</p>
<ul>
<li>Amazon S3 File Gateway: 자주 액세스하는 데이터는 로컬, 그 외 일반적인 데이터를 클라우드. = 데이터 검색, 파일 공유에 최적화</li>
<li>Volume Gateway: Cached(자주 액세스하는 데이터는 로컬, 그 외 일반적인 데이터를 클라우드), Stored(전체 데이터는 로컬, EBS 스냅샷으로 백업을 클라우드) = 파일 공유보다는 데이터 보관 목적</li>
<li>Tape Gateway: 물리적인 Tape처럼 동작.</li>
</ul>
<h3 id="aws-elastic-disaster-recovery">AWS Elastic Disaster Recovery</h3>
<p>물리/가상/클라우드 기반 서버를 AWS에 간단히 복구하도록 하는 완전 관리형 서비스.</p>
<h2 id="스토리지-서비스의-responsibility">스토리지 서비스의 responsibility</h2>
<h3 id="fully-managed">Fully managed</h3>
<p>고객은 데이터, 클라이언트-사이드 데이터 암호화 등만 책임지면 된다.
AWS가 서버-사이드 암호화, 네트워크 트래픽 보안 등 책임을 가진다.</p>
<h3 id="managed">Managed</h3>
<p>고객은 서버-사이드 암호화, 네트워크 트래픽 보안 책임을 추가로 갖는다. 데이터 백업 전략이나 암호화 구성, 성능 최적화 및 가용성 계획 등의 책임을 더 갖는다.
AWS는 스토리지 인프라 아래의 하드웨어, 저장 용량 등 책임을 가진다.</p>
<h3 id="unmanaged">Unmanaged</h3>
<p>고객은 데이터 관리, 백업/복구, 암호화, 성능 개선, 내구성 등의 모든 책임을 갖는다.
AWS는 오직 물리적인 데이터 보관 장치 하드웨어와 해당 하드웨어의 네트워크 인프라에 대한 책임을 갖는다.</p>
<hr>
<h1 id="module-6">Module 6</h1>
<h2 id="aws-shared-responsibility-model">AWS Shared Responsibility Model</h2>
<p>shared responsibility model은 customer와 AWS의 responsibility를 분리한다.</p>
<p>customer는 homeowner로서 &quot;security in the cloud&quot;, AWS는 homebuilder로서 &quot;security of the cloud&quot;의 차이가 있다.</p>
<p><strong>Cusomers</strong></p>
<table>
  <colgroup>
    <col></col>
      <col></col>
      <col></col>
  </colgroup>
  <tbody>
    <tr>
        <td colspan="3">Customer Data</td>
      </tr>
      <tr>
        <td colspan="3">Platform, Applications, Identity and Access Management</td>
      </tr>
      <tr>
        <td colspan="3">OS, Network/Firewall Configuration</td>
      </tr>
      <tr>
        <td>Client-side Data Encryption</td>
        <td>Server-side Encryption</td>
        <td>Networking Traffic Protection</td>
      </tr>
  </tbody>
</table>

<p><strong>AWS</strong></p>
<table>
  <colgroup>
    <col></col>
      <col></col>
      <col></col>
  </colgroup>
  <tbody>
    <tr>
        <td colspan="3">Software</td>
      </tr>
      <tr>
        <td colspan="3">Compute / Storage / Database / Networking</td>
      </tr>
      <tr>
        <td colspan="3">Hardware/AWS Global Infrastructure</td>
      </tr>
      <tr>
        <td>Regions</td>
        <td>Availability Zones</td>
        <td>Edge Locations</td>
      </tr>
  </tbody>
</table>

<h2 id="user-permissions-and-access">User Permissions and Access</h2>
<ul>
<li>AWS account root user = owner: access/control any resources. 강력한 권한을 가진 계정이므로, multi-factor authentication(MFA) 사용하는 등 로그인에 보안성을 높이기를 권장.</li>
</ul>
<h3 id="aws-iam--identity-and-access-management">AWS IAM = Identity and Access Management</h3>
<p>AWS 서비스와 리소스를 보안성 있게 관리할 수 있게 한다.</p>
<p>json 문서에 permission을 명시. Effect를 Allow/Deny 둘 중 한 값으로 허용과 금지를 선언할 수 있다. Action 항목에는 AWS API 호출을 특정할 수 있다. Resource 항목으로는 AWS API가 속한 특정 AWS Resource로 제한한다.</p>
<p>IAM group 기능이 있어, 그룹에 보안 정책을 수립하고 유저들을 특정 그룹에 속하게 한다. 관리가 훨씬 편하다.</p>
<ul>
<li>User<ul>
<li>Root user</li>
</ul>
</li>
<li>Group</li>
<li>Policy</li>
<li>Role = One other major identity in IAM<ul>
<li>Associated permission</li>
<li>allow or deny</li>
<li>assumed for temporary amounts of time</li>
<li>no username or password</li>
</ul>
</li>
</ul>
<p><strong>Best practice</strong>:</p>
<ul>
<li><em>IAM root user</em>: Do not use the root user for everydaty tasks.</li>
<li><em>IAM user</em>: Create individual IAM users for each person.</li>
<li><em>IAM policy</em>: Follow the security principle of least privilege when granting permissions.</li>
<li><em>IAM role</em>: 서비스나 자원에 임시적으로 접근해야 할 경우 사용하는 것이 적절하다.</li>
</ul>
<h2 id="aws-organization">AWS Organization</h2>
<p>회사 단위라면 여러개의 AWS 계정을 사용하게 된다. 그럴 경우 AWS Organization을 사용하여 여러 AWS 계정을 통합하여 관리할 수 있다.</p>
<ul>
<li>Centralized management</li>
<li>Consolidated billing</li>
<li>Hierarchical groupings of accounts (Organization Unit)</li>
<li>AWS service and API action aceess conrol</li>
</ul>
<p>SCPs(Service Control Policies)를 사용하여 기관 내 각 계정 별 권한을 중앙에서 제한하고 조절할 수 있다. AWS 서비스, 자원, API 등 user/role 별로 주어졌던 제한 사항을 설정할 수 있다...</p>
<blockquote>
<p>SPC가 적용될 수 있는 대상: (Individual) account 또는 OU</p>
</blockquote>
<h3 id="ou--organization-unit">OU = Organization Unit</h3>
<p>사업적 연관성이나 보안 요구사항 등, 필요에 따라 OU를 조직하여 계정들을 그룹화하여 더 쉽게 관리할 수 있다.</p>
<h2 id="compliance">Compliance</h2>
<h3 id="aws-artifact">AWS Artifact</h3>
<p>회사가 속한 산업군에 따라, 특정 표준을 따라야 할 수 있다. 감사, 검사를 통해서 표준에 부합한지 확인하게 된다.</p>
<p>AWS Artifact는 계약에 따라 AWS 보안 및 규정 준수 보고서를 제공하는 서비스이다. 두 가지의 주요 섹션, 계약과 레포트로 나뉜다.</p>
<p>-<strong>AWS Artifact Agreement</strong>
-<strong>AWS Artifact Reports</strong>: 지역/산업 별 보안 표준 및 규정을 준수하고 있는지 확인할 수 있는 레포트가 제공.</p>
<h3 id="customer-compliance-center">Customer Compliance Center</h3>
<p>AWS Cloud 서비스를 사용히면서 규정 준수 여부를 입증할 수 있도록 감사자를 위한 방법을 안내하고 있다.</p>
<ul>
<li>주요 규정 준수 여부에 대한 AWS 답변</li>
<li>위험 및 규정 준수 여부에 대한 개괄적 리뷰</li>
<li>보안 체크리스트 감사 결과</li>
</ul>
<h2 id="dos-attacks">Dos Attacks</h2>
<h3 id="ddos-attacks">DDos Attacks</h3>
<blockquote>
<p>DDoS = Distriibuted denial-of-service</p>
</blockquote>
<p>DDoS 공격은 웹 사이트나 애플리케이션을 사용자가 사용할 수 없는 상태로 만들기 위한 고의적인 시도, 행위를 말한다.</p>
<p>SlOWLORIS Attack -&gt; Elastic Load Balancer (특정 느린 클라이언트의 시간 지연이 생겨도 다른 클라이언트를 다른 자원에 접근할 수 있도록 해주기 때문)</p>
<p>UDP Flood -&gt; Security Group으로 해결 (AWS Network Level에서 동작하기 때문)</p>
<h3 id="aws-shield-with-aws-waf">AWS Shield with AWS WAF</h3>
<hr>
<h1 id="module-5-6-summary-keywords">Module 5-6 Summary: Keywords</h1>
<ul>
<li>Amazon EBS = Elastic Block Store</li>
<li>Amazon S3 = Simple Storage Service<ul>
<li>S3 Standard</li>
<li>S3 Standard-IA</li>
<li>S3 One Zone-IA</li>
<li>S3 Intelligent-Tiering</li>
<li>S3 Glacier Instance Retrieval</li>
<li>S3 Glacier Flexible Retrieval</li>
<li>S3 Glacier Deep Archive</li>
<li>S3 Outposts</li>
</ul>
</li>
<li>Amazon EFS = Elastic File System</li>
<li>Amazon RDS = Relational Database Service</li>
<li>Amazon DynamoDB</li>
<li>Amazon Redshift</li>
<li>AWS DMS = Database Migration Service</li>
<li>Amazon DocumentDB</li>
<li>Amazon Neptune</li>
<li>Amazon Quantum Ledger Database</li>
<li>Amazon Managed Blockchain</li>
<li>Amazon ElastiCache</li>
<li>Amazon DynamoDB Accelerator</li>
<li>AWS IAM</li>
<li></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[2-2. AWS Cloud Practitioner Essentials 공부하기 (Module 3~4)]]></title>
            <link>https://velog.io/@minjeong-dev/AWS-Cloud-Practitioner-Essentials-3-to-4</link>
            <guid>https://velog.io/@minjeong-dev/AWS-Cloud-Practitioner-Essentials-3-to-4</guid>
            <pubDate>Mon, 06 Jan 2025 06:28:20 GMT</pubDate>
            <description><![CDATA[<ul>
<li>Module 3: Global Infrastructure And Reliability</li>
<li>Module 4: Networking</li>
</ul>
<hr>
<h1 id="module-3">Module 3</h1>
<ul>
<li>AWS Gloal Infrastructure</li>
<li>Availability Zones</li>
<li>Amazon CloudFront</li>
<li>Provisioning AWS services</li>
</ul>
<h2 id="aws-global-infrastructure">AWS Global Infrastructure</h2>
<h3 id="region">Region</h3>
<p>서비스, 데이터, 애플리케이션 등을 위한 지역을 결정할 때, 사업적인 요인을 고려해야 한다.</p>
<ul>
<li>location-specific data regulations 정책 상 지역 제한</li>
<li>proximity 거리상 인접하게</li>
<li>availablity</li>
<li>pricing 비용적 측면</li>
</ul>
<h4 id="availability-zone--az">Availability Zone = AZ</h4>
<ul>
<li>단일/복수 개의 데이터 센터를 가진 지역</li>
<li>AZ는 서로 10 마일씩, 지연이 적을 수 있는 만큼씩 떨어져 있다. </li>
<li>regionally scoped service</li>
</ul>
<p>us-west-1이라는 AZ가 있다고 하자. us-west-1a 안에 인스턴스가 있고 서비스를 운영 중인데 문제가 생기게 될 경우, us-west-1b에서 동작하도록 할 수 있게 된다.</p>
<h4 id="edge-locations">Edge Locations</h4>
<p>Amazon CloudFront = cache storage</p>
<h2 id="provisioning-aws-resources">Provisioning AWS Resources</h2>
<p><strong>Ways to interact with AWS services</strong></p>
<ul>
<li>AWS Management Console<ul>
<li>web-based</li>
</ul>
</li>
<li>AWS Command Line Interface (CLI)</li>
<li>AWS Software Development Kits (SDKs)<ul>
<li>C++, JAva, .NET 등의 언어를 지원</li>
</ul>
</li>
</ul>
<p><strong>AWS Outposts</strong>
Extend AWS infrastructure and services to different locations including your on-premises data center.</p>
<p><strong>AWS Elastic Beanstalk</strong>
EC2 인스턴스(+로드 밸런서)로 이루어진 구성 환경을 자동으로 구성, 조정</p>
<p><strong>AWS CloudFormation</strong>
JSON, YAML 형식으로 템플릿 작성하여 전체 인프라를 모델링, 관리.</p>
<hr>
<h1 id="module-4">Module 4</h1>
<h2 id="networking">Networking</h2>
<h3 id="vpc--virtual-private-cloud">VPC = Virtual Private Cloud</h3>
<p>AWS 리소스의 바운더리를 조직하는 네트워킹 서비스를 말한다.</p>
<blockquote>
<p>Subnet = EC2 인스턴스 같은 리소스를 포함한, VPC의 일부가 될 수 있는 부분. 보안 또는 운영적 필요에 의해 그룹으로 만들게 된다.</p>
</blockquote>
<ul>
<li>Public subnet = 웹 사이트 등 접근 자체가 public 해야 하는 자원들로 이루어져 있다.</li>
<li>Private subnet = 로그, 유저 정보 등을 다루는 데이터베이스와 같이 private한 네트워크에서만 접근해야 하는 자원들로 이루어져 있다.</li>
</ul>
<p>1) 일반적인 VPC
Client의 Public traffic ---&gt; <strong>Internet Gateway</strong> ---&gt; VPC 방향으로 접근하게 한다. 인터넷 게이트웨이는 AWS Cloud에 속해, VPC에 접근하기 위한 유일한 방법으로써 제공된다.</p>
<p>2) private한 자원만 가진 VPC일 경우
Public/Private traffic ---(VPN Connection)---&gt; <strong>Virtual Private Gateway</strong> ---&gt; VPC</p>
<h3 id="aws-direct-connect">AWS Direct Connect</h3>
<blockquote>
<p>Which component can be used to establish a private dedicated connection between your company’s data center and AWS?</p>
</blockquote>
<p>Data center와 VPC 사이의 네트워크 연결이 private하게 이뤄지도록 설정하는 서비스. (카페 예시에 따르면 특정 복도를 거쳐야만 카페에 입장할 수 있다고 보면 된다.)</p>
<h3 id="network-hardening">Network hardening</h3>
<p>Internet Gateway --- Network access control list (ACL) ---&gt; Subnet</p>
<blockquote>
<p>Network ACL = 서브넷 레벨에서의 in/outbound 트래픽을 컨트롤하는 가상의 방화벽.</p>
</blockquote>
<p>AWS 계정은 기본적으로 설정된 Network ACL을 가진다. VPC를 구성할 때 기본 값을 사용하면 되고, 커스텀도 가능하다.</p>
<p>기본적으로는 모든 in/outbound 트래픽을 모두 허용한다. 조건을 커스텀하여 제한을 두면, 허용되지 못한 패킷은 무시된다.</p>
<blockquote>
<p>Security Group = Amazon EC2 인스턴스 레벨에서의 in/outbound 트래픽을 컨트롤하는 가상의 방화벽.</p>
</blockquote>
<p>Security Group은 기본적으로는 모든 inbound 트래픽을 허용하지 않고 있고, 커스텀하여 사용한다.</p>
<h4 id="security-group-network-acl">Security Group, Network ACL</h4>
<p>Network ACL에 허용된 출처로부터 온 패킷만 전달되는 등의 보안 규칙 설정이 가능하다. Network ACL은 서브넷 바운더리에서의 패킷 in/out을 컨트롤한다. 따라서 서브넷 내의 EC2 인스턴스 레벨에서의 보안성을 보장하진 못한다.</p>
<p>EC2가 받는 트래픽(패킷)을 컨트롤하기 위해서는 Security Group을 규정함으로써 특정 프로토콜, 출처 등 트래픽을 제한하여 받을 수 있다.</p>
<p>Security Group (Stateful) &lt;-&gt; Network ACL (Stateless) 라는 차이가 있다.</p>
<ul>
<li>Security Group: <em><strong>Stateful</strong></em> 패킷 필터링. 이전의 필터링 결정을 기억한다. 요청할 때 확인했던 패킷에 대한 응답이 인스턴스에 도착할 경우, 이전 요청(에 대한 확인)을 기억하고 있으므로 다시 새로운 확인 없이 허용한다.</li>
<li>Network ACL: <em><strong>Stateless</strong></em> 패킷 필터링. 서브넷 간 in/outbound 되는 모든 패킷에 대해 항상 필터링을 거친다. 동일한 요청자나 데이터의 패킷 여부는 알 수 없다. 요청 패킷에 대한 응답 패킷이어도 상관 없이 정해진 규칙을 기준으로 확인한다.</li>
</ul>
<h3 id="amazon-route-53">Amazon Route 53</h3>
<p>AWS의 DNS (도메인 네임 시스템) 웹 서비스.</p>
<blockquote>
<p>DNS = Domain Name System. 웹 사이트 주소를 IP 주소로 변환해주는 역할을 한다.</p>
</blockquote>
<hr>
<h1 id="module-3-4-summary-keywords">Module 3-4 Summary: Keywords</h1>
<ul>
<li>AWS Region</li>
<li>AZ = Availiability Zone</li>
<li>Edge Location</li>
<li>Amazon CloudFront</li>
<li>AWS Outpost</li>
<li>AWS Elastic Beanstalk</li>
<li>AWS CloudFormation</li>
<li>VPC</li>
<li>Subnet</li>
<li>Internet Gateway</li>
<li>Virtual Private Gateway</li>
<li>AWS Direct Connect</li>
<li>Network ACL = Access Control List</li>
<li>Security Group</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[2-1. AWS Cloud Practitioner Essentials 공부하기 (Module 1~2)]]></title>
            <link>https://velog.io/@minjeong-dev/AWS-Cloud-Practitioner-Essentials-1-to-2</link>
            <guid>https://velog.io/@minjeong-dev/AWS-Cloud-Practitioner-Essentials-1-to-2</guid>
            <pubDate>Mon, 16 Dec 2024 01:53:39 GMT</pubDate>
            <description><![CDATA[<p>24년 12월 10일부터 공부 시작하며 정리해보는 글.</p>
<p><a href="https://explore.skillbuilder.aws/learn/course/internal/view/elearning/134/aws-cloud-practitioner-essentials">AWS Cloud Practitioner Essentials</a>은 무료로 볼 수 있는 7시간 분량의 기본 강의이다.</p>
<p>25년도에 수정되어 12시간 분량으로 늘어났고, 약간의 수정이 있다.</p>
<hr>
<h1 id="module-1">Module 1</h1>
<h2 id="client-server-model">Client-Server Model</h2>
<ul>
<li>client는 웹 브라우저, 데스크탑 애플리케이션 등이 될 수 있고, 사용자와 상호 작용을 하며 server로 요청을 보낸다.</li>
<li>server는 요청한 리소스를 응답으로 제공하게 되고, AWS에서는 virtual server인 Amazon Elastic Compute Cloud (Amazon EC2)가 해당 역할을 수행할 수 있다.</li>
</ul>
<h2 id="cloud-computing">Cloud Computing</h2>
<ul>
<li><p><strong>Cloud Computing Deployment Model</strong></p>
<ul>
<li><strong>Cloud-Based Deployment</strong><ul>
<li>app의 모든 파트가 cloud에서 동작</li>
<li>app을 cloud로 마이그레이션</li>
<li>새로운 app의 설계 및 구축을 cloud 환경에서    </li>
</ul>
</li>
<li><strong>On-Premises Deployment</strong><ul>
<li>(a.k.a.) <em>private cloud delpoyment</em></li>
<li>레거시 IT Infra가 전부 On-Premises로 이루어진 편이다.</li>
</ul>
</li>
<li>Hybrid Deployment<ul>
<li>On-Premises 인프라를 Cloud-Based로 연결하게 구성</li>
<li>레거시 IT app들을 Cloud-Based 리소스와 상호작용 시키기 등</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Benefits</strong></p>
<ul>
<li>(fixed) upfront expense → variable expense</li>
<li>data center 구축, 운영 비용의 절감</li>
<li>infra의 capacity를 사전 계산 및 제한하며 운영할 필요가 없음</li>
<li>scale이 커질 수록 경제적 이득을 볼 수 있음</li>
<li>시스템/서비스의 flexibility(유연성) 커지고 agility(속도)도 좋아짐</li>
<li>글로벌 서비스에 최적화한 환경을 가질 수 있음 (low latency)</li>
</ul>
</li>
</ul>
<h2 id="aws-shared-responsibility">AWS Shared Responsibility</h2>
<p> AWS 클라우드 환경의 서비스는 Customer와 AWS가 함께 보안 책임을 가진다.</p>
<ol>
<li><p>Customer 책임 = Security <strong>in</strong> the cloud: 고객 데이터, Client-side data encryption, OS의 구성 및 운영 등.</p>
</li>
<li><p>Customer 또는 AWS 책임: 서비스에 따라 다르다. Server-side encryption, Network traffic protection, OS/Network/Firewall configurations, ...</p>
</li>
<li><p>AWS 책임 = Security <strong>of</strong> the cloud: Hardware/Software, Global infrastructure, ...</p>
<p>basic 레벨, cloud 환경의 책임은 AWS.
데이터 액세스, 관리 등의 서비스 운용 책임은 Customer.</p>
</li>
</ol>
<hr>
<h1 id="module-2">Module 2</h1>
<blockquote>
<p><strong>Amazon EC2</strong>
the servers you use to gain access to virtual servers</p>
</blockquote>
<ul>
<li>특징<ol>
<li>highly-flexible</li>
<li>cost-effective</li>
<li>quick</li>
</ol>
</li>
</ul>
<hr>
<h2 id="amazon-ec2-instance-types">Amazon EC2 Instance Types</h2>
<h3 id="general-purpose">General Purpose</h3>
<ul>
<li>균형 있는 컴퓨팅, 메모리, 네트워크 리소스 등...</li>
<li>application/gaming/backend server, small ~ medium database server...</li>
</ul>
<h3 id="compute-optimized">Compute Optimized</h3>
<ul>
<li>high-performance processor</li>
<li>workloads that require processing many transactions</li>
</ul>
<h3 id="memory-optimized">Memory Optimized</h3>
<ul>
<li>high-performance database</li>
<li>workloads that process large datasets in memory</li>
</ul>
<h3 id="accelerated-computing">Accelerated Computing</h3>
<ul>
<li>graphic processing, data pattern matching, streaming...</li>
<li>acceleraters or coprocessors, CPU 가속화</li>
</ul>
<h3 id="stroage-optimized">Stroage Optimized</h3>
<ul>
<li>file system, data warehousing, OLTP system...</li>
</ul>
<hr>
<h2 id="amazon-ec2-pricing-options">Amazon EC2 Pricing Options</h2>
<h3 id="on-demand-instances">On-Demand Instances</h3>
<ul>
<li>for short-term, irregular workloads</li>
<li>no upfront costs or minimum contract</li>
</ul>
<h3 id="reserved-instances">Reserved Instances</h3>
<ul>
<li>Standard Reserved Instances<ul>
<li>구체적으로 결정해야 하는 spec<ul>
<li>Instance (family) type and size</li>
<li>Platform description (operating system)</li>
<li>Tenancy (default or dedicated)</li>
<li>Region</li>
</ul>
</li>
</ul>
</li>
<li>Convertible Reserved Instances</li>
<li>contract 1 year or 3 years</li>
</ul>
<h3 id="ec2-instance-savings-plan">EC2 Instance Savings Plan</h3>
<p>reduce EC2 instance costs when you make an hourly spend commitment to an instance family and Region for 1 or 3 year term.
Instance 타입과 지역에 대한 1/3년 시간당 지출 약정할 때 할인 제공해주는 옵션.</p>
<h3 id="spot-instances">Spot Instances</h3>
<ul>
<li>Amazon EC2 computing capacity가 있을 때 요청 및 작업이 이루어지는 Instance.</li>
<li>시작 및 종료 시점이 유연하거나 중단 및 지연이 발생해도 괜찮은 경우 적합.</li>
</ul>
<h3 id="dedicated-hosts">Dedicated Hosts</h3>
<ul>
<li>virtual private cloud (VPC)에서 동작되는 인스턴스로, 한 고객에게만 제한되어 제공된다.</li>
<li>실제 하드웨어를 공유하여 쓰는 다른 옵션들과 달리, 가장 비싼 옵션...</li>
</ul>
<hr>
<h2 id="amazon-ec2-auto-scaling">Amazon EC2 Auto Scaling</h2>
<p>AWS 서비스는 Amazon EC2 인스턴스가 자동적으로 요청에 따라 scale in/out하도록 하고 그에 대한 사용량만 부과하도록 제공하고 있다.</p>
<p>Availablity는 유지하되 Unused capacity가 생기지 않게 하고 Demand에 맞게 인스턴스 수를 조절하며 리소스를 낭비하지 않고, 비용도 절감할 수 있게 된다.</p>
<p>Auto Scaling에는 두 가지의 접근 방식이 있고, 두 방법을 모두 사용할 수도 있다고 한다.</p>
<ul>
<li><p>Dynamic scailing - 실시간 사용량에 따른 스케일링</p>
</li>
<li><p>Predictive scailing - 예측된 스케쥴에 따라 스케일링</p>
</li>
<li><p><strong>Configuring Auto Scaling</strong></p>
<ol>
<li><strong><em>Auto Scaling Group</em></strong>을 만든다.</li>
<li><strong><em>Minimum Capacity</em></strong> 값을 설정한다. 필요로 하는 최소한의 인스턴스 개수, 최소 1개가 될 것이다.</li>
<li><strong><em>Desired Capacity</em></strong> 값을 설정한다. default 값으로는 minimum capacity로 설정한 값을 갖게 된다. 주로 애플리케이션이 필요로 하는 최소의 인스턴스 갯수가 된다.</li>
<li><strong><em>Maximum Capacity</em></strong> 값을 설정한다. 요청량의 증대로 scale out하게 될 때, 최대 몇 개까지 사용될 수 있도록 할 것인지 제한하는 값이다.</li>
</ol>
</li>
</ul>
<hr>
<h2 id="amazon-elb">Amazon ELB</h2>
<p><em>*<em>Amazon ELB = Elastic Load Balancing
*</em></em></p>
<p>애플리케이션의 요청을 다중 리소스(Amazon EC2 인스턴스)에 자동으로 분배하여 전달하는 것을 말한다.</p>
<p><strong><em>Load Balancer</em></strong>가 Auto Scaling Group에게 들어오는 웹 트래픽을 single point로써 받는다. 요청을 분배하여 핸들링하는 역할을 수행한다.</p>
<p>Auto Scaling과 Elastic Load Balancing은 분리된 다른 서비스이지만 같이 동작시켰을 때 성능이나 가용성을 굉장히 높일 수 있다.</p>
<p>Elastic Load Balancing은 어떤 과정으로 이루어질까?</p>
<ul>
<li>Low-demand period: 들어오는 요청들을 Auto Scaling Group 내 인스턴스에 분배한다.</li>
<li>High-deman period: 그러다가 client 수 및 리소스 요청의 수가 늘어날 경우 Auto Scaling Group의 인스턴스도 증가할 수 있다. Load Balancer가 새로 연결된 인스턴스에게도 요청을 분배하는 것이다. End-to-End에선 Load Balancer를 통해 요청과 응답을 주고 받기 때문에 그대로다.</li>
</ul>
<hr>
<h2 id="messaging-and-queuing">Messaging and Queuing</h2>
<ul>
<li>Monolithic application. tightly coupled component architecture. DB, 서버, 유저 인터페이스 등 구성 요소가 강하게 결합되어 있다. 특정 컴포넌트의 오류로 전체 시스템의 동작 및 운영에 오류가 생길 수 있다.</li>
<li>Microservices. loosely coupled component architecture. 시스템이 일부 애플리케이션, 인스턴스의 오류가 생겨도 정상적으로 운영될 수 있다.</li>
</ul>
<h3 id="amazon-sqs">Amazon SQS</h3>
<ul>
<li>SQS = Simple Queue Service</li>
<li>send/store/receive messages by buffer.</li>
</ul>
<h3 id="amazon-sns">Amazon SNS</h3>
<ul>
<li>SNS = Simple Notification Service</li>
<li>publish-subscribe model.</li>
<li>Amazon SNS topic을 사용해 메시지를 퍼블리싱, 구독한다.</li>
<li>구독자의 역할은 web server, AWS Lambda function 등이 될 수 있다.</li>
</ul>
<hr>
<h2 id="serverless-computing">Serverless computing</h2>
<p>EC2는 가상의 서버를 cloud에서 구동시켜 사용하는 서비스. 만약 EC2를 이용해 애플리케이션을 운영한다면,</p>
<ul>
<li>EC2 인스턴스를 세팅한다.</li>
<li>애플리케이션 코드를 업로드한다.</li>
<li>애플리케이션을 동작시킨 후 관리한다.</li>
</ul>
<p>여기서 <strong><em>serverless</em></strong>란 코드를 서버에 올려 동작을 시키되, 직접 가상 서버에 대한 프로비저닝 등의 작업을 하지 않아도 되는 것을 말한다.</p>
<p>서버에 대한 유지, 관리 뿐 아니라 capacity에 따른 유동적인 조치도 알아서 한다.</p>
<p>serveless computing으로써 제공되는 AWS Service가 <strong><em>AWS Lambda</em></strong>이다.</p>
<h3 id="aws-lambda">AWS Lambda</h3>
<ul>
<li>without needing to provision or manage servers.</li>
<li>비용은 실제 코드가 동작한 compute time에 대해서만 부과된다.</li>
<li>15분 이하가 소요되는 짧은 프로세싱에 적합하다.</li>
<li><em>How AWS Lambda works</em><ol>
<li>Upload code to Lambda.</li>
<li>Set code to trigger from an event source, such as AWS service, mobile applications, or HTTP endpoints.</li>
<li>Code runs only when triggered.</li>
<li>Pay only for the compute time you use.</li>
</ol>
</li>
</ul>
<h2 id="containerized-application">Containerized application</h2>
<blockquote>
<p><strong><em>Container</em></strong>: A package for your code.
특정 애플리케이션 코드, dependencies 등을 하나의 분리된 object로 패키징한 개념이다. 하나의 host(server)에 애플리케이션들이 독립되고 구분된 환경으로 동작하게 된다.</p>
</blockquote>
<h3 id="amazon-ecs--elastic-container-service">Amazon ECS = Elastic Container Service</h3>
<ul>
<li>a highly scalable, high-performance container management system.</li>
<li>surpports <strong><em>Docker</em></strong> containers.</li>
</ul>
<blockquote>
<p><strong>Docker</strong>
애플리케이션의 build, 테스트, 배포하는 소프트웨어 플랫폼.</p>
</blockquote>
<h3 id="amazon-eks--elastic-kubernetes-service">Amazon EKS = Elastic Kubernetes Service</h3>
<ul>
<li>AWS 상에서 쿠버네티스를 사용할 수 있게 전체적으로 관리 가능한 서비스.</li>
</ul>
<blockquote>
<p><strong>Kubernetes</strong>
containerized application deployment/management software. </p>
</blockquote>
<h3 id="aws-fargate">AWS Fargate</h3>
<ul>
<li>serverless compute engine for containers.</li>
<li>Amazon ECS/EKS와 함께 동작된다.</li>
<li>AWS Fargate를 쓰면 서버의 프로비저닝, 관리를 하지 않아도 된다. 서버 인프라를 관리해준다.</li>
</ul>
<hr>
<h2 id="module-2-summary-keywords">Module 2 Summary: Keywords</h2>
<ul>
<li>Cloud Computing</li>
<li>Amazon EC2</li>
<li>Amazon EC2 Instance Family<ul>
<li>General purpose</li>
<li>Compute optimized</li>
<li>Memory optimized</li>
<li>Accelerated computing</li>
<li>Storage optimized</li>
</ul>
</li>
<li>Amazion EC2 Auto Scaling</li>
<li>ELB = Elastic Load Balancing</li>
<li>Amazon EC2 Billing Options<ul>
<li>On-Demand</li>
<li>Spot instance</li>
<li>Reserved instances</li>
<li>saving plans</li>
</ul>
</li>
<li>Amazon SQS = Simple Queue Sercice</li>
<li>Amazon SNS = Simple Notification Service</li>
<li>Amazon ECS = Elastic Container Service</li>
<li>Amazon EKS = Elastic Kubernetis Service</li>
<li>AWS Fargate</li>
<li>AWS Lambda</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[1. AWS Cloud Practitioner]]></title>
            <link>https://velog.io/@minjeong-dev/aws-cloud-practitioner-introduction</link>
            <guid>https://velog.io/@minjeong-dev/aws-cloud-practitioner-introduction</guid>
            <pubDate>Tue, 10 Dec 2024 02:10:35 GMT</pubDate>
            <description><![CDATA[<p>미리 밝히는 출처: <a href="https://aws.amazon.com/certification/certified-cloud-practitioner/">AWS Certified Cloud Practitioner</a> 홈페이지를 참고하여 정리하였다.</p>
<hr>
<p><img src="https://velog.velcdn.com/images/minjeong-dev/post/b781cf5c-e214-41b6-b0b8-f96a800822ec/image.png" alt="AWS Cloud Practitioner"></p>
<h2 id="시험-개요">시험 개요</h2>
<ul>
<li>시험 시간: 90분 (한글로 응시할 경우 30분 추가 부여)</li>
<li>시험 형식: 65개 문항 (15개는 점수 반영 안 됨)</li>
<li>비용: 100 USD</li>
<li>시험 장소: Pearson VUE 테스트 센터 또는 온라인 감독 시험.</li>
</ul>
<h3 id="시험-내용">시험 내용</h3>
<ol>
<li>클라우드 개념 (24%)
1.1 AWS 클라우드의 이점<ul>
<li>글로벌 인프라의 이점</li>
<li>고가용성, 탄력성, 민첩성
1.2 AWS 클라우드의 설계 원칙 = AWS Well-Architected Framework</li>
<li>운영 우수성</li>
<li>보안</li>
<li>신뢰성</li>
<li>성능 효율성</li>
<li>비용 최적화</li>
<li>지속 가능성
1.3 AWS 클라우드 마이그레이션</li>
<li>AWS Cloud Adoption Framework (AWS CAF)</li>
<li>적절한 마이그레이션 전략 (데이터베이스 복제, AWS Snowball)
1.4 클라우드 인프라의 경제성</li>
<li>고정 비용과의 비교 = 가변 비용</li>
<li>On-premise 환경과의 비교</li>
<li>규모 조정</li>
<li>규모의 경제 (비용 절감)</li>
</ul>
</li>
<li>보안 및 규정 준수 (30%)
2.1 AWS 공동 책임 모델 AWS Shared Responsibility<ul>
<li>구성 요소 파악</li>
<li>Customer 책임, 공유 책임, AWS 책임
2.2 보안, 거버넌스 및 규정 준수</li>
<li>AWS 규정 준수 = AWS Artifact</li>
<li>지리적/산업별 규정 준수 요구 사항</li>
<li>고객이 AWS에서 리소스 보호하는 방법<ul>
<li>Amazon Inspector</li>
<li>AWS Security Hub</li>
<li>Amazon GuardDuty</li>
<li>AWS Shield</li>
</ul>
</li>
<li>거버넌스 및 규정 준수 지원 서비스<ul>
<li>Amazon CloudWatch (모니터링)</li>
<li>AWS CloudTrail</li>
<li>AWS Audit Manager, AWS Config 등을 통한 감사, 보고</li>
</ul>
2.3 AWS 액세스 관리 기능</li>
<li>AWS IAM = AWS Identity and Access Management: 자격 증명 및 액세스 관리</li>
<li>AWS IAM Identity Center (AWS Single Sign-On)</li>
<li>AWS 인증 방법</li>
<li>AWS Secrets Manager, AWS Systems Manager = 액세스 키, 암호 정책 및 자격 증명 스토리지</li>
<li>최소 권한의 원칙: 그룹, 사용자 지정 정책 및 관리형 정책
2.4 보안용 구성 요소, 리소스</li>
<li>AWS 보안 기능 및 서비스<ul>
<li>AWS WAF</li>
<li>AWS Firewall Manager</li>
<li>AWS Shield</li>
<li>Amazon GuardDuty</li>
<li>AWS Marketplace에서 서드 파티 보안 제품 사용 가능</li>
<li>AWS 보안 정보 사용할 수 있는 위치 파악: AWS Knowledge Center, AWS Security Center, AWS Security Blog</li>
<li>보안 문제 식별을 위한 AWS 서비스: AWS Trusted Advisor</li>
</ul>
</li>
</ul>
</li>
<li>클라우드 기술 및 서비스 (34%)
3.1 AWS 클라우드 배포 및 운영 방법 정의<ul>
<li>프로그래밍 방식 액세스(API, SDK, CLI), AWS Management Console및 코드형 IaC</li>
<li>배포 모델: Cloud / On-premise / Hybrid
3.2 AWS 글로벌 인프라</li>
<li>AWS Region, Availability Zone, Edge Location</li>
<li>다중 AZ를 통한 고가용성</li>
<li>AZ가 단일 장애 지점을 공유하지 않는다</li>
<li>다중 AZ의 이점: 재해 복구, 비지니스 연속성, 짧은 지연 시간, 데이터 주권 등
3.3 AWS 컴퓨팅 서비스</li>
<li>EC2 인스턴스 유형</li>
<li>컨테이너 옵션: Amazon ECS, Amazion EKS</li>
<li>서버리스 컴퓨팅: AWS Fargate, Lambda</li>
<li>Auto-Scailing과 탄력성</li>
<li>로드 밸런서
3.4 AWS 데이터베이스 서비스</li>
<li>EC2 호스팅 데이터베이스 vs. AWS 관리형 데이터베이스</li>
<li>관계형 데이터베이스: Amazon RDS, Amazon Aurora</li>
<li>NoSQL 데이터베이스: DynamoDB</li>
<li>메모리 기반 데이터베이스: Amazon ElastiCache</li>
<li>데이터베이스 마이그레이션 도구: AWS Datavase Migration Service(AWS DMS), AWS Schema Conversion Tool(AWS SCT)
3.5 AWS 네트워크 서비스</li>
<li>VPC 구성 요소: 서브넷, 게이트웨이...</li>
<li>VPC 보안: 네트워크 ACL, 보안 그룹, Amazon Inspector</li>
<li>Amazon Route 53</li>
<li>AWS에 대한 네트워크 연결 옵션: AWS VPN, AWS Direct Connect
3.6 AWS 스토리지 서비스</li>
<li>Amazon S3 스토리지 등급</li>
<li>블록 스토리지 솔루션: Amazon Elastic Block Store (EBS), 인스턴스 스토어</li>
<li>파일 서비스: Amazon Elastic File System (EFS), Amazon FSx</li>
<li>캐시된 파일 시스템: AWS Storage Gateway</li>
<li>수명 주기 정책</li>
<li>AWS Backup
3.7 AWS 인공 지능 및 기계 학습(AI/ML) 서비스, 분석 서비스</li>
<li>AI/ML 서비스<ul>
<li>Amazon SageMaker</li>
<li>Amazon Lex</li>
<li>Amazon Kendra</li>
</ul>
</li>
<li>데이터 분석용 서비스<ul>
<li>Amazon Athena</li>
<li>Amazon Kinesis</li>
<li>AWS Glue</li>
<li>Amazon QuickSight</li>
</ul>
3.8 그 외 AWS 서비스</li>
<li>애플리케이션 통합 서비스 (메시지 전달, 경고 및 알림)<ul>
<li>Amazon EventBridge</li>
<li>Amazon Simple Notification Service (SNS)</li>
<li>Amazon Simple Queue Service (SQS)</li>
</ul>
</li>
<li>비즈니스 애플리케이션 서비스<ul>
<li>Amazon Connect</li>
<li>Amazon Simple Email Service (SES)</li>
</ul>
</li>
<li>고객 지원 서비스: AWS Support</li>
<li>개발자 도구 서비스 (애플리케이션 개발, 배포 및 문제 해결)<ul>
<li>AWS CodeBuild</li>
<li>AWS CodePipeline</li>
<li>AWS X-Ray</li>
</ul>
</li>
<li>최종 사용자 컴퓨팅 서비스 (최종 사용자 컴퓨터에 가상머신(VM)의 출력 표시)<ul>
<li>Amazon AppStream 2.0</li>
<li>Amazon WorkSpaces</li>
<li>Amazon WorkSpaces Secure Browser</li>
</ul>
</li>
<li>프론트엔드 웹 및 모바일 서비스 (배포)<ul>
<li>AWS Amplify</li>
<li>AWS AppSync</li>
</ul>
</li>
<li>IoT 서비스: AWS IoT Core (IoT 디바이스 관리)</li>
</ul>
</li>
<li>결제, 요금 및 지원 (12%)
4.1 AWS 요금 모델 비교<ul>
<li>컴퓨팅 구매 옵션<ul>
<li>On-demand</li>
<li>예약 인스턴스</li>
<li>스팟 인스턴스</li>
<li>절감형 플랜</li>
<li>전용 호스트</li>
<li>전용 인스턴스</li>
<li>용량 예약</li>
</ul>
</li>
<li>예약 인스턴스의 유연성</li>
<li>AWS Organizations의 예약 인스턴스 동작</li>
<li>수신/발신 데이터 전송 비용(동일 리전, 다른 리전)</li>
<li>다양한 스토리지 옵션 및 티어 적용 요금 옵션
4.2 결제, 예산 및 비용 관리용 리소스</li>
<li>AWS Budgets, AWS Cost Explorer</li>
<li>AWS 요금 계산기</li>
<li>AWS Organiztions 통합 결제 및 비용 할당</li>
<li>AWS Cost and Usage Report: 다양한 유형의 비용 할당 태그 및 결제 보고서
4.3 AWS 기술 리소스 및 고객 지원</li>
<li>AWS 기술 리소스: AWS 권장 가이드, AWS Knowledge Center, AWS re:POST</li>
<li>AWS Support 플랜</li>
<li>Independent Software Vendor (ISV) 및 시스템 통합 사업자를 포함한 AWS 파트너 네트워크의 역할</li>
<li>AWS Support Center</li>
</ul>
</li>
</ol>
<h2 id="시험-준비">시험 준비</h2>
<h3 id="시험-유형-및-사전-지침">시험 유형 및 사전 지침</h3>
<ul>
<li>AWS Cloud Practitioner (CLF-C02) 시험 안내서 검토</li>
<li>AWS 공식 연습 문제 세트 풀어보기</li>
<li>시험 준비 공식 사전 테스트 해보기</li>
<li>AWS Skill Builder 시험 준비에서 추가적인 지침 참고하기</li>
</ul>
<h3 id="aws-지식-및-기술-업데이트">AWS 지식 및 기술 업데이트</h3>
<ul>
<li>AWS Cloud Practitioner Essentials (무료, 7시간)</li>
<li>AWS Cloud Quest: Cloud Practitioner (무료, 12시간)</li>
</ul>
<h3 id="시험-리뷰-및-연습">시험 리뷰 및 연습</h3>
<ul>
<li>시험 준비 표준 과정 (무료, 4시간 반)</li>
<li>시험 준비 고급 과정 (유료 구독 필요, 11시간)</li>
<li>AWS Escapte Room: Exam Prep (유료 구독 필요, 2-4시간)</li>
</ul>
<h3 id="시험-준비-상태-평가">시험 준비 상태 평가</h3>
<ul>
<li>공식 모의 시험 (유료 구독 필요, 1시간 반)</li>
</ul>
<hr>
<h3 id="aws-skill-builder-구독">AWS Skill Builder 구독</h3>
<ul>
<li>공식 홈페이지: <a href="https://skillbuilder.aws/subscriptions">AWS Skill Builder Subscriptions</a></li>
<li>가격: $29/month, $449/year</li>
</ul>
<p>이해하기로는 월간 결제 12개월보다 연간 결제 1년이 싸야할 것 같은데, 훨씬 비싸다. 왜 이런가 궁금해서 알아보니 AWS Digital Classroom이라는 서비스를 연간 결제 회원만 이용할 수 있다고 한다... 뭔가 온라인으로 실제 강사에게 강의를 듣거나 질의응답을 할 수 있는 기능일까? 아직 잘 모르겠다.</p>
<hr>
<p>일단 Essentials 강의를 듣고 나서 공식 연습 문제를 풀어볼 예정이다.</p>
<p>풀어봤는데 잘 모르겠다고 하면, AWS Skill Builder 구독을 해서 유료 강의를 듣거나 서치를 해보고 다른 사람들이 듣는 유료 강의를 들을 수도 있겠다...</p>
<p>다음 글에서는 Essentials 강의를 듣고 나서 연습 문제를 풀어보고 그 결과를 확인해보는 글이 되었으면 좋겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[0. AWS Certification에 대해 알아보기]]></title>
            <link>https://velog.io/@minjeong-dev/aws-certification-introduction</link>
            <guid>https://velog.io/@minjeong-dev/aws-certification-introduction</guid>
            <pubDate>Tue, 10 Dec 2024 01:26:55 GMT</pubDate>
            <description><![CDATA[<p>25년부터는 AWS 공부를 시작해야겠다는 결심이 생겼다.</p>
<p>회사에서 팀장님이 공부해서 프론트 서버 운용 자체를 능숙하게 다룰 수 있기를 바란다고 해주시기도 했고, 안 그래도 너무 무지한 것 같아 늘 걱정인 부분이었어서 &quot;그래! 미루지 말고 시작하자. (늦었다고 생각할 때가 진짜 늦었다... 발등에 불을 얹어졌으니 해보자.)&quot; 결심하게 되었다.</p>
<p>그렇다고 공부를 해서 AWS 자격증을 꼭 응시해야 할까? 이렇게 생각해보면 필요하다고 말하기는 어렵다. 당연히 개발자에겐 실무 능력 및 경험이 중요하다.</p>
<p>하지만 자격증이 있어서 좋으면 좋았지, 나쁠 것이 없을 것이다. 그리고 나같은 경우 정말 DevOps나 인프라에 대한 실무 경험이 부족하기 때문에, 공부를 위한 로드맵으로써 자격 커리큘럼을 따라 공부하기로 했다. 그리고 그걸 잘 공부했나 확인해보는 (유료) 수단으로도 자격 시험 응시가 좋을 것 같다고 생각이 든다!</p>
<hr>
<h2 id="aws-certification">AWS Certification</h2>
<p>공식 홈페이지는 다음과 같다.
<a href="https://aws.amazon.com/ko/certification/">https://aws.amazon.com/ko/certification/</a></p>
<p><img src="https://velog.velcdn.com/images/minjeong-dev/post/6dbabb2e-cc88-4d21-9f80-66ed4b3fdd66/image.png" alt="AWS Certification 메인 페이지"></p>
<p>시작하기 &gt; AWS Certification 경로 선택을 누르면 PDF로 각 직무 별 어떤 자격증을 따면 좋은지 친절하게 안내하고 있다.</p>
<p><img src="https://velog.velcdn.com/images/minjeong-dev/post/e8befa33-ad07-4d2d-9bbf-3d8fa3cb479f/image.png" alt="직무 별 추천 AWS Certification 경로 예시"></p>
<p>흥미롭다. 아키텍처나 시스템 운영, DevOps 등의 직무는 이렇게 세세하고 심화 자격증까지 추천하고 있다. 나(저년차 프론트엔드 개발자)의 경우는 일단 소프트웨어 개발 엔지니어의 경로대로 공부를 하고 취득해보면 좋을 것 같다.</p>
<hr>
<h3 id="소프트웨어-개발-엔지니어">소프트웨어 개발 엔지니어</h3>
<p><img src="https://velog.velcdn.com/images/minjeong-dev/post/50d6168f-15cf-4a0b-a91c-3cd8be4153f4/image.png" alt="소프트웨어 개발 엔지니어 직무의 추천 AWS Certification 경로"></p>
<ol>
<li>AWS Cloud Practitioner</li>
<li>(AI 활용자의 경우) AWS AI Practitioner</li>
<li>AWS Developer</li>
<li>AWS DevOps Engineer</li>
</ol>
<hr>
<p>그 외 특이사항으로는 다음과 같은 사항이 있다.</p>
<ul>
<li>AWS Certification은 3년 동안 유효하다. (갱신 프로세스가 있다.)</li>
<li><a href="https://explore.skillbuilder.aws/learn#prepare-for-exam">AWS Skill Builder</a>라는 온라인 학습 센터에서 무료/유료 강의를 들으며 공부할 수 있다.</li>
<li>영어가 모국어가 아닌 응시자가 영어로 시험을 보게 되면 30분의 연장 시간을 제공받을 수 있다. (시험 전에 한 번 등록하면 된다.)</li>
</ul>
<hr>
<p>다음 글로는, AWS Cloud Practitioner 자격증 및 준비 내용에 대해 작성해볼 예정이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[『육각형 개발자』 읽어보기]]></title>
            <link>https://velog.io/@minjeong-dev/%E3%80%8E%EC%9C%A1%EA%B0%81%ED%98%95-%EA%B0%9C%EB%B0%9C%EC%9E%90%E3%80%8F-%EC%9D%BD%EC%96%B4%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@minjeong-dev/%E3%80%8E%EC%9C%A1%EA%B0%81%ED%98%95-%EA%B0%9C%EB%B0%9C%EC%9E%90%E3%80%8F-%EC%9D%BD%EC%96%B4%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Sun, 10 Sep 2023 09:34:27 GMT</pubDate>
            <description><![CDATA[<p>트위터에서 신간 소식을 보고 마치 게임 캐릭터의 능력치 정보 창과 같은 책 커버 디자인이 흥미롭다는 얘기를 회사 점심시간에 꺼냈다가, 선뜻 주문해주셔서 회사 서재에 이 책이 한 권 생겼다.</p>
<p><img src="https://velog.velcdn.com/images/minjeong-dev/post/a242fcde-a454-4a6a-8aa8-99739af2860b/image.jpg" alt="육각형 개발자 책 표지"></p>
<p>글을 정리하기 전 써보는 간단한 후기는...</p>
<ol>
<li>당연한 말의 지분이 생각보다 높다. (당연한 말이지만, 이라는 수식을 굉장히 자주 사용한다.) 사실 개인적으로는 당연한 말이더라도 그 말을 그럼에도 해야하는 이유나 목적이 분명하게 설명될 경우 아무 문제가 되지 않는다고 생각한다. 그런데 이 책은 당연한 말을, 그 말이 당연한 이유만 붙여 설명할 뿐이다.</li>
<li>제목에 충실하게, 글이 굉장히 넓고 얕다. 술술 읽으며 시니어 개발자는 이런 생각을 하는구나, 읽기 위해 이 책을 펴는 것이 가장 적합하다.</li>
</ol>
<hr>
<p>지은이가 제시하는 개발자의 역량은 다음과 같은 키워드로 정리된다.</p>
<ul>
<li>구현 기술</li>
<li>코드 이해 역량</li>
<li>아키텍처 설계 역량</li>
<li>업무 관리 역량</li>
<li>글쓰기와 발표 역량</li>
<li>리더/팔로워로서의 협업 역량</li>
</ul>
<p>이를 중심으로 책을 읽으며 2년차 개발자로서 지난 날을 돌아보고, 현재와 앞으로 할 일을 정리해보는 시간을 갖기 위해 책을 읽어봤다. 이 책은 읽고 요약하기 보단 나중에 다시 한 번 읽고 싶을 만한 문장을 남겨놓는 쪽으로 정리를 했다.</p>
<hr>
<h2 id="구현-기술">구현 기술</h2>
<blockquote>
<p>개발자가 얼마나 구현 기술을 활용할 수 있는가?</p>
</blockquote>
<h3 id="구현-기술의-적용">구현 기술의 적용</h3>
<p>어떤 기술을 도입할 때 보수적으로 고민하면서 고려해야할 것들이 있다.</p>
<ul>
<li>신뢰왇 동료<ul>
<li>회사 내에서 동료, 리더의 신뢰를 얻은 후 기술 도입을 주장해야 한다.</li>
<li>혼자서 어떤 기술을 새로 도입하고, 기존의 코드를 바꿀 수는 없다.</li>
</ul>
</li>
<li>타당성<ul>
<li>특정 기술을 적용하려는 타당한 이유를 제시할 수 있어야 한다.</li>
</ul>
</li>
<li>점진적 적용<ul>
<li>동작하는 서비스, 시스템에 새 구현 기술을 도입할 때에는 점진적으로 적용해야 한다.</li>
</ul>
</li>
<li>시장 상황<ul>
<li>도입하려는 기술을 능숙하게 사용할 수 있는 인력을 충분히 구할 수 있어야 한다.</li>
</ul>
</li>
</ul>
<p>사실 내가 쓰는 크로스 플랫폼 모바일 앱의 기술이 굉장히 마이너해서, 이 기술을 사용하는 회사를 만나기는 커녕 내 이력서를 통해 그 프레임워크의 이름을 처음 들어봤다는 사람들을 훨씬 많이 보게 된다. (사실상 이전 회사에서 1년 정도 썼고, 여러 플러그인도 써봤지만 이를 필요로 하는 회사가 없으니 내 이력서에서는 그냥 분량을 채우는 역할만 하게 된 것이다.)</p>
<h2 id="유지-보수와-개발-비용">유지 보수와 개발 비용</h2>
<blockquote>
<p>어떻게 유지 보수하는 비용을 줄일 수 있을까?</p>
</blockquote>
<p>코드 품질 관리가 곧 결국 비용 문제에 직결된다.</p>
<h3 id="코드-이해">코드 이해</h3>
<p>유지 보수를 하기 위해서는 기존 코드를 이해하는 과정이 늘 선행된다.
이 코드 이해를 하는데 소요되는 비용을 어떻게 줄일 수 있을까?</p>
<h4 id="코드-시각화">코드 시각화</h4>
<p>중요한 점. 코드를 다이어그램으로 시각화할 때 모든 상세 내용을 전부 표시하려고 하면 안 된다. 불필요한 요소는 생략하여 분명하게 다이어그램의 목적을 수행하고, 의도된 정보를 제공하게 한다.</p>
<h5 id="uml">UML</h5>
<ul>
<li>액티비티 다이어그램<ul>
<li>코드 실행 흐름을 이해하는 데 도움이 된다.</li>
</ul>
</li>
<li>시퀀스 다이어그램<ul>
<li>런타임의 객체/프로세스 간 상호 작용을 이해하는 데 도움이 된다.</li>
</ul>
</li>
<li>클래스 다이어그램<ul>
<li>코드의 정적 구조를 이해하는 데 도움이 된다.</li>
</ul>
</li>
</ul>
<h2 id="응집도와-결합도">응집도와 결합도</h2>
<blockquote>
<p>왜 응집도를 높이고 결합도를 낮추어야 할까?</p>
</blockquote>
<p>응집도를 높이고 결합도를 낮춘다는 것은 구성 요소 간 상호 작용을 최소화하는 것이다.</p>
<h3 id="응집도">응집도</h3>
<ul>
<li>응집도가 높다는 것은 곧, 역할과 기능이 같은 코드가 분리된다는 것이다. 이는 자연스럽게 클래스 코드의 길이가 줄어들고 메서드 단위로 작성되어 가독성이 좋다는 것이다. 또한 그만큼 역할과 책임의 범위가 분리되어 유지 보수에 유리하다.</li>
</ul>
<h3 id="결합도">결합도</h3>
<ul>
<li>응집도가 높다고 해서 반드시 결합도가 낮은 건 아니다. 코드를 역할에 따라 분리하여 응집도를 높였으나, 그 분리된 요소 간의 의존이 발생하고 굉장히 의존성이 높다면 결합도는 증가하는 것이다.</li>
</ul>
<h2 id="레거시-코드">레거시 코드</h2>
<blockquote>
<p>레거시 코드는 왜 무서운가?</p>
</blockquote>
<ul>
<li>테스트가 없는 코드, 이전 버전의 프레임워크를 사용해 개발한 코드 등 보다 넓은 의미의 단어로 쓰인다. 그러나 어떤 의미로 사용되더라도 레거시 코드는 수정하기가 어려운 코드라는 핵심적인 특성을 갖는다.</li>
</ul>
<h2 id="테스트-코드">테스트 코드</h2>
<blockquote>
<p>테스트 코드를 작성하는 게 쉽지만은 않다. 하지만 테스트가 주는 이점을 고려하면 테스트 코드 작성 능력을 길러야 한다.</p>
</blockquote>
<ul>
<li>테스트 코드가 없는 조직은 수동 테스트를 진행한다. 하지만 이런 QA는 다양한 경우의 수를 확인하기 어렵다.</li>
<li>테스트 코드가 있다고 해서 모든 문제를 완벽하게 없애는 건 아니다. 그러나 적어도 테스트를 통과한 코드는 문제가 없다는 것을 확신할 수 있다는 강력한 이점이 있다.</li>
<li>테스트 커버리지는 7-80% 정도를 이루면 코드를 안정적으로 유지할 수 있게 만든다. 그렇다면 테스트 커버리지를 어떻게 넓힐 수 있을까?</li>
</ul>
<h3 id="tdd-test-driven-development">TDD (Test-Driven Development)</h3>
<p>테스트 코드를 만들고 이 테스트를 통과할 수 있는 구현을 진행하여 소프트웨어를 개발하는 방법론.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[『클린 코드의 기술: 단순함의 노하우』  읽어보기]]></title>
            <link>https://velog.io/@minjeong-dev/%E3%80%8E%ED%81%B4%EB%A6%B0-%EC%BD%94%EB%93%9C%EC%9D%98-%EA%B8%B0%EC%88%A0-%EB%8B%A8%EC%88%9C%ED%95%A8%EC%9D%98-%EB%85%B8%ED%95%98%EC%9A%B0%E3%80%8F-%EC%9D%BD%EC%96%B4%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@minjeong-dev/%E3%80%8E%ED%81%B4%EB%A6%B0-%EC%BD%94%EB%93%9C%EC%9D%98-%EA%B8%B0%EC%88%A0-%EB%8B%A8%EC%88%9C%ED%95%A8%EC%9D%98-%EB%85%B8%ED%95%98%EC%9A%B0%E3%80%8F-%EC%9D%BD%EC%96%B4%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Sat, 22 Jul 2023 04:23:05 GMT</pubDate>
            <description><![CDATA[<h1 id="클린-코드의-기술">클린 코드의 기술</h1>
<p><img src="https://velog.velcdn.com/images/minjeong-dev/post/aa419061-03c1-47b5-bc51-d8dba01e2994/image.jpeg" alt="클린 코드의 기술: 단순함의 노하우 책 표지"></p>
<p>책을 읽으면서 소화하지 못해 다시 읽어야 하는, 재밌거나 인상깊어서 다시 읽고 싶어지는 텍스트를 요약한 글.</p>
<p>로버트 C. 마틴이 기술한 『클린 코드』 는 실제 개발 산출물로써의 코드를 어떻게 클린하게 작성할 수 있는가에 대한 개발 방법론이라면, 이 책은 어떻게 프로그래밍의 생산성을 높일 수 있는가에 대한 더욱 넓은 주제의 책이었다. (물론 소스 코드를 클린하게 작성하는 방법에 대한 이야기가 주된 컨텐츠이긴 하다.)</p>
<p>정식 번역 서적 출간이 23년 1월인데 이 책이 회사에 있다니 반가운 마음에 냉큼 주말 동안 읽었다.</p>
<hr>
<h2 id="1장-복잡성은-어떻게-생산성을-해치는가">1장, 복잡성은 어떻게 생산성을 해치는가</h2>
<h3 id="복잡성complexity">복잡성(Complexity)</h3>
<blockquote>
<p>부분들로 이루어진 전체에 대한 것을 분석, 이해하기 어려운 정도.</p>
</blockquote>
<p>컴퓨터 공학에서는 주어진 코드를 분석하여 계산 복잡도를 계산하는 등 엄격한 정의를 사용하고, 다른 경우에는 시스템 컴포넌트 사이의 상호 작용의 양 또는 구조의 정도로 느슨하게 정의하여 사용하기도 한다. 현재 이 책에서는 범용적으로, 그리고 전체 시스템 혹은 엔티티를 대상으로 사용하고자 한다. </p>
<p>프로그래머가 직면할 수 있는 복잡성의 원천은 다음과 같다.</p>
<ul>
<li>프로젝트 생명주기의 복잡성<ul>
<li>계획, 설계, 구현 및 테스트에 이르는 과정 속 이해 관계 충돌, 한정된 자원 등에 의한 복잡성을 말한다.</li>
</ul>
</li>
<li>소프트웨어와 알고리즘 이론의 복합성<ul>
<li>algorithmic complexity -&gt; 성능에 직결된다.</li>
<li>계산 복잡도를 낮춰 자원 활용의 효율을 높이고 비용을 줄이고자 한다.</li>
</ul>
</li>
<li>학습의 복잡성<ul>
<li>개발을 위해 요구되는 컴퓨터 공학적 배경 및 도메인에 요구되는 사전 배경, 사용할 언어 및 프레임워크의 필요 전문성 등에 의한 복잡성을 말한다.</li>
</ul>
</li>
<li>프로세스의 복잡성<ul>
<li>소프트웨어 개발 과정의 프로세스는 개발, 테스트(QA), 출시라는 사이클을 가지지만 세부 프로세스가 다양해지고 커지면서 가지는 복잡성을 말한다.</li>
</ul>
</li>
<li>...</li>
</ul>
<h3 id="결론">결론</h3>
<p>&quot;개발자는 복잡성을 극복해야 한다!&quot;</p>
<h2 id="2장-8020-원칙">2장, 80:20 원칙</h2>
<h3 id="8020-원칙">80:20 원칙</h3>
<blockquote>
<p>대부분의 결과(80%)가 소수의 원인(20%)에서 온다.</p>
</blockquote>
<p>이 원칙(이하 &#39;파레토 원칙&#39;)은 소프트웨어 프로젝트에도 적용 가능하며, 실제로 연구에서 밝혀진 바가 있다. 어떤 소프트웨어의 소스 코드 실행 시간 전체 중 대다수의 실행 시간을 차지하는 것은 소수 코드이다. 따라서, 사소한 다수를 최적화하는 데에 오랜 시간을 소비하더라도 전반적인 실행 시간 향상에는 거의 영향이 없게 된다. 20%의 코드를 반복적으로 최적화하는 것이 중요하다.</p>
<p>(여기서부턴 왜 이런 논점으로 이야기가 흘러가는지 이해하진 못했다.)</p>
<p>그리고 이 원칙을 소프트웨어 프로젝트의 생산성, 즉 참여 개발진의 성과를 지표로 계산한 생산성에 적용할 수도 있다? 그리고 이것은 고소득으로 이어지므로, 어떻게 개발자는 자신의 성과를 높여 고소득자가 될 수 있을까? 저자는 이런 속담을 인용한다. &quot;열두 가지 재주 있는 사람이 밥 굶는다&quot; 라고. 다양한 활동, 학습 하지 말고 중요한 영역의 전문 지식을 쌓으라고 말한다. &#39;위대한 프로그래머&#39;는 평균적인 프로그래머가 만드는 생산성의 10,000배 가치가 있다고 한다. 따라서 그렇게 되기 위해서는 20%의 활동에 집중해야 하고, 그 중 하나의 방법은 더 많은 코드를 쓰는 것이라고 한다.</p>
<p>(흥... 100명이 들으면 100명 모두 동의할 말이다. 그리고 범용적으로 쓰여도 맞는 말일 것이다. 굉장히 자기 계발 서적 같은 챕터다...)</p>
<h2 id="3장-최소-기능-제품-만들기">3장, 최소 기능 제품 만들기</h2>
<h3 id="최소-기능-제품minimum-viable-product-mvp">최소 기능 제품(minimum viable product, MVP)</h3>
<blockquote>
<p>가장 필요한 기능들 외에는 모두 제거한 제품의 버전.</p>
</blockquote>
<p>배포할 때마다 단지 하나의 기능을 구현(=MVP)하여 시장을 분석하고 전략을 설정하는 빠른 프로토타이핑 형태의 사이클을 가지면 좋다. 자동적으로 최소 기능들의 조합으로 이루어진 아키텍처 형태로 서비스가 구성될 것이고, 분리된 단위 테스트가 함께 확장될 것이다.</p>
<h2 id="4장-클린하고-단순한-코드-작성하기">4장, 클린하고 단순한 코드 작성하기</h2>
<h3 id="클린-코드">클린 코드</h3>
<blockquote>
<p>읽고 이해하고 고치기 쉬운 코드.</p>
</blockquote>
<p>작성한 코드를 단 한 번도 개선하지 않은 클린 코드는 없다. 코드 기반을 개선하고 복잡성을 줄이는 리팩토링도 주기적으로 수행해야 한다. 코드를 작성하고 리팩토링 하는 데에는 여러 원칙이 있다.</p>
<h4 id="1-큰-그림을-생각하라">1. 큰 그림을 생각하라</h4>
<p>좋은 소프트웨어 아키텍처가 곧 코드를 클린하게 한다. 소프트웨어 아키텍처는 다수의 파일, 모듈, 라이브러리 등의 구성 요소가 어떻게 상호 작용하는지 정의한 것이다. 좋은 아케틱처는 성능, 유지보수성, 사용성 개선에 큰 영향을 끼친다.</p>
<p>그렇다면 어떻게 좋은 소프트웨어 아키텍처를 만들 수 있을까? 기능을 정의하고 디자인해야 한다.</p>
<h4 id="2-거인들의-어깨-위에-서라">2. 거인들의 어깨 위에 서라</h4>
<p>거인들, 즉 세계 최고의 프로그래머들은 잘 튜닝되고 검증된 알고리즘, 코드와 같은 유산을 남겼다. 자동차를 만드는데 바퀴를 재발명할 필요가 있는가? 프로그래밍도 그렇다. 라이브러리 코드를 적극적으로 사용한다!</p>
<h4 id="3-기계가-아닌-사람을-위한-코드">3. 기계가 아닌 사람을 위한 코드</h4>
<p>high-level language로 프로그래밍을 한다면, 궁극적으로 그 사용 언어의 목적은 프로그래머가 코드를 작성하는 일을 돕는 것이다.</p>
<h4 id="4-올바른-이름을-사용하라">4. 올바른 이름을 사용하라</h4>
<ul>
<li>서술적인 이름을 고른다.</li>
<li>모호하지 않은 이름을 고른다.</li>
<li>발음하기 쉬운 이름을 고른다.<ul>
<li>잠재의식적으로 프로그래머는 코드를 &quot;읽기&quot; 때문에 코드 해독은 발음하기 쉬울 수록 더욱 용이하다.</li>
</ul>
</li>
<li>상수에 이름을 붙인다.</li>
</ul>
<p>이 외에도 여러 클린 코드를 위한 네이밍 규칙은 많으니 구글링을 하여 학습하고 정해두는 것이 좋다.</p>
<h4 id="5-표준을-지키고-일관성을-유지하라">5. 표준을 지키고 일관성을 유지하라</h4>
<p>IDE와 린터를 사용해 스타일을 일관되게 유지하여 가독성을 높인다.</p>
<h4 id="6-주석을-사용하라">6. 주석을 사용하라</h4>
<p>주석을 이용해 명명 규칙으로도 해결되지 않는 이해를 돕는다. 주석은 곧 코드의 불록을 추상화한다.</p>
<h4 id="7-불필요한-주석을-피하라">7. 불필요한 주석을 피하라</h4>
<p>모든 주석이 코드 이해에 도움을 주는 것은 아니다. 오히려 명료성을 낮추고 코드를 읽는 사람을 혼란스럽게 할 수 있다.</p>
<ul>
<li>인라인 주석을 사용하지 않는다.<ul>
<li>의미있는 네이밍을 하면 전적으로 사용하지 않을 수 있게 된다.</li>
</ul>
</li>
<li>옛날 코드를 주석 처리하지 않는다.<ul>
<li>코드의 가독성을 매우매우 해친다.</li>
<li>옛날 코드는 형상 관리 도구를 사용하여 관리하면 된다.</li>
</ul>
</li>
<li>문서화 기능을 사용한다.</li>
</ul>
<h4 id="8-놀람-최소화-원칙">8. 놀람 최소화 원칙</h4>
<blockquote>
<p>어떤 시스템의 컴포넌트는 <strong>사용자가 예상하는 대로</strong> 동작해야 한다.</p>
</blockquote>
<h4 id="9-반복하지-않는다">9. 반복하지 않는다</h4>
<h4 id="10-단일-책임-원칙">10. 단일 책임 원칙</h4>
<blockquote>
<p>모든 클래스와 함수는 <strong>한 개의 책임</strong>(=주요 목적)을 가진다.</p>
</blockquote>
<p>동시에 모든 것을 해내는 하나의 거대 컴포넌트가 아닌, 다수의 작은 컴포넌트를 사용하도록 개발해야 한다. 기능성을 캡슐화하면, 전체적인 코드 복잡도가 낮아진다.</p>
<h4 id="11-테스트">11. 테스트</h4>
<h4 id="12-작은-것이-아름답다">12. 작은 것이 아름답다</h4>
<h4 id="13-디미터의-법칙">13. 디미터의 법칙</h4>
<p>코드 요소들의 상호 의존성을 최소화해야 한다. </p>
<h4 id="14-필요하지-않아요">14. 필요하지 않아요</h4>
<p>당장 필요한 코드만 작성한다. (미래의 요구사항 및 이해 관계를 위한 코드를 작성하지 않는다.) 과도한 엔지니어링을 피해야 한다.</p>
<h4 id="15-과도한-들여쓰기-금지">15. 과도한 들여쓰기 금지</h4>
<p>수없이 중첩되어 들여쓰기의 depth가 높으면 코드의 가독성이 떨어지게 된다.</p>
<h4 id="16-지표를-사용하라">16. 지표를 사용하라</h4>
<p>코드의 복잡성을 추적할 수 있는 코드 품질 지표를 사용해야 한다. 비공식적이지만 궁극적인 지표는 WTF(Wath the Fuck), 코드를 읽는 동안 몇 번의 욕을 하는지 ㅋㅋ 이다. IDE에는 많은 도구, 플러그인들이 복잡도를 계산해 준다고 하니 적극적으로 사용해보는 것이 좋다.</p>
<h4 id="17-보이-스카웃-법칙과-리팩토링">17. 보이 스카웃 법칙과 리팩토링</h4>
<blockquote>
<p>야영장을 떠날 때는 들어올 때보다 깨끗하게 하라.</p>
</blockquote>
<h2 id="5장-성급한-최적화는-모든-악의-근원">5장, 성급한 최적화는 모든 악의 근원</h2>
<h3 id="성급한-최적화의-유형들">성급한 최적화의 유형들</h3>
<h4 id="코드-함수의-최적화">코드 함수의 최적화</h4>
<p>함수가 얼마나 쓰일지 알 수 없다면 최적화를 함부로 하지 않는다.</p>
<h4 id="기능-최적화">기능 최적화</h4>
<p>반드시 필요로 하지 않는 기능을 추가하거나 최적화를 하느라 시간을 낭비하지 않는다.</p>
<h4 id="계획-최적화">계획 최적화</h4>
<blockquote>
<p>&quot;세상에 가치 있는 것을 배포하려면 불완전함을 수용해야 한다.&quot;</p>
</blockquote>
<p>소프트웨어 프로젝트 생명주기의 계획 단계에서 최적화를 도입할 경우, 오히려 지연을 발생시킨다. </p>
<h4 id="확장성-최적화">확장성 최적화</h4>
<p>실제 사용자를 만나기 전에 확장성을 최적화하는 것은 주의가 분산되고, 개발자와 서버 비용을 낭비할 수 있다. (수백만 명의 사용자가 방문할 것을 기대하고 예상한 시나리오 대로 설계한 분산 아키텍처를 구현하는 사례와 같다. 이럴수가. 완전 흔한 사례다.)</p>
<h4 id="테스트-설계-최적화">테스트 설계 최적화</h4>
<p>테스트 주도 개발을 위해 &quot;완벽한 단위 테스트&quot;를 설계하는 일은 불필요한 복잡성을 늘리고 소프트웨어 개발 주기를 느리게 만들 수 있다. (어떤 기능이나 상황은 100%의 테스트 커버리지를 만들기가 어려운데, 그를 도달하기 위해 노력하는 상황을 말하는 것 같다.)</p>
<h4 id="객체지향-최적화">객체지향 최적화</h4>
<p>성급한 &quot;개념적&quot; 최적화는 불필요한 복잡성을 만든다. 객체지향적 설계를 위해 불필요한 계층 구조를 만들고 모델링하게 되는 경우를 말한다.</p>
<h3 id="성능-튜닝을-위한-팁">성능 튜닝을 위한 팁</h3>
<h4 id="측정을-먼저-개선은-다음">측정을 먼저, 개선은 다음</h4>
<p>소프트웨어의 성능을 측정한 후에 최적화를 진행해야 한다. 최적화 목표 및 성공 여부를 판단할 수 있는 기준점(benchmark)도 이 측정으로부터 만들어진다.</p>
<h4 id="파레토">파레토</h4>
<p>파레토 원칙(80:20 원칙)을 성능 최적화에도 적용한다. 실제 많은 자원을 사용하거나 지연을 발생시키는 코드를 측정을 통해 발견한 후 해당 부분만 최적화한다.</p>
<h4 id="알고리즘-최적화">알고리즘 최적화</h4>
<p>대부분의 병목 현상은 알고리즘과 자료구조를 튜닝하여 해결 가능하다.</p>
<ul>
<li>더 나은 알고리즘이 있는가?</li>
<li>기존의 알고리즘이 수정 가능한가?</li>
<li>자료구조를 개선할 수 있는가?</li>
</ul>
<h4 id="캐시">캐시</h4>
<p>캐싱 정책을 세우고 활용한다.</p>
<h2 id="7장-한-개의-일을-잘하기와-다른-유닉스-원칙들">7장, 한 개의 일을 잘하기와 다른 유닉스 원칙들</h2>
<blockquote>
<p>&quot;한 개의 일을 잘 하자(Do one thing and do it well)&quot;</p>
</blockquote>
<blockquote>
<p>유닉스 철학의 기본적 생각은 확장하고 유지보수하기 쉽도록 단순하고 분명하고 정확하고 모듈화된 코드를 작성하는 것이다.</p>
</blockquote>
<h4 id="각-함수는-한-개의-일을-잘한다">각 함수는 한 개의 일을 잘한다</h4>
<p>작게 유지한 함수는 기존 기능성을 기반하는 새로운 코드를 쉽게 만들 수 있게 하고, 중복성도 발생하지 않게 만든다. 이는 코드의 모듈화로 이어지고 재사용성, 유지보수성과 확장성이 좋아진다.</p>
<h4 id="단순함이-복잡함보다-좋다">단순함이 복잡함보다 좋다</h4>
<h4 id="작은-것이-아름답다">작은 것이 아름답다</h4>
<p>코드 블럭을 작게 만든다.</p>
<h4 id="프로토타입을-가능한-빠르게-만든다">프로토타입을 가능한 빠르게 만든다</h4>
<h4 id="효율성보다는-이식성을-선택한다">효율성보다는 이식성을 선택한다</h4>
<blockquote>
<p>어떤 시스템 혹은 프로그램이 한 환경에서 다른 환경으로 이동했을 때 여전히 정상적으로 동작하는 능력</p>
</blockquote>
<p>이식성과 효율성의 트레이드-오프 관계를 이해해야 한다. 이식성이 좋다는 것은 효율성의 희생이 따른 결과다. 한 환경에 최적화되어 매우 효율적이라는 것은 이식성이 그만큼 희생된 결과인 것과 같다.</p>
<h4 id="데이터는-플랫-텍스트-파일에-저장한다">데이터는 플랫 텍스트 파일에 저장한다</h4>
<p>플랫 텍스트 파일에 저장하면 파일 내용을 접근하는 고도의 메커니즘을 갖지 않는 이진 파일이므로, 쉽게 데이터이 CRUD가 가능하다. 더 적은 메모리를 차지하기도 한다. 최적화된 데이터 표현 형식을 사용하고자 할 경우 확실한 검증을 통해 결정해야 한다.</p>
<h4 id="소프트웨어를-레버리지로-사용한다">소프트웨어를 레버리지로 사용한다</h4>
<h4 id="캡티브-사용자-인터페이스를-피한다">캡티브 사용자 인터페이스를 피한다</h4>
<blockquote>
<p>프로그램의 주요 실행 흐름이 시작되기 전에 사용자의 상호작용을 요구하는 기능, 인터페이스</p>
</blockquote>
<h4 id="모든-프로그램을-필터로-만든다">모든 프로그램을 필터로 만든다</h4>
<h4 id="더-나쁜-것이-좋다">더 나쁜 것이 좋다</h4>
<p>시간과 자원은 한정적이므로, 완벽한 제품을 구현하여 배포하는 것보다는 부족하고 나쁜 제품을 먼저 배포한 뒤 완성해나가는 것이 효율적일 수 있다는 뜻이다.</p>
<h4 id="클린-코드가-영리한-코드보다-좋다">클린 코드가 영리한 코드보다 좋다</h4>
<h4 id="다른-프로그램과-연결되는-프로그램을-설계한다">다른 프로그램과 연결되는 프로그램을 설계한다</h4>
<h4 id="코드를-견고하게-만든다">코드를 견고하게 만든다</h4>
<ul>
<li>형상 관리 시스템을 사용해 이전 버전의 코드를 복원할 수 있도록 한다.</li>
<li>데이터를 정기적으로 백업해 복구 가능하도록 만든다.</li>
<li>분산 시스템을 사용하여 단일 장애점 문제를 회피한다.</li>
</ul>
<h4 id="여러분이-할-수-있는-것은-고친다-하지만-실패는-빠르고-시끄럽게">여러분이 할 수 있는 것은 고친다, 하지만 실패는 빠르고 시끄럽게</h4>
<p>오류는 축적될 수 있다. 프로그래머는 사용성 개선을 위해 오류를 감추기를 원하지만 이것이 가장 합리적인 접근법은 아니다.</p>
<h4 id="손-해킹hand-hacking을-피한다-할-수-있다면-프로그램을-생성하는-프로그램을-만든다">손 해킹(hand-hacking)을 피한다: 할 수 있다면 프로그램을 생성하는 프로그램을 만든다</h4>
]]></description>
        </item>
        <item>
            <title><![CDATA[2021 OWASP 10대 취약점]]></title>
            <link>https://velog.io/@minjeong-dev/2021-OWASP-10%EB%8C%80-%EC%B7%A8%EC%95%BD%EC%A0%90</link>
            <guid>https://velog.io/@minjeong-dev/2021-OWASP-10%EB%8C%80-%EC%B7%A8%EC%95%BD%EC%A0%90</guid>
            <pubDate>Tue, 23 May 2023 08:01:35 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/minjeong-dev/post/9f7853ae-7109-425c-aa3d-54e8eab2587e/image.png" alt="OWASP MEME - after reading an article on owasp"></p>
<blockquote>
<p>웹 애플리케이션을 개발할 때 보안성을 높이기 위해 참고할 수 있는 기준과 대응 방법에 대해 요약합니다.</p>
</blockquote>
<hr>
<h1 id="owasp-10대-취약점">OWASP 10대 취약점</h1>
<ul>
<li>The Open Web Application Security Project</li>
<li>웹에 관한 정보 노출, 악성 파일 및 스크립트, 보안 취약점 등을 연구한다.</li>
<li>OWASP TOP 10<ul>
<li>가장 빈도가 높고 보안상 영향을 크게 줄 수 있는 10대 웹 애플리케이션 취약점 목록.</li>
<li>2004년에 처음 발표되었고, 가장 마지막은 2021년이다.</li>
<li>2017년도 버전에서 순서가 변동되고 3가지 항목이 새롭게 구성되었다.
<a href="https://owasp.org/www-project-top-ten/">https://owasp.org/www-project-top-ten/</a>
<img src="https://velog.velcdn.com/images/minjeong-dev/post/70ecafdf-8ba6-4bfa-a23f-a56ce56c7ab1/image.png" alt="owasp top 10 from 2017 ti 2021"></li>
</ul>
</li>
</ul>
<hr>
<h1 id="2021-10대-취약점">2021 10대 취약점</h1>
<p>출처: <a href="https://owasp.org/www-project-top-ten/">https://owasp.org/www-project-top-ten/</a>
출처: <a href="https://www.appsealing.com/kr/2022-owasp-10%EB%8C%80-%EC%B7%A8%EC%95%BD%EC%A0%90/">https://www.appsealing.com/kr/2022-owasp-10대-취약점/</a></p>
<h2 id="1-손상된-액세스-제어-broken-access-control">1. 손상된 액세스 제어, Broken Access Control</h2>
<p>5위에서 1위로 치고 올라왔고, 웹사이트의 94%가 평균 3.81% 발생 중인 최대 화두의 취약점.</p>
<p><strong>취약점 설명</strong></p>
<ul>
<li>특정 기능, 특정 역할에게만 액세스 권한을 부여해야 하는 기본적인 원칙을 위반하는 사례.</li>
<li>POST, PUT, DELETE에 대한 액세스 제어가 누락된 API를 제공하는 사례.</li>
<li>로그인하지 않고 사용자처럼, 사용자로 로그인하고 관리자처럼 접근하고 사용할 수 있게 되는 권한 상승 오류를 발생시키는 사례.</li>
<li>CORS 구성 오류로 인해 승인되지 않은/신뢰할 수 없는 출처의 API 액세스를 허용시키는 사례.</li>
</ul>
<p><strong>예방법</strong></p>
<ul>
<li>공용 리소스를 제외하고는 기본적으로 거부하도록 한다.</li>
<li>사용자에게 모든 테이블의 CRUD 권한을 주지 않고 특정 레코드에만 CRUD 권한을 부여한다.</li>
<li>상태 저장 섹션 식별자는 로그아웃 후 서버에서 무효화되게 해야 한다. / Stateless JWT 토큰은 공격자의 기회를 최소화시킬 수 있게 수명이 짧아야 한다. / 수명이 긴 JWT의 경우 OAuth 표준을 따라 액세스를 취소시키는 것이 좋다.</li>
<li>CORS 사용을 최소화한다.</li>
</ul>
<h2 id="2-암호화-실패-cyptographic-failures">2. 암호화 실패, Cyptographic Failures</h2>
<p>암호화 부족 또는 실패는 민감한 데이터를 노출시키는 문제를 야기시키므로 2위로 상승한 취약점.</p>
<p><strong>취약점 설명</strong></p>
<ul>
<li>비밀번호, 신용 카드 번호, 건강 기록, 개인 정보 등의 개인 정보 보호법 관리 대상으로 해당하는 데이터를 일반 텍스트로 전송한다.</li>
<li>오래되었거나 취약점이 발견된 암호화 알고리즘, 프로토콜을 사용한다.</li>
</ul>
<p><strong>예방법</strong></p>
<ul>
<li>개인 정보 보호법과 비지니스 요구 사항 등에 따라 데이터를 식별한 후 민감한 정보는 암호화하여 처리, 저장한다.</li>
<li>최신의 표준 암호화 알고리즘, 프로토콜을 사용한다. (MD5, SHA1과 같이 더이상 사용되지 않는 암호화 기능을 피해야 한다.)</li>
<li>민감한 데이터를 포함한 응답은 캐싱을 비활성화하여 보낸다.</li>
<li>민감한 데이터를 전송할 땐 FTP, SMTP 같은 레거시 프로토콜을 사용하지 않는다.</li>
</ul>
<h2 id="3-injection">3. Injection</h2>
<p>웹 애플리케이션의 94%가 최대 발생률 19%, 평균 발생률 3% 발생하는 취약점.</p>
<p><strong>취약점 설명</strong></p>
<ul>
<li><p>임의의 SQL 문을 주입, 실행시켜 데이터베이스가 비정상적인 동작을 하도록 조작한다.</p>
<pre><code class="language-sql">-- 가장 대표적인 사례 --

SELECT * FROM Users WHERE id = `INPUT_ID` AND password = `INPUT_PASSWORD`;
↓
↓ INPUT_ID === &quot; ` OR 1=1 --&quot;
↓
SELECT * FROM Users WHERE id = ` ` OR 1=1 --`AND password = `INPUT_PASSWORD`;
↓
↓ OR문과 주석 처리 후 결과
↓
SELECT * FROM Users;</code></pre>
</li>
</ul>
<p><strong>예방법</strong></p>
<ul>
<li>서버측에서 입력 유효성 검사를 사용한다. (완벽한 방어 수단은 아니다.)<ul>
<li>SQL 명령어가 포함된 문자열은 유효하지 않다고 판단하는 등.</li>
</ul>
</li>
<li>쿼리 내에서 LIMIT, 기타 SQL 컨트롤을 사용하여 대량의 레코드가 삽입되거나 공개되지 않도록 설정한다.</li>
<li>저장 프로시저를 사용한다. = 사용하고자 하는 Query에 미리 형식을 지정하여, 형식이 맞지 않으면 Query가 실행되지 않기 땝문에 보안성을 향상시킨다고 한다.</li>
</ul>
<h2 id="4-안전하지-않은-설계-insecure-design">4. 안전하지 않은 설계, Insecure Design</h2>
<p>(설계 결함과 구현 결함을 구분한다. 원인과 해결 방법이 다르다.) </p>
<p><strong>취약점 설명</strong></p>
<ul>
<li>특정 공격을 방어하기 위해 필요한 보안 제어를 생성하지 않은 경우, 구현을 완벽하게 한다고 해도 결함이 발생한다.</li>
<li>데이터 무결성, 기밀성, 가용성, 신뢰성 고려한 비지니스 로직 설계를 하지 않는다.</li>
<li>보안 소프트웨어 설계—보안 개발 수명 주기, 보안 설계 패턴, 보안 컴포넌트 라이브러리 및 모델링 등을 하지 않는다.</li>
</ul>
<p><strong>예방법</strong></p>
<ul>
<li>AppSec 전문가와 보안 개발 수명 주기를 설정한다?</li>
<li>보안 설계 패턴의 라이브러리를 사용하도록 한다?</li>
<li>액세스 제어, 보안 인증, 비지니스 로직을 모델링한다.</li>
<li>…</li>
</ul>
<h2 id="5-보안-구성-오류-security-misconfiguration">5. 보안 구성 오류, Security Misconfiguration</h2>
<p><strong>취약점 설명</strong></p>
<ul>
<li>오류 처리 시 사용자가 추적할 수 있는, 지나치게 유익한 오류 메시지를 표시한다.</li>
<li>불필요한 기능이 활성화되어 있거나 설치되어 있다.</li>
</ul>
<p><strong>예방법</strong></p>
<ul>
<li>불필요한 기능, 구성 요소, 문서, 샘플 파일 등이 없는 최소한의 플랫폼으로 구성한다.</li>
<li>개발, QA, 프로덕션의 보안 환경을 동일하게 구성한 채 관리하며 배포하는 시스템을 구축한다.</li>
</ul>
<h2 id="6-취약하고-오래된-구성요소-vulnerable-and-outdated-components">6. 취약하고 오래된 구성요소, Vulnerable and Outdated Components</h2>
<p>사용 중인 플랫폼, 프레임워크, 라이브러리가 업데이트, 패치되었는데 이를 수정하거나 업그레이드하지 않은 채 계속 사용할 경우 보안 상 위험할 수 있다. </p>
<p><strong>예방법</strong></p>
<ul>
<li>정기적으로 사용중인 구성요소의 취약성을 스캔하고, 패칭과 업데이트를 관리한다.<ul>
<li>정기적으로 구성요소를 패칭할 수 있는 업무 흐름을 자동화하여 관리한다.</li>
</ul>
</li>
<li>업데이트, 업그레이드, 패치된 구성요소의 호환성을 테스트한 후 적용한다.</li>
</ul>
<h2 id="7-식별-및-인증-실패-identification-and-authentication-failures">7. 식별 및 인증 실패, Identification and Authentication Failures</h2>
<p><strong>취약점 설명</strong></p>
<ul>
<li>자동화된 무차별 공격을 허용한다.</li>
<li>password나 admin 같은 기본 암호, 잘 알려진 암호 등을 허용한다.</li>
<li>URL에 세션 식별자를 노출한다.</li>
<li>세션 식별자나 토큰을 올바르게 무효화하지 못해, 사용자가 로그아웃 후에도 세션 값이나 인증 토큰이 유효하게 동작한다.</li>
</ul>
<p><strong>예방법</strong></p>
<ul>
<li>다단계 인증을 구현한다.</li>
<li>상위 10,000개 최악의 암호 목록 등으로 취약한 암호 검사를 구현한다.<ul>
<li><a href="https://www.itworld.co.kr/news/107631">123456, password, qwerty, letmein, login 등등…</a></li>
</ul>
</li>
<li>로그인 실패 횟수를 카운트하여 제한한다.</li>
<li>무차별 공격, 기타 공격, <em><a href="https://auth0.com/blog/what-is-credential-stuffing/">Credential Stuffing</a></em>(빼내온 어느 서비스의 ID/PW로 모든 사이트에 로그인 시도) 등을 감지하면 로그인 실패 기록을 관리하고 관리자에게 알리는 대응을 하도록 한다.</li>
<li>세션 식별자는 URL에 포함시키지 않는다.</li>
<li>사용자가 로그아웃하거나 유휴 시간을 초과할 경우 무조건 세션이나 발급한 인증 토큰을 무효화하도록 한다.</li>
</ul>
<h2 id="8-소프트웨어-및-데이터-무결성-실패-software-and-data-integrity-failures">8. 소프트웨어 및 데이터 무결성 실패, Software and Data Integrity Failures</h2>
<p><strong>취약점 설명</strong></p>
<ul>
<li>신뢰할 수 없는 소스 코드, 리포지토리, CDN의 플러그인·라이브러리·모듈 등을 사용한다.</li>
<li>안전하지 않은 CI/CD 파이프라인을 사용한다. → 무단 액세스, 악성 코드 주입, 시스템 손상 등의 가능성이 있다.</li>
<li>자동 업데이트를 활성화해두어서 구성 요소가 무결성 검사 없이 설치되고 업로드 된다.</li>
</ul>
<p><strong>예방법</strong></p>
<ul>
<li><code>npm</code>, <code>maven</code>과 같은 라이브러리, 종속성 관리 툴에 의해 신뢰 가능한 리포지토리로 호스팅 된 플러그인·라이브러리·모듈 등인지 확인하고 사용한다.</li>
<li>악성 코드 및 구성 요소가 소프트웨어 파이프라인에 도입될 가능성을 최소화하기 위해, 코드 및 구성 변경에 대한 검토 프로세스를 구축한다.</li>
<li>빌드, 배포 프로세스 상의 코드 무결성을 보장하기 위해 CI/CD 파이프라인의 액세서 제어 등을 확인한다.</li>
<li>디지털 서명과 같은 메커니즘을 사용하여 소프트웨어와 데이터의 변경, 변조, 재생을 감지하며 어떤 형태의 무결성 검사나 디지털 서명이 없으면 신뢰할 수 없는 클라이언트에게 전송하지 않도록 처리한다.</li>
</ul>
<h2 id="9-보안-로깅-및-모니터링-실패-security-logging-and-monitoring-failures">9. 보안 로깅 및 모니터링 실패, Security Logging and Monitoring Failures</h2>
<p>로깅, 모니터링 없이는 보안 침해를 감지할 수 없다.</p>
<p><strong>취약점 설명</strong></p>
<ul>
<li>로그인 시도 및 실패, 중요 데이터 및 권한과 관련된 트랜잭션 로그를 쌓지 않는다.</li>
<li>적절한 임계값, 응답 <a href="https://www.zendesk.kr/blog/what-is-escalation/">*에스컬레이션</a>* 프로세스가 없거나 있어도 효과적이지 않다.</li>
<li>의심스러운 활동으로 판별하는 기준을 세우지 않고, 모니터링도 하지 않는다.</li>
</ul>
<p><strong>예방법</strong></p>
<ul>
<li>로깅 및 모니터링 시스템을 구축하고 액세스 제어 및 이상 활동 감지를 위해 기록한다.</li>
<li>의심스러운 로그 발생 시 모니터링 및 경고 알림을 설정하여 대응할 수 있도록 한다.<ul>
<li>응용프로그램 보호 프레임워크를 사용하여 로그를 대시보드로 확인하고 알림 기능을 사용할 수 있다.</li>
</ul>
</li>
<li>사고 대응 및 복구 계획을 수립해둔다.</li>
</ul>
<h2 id="10-서버사이드-요청-위조-erver-side-request-forgery">10. 서버사이드 요청 위조, erver-Side Request Forgery</h2>
<p>사용자 제공 URL의 유효성을 검사하지 않고 원격 리소스를 가져올 때 발생한다. (클라이언트가 서버에게 원격 경로의 특정 파일을 URL로 접근했는데 아무 보안 처리를 해두지 않아서 열람이나 다운로드가 가능한 경우를 말하는 것 같다.)</p>
<p><strong>예방법</strong></p>
<ul>
<li>클라이언트에게 raw response 보내지 않는다.</li>
<li>HTTP 리디렉션을 비활성화한다.</li>
<li>URL Scheme, port, destination의 허용 목록을 설정하고 관리한다.</li>
</ul>
<hr>
<h1 id="요약">요약</h1>
<table>
<thead>
<tr>
<th align="left"></th>
<th align="left">취약점</th>
<th align="left">예방법</th>
</tr>
</thead>
<tbody><tr>
<td align="left">1. 손상된 액세스 제어</td>
<td align="left">- API 액세스 관리 미흡</td>
<td align="left">- CORS 사용 최소화</td>
</tr>
<tr>
<td align="left"></td>
<td align="left"></td>
<td align="left">- JWT 관리</td>
</tr>
<tr>
<td align="left">2. 암호화 실패</td>
<td align="left">- 민감한 정보 Plane Text로 관리</td>
<td align="left">- 민감한 정보 암호화하여 처리, 저장</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">- 취약한 알고리즘, 프로토콜 사용</td>
<td align="left">- 표준 알고리즘 사용, 레거시 프로토콜 X</td>
</tr>
<tr>
<td align="left">3. (SQL) Injection</td>
<td align="left">- 임의의 SQL문 주입해도 동작</td>
<td align="left">- 서버에서 입력값 유효성 검사</td>
</tr>
<tr>
<td align="left"></td>
<td align="left"></td>
<td align="left">- 저장 프로시저 사용</td>
</tr>
<tr>
<td align="left">4. 안전하지 않은 설계</td>
<td align="left">- 데이터 무결성, 기밀성, 신뢰성 있게 비지니스 로직 설계 X</td>
<td align="left">- 보안 소프트웨어 방법론 적용하여 설계</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">- 보안 설계 미흡</td>
<td align="left">- 액세스 제어, 보안 인증, 비지니스 로직 모델링</td>
</tr>
<tr>
<td align="left">5. 보안 구성 오류</td>
<td align="left">- 사용자 오류 처리 미흡</td>
<td align="left">- 서버 정보 노출 최소화</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">- 불필요한 코드, 파일 잔존</td>
<td align="left">- 개발/QA/상용 보안 환경 구성, 관리, 배포하는 시스템 구축</td>
</tr>
<tr>
<td align="left">6. 취약하고 오래된 구성 요소</td>
<td align="left">- 사용하는 구성 요소의 패치, 업데이트 버전 적용, 관리 X</td>
<td align="left">- 정기적인 구성요소 취약점 스캔, 패칭 작업을 수행하고 자동화하여 관리</td>
</tr>
<tr>
<td align="left">7. 식별 및 인증 실패</td>
<td align="left">- 자동화된 로그인 시도를 허용</td>
<td align="left">- 무차별, 자동화 로그인 실패 로그 기록</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">- 취약한 암호를 허용</td>
<td align="left">- 취약한 암호 검사 구현(계정 생성 방해)</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">- URL에 세션 식별자, 인증 토큰 노출</td>
<td align="left">- 세션 식별자, 인증 토큰 URL 노출 X</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">- 로그아웃 후에도 세션 및 토큰 유효</td>
<td align="left">- 로그아웃/유휴 시간 초과 시 인증 무효화</td>
</tr>
<tr>
<td align="left">8. 소프트웨어 및 데이터 무결성 실패</td>
<td align="left">- 무결성 검사, 디지털 서명 미흡</td>
<td align="left">- 디지털 서명 구현</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">- 무결성 검사, 디지털 서명 미흡</td>
<td align="left">- 디지털 서명 구현</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">- 신뢰할 수 없는 구성요소 사용</td>
<td align="left">- 신뢰 가능한 리포지토리 확인 후 구성 요소 업데이트 및 사용</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">- 안전하지 않은 CI/CD 사용</td>
<td align="left">- CI/CD 파이프라인에 접근 제어 설정</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">- 자동 업데이트 활성화 환경</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">9. 보안 기록 및 모니터링 실패</td>
<td align="left">- 액세스 및 트랜잭션 로그 관리 부재</td>
<td align="left">- 로깅 및 모니터링 시스템 구축</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">- 응답 에스컬레이션 프로세스 미흡</td>
<td align="left">- 모니터링 및 경고 알림으로 개발자 대응</td>
</tr>
<tr>
<td align="left"></td>
<td align="left">- 모니터링 및 알림 기능 부재</td>
<td align="left">- 사고 대응 및 복구 계획 수립</td>
</tr>
<tr>
<td align="left">10. 서버사이드 요청 위조</td>
<td align="left">- 서버의 원격 리소스를 URL 접근 허용</td>
<td align="left">- raw response 비허용</td>
</tr>
<tr>
<td align="left"></td>
<td align="left"></td>
<td align="left">- URL scheme, port , destination의 허용 목록 설정, 관리</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[Android SDK Version]]></title>
            <link>https://velog.io/@minjeong-dev/Android-SDK-Version</link>
            <guid>https://velog.io/@minjeong-dev/Android-SDK-Version</guid>
            <pubDate>Mon, 17 Apr 2023 06:45:12 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/minjeong-dev/post/34a45725-dcc0-4fdb-ac36-e9313ef6df2b/image.png" alt="android studio meme"></p>
<p>&quot;안드로이드 앱을 어떤 버전까지 지원할 것인가? 어떤 버전을 기준으로 최적화하였나?&quot;라는 고민은 &quot;Android SDK Version 세팅을 어떻게 할 것인가?&quot;라는 결정 사항으로 이어진다.</p>
<h3 id="buildgradle"><strong>build.gradle</strong></h3>
<pre><code class="language-jsx">android {
    compileSdkVersion 31

    defaultConfig {
        targetSdkVersion 31
    }
}</code></pre>
<h3 id="androidmanifestxml"><strong>AndroidManifest.xml</strong></h3>
<pre><code class="language-xml">&lt;uses-sdk android:minSdkVersion=&quot;integer&quot;
          android:targetSdkVersion=&quot;integer&quot; /&gt;</code></pre>
<h3 id="개념-정리">개념 정리</h3>
<ul>
<li><code>android:minSdkVersion</code><ul>
<li>애플리케이션이 실행하는데 필요한 최소 API 수준 지정하는 정수.</li>
<li>Android 시스템은 시스템의 API 수준이 속성에 지정된 값보다 낮은 경우, 사용자가 애플리케이션을 설치하지 못하도록 제한한다.</li>
</ul>
</li>
<li><code>android:targetSdkVersion</code><ul>
<li>개발자가 테스트 완료한 API 중 가장 최신 버전의 API 수준 지정하는 정수.</li>
<li>최적화된 버전으로 명시하는 값이다.</li>
<li>Android의 새 버전이 출시되었을 때 시스템은 앱이 예상(=개발자가 테스트 완료)한 대로 동작할 수 있게 호환성 동작 처리를 사용한다.</li>
</ul>
</li>
<li><code>compileSdkVersion</code><ul>
<li>어떤 안드로이드 SDK 버전으로 앱을 컴파일 할 것인지 명시하는 정수.</li>
</ul>
</li>
</ul>
<p>→ 결론: minSdkVersion &lt;= targetSdkVersion == compileSdkVersion</p>
<h3 id="android-플랫폼-버전이-지원하는-api-수준">Android 플랫폼 버전이 지원하는 API 수준</h3>
<p><strong>플랫폼 버전 - API 수준</strong>
(2023-03 기준)</p>
<p>Android 13 [Beta]　- API 32 (= T 베타 2)</p>
<p>Android 12　　　　- API 31, 32</p>
<p>Android 11　　　　- API 30</p>
<p>Android 10　　　　- API 29</p>
<p>Android 9 = Pie　　- API 28</p>
<p>…</p>
<h3 id="andrid-os-추정-점유율">Andrid OS (추정) 점유율</h3>
<ul>
<li>Android 9.0 (Pie) = API 28 이상 ⬆️: &gt; 84.5%</li>
<li>Android 8 (Oreo) = API 26 이상 ⬆️: &gt; 91.4%</li>
<li>Android 7 (Nougat) = API 24 이상 ⬆️: &gt; 96.0%</li>
</ul>
<p>출처: <a href="https://www.appbrain.com/stats/top-android-sdk-versions">https://www.appbrain.com/stats/top-android-sdk-versions</a></p>
<h3 id="google-play-앱의-대상-api-수준-요구사항">Google Play 앱의 대상 API 수준 요구사항</h3>
<blockquote>
<p><strong>targetSdkVersion ≥ 31</strong></p>
</blockquote>
<p><a href="https://support.google.com/googleplay/android-developer/answer/11926878">https://support.google.com/googleplay/android-developer/answer/11926878</a></p>
<p>(대상 API 수준 = targetSdkVersion으로 이해함)</p>
<ul>
<li>기존 앱이 targetSdkVersion &lt; 30인 경우 Android 11 이상이 설치된 안드로이드 단말에서는 앱이 더이상 표시되지 않는다. (설치 불가능)</li>
<li>기존 앱이 API 레벨 30 수준 이상을 타겟팅하도록 강제하고 있다.</li>
<li>신규 앱을 게시하기 위해서는 <strong>API 레벨 31 수준 이상</strong>을 타겟팅하도록 제한하고 있다.</li>
</ul>
<hr>
<p><strong>출처</strong></p>
<p><a href="https://developer.android.com/guide/topics/manifest/uses-sdk-element?hl=ko">https://developer.android.com/guide/topics/manifest/uses-sdk-element?hl=ko</a></p>
<p><a href="https://velog.io/@jaeyunn_15/Android-SDK-Version-%EC%84%A4%EC%A0%95%EC%9D%84-%EC%99%9C-%EA%B7%B8-%EB%B2%84%EC%A0%84%EC%9C%BC%EB%A1%9C-%ED%95%A0%EA%B9%8C">https://velog.io/@jaeyunn_15/Android-SDK-Version-설정을-왜-그-버전으로-할까</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JsDoc 사용기]]></title>
            <link>https://velog.io/@minjeong-dev/JsDoc-%EC%82%AC%EC%9A%A9%EA%B8%B0</link>
            <guid>https://velog.io/@minjeong-dev/JsDoc-%EC%82%AC%EC%9A%A9%EA%B8%B0</guid>
            <pubDate>Thu, 02 Feb 2023 14:48:27 GMT</pubDate>
            <description><![CDATA[<p>배포 주소
<a href="https://min-jeong96.github.io/wanted-pre-onboarding-challenge-fe-2/index.html">https://min-jeong96.github.io/wanted-pre-onboarding-challenge-fe-2/index.html</a></p>
<hr>
<h1 id="jsdoc">JsDoc</h1>
<h2 id="block-tags">Block Tags</h2>
<h3 id="classconstructor">@Class(@Constructor)</h3>
<pre><code class="language-js">/**
 * 클래스 설명
 * @constructor
 * @type {Object}
 * @property {number} id - 아이디
 * @property {string} content - 내용
 * @property {boolean} completed - 완료 여부
 * @property {string} category - 카테고리
 * @property {string[]} [tags] - 태그들
 */
function Todo(id, content, completed, category, tags) { }</code></pre>
<ul>
<li><code>@typedef</code>를 사용하여 type을 정의하면 Class가 아닌 Global로 docs가 만들어져서 고민하다가 constructor로 만들었다.</li>
<li>required/optional property는 <code>[&lt;property_name&gt;]</code>으로 작성하면 된다.</li>
</ul>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://jsdoc.app/index.html">JsDoc 공식 문서</a></li>
<li><a href="https://velog.io/@picpal/JSDoc-%EC%A0%95%EB%A6%AC-%EC%84%A4%EC%B9%98">picpal.log - JSDoc 정리</a></li>
<li><a href="https://okayoon.tistory.com/entry/JSDoc%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%84%9C-Javasript-%EB%AC%B8%EC%84%9C%ED%99%94%ED%95%B4%EB%B3%B4%EC%9E%90">성장 블로그:) - JSDoc를 사용해서 Javasript 문서화해보자!</a></li>
<li><a href="https://noogoonaa.tistory.com/37">JSDoc을 설정 파일로 빼서 사용해보도록 합시다</a></li>
</ul>
<hr>
<h1 id="github-pages-이용해-jsdocs-배포">Github Pages 이용해 JsDocs 배포</h1>
<pre><code class="language-js">// package.json
&quot;scripts&quot;: {
  &quot;test&quot;: &quot;echo \&quot;Error: no test specified\&quot; &amp;&amp; exit 1&quot;,
  &quot;docs&quot;: &quot;jsdoc -c jsdoc.json&quot;,
  &quot;deploy&quot;: &quot;gh-pages -d docs&quot; &lt;- 추가
},</code></pre>
<p>Github Pages 기능을 이용한 배포 방법은 구글링을 통해 쉽게 찾을 수 있다. 다만 <code>npm run docs</code> 명령어 수행 후 만들어지는 jsdoc 정적 페이지는 <code>/docs</code>이므로 <code>package.json</code>에 스크립트 명령어를 추가할 때, 경로를 <code>docs</code>로 지정해주어야 한다.</p>
<p>참고</p>
<ul>
<li><a href="https://tlsdnjs12.tistory.com/68?category=1029328">서스포PAR - [GitHub] 깃허브 페이지 + 배포</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React MUI TextField 스타일 적용시키기]]></title>
            <link>https://velog.io/@minjeong-dev/React-MUI-TextField-%EC%8A%A4%ED%83%80%EC%9D%BC-%EC%A0%81%EC%9A%A9%EC%8B%9C%ED%82%A4%EA%B8%B0</link>
            <guid>https://velog.io/@minjeong-dev/React-MUI-TextField-%EC%8A%A4%ED%83%80%EC%9D%BC-%EC%A0%81%EC%9A%A9%EC%8B%9C%ED%82%A4%EA%B8%B0</guid>
            <pubDate>Mon, 30 Jan 2023 15:23:03 GMT</pubDate>
            <description><![CDATA[<p>다크 모드를 지원하는 사이드 프로젝트를 개발하던 도중, <a href="https://mui.com/material-ui/react-text-field/">React MUI의 TextField 컴포넌트</a>를 모드에 따라 색상을 달리 설정하여 사용하고자 스타일을 커스터마이징 하는 방법을 알아내 사용하였다.</p>
<pre><code class="language-jsx">const InputTextField = styled(TextField)({
  &#39;&amp; label&#39;: {
    // placeholder text color
    color: &#39;var(--sub-text)&#39;
  },
  &#39;&amp; label.Mui-focused&#39;: {
    // 해당 input focus 되었을 때 placeholder text color
    // floatng label을 사용할 때 처리 필요하다
    color: &#39;var(--primary)&#39;,
  },
  &#39;&amp; label.Mui-error&#39;: {
    color: &#39;#d32f2f&#39;,
  },
  &#39;&amp; .MuiOutlinedInput-root&#39;: { 
    color: &#39;var(--text)&#39;,
    &#39;&amp; fieldset&#39;: {
      borderColor: &#39;var(--sub-text)&#39;,
    },
  },
});

// component
export function page(props) {
  return (
    &lt;div&gt;
      &lt;InputTextField /&gt;
    &lt;/div&gt;
  );
}</code></pre>
<ul>
<li><code>&lt;TextField /&gt;</code> ui 컴포넌트가 렌더링 된 html을 보면 label로 placeholder가 구현되어 있기 때문에 <code>label</code>에 color를 적용해줘야 했다.</li>
<li>Input의 기본 border color를 변경해주고 싶었는데 fieldset 태그의 스타일링을 바꿔야하는 것이었다. <code>border-color</code>가 아닌 <code>borderColor</code>라는 정해진 key값에 설정해주어야 하는 것이 포인트.</li>
</ul>
<div style='display: flex; max-width: 100%;'>
  <img style='width: 50%' alt='before' src='https://velog.velcdn.com/images/minjeong-dev/post/27b23360-9062-450e-893b-632b33c9845c/image.png' />
  <img style='width: 50%' alt='after'  src='https://velog.velcdn.com/images/minjeong-dev/post/4bca29fc-63df-4488-b8c7-b269df6b184f/image.png' />
</div>
그 결과 다크 모드에서 아예 색상이 묻혀 죽어있던 인풋이 살아났다!]]></description>
        </item>
        <item>
            <title><![CDATA[React Hook이란 무엇인가?]]></title>
            <link>https://velog.io/@minjeong-dev/React-Hook%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@minjeong-dev/React-Hook%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Wed, 18 Jan 2023 02:44:00 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/minjeong-dev/post/bbf1c692-da09-4d82-8c3b-c543b3945ecc/image.png" alt="React hooks meme"></p>
<p>클래스 컴포넌트가 아닌 함수형 컴포넌트로 개발해야 한다는 것을 알게 되었다. (아무것도 모른 채 학습을 시작했던 리액트 튜토리얼의 틱택토 게임은 클래스 컴포넌트 코드를 제공한다.) 그래서 튜토리얼의 모든 컴포넌트를 함수로 리팩토링 하는데, 바로 props/state 데이터를 어떻게 처리해야 하는지에 대한 선행 학습 문제가 바로 따라온다.</p>
<p>그리고 친절히 클래스가 아니어도 상태 값을 관리하며 여러 React 기능을 사용할 수 있도록 지원하는 Hook API 안내가 공식 문서에 작성되어 있었다.</p>
<p>출처 <a href="https://ko.reactjs.org/docs/hooks-intro.html">Reactjs.org, Hook의 개요</a></p>
<hr>
<h1 id="hook">Hook</h1>
<blockquote>
<p>함수 컴포넌트에서 React의 주요 개념(상태관리, 생명주기 기능 등)을 <strong>&quot;연동(hook into)&quot;</strong> 할 수 있게 해준다.</p>
</blockquote>
<ul>
<li>React 16.8.0 / React Native 0.59버전에서부터 Hook을 지원하기 시작했다.</li>
<li>props, state, context, refes, lifecycle과 같은 React 개념에 보다 직관적인 API를 제공한다.</li>
<li>클래스 컴포넌트 안에서는 동작하지 않는다. 클래스로 만들지 않고 React를 사용하게 해주는 것이다.<br />

</li>
</ul>
<h2 id="motivation">Motivation</h2>
<p>&quot;왜 Hook이 등장했을까?&quot;</p>
<ul>
<li><p>기존에는 <em>render props</em>, <em>고차 컴포넌트</em> 패턴으로 컴포넌트 간 재사용 로직을 사용하게 했다. 그러나 이 방법들은 컴포넌트의 재구성을 강요하고 코드의 래핑이 중첩되는 문제를 야기시켰다.</p>
</li>
<li><p>함수형 컴포넌트에 Hook API를 제공함으로써 계층의 변화 없이 상태 관리 등의 React 개념과 관련된 로직을 재사용할 수 있도록 도와준다.</p>
<p><a href="https://ko.reactjs.org/docs/render-props.html"><em>render props</em></a>: 컴포넌트 간 코드를 공유하기 위한 테크닉. 
<a href="https://ko.reactjs.org/docs/higher-order-components.html"><em>고차 컴포넌트</em></a>: 컴포넌트를 parameter로 받아서 새 컴포넌트를 반환하는 함수.</p>
<br />

</li>
</ul>
<h2 id="rules">Rules</h2>
<p>JavaScript 함수이지만 두 가지의 규칙을 준수해야 한다.</p>
<ol>
<li><strong>최상위 레벨에서만 Hook을 호출</strong>할 것. 반복문, 조건문, 중첩 함수 내에서 Hook을 실행시키지 않는다.</li>
<li><strong>React 함수 컴포넌트 내에서만 Hook을 호출</strong>한다. 컴포넌트가 아닌 일반 JavaScript 함수에서는 Hook을 호출하지 않는다. (직접 작성한 Custom Hook에서도 가능.)</li>
</ol>
<p>해당 규칙을 강제하기 위해 <a href="https://www.npmjs.com/package/eslint-plugin-react-hooks">eslint-plugin-react-hooks</a>를 제공하고 있다.</p>
<p>더 읽어보기: <a href="https://ko.reactjs.org/docs/hooks-rules.html">https://ko.reactjs.org/docs/hooks-rules.html</a>
<br /></p>
<h2 id="state-hook">State Hook</h2>
<pre><code class="language-js">function Example() {
  const [count, setCount] = useState(0);
}</code></pre>
<ul>
<li>함수 컴포넌트는 <code>this</code>를 가질 수 없기 때문에 <code>this.state</code>를 할당하거나 읽을 수 없어, <code>useState</code> Hook을 컴포넌트에 호출하여 사용한다. 기능적으로 같다.</li>
<li><code>useState</code>의 parameter는 해당 state의 초기값이다.</li>
<li><code>useState</code>는 state 변수, 해당 변수를 갱신할 수 있는 함수로 이뤄진 쌍을 반환한다. 따라서 <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#%EB%B0%B0%EC%97%B4_%EA%B5%AC%EC%A1%B0_%EB%B6%84%ED%95%B4"><em>구조 분해 할당(destructuring assignment)</em></a>를 이용하면 한 문장으로 된 코드로 선언, 초기화할 수 있는 것이다.<br />

</li>
</ul>
<h2 id="effect-hook">Effect Hook</h2>
<blockquote>
<p>React의 <strong>&quot;Effect&quot;</strong>(=side effect)는 컴포넌트 안에서 데이터를 가져오거나 구독하고, DOM을 직접 조작하는 작업 등의 모든 동작을 뜻한다.</p>
</blockquote>
<ul>
<li><code>useEffect</code>는 함수 컴포넌트 내에서 side effect, 즉 렌더링 이후 어떤 일을 수행할 수 있게 해준다. (ex. 데이터 가져오기, API 불러내기 등)</li>
<li>클래스 컴포넌트의 <code>componentDidMount</code>, <code>componentDidUpdate</code>, <code>componentWillUnmount</code>와 같은 목적이나 하나의 API로 통합되었다.</li>
<li><code>useEffect</code>는 컴포넌트 안에 선언되어 있으므로 props/state에 접근 가능하다.</li>
</ul>
<h3 id="useeffect를-컴포넌트-안에서-불러내는-이유">useEffect를 컴포넌트 안에서 불러내는 이유</h3>
<ul>
<li>컴포넌트 내부에 둠으로써 props/state의 값에 접근할 수 있다. 함수 범위 안에 존재하므로 특별한 API 없이 가능한 것이다.</li>
<li>JavaScript의 Closure를 이용하여 문제를 해결하는 방법이다.<ul>
<li><a href="https://poiemaweb.com/js-closure">PoiemaWeb, Closure</a> 읽어보기</li>
</ul>
</li>
</ul>
<h3 id="정리clean-up를-이용하는-effects">정리(clean-up)를 이용하는 Effects</h3>
<ul>
<li>정리가 필요한 effect의 가장 대표적인 예시; 외부 데이터를 구독(subscription)해야하는 경우 subscribe 이후 컴포넌트가 제거될 때 unsubscribe 처리가 필요하다.</li>
<li>클래스 컴포넌트에서는 <code>componentDidMount</code>에서 구독을 설정하고 <code>componentWillUnmount</code>에서 구독을 해제하는 방식으로 구현할 것이다.</li>
<li>하지만 Hook을 이용할 경우, <strong>effect가 함수를 반환하면</strong> React는 그 함수를 정리가 필요할 때, 즉 컴포넌트의 생명주기가 끝날 때 실행시킨다.</li>
<li>공식 문서의 예제에서는 <code>cleanup()</code>이라는 이름의 함수를 반환했으나, 다른 이름으로 작성하거나 화살표 함수로 반환해도 무관하다고 한다.</li>
</ul>
<pre><code class="language-js">function Example(props) {
  const [isOnline, setIsOnline] = useState(null);

  function handleChatStatusChange(status) {
      setIsOnline(status.isOnline);
  }

  useEffect(() =&gt; {
    ChatAPI.subscribeChatStatus(props.id, handleChatStatusChange);

    // clean-up
    return function cleanup() {
      ChatAPI.unsubscribeChatStatus(props.id, handleChatStatusChange);
    }
  });

  if (isOnline === null) {
    return &#39;Loading...&#39;;
  }

  return isOnline ? &#39;Online&#39; : &#39;Offline&#39;;
}</code></pre>
<h4 id="react가-effect를-정리clean-up하는-시점이란">React가 effect를 정리(clean-up)하는 시점이란?</h4>
<blockquote>
<p>React는 컴포넌트가 마운트 해제될 때 정리를 실행한다.</p>
</blockquote>
<h3 id="useeffect는-렌더링-이후-매번-수행된다">useEffect는 렌더링 이후 매번 수행된다.</h3>
<ul>
<li>기본적으로 첫번째 렌더링과 이후의 모든 업데이트에서 수행된다.
(첫번째 렌더링이란 JSX 코드의 렌더링을 말하는 게 아닐까.)</li>
<li><em>effects scheduled with <code>useEffect</code> don&#39;t block the browser from updating the screen.</em>: 한국어로 된 공식 문서의 문장이 괜히 더 헷갈리는 것 같아 원문 첨부. 아마 effect 내 코드를 수행하는 동안 일어나는 브라우저의 화면 렌더링 작업이 비동기로 계속 이루어질 수 있다는 뜻 같다.</li>
</ul>
<h4 id="리렌더링-조건으로-성능-최적화">리렌더링 조건으로 성능 최적화</h4>
<ul>
<li>특정 값들이 변경된 렌더링 이후에만 effect가 실행되도록 조건을 걸 수 있다.</li>
<li><code>useEffect</code>의 두 번째(선택적) parameter로 배열을 작성한다.</li>
</ul>
<p>(더 공부하고 이해해야 하는 사항)</p>
<ul>
<li>컴포넌트 범위 내에서 바뀌는 값, effect에 의해 사용되는 값을 모두 포함한다.</li>
<li>effect를 실행하고 정리(clean-up)하는 과정을 딱 한 번만 실행하고 싶다면 빈 배열([])을 두 번째 인수로 넘겨준다.</li>
<li><code>exhaustive-deps</code> 규칙을 <code>eslint-plugin-react-hooks</code> 패키지에 포함하면 의존성이 바르지 않게 지정되었을 때 경고해준다.</li>
</ul>
<br/>

<h2 id="etc">etc.</h2>
<h3 id="usecontext">useContext()</h3>
<h3 id="usereducer">useReducer()</h3>
<hr>
<p><a href="https://ko.reactjs.org/docs/hooks-rules.html">Hooks API Reference</a> 공식 문서로 공부할 것.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React Router]]></title>
            <link>https://velog.io/@minjeong-dev/React-Router</link>
            <guid>https://velog.io/@minjeong-dev/React-Router</guid>
            <pubDate>Tue, 17 Jan 2023 18:09:29 GMT</pubDate>
            <description><![CDATA[<p>간단한 사이트를 하나 구현해보면서 필요한 기능을 찾아 학습하는 게 좋을 것 같아 냅다 튜토리얼 이후 새 프로젝트를 시작해봤다. 일단 사이트이니 라우팅 기능이 필요했는데, 어째서인지 구글링 결과 2019년과 2021년의 React Route 코드가 다르고 내 코드에서는 에러만 잔뜩 뱉거나 아무 에러 없이 화면이 렌더링되지 않아 텅 비어버리는 게 아니겠는가?!</p>
<p>그래서 결국 쉬운 길을 가려다 길을 잃었다.
영어에 눈이 조금 흐려지는 것 같지만 공식 문서로 왔다.</p>
<hr>
<h3 id="파악한-react-v6에서의-라우팅-방법">파악한 React (v6)에서의 라우팅 방법</h3>
<ol start="0">
<li><p><code>react-router-dom</code> 설치한다.</p>
<pre><code class="language-bash">npm i react-router-dom</code></pre>
<p>당연한 것이지만 예제 코드를 읽으면서 쓰고 나서 <code>npm start</code> 했다가 모듈 못 찾았다는 콘솔 에러를 보고 호다닥 설치 해주었다. <code>react-dom</code>과 달리 <code>create-react-app</code>으로 프로젝트를 생성했을 때 <code>node_modules</code>에 설치되는 기본 모듈이 아닌가보다.</p>
<br>
</li>
<li><p><code>&lt;Router&gt;</code> 안에 <code>&lt;Routes&gt;</code>, 그 안에 각 필요한 <code>&lt;Route&gt;</code>를 작성한다.</p>
</li>
</ol>
<pre><code class="language-jsx">import { BrowserRouter as Router, Routes, Route } from &#39;react-router-dom&#39;;

function MainRouter(props) {
  return (
    &lt;Router&gt;
      &lt;Routes&gt;
        &lt;Route
          path=&quot;/main&quot;
          element={&lt;Example /&gt;} /&gt;
      &lt;/Routes&gt;
    &lt;/Router&gt;
  );
}</code></pre>
<p><code>&lt;Switch&gt;</code>라는 것으로 래핑한 코드를 봤는데 그건 4인지 5인지 모르겠으나 현재(v6)에는 &#39;react-router-dom&#39;에서 import도 안 되는 것이었다. <code>&lt;Route&gt;</code>의 <code>element</code>로는 함수형 컴포넌트의 <code>return()</code>에 들어갈 렌더링될 jsx를 넣어주면 된다.
<br></p>
<ol start="2">
<li><code>useParams</code>를 이용하면 URI의 parameter를 읽어 사용 가능하다.<pre><code class="language-jsx">import { BrowserRouter as Router, Routes, Route, useParams } from &#39;react-router-dom&#39;;
</code></pre>
</li>
</ol>
<p>function MainRouter(props) {
  return (
    <Router>
      <Routes>
        &lt;Route
          path=&quot;/:param1&quot;
          element={<Example />} /&gt;
      </Routes>
    </Router>
  );
}</p>
<p>function Example(props) {
  const { param1 } = useParams();</p>
<p>  return (
      <div>param: {param1}</div>
  )
}</p>
<pre><code>&lt;br&gt;

3. ```errorElement```를 이용하여 페이지 에러 핸들링을 할 수 있다.
- 공식 문서에 &quot;(!) DANGER: This feature only works if using a data router like _createBrowserRouter_&quot; 라는 문장이 함께 작성되어 있고 실제로 이 생성 코드를 넣어주지 않았더니 동작하지 않고 있다. ```create-browser-router```를 함께 사용해야만 동작하는 것으로 이해가 된다.

  ```index.js```에서 ```&lt;RouterProvider /&gt;```를 이용하여 ```create-browser-router```로 생성한 라우터를 root element에 넣어주었다.

  https://reactrouter.com/en/main/route/error-element
  https://reactrouter.com/en/main/routers/create-browser-router

---

### React Router (v6.4)

출처는 [React Router, Picking a Router](https://reactrouter.com/en/main/routers/picking-a-router)

(v6.4) 기준 세 가지 종류의 라우터가 있다.
- ```createBrowserRouter```
- ```createMemoryRouter```
- ```createHashRouter```
&lt;br&gt;
- 웹 프로젝트에는 ```createBrowserRouter```를 추천한다.
  - hash url이 아닌 full url을 사용한다.
  - full url은 SEO(검색최적화), SSR(서버-사이드 렌더링)에 좋으며 웹 플랫폼에 호환 가능하다.
- _full url을 사용할 수 없는 경우 ```createHashRouter```를 추천한다?_
- 컴포넌트를 테스트할 때 ```createMemoryRouter```를 사용하는 것이 가장 쉬울 것이다. _(DOM History API를 요구하는 사이트에 사용된 라우터와 다르게?)_

#### createBrowserRouter

&gt; This is the recommended router for all React Router web projects. It uses the [DOM History API](https://developer.mozilla.org/en-US/docs/Web/API/History) to update the URL and manage the history stack.

```jsx
import { createRoot } from &#39;react-dom/client&#39;;
import {
  createBrowserRouter,
  RouterProvider
} from &#39;react-router-dom&#39;;

import { Main } from &#39;./pages/main.js&#39;;
import { Sub1 } from &#39;./pages/sub1.js&#39;;
import { Sub2 } from &#39;./pages/sub2.js&#39;;
import { ErrorPage } from &#39;./pages/error.js&#39;;

const router = createBrowserRouter([
  {
    path: &#39;/&#39;,
    element: &lt;Main /&gt;,
    errorElement: &lt;ErrorPage /&gt;,
    children: [
      {
        path: &#39;/sub1&#39;,
        element: &lt;Sub1 /&gt;,
      },
      {
        path: &#39;/sub2&#39;,
        element: &lt;Sub2 /&gt;,
      },
      // ...
    ]
  }
]);

const root = createRoot(document.getElementById(&#39;root&#39;));
root.render(&lt;RouterProvider router={router} /&gt;);</code></pre><ul>
<li><code>routes</code><ul>
<li><code>route</code> object의 배열.</li>
<li><code>route</code> object는 <code>children</code> property로 <code>route</code> 배열을 가질 수 있다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Props/State]]></title>
            <link>https://velog.io/@minjeong-dev/PropsState</link>
            <guid>https://velog.io/@minjeong-dev/PropsState</guid>
            <pubDate>Tue, 17 Jan 2023 12:22:00 GMT</pubDate>
            <description><![CDATA[<h2 id="props--state">Props &amp; state</h2>
<ul>
<li>React에서 다루는 데이터의 개념.</li>
<li>동일한 데이터라고 하더라도 데이터를 생성한 컴포넌트는 그 데이터를 state라고 하지만 그 데이터를 전달 받은 컴포넌트는 props로 본다?</li>
</ul>
<pre><code class="language-javascript">class Square extends React.Component {
  constructor(props) {
    super(props); // 서브클래스의 생성자를 정의 시 super() 명시적으로 호출 필요
    this.state = {
      value: null,
    };
  }

  render() {
    return (
      &lt;button className=&quot;square&quot; onClick={() =&gt; this.setState({value: this.props.value})}&gt;
        {this.state.value}
      &lt;/button&gt;
    );
  }
}</code></pre>
<h3 id="props">props</h3>
<ul>
<li>부모 컴포넌트로부터 전달받은 데이터.</li>
<li>state 뿐만 아니라 메서드도 전달 가능하다고 한다.</li>
</ul>
<h3 id="state">state</h3>
<ul>
<li>현재 컴포넌트에서 생성, 변할 수 있는 데이터.</li>
<li>state는 <strong>오직 state가 생성된 컴포넌트 내에서만 변경</strong>이 가능하다.</li>
<li>class 내부에 state라는 프로퍼티를 하나 생성하여 사용할 수 있다.</li>
<li>여러 하위 컴포넌트로부터 데이터를 모으거나, 여러 하위 컴포넌트들이 통신하기를 원한다면 데이터를 상위 컴포넌트의 state로 이동시킨다. 그러면 props를 통해 하위 컴포넌트로 state를 전달해주므로, 동기될 수 있다.</li>
</ul>
<p>props, state 관련 출처: <a href="https://ljh86029926.gitbook.io/coding-apple-react/1/props-and-state">https://ljh86029926.gitbook.io/coding-apple-react/1/props-and-state</a></p>
<h2 id="react-hook">React Hook</h2>
<h3 id="usestate">useState</h3>
<pre><code class="language-jsx">function Example() {
  const [count, setCount] = useState(0);

  return (
    &lt;button onClick={() =&gt; setCount(count + 1)}&gt;&lt;/button&gt;
  );
}</code></pre>
<ul>
<li>함수 컴포넌트 안에서 React State를 사용할 수 있게 해준다.</li>
<li>클래스 컴포넌트의 this.state가 제공하는 기능과 똑같다.</li>
<li><code>useState()</code>의 parameter 값은 state 값의 초기 값이다.</li>
<li><code>useState()</code>는 state 변수와 해당 변수를 갱신할 수 있는 함수(set) 쌍을 반환한다.</li>
</ul>
<p>출처 <a href="https://ko.reactjs.org/docs/hooks-intro.html">https://ko.reactjs.org/docs/hooks-intro.html</a></p>
<hr>
<h2 id="불변성">불변성</h2>
<h3 id="state의-데이터를-직접-변경하지-않는-이유">state의 데이터를 직접 변경하지 않는 이유</h3>
<ul>
<li>변수의 값을 직접 변경하지 않고, 해당 변수의 값을 복사한 후 변경하여 데이터를 대체한다.</li>
<li>실제 데이터를 직접 변경하여도 결과적으로는 다를 게 없다.</li>
<li>하지만 컴포넌트, 전체 애플리케이션의 <strong>성능</strong>을 향상시킬 수 있다.</li>
</ul>
<h4 id="react에서-언제-다시-렌더링할지-결정하기">React에서 언제 다시 렌더링할지 결정하기</h4>
<ul>
<li>불변성의 가장 큰 장점 중 하나로, <em>간단한 순수 컴포넌트들이 다시 렌더링될 때를 결정하기가 쉬워진다?</em></li>
<li><code>shouldComponentUpdate()</code>에 대해 더 알아볼 것.</li>
</ul>
<p>읽어보기 <a href="https://ko.reactjs.org/docs/optimizing-performance.html#shouldcomponentupdate-in-action">shouldcomponentupdate-in-action</a></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드 면접 준비]]></title>
            <link>https://velog.io/@minjeong-dev/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%A9%B4%EC%A0%91-%EC%A4%80%EB%B9%84</link>
            <guid>https://velog.io/@minjeong-dev/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%A9%B4%EC%A0%91-%EC%A4%80%EB%B9%84</guid>
            <pubDate>Tue, 10 Jan 2023 04:31:43 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/minjeong-dev/post/b6ee82b4-f952-443d-ab35-2aa3c605d1e1/image.png" alt="developer between reality and &#39;Linked-In&#39;"></p>
<h1 id="웹-프론트엔드-관련">웹 프론트엔드 관련</h1>
<h2 id="pwa-프로그레시브-웹-앱">PWA, 프로그레시브 웹 앱</h2>
<ul>
<li>웹과 네이티브 앱의 기능 모두의 이점을 갖도록 수 많은 특정 기술과 표준 패턴을 사용해 개발된 웹 앱.</li>
<li>html, css, javascript와 같은 웹 기술로 만든 앱.</li>
</ul>
<p>출처 <a href="https://blog.wishket.com/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%A0%88%EC%8B%9C%EB%B8%8C-%EC%9B%B9-%EC%95%B1pwa%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B4%EB%A9%B0-%EC%99%9C-%ED%95%84%EC%9A%94%ED%95%9C%EA%B0%80/">PWA이란 무엇이며 왜 필요한가</a>
출처 <a href="https://developer.mozilla.org/ko/docs/Web/Progressive_web_apps/Introduction">MDN PWA</a></p>
<h2 id="브라우저">브라우저</h2>
<h3 id="브라우저-렌더링">브라우저 렌더링</h3>
<ul>
<li>클라이언트가 도메인을 웹 브라우저에 입력해서 서버로부터 HTML, CSS, script 파일 등을 전달받는다.</li>
<li>웹 엔진의 HTML/XML Parser가 문서를 파싱해서 HTML -&gt; DOM Tree, CSS -&gt; CSSOM Tree를 만든다.</li>
<li>DOM Tree + CSSOM Tree -&gt; 페이지를 렌더링하는 데 필요한 Render Tree를 만든다.</li>
<li>CSS 스타일 규칙이 적용되도록 위치, 크기 등의 모든 스타일링을 적용시킨다(Layout).</li>
<li>렌더 트리의 노드를 실제 픽셀로 그린다(Paint).</li>
</ul>
<h4 id="script-태그">script 태그</h4>
<p>script 태그를 만나게 되면 JS 코드를 실행하기 위해 HTML/CSS 파싱을 중단한다고 한다. 외부 스크립트 참조를 위한 script 태그에 <code>async</code> 속성을 명시하여 브라우저가 페이지를 파싱하는 동안에도 스크립트가 실행되도록 하거나, <code>defer</code> 속성을 명시하여 브라우저가 페이지 파싱을 끝내고 나서 스크립트가 실행되도록 할 수 있다. 둘 다 명시하지 않을 경우 파싱 중 만난 script 태그의 스크립트를 받고 실행시키느라 브라우저의 파싱을 중단하므로 사용자에겐 화면이 지연되게 된다.</p>
<h3 id="검색-엔진-최적화-seo">검색 엔진 최적화 SEO</h3>
<ul>
<li>검색 엔진에 웹 사이트를 검색했을 때 그 결과를 페이지 상단에 노출시켜 많은 사람이 볼 수 있도록 최적화 하는 방법.</li>
<li>캐노니컬 설정, 메타 설정, 페이지 속도 개선, 사이트맵 관리 등이 있다.</li>
<li>캐노니컬 설정: <code>&lt;link rel=&quot;canonical&quot; href=&quot;...&quot;/&gt;</code></li>
<li>메타 설정: html 파일의 <code>&lt;meta&gt;</code> 태그 작성</li>
<li>사이트맵 관리: sitemap.xml을 정기적으로 관리할 것.</li>
</ul>
<h3 id="웹-브라우저-캐시">웹 브라우저 캐시</h3>
<p>(캐시: 데이터의 임시 저장소)</p>
<ul>
<li>쿠키<ul>
<li>만료기한이 있는 Key-Value 저장소.</li>
<li>4KB까지 데이터 저장할 수 있고, 만료기한 지정 가능.</li>
<li>httponly 옵션을 설정하여야 document.cookie로 정보를 읽을 수 없게 할 수 있다.</li>
<li>서버/클라이언트 모두 만료기한 지정 가능하나 보통 서버에서 지정한다.</li>
</ul>
</li>
<li>로컬 스토리지<ul>
<li>만료기한이 없는 Key-Value 저장소.</li>
<li>10MB까지 데이터 저장할 수 있고, 도메인 단위로 저장/생성 가능.</li>
<li>브라우저를 닫았다가 켜도 유지.</li>
<li>클라이언트에서만 수정 가능.</li>
</ul>
</li>
<li>세션 스토리지<ul>
<li>만료기한이 없는 Key-Value 저장소.</li>
<li>5MB까지 데이터 저장할 수 있고, 브라우저 탭 단위로 세션 스토리지를 생성.</li>
<li>탭을 닫을 때 데이터 삭제.</li>
<li>클라이언트에서만 수정 가능.</li>
</ul>
</li>
</ul>
<h3 id="멀티프로세싱">멀티프로세싱</h3>
<ul>
<li>브라우저 프로세스: 주소 표시줄, 북마크 바, 뒤로/앞으로 가기 버튼 등의 기능 제공. 네트워크 요청이나 파일 접근 등의 권한 담당.</li>
<li>렌더러 프로세스: 웹 사이트 출력의 모든 과정 제어.</li>
<li>플러그인 프로세스: 웹 사이트에서 사용하는 플러그인 제어.</li>
<li>GPU 프로세스: GPU 이용해서 화면에 그리는 부분 제어.</li>
</ul>
<h2 id="restful-api">RESTful API</h2>
<ul>
<li>RESTful API: 두 컴퓨터 시스템이 인터넷을 통해 정보를 안전하게 교환하기 위해 사용하는 인터페이스. </li>
<li>API: Application Programming Interface. 다른 소프트웨어 시스템과 통신하기 위해 따라야 하는 규칙.</li>
<li>REST: Representational State Transfer(REST). 클라이언트-서버 구현을 독립적으로 사용하는 아키텍처 스타일. REST는 통신에 HTTP 프로토콜을 사용한다. </li>
</ul>
<h3 id="rest-api">REST API</h3>
<ul>
<li>HTTP 요청을 통해 통신하여 데이터 생성, 읽기, 업데이트 및 삭제 기능(CRUD)을 수행.<ul>
<li>POST — 리소스 생성</li>
<li>GET — 리소스 가져오기</li>
<li>PUT — 리소스 업데이트</li>
<li>DELETE — 리소스를 삭제합니다.</li>
</ul>
</li>
</ul>
<p>출처 <a href="https://appmaster.io/ko/blog/rest-apiran-mueosimyeo-dareun-yuhyeonggwa-eoddeohge-dareungayo">REST API</a></p>
<h2 id="javascript">JavaScript</h2>
<h3 id="typescript">TypeScript</h3>
<h4 id="javascript-vs-typescript">javascript vs typescript</h4>
<ul>
<li>typescript 컴파일러를 사용하여 .ts -&gt; .js file로 변환하게 된다.</li>
<li>정적 타입을 지원하므로 이에 대한 오류를 발견할 수 있다.</li>
<li>클래스 기반 객체 지향 프로그래밍 언어로 상속, 캡슐화 및 생성자를 지원한다.</li>
</ul>
<h4 id="type-vs-interface">type vs interface</h4>
<ul>
<li>type과 interface는 </li>
<li>interface는 객체에만 사용이 가능하다.</li>
</ul>
<p>읽어보기 <a href="https://yceffort.kr/2021/03/typescript-interface-vs-type">typescript interface vs type</a></p>
<hr>
<h1 id="cs-관련">CS 관련</h1>
<h2 id="network">Network</h2>
<h3 id="osi-7계층">OSI 7계층</h3>
<ul>
<li>Application</li>
<li>Presentation</li>
<li>Session</li>
<li>Transport</li>
<li>Network</li>
<li>Data Link</li>
<li>Physical</li>
</ul>
<h3 id="tcpip-4계층">TCP/IP 4계층</h3>
<ul>
<li>PDU 캡슐화: (Application) Message -&gt; Segment/Datagram -&gt; Packet -&gt; Frame<ul>
<li>PDU: Protocol Data Unit, 계층 간 데이터가 전달될 때의 단위</li>
</ul>
</li>
<li>Application: Application + Presentation + Session<ul>
<li>사용자에게 서비스를 제공하고, 사용자는 응용 프로그램을 사용하는 프로토콜 계층</li>
<li>HTTP(웹), SMTP(전자메일 전송), SSH(암호화), DNS(도메인 네임&lt;-&gt;IP주소 매핑), FTP(파일 전송)</li>
</ul>
</li>
<li>Transport = Transport<ul>
<li>송신자/수신자, 서버/클라이언트를 연결하는 통신 서비스를 제공하는 프로토콜 계층.</li>
<li>TCP, UDP, QUIC</li>
<li>TCP: 패킷 사이의 순서를 보장한다. 연결 지향 프로토콜(3-Way HandShaking), SYN/ACK NUMBER를 이용한다. 신뢰성 있는 데이터 전달. 연결 해제(4-WAY HandShaking), FIN/ACK.</li>
<li>UDP: </li>
</ul>
</li>
<li>Internet = Network<ul>
<li>장치로부터 받은 네트워크 패킷을 IP 주소로 지정된 목적지에 전송하는 계층.</li>
<li>상대방이 제대로 받았는지 보장하지 않는 비연결형적 특징.</li>
<li>IP, ICMP</li>
</ul>
</li>
<li>Link = Data Link + Physical<ul>
<li>전선, 광섬유, 무선 등 실질적으로 데이터를 전달하며 장치 간에 신호를 주고받는 &#39;규칙&#39;을 정하는 계층.</li>
<li>Ethernet</li>
</ul>
</li>
</ul>
<h2 id="운영체제">운영체제</h2>
<p>사용자가 컴퓨터를 쉽게 다루게 해주는 인터페이스.</p>
<h3 id="운영체제의-역할">운영체제의 역할</h3>
<ul>
<li>CPU 스케줄링, 프로세스 관리</li>
<li>메모리 관리</li>
<li>디스크 파일 관리</li>
<li>I/O 디바이스 관리</li>
</ul>
<h3 id="운영체제의-구조">운영체제의 구조</h3>
<ul>
<li>GUI</li>
<li>시스템콜: 운영체제가 커널에 접근하기 위한 인터페이스. 커널 함수 호출할 때 사용.</li>
<li>커널</li>
<li>드라이버: 하드웨어 제어 소프트웨어</li>
</ul>
<h3 id="메모리">메모리</h3>
<h4 id="메모리-계층">메모리 계층</h4>
<p>속도 빠름 ---------------------------------------------------------&gt; 속도 낮음
레지스터(CPU) - 캐시(L1, L2) - RAM:주기억장치 - HDD/SDD:보조기억장치 
용량 작음 ---------------------------------------------------------&gt; 용량 큼</p>
<h4 id="가상-메모리">가상 메모리</h4>
<ul>
<li>메모리 관리 기법의 하나.</li>
<li>메모리 자원을 추상화하여 메모리의 활용성 높이는 것이 목적.</li>
</ul>
<h4 id="페이지-폴트-page-fault">페이지 폴트 Page Fault</h4>
<ul>
<li>프로세스의 주소 공간에는 존재하지만 RAM에 없는 데이터에 접근할 때 발생.</li>
<li>물리 기억장치부터, 혹은 RAM에서부터 해당 페이지를 가져와 동작한다.</li>
<li>Page vs Frame: 가상 메모리 최소 단위 &lt;-&gt; 실제 메모리 최소 단위</li>
</ul>
<h4 id="페이지-교체-알고리즘">페이지 교체 알고리즘</h4>
<ul>
<li>FIFO: 캐시에 올라온지 가장 오래된 페이지를 교체한다.</li>
<li>LRU: Least Recentle Use, 캐시에서 사용한지 가장 오래된 페이지를 교체한다.<ul>
<li>해시 테이블과 이중 연결 리스트로 구현한다고 한다.</li>
</ul>
</li>
<li>LFU: Least Frequently Use, 캐시에서 가장 적게 사용된 페이지를 교체한다.</li>
</ul>
<h3 id="프로세스">프로세스</h3>
<h4 id="프로그램-프로세스와-스레드">프로그램, 프로세스와 스레드</h4>
<ul>
<li>프로그램: 파일 시스템에 존재하는 실행 파일.</li>
<li>프로세스: 프로그램의 인스턴스. 컴퓨터에서 &quot;실행되고 있는&quot; 프로그램. CPU 스케줄링의 대상.</li>
<li>스레드: 프로세스의 실행 가능한 가장 작은 단위. 프로세스 내 작업의 흐름.</li>
</ul>
<h2 id="데이터베이스">데이터베이스</h2>
<ul>
<li>DataBase: 일정한 규칙, 규약을 통해 구조화되어 저장되는 데이터.</li>
<li>DBMS: 데이터베이스를 제어, 관리하는 통합 시스템. 쿼리 언어를 통해 CRUD 수행 가능.</li>
<li>엔티티 -&gt; 릴레이션: 여러 속성을 가진 정보 대상이 DB의 저장 단위가 된다.<ul>
<li>ex. 이름/아이디/전화번호를 가진 회원 -&gt; TABLE_USER(NAME, ID, TEL)</li>
<li>관계형 DB에서는 &#39;테이블&#39;이 되고, NoSQL DB에서는 &#39;컬렉션&#39;이 된다.</li>
</ul>
</li>
</ul>
<h3 id="erd-entity-relationship-diagram">ERD, Entity Relationship Diagram</h3>
<ul>
<li>릴레이션 간의 관계를 정의한 것.</li>
<li>DB를 구축할 때 가장 기초적인 뼈대 역할이 된다.</li>
<li>시스템의 요구 사항을 기반으로 작성된다.</li>
</ul>
<h3 id="정규화-db-normalization">정규화 DB Normalization</h3>
<ul>
<li>릴레이션 간의 잘못된 종속 관계로 인한 이상 현상을 해결하거나, 저장 공간을 효율적으로 사용하기 위해서 등의 목적으로 릴레이션을 여러 개로 분리하는 것.</li>
<li>정규형 원칙을 기반으로 만들어가며 1NF, 2NF, 3NF, BCNF 등이 있다.</li>
</ul>
<h3 id="트랜잭션-transaction">트랜잭션 Transaction</h3>
<ul>
<li>DB에서 하나의 논리적 기능을 수행하기 위한 작업의 단위.</li>
<li>여러 개의 쿼리를 묶은 단위.</li>
</ul>
<h4 id="데이터-무결성">데이터 무결성</h4>
<p>데이터의 정확성, 일관성, 유효성을 유지하는 것을 말한다.</p>
<h4 id="acid">ACID</h4>
<ul>
<li>A, Atomicity = 원자성<ul>
<li>트랜잭션의 모든 명령은 데이터베이스에 모두 반영되거나, 전혀 반영되지 않아야 한다.</li>
<li>&quot;all or nothing&quot;</li>
<li>수행 중에 오류가 생긴다면 전부 취소시키고 롤백되어야한다.</li>
<li>커밋: 여러 쿼리가 성공적으로 처리되었다고 확정하는 명령어.<ul>
<li>커밋이 수행되었다 = 하나의 트랜잭션이 성공적으로 수행되었다</li>
<li>커밋 종료 이후 DB에 영구 저장된다.</li>
</ul>
</li>
<li>롤백: 에러나 여러 이슈가 발생할 경우 커밋 시작 이전으로 돌리는 것.</li>
<li>커밋과 롤백 덕분에 데이터의 무결성이 보장된다.</li>
</ul>
</li>
<li>C, Consistency = 일관성<ul>
<li>허용된 방식으로만 데이터를 변경해야 한다.</li>
<li>트랜잭션의 작업 처리 결과가 항상 일관되어야 한다는 뜻이다.</li>
</ul>
</li>
<li>I, Isolation = 격리성<ul>
<li>트랜잭션 수행 시 어떤 트랜잭션이 다른 트랜잭션의 연산에 끼어들 수 없다.</li>
<li>복수의 병렬 트랜잭션은 서로 격리되어 마치 순차적으로 실행되는 것처럼 작동되어야 한다.</li>
<li>수행 중인 트랜잭션이 완전히 종료될 때까지 다른 트랜잭션에서는 DB 데이터를 참조할 수 없다.</li>
<li>동시성과 격리성은 반비례하게 된다.</li>
</ul>
</li>
<li>D, Durability = 지속성<ul>
<li>성공적으로 수행된 트랜잭션은 영원히 반영되어야 한다.</li>
</ul>
</li>
</ul>
<h3 id="rdbms-관계형-데이터베이스">RDBMS, 관계형 데이터베이스</h3>
<ul>
<li>행과 열을 가지는 표 형식 데이터를 저장하는 DB.</li>
<li>SQL이라는 언어를 사용해 조작한다.</li>
</ul>
<h3 id="index">Index</h3>
<ul>
<li>추가적인 공간을 활용하여 DB 검색 속도를 향상시키는 자료구조.</li>
<li>책의 목차와 같은 역할로, 인덱스를 만들어 둔 경우 먼저 인덱스에서 조회한 후 데이터의 물리적 주소를 접근해 가져오기 때문에 검색 속도가 향상된다.</li>
<li>조건 검색(Where)에서도 Full Table Scan을 하지 않고 정렬된 인덱스 테이블에서 조회하므로 검색 속도가 빠르다.</li>
<li>그러나 정렬된 상태를 계속 유지시켜야 하는 비용이 소모된다. INSERT/UPDATE/DELETE로 값이 바뀌면 다시 정렬해야 하는 문제가 있다.</li>
<li>테이블의 전체 데이터 중 10-15% 이하의 데이터를 처리하는 경우에만 효율젖ㄱ이라고 한다.</li>
</ul>
<h3 id="join">Join</h3>
<ul>
<li>Inner Join: A∩B, 왼/오 두 테이블의 행 중 Join 조건을 양쪽에 부합하는 행만 표기</li>
<li>Left Outer Join: A, 왼쪽 테이블의 모든 행이 결과에 표기</li>
<li>Right Outer Join: B, 오른쪽 테이블의 모든 행이 결과에 표기</li>
<li>Full Outer JoinL A∪B, 왼/오 두 테이블의 모든 행을 표기 (Join 조건 만족하지 않아도)</li>
</ul>
<h2 id="자료구조알고리즘">자료구조/알고리즘</h2>
<h3 id="시간-복잡도">시간 복잡도</h3>
<p>주어진 문제를 해결하기 위한 연산 횟수.
효율적인 코드로 개선하는 데 쓰이는 척도가 된다.</p>
<ul>
<li>Big-O: Worst Case, 최악의 연산 횟수 표기</li>
<li>Big-Theta: Average Case, 보통의 연산 횟수 표기</li>
<li>Big-Omega: Best Case, 최선의 연산 횟수 표기</li>
</ul>
<h4 id="정렬-알고리즘-별-시간-복잡도">정렬 알고리즘 별 시간 복잡도</h4>
<ul>
<li>삽입 정렬: O(n^2)</li>
<li>선택 정렬: O(n^2)</li>
<li>버블 정렬: O(n^2)</li>
<li>퀵 정렬: O(n log n) &lt;- 실제로는 O(n^2)이나 pivot을 잘 설정한다고 하면 평균적으로</li>
<li>힙 정렬: O(n log n)</li>
<li>병합 정렬: O(n log n)</li>
</ul>
<h4 id="자료구조-별-시간-복잡도">자료구조 별 시간 복잡도</h4>
<ul>
<li>배열: index로 접근하므로 읽고쓰기는 O(1), 탐색과 삽입/삭제는 O(n)</li>
<li>스택: push/pop이므로 삽입/삭제는 O(1), 읽고쓰기와 탐색은 O(n)</li>
<li>큐: enqueue/dequeue이므로 삽입/삭제는 O(1), 읽고쓰기와 탐색은 O(n)</li>
<li>double linked list: first/last node에서 접근 가능하므로 삽입/삭제는 O(1), 읽고쓰기와 탐색은 O(n)</li>
</ul>
<p>(ㅋㅅㅋ 이전 회사 면접에서 상무님이 꼭 하신다고 했던 질문!)
Q. 스택과 큐의 차이, 두 자료구조의 사용 예시
A. 스택은 LIFO, 큐는 FIFO. 스택은 함수 호출, 웹 브라우저 방문 기록 등에 쓰인다. 큐는 CPU의 프로세스/스레드 자원 할당을 대기하는 Ready Queue로 사용되는 예시가 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[디자인 패턴과 프로그래밍 패러다임]]></title>
            <link>https://velog.io/@minjeong-dev/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84</link>
            <guid>https://velog.io/@minjeong-dev/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84</guid>
            <pubDate>Mon, 09 Jan 2023 15:12:25 GMT</pubDate>
            <description><![CDATA[<h2 id="디자인-패턴">디자인 패턴</h2>
<h3 id="싱글톤-패턴singleton-pattern">싱글톤 패턴(Singleton Pattern)</h3>
<pre><code class="language-javascript">class Database {
  const URL = &#39;...&#39;;

  constructor() {
    if (!Database.instance) {
      Database.instance = createConnection(URL);
    }
    return Database.instance;
  }

  connect() {
    return this.instance;
  }
}</code></pre>
<ul>
<li>하나의 클래스에 <strong>오직 하나의 인스턴스</strong>를 가진다.</li>
<li>데이터베이스 연결 모듈에 많이 사용한다.</li>
<li>인스턴스를 생성하고 관리하는 비용이 줄어들지만, 의존성이 높아진다는 단점이 있다.</li>
</ul>
<h4 id="의존성-주입di-dependency-injection">의존성 주입(DI, Dependency Injection)</h4>
<ul>
<li>사용이 쉽고 실용적이지만 모듈 간의 결합이 강해진다 -&gt; 의존성이 강해진다.</li>
<li>의존성 주입이란, 메인 모듈이 &#39;직접&#39; 하위 모듈에 대한 의존성을 갖는 대신 의존성을 주입시켜 객체들 간의 상호작용을 최소한으로 시킨다. 즉, 메인 모듈이 간접적으로 의존성을 갖도록 모듈 간의 결합을 느슨하게 한다. -&gt; 의존성을 낮춘다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/minjeong-dev/post/40529482-c9dd-4003-9c16-64145dca7b58/image.png" alt="">
▲ 출처 <a href="https://devopedia.org/dependency-injection">https://devopedia.org/dependency-injection</a></p>
<ul>
<li><p><strong>&quot;상위 모듈은 하위 모듈에서 어떠한 것도 가져오지 않아야 한다.&quot;</strong></p>
</li>
<li><p>모듈을 쉽게 교체할 수 있는 구조가 되어 테스트가 쉽고 마이그레이션에도 수월하다.</p>
</li>
<li><p>추상화 레이어를 넣고 구현체를 넣어주기 때문에 애플리케이션의 의존성 방향이 일관되고, 모듈 간 관계가 명확해진다.</p>
</li>
<li><p>참고하기</p>
<ul>
<li><a href="https://poiemaweb.com/angular-service_">Angular의 Service (DI pattern)</a></li>
<li><a href="https://asunhs.gitbooks.io/ng2/content/contents/services/serviceDI.html">Angular에서의 DI Service</a></li>
</ul>
</li>
</ul>
<h3 id="팩토리-패턴factory-pattern">팩토리 패턴(Factory Pattern)</h3>
<pre><code class="language-javascript">// before
let coffee1 = new Latte();
let coffee2 = new Espresso();

// after
let coffee1 = CoffeeFactory.brew(&#39;Latte&#39;);
let coffee2 = CoffeeFactory.brew(&#39;Espresso&#39;);</code></pre>
<pre><code class="language-javascript">// before
class Latte extends Coffee {
  constructor() {
    this.name = &#39;Latte&#39;;
  }
}

// after
class Latte extends Coffee {
  constructor() {
    this.name = &#39;Latte&#39;;
  }
}

class LatteFactory {
  static brew() {
      return new Latte();
  }
}

class CoffeeFactory {
  constructor() {
      this.factories = { &#39;Latte&#39;: LatteFactory } //...
  }

  static brew(type) {
    const factory = this.factories[type];
    return factory.brew();
  }
}</code></pre>
<ul>
<li>개체 생성 부분의 추상화.</li>
<li>클래스의 인스턴트를 생성하는 주체는 객체 생성 로직을 전혀 알지 않아도 생성할 수 있으므로 유연성을 갖게 되고 유지 보수성이 좋아진다.</li>
<li>팩토리 클래스에서 정적(static) 메서드로 정의할 경우 클래스의 인스턴스를 만들지 않고도 호출이 가능하므로 메모리를 절약할 수 있다.</li>
</ul>
<h3 id="전략-패턴strategy-pattern">전략 패턴(Strategy Pattern)</h3>
<ul>
<li>정책 패턴(Policy Pattern)이라고도 한다.</li>
<li>객체의 행위를 바꾸고 싶을 때 &#39;직접&#39; 수정하지 않고 <strong>전략</strong>이라고 부르는 <strong>&#39;캡슐화한 알고리즘&#39;</strong>을 컨텍스트 안에서 바꿔주며 상호 교체가 가능하도록 한다.</li>
</ul>
<p>읽어보기 <a href="https://refactoring.guru/ko/design-patterns/strategy">https://refactoring.guru/ko/design-patterns/strategy</a>
읽어보기 <a href="https://developercc.tistory.com/18">https://developercc.tistory.com/18</a></p>
<h3 id="옵저버-패턴">옵저버 패턴</h3>
<ul>
<li>publish/subscribe 개념으로 설명하기도 한다.</li>
<li>주체가 어떤 객체(Subject)의 상태 변화를 관찰하다가 상태 변화가 있을 때마다 구독 모델(Observer)에게 변화를 알려준다. (객체와 주체가 합쳐진 패턴도 흔히 쓰인다.)</li>
<li>1:n 의존성.</li>
<li>이벤트 기반 시스템에 사용한다.</li>
<li>예시<ul>
<li>객체: 상태 변화가 일어나는 관심 대상 -&gt; 유튜버</li>
<li>구독 모델(옵저버): 객체의 상태 변화를 보고 있는 관찰자 -&gt; 유튜브 구독자들</li>
</ul>
</li>
</ul>
<p>읽어보기 <a href="https://coding-factory.tistory.com/710">https://coding-factory.tistory.com/710</a></p>
<h3 id="프록시-패턴">프록시 패턴</h3>
<ul>
<li>프록시 객체가 대상 객체에 접근하기 전 그 접근에 대한 흐름을 가로채 대산 객체 앞단의 인터페이스 역할을 수행한다.</li>
</ul>
<h4 id="프록시-서버">프록시 서버</h4>
<ul>
<li>서버와 클라이언트 사이에서 클라이언트가 프록시 서버를 통해 네트워크 서비스에 간접적으로 접속할 수 있게 해준다.</li>
<li>클라이언트의 속성, 변환 등을 보완하며 보안, 데이터 검증, 캐싱, 로깅 등에 사용한다.</li>
</ul>
<p>읽어보기 <a href="https://nordvpn.com/ko/blog/proxy-versus-vpn/">Proxy vs. VPN</a></p>
<h3 id="이터레이터-패턴">이터레이터 패턴</h3>
<ul>
<li>이터레이터를 사용해 컬렉션의 요소에 접근한다.</li>
<li>다른 자료구조임에도 <code>for (let obj of collection)</code>이라는 동일한 이터레이터 프로토콜을 통해 순회가 가능하다.</li>
</ul>
<h3 id="노출모듈-패턴">노출모듈 패턴</h3>
<ul>
<li><p>private/public 같은 접근 제어자를 만드는 패턴.</p>
</li>
<li><p>javascript는 접근 제어자가 존재하지 않고 스크립트가 전역 범위에서 실행된다.</p>
</li>
<li><p>javascript의 private class fields 문법: 변수나 메서드 앞에 #을 붙인다. 이렇게 하면 클래스 내부적으로는 접근 가능하나 외부에서는 setter/getter로 접근해야 한다.</p>
</li>
</ul>
<p>출처 MDN - <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields">Private class features</a></p>
<h3 id="mvc-패턴">MVC 패턴</h3>
<ul>
<li><p>Model: 애플리케이션의 데이터.</p>
</li>
<li><p>View: 사용자 인터페이스 요소. 모델을 기반으로 사용자가 볼 수 있는 화면.</p>
</li>
<li><p>Contoller: 메인 로직. 이벤트 처리, 보델과 뷰의 생명주기 관리 등의 기능 수행.</p>
</li>
<li><p>애플리케이션의 구성 요소를 세 역할로 분리하여 개발한다. 재사용성과 확장성이 용이하지만, 애플리케이션이 복잡해질수록 Model &lt;-&gt; View 관계가 복잡해진다 = View와 Model 사이의 의존성이 높아진다.</p>
<p>  View   --- event ---&gt;  Controller --- update ---&gt; Model
  Model  --- notify ---&gt; Controller --- update ---&gt; View</p>
</li>
</ul>
<h3 id="mvp-패턴">MVP 패턴</h3>
<ul>
<li><p>Contoller: 메인 로직. 이벤트 처리, 보델과 뷰의 생명주기 관리 등의 기능 수행.</p>
</li>
<li><p>MVC 패턴으로부터 파생되어 Contoller가 Presenter로 교체.</p>
</li>
<li><p>인터페이스로 통신하여 MVC 패턴의 View와 Model 사이의 의존성을 없내는 것이 목적이다. 그러나 다시 View와 Presenter 사이의 의존성이 커진다는 단점이 있다.</p>
<p>  View --- getData() ---&gt; Present --- getData() ---&gt; Model</p>
<pre><code>   &lt;-- ui data &lt;----- Present &lt;-- data ------------┛</code></pre></li>
</ul>
<h3 id="mvvm-패턴">MVVM 패턴</h3>
<p>읽어보기 <a href="https://hackmd.io/@NItj2RZUR_6qs26fqgepdg/rJ9EnWKJs#MVP%EC%9D%98-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%90%98%EB%82%98%EC%9A%94">MVC, MVP, MVVM</a>
읽어보기 <a href="https://hackersstudy.tistory.com/71">MVC, MVP, MVVM</a>
읽어보기 <a href="https://n-square.tistory.com/51">MVC, MVP, MVVM in Angular</a></p>
<h2 id="프로그래밍-패러다임">프로그래밍 패러다임</h2>
<h3 id="선언형-프로그래밍declarative-programming">선언형 프로그래밍(Declarative Programming)</h3>
<ul>
<li>&#39;무엇을&#39; 풀어내는가에 집중하는 패러다임.</li>
<li>&quot;프로그램은 함수로 이루어진 것이다.&quot; 라는 명제가 담겨 있는 패러다임.</li>
</ul>
<h4 id="함수형-프로그래밍functional-programming">함수형 프로그래밍(Functional Programming)</h4>
<ul>
<li><p>작은 &#39;순수 함수&#39;들을 사용하여 로직을 구현하고 &#39;고차 함수&#39;를 통해 재사용성을 높인다.</p>
</li>
<li><p>javascript는 단순하고 유연한 언어적 특성을 가지면서 함수가 일급 객체이기 때문에, 객체지향 프로그래밍보다는 함수현 프로그래밍 방식이 선호된다.</p>
</li>
<li><p>순수 함수</p>
<ul>
<li>출력이 입력에만 의존한다.</li>
</ul>
</li>
<li><p>고차 함수</p>
<ul>
<li>함수가 함수를 값처럼 매개변수로 받아 로직을 생성할 수 있다.</li>
<li>일급 객체인 언어여야 가능하다.</li>
<li>일급 객체<ul>
<li>변수나 메서드에 함수를 할당할 수 있다.</li>
<li>함수 안에 함수를 매개변수로 담을 수 있다.</li>
<li>함수가 함수를 반환할 수 있다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="명령형-프로그래밍imperative-programming">명령형 프로그래밍(Imperative Programming)</h3>
<h4 id="객체-지향-프로그래밍oop-object-oriented-programming">객체 지향 프로그래밍(OOP, Object-Oriented Programming)</h4>
<ul>
<li>프로그램의 상호 작용을 객체들의 집합과 관계로 표현한다.</li>
<li>데이터를 객체로 취급하여 객체 내부에 선언된 메서드를 활용한다.</li>
<li>SOLID 설계 원칙</li>
<li>특징<ul>
<li>추상화(Abstraction)<ul>
<li>복잡한 시스템으로부터 핵심적인 개념, 기능 간추리는 것.</li>
<li>class <code>Dog</code>, <code>Cat</code>, <code>Bird</code> =&gt; <code>Animal</code></li>
</ul>
</li>
<li>캡술화(Encapsulation)<ul>
<li>객체의 속성과 메서드를 하나로 묶고 일부를 외부에 감추어 은닉하는 것.</li>
</ul>
</li>
<li>상속성(Inheritance)<ul>
<li>상위 클래스의 특성을 하위 클래스가 이어받아 재사용, 확장하는 것.</li>
<li>class <code>Bus</code>, <code>Subway</code>, <code>Srt</code> extends <code>PublicTransport</code></li>
</ul>
</li>
<li>다형성(Polymorphism)<ul>
<li>하나의 메서드나 클래스가 다양한 방법으로 동작하는 것.</li>
<li>오버로딩(Overloading): 같은 이름을 가진 메서드를 여러 개 두는 것. 메서드의 return type, parameter의 개수 및 type 등의 차이로 구분할 수 있다. javascript에서는 직접 제공하는 기능은 아니지만 <code>arguments.length</code> 값으로 분기 처리하여 동작하게 할 수 있다고 한다.</li>
<li>오버라이딩(Overriding): 상위 클래스로부터 상속받은 메서드를 하위 클래스에서 재정의하는 것.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="절차-지향-프로그래밍">절차 지향 프로그래밍</h4>
<ul>
<li>로직이 수행되어야 할 연속적인 계산 과정으로 이루어져 있다.</li>
<li>일이 진행되는 방식으로 코드를 구현하므로 코드의 가독성이 좋고 실행 속도가 빠르다.</li>
<li>그러나 모듈화하기 어렵고 유지 보수성이 떨어진다는 단점을 갖는다.</li>
</ul>
<hr>
<p>출처《면접을 위한 CS 전공지식 노트》, 16-66p</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Warning] createRoot from "react-dom/client".]]></title>
            <link>https://velog.io/@minjeong-dev/Warning-createRoot-from-react-domclient</link>
            <guid>https://velog.io/@minjeong-dev/Warning-createRoot-from-react-domclient</guid>
            <pubDate>Wed, 04 Jan 2023 14:59:27 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><span style="color: red;">Warning: You are importing createRoot from &quot;react-dom&quot; which is not supported. You should instead import it from &quot;react-dom/client&quot;.</span></p>
</blockquote>
<p>그저 튜토리얼 시작 코드 파일을 추가해 띄웠을 뿐인데 Warning 메시지가 뜨다니? 냅다 놀라기도 했고 궁금해서 검색해보았다.</p>
<p>버전이 높아지면서 문법이 바뀐 것 같다.</p>
<pre><code class="language-javascript">// before
import ReactDOM from &#39;react-dom&#39;;
const root = ReactDOM.createRoot(document.getElementById(&quot;root&quot;));

// after
import { createRoot } from &#39;react-dom/client&#39;;
const root = createRoot(document.getElementById(&quot;root&quot;));</code></pre>
<p>▲ 위의 코드로 변경해주니 import 사이즈도 확 줄고 warning이 사라졌다.</p>
<p><a href="https://17.reactjs.org/docs/concurrent-mode-reference.html#createroot">React의 Concurrent Mode</a> 관련 공식 문서에 작성되어 있는 내용을 (초보자로서) 이해해보면 React v18부터는 해당 문법 및 사용을 지원하지 않는다고 한다.</p>
<p><code>ReactDOM.createRoot(rootNode).render(component);</code>가 아닌 <code>ReactDOM.render(component, rootNode);</code>로 작성해야 <strong><em>Concurrent Mode</em></strong>를 가능하게 할 수 있다고 한다. 그게 무엇인지는 언젠가 알 수 있기를...</p>
<hr>
<p>출처: <a href="https://ba-gotocode131.tistory.com/100">https://ba-gotocode131.tistory.com/100</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React 튜토리얼 도전기 (Angular만 써본 개발자가)]]></title>
            <link>https://velog.io/@minjeong-dev/React-%ED%8A%9C%ED%86%A0%EB%A6%AC%EC%96%BC-%EB%8F%84%EC%A0%84%EA%B8%B0-Angular%EB%A7%8C-%EC%8D%A8%EB%B3%B8-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80</link>
            <guid>https://velog.io/@minjeong-dev/React-%ED%8A%9C%ED%86%A0%EB%A6%AC%EC%96%BC-%EB%8F%84%EC%A0%84%EA%B8%B0-Angular%EB%A7%8C-%EC%8D%A8%EB%B3%B8-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80</guid>
            <pubDate>Wed, 04 Jan 2023 14:44:55 GMT</pubDate>
            <description><![CDATA[<p>리액트 빠샤빠샤 공부해보기!</p>
<p><img src="https://velog.velcdn.com/images/minjeong-dev/post/123a82b3-d02d-48f4-8f9c-083d5dd3ea00/image.png" alt="tic-tac-toe"></p>
<p><a href="https://min-jeong96.github.io/react-tic-tac-toe/">https://min-jeong96.github.io/react-tic-tac-toe/</a>
▲ Github Pages 제공 기능을 이용해 배포한 주소</p>
<p><a href="https://github.com/min-jeong96/react-tic-tac-toe">Github Source Code</a>는 여기!</p>
<p>나름 반응형이다. (모바일과 웹 둘 다 접속 가능하다.)</p>
<hr>
<blockquote>
</blockquote>
<p><a href="https://reactjs-kr.firebaseapp.com/tutorial/tutorial.html">react 공식 문서의 튜토리얼 링크</a>를 따라해본다.
Angular 사용하던 회사 입사하고 온보딩 기간에 제일 먼저 한 게 Angular도 공식 가이드 사이트의 튜토리얼 일주일 동안 완성시키기 였는데... 옛날 생각나고 그런다.
(주소에 firebase 기본 도메인 들어가있는 거 진짜 짱이다.)</p>
<hr>
<h1 id="react">React</h1>
<ul>
<li>유저 인터페이스 구현을 위한 선언적, 효율적이고 유연한 JavaScript 라이브러리.</li>
<li>XML과 비슷한 태그를 사용한다.</li>
<li>React는 여러 종류의 컴포넌트를 갖는다.
  (컴포넌트: 재사용 가능한 독립적인 업무, 기능 수행 가능한 단위. 모듈.)</li>
<li>커스텀 React 컴포넌트를 쉽게 구성할 수 있다. 각 컴포넌트는 캡슐화되어 독립적으로 동작할 수 있기 때문에 간단한 컴포넌트들로 복잡한 UI를 구현할 수 있다.</li>
</ul>
<pre><code class="language-javascript">class ShoppingList extends React.Component {
  render() {
    return (
      &lt;div className=&quot;shopping-list&quot;&gt;
        &lt;h1&gt;Shopping List for {this.props.name}&lt;/h1&gt;
        &lt;ul&gt;
          &lt;li&gt;Instagram&lt;/li&gt;
          &lt;li&gt;WhatsApp&lt;/li&gt;
          &lt;li&gt;Oculus&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
    );
  }
}

// Example usage: &lt;ShoppingList name=&quot;Mark&quot; /&gt;</code></pre>
<ul>
<li>(<code>React.Component</code>를 상속 받아) 작성한 컴포넌트는 React에게 &quot;무엇을 렌더링하고 싶은지&quot; 알려준다. React는 데이터가 &quot;변경&quot;될 때 올바른 컴포넌트들을 업데이트하고 렌더링한다.</li>
<li>하나의 컴포넌트는 <code>props</code>라고 불리는 파라미터를 사용하고, <code>render</code> 메서드를 통해 표시할 뷰 계층 구조, React Element를 반환한다.</li>
<li>JSX라는 특별한 문법을 사용한다. JSX에서는 중괄호 안에 JavaScript 문법을 사용할 수 있다. 각 React Element는 변수에 저장하거나 프로그램 여기저기에 전달할 수 있는 실제 JavaScript 객체다.
  <code>return (&lt;div /&gt;)</code>라고 쓴 코드가 빌드 시에는 <code>Return.createElement(&#39;div&#39;)</code>로 변환된다. &lt;- 하지만 튜토리얼에서는 <code>createdElement()</code>를 직접적으로 사용하지 않는 대신 JSX를 사용한다고 한다.</li>
</ul>
<pre><code class="language-javascript">return React.createElement(&#39;div&#39;, {className: &#39;shopping-list&#39;},
    React.createElement(&#39;h1&#39;, /* ... h1 children ... */),
    React.createElement(&#39;ul&#39;, /* ... ul children ... */)
);</code></pre>
<hr>
<h3 id="프로젝트-생성하고-띄우기">프로젝트 생성하고 띄우기</h3>
<pre><code class="language-bash">npx create-react-app &lt;app-name&gt;
npm start</code></pre>
<ul>
<li><a href="http://localhost:3000">http://localhost:3000</a> 에서 확인 가능하다.</li>
<li><code>create-react-app</code>이 npm command가 아니라고 뜬다.</li>
</ul>
<hr>
<h3 id="함수형-컴포넌트">함수형 컴포넌트</h3>
<pre><code class="language-javascript">// before
Class Square extends React.Component {
  render() {
    return (
      &lt;button className=&quot;square&quot; onClick={() =&gt; this.props.onClick()}&gt;
        {this.props.value}
      &lt;/button&gt;
    );
  }
}

// after
function Square(props) {
  return (
    &lt;button className=&quot;square&quot; onClick={props.onClick}&gt;
      {props.value}
    &lt;/button&gt;
  );
}</code></pre>
<ul>
<li>클래스 컴포넌트보다 더 쉽게 작성할 수 있고, React가 더 효율적으로 최적화할 수 있다는 장점이 있다.</li>
</ul>
<blockquote>
<p>(최종적으로는 불합격한) 프론트엔드 기술 면접에서 React를 전혀 사용해본 적이 없어 공부를 시작한지 일주일 차라고 소개했다. 그러면서 React 튜토리얼 공부하는 이야기가 잠깐 나왔는데, FE팀 면접관 분이 클래스 컴포넌트는 읽을 줄만 알면 되는 정도고 현업에선 전부 Hook을 이용한 함수형 컴포넌트로 개발하게 된다고 알려주셨다. 그래서 면접 보고 온 날 전부 함수형으로 바꿔봤다. 그러면서 자연스럽게 useState, useEffect를 검색해 사용하게 되더라.</p>
</blockquote>
<hr>
<p>전체 출처: <a href="https://reactjs-kr.firebaseapp.com/tutorial/tutorial.html">https://reactjs-kr.firebaseapp.com/tutorial/tutorial.html</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[의미 있는 이름]]></title>
            <link>https://velog.io/@minjeong-dev/%EC%9D%98%EB%AF%B8-%EC%9E%88%EB%8A%94-%EC%9D%B4%EB%A6%84</link>
            <guid>https://velog.io/@minjeong-dev/%EC%9D%98%EB%AF%B8-%EC%9E%88%EB%8A%94-%EC%9D%B4%EB%A6%84</guid>
            <pubDate>Tue, 13 Dec 2022 12:59:46 GMT</pubDate>
            <description><![CDATA[<img height="100px" width="300px" alt="When you try to choose a meaningful variable name" src="https://velog.velcdn.com/images/minjeong-dev/post/61723a5c-fa07-475a-b0f3-d4a9611efa24/image.png"/>

<h3 id="의미-있는-이름-쓰는-법">의미 있는 이름 쓰는 법</h3>
<h4 id="의도를-분명히-밝혀라">의도를 분명히 밝혀라</h4>
<ul>
<li>변수, 함수, 클래스의 존재 이유나 수행 기능, 사용 방법이 주석 없이도 이해될 수 있게 작성되어야 한다.</li>
<li>네이밍을 너무 함축적으로 할 경우 코드 맥락이 코드 자체에 드러나지 않는다.</li>
</ul>
<h4 id="그릇된-정보를-피해라--의미-있게-구분하라">그릇된 정보를 피해라 / 의미 있게 구분하라</h4>
<ul>
<li>약어가 다른 의미로 혼동될 수 있을 경우 사용을 피한다. (ex. add -&gt; address or addition, dir -&gt; direction or directory)</li>
<li>자료구조 등과 같이 프로그래머에게 특수한 의미를 가진 단어를 사용할 때 주의한다. (ex. <code>accountList: HashMap&lt;Account&gt;</code>)</li>
</ul>
<h4 id="발음하기-쉬운-이름을-사용하라--검색하기-쉬운-이름을-사용하라">발음하기 쉬운 이름을 사용하라 / 검색하기 쉬운 이름을 사용하라</h4>
<ul>
<li>genymdhms(generate year-month-day-hour-minute-seconds) vs. generationTimestamp</li>
<li>이름의 길이는 범위 크기에 비례해야 한다.<ul>
<li>간단한 메서드 내에서 사용되는 로컬 변수의 경우 한 단어 정도로 짧을 수 있겠다.</li>
<li>코드 여러 곳에서 사용하는 변수나 상수는 검색하기 쉬우면서 정확한 의미를 표현해야 한다.</li>
</ul>
</li>
<li>검색하기 쉽다 = 긴 이름이 구체적이고 프로젝트 코드 내 사용처가 특정적이다.</li>
</ul>
<h4 id="인코딩을-피하라">인코딩을 피하라</h4>
<ul>
<li>IDE가 발전하여 이제 코드 컴파일 이전에도 타입 오류를 감지할 수 있고, 빠른 확인이 가능해졌다. 따라서 네이밍에 타입을 기억할 단서를 넣지 않아도 된다.</li>
<li>(ex. <code>phoneString</code>) 변수, 함수, 클래스 이름이나 타입을 바꾸기 어려워질 뿐이다.</li>
</ul>
<h4 id="자신의-기억력을-자랑하지-마라">자신의 기억력을 자랑하지 마라</h4>
<ul>
<li>일반적으로 사용하는 용어, 문맥상 이해 가능한 단어를 사용하여 이름의 의미를 기억하지 않고도 직관적으로 이해할 수 있어야 한다.</li>
</ul>
<h4 id="한-개념에-한-단어를-사용하라--말장난을-하지-마라">한 개념에 한 단어를 사용하라 / 말장난을 하지 마라</h4>
<ul>
<li>add와 append와 같이 공통 기능을 구분하라.</li>
<li>이미 사용한 단어를 혼란스럽게 두 가지 목적으로 사용하지 마라.</li>
</ul>
<h4 id="해법-문제-영역에서-가져온-이름을-사용하라">해법, 문제 영역에서 가져온 이름을 사용하라</h4>
<ul>
<li>문제 영역: domain → 도메인(비지니스 로직 등)의 개념과 관련이 깊은 코드라면 문제 영역에서 가져와 이름을 쓰는 것이 더욱 의미가 분명하다.</li>
<li>해법 영역: programming → 프로그래머로서 알 수 있는 전산, 알고리즘, 설계 패턴, 수학 등의 용어를 사용하면 코드를 일고 쓸 다른 프로그래머에게도 의미가 분명하다.</li>
</ul>
<h4 id="불필요한-맥락을-없애라">불필요한 맥락을 없애라</h4>
<ul>
<li>제외시켜도 이해에 전혀 문제가 없는 과다한 맥락과 의미의 단어는 제외시킨다. 그것이 더욱 가독성있게 만든다.</li>
</ul>
<h3 id="예제-연습해보기">예제 연습해보기</h3>
<pre><code class="language-typescript">// 적폐 코드 (before)
// 지뢰찾기 게임의 깃발 꽂혀진 칸 배열 반환하는 함수
// input param: arr -&gt; 지뢰찾기 전체 이차원 배열
public getThem(arr): any[] {
  let list: Array&lt;any&gt; = [];
  for (let x of arr) {
    for (let y of x) {
      if (y === 1) {
        list.push(y);
      }
    }
  }
  return list;
}</code></pre>
<pre><code class="language-typescript">// 개선해본 코드 (after) 22.12.13
public getFlaggedCells(board: Board): BoardCell[] {
  let flaggedCells: Array&lt;BoardCell&gt; = [];
  for (let row of board) {
    for (let cell of row) {
      if (cell.isFlagged()) {
        flaggedCells.push(cell);
      }
    }
  }
  return flaggedCells;
}</code></pre>
<hr>
<h3 id="출처">출처</h3>
<p>《클린 코드》, 22-38p</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[깨끗한 코드]]></title>
            <link>https://velog.io/@minjeong-dev/%EA%B9%A8%EB%81%97%ED%95%9C-%EC%BD%94%EB%93%9C</link>
            <guid>https://velog.io/@minjeong-dev/%EA%B9%A8%EB%81%97%ED%95%9C-%EC%BD%94%EB%93%9C</guid>
            <pubDate>Tue, 13 Dec 2022 10:04:23 GMT</pubDate>
            <description><![CDATA[<h3 id="코드">코드</h3>
<blockquote>
<p>어느 수준에 이르면 코드의 도움 없이 요구사항을 상세하게 표현하기란 불가능하다. 추상화도 불가능하다. 정확히 명시하는 수밖에 없다. 기계가 실행할 정도로 사에하게 요구사항을 명시하는 작업, 바로 이것이 프로그래밍이다. 이렇게 명시한 결과가 바로 코드다.</p>
</blockquote>
<h3 id="깨끗한-코드란">깨끗한 코드란?</h3>
<blockquote>
<p>비야네 스트롭스트룹
“나는 우아하고 효율적인 코드를 좋아한다. 논리가 간단해야 버그가 숨어들지 못한다. 의존성을 최대한 줄여야 유지보수가 쉬워진다. (중략)”</p>
</blockquote>
<blockquote>
<p>그래디 부치
“깨끗한 코드는 단순하고 직접적이다. 깨끗한 코드는 잘 쓴 문장처럼 읽힌다. 깨끗한 코드는 결코 설계자의 의도를 숨기지 않는다. 오히려 명쾌한 추상화와 단순한 제어문으로 가득하다.”</p>
</blockquote>
<ul>
<li>가독성이 좋은 코드</li>
<li>효율적인 코드 (CPU 자원을 낭비하지 않는다는 의미를 포함하여)</li>
<li>철저한 오류 처리가 된 코드</li>
<li>각 함수나 클래스, 모듈이 명료하고 분명한 기능만을 동작하는 코드</li>
<li>단위 테스트와 인수 테스트가 존재하는 코드</li>
<li>중복이 없는 코드</li>
<li>한 기능만 수행하는, 작고 구체적으로 추상화된 코드</li>
</ul>
<hr>
<h4 id="출처">출처</h4>
<p>《클린 코드》, 1-20p</p>
]]></description>
        </item>
    </channel>
</rss>