├── .github
├── ISSUE_TEMPLATE
│ ├── feature_issue_template.md
│ └── question_issue_template.md
└── pull_request_template.md
├── .gitignore
├── Certification
└── sqld
│ ├── ch1-1.md
│ ├── ch1-2.md
│ ├── ch2-1.md
│ ├── ch2-2.md
│ └── ch2-3.md
├── Cloud and DevOps
├── aws
│ ├── autoScaling.md
│ ├── cloudComputing.md
│ ├── ecs_ecr.md
│ ├── rds.md
│ └── vpc_peering.md
├── cicd.md
├── cloudService.md
├── devopsCloud.md
├── docker
│ ├── docker.md
│ ├── dockerExecution.md
│ └── hypervisor.md
├── git
│ ├── gitflow.md
│ └── github.md
└── terraform
│ └── terraform.md
├── Computer Science
├── Algorithm
│ ├── bellmanFord.md
│ ├── bruteForce.md
│ ├── catalan.md
│ ├── ccw.md
│ ├── combination.md
│ ├── dijkstra.md
│ ├── greedy.md
│ ├── kmp.md
│ ├── kruskal.md
│ ├── lis.md
│ ├── mst.md
│ ├── permutation.md
│ ├── shortestPath.md
│ └── substring.md
├── Data Structure
│ ├── bTree.md
│ ├── binaryTree.md
│ ├── list.md
│ └── tree.md
├── Database
│ ├── SQL
│ │ ├── ddl_dml_dcl_tcl.md
│ │ ├── join.md
│ │ └── sqlGrammar.md
│ ├── dbDesign.md
│ ├── identifyRelationship.md
│ ├── index.md
│ ├── key.md
│ ├── normalization.md
│ ├── rdb.md
│ ├── rdbNaming.md
│ ├── sqlAndNoSql.md
│ ├── transaction.md
│ └── 트랜잭션_격리수준.md
├── Network
│ ├── 3wayN4way.md
│ ├── blockNnonNsyncNasync.md
│ ├── httpNhttps.md
│ ├── loadBalancing.md
│ ├── osi.md
│ ├── port-forwarding.md
│ ├── proxy.md
│ └── tcpNudp.md
├── Operating System
│ ├── contextSwitching.md
│ ├── deadlock.md
│ ├── operatingSystem.md
│ ├── pas_pcb.md
│ ├── process_thread.md
│ ├── raceCondition.md
│ └── semaphore_mutex.md
├── SW Engineering
│ ├── decorator_pattern.md
│ ├── design_pattern.md
│ ├── factoryPattern.md
│ ├── mvc.md
│ └── solid.md
└── computerScience.md
├── LICENSE
├── Language
├── Java
│ ├── Executor와_ExecutorService.md
│ ├── Java_실행_과정.md
│ ├── ThreadLocal과_Atomic.md
│ ├── aboutJava.md
│ ├── aboutStream.md
│ ├── collectionFramework.md
│ ├── compare.md
│ ├── completableFuture.md
│ ├── future.md
│ ├── gc.md
│ ├── gc_튜닝하기.md
│ ├── input.md
│ ├── iteratorNlistiterator.md
│ ├── javaVersion.md
│ ├── java_쓰레드.md
│ ├── jvm_메모리_영역.md
│ ├── jvm_클래스로더.md
│ ├── lambda.md
│ ├── list.md
│ ├── priorityQueue.md
│ ├── set.md
│ ├── stream.md
│ ├── string.md
│ ├── stringBuilder.md
│ ├── typeOfJava.md
│ ├── volatile과_synchronized.md
│ └── 멀티스레드_환경에서_싱글톤으로_객체_생성하기.md
├── JavaScript
│ ├── ES2015+.md
│ └── asyncAwait.md
├── Kotlin
│ ├── dataClass.md
│ ├── javaVsKotlin.md
│ ├── kotlinSingleton.md
│ ├── scopeFunction.md
│ ├── 이펙티브_코틀린_1.md
│ ├── 이펙티브_코틀린_2.md
│ └── 이펙티브_코틀린_3.md
├── Python
│ └── selenium.md
├── Typescript
│ └── typescript_cleancode.md
└── programmingLanguage.md
├── Programming
├── Object-Orientation
│ ├── ood.md
│ ├── oop.md
│ └── transaction_domain.md
├── Test
│ ├── tdd.md
│ ├── test.md
│ └── testcodePattern.md
└── programming.md
├── README.md
├── System Design
├── SNS_시스템_규모_추정.md
├── URL_단축기.md
├── rdb_nosql.md
├── server.md
├── systemDesign.md
├── 개략적_규모_추정.md
├── 검색어_자동완성_시스템.md
├── 뉴스_피드_시스템.md
├── 데이터_센터.md
├── 메시지_큐.md
├── 분산_시스템을_위한_유일_ID_생성기.md
├── 시스템_설계_면접_공략법.md
├── 안정_해시.md
├── 알림_시스템.md
├── 유튜브_시스템.md
├── 채팅_시스템.md
├── 처리율_제한_장치.md
├── 캐시와_CDN.md
└── 홈페이지_시스템_규모_추정.md
├── Web-Node
├── Express js
│ ├── express.md
│ └── middleware
│ │ └── body-parser.md
├── Nest js
│ └── Overview
│ │ ├── exceptionfilters.md
│ │ └── middleware.md
├── Node js
│ └── nodejs.md
└── node.md
├── Web-Spring
├── Async_어노테이션을_활용한_비동기.md
├── Jpa
│ ├── dirtyChecking.md
│ ├── entitySetter.md
│ ├── jpa.md
│ └── jpql.md
├── MyBatis
│ ├── dynamicSQL.md
│ └── myBatis.md
├── Spring MVC
│ ├── dao_dto_vo.md
│ └── springMvc.md
├── Spring REST Docs
│ └── springRestDocs.md
├── basic
│ ├── aboutBeanFactory.md
│ ├── aboutSpring.md
│ ├── bean.md
│ ├── springConfig.md
│ ├── springContainer.md
│ └── springNboot.md
├── controller.md
├── devtools.md
├── googleLogin.md
├── lombok.md
├── mavenCentral.md
├── restTemplate.md
├── spring.md
├── swagger.md
└── test
│ ├── JUnit.md
│ ├── JUnit5_Extension.md
│ ├── SpringExtension.md
│ └── TestContainer를_활용한_통합_테스트.md
├── Web
├── OAuth2.0.md
├── cookieNsession.md
├── cors.md
├── crawling.md
├── jwt.md
├── orm.md
├── putNpatch.md
├── redirectNforward.md
├── requestObject.md
├── restApi.md
├── web.md
└── webReadme.md
└── resources
├── 1v1_chatting.png
├── URL_단축기.png
├── active_send.png
├── algorithm
├── bellman1.png
├── bellman2.jpeg
├── catalan1.png
├── catalan2.jpeg
├── catalan3.jpeg
├── catalan4.png
├── catalan5.png
├── catalan6.png
├── catalan7.png
├── catalan8.jpeg
├── dijkstra.png
├── greedy1.png
├── greedy2.png
├── kruskal-a.png
├── kruskal-b.png
├── kruskal-c.png
├── kruskal-d.png
├── kruskal-e.png
├── kruskal-f.png
├── kruskal-g.png
├── kruskal-h.png
├── kruskal-i.png
├── kruskal-j.png
├── kruskal-k.png
├── kruskal-l.png
├── kruskal-m.png
├── kruskal-n.png
├── kruskal-o.png
├── kruskal-p.png
├── mst.png
└── spanningTree.png
├── aws
├── cloudService.png
└── ecs.png
├── chatting_data_model.png
├── chatting_process.png
├── chatting_server_discovery.png
├── chatting_system_1.png
├── dag_process.png
├── dataStructure
└── tree
│ └── tree.png
├── data_collect.png
├── db
├── design.png
├── identifyingRelationship.png
├── non-identifyingRelationship.png
└── rdb.png
├── decorator_pattern.png
├── device_synchronization.png
├── docker
└── vm_container.png
├── feed_publish.png
├── feed_publish_detail.png
├── feed_read.png
├── feed_read_detail.png
├── git
└── gitflow.png
├── group_chatting.png
├── java
├── collection.png
├── executeJava.png
├── javaType.png
├── jvm.png
└── linkedlist.jpeg
├── long_polling.png
├── message_queue.png
├── multi_master_replication.png
├── nest
├── exceptionFilter.png
└── middleware.png
├── network
├── 2by2matrix.png
├── 3way.jpg
├── 4way.jpg
├── http.png
├── loadbalancing.png
├── osi.png
├── tcp.png
└── udp.png
├── notification_contact.png
├── notification_system_1.png
├── notification_system_2.png
├── notification_system_3.png
├── notification_system_4.png
├── os
├── contextSwitching.png
├── pap.png
├── pcb.png
└── process_thread.png
├── os1.png
├── polling.png
├── port1.png
├── programming
└── Test
│ └── test.png
├── proxy1.png
├── proxy2.jpeg
├── proxy3.jpeg
├── python
└── selenium1.png
├── rate_limiter.png
├── sliding_window_counter.png
├── snowflake.png
├── spring
├── BeanDefinition.png
├── Factory.png
├── MyBatis
│ └── myBatisDatabaseAccess.PNG
├── RESTDocs
│ └── springRestDoc.png
├── basic
│ ├── context.PNG
│ └── mvc-context.png
├── controller.png
├── di.png
├── di2.png
├── jcenter.png
├── jpa.png
├── liveReload.png
├── restTemplate.png
├── restcontroller.png
├── security
│ └── google
│ │ ├── googleLogin1.png
│ │ ├── googleLogin2.png
│ │ ├── googleLogin3.png
│ │ ├── googleLogin4-1.png
│ │ ├── googleLogin4-2.png
│ │ ├── googleLogin4-3.png
│ │ ├── googleLogin5.png
│ │ ├── googleLogin6-1.png
│ │ └── googleLogin6-2.png
├── springMVC.png
└── vendor.png
├── sql1.png
├── swEngineering
├── mvc1.png
├── tdd1.png
├── tdd2.png
└── tdd3.png
├── ticket_server.png
├── token_bucket.png
├── transcoding_process.png
├── trie_example.png
├── video_upload_process.png
├── web
├── forward.png
├── jwt.png
├── jwtProcess.png
├── oauth1.png
├── oauth2.png
├── oauth3.png
├── oauth4.png
├── redirect.png
└── web.png
├── websocket.png
└── youtube_basic.png
/.github/ISSUE_TEMPLATE/feature_issue_template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Request
3 | about: Create a Feature Request Issue
4 | title: ""
5 | labels: enhancement
6 | assignees: ""
7 | ---
8 |
9 | ## Describe the recipe you request
10 |
11 | **Describe your recipe request.**
12 |
13 | ## If approved, would you be writing?
14 |
15 | _Yes / No_
16 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question_issue_template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Question
3 | about: Create a Question Issue
4 | title: ""
5 | labels: question
6 | assignees: ""
7 | ---
8 |
9 | ## Describe your question
10 |
11 | _Tell us any question!_
12 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Summary
2 |
3 | _Describe summary of your pr._
4 |
5 | ## (Optional): Description
6 |
7 | _Describe your pr in detail._
8 |
9 | ## Checklist
10 |
11 | - check base branch
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # os
2 | .DS_Store
3 |
4 | # IntelliJ IDEA
5 | .idea
--------------------------------------------------------------------------------
/Cloud and DevOps/aws/autoScaling.md:
--------------------------------------------------------------------------------
1 | ## Amazon Auto Scaling
2 |
3 | : 애플리케이션을 모니터링하고 용량을 자동으로 조정하여, 최대한 저렴한 비용으로 안정적이고 예측 가능한 성능을 유지하는 서비스
4 |
5 | - 클라우드의 이점을 살려 인프라의 증설/축소를 손쉽게 구현 가능
6 | - 서버나 애플리케이션을 모니터링하고, 리소스를 자동으로 Scale In/Out
7 | - 확장성 및 탄력성 높은 시스템 구축 가능
8 |
9 |
10 |
11 | ## Amazon Auto Scaling의 구성 요소
12 |
13 | > ### 1️⃣ Amazon Auto Scaling 그룹
14 |
15 | : 인스턴스의 조정 및 관리 목적으로 구성된 논리적 그룹
16 |
17 | - Auto Scaling 그룹을 사용하여
18 | - 지정된 조건에 따라 자동으로 인스턴스 수를 늘리거나
19 | - 비정상적으로 동작하는 경우 고정된 수의 인스턴스를 유지하거나
20 | - 비용 절감을 위해 인스턴스의 수를 자동으로 조정 가능
21 |
22 | > ### 2️⃣ 시작 구성
23 |
24 | : Auto Scaling 그룹에서 인스턴스를 시작하는 데 사용하는 템플릿
25 | → AMI, 인스턴스 유형, 키 페어, 보안그룹, EBS 등 인스턴스에 대한 정보 지정
26 |
27 | - 여러 개의 Auto Scaling 그룹에 지정 가능
28 | - 반대로, Auto Scaling 그룹은 하나의 시작 구성만을 지정 가능
29 | - 한번 생성 후 수정/변경 불가능
30 |
31 | > ### 3️⃣ Amazon Auto Scaling 그룹 조정
32 |
33 | : 인스턴스의 수를 늘리거나 줄이는 기능
34 |
35 | - 조정옵션
36 | - 현재 인스턴스 수준 유지 관리
37 | - 수동 조정
38 | - 일정을 기반으로 조정
39 | - 온디맨드 기반 조정
40 |
--------------------------------------------------------------------------------
/Cloud and DevOps/aws/cloudComputing.md:
--------------------------------------------------------------------------------
1 | ## **클라우드와 아마존 웹 서비스**
2 |
3 |
4 |
5 | > ### 1. 클라우드 컴퓨팅
6 |
7 | → 개인용 컴퓨터가 아닌 `인터넷을 통해 연결된 원격 컴퓨터`를 활용하는 기술
8 |
9 | - 언제, 어디서나 인터넷을 사용해 쉽게 접근 가능
10 | - 최소한의 노력 + 최단 시간 → 컴퓨터 자원 관리
11 | - `Pay-Per-Use` Pricing
12 |
13 |
14 |
15 | > ### 2. 클라우드 컴퓨팅을 배워야 하는 이유
16 |
17 | - 이미 많은 기업이 클라우드를 도입하였거나 도입을 검토하고 있다.
18 | - HW를 데이터 센터에 넣고 운영/관리하는 일이 점점 줄어들 것이다.
19 |
20 |
21 |
22 | > ### 3. 클라우드 컴퓨팅 서비스 이용 방식
23 |
24 |

25 |
26 | - **Iaas**
27 | - Infrastructure-as-a-Services
28 | - 물리적인 서버(cpu, memory, os), 네트워크, 스토리지를 가상화하여 다수의 고객을 대상으로 유연하게 제공하는 인프라 서비스
29 | - **PaaS**
30 | - Platform-as-a-Services
31 | - Web 기반의 서비스 또는 애플리케이션 등의 개발 및 실행을 위한 표준 플랫폼 환경을 서비스 형태로 제공하는 서비스
32 | - **SaaS**
33 | - Software-as-a-Services
34 | - 구글의 Gmail이나 MS Office 등과 같이 응용프로그램을 인터넷 및 웹 브라우저를 통해 제공하는 서비스
35 |
36 |
37 |
38 | > ### 4. 클라우드 컴퓨팅의 장점 및 혜택
39 |
40 | - 초기 투자 비용 발생 X → 사용한 만큼만 지불
41 | - 미래에 필요한 인프라 용량을 추정할 필요가 없음 → 오버 프로비저닝 방지
42 | - 데이터 센터 운영 및 유지 관리가 필요하지 않음
43 | - 몇분 만에 전세계에 서비스 런칭 및 배포 가능
44 |
45 |
46 |
47 | > ### 5. AWS 주요 서비스
48 |
49 | - 컴퓨팅 서비스
50 | - EC2, Auto Scaling, Lightsail, WorkSpaces
51 | - 네트워킹 서비스
52 | - Route 53, VPC, Direct Connect, ELB
53 | - 스토리지 서비스
54 | - S3, Glacier, EBS, Storage Gateway, Snowball
55 | - DB 서비스
56 | - RDS, DynamoDB, ElasticCache
57 | - 분석 플랫폼
58 | - Kinesis, Redshift, EMR
59 | - 애플리케이션 서비스
60 | - CloudSearch, SES, Elastic Transcoder
61 |
--------------------------------------------------------------------------------
/Cloud and DevOps/aws/ecs_ecr.md:
--------------------------------------------------------------------------------
1 | ## ECR (Elastic Container Registry)
2 |
3 | : AWS에서 제공하는 컨테이너 레지스트리
4 |
5 | - 개발자가 컨테이너 이미지를 손쉽게 저장, 관리 및 배포할 수 있게 도와줌
6 | - 컨테이너 이미지를 ECR에 업로드 하여 ECS를 이용해 배포
7 | - Private Docker Hub와 유사
8 |
9 |
10 |
11 | ## ECS (Elastic Container Service)
12 |
13 | : 완전 관리형 컨테이너 오케스트레이션 서비스
14 |
15 | - 다양한 오케스트레이션 서비스가 있음
16 | - 다양한 AWS 기능과 통합이 쉬움
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | ---
25 |
26 |
27 |
28 | ### Reference
29 |
30 | - [@topasvga](https://brunch.co.kr/@topasvga/1190)
31 |
--------------------------------------------------------------------------------
/Cloud and DevOps/aws/rds.md:
--------------------------------------------------------------------------------
1 | ## AWS RDS란?
2 |
3 | : AWS 클라우드에서 RDB를 더욱 간편하게 설정, 운영 및 확장할 수 있는 서비스
4 |
5 | - 시간 소모적인 관리 작업 자동화
6 | - 하드웨어 프로비저닝
7 | - DB 설정
8 | - 패치 및 백업
9 | - 효율적인 비용
10 | - 크기 조정 가능
11 |
12 |
13 |
14 | ## RDS의 주요 특징
15 |
16 | > ### 4-1. Amazon 클라우드 DB 서비스의 선택 사항
17 |
18 | - 1. 직접 EC2에 DB 설치 및 이용
19 | - On-Premise에서 사용하던 DB를 그대로 사용 가능
20 | - DB 제공 밴더사에 따라 클라우드용 라이센스를 운여하는 경우를 주의해야 함
21 | - 2. AWS에서 직접 제공해주는 DB 서비스 이용
22 | - RDS : RDB 서비스
23 | - DynamoDB : NoSQL 기반의 중단 없는 확장성 제공
24 | - Amazon Redshift : 대용량 병렬 페타바이트급 데이터 웨어 서비스
25 |
26 |
27 |
28 | > ### 4-2. Amazon RDS의 주요 특징
29 |
30 | → 뛰어난 확장성, 빠르게 확장 가능한 가용성, 높은 보안성
31 |
32 | - 유연한 인스턴스 및 스토리지 확장
33 | - 다양한 CPU / 메모리 옵션 제공
34 | - 트래픽에 따른 증설 및 사양의 축소 가능
35 | - 백업 및 복원 기능
36 | - 자동 백업 설정
37 | - 손쉬운 복구 기능
38 | - 스냅샷
39 | - 멀티 AZ를 통한 고가용성 확보
40 | - 리전 내 AZ 간 DB 동기화 구성 가능
41 | - 장애 상황 발생 시 자동으로 DB Failover 수행
42 | - 리플리케이션을 통한 가용성 지원
43 | - RDS 암호화 옵션을 통한 보안성 강화
44 | - DB Migration 서비스
45 |
46 | ```text
47 | 👆 리플리케이션이란?
48 | : 두 개의 이상의 DBMS 시스템을 Mater / Slave 로 나눠서 동일한 데이터를 저장하는 방식
49 | ```
50 |
--------------------------------------------------------------------------------
/Cloud and DevOps/aws/vpc_peering.md:
--------------------------------------------------------------------------------
1 | # VPC Peering
2 |
3 | : 두 개의 VPC를 연결하여, `서로 다른 VPC` 간에 `트래픽`을 전송할 수 있도록 하는 서비스
4 |
5 | - VPC 간 1:1 연결 방식 제공
6 | - 동일한 계정 또는 다른 계정에 있는 VPC 간 비공개 연결
7 | - private IP 사용
8 | - 동일 리전뿐 아니라 서로 다른 리전 연결도 가능
9 | - CIDR이 중복되면 안됨
10 | - 다중 피어링 관계 불가능
11 | - 고가용성 연결 제공
12 |
13 | ## VPC Peering 구성
14 |
15 | 1. 요청자가 수신자에게 VPC 피어링 요청
16 | 2. 수신자가 요청을 수락
17 | 3. VPC 피어링 연결에 대한 `DNS 확인` 설정
18 | 4. `라우팅 테이블` 설정
19 | 5. 피어링 연결 완료
20 |
21 | ### DNS 확인 설정
22 |
23 | - 피어 VPC의 인스턴스가 쿼리를 보낼 때, VPC가 퍼블릭 `IPv4 DNS 호스트 이름`을 `프라이빗 IPv4 주소`로 확인하기 위함
24 |
25 | ### 라우팅 테이블 설정
26 |
27 | - 두 VPC가 서로의 프라이빗 IP 주소로 `트래픽 통신`할 수 있도록 라우팅 테이블 설정
28 |
29 | ## DGW, TGW와 비교
30 |
31 | | 특징 | VPC Peering | Direct Connect Gateway (DGW) | Transit Gateway (TGW) |
32 | |---------|--------------------|------------------------------|------------------------|
33 | | **용도** | 두 VPC 간 직접 연결 | 온프레미스와 여러 VPC 연결 | 다수의 VPC, 온프레미스, VPN 연결 |
34 | | **확장성** | 제한적, 연결이 많아지면 복잡해짐 | Direct Connect 연결 중심 | 뛰어난 확장성, 네트워크 관리 용이 |
35 | | **보안** | 직접 연결로 간단한 보안 설정 | Direct Connect로 안정적 보안 제공 | 중앙 집중식 보안 정책 관리에 유리 |
36 | | **비용** | 상대적으로 저렴 | 데이터 전송 비용 발생 | 유연한 비용 구조, 다양한 네트워크 연결 |
37 |
--------------------------------------------------------------------------------
/Cloud and DevOps/cicd.md:
--------------------------------------------------------------------------------
1 | ## CI (Continuous Integration)
2 |
3 | : 빌드/테스트 자동화 과정
4 |
5 | - 지속적인 통합
6 | - 애플리케이션에 대한 새로운 코드 변경 사항이 정기적으로 `빌드 및 테스트`
7 | - 여러 개발자가 동시에 애플리케이션 개발과 관련된 코드 작성을 할 경우 충돌 문제 해결
8 | - 커밋(Commit)할 때마다 `빌드`와 일련의 `자동 테스트`가 이루어짐
9 | - 동작을 확인하고 변경으로 인해 문제가 발생하는 부분이 없도록 보장
10 |
11 |
12 |
13 | ## CD (Continuous Deployment)
14 |
15 | : 배포 자동화 과정
16 |
17 | - 지속적인 배포
18 | - CI 과정이 성공적으로 통과하면 수동 개입 없이 해당 변경 사항이 프로덕션에 `자동 배포`
19 | - 품질 저하 없이 최대한 빠르게 유저에게 새로운 기능 제공 가능
20 |
21 |
22 |
23 | ## CICD 파이프라인 보호하기
24 |
25 | - CI/CD 환경에 `기밀`을 저장하지 말 것
26 | - 자동화된 `PULL` 요청과 예약된 작업을 철저히 조사
27 | - 클라우드 네이티브 컨테이너 강화 및 정기적 검사
28 | - 심층 코드 스캔을 통합해 `코드 품질 검사` 자동화
29 | - 최신 CI/CD `도구 취약점`에 대한 빠른 패치
30 | - 업데이트를 적용하기 전에 `무결성 검사`
31 |
32 |
33 |
34 | ---
35 |
36 | ### Reference
37 |
38 | - [@ciokorea](https://www.ciokorea.com/tags/27787/ci_cd/201639)
39 | - [@seosh817](https://seosh817.tistory.com/104)
40 |
--------------------------------------------------------------------------------
/Cloud and DevOps/cloudService.md:
--------------------------------------------------------------------------------
1 | ## SaaS
2 |
3 | > ### Software as a Service
4 |
5 | : 사용자에게 애플리케이션 형태로 제공돼 설치 및 관리할 필요 없이 편리하게 사용 가능
6 |
7 | ex. MS Office, Notion 등
8 |
9 | ## PaaS
10 |
11 | > ### Platform as a Service
12 |
13 | : 애플리케이션을 개발, 테스트, 배포하기 위한 플랫폼을 제공하는 클라우드
14 |
15 | ex. AWS ELB
16 |
17 | ## IaaS
18 |
19 | > Infrastructure as a Service
20 |
21 | : 서버, 스토리지 및 네트워킹을 포함한 가상화된 컴퓨팅 인프라를 제공하는 클라우드
22 |
23 | ex. AWS, Google Cloud
24 |
25 |
26 |
27 | ---
28 |
29 | ### Ref
30 |
31 | - [google cloud](https://cloud.google.com/learn/paas-vs-iaas-vs-saas?hl=ko)
32 |
--------------------------------------------------------------------------------
/Cloud and DevOps/devopsCloud.md:
--------------------------------------------------------------------------------
1 | # DevOps and Cloud Recipe
2 |
3 | 데브옵스와 클라우드 관련 레시피 입니다. 직접 학습하고 구성해보면서 작성 했습니다. 필요한 레시피를 편하게 얻어가시고, 원하는 레시피는 `ISSUE`에 등록, 추가하고 싶은 레시피와 잘못된 레시피는 `PR`에 등록해주시면 감사하겠습니다.
4 |
5 | ## Git
6 |
7 | - [Github란?](https://github.com/lcomment/development-recipes/blob/main/Cloud%20and%20DevOps/git/github.md)
8 | - [깃 플로우란? (Git-Flow)](https://github.com/lcomment/development-recipes/blob/main/Cloud%20and%20DevOps/git/gitflow.md)
9 |
10 | ## AWS
11 |
12 | - [Cloud와 AWS](https://github.com/lcomment/development-recipes/blob/main/Cloud%20and%20DevOps/aws/cloudComputing.md)
13 | - [AWS RDS](https://github.com/lcomment/development-recipes/blob/main/Cloud%20and%20DevOps/aws/rds.md)
14 | - [AWS Auto Scaling](https://github.com/lcomment/development-recipes/blob/main/Cloud%20and%20DevOps/aws/autoScaling.md)
15 | - [AWS ECS, ECR](https://github.com/lcomment/development-recipes/blob/main/Cloud%20and%20DevOps/aws/ecs_ecr.md)
16 | - [VPC Peering](https://github.com/lcomment/development-recipes/blob/main/Cloud%20and%20DevOps/aws/vpc_peering.md)
17 |
18 | ## Docker
19 |
20 | - [가상화와 하이퍼바이저](https://github.com/lcomment/development-recipes/blob/main/Cloud%20and%20DevOps/docker/hypervisor.md)
21 | - [도커란?](https://github.com/lcomment/development-recipes/blob/main/Cloud%20and%20DevOps/docker/docker.md)
22 | - [도커 이미지와 레이어, 컨테이너](https://github.com/lcomment/development-recipes/blob/main/Cloud%20and%20DevOps/docker/dockerExecution.md)
23 |
24 | ## CICD
25 |
26 | - [CI/CD란?](https://github.com/lcomment/development-recipes/blob/main/Cloud%20and%20DevOps/cicd.md)
27 |
28 | ## Terraform
29 |
30 | - [Terraform이란?](https://github.com/lcomment/development-recipes/blob/main/Cloud%20and%20DevOps/terraform/terraform.md)
31 |
--------------------------------------------------------------------------------
/Cloud and DevOps/docker/docker.md:
--------------------------------------------------------------------------------
1 | ## Docker
2 |
3 | : Go 언어로 작성된 리눅스 컨테이너 기반으로 하는 오픈소스 가상화 플랫폼
4 |
5 | - 성능 향상
6 | - 뛰어난 이식성
7 | - 쉽게 Scale Out을 할 수 있는 이식성
8 |
9 |
10 |
11 | > ### 가상화를 사용하는 이유
12 |
13 | - 서버 관리자 입장
14 | - CPU 사용률이 낮은 서버들 → 리소스 낭비
15 | - 그렇다고 모든 서비스를 한 서버에 올린다면 안정성에 문제가 생김
16 | - `서버 가상화` → 안정성을 높이며 리소스를 최대한 활용 가능
17 |
18 |
19 |
20 | > ### 컨테이너란?
21 |
22 | : 가상화 기술 중 하나로, OS 레벨의 가상화로 프로세스를 격리시켜 동작하는 방식
23 |
24 |
25 |
26 | > ### Docker를 사용하는 경우
27 |
28 | - MSA (Micro Service Architecture)
29 | - Docker 컨테이너를 통해 표준화된 코드 배포를 활용하여 MSA 구축 및 확장
30 | - CICD
31 | - 환경 표준화, 언어 스택 및 버전 간 충동 제거
32 | - 데이터 처리
33 | - 빅 데이터 처리를 서비스로서 제공
34 | - 서비스로서의 컨테이너
35 |
36 |
37 |
38 | ## VM vs Docker
39 |
40 |
41 |

42 |
출처: https://aws.amazon.com/ko/docker/
43 |
44 |
45 | - VM (Virtual Machine)
46 | - Host OS 위에 가상화를 위한 `Hypervisor` 엔진, `Guest OS`를 올려 사용
47 | - Host OS와 Guest OS를 완벽히 분리 → 높은 격리 레벨
48 | - 무겁고 느림
49 | - Docker
50 | - Docker 엔진 위에 애플리케이션 실행에 `필요한 바이너리`만 올라감
51 | - Host의 `커널 공유` → IO 처리가 쉬워 효율을 높일 수 있음
52 |
53 |
54 |
55 | ---
56 |
57 | ### Reference
58 |
59 | - [@aws](https://aws.amazon.com/ko/docker/)
60 | - [@khj93](https://khj93.tistory.com/entry/Docker-Docker-%EA%B0%9C%EB%85%90)
61 |
--------------------------------------------------------------------------------
/Cloud and DevOps/docker/dockerExecution.md:
--------------------------------------------------------------------------------
1 | ## Docker Image
2 |
3 | > ### Docker Image란?
4 |
5 | : 서비스 운영에 필요한 서버 프로그램, 소스코드 및 라이브러리, 컴파일 된 파일을 묶은 형태
6 |
7 | > ### Image Layer란?
8 |
9 | : 기존 이미지에 추가적인 파일이 필요할 때, 다시 다운로드 받지 않고 해당 파일을 추가하기 위한 개념
10 |
11 | > ### Docker Container란?
12 |
13 | : Docker Image를 실행한 형태
14 |
15 |
16 |
17 | > ### 실행 과정
18 |
19 | 1. Dockerfile 작성
20 | - 애플리케이션을 컨테이너화하기 위해 필요한 단계와 명령을 순차적으로 기술한 파일
21 | - 기반 이미지, 작업 디렉토리, 복사할 파일, 실행할 명령 등을 포함
22 | 2. Docker 이미지 빌드
23 | - 작성한 Dockerfile을 사용하여 Docker 이미지를 빌드
24 | - `docker build` 명령
25 | - Dockerfile의 내용을 읽고, 각 명령을 순차적으로 실행하여 `이미지 레이어`를 생성
26 | 3. 이미지 레이어 생성
27 | - Dockerfile의 각 단계별로 이미지 레이어를 생성
28 | - 각 단계는 중간 이미지로 저장
29 | - 이를 활용하여 나중에 변경이 있을 경우 캐싱하여 빌드 시간을 단축
30 | 4. 최종 이미지 생성
31 | - 기반 이미지, 애플리케이션 코드, 설정 등을 포함
32 | - 컨테이너를 실행하는 데 필요한 모든 것을 갖춘 상태
33 |
--------------------------------------------------------------------------------
/Cloud and DevOps/docker/hypervisor.md:
--------------------------------------------------------------------------------
1 | ## 가상화와 하이퍼 바이저
2 |
3 | > ### 1. 가상화 등장 이전
4 |
5 | - 어떤 서비스를 운영하기 위해 애플리케이션이 OS 단위로 올라가 있음
6 | - OS들은 하드웨어에 종속된 환경으로 구성됨
7 | - 간단히 말하면, 1PC 1Application
8 |
9 |
10 |
11 | > ### 2. 가상화(Virtualization)란?
12 |
13 | : 가상화를 관리하는 소프트웨어를 사용하여 하나의 물리적 머신에서 가상 머신(VM)을 만드는 프로세스
14 |
15 | - 애플리케이션이 OS 위가 아닌 VM 위에 올라감
16 | - 하나의 PC에 많은 애플리케이션 가동 가능
17 | - 하이퍼바이저가 필요에 따라 각 VM에 컴퓨팅 리소스를 할당
18 |
19 |
20 |
21 | > ### 3. 하이퍼바이저 (Hypervisor)
22 |
23 | : 가상 머신(Virtual Machine, VM)을 생성하고 구동하는 소프트웨어
24 |
25 | - 하이퍼바이저 운영 체제와 가상 머신의 리소스를 분리해 VM의 생성과 관리를 지원
26 | - 하이퍼바이저로 사용되는 물리 하드웨어 → `호스트`
27 | - 리소스를 사용하는 여러 VM → `게스트`
28 | - CPU, 메모리, 스토리지 등의 리소스를 처리하는 풀
29 | - 기존 게스트 간 또는 새로운 가상 머신에 쉽게 재배치 가능
30 | - 서로 다른 OS들을 나란히 구동 가능 및 동일한 가상화 하드웨어 리소스를 공유
31 |
32 |
33 |
34 | > ### 4. Linux는 하이퍼바이저를 사용하지 않는다?
35 |
36 | - 리눅스는 하이퍼바이저를 가지고 있지 않음
37 | - 리눅스 커널 → 직접 하드웨어를 관리하고 여러 프로세스를 실행하는 운영 체제
38 | - 컨테이너 기반의 가상화를 위한 기능을 내장
39 | - 리눅스 커널의 `Namespace`와 `Cgroups` 활용
40 | - Docker → 컨테이너 격리 및 리소스를 관리하여 가상화를 구현
41 |
42 |
43 |
44 | > ### References
45 |
46 | - [https://www.redhat.com/ko/topics/virtualization/what-is-a-hypervisor](https://www.redhat.com/ko/topics/virtualization/what-is-a-hypervisor)
47 | - [https://mangkyu.tistory.com/86](https://mangkyu.tistory.com/86)
48 |
--------------------------------------------------------------------------------
/Cloud and DevOps/git/gitflow.md:
--------------------------------------------------------------------------------
1 | ## 깃 플로우 (Git Flow)
2 |
3 | : [Viencent Driessen](https://nvie.com/posts/a-successful-git-branching-model/)이라는 사람의 블로그 글에 의해 퍼진 Git을 이용한 개발 방법론
4 |
5 | - 기능이 아닌 `방법론`
6 | - 각자 개발 환경에 따라 수정 및 변형하여 사용
7 |
8 | > ### Git-Flow의 5가지 브랜치
9 |
10 | - `master`
11 | - 기준이 되는 브랜치
12 | - 제품을 `배포`
13 | - `develop`
14 | - 개발 브랜치
15 | - 이 브랜치를 기준으로 각자 작업한 기능을 Merge
16 | - `feature`
17 | - 단위 기능을 개발하는 브랜치
18 | - 기능 개발 후 develop 브랜치에 Merge
19 | - `release`
20 | - 배포를 위해 master 브랜치에 보내기 전에 `QA`를 하기 위한 브랜치
21 | - `hotfix`
22 | - master 브랜치로 배포했을 때 `긴급 수정`하는 브랜치
23 |
24 |
25 |
26 | > ### Vincent Driessen이 소개한 Git-Flow
27 |
28 |
29 |
30 |
31 |
32 | 1. `Master` 브랜치와 `develop` 브랜치를 나누는 것이 핵심
33 | 2. `develop` 브랜치를 현재 개발 완료 상태와 일치시키면서 동료와의 `conflict를 방지`하기 위해 `feature` 브랜치 이용
34 | - `develop`에서 `feature` 브랜치를 생성해서 새로운 작업 수행
35 | - 작업 종료 후 `feature` 브랜치를 최신 `develop`에 merge
36 | 3. 모든 기능 완료 후 `release` 브랜치를 만들어 QA를 하며 `보완` 및 `버그 픽스` 수행
37 | 4. 완료 후 release 브랜치를 `develop` 브랜치와 `master` 브랜치로 보냄
38 | 5. `master` 브랜치에서 버전 추가를 위해 태그를 하나 생성하고 배포
39 | 6. 배포 후 갑작스런 버그 발견 및 발생 시 `hotfix` 브랜치를 만들어 `긴급 수정` 후 태그를 생성하고 바로 `수정 배포`
40 |
41 | ---
42 |
43 | ### 참고 자료
44 |
45 | - [@nvie](https://nvie.com/posts/a-successful-git-branching-model/)
46 | - [@nJo2](https://ux.stories.pe.kr/183)
47 | - [@gangnamunni](https://blog.gangnamunni.com/post/understanding_git_flow/)
48 |
--------------------------------------------------------------------------------
/Cloud and DevOps/terraform/terraform.md:
--------------------------------------------------------------------------------
1 | # **Terraform**
2 |
3 | : HashiCorp사가 만든 오픈 소스 `코드형 인프라 툴`
4 |
5 | - 현재 공급되는 가장 인기 있는 인프라 자동화 툴 중 하나
6 | - 단순 구문을 사용하여 여러 클라우드 및 on-premise 데이터 센터에서 `인프라 프로비저닝`, `구성 변경`에 대한 반응으로 인프라를 안전하고 효율적으로 `다시 프로비저닝`
7 | - 개발자가 HCL(; HashiCorp Configuration Language)이라 불리는 `상위 레벨 구성 언어를 사용`하여 애플리케이션 실행을 위해 원하는 엔드 상태 클라우드 또는 on-premise 인프라를 `기술`하도록 함
8 | - 이후 해당 엔드 상태에 도달하기 위한 `계획 생성` 및 `인프라를 프로비저닝`하기 위한 계획 실행
9 |
10 | ### ⭐️ 조직이 하이브리드 클라우드 또는 멀티 클라우드 환경을 전개할 경우, Terraform 사용을 원하거나 필요할 수 있다!
11 |
12 | ```text
13 | ✎ 멀티 클라우드: 기업이 각각의 특정 애플리케이션 또는 서비스를 제공하는 클라우드 플랫폼을 두 개 이상 사용하는 환경을 말하며, 목표는 퍼블릭, 프라이빗, 엣지
14 | 클라우드로 구성하는 것이다.
15 | ✎ 하이브리드 클라우드: 멀티 클라우드의 하위 집단으로, on-premise it를 퍼블릭 클라우드 또는 클라우드 서비스 제공업체의 오프 프레미스 등(AWS, GCP,
16 | Azure)과 결합하는 환경
17 |
18 | → 멀티 클라우드 환경에서는 상호 운용성이 있거나 없는 상태에서 여러 클라우드가 존재하고 사용되는데, 여러 서비스 모델에 대한 액세스를 제공하므로 이러한 새로운
19 | 아키텍처가 점점 더 많이 활용되고 있다.
20 | ```
21 |
22 |
23 |
24 | ## 코드형 인프라의 장점
25 |
26 | - 속도 향상
27 | - 자원 배치 및 연결을 하는 경우 인터페이스의 수동 탐색보다 `자동화가 빠름`
28 | - 안정성 향상
29 | - 인프라 규모가 클 경우, 자원 또는 프로비저닝 서비스를 `잘못된 순서로 구성할 수 있는 위험` 감소
30 | - 사용자 환경을 프로비저닝한 구성이 실제 환경과 더 이상 일치하지 않는 경우 발생하는 `구성 드리프트 방지`
31 | - 실험, 테스트 및 최적화 지원
32 |
33 |
34 |
35 | ## Terraform을 사용하는 이유
36 |
37 | - 개방형 소스
38 | - 대규모 커뮤니티 지원
39 | - 신속하게 진화하고 새로운 이점과 개선된 기능이 지속적으로 향상
40 | - 플랫폼 애그노스틱
41 | - 모든 클라우드 서비스 공급자와 함께 사용 가능
42 | - 대부분의 다른 코드형 인프라 툴은 단일 클라우드 공급자와 함께 작동하도록 설계돼 있음
43 | - 변경 불가 인프라
44 | - 대부분의 코드형 인프라는 변경 가능 인프라 생성
45 | - 인프라가 미들웨어 update 또는 새 스토리지 서버와 같은 변경을 수용하도록 변화 가능
46 | - 변경 내용이 쌓이면서 다른 서버 또는 기타 인프라 요소의 실제 프로비저닝이 원래 구성에서 멀어짐 (드리프트)
47 | - Terraform은 환경에 대한 모든 변경사항에 대해 현재 구성이 변경을 기술하는 새로운 구성으로 대체되고 인프라가 다시 프로비저닝됨
48 | - 이전 구성은 필요하거나 원할 경우 롤백이 가능한 버전으로 유지 가능
49 |
50 |
51 |
52 | ## Kubernetes와의 차이
53 |
54 | > _→ 결론: 실제로 둘은 서로 대안이 아니며 실제로 효과적으로 협력한다!_
55 |
56 | Terraform은 IaaS, PaaS, 심지어 SaaS 레벨 기능을 자동화 및 관리할 수 있으며, 모든 해당 제공자들 간에 병렬로 이러한 모든 리소스를 구축할 수 있다. Terraform을 사용하여 Kubernetes(특히 클라우드 플랫폼의 관리형 Kubernetes 클러스터)의 프로비저닝을 자동화하고 클러스터에 애플리케이션 배치를 자동화할 수 있다.
57 |
58 | ---
59 |
60 | ### 참고자료
61 |
62 | - [ibm 게시물](https://www.ibm.com/kr-ko/cloud/learn/terraform)
63 |
--------------------------------------------------------------------------------
/Computer Science/Algorithm/bruteForce.md:
--------------------------------------------------------------------------------
1 | ## 1. Brute-Force Algorithm
2 |
3 | → 가능한 `모든` 경우의 수를 `모두` 체크해서 정답을 찾는 방법
4 |
5 |
6 | ### 기본적인 2가지 규칙
7 |
8 | - ① 사용된 알고리즘이 적절한가? (문제 해결이 가능한가?)
9 | - ② 효율적으로 동작하는가?
10 |
11 | 다른 알고리즘을 사용하면 O(N)으로 해결되는 어떤 문제가 있다고 가정했을 때, 이 문제를 O(N²)이 걸리는 Brute-Force를 사용하는 것은 옳지 않다! 따라서 아래와 같은 사항을 고려해서 수행해야 한다.
12 |
13 | - 해결하고자 하는 문제의 가능한 경우의 수를 대략적으로 계산
14 | - 가능한 모든 방법을 다 고려
15 | - 실제 답을 구할 수 있는지 적용
16 |
17 |
18 |
19 | ## 2. 완전 탐색 기법
20 |
21 | > ### i) 단순 완전탐색 문제
22 |
23 | - 특별한 어느 기법을 사용하지 않고, 단순히 `반복문`과 `조건문` 등으로 모든 경우의 수를 만들어 답을 구하는 방식
24 | - 시간복잡도가 O(N²)이나 `O(N!)`이기 때문에 케이스의 범위를 보고 사용해야 함
25 | - 사실 간단한 문제이기 때문에 코딩 테스트 문제로 자주 출제되지 않음
26 |
27 |
28 |
29 | > ### ii) 비트 마스크 (Bit-Mask)
30 |
31 | - 비트 연산을 통해 부분 집합을 표현하는 방법
32 | - and(`&`), or(`|`), not(`~`), xor(`^`), shift(`<<`, `>>`)
33 |
34 | | A | B | A & B | A | B | ~A | A ^ B |
35 | | :-: | :-: | :---: | :--------: | :-: | :-------: |
36 | | 0 | 0 | 0 | 0 | 1 | 0 |
37 | | 0 | 1 | 0 | 1 | 1 | 1 |
38 | | 1 | 0 | 0 | 1 | 0 | 1 |
39 | | 1 | 1 | 1 | 1 | 0 | 0 |
40 |
41 |
42 |
43 | > ### iii) Recursive
44 |
45 | → 말 그대로 자기 자신을 호출
46 |
47 | - 재귀를 탈출하기 위한 `탈출 조건` 필요
48 | - 현재 함수의 `상태를 저장`하는 Parameter 필요
49 | - `return문`을 신경쓸 것
50 |
51 | #### → DP와의 차이점
52 |
53 | - DP: 작은 문제가 큰 문제와 `동일한 구조`를 가져 큰 문제의 답을 구할 시에 작은 문제의 결과를 `기억`한 뒤 그대로 사용하여 수행속도르 빠르게 함
54 | - 완전탐색은 크고 작은 문제의 구조가 `다를 수 있고`, 해결 가능한 방법을 `모두 탐색`
55 |
56 |
57 |
58 | > ### iv) 순열과 조합 (Permutation and Combination)
59 |
60 | - [순열 (Permutation)](https://github.com/lcomment/development-recipes/blob/main/Computer%20Science/Algorithm/permutaion.md)
61 | - [조합 (Combination)](https://github.com/lcomment/development-recipes/blob/main/Computer%20Science/Algorithm/combination.md)
62 |
63 |
64 |
65 | > ### v) DFS / BFS
66 |
67 | - [깊이 우선 탐색 (DFS)](https://github.com/lcomment/development-recipes/blob/main/Computer%20Science/Algorithm/dfs.md)
68 | - [너비 우선 탐색 (BFS)](https://github.com/lcomment/development-recipes/blob/main/Computer%20Science/Algorithm/bfs.md)
69 |
--------------------------------------------------------------------------------
/Computer Science/Algorithm/catalan.md:
--------------------------------------------------------------------------------
1 | ## 카탈란 수 (Catalan Number)
2 |
3 | 
4 |
5 | 𝙣 번째 카탈란 수 𝘾𝘯 이란 위의 점화식을 만족하는 수열의 𝙣 번째 항이다. 이 수열의 첫 10개의 항을 나열하면 `1, 1, 2, 5, 14, 43, 132, 429, 1430, 4862, ... (𝘾₀~𝘾₉)` 이다. 코드로 표현하면 아래와 같다.
6 |
7 | ```java
8 | // java 코드
9 | public int catalan(int n) {
10 | int dp[] = new int[n + 1];
11 | dp[0] = 1;
12 | dp[1] = 1;
13 |
14 | for (int i = 2; i <= n; i++) {
15 | for (int j = 1; j <= i; j++) {
16 | dp[i] += dp[i-j] * dp[j-1];
17 | }
18 | }
19 |
20 | return dp[n];
21 | }
22 | ```
23 |
24 |
25 |
26 | 카탈란 수는 조합론에서 빈번하게 등장하는 수 중 하나로, 아래와 같은 문제들의 해답이 모두 카탈란 수로 주어진다.
27 |
28 | > ### 1. 올바른 괄호
29 |
30 | : n쌍의 여는 괄호 `(`와 닫는 괄호 `)`로 만들 수 있는 올바른 괄호 구조의 가짓수와 같다.
31 |
32 | 
33 |
34 | > ### 2. 산 만들기
35 |
36 | : 괄호와 비슷하게 `/`와 `\`을 n쌍으로 산을 만들 수 있는 방법과 같다.
37 |
38 | 
39 |
40 | > ### 3. 다각형을 삼각형으로 나누기
41 |
42 | : (n+2)각형을 n개의 삼각형으로 나누는 방법의 개수와 같다.
43 |
44 | 
45 |
46 | > ### 4. 대각선 피해가기
47 |
48 | : (n x n) 격자의 좌측 하단 좌표 `(0, 0)`에서 우측 상단 좌표 `(n, n)`을 향해 대각선을 피해 최단거리로 이동하는 경우의 수와 같다.
49 |
50 | 
51 |
52 | > ### 5. 계단 채우기
53 |
54 | : 높이가 n인 계단 모양을 n개의 직사각형으로 완전히 채울 수 있는 경우의 수와 같다.
55 |
56 | 
57 |
58 |
59 |
60 | ## 증명하기
61 |
62 |
63 | 점화식 이해하기
64 | 
65 |
66 |
67 |
68 | 카탈란 수의 계산
69 | 
70 |
71 |
72 |
73 |
74 | ---
75 |
76 | ### **참고자료**
77 |
78 | - Web
79 | - [#wikipedia](http://en.wikipedia.org/wiki/Eug%C3%A8ne_Charles_Catalan)
80 | - [#geometer](http://www.geometer.org/mathcircles/catalan.pdf)
81 | - [@suhak](https://suhak.tistory.com/77)
82 | - [@jjycjnmath](https://jjycjnmath.tistory.com/139)
83 |
--------------------------------------------------------------------------------
/Computer Science/Algorithm/ccw.md:
--------------------------------------------------------------------------------
1 | ## CCW 알고리즘
2 |
3 | CCW 알고리즘은 `Counter Clockwise`의 약자로, 평면 위에 놓여진 세 점의 방향관계를 구할 수 있는 알고리즘이다. 이 알고리즘은 점 A, B, C를 순서대로 봤을 때, 반시계 방향으로 놓여 있으면 양수를, 시계방향이면 음수를, 평행하게 놓여있으면 0을 반환한다.
4 |
5 | ```java
6 | int ccw(Point A, Point B, Point C) {
7 | int a = A.x*B.y + B.x*C.y + C.x*A.y;
8 | int b = A.y*B.x + B.y*C.x + C.y*A.x;
9 |
10 | return a-b;
11 | }
12 | ```
13 |
14 | 위의 코드는 CCW 알고리즘을 Java 코드로 구현한 것이다. CCW 알고리즘은 기하 알고리즘의 기초라고 할 수 있으니 알아두도록 하자.
15 |
--------------------------------------------------------------------------------
/Computer Science/Algorithm/combination.md:
--------------------------------------------------------------------------------
1 | ## 조합 (Combination)
2 |
3 | 조합(Combination)이란 n개 중 r개를 중복과 순서 없이 뽑는 경우의 수를 말한다. 순서가 없다는 점에서 순열(Permutation)과 다르다.
4 |
5 | 순열과 마찬가지로 조합 또한 많이 쓰이는 알고리즘이다. 만약 `C++`을 사용한다면 algorithm 라이브러리의 `prev_permutation()` 함수를 이용하여 조합을 간단하게 구현해주면 되고, `python`을 사용한다면 그보다 더 쉽게 `from itertools import combinations`로 조합을 import 해준 후 `combinations()` 함수를 사용하면 된다. `Java`는 순열과 마찬가지로 존재하지 않아 구현해줘야 한다. 방법이 여러가지 있지만, 다음 예제는 `백트래킹`으로 구현한 것이다.
6 |
7 | ```java
8 | // combination(arr, visited, 0, n, r, 0)
9 |
10 | int[] combination(int[] arr, boolean[] visited, [] int start, int n, int r, int cnt) {
11 | if(cnt == r){
12 | return save(arr, visited, r)
13 | }
14 |
15 | for(int i=start ; i
58 |
59 | ## 중복조합 (Combination With Repetition)
60 |
61 | 중복조합은 n개 중 `순서 없이`, `중복 가능`하게 r개를 뽑는 경우의 수를 말한다. 조합과 비슷하게 구현 가능하고, 가장 큰 차이점은 방문을 체크하는 `visited 배열의 유무`다.
62 |
63 | ```java
64 | public static void combinationRepetition(int[] arr, int[] out, int start, int depth, int r){
65 | if(depth == r){
66 | for(int num : out)
67 | System.out.print(num);
68 | System.out.println();
69 | return;
70 | }
71 | for(int i=start; i
79 |
80 | ---
81 |
82 | ### **참고자료**
83 |
84 | - Web
85 | - [@bcp0109](https://bcp0109.tistory.com/15)
86 | - [@cgw0519](https://velog.io/@cgw0519/알고리즘-순열-중복순열-조합-중복조합-총정리)
87 |
--------------------------------------------------------------------------------
/Computer Science/Algorithm/dijkstra.md:
--------------------------------------------------------------------------------
1 | ## **다익스트라 알고리즘** (Dijkstra's Algorithm)
2 |
3 | : 그래프에서 한 정점에서 다른 정점까지의 최단 경로를 구하는 알고리즘 중 하나
4 |
5 | - 도착 정점뿐 아니라 모든 정점까지의 최단 경로를 모두 찾음
6 | - 매번 최단 경로의 정점을 선택해 탐색 반복
7 | - 음의 가중치가 존재하지 않는다는 가정 안에서 그리디 알고리즘의 관점으로 동작
8 | - 구현 방법이 여러 가지고, 어떤 방법을 쓰느냐에 따라 시간복잡도가 달라짐
9 |
10 |
11 |
12 | ### **동작 순서**
13 |
14 | 
15 |
16 | - ① 최단 비용 테이블 초기화
17 | - ② 출발 정점 선택
18 | - ③ Loop:
19 | - 현재 정점 방문 처리
20 | - 현재 정점 기준 인접 노드 최소 비용 계산
21 | - 현재 정점의 방문하지 않은 인접 노드 중 거리가 가장 짧은 노드를 선택
22 | - ④ 모든 정점 방문 시, Loop를 빠져나가면서 종료
23 |
24 |
25 |
26 | ## **구현**
27 |
28 | ### **DIJKSTRA(G, w, s)**
29 |
30 | ```
31 | // Initialize
32 | for each vertex v ∈ G.V
33 | v.d = ∞
34 | v.π = NIL
35 |
36 | S = Ø // 공집합
37 | Q = G.V // 전체집합
38 |
39 | while Q != Ø
40 | u = EXTRACT-MIN(Q)
41 | S = S U {u}
42 |
43 | for each vertex v ∈ G.adj[u]
44 | // Relax
45 | if v.d > u.d + w(u, v)
46 | v.d = u.d + w(u, v)
47 | v.π = u
48 | ```
49 |
50 | ### **i) 순차 탐색 이용**
51 |
52 | - 각 정점마다 인접한 간선들을 모두 검사
53 | - 시간복잡도: (V-1) x V = O(V²)
54 | - V: 노드의 수
55 |
56 |
57 |
58 | ### **ii) 우선순위 큐 이용**
59 |
60 | - 우선순위 큐에 원소를 넣고 삭제
61 | - 시간복잡도: O(E•logV)
62 | - E: 간선의 수
63 | - V: 노드의 수
64 |
65 |
66 |
67 | ---
68 |
69 | ### **참고자료**
70 |
71 | - Web
72 | - [@gomgomkim](https://gomgomkim.tistory.com/19)
73 |
--------------------------------------------------------------------------------
/Computer Science/Algorithm/kmp.md:
--------------------------------------------------------------------------------
1 | ## **KMP 알고리즘**
2 |
3 | KMP(; Knuth-Morris-Pratt) 알고리즘은 문자열 중에 특정 패턴을 찾아내는 문자열 검색 알고리즘의 하나다. 이 알고리즘을 만든 Knuth, Morris, Pratt의 이름 중 첫 알파벳을 따 KMP 알고리즘이라고 부른다.
4 |
5 | KMP 알고리즘은 `접두사`와 `접미사`를 활용하여 중복 연산을 줄인다. 접두사는 문자열에서 앞쪽을 떼어내어 만든 부분 문자열을 말하고, 접미사는 문자열 전체에서 뒷쪽을 떼어내어 만든 부분 문자열을 말한다. 이 알고리즘을 구현할 때 `table` 배열을 하나 선언해줘야 한다. 문자열의 0부터 i인 부분 문자열에서 길이가 `value`인 접두사와 길이가 `value`인 접미사가 일치한다고 했을 때, 이 table 배열의 인덱스 i에 해당하는 요소의 값은 value의 최대값이 된다. 단, 접두사와 접미사가 부분 문자열 전체와 일치해서는 안된다.
6 |
7 | | i | 부분문자열 | table[i] |
8 | | :-: | :----------: | :------: |
9 | | 0 | A | 0 |
10 | | 1 | AB | 0 |
11 | | 2 | `A`B`A` | 1 |
12 | | 3 | ABAC | 0 |
13 | | 4 | `A`BAC`A` | 1 |
14 | | 5 | `A`BACA`A` | 1 |
15 | | 6 | `AB`ACA`AB` | 2 |
16 | | 7 | `ABA`CA`ABA` | 3 |
17 |
18 | 위 표는 `ABACAABA`의 table 배열이다. 부분 문자열의 접두사와 접미사가 일치하는 최댓값을 각 요소에 저장해주었다. 아래 코드는 table 배열을 생성해주는 메서드다. (`자바 코드`)
19 |
20 | ```java
21 | public static void makeTable(String pattern) {
22 | int len = pattern.length();
23 | table = new int[len];
24 |
25 | int index = 0;
26 | for(int i = 1; i < len; i++) {
27 | while(index > 0 && pattern.charAt(i) != pattern.charAt(index)) {
28 | index = table[index - 1];
29 | }
30 |
31 | if(pattern.charAt(i) == pattern.charAt(index)) {
32 | index += 1;
33 | table[i] = index;
34 | }
35 | }
36 | }
37 | ```
38 |
39 | 이렇게 table 배열을 선언 및 초기화 후 문자열을 비교한다. `makeTable()` 메서드를 사용해 만든 table 배열을 통해 두 문자열을 비슷한 방식으로 비교하여 문자열 `str`에 문자열 `pattern`이 포함되는지 탐색할 수 있다.
40 |
41 | ```java
42 | public static int search(String str, String pattern) {
43 | int sLen = str.length();
44 | int pLen = pattern.length();
45 |
46 | int index = 0;
47 | for(int i = 0; i < sLen; i++) {
48 | while(index > 0 && str.charAt(i) != pattern.charAt(index)) {
49 | index = table[index - 1];
50 | }
51 |
52 | if(str.charAt(i) == pattern.charAt(index)) {
53 | if(index == pLen - 1) {
54 | index = table[index];
55 | return 1;
56 | }
57 | else {
58 | index++;
59 | }
60 | }
61 | }
62 | return 0;
63 | }
64 | ```
65 |
66 |
67 |
68 | ### **관련 문제**
69 |
70 | - [BOJ 16916 부분문자열](https://www.acmicpc.net/problem/16916)
71 | - [BOJ 1786 찾기](https://www.acmicpc.net/problem/1786)
72 |
73 |
74 |
75 | ---
76 |
77 | ### **참고자료**
78 |
79 | - Web
80 | - [#wikipedia](https://en.wikipedia.org/wiki/Knuth–Morris–Pratt_algorithm)
81 | - [@hanyeop](https://hanyeop.tistory.com/355?category=942306)
82 | - [@junstar92](https://junstar92.tistory.com/112?category=884881)
83 | - [@wns7756](https://m.blog.naver.com/wns7756/221852410609)
84 |
--------------------------------------------------------------------------------
/Computer Science/Algorithm/mst.md:
--------------------------------------------------------------------------------
1 | ## **Spanning Tree란?**
2 |
3 | 
4 |
5 | - 그래프 내의 모든 정점을 포함하는 트리
6 | - 그래프의 최소 연결 부분 그래프
7 | - 최소 연결은 간선의 수가 가장 적다는 것을 의미
8 | - n개의 정점을 가지는 그래프의 최소 간선의 수 = (n-1)개
9 | - 그래프에서 일부 간선을 선택해 만든 트리
10 |
11 | ### **특징**
12 |
13 | - DFS, BFS 등을 이용해 신장 트리를 찾을 수 있음
14 | - 하나의 그래프는 많은 신장 트리를 포함할 수 있음
15 | - 모든 정점들이 연결돼 있지만, 사이클이 있으면 안됨
16 | - 따라서 그래프 내 n개의 정점을 정확히 (n-1)개의 간선으로 연결해야 함
17 |
18 |
19 |
20 | ## **최소 신장 트리 (MST; Minimum Spanning Tree)**
21 |
22 | 
23 |
24 | : Spanning Tree 중 사용된 간선들의 가중치 합이 최소인 트리
25 |
26 | - 간선의 가중치 합이 최소여야 함
27 | - n개의 정점을 갖는 그래프에 대해 반드시 (n-1)개의 간선만을 사용해야 함
28 | - 사이클이 없어야 함
29 |
30 | ### MST 구현 방법
31 |
32 | - [Kruskal MST 알고리즘](https://github.com/lcomment/development-recipes/blob/main/Computer%20Science/Algorithm/kruskal.md)
33 | - [Prim MST 알고리즘]()
34 |
35 |
36 |
37 | ---
38 |
39 | ### **참고자료**
40 |
41 | - Web
42 | - [@gmlwjd9405](https://gmlwjd9405.github.io/2018/08/28/algorithm-mst.html)
43 |
--------------------------------------------------------------------------------
/Computer Science/Algorithm/permutation.md:
--------------------------------------------------------------------------------
1 | ## 순열 (Permutation)
2 |
3 | 순열(Permutation)이란 n개 중 r개를 중복 없이 뽑아 `정렬`하는 경우의 수를 말한다. 정렬, 즉 `순서가 있다`는 점에서 조합(Combination)과 다르다.
4 |
5 | 알고리즘 문제를 풀다보면 문제의 서브 알고리즘으로 순열을 사용하는 경우가 종종 있다. 만약 `C++`을 사용한다면 algorithm 라이브러리의 `prev_permutation()` 함수를 이용하면 되고, `python`을 사용한다면 그보다 더 쉽게 `from itertools import permutations`로 순열을 import 해준 후 `permutations()` 함수를 사용하면 된다. 그렇다면 `Java`는? Java는 순열 관련 라이브러리가 존재하지 않기 때문에 메서드로 구현해주어야 한다. 방법이 여러가지 있지만, 다음 예제는 `백트래킹`으로 구현한 것이다.
6 |
7 | ```java
8 | void permutation(int[] arr, int[] out, boolean[] visited, int depth, int r){
9 | if(depth == r){
10 | for(int num: out)
11 | System.out.print(num);
12 | System.out.println();
13 | return;
14 | }
15 |
16 | for(int i=0; i
28 |
29 | ## 중복순열 (Permutation With Repetition)
30 |
31 | 중복순열은 n개 중 `중복 가능`하게 r개를 뽑아 `정렬`하는 경우의 수를 말한다. 순열과 비슷하게 구현 가능하고, 가장 큰 차이점은 방문을 체크하는 `visited 배열의 유무`다.
32 |
33 | ```java
34 | void permutation(int[] arr, int[] out, int depth, int r){
35 | if(depth == r){
36 | for(int num: out)
37 | System.out.print(num);
38 | System.out.println();
39 | return;
40 | }
41 |
42 | for(int i=0; i
50 |
51 | ---
52 |
53 | ### **참고자료**
54 |
55 | - Web
56 | - [@cgw0519](https://velog.io/@cgw0519/알고리즘-순열-중복순열-조합-중복조합-총정리)
57 |
--------------------------------------------------------------------------------
/Computer Science/Algorithm/shortestPath.md:
--------------------------------------------------------------------------------
1 | ## Single-Source Shortest Path
2 |
3 | 최단 경로 문제는 쉽게 접할 수 있는 알고리즘 문제 중 한 가지다. 최단 경로 문제에도 여러 유형이 있는데, 그 유형들은 다음과 같다.
4 |
5 | - Single-Source (One to All)
6 | - Single-Destination (All to One)
7 | - Single-Pair (One to One)
8 | - All-Pairs (All to All)
9 |
10 | 이 네 가지 중 `Single-Source` 문제에 대해 다룰 예정이다. 이 문제에서 몇몇 특징을 찾을 수 있는데,
11 |
12 | - 최단 경로는
13 | - `부분 경로` 또한 최단 경로이다.
14 | - `가중치(weight)`가 양이든, 음이든, 0이든 `사이클(Cycle)`을 포함하지 않는다.
15 |
16 |
17 |
18 | - 그래프 𝐺(𝑉, 𝐸)의 경로는
19 | - 정점을 𝑉 이하 가진 것만 고려한다.
20 | - 간선은 𝑉-1개 이하인 것만 고려한다.
21 |
22 |
23 |
24 | ### Single-Source 문제 해결방법
25 |
26 | - [Dijkstra 알고리즘](https://github.com/lcomment/development-recipes/blob/main/Computer%20Science/Algorithm/dijkstra.md)
27 | - [Bellman-Ford 알고리즘](https://github.com/lcomment/development-recipes/blob/main/Computer%20Science/Algorithm/bellmanFord.md)
28 |
--------------------------------------------------------------------------------
/Computer Science/Algorithm/substring.md:
--------------------------------------------------------------------------------
1 | ## **문자열 탐색**
2 |
3 | 알고리즘 문제 중 가장 기본이라고 판단되는 유형은 문자열 문제다. "Hello World"라는 문자열에서 "Hello"를 찾는다고 가정하자. 우리가 간단하게 로직을 구현하여 쉽게 찾을 수 있다.
4 |
5 | ```java
6 | // 자바 코드
7 | public class SearchSubstring {
8 | public static void main(String[] args) throws IOException {
9 | String str = "Hello World";
10 | String find = "Hello";
11 |
12 | System.out.println(str.contains(find));
13 | }
14 | }
15 | ```
16 |
17 | 하지만 위와 같이 구현하거나 for문을 통한 완전탐색으로 구현하면, 입력을 받아 처리를 할 경우 최대 시간복잡도는 `O(N*M)`이다. 문자열의 길이가 길어질수록 걸리는 시간은 당연히 급격하게 증가해서 시간초과가 발생할 수 있다. 따라서 문자열 탐색에 유리한 알고리즘을 학습해야 할 필요가 있다.
18 |
19 |
20 |
21 | ## **문자열 탐색 알고리즘**
22 |
23 | - ### [KMP 알고리즘](https://github.com/lcomment/development-recipes/blob/main/Computer%20Science/Algorithm/kmp.md)
24 | - ### [Rabin-karp 알고리즘](https://github.com/lcomment/development-recipes/blob/main/Computer%20Science/Algorithm/rabinKarp.md)
25 |
--------------------------------------------------------------------------------
/Computer Science/Data Structure/bTree.md:
--------------------------------------------------------------------------------
1 | ## B-Tree
2 |
3 | : 이진트리를 확장해 하나의 노드가 가질 수 있는 자식 노드의 최대 숫자가 `2보다 큰` 트리 구조
4 |
5 | - 이진 트리를 확장해 더 많은 수의 자식을 가질 수 있게 일반화
6 | - 많은 데이터베이스 시스템의 `인덱스 저장 방법`으로 애용됨
7 |
8 |
9 |
10 | > ### 규칙
11 |
12 | - 노드 안에 `k`개의 데이터가 있다면 자식 노드 수는 `k+1`개여야 한다.
13 | - 노드안에 데이터는 `정렬`돼 있어야 한다.
14 | - 자식 노드의 데이터는 부모의 데이터 값에 따라 배치된다.
15 | - 루트 노드가 리프 노드가 아닌 경우 `항상 2개 이상`의 자식을 가진다
16 | - M차 B-Tree라면 루트 노드와 리프 노드를 제외하고 최소 `M/2` 이상의 데이터를 가지고 있어야 한다.
17 | - 모든 리프 노드의 `높이는 같아야 한다`.
18 | - 리프 노드의 데이터 수는 `M-1` 이하여야 한다.
19 |
20 |
21 |
22 | ## B\*Tree
23 |
24 | : 하나의 구조를 유지하기 위해 `추가적인 연산`이 수행되거나 `새로운 노드가 생성`한다는 B-Tree의 단점을 `최소화`하기 위해 몇 가지 규칙이 추가된 트리 구조
25 |
26 | > ### B-Tree와의 차이
27 |
28 | - 기존 노드의 자식 노드 수 최소 제약 조건 : 최소 `M/2` → `2M/3`
29 | - 노드가 가득 차면 분열 대신 이웃한 형제 노드로 재배치
30 |
31 |
32 |
33 | > ### 특징
34 |
35 | - 각 노드의 자료가 `정렬`돼있다.
36 | - 자료가 중복되지 않는다.
37 | - 모든 Leaf Node는 같은 레벨에 있다.
38 | - Root Node는 자신이 Leaf Node가 되지 않는 이상 `최소 2개` 이상의 자식노드를 갖는다.
39 | - Root Node가 아닌 노드들은 최소 `2{(M-2)/3}+1`, 최대 `M`개의 자식 노드를 갖는다.
40 |
41 |
42 |
43 | ## B+Tree
44 |
45 | : 탐색을 위해 노드를 찾아 이동해야 한다는 B-Tree의 단점을 해소하기 위해 같은 레벨의 모든 키 값들이 정렬돼 있고, 같은 레벨의 형제 노드는 연결리스트 형태로 이어져 있는 트리 구조
46 |
47 | - Leaf Node가 아닌 자료 → 인덱스 노드
48 | - Leaf Node 자료 → 데이터 노드
49 | - 키 값은 중복 가능
50 | - 데이터 탐색을 위해 `반드시 Leaf Node`까지 내려가야 함
51 | - `검색 속도`를 위해 대부분의 데이터베이스 시스템에서 B+Tree 구조 채택
52 |
53 |
54 |
55 | > ### 특징
56 |
57 | - 데이터 노드의 자료는 `정렬`돼 있다.
58 | - 데이터 노드에서는 `데이터가 중복되지 않는다`.
59 | - 모든 Leaf Node는 `같은 레벨`에 있다.
60 | - Leaf Node가 아닌 노드의 키 값의 수는 그 노드의 서브트리 수보다 하나 적다.
61 | - 모든 Leaf Node는 `연결리스트`로 연결돼 있다.
62 |
63 |
64 |
65 | ---
66 |
67 | ### Reference
68 |
69 | - [@code-lab](https://code-lab1.tistory.com/217)
70 | - [@ssocoit](https://ssocoit.tistory.com/217)
71 |
--------------------------------------------------------------------------------
/Computer Science/Data Structure/binaryTree.md:
--------------------------------------------------------------------------------
1 | ## 이진트리 (Binary Tree)
2 |
3 | : 모든 노드가 정확하게 `두 개`의 서브 트리를 가지고 있는 트리
4 |
5 | - 이진트리의 `레벨 n`에서 노드의 최대 수 → `2ⁿ`
6 | - 최대 높이가 `h`일 때 최대 노드 수 → `2ʰ-1`
7 | - Leaf Node 높이가 1일 때 최소 높이 → `log₂(N+1)`
8 |
9 |
10 |
11 | ## 이진트리 유형
12 |
13 | > ### 전 이진트리 (Full Binary Tree, Strict Binary Tree)
14 |
15 | : 모든 노드가 `0개` 또는 `2개`의 자식노드를 갖는 트리
16 |
17 |
18 |
19 | > ### 완전 이진트리 (Complete Binary Tree)
20 |
21 | : 마지막 레벨을 제외하고 모든 레벨이 `왼쪽에서 오른쪽으로` 완전히 채워져 있는 트리
22 |
23 |
24 |
25 | > ### 포화 이진트리 (Perfect Binary Tree)
26 |
27 | : 모든 내부 노드가 `2개`의 자식노드를 가지며 모든 잎 노드가 `동일한 깊이` 또는 레벨을 갖는 트리
28 |
29 |
30 |
31 | > ### 균형 이진트리 (Balanced Binary Tree)
32 |
33 | : 왼쪽과 오른쪽 트리의 높이 차이가 모두 `1`만큼 나는 트리
34 |
35 | - AVL Tree
36 | - Red-Black Tree
37 | - B-Tree, B\*Tree, B+Tree
38 |
39 |
40 |
41 | ---
42 |
43 | ### Referencs
44 |
45 | - [@ratsgo](https://ratsgo.github.io/data%20structure&algorithm/2017/10/21/tree/)
46 | - [@yoongrammer](https://yoongrammer.tistory.com/69#이진트리_속성)
47 |
--------------------------------------------------------------------------------
/Computer Science/Data Structure/list.md:
--------------------------------------------------------------------------------
1 | ## ArrayList와 LinkedList
2 |
3 | > ### ArrayList
4 |
5 | - 원하는 데이터에 `무작위로 접근` 가능
6 | - `용량에 제한`이 있어, 확장할 때 많은 연산 필요
7 | - 데이터 삽입/삭제를 위해 임시 배열을 생성 및 복제 → 시간이 오래 걸림
8 |
9 |
10 |
11 | > ### LinkedList
12 |
13 | - 용량에 영향 없이 데이터 추가 가능
14 | - 삽입 → 새로운 노드를 생성하여 연결
15 | - 삭제 → 해당 노드의 연결 해제
16 | - 무작위 접근 불가능 → 순차 접근만 가능
17 |
18 |
19 |
20 | > ### **LinkedList와 ArrayList의 차이**
21 |
22 | - `순차`적으로 삽입/삭제하는 경우, `ArrayList`가 효율적
23 | - `중간` 데이터를 삽입/삭제하는 경우, `LinkedList`가 효율적
24 |
25 | | Collection | 접근시간(읽기) | 삽입 / 삭제 | 설명 |
26 | | :--------: | :------------: | :---------: | ------------------------------------------------------------ |
27 | | ArrayList | 빠르다 | 느리다 | ✓ 순차적인 삽입삭제는 더 빠름 ✓ 비효율적인 메모리 사용 |
28 | | LinkedList | 느리다 | 빠르다 | ✓ 데이터가 많을수록 접근성이 떨어짐 |
29 |
--------------------------------------------------------------------------------
/Computer Science/Data Structure/tree.md:
--------------------------------------------------------------------------------
1 | ## 트리 (Tree)
2 |
3 | : 노드(Node)들이 나뭇가지처럼 연결된 `비선형 계층적 자료구조`
4 |
5 | - 트리 내에 하위 트리 있는 `재귀적` 자료구조
6 | - 임의의 노드에서 다른 노드로 가는 경로는 유일함
7 | - 순환구조(cycle)이 존재하지 않음
8 | - 모든 노드는 서로 `연결`돼 있음
9 | - 간선(edge)를 하나 자르면 트리가 2개로 분리됨
10 |
11 |
12 |
13 | > ### 트리의 구성
14 |
15 |
16 |
17 |
18 |
19 | - 노드 (Node)
20 | - 트리를 구성하는 기본 요소
21 | - Key 또는 값과 하위 노드에 대한 포인터(Pointer)를 가지고 있음
22 | - `루트 노드` (Root Node) : 트리 구조에서 부모가 없는 최상위 노드
23 | - `부모 노드` (Parent Node) : 자식 노드를 가진 노드
24 | - `자식 노드` (Child Node) : 부모 노드의 하위 노드
25 | - `형제 노드` (Sibiling Node) : 같은 부모를 가진 노드
26 |
27 |
28 |
29 | - 외부 노드 (External Node, Outer Node)
30 | - 단말 노드(Terminal Node) 또는 리프 노드(Leaf Node)라고도 불림
31 | - 자식 노드가 없는 노드
32 | - H, I, J, F, G
33 |
34 |
35 |
36 | - 내부 노드 (Internal Node, Inner Node)
37 | - 비 단말 노드(Non-Terminal Node) 또는 가지 노드(Branch Node)
38 | - 자식 노드를 하나 이상 가진 노드
39 | - A, B, C, D, E
40 |
41 |
42 |
43 | - 간선 (Edge)
44 | - 노드와 노드 간의 연결선
45 | - 노드의 개수가 `n`개라면 간선의 개수는 `n-1`개
46 |
47 |
48 |
49 | - `깊이` (Depth)
50 | - 루트에서 어떤 노드까지의 간선 수
51 | - Root Node의 깊이 == 0
52 | - `높이` (Height)
53 | - 어떤 노드에서 리프 노드까지 가장 긴 경로의 간선 수
54 | - Leaf Node의 높이 == 0
55 |
56 |
57 |
58 | ---
59 |
60 | ### Reference
61 |
62 | - [@yoongrammer](https://yoongrammer.tistory.com/68)
63 | - [@ratsgo](https://ratsgo.github.io/data%20structure&algorithm/2017/10/21/tree/)
64 |
--------------------------------------------------------------------------------
/Computer Science/Database/SQL/ddl_dml_dcl_tcl.md:
--------------------------------------------------------------------------------
1 | ## DDL, DML, DCL, TCL 구별하기
2 |
3 |
4 |
5 | > ### 데이터 정의어 (DDL ; Data Definition Language)
6 |
7 | : 테이블과 같은 데이터 구조를 정의하는 데에 사용되는 명령어들
8 |
9 | - `CREATE` : 테이블 생성
10 | - `ALTER` : 테이블 구조 수정
11 | - `DROP` : 테이블 삭제
12 | - `RENAME` : 테이블 이름 변경
13 | - `TRUNCATE` : 테이블 초기화
14 |
15 |
16 |
17 | > ### 데이터 조작어 (DML ; Data Manipulation Language)
18 |
19 | : DB에 들어있는 데이터를 조회 및 검색하거나 변형을 가하는 종류의 명령어들
20 |
21 | - `SELECT` : 데이터 조회
22 | - `INSERT` : 데이터 추가
23 | - `UPDATE` : 데이터 수정
24 | - `DELETE` : 데이터 삭제
25 |
26 |
27 |
28 | > ### 데이터 제어어 (DCL ; Data Control Language)
29 |
30 | : DB에 접근하고 객체들을 사용하도록 권한을 주고 회수하는 명령어들
31 |
32 | - `GRANT` : 권한을 정의할 때 사용
33 | - `REVOKE` : 권한을 삭제할 때 사용
34 |
35 |
36 |
37 | > ### 트랜잭션 제어어 (TCL ; Transaction Control Language)
38 |
39 | : 논리적인 작업의 단위를 묶어 DML에 의해 조작된 결과를 트랜잭션 별로 제어하는 명령어들
40 |
41 | - `COMMIT` : 모든 작업을 정상적으로 처리
42 | - `ROLLBACK` : 모든 작업을 다시 돌려 놓음
43 | - `SAVEPOINT` : COMMIT 전에 특정 시점까지만 반영하거나 ROLLBACK
44 |
45 |
46 |
47 | ---
48 |
49 | ### Reference
50 |
51 | - [@brownbears](https://brownbears.tistory.com/180)
52 | - [@alicesykim95](https://velog.io/@alicesykim95/DB-DDL-DML-DCL-TCL%EC%9D%B4%EB%9E%80)
53 |
--------------------------------------------------------------------------------
/Computer Science/Database/SQL/sqlGrammar.md:
--------------------------------------------------------------------------------
1 | > ### 해당 문법은 `MySQL` 기준입니다❗️
2 |
3 |
4 |
5 | ## 1. 집계함수
6 |
7 | > ### COUNT
8 |
9 | - 해당 열들의 `개수`
10 | - `NULL` 값을 제외하고 모두 셈
11 |
12 | ```sql
13 | SELECT COUNT(id)
14 | ```
15 |
16 | > ### SUM
17 |
18 | - 해당 열들을 모두 `더함`
19 |
20 | ```sql
21 | SELECT SUM(weight)
22 | ```
23 |
24 | > ### AVG
25 |
26 | - 해당 열들의 `평균`
27 |
28 | ```sql
29 | SELECT AVG(weight)
30 | ```
31 |
32 | > ### MAX, MIN
33 |
34 | - 해당 열들의 `최대값`, `최소값`
35 | - 다른 집계함수와 달리 `문자열`이나 `날짜`에도 사용 가능
36 |
37 | ```sql
38 | SELECT MAX(weight), MIN(weight)
39 | ```
40 |
41 | > ### + DISTINCT
42 |
43 | - 해당 열에서 같은 값을 가진 중복된 행 제거
44 | - 집계 함수와 같이 사용 가능
45 |
46 | ```sql
47 | SELECT DISTINCT COUNT(name)
48 | ```
49 |
50 |
51 |
52 | ## 2. DATE_FORMAT(날짜, 형식)
53 |
54 | → 날짜를 지정한 형식으로 출력
55 |
56 | | 기호 | 역할 |
57 | | :--: | :-------------------------: |
58 | | `%Y` | 4자리 년도 |
59 | | `%y` | 2자리 년도 |
60 | | `%M` | 긴 월 (영문) |
61 | | `%b` | 짧은 월 (영문) |
62 | | `%W` | 긴 요일 이름 (영문)) |
63 | | `%a` | 짧은 요일 이름 (영문) |
64 | | `%i` | 분 |
65 | | `%T` | hh:mm:ss |
66 | | `%m` | 숫자 월 (두 자리) |
67 | | `%c` | 숫자 월 (한 자리는 한 자리) |
68 | | `%d` | 일자 (두 자리) |
69 | | `%e` | 일자 (한 자리는 한 자리) |
70 | | `%I` | 시간 (12시간) |
71 | | `%H` | 시간 (24시간) |
72 | | `%r` | hh:mm:ss AM, PM |
73 | | `%s` | 초 |
74 |
75 | ```sql
76 | SELECT DATE_FORMAT(NOW(), '%Y-%m-%d) AS DATE
77 |
78 | # DATE | 2022-11-16
79 | ```
80 |
81 |
82 |
83 | ## 3. GROUP BY와 HAVING
84 |
85 | - `GROUP BY`: 특정 컬럼을 그룹화 하는 명령어
86 | - `HAVING`: 특정 컬럼을 그룹화한 결과에 조건을 거는 명령어
87 |
88 | > ### 사용법
89 |
90 | ```sql
91 | # 1. 컬럼 그룹화
92 | SELECT 컬럼 FROM 테이블 GROUP BY 그룹화할 컬럼;
93 |
94 | # 2. 조건(WHERE) 처리 후 컬럼 그룹화
95 | SELECT 컬럼 FROM 테이블 WHERE 조건식 GROUP BY 그룹화할 컬럼;
96 |
97 | # 3. 컬럼 그룹화 후에 조건 처리
98 | SELECT 컬럼 FROM 테이블 GROUP BY 그룹화할 컬럼 HAVING 조건식;
99 |
100 | # 4. 조건 처리 후에 컬럼 그룹화 후에 조건 처리
101 | SELECT 컬럼 FROM 테이블 WHERE 조건식 GROUP BY 그룹화할 컬럼 HAVING 조건식;
102 | ```
103 |
104 |
105 |
106 | ## 그 외 문법
107 |
108 | > ### IFNULL(컬럼명, 대체값)
109 |
110 | : Column 값이 NULL일 때, 대체 값으로 출력할 수 있도록 하는 함수
111 |
112 | ```sql
113 | SELECT IFNULL(SCORE, "0")
114 | ```
115 |
116 |
117 |
118 | > ### LIKE '문자열'
119 |
120 | : 뒤에 오는 문자열에 포함되는지 판단
121 |
122 | ```sql
123 | # 1. 접두사가 word인 NAME 찾깁
124 | WHERE NAME LIKE 'word%'
125 |
126 | # 2. 접미사가 word인 NAME 찾깁
127 | WHERE NAME LIKE '%word'
128 |
129 | # 3. word를 포함하고 있는 NAME 찾깁
130 | WHERE NAME LIKE '%word%'
131 | ```
132 |
--------------------------------------------------------------------------------
/Computer Science/Database/dbDesign.md:
--------------------------------------------------------------------------------
1 | ## 데이터베이스 설계
2 |
3 | ### ① 정의
4 |
5 | : 사용자의 `요구를 분석`하여 그것들을 컴퓨터에 저장할 수 있는 DB의 구조에 맞게 `변형`한 후 특정 `DBMS로 DB를 구현`하여 일반 사용자들이 사용하게 하는 것
6 |
7 |
8 |
9 | ### ② 설계 시 고려사항
10 |
11 | - `무결성`: 연산 후에도 DB에 저장된 데이터가 정해진 제약 조건을 항상 만족해야 함
12 | - `일관성`: DB에 저장된 데이터들 사이나 특정 질의에 대한 응답이 처음부터 끝까지 변함없이 일정해야 함
13 | - `회복`: 시스템에 장애가 생겼을 때 장애 발생 직전의 상태로 복구할 수 있어야 함
14 | - `보안`: 불법적인 데이터의 노출 또는 변경이나 손실로부터 보호할 수 있어야 함
15 | - `효율성`: 응답시간의 단축, 시스템의 생산성, 저장 공간의 최적화 등이 가능해야 함
16 | - `DB 확장`: DB 운영에 영향을 주지 않으면서 지속적으로 데이터를 추가할 수 있어야 함
17 |
18 |
19 |
20 | ### ③ 데이터베이스 설계 순서
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Computer Science/Database/identifyRelationship.md:
--------------------------------------------------------------------------------
1 | ## 서론
2 |
3 | RDB의 테이블을 생성하고, 테이블끼리 관계를 설정할 때 일반적으로 `외래키`(Foreign Key)를 사용한다. 외래키를 사용하여 테이블 간 `관계를 설정할 때 사용하는 전략`은 크게 두 가지가 있다. 이번 글에서는 그 두 가지에 대해 알아볼 것이다.
4 |
5 |
6 |
7 | ## 식별 관계 (Identifying Relationship)
8 |
9 |
10 |
11 |
12 |
13 | : 부모 테이블의 기본 키 또는 유니크 키를 자식 테이블이 자신의 기본 키로 사용하는 관계
14 |
15 | - 자식 테이블에 데이터가 존재한다면 부모 데이터가 반드시 존재
16 | - 부모 테이블에 자식 테이블이 `종속`
17 | - ERD 상에서 `실선 표시`
18 |
19 |
20 |
21 | ## 비식별 관계 (Non-Identifying Relationship)
22 |
23 |
24 |
25 |
26 |
27 | : 부모 테이블의 기본 키 또는 유니크 키를 자신의 기본 키로 사용하지 않고, 외래 키로 사용하는 관계
28 |
29 | - 자식 데이터는 부모 데이터가 없어도 독립적으로 생성 가능
30 | - 부모 테이블과의 `의존성`을 줄일 수 있음
31 | - 보다 `자유`로운 데이터 생성 및 수정 가능
32 |
33 |
34 |
35 | ---
36 |
37 | ### Reference
38 |
39 | - [@deveric](https://deveric.tistory.com/108)
40 | - [@developer-hm](https://developer-hm.tistory.com/217?category=910205)
41 |
--------------------------------------------------------------------------------
/Computer Science/Database/index.md:
--------------------------------------------------------------------------------
1 | ## 인덱스 (index)
2 |
3 | : 전체 내용 중에서 특정한 부분을 바로 찾을 수 있도록 목차를 만드는 개념으로, 데이터가 정렬돼있는 주소값을 저장하는 오브젝트
4 |
5 | - 일반적인 테이블은 정렬이 돼있지 않지만, `인덱스는 정렬`돼 있음
6 | - 전체 데이터에서 적은 양의 데이터를 검색할 때 사용
7 | - 전체 테이블의 `15%` 이내여야 유리
8 | - 성능향상 조건 → `I/O`와 `지연시간` 낮추기
9 | - `B트리`로 구성
10 |
11 |
12 |
13 | ## 인덱스를 사용하면 안되는 경우
14 |
15 | > ### 1. LIKE 검색 시 `좌변에 %`를 붙일 경우
16 |
17 | 컬럼의 값과 주소를 정렬하여 저장하는 인덱스는 `맨 처음 값이 무엇인지` 모른다면 참조 불가능하다. 이럴 경우 `Full Scan`을 해야 한다.
18 |
19 | - WHERE column1 LIKE '`%`index' → 사용 불가
20 | - WHERE column2 LIKE 'index`%`' → 사용 가능
21 |
22 |
23 |
24 | > ### 2. IS NULL or NOT NULL을 사용 할 경우
25 |
26 | - `IS NULL` → NULL은 value에 들어가지 않음
27 | - `IS NOT NULL` → 인덱스는 NULL이 없으므로 `Full Scan`
28 |
29 |
30 |
31 | > ### 3. 인덱스로 지정된 칼럼이 가공되거나 변경된 경우
32 |
33 | - SUBSTR() 같이 중간 부분을 떼어내는 경우
34 | - 칼럼의 값이 변형된 경우
35 |
36 |
37 |
38 | > ### 4. 부정 연산자를 사용하는 경우
39 |
40 | - 부정 연산자를 사용하면 결과값의 범위가 넓어짐
41 |
42 |
43 |
44 | > ### 5. 암시적 형변환
45 |
46 | 암시적 형변환이 일어날 경우, 인덱스 컬럼이 가공이 되는지, 비교되는 데이터가 변경이되는지 에 따라서 인덱스를 사용할 수도 안할수도 있음
47 |
48 | ---
49 |
50 | ### 참고자료
51 |
52 | - [@ggancho](https://ggancho.tistory.com/16)
53 | - [@inpa](https://inpa.tistory.com/entry/MYSQL-📚-인덱스index-핵심-설계-사용-문법-💯-총정리)
54 | - [jojoldu](https://jojoldu.tistory.com/243)
55 |
--------------------------------------------------------------------------------
/Computer Science/Database/key.md:
--------------------------------------------------------------------------------
1 | ## Key
2 |
3 | : 데이터베이스에서 조건에 만족하는 튜플을 찾거나 순서대로 정렬할 때 튜플들을 서로 `구분`할 수 있는 `기준이 되는 애트리뷰트`
4 |
5 |
6 |
7 | > ### 후보키 (Candidate Key)
8 |
9 | : Tuple을 `유일하게 식별`하기 위해 사용하는 `Attribute들의 부분집합`
10 |
11 | - `기본키`로 사용할 수 있는 Attribute
12 | - 모든 릴레이션에 `반드시` 하나 이상의 후보키 존재
13 | - 릴레이션에 있는 모든 Tuple에 대해 `유일성`과 `최소성`을 만족시켜야 함
14 | - 유일성(Unique): `하나의 키` 값으로 `하나의 튜플`만을 유일하게 식별 가능
15 | - 최소성(Minimality): 모든 레코드들을 `유일하게 식별`하는 데 꼭 필요한 속성으로만 구성
16 |
17 |
18 |
19 | > ### 기본키 (Primary Key)
20 |
21 | : 후보키 중 선택된 `메인 키`
22 |
23 | - 한 릴레이션에서 각 Tuple들을 유일하게 구별할 수 있는 Attribute
24 | - 후보키의 성질(유일성, 최소성)을 갖음
25 | - NULL 값을 가질 수 없음
26 |
27 |
28 |
29 | > ### 대체키 (Alternate Key)
30 |
31 | : 후보키가 둘 이상일 때, 기본키를 제외한 나머지 후보키
32 |
33 |
34 |
35 | > ### 슈퍼키 (Super Key)
36 |
37 | : 한 릴레이션 내에 있는 속성들의 집합으로 구성된 키
38 |
39 | - 유일성은 `만족`하지만, 최소성은 `만족하지 못함`
40 |
41 |
42 |
43 | > ### 외래키 (Foreign Key)
44 |
45 | : 다른 릴레이션의 기본키를 `참조`하는 Attribute 또는 Attribute들의 집합
46 |
--------------------------------------------------------------------------------
/Computer Science/Database/rdb.md:
--------------------------------------------------------------------------------
1 | ## RDB(Relational Database)
2 |
3 | : 관계형 데이터 모델에 기초를 둔 데이터베이스다.
4 |
5 | - 데이터 모델 → 행(Row)와 열(Column)으로 이루어졌을 때 테이블(Table)이라 할 수 있음
6 | - 개체(Entity)나 관계(Relationship)를 모두 릴레이션(Relation)에 표현
7 | - 장점
8 | - 간결하고 보기 편리함
9 | - 다른 RDB로의 변환이 용이
10 | - 단점
11 | - 성능이 다소 떨어짐
12 |
13 |
14 |
15 | ## RDB의 구조
16 |
17 |
18 |
19 | > ### ✓ Tuple
20 |
21 | - 릴레이션을 구성하는 행
22 | - 애트리뷰트의 모임
23 | - 파일 구조상의 레코드
24 | - 카다널리티(Cardinality): 튜플의 수, 기수
25 |
26 | > ### Attribute
27 |
28 | - DB를 구성하는 가장 작은 논리적 단위
29 | - 파일 구조상의 데이터 항목 또는 데이터 필드
30 | - 개체의 특성을 기술
31 | - Degree: 속성의 수, 차수
32 |
33 | > ### Domain
34 |
35 | - 하나의 애트리뷰트가 취할 수 있는 같은 타입의 원자값들의 집합
36 | - 실제 애트리뷰트 값이 나타날 때 그 값의 합법 여부를 시스템이 검사하는 데에도 이용됨
37 |
38 |
39 |
40 | ## RDBMS(Relational Database Management System)
41 |
42 | : RDB를 관리하는 소프트웨어
43 |
--------------------------------------------------------------------------------
/Computer Science/Database/rdbNaming.md:
--------------------------------------------------------------------------------
1 | ## RDB에서 꼭 지켜야 할 7가지 네이밍 규칙
2 |
3 | > ### 공통
4 |
5 | 1. 이름은 `snake case`를 따른다.
6 | - userLogin, Name (X) → user_login, name (O)
7 | 2. `prefix`와 `postfix`는 사용하지 않는다.
8 | - user_TB (X)
9 |
10 |
11 |
12 | > ### Table 관련
13 |
14 | 3. 테이블의 이름은 복수가 아닌 `단수`로 쓴다.
15 | - users (X) → user(O)
16 | 4. 가능하면 단어를 줄여쓰지 않는다.
17 | - mid_name (X) → middle_name (O)
18 |
19 |
20 |
21 | > ### Attribute 관련
22 |
23 | 5. 테이블이 하나의 기본키를 가진다면, 그 속성의 이름은 `id`로 한다.
24 | - user_id (X) → id (O)
25 | 6. 외래키는 테이블 이름과 속성 이름을 `더해 정한다`.
26 | - user 테이블의 id → id
27 | 7. index와 constraint는 `descriptive`하게 작성한다.
28 | - 예를 들어, index는 테이블명, 속성명, 인덱스 유형이 포함돼야 한다.
29 | - user_xx (X) → user_xx_email_lower (O)
30 |
31 |
32 |
33 | ---
34 |
35 | ### 참고자료
36 |
37 | - [@killu](https://killu.tistory.com/52)
38 |
--------------------------------------------------------------------------------
/Computer Science/Database/sqlAndNoSql.md:
--------------------------------------------------------------------------------
1 | ## **📌 SQL이란?**
2 |
3 | : RDBMS의 데이터를 관리하기 위해 설계된 특수 목적의 프로그래밍 언어
4 |
5 | - 자료 검색 및 관리
6 | - 데이터베이스 스키마 생성과 수정
7 | - 데이터베이스 객체 접근 조정 관리
8 |
9 | RDBMS는 사용자와 데이터베이스 사이에서 사용자의 요구에 따라 정보를 생성해주고 데이터베이스를 관리해주는 소프트웨어다. 데이터를 `테이블(table)`에 `레코드(record)`로 저장하는데, 이때 필드의 이름과 데이터 유형이라는 정의된 구조에 맞게 저장해야 한다.
10 |
11 | 
12 |
13 | RDBMS의 R은 relaional을 의미한다. RDB는 테이블이 다른 테이블과 `관계(relation)`를 맺을 수 있다. 이러한 관계를 나타내기 위해 외래키(foreign key)를 사용한다. 관계 덕분에 데이터의 중복을 피할 수 있다.
14 |
15 | ### **💡SQL의 장점**
16 |
17 | - 명확한 데이터 구조(스키마) 보장 → `데이터 무결성`
18 | - 관계는 데이터 `중복 없이` 한번만 저장
19 |
20 | ### **💡SQL의 단점**
21 |
22 | - 스키마로 인해 데이터가 유연하지 못함
23 | - 시스템의 규모가 커질 경우 `Join문이 많은 복잡한 쿼리`가 만들어질 수 있음
24 | - 수직적 확장(Scale-Up)만 지원 → `비용 문제` 발생
25 |
26 |
27 |
28 | ## **📌 NoSQL이란?**
29 |
30 | : RDB가 아닌 다른 형태의 데이터 저장 기술
31 |
32 | - 관계를 정의하지 않음
33 | - 데이터베이스 구조
34 | - `Database`
35 | - `Collection`: RDB에서는 Table
36 | - `Field`: RDB에서는 Column
37 | - `Document`: RDB에서는 Row
38 | - 다른 구조의 데이터를 같은 컬렉션(collection)에 추가 가능
39 | - 문서(document)는 json과 비슷한 형태로 가지고 있음
40 | - `Scale-Out`을 목표로 등장
41 |
42 | ### **💡NoSQL의 장점**
43 |
44 | - `유연`하고 `자유`로운 데이터 구조
45 | - `데이터 분산` 용이
46 | - 수직적 확장(Scale-Up)뿐만 아니라 `수평적 확장(Scale-Out)`도 지원
47 |
48 | ### **💡NoSQL의 단점**
49 |
50 | - 데이터 중복이 발생할 수 있음
51 | - 중복된 데이터 변경 시 `모든 컬렉션에서 수행`해야 함
52 | - 스키마가 존재하지 않아 명확한 데이터 구조를 보장하지 않음
53 | - 데이터 구조 결정이 어려울 수 있음
54 |
55 |
56 |
57 | ## **📌 언제 무엇을 사용해야 할까?**
58 |
59 | ### **이럴 땐 SQL을 사용하세요❗️**
60 |
61 | - 데이터 구조가 명확하여 변경될 여지가 없는 경우
62 | - 관계를 맺고 있는 `데이터가 자주 변경`이 이루어지는 시스템인 경우
63 |
64 | ### **이럴 땐 NoSQL을 사용하세요❗️**
65 |
66 | - 정확한 데이터 구조를 알 수 없고, 데이터가 `변경`•`확장`될 수 있는 경우
67 | - 중복 데이터 등의 특징을 기반으로 업데이트가 많이 이루어지지 않는 시스템인 경우
68 | - `막대한 데이터`를 저장해야 해서 DB를 Scale-Out해야 되는 시스템인 경우
69 |
70 | ---
71 |
72 | ### **참고자료**
73 |
74 | - 웹 사이트
75 | - [khj93 tistory](https://khj93.tistory.com/entry/Database-RDBMS와-NOSQL-차이점)
76 | - [gyoogle.dev](https://gyoogle.dev/blog/computer-science/data-base/SQL%20&%20NOSQL.html)
77 |
--------------------------------------------------------------------------------
/Computer Science/Database/transaction.md:
--------------------------------------------------------------------------------
1 | ## 트랜잭션 (Transaction)
2 |
3 | : 데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 단위
4 |
5 | - 상태 변화 → SQL을 이용해 DB에 접근하는 것
6 | - SELECT
7 | - INSERT
8 | - UPDATE
9 | - DELETE
10 | - ex) A가 B에게 10,000원 송금
11 | - A의 계좌에서 10,000원 `출금`
12 | - B의 계좌에 10,000원 `입금`
13 | - 두 동작 중 하나라도 정상 동작하지 않으면 문제 발생❗️
14 | - 트랜잭션은 위와 같은 상황이 일어나지 않도록 보장
15 | - 두 동작 모두 성공 → `commit`
16 | - 하나라도 실패 → `rollback`
17 |
18 |
19 |
20 | ## ACID
21 |
22 | → 데이터의 유효성을 보장하기 위한 트랜잭션의 특징들
23 |
24 | > ### Atomicity (원자성)
25 |
26 | : 모든 작업이 `반영`되거나 모두 `롤백`되는 특성
27 |
28 |
29 |
30 | > ### Consistency (일관성)
31 |
32 | : 데이터는 `미리 정의된 규칙`에서만 수정이 가능한 특성
33 |
34 |
35 |
36 | > ### Isolation (고립성)
37 |
38 | : 둘 이상의 트랜잭션이 실행되고 있을 때, 트랜잭션 서로의 연선에 끼어들 수 없는 특성
39 |
40 |
41 |
42 | > ### Durability (영구성)
43 |
44 | : 한번 커밋된 트랜잭션의 내용은 영원히 적용되는 특성
45 |
46 |
47 |
48 | ---
49 |
50 | ### Reference
51 |
52 | - [@mommoo](https://mommoo.tistory.com/62)
53 | - [@chrisjune](https://chrisjune-13837.medium.com/db-transaction-%EA%B3%BC-acid%EB%9E%80-45a785403f9e)
54 |
--------------------------------------------------------------------------------
/Computer Science/Database/트랜잭션_격리수준.md:
--------------------------------------------------------------------------------
1 | # 트랜잭션의 격리 수준
2 |
3 | ### SERIALIZABLE
4 |
5 | - 트랜잭션을 `순차`적으로 진행
6 | - 여러 트랜잭션이 `동일한 레코드에 동시 접근할 수 없음`
7 | - 어떠한 부정합도 발생하지 않음
8 | - select에서도 `shared lock`을 걺
9 | - 성능 저하
10 |
11 | ### REPEATABLE READ
12 |
13 | - 변경 전의 레코드를 undo 공간에 백업
14 | - 변경 전/후의 데이터 모두 존재
15 | - MVCC (다중 버전 동시성 제어)
16 | - 한 트랜잭션 내에서 동일한 결과를 보장, But `새로운 레코드가 추가되는 경우`에 부정합이 생길 수 있음
17 | - 업데이트 시 `Exclusive Lock`을 걺
18 | - Phantom Read가 거의 발생하지 않지만 유일한 케이스가 있음
19 | - 처음 데이터를 조회 후 다시 데이터를 조회할 때 `이전에 없던 데이터가 조회`되는 문제
20 | - select에 lock이 없어서 발생
21 |
22 | ### READ COMMITTED
23 | - 커밋된 데이터만 조회
24 | - Phantom Read에 더해 `Non-Repeatable Read`(반복 읽기 불가능) 문제까지 발생
25 |
26 | ### READ UNCOMMITED
27 | - 커밋하지 않은 데이터 조차도 접근할 수 있는 격리 수준
--------------------------------------------------------------------------------
/Computer Science/Network/3wayN4way.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | TCP 프로토콜은 대표적인 연결 지향형 프로토콜으로, 데이터를 전송하기 전에 `Connection`을 먼저 확립하고, 작업이 끝나면 종료한다. 확립할 때 사용하는 방식이 `3-way Handshaking`이고, 종료할 때 사용하는 방식이 `4-way Handshaking`이다. 다음 표를 통해 코드 비트에 대해 알아본 후 각 방식에 대해 살펴보자.
4 |
5 | | 코드 비트 | 설명 |
6 | | :-------: | :----------------------------------: |
7 | | URG | 긴급하게 처리할 데이터가 들어있음 |
8 | | ACK | 응답 확인 번호 사용 |
9 | | PSH | TCP가 받은 데이터를 상위 계층에 전달 |
10 | | RST | 연결 재설정 |
11 | | SYN | 연결을 초기화하려고 순서 번호 동기화 |
12 | | FIN | 데이터 송신 종료 |
13 |
14 |
15 |
16 | ## 3-way Handshaking
17 |
18 | 
19 |
20 | - ① 송신 측에서 `연결 확립 허가`를 위해 수신 측에 `SYN` 요청
21 | - ② 수신 측에서 요청을 받고 허가한다는 응답을 위해 `ACK`와 함께 `연결 확립 허가`를 위해 `SYN` 전송
22 | - ③ 수신 측 요청을 받은 송신 측에서 허가한다는 응답을 위해 `ACK` 전송
23 |
24 |
25 |
26 | ## 4-way Handshaking
27 |
28 | 
29 |
30 | - ① 송신 측에서 `연결 종료 요청`을 위해 수신 측에 `FIN` 요청
31 | - ② 수신 측에서 요청을 받고 허가한다는 응답을 위해 `ACK` 전송
32 | - ③ 수신 측에서도 `연결 종료 요청`을 위해 `FIN` 전송
33 | - ④ 수신 측 요청을 받은 송신 측에서 허가한다는 응답을 위해 `ACK` 전송
34 |
--------------------------------------------------------------------------------
/Computer Science/Network/blockNnonNsyncNasync.md:
--------------------------------------------------------------------------------
1 | ## Blocking과 Non-Blocking
2 |
3 | > ### 호출된 함수가 바로 리턴하느냐 마느냐
4 |
5 | Blocking과 Non-Blocking은 호출된 함수가 바로 리턴해서 호출한 함수에게 제어권을 넘겨주느냐, 안 넘겨주느냐의 차이다.
6 |
7 | - Blocking
8 | - `호출된 함수`가 자신의 작업을 마칠 때까지 제어권을 `가지고 있음`
9 | - `호출한 함수`는 호출된 함수가 작업을 마칠 때까지 `기다림`
10 | - Non-Blocking
11 | - `호출된 함수`가 바로 리턴해서 호출한 함수에게 제어권을 `넘겨줌`
12 | - `호출한 함수`는 호출된 함수를 기다리면서도 `다른 일을 진행`할 수 있음
13 |
14 |
15 |
16 | ## Synchronous와 Asynchronous
17 |
18 | > ### 호출된 함수의 작업 완료 여부를 누가 신경쓰느냐
19 |
20 | - Synchronous
21 | - `호출한 함수`는 `호출된 함수`가 작업을 하는 중에, 기다리면서 현재 상태를 `계속 체크`
22 | - Asynchronous
23 | - `호출된 함수`의 수행 상태를 `호출된 함수` 혼자 직접 신경쓰면서 처리
24 | - `호출된 함수`가 작업이 끝나면 `callback` 전달
25 |
26 | ## 4가지 경우
27 |
28 | → 함수 `A`, `B`가 있다고 가정
29 |
30 |
31 |

32 |
33 |
34 | > ### 1) Blocking & Synchronous
35 |
36 | - ① A가 B 호출
37 | - ② B가 제어권 받음
38 | - ③ A는 B의 작업 완료 여부를 체크하면서 기다림
39 |
40 | > ### 2) Blocking & Asynchronous
41 |
42 | - ① A가 B 호출
43 | - ② B가 제어권 받음
44 | - ③ A는 B가 작업을 마칠 때까지 기다리지만, 완료 여부를 신경쓰지 않음
45 |
46 | > ### 3) Non-Blocking & Synchronous
47 |
48 | - ① A가 B 호출
49 | - ② B가 바로 리턴해서 A에게 제어권 넘겨줌
50 | - ③ A는 다른 작업을 하면서 B의 작업 완료 여부를 체크함
51 |
52 | > ### 4) Non-Blocking & Asynchronous
53 |
54 | - ① A가 B 호출
55 | - ② B가 바로 리턴해서 A에게 제어권 넘겨줌
56 | - ③ A는 B를 신경쓰지 않고 다른 작업을 함
57 | - ④ 작업이 끝난 B가 A에게 callback 전달
58 |
59 |
60 |
61 | ---
62 |
63 | ### **참고자료**
64 |
65 | - [@homoefficio](https://homoefficio.github.io/2017/02/19/Blocking-NonBlocking-Synchronous-Asynchronous/)
66 | - [@gyoogle](https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Network/OSI%207%20계층.md)
67 |
--------------------------------------------------------------------------------
/Computer Science/Network/httpNhttps.md:
--------------------------------------------------------------------------------
1 | ## HTTP (Hyper Text Transfer Protocol)
2 |
3 | : Server/Client 모델을 따라 데이터를 주고 받기 위한 프로토콜
4 |
5 | - 인터넷에서 `하이퍼 텍스트`를 교환하기 위한 통신 규약
6 | - `80`번 포트 사용
7 | - HTTP Server가 80번 포트에서 요청을 기다림
8 | - Client는 80번 포트로 요청을 보내게 됨
9 | - 1989년, Tim Berners Lee에 의해 처음 설계
10 | - `WWW`(World Wide Web) 기반에서 세계적인 정보를 공유하는 데 큰 역할을 함
11 |
12 | ### HTTP의 구조
13 |
14 | 
15 |
16 | - Application 레벨의 프로토콜로, TCP/IP 위에서 작동
17 | - 상태를 갖지 않는 `Stateless` 프로토콜
18 | - Method, Path, Version, Headers, Body 등으로 구성
19 | - 암호화가 되지 않은 평문 데이터를 전송하는 프로토콜 → `보안상의 문제`
20 |
21 |
22 |
23 | ## HTTPS (Hyper Text Transfer Protocol Secure)
24 |
25 | : 인터넷 상에서 정보를 암호화하는 `SSL` 프로토콜을 사용해 클라이언트와 서버가 자원을 주고 받을 때 쓰는 통신 규약
26 |
27 | - HTTP에 `데이터 암호화`가 추가된 프로토콜
28 | - `443`번 포트 사용
29 | - 네트워크 상에서 제3자가 정보를 볼 수 없도록 `암호화 지원`
30 |
31 | ---
32 |
33 | ### 참고자료
34 |
35 | - [@hazel-developer](https://hazel-developer.tistory.com/145)
36 | - [@mangkyu](https://mangkyu.tistory.com/98)
37 |
--------------------------------------------------------------------------------
/Computer Science/Network/loadBalancing.md:
--------------------------------------------------------------------------------
1 | ## 로드 밸런싱 (Load Balancing)
2 |
3 | : 네트워크 트래픽을 하나 이상의 서버나 장비로 분산하기 위해 사용되는 기술
4 |
5 |
6 |

7 |
출처: https://tecoble.techcourse.co.kr/post/2021-11-07-load-balancing/
8 |
9 |
10 | ### ✓ 트래픽 증가에 대한 처리 방식
11 |
12 | - `Scale-Up` : CPU, 메모리, 디스크 등의 `기능 업그레이드`
13 | - 비용이 기하급수적으로 증가
14 | - 하나의 서버에서 웹 서비스 제공 → 서버 중지 및 장애 발생 시 가용성에 문제 발생
15 | - `Scale-Out` : 저렴한 노드 여러 개를 하나의 `Cluster`로 구성하는 방식
16 | - 하나의 노드에 문제가 발생해도 웹 서비스 중단 X
17 | - Scale-Out 방식의 웹 서비스 구성에 로드 밸런싱을 주로 사용
18 |
19 |
20 |
21 | ## 로드 밸런싱의 방식
22 |
23 | > ### ✓ Round Robin
24 |
25 | - Real 서버로의 Session 연결을 순차적으로 맺어주는 방식
26 | - 각 서버가 동일한 스펙을 가지고 있고, Session이 오래 지속되지 않는 경우 적합
27 | - Session에 대해 보장을 제공하지 않음
28 |
29 | > ### ✓ Weighted Round Robin
30 |
31 | - 각 서버마다 `가중치`를 매기고 가중치가 높은 서버에 우선적으로 배정하는 방식
32 | - 각 서버의 트래픽 처리 속도가 상이한 경우에 적합
33 |
34 | > ### ✓ Hash
35 |
36 | - Hash 알고리즘을 이용한 로드 밸런싱 방식
37 | - Client가 해시함수를 통해 특정 Server로 연결된 이후 `동일 서버로만 연결`되는 구조
38 | - `Session에 대한 보장` 제공
39 |
40 | > ### ✓ Least Connection
41 |
42 | - Session 수를 고려하여 `가장 작은 Session`을 보유한 서버로 Session을 맺어주는 연결 방식
43 | - 서버에 분배된 트래픽이 일정하지 않은 경우 적합
44 | - Session에 대한 보장을 제공하지 않음
45 |
46 | > ### ✓ Response Time
47 |
48 | - 응답시간을 고려하여 `빠른 응답시간`을 제공하는 서버로 Session을 맺어주는 방식
49 | - Session에 대한 보장을 제공하지 않음
50 |
--------------------------------------------------------------------------------
/Computer Science/Network/osi.md:
--------------------------------------------------------------------------------
1 | ## OSI 7-Layer
2 |
3 | ### ① 정의
4 |
5 | : 네트워크에서 통신이 일어나는 과정을 7단계로 나눈 것
6 |
7 | ### ② OSI 7계층으로 나눈 이유
8 |
9 | > #### It is because of the fact that it will be `easy for troubleshooting the network problems`. Only the layer in which the problem exist will `be modified`. Other layers are left `untouched`.
10 |
11 | - 통신이 일어나는 과정을 단계별로 파악할 수 있음
12 | - 흐름을 한눈에 알아보기 쉽고, 사람들이 이해하기 쉬움
13 | - 하나의 계층에 이상이 생겼을 때 다른 계층의 장비 및 SW를 건들지 않고, 이상 있는 계층만 고치면 됨
14 |
15 |
16 |
17 | ## 계층별 설명
18 |
19 |
20 |

21 |
출처: https://satoms.com/7-layers-of-the-osi-model-explained/
22 |
23 |
24 | > ### 1) 물리 계층 (Pysical Layer)
25 |
26 | : 데이터를 전기 신호로 바꾸어주는 계층
27 |
28 | - 데이터를 전송하는 역할
29 | - 데이터가 무엇인지, 에러가 있는지 등은 신경쓰지 않음
30 | - 통신 단위는 `bit`이고, `1`과 `0`으로 나타내짐
31 | - 리피터, 케이블, 허브 등
32 |
33 |
34 |
35 | > ### 2) 데이터 링크 계층 (Data Link Layer)
36 |
37 | : `Point to Point` 간 신뢰성 있는 전송을 보장하기 위한 계층
38 |
39 | - 물리 계층으로 송수신되는 데이터를 관리하여 안전하게 전달되도록 도와주는 역할
40 | - 전송 단위는 `프레임`
41 | - 프레임에 `MAC Addres`s`를 부여하고, `에러 검출`, `재전송`, `흐름제어` 진행
42 | - 브릿지, 스위치 등
43 |
44 |
45 |
46 | > ### 3) 네트워크 계층 (Network Layer)
47 |
48 | : 여러 개의 노드를 거칠 때마다 경로를 찾아주는 역할을 하는 게층
49 |
50 | - 논리적인 주소 구조인 `IP`를 가짐 → `계층적`
51 | - 데이터를 목적지까지 가장 안전하고 빠르게 전달하는 기능 → 라우팅
52 | - 이동할 경로를 선택(`라우팅`)하여 `IP 주소를 부여`하고, 해당 경로를 따라 `패킷 전달`
53 | - 라우터, 특정 스위치 등
54 |
55 |
56 |
57 | > ### 4) 전송 계층 (Transport Layer)
58 |
59 | : 통신을 환성화하기 위한 계층
60 |
61 | - `End to End` 통신을 다루는 최하위 계층
62 | - 종단 간 신뢰성 있고 효율적인 데이터 전송
63 | - 오류 검출 및 복구와 흐름제어, 중복 검사 등을 수행
64 | - `TCP`와 `UDP`
65 |
66 |
67 |
68 | > ### 5) 세션 계층 (Session Layer)
69 |
70 | : 데이터가 통신하기 위한 논리적인 연결을 담당하는 계층
71 |
72 | - TCP/IP 세션을 만들고 없애는 책임을 가짐
73 | - 동시 송수신 방식, 반이중 방식, 전이중 방식의 통신과 함께 체크 포인팅과 유휴, 종료, 다시 시작 과정 등을 수행
74 |
75 |
76 |
77 | > ### 6) 표현 계층 (Presentation Layer)
78 |
79 | : 데이터 표현이 상이한 응용 프로세스의 독립성을 제공하고, 암호화하는 역할을 담당하는 계층
80 |
81 | - 파일 인코딩, 암호화 등의 동작을 함
82 | - 해당 데이터가 text인지, gif인지, jpg인지 등의 구분하는 역할
83 |
84 |
85 |
86 | > ### 7) 응용 계층 (Application Layer)
87 |
88 | : 최종 목적지
89 |
90 | - 응용 프로세스와 직접 관계하여 일반적인 응용 서비스 수행
91 | - HTTP, FTP, Telnet 등의 `프로토콜`이 있음
92 |
93 |
94 |
95 | ---
96 |
97 | ### **참고자료**
98 |
99 | - [@shlee0882](https://shlee0882.tistory.com/110)
100 | - [@gyoogle](https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Network/OSI%207%20계층.md)
101 |
--------------------------------------------------------------------------------
/Computer Science/Network/port-forwarding.md:
--------------------------------------------------------------------------------
1 | ## **포트(Port)란?**
2 |
3 | : ip 내에서 애플리케이션 상호 구분(프로세스 구분)을 위해 사용하는 번호
4 |
5 | - 0번부터 65535번까지 있음
6 | - 0번 ~ 1023번: `well-known port`
7 | - 1024번 ~ 49151번: registered port
8 | - 49152번 ~ 65535번: dynamic port
9 |
10 | ### well-known port 예시
11 |
12 | | Port | 20 | 21 | 22 | 23 | 53 | 80 | 119 | 443 |
13 | | :--: | :-------: | :-------: | :-: | :--: | :-: | :------: | :--: | :-----------------: |
14 | | Role | FTP(data) | FTP(제어) | SSH | 텔넷 | DNS | www HTTP | NNTP | TSL/SSL 방식의 HTTP |
15 |
16 |
17 |
18 | ## **포트포워딩(Port-Forwarding)이란?**
19 |
20 | : 컴퓨터 네트워크에서 패킷이 라우터나 방화벽 같은 네트워크 게이트웨이를 가로지르는 동안 네트워크 주소를 변환해주는 것
21 |
22 | ### 포트포워딩의 목적
23 |
24 | - `public` HTTP 서버를 `private` LAN 안에 실행
25 | - 인터넷으로부터 private LAN 상의 호스트에 대한 `시큐어 셸(Secure SHell; SSH) 접근을 허가`
26 | - 인터넷으로부터 호스트에 대한 `FTP 접근을 허가`
27 | - 프라이빗 LAN에 위치한 `공개 게임 서버`를 실행
28 |
29 | 
30 |
31 | 공유기를 설치하면 공유기와 연결된 PC들은 192.168~로 시작하는 ip를 공유기로부터 할당 받는다. 그리고 공유기 또한 ISP 업체로부터 할당받은 IP를 갖는다. 공유기를 중심으로 공유기 뒤에 있는 PC들은 `내부 ip`라고 부르고, 공유기를 `외부 ip`라고 부르는데, 만약 다른 영역에 있는 PC에서 내부 ip에 있는 192.168.0.20 PC에 접속하고자 하는 요청이 들어왔을 때 공유기는 어느 PC로 연결을 해주어야 할지 모르는 상태가 된다.
32 |
33 | 이러한 상황에서 공유기에게 해당 포트로 요청이 오면 192.168.0.20 PC로 연결하라는 이정표를 달아주는 것을 `포트 포워딩`이라고 한다.
34 |
35 | ---
36 |
37 | ### **참고자료**
38 |
39 | - 블로그
40 | - [ooeunz tistory](https://ooeunz.tistory.com/104)
41 | - [hanamon.kr](https://hanamon.kr/네트워크-기본-ip-주소와-포트-port/)
42 | - [위키백과](https://ko.wikipedia.org/wiki/포트_포워딩)
43 |
--------------------------------------------------------------------------------
/Computer Science/Network/proxy.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | ## **프록시 서버란?**
4 |
5 | : 서버를 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용프로그램
6 |
7 | **🧷 Client 입장에서는 원격 서버❗️, 원격 서버 입장에서는 Client❕**
8 |
9 |
10 |
11 | ## **프록시 서버의 목적**
12 |
13 | - 프록시 서버에 요청된 내용들을 캐시를 이용하여 저장
14 |
15 |
16 |
17 | ## **프록시 서버의 특징**
18 |
19 | - client와 외부 인터넷 사이의 링크 역할
20 | - 보안 및 우회 기능
21 | - 보안상의 이유 등으로 직접 통신이 불가능할 떄 대리로 통신을 수행
22 | - ACL(; access control list) 정의 가능
23 | - 외부 인터넷에서는 client 정보를 알 수 없음
24 | - ip를 바꾸기 위한 용도로 많이 사용
25 | - 캐시 기능
26 | - 프록시 서버에 요청된 데이터를 캐시를 이용해 저장
27 | - 전송시간 절약
28 | - 외부와 연결을 하지 않아도 됨
29 | - 외부와의 트래픽을 줄이게 됨
30 | - 네트워크 병목 현상 방지
31 |
32 |
33 |
34 | ## **프록시 서버의 종류**
35 |
36 | ### **① Foward Proxy**
37 |
38 | 
39 |
40 | : 프록시 서버를 Client Host들과 원격 서버의 사이에 위치시키는 방식
41 |
42 | - Client는 요청을 보낼 때 직접이 아닌 프록시 서버를 거치게 됨
43 | - 로컬 디스크에 데이터를 저장
44 | - 사용 중인 웹 브라우저를 이용하여 프록시 서버 사용 설정을 해야 함
45 | - client가 프록시 서버를 사용하고 있다는 것을 인식할 수 있음
46 | - 보안을 위해 기업 환경 등에서 많이 사용
47 | - 대역복 사용을 감소시킬 수 있음
48 | - 접근 정책 구현에 있어서 다루기 쉬우면서 비용 저렴
49 |
50 | ### **② Reverse Proxy**
51 |
52 | 
53 |
54 | : 프록시 서버를 인터넷 리소스 앞에 위치시키는 방식
55 |
56 | - reverse proxy가 client의 요청을 받아 내부 서버에서 데이터를 받은 후 사용자에게 전달
57 | - client가 프록시 서버에 연결되었다는 것을 인식하지 못함
58 | - 구조를 이해하면 Cache Server를 붙이거나 SSL 하드웨어 가속기를 연동하는등 아키텍처 측면에서 성능 향상을 하기가 용이
59 | - 리버시 프록시를 cluster로 구성해 놓으면 가용성을 높일 수 있고 사용자가 증가하는 상황에 맞게 Web Server 나 WAS 를 유연하게 늘릴 수 있음
60 |
61 |
62 |
63 | ---
64 |
65 | ### **참고자료**
66 |
67 | - 블로그: [yunyoung1819님](https://yunyoung1819.tistory.com/9)
68 | - 웹사이트: https://www.imperva.com
69 |
--------------------------------------------------------------------------------
/Computer Science/Network/tcpNudp.md:
--------------------------------------------------------------------------------
1 | ## TCP (Transmission Control Protocol)
2 |
3 | : 인터넷 상에서 데이터를 `메세지`의 형태로 보내기 위해 `IP`와 함께 사용하는 프로토콜
4 |
5 | > ### TCP 특징
6 |
7 | - `연결형 서비스`, `가상 회선 방식` 제공
8 | - `3-way Handshaking`을 통해 연결 설정
9 | - `4-way Handshaking`을 통해 연결 해제
10 | - `흐름제어` 및 `혼잡제어`
11 | - 높은 `신뢰성` 보장
12 | - UDP보다 `속도가 느림`
13 | - 전이중(Full-Duplex), 점대점(Point to Point) 방식
14 |
15 | > ### TCP 서버 특징
16 |
17 | 
18 |
19 | - Server Socket은 연결만 담당
20 | - 연결 과정에서 반환된 Client Socket은 데이터 송수신에 사용 → `가상 회선 방식`
21 | - Server와 Client는 `1:1 연결`
22 | - Stream 전송 → 전송 데이터 크기 `무제한`
23 | - 성능이 낮음
24 |
25 |
26 |
27 | ## UDP (User Datagram Protocol)
28 |
29 | : 데이터를 `데이터그램` 단위로 처리하는 프로토콜
30 |
31 | > ### UDP 특징
32 |
33 | - `비연결형 서비스`, `데이터그램 방식` 제공
34 | - 정보를 주고 받을 때 신호절차를 거치지 않음
35 | - UDP 헤더의 `checksum` 필드를 통해 최소한의 오류만 검출
36 | - 신뢰성이 낮음
37 | - TCP보다 `속도가 빠름`
38 |
39 | > ### UDP 서버 특징
40 |
41 | 
42 |
43 | - Connection이 없음 → Server Socket과 Client Socket의 구분이 없음
44 | - Socket 대신 `IP` 기반으로 데이터 전송
45 | - `데이터그램` 단위로 데이터 전송 → `65535byte`를 초과하면 잘라서 보냄
46 | - 흐름제어 없음 → 재전송 X
47 | - 신뢰성보단 성능이 중요시 되는 경우 사용
48 |
49 |
50 |
51 | ---
52 |
53 | ### **참고자료**
54 |
55 | - [#wikipedia](https://ko.wikipedia.org/wiki/전송_제어_프로토콜)
56 | - [@mangkyu](https://mangkyu.tistory.com/15)
57 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/contextSwitching.md:
--------------------------------------------------------------------------------
1 | ## 문맥교환 (Context Switching)
2 |
3 | : 동작 중인 프로세스의 상태를 PCB에 보관하고, Context를 바꿀 프로세스의 상태를 불러와 복구하는 과정
4 |
5 |
6 |
7 |
8 |
9 | > `Context`: PC, CPU 레지스터들의 값 등을 포함한 프로세스의 상태 정보
10 | > `Idle` : 유휴 상태
11 |
12 | - P1 실행 중
13 | - Interrupt나 System Call 발생
14 | - `P1의 상태 정보`를 PCB1에 저장
15 | - PCB2에 저장된 `P2의 상태 정보`를 불러와 복구
16 | - P2 실행
17 | - Interrupt나 System Call 발생
18 | - `P2의 상태 정보`를 PCB2에 저장
19 | - PCB1에 저장된 `P1의 상태 정보`를 불러와 복구
20 | - 다시 P1 실행
21 |
22 |
23 |
24 | ### 오버헤드 (OverHead)
25 |
26 | - Context Switching 과정에서 시간과 메모리가 소비돼 성능 저하
27 | - 하지만 CPU를 놀게 두지 않기 위해 오버헤드를 감수하더라도 Context Switching 해야 함
28 |
29 | ---
30 |
31 | ### 참고자료
32 |
33 | - [@gyoogle](https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Operating%20System/PCB%20%26%20Context%20Switcing.md)
34 | - [@code-lab1](https://code-lab1.tistory.com/41)
35 | - [@beststar](https://beststar-1.tistory.com/26)
36 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/deadlock.md:
--------------------------------------------------------------------------------
1 | ## 교착 상태 (DeadLock)
2 |
3 | : 한전된 자원을 여러 프로세스가 사용하고자 할 때 발생하는 상황
4 |
5 | - 자원 A를 점유한 `P1`과 자원 B를 점유한 `P2`
6 | - P1은 B를, P2는 A를 필요로 함
7 | - DeadLock 발생
8 | - 프로세스가 자원을 얻기 위해 무한 대기
9 |
10 |
11 |
12 | > ### 교착상태의 4가지 조건
13 |
14 | - `상호배제` (Mutual Exclusion)
15 | - Only one process may use a resource at a time.
16 | - `오직 하나의 프로세스`만이 자원을 사용할 수 있다.
17 | - `점유대기` (Hold and Wait)
18 | - A process may hold allocated resources while awaiting assignment of others
19 | - `이미 자원을 점유`하고 있는 프로세스가 다른 프로세스가 점유한 자원을 `요청`한다.
20 | - `비선점` (No Preemption)
21 | - No resource can be forcibly removed from a process holding it.
22 | - 자원을 보유중인 프로세스에서 `강제`로 자원을 뺏어갈 수 없다.
23 | - `환형 대기` (Circular Wait)
24 | - A closed chain of processes exists, such that each process holds at least one resource needed by the next process in the chain.
25 | - 상대 프로세스가 가진 자원에 대해 `순환상태로 서로 대기`한다.
26 |
27 |
28 |
29 | > ### 교착상태 예방
30 |
31 | - 상호배제 부정
32 | - 여러 프로세스가 `공유 자원` 사용
33 | - 자원들은 근본적으로 공유가 불가능
34 | - 점유대기 부정
35 | - 프로세스 실행 전 `모든 자원`을 할당
36 | - 자원을 전혀 갖고 있지 않을 때만 자원요청 허용
37 | - `기아상태`(Starvation)이 발생할 수 있음
38 | - 비선점 부정
39 | - 자원을 점유 중인 프로세스가 다른 자원을 요구할 때 가진 `자원 반납`
40 | - 이미 실행한 작업의 상태를 잃지 않도록 주의해야 함
41 | - 환형대기 부정
42 | - 자원에 고유번호 할당 후 오름차순으로만 자원 요구
43 |
44 |
45 |
46 | > ### 교착상태 회피
47 |
48 | - 프로세스 시작 중단
49 | - 각 프로세스마다 요청과 해제에서 `정확한 순서를 파악`하고, 요청에 따른 프로세스 `대기 여부를 결정`
50 | - 자원 할당 거부
51 | - `은행가 알고리즘` 이용
52 | - 프로세스가 자원을 요청할 때, `자원 할당 후에도 안정상태인지` 시스템이 사전에 검사
53 |
54 |
55 |
56 | > ### 회복
57 |
58 | - 교착 상태가 제거될 때까지 교착상태의 `프로세스 종료`
59 | - 교착 상태의 프로세스가 점유하고 있는 자원을 `선점`해 다른 프로세스에게 할당
60 |
61 |
62 |
63 | ---
64 |
65 | ### 참고자료
66 |
67 | - [@gold-dragon](https://gold-dragon.tistory.com/263)
68 | - [@momoiot](https://momoiot.co.kr/iot-tech/scheduler/)
69 | - [@hoyeonkim795](https://hoyeonkim795.github.io/posts/교착상태해결방법/)
70 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/operatingSystem.md:
--------------------------------------------------------------------------------
1 | ## **운영체제의 정의**
2 |
3 | > **운영체제(OS; Operating System)**
4 |
5 | : 컴퓨터 시스템의 `자원들을 효율적으로 관리`하며, 사용자가 컴퓨터를 편리하고 효과적으로 사용할 수 있도록 `환경을 제공`하는 여러 프로그램의 모임
6 | **→ 사용자와 컴퓨터 HW 간의 인터페이스로서 동작하는 시스템 SW**
7 |
8 | 
9 |
10 |
11 |
12 | ## **운영체제의 목적**
13 |
14 | - 처리 능력(Throughput): 일정 시간 내에 시스템이 처리하는 일의 양
15 | - 반환 시간(Turn-Around-Time): 시스템에 작업을 의뢰한 시간부터 처리가 완료될 때까지 걸린 시간
16 | - 사용 가능도(Availability): 시스템을 사용할 필요가 있을 때 즉시 사용 가능한 정도
17 | - 신뢰도(Reliability): 시스템이 주어진 문제를 정확하게 해결하는 정도
18 |
19 |
20 |
21 | ## **운영체제의 기능**
22 |
23 | - 자원 관리
24 | - 자원의 종류: 프로세서, 기억장치, 입•출력장치, 파일 및 정보 등
25 | - 자원의 스케줄링 기능
26 | - 사용자와 시스템 간의 편리한 인터페이스 제공
27 | - 시스템의 각종 HW와 네트워크를 관리 및 제어
28 | - 데이터 관리, 데이터 및 자원의 공유 기능 제공
29 | - 시스템의 오류 검사 및 복구
30 | - 자원 보호 기능 제공
31 | - 입•출력에 대한 보조 기능 제공
32 | - 가상 계산기 기능 제공
33 |
34 |
35 |
36 | ## **운영체제의 주요 자원 관리**
37 |
38 | - 프로세스 관리
39 | - 프로세스 `스케줄링` 및 `동기화` 관리 담당
40 | - 프로세스 생성과 제거, 시작과 정지, 메시지 전달 등의 기능 담당
41 | - 기억장치 관리
42 | - 프로세스에게 메모리 `할당 및 회수` 관리 담당
43 | - 주변장치 관리
44 | - 입•출력 장치 `스케줄링 및 전반적인 관리` 담당
45 | - 파일 관리
46 | - 파일의 생성과 삭제, 변경, 유지 등의 `파일 관리` 담당
47 |
48 |
49 |
50 | ## **운영체제의 종류**
51 |
52 | → Windows, UNIX, LINUX, MacOS, MS-DOS
53 |
54 | - 분류1
55 | - 단일 작업 처리 시스템: MS_DOS
56 | - 다중 작업 처리 시스템: Windows, UNIX, LINUX, MacOS 등
57 | - 분류2
58 | - 개인용 OS: Windows, MacOS, MS-DOS
59 | - 서버용 OS: UNIX, LINUX
60 |
61 | ```markdown
62 | 단일 작업 처리 시스템 (Single Tasking System)
63 | : 컴퓨터 시스템을 한 개의 작업이 독점하여 사용하는 방식
64 |
65 | 다중 작업 처리 시스템 (Multi Tasking System)
66 | : 여러 개의 프로그램을 열어 두고 다양한 작업을 동시에 진행하는 방식
67 | ```
68 |
69 | ---
70 |
71 | ### **참고자료**
72 |
73 | - 서적: 2022 시나공 정보처리기사 필기
74 | - tistory: [코딩팩토리](https://coding-factory.tistory.com/300)
75 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/pas_pcb.md:
--------------------------------------------------------------------------------
1 | ## 프로세스 주소 공간 (Process Address Place)
2 |
3 | : 프로세스가 실행 중에 접근할 수 있도록 허용된 주소의 최대범위
4 |
5 | > → 최대한 데이터를 공유해 메모리 사용량을 줄이기 위해 영역을 나눈다❕
6 |
7 |
8 |
9 |
10 |
11 | - `Stack` 영역
12 | - 함수와 지역변수가 저장되는 영역
13 | - 함수 호출과 함께 `할당`, 함수 리턴과 함께 `소멸`
14 | - 재귀함수가 너무 깊거나 다량의 지역변수 존재 → Stack 영역 초과 → `Stack Overflow`
15 | - `Heap` 영역
16 | - 런타임의 크기가 결정되는 영역
17 | - 사용자에 의해 공간이 `동적` 할당 및 해제
18 | - 참조형 데이터 등 할당 (`class`)
19 | - `Data` 영역
20 | - 전역 변수가 저장되는 영역
21 | - 프로그램 시작과 함께 `할당`, 프로그램 종료와 함께 `소멸`
22 | - `Code` 영역
23 | - 프로그램이 실행될 수 있도록 `기계어` 코드가 저장돼 있는 공간
24 | - `readonly` 상태로 저장
25 |
26 |
27 |
28 | ## 프로제스 제어 블록 (PCB; Process Control Block)
29 |
30 | : 특정한 프로세스의 메타데이터(meta data)들을 저장해 놓은 OS 커널의 자료구조
31 |
32 |
33 |
34 |
35 |
36 | - CPU에서 프로세스의 상태에 따라 `교체작업`을 할 때, `이전의 프로세스 상태정보`를 PCB에 저장
37 | - `LinkedList` 방식으로 관리
38 |
39 |
40 |
41 | ---
42 |
43 | ### 참고자료
44 |
45 | - [@klm03025](https://velog.io/@klm03025/운영체제-프로세스-주소-공간)
46 | - [@zeroco](https://zeroco.tistory.com/73)
47 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/process_thread.md:
--------------------------------------------------------------------------------
1 | ## 프로세스와 스레드 (Process And Thread)
2 |
3 |
4 |
5 |
6 |
7 | > ### Process
8 |
9 | : OS로부터 메모리 등의 `시스템 자원`을 할당받는 `작업`의 단위
10 |
11 | - OS로부터 `독립`된 메모리 영역을 할당 받음
12 | - Code 영역, Data 영역, Heap 영역, Stack 영역
13 | - 프로세스들은 독립적임 → 통신을 위해 `IPC`(; Inter-Process-Communication) 사용
14 | - 최소 1개의 스레드(메인 스레드)를 가짐
15 |
16 |
17 |
18 | > ### Thread
19 |
20 | : 프로세스 내에서 할당 받은 자원을 이용해 동작하는 여러 흐름 단위
21 |
22 | - 프로세스의 `Stack 영역`만 따로 할당 받음
23 | - Code 영역, Data 영역, Heap 영역은 다른 스레드들과 `공유`
24 | - 프로세스 자원을 공유하기 때문에 다른 스레드에 의한 결과를 바로 확인 가능
25 |
26 |
27 |
28 | > ### Process와 Thread 비교
29 |
30 | - `자원` 측면
31 | - 프로세스 → 자신만의 고유 자원을 할당받아 사용
32 | - 스레드 → 프로세스 내에서 스택 영역만 따로 할당 받고, 나머지 자원은 다른 스레드와 공유
33 | - `효율` 측면
34 | - 프로세스
35 | - 독립된 자원을 사용하기 때문에 안전함
36 | - 프로세스 생성으로 인한 시스템 콜, 문맥 교환(Context Switching) 등에 의한 오버헤드
37 | - 스레드
38 | - 자원을 효율적으로 관리할 수 있고, 통신 부담이 줄어듦
39 | - 공유자원으로 인한 여러 문제(경쟁상태, 기아상태 등) 발생
40 |
41 |
42 |
43 | ## 멀티 프로세스와 멀티 스레드
44 |
45 | > ### Multi-Process
46 |
47 | : 하나의 프로그램을 `여러 개의 프로세스로 구성`하여 각 프로세스가 `1개의 작업`을 병렬적으로 처리하도록 하는 것
48 |
49 | - 1개의 프로세스가 죽어도 다른 프로세스들은 계속 싫애
50 | - Context Switching을 위한 오버헤드 발생
51 | - 통신을 위해서 IPC가 필요
52 |
53 |
54 |
55 | > ### Multi-Thread
56 |
57 | : 하나의 프로그램을 `여러 개의 스레드로 구성`하여 각 스레드가 `1개의 작업`을 처리하도록 하는 것
58 |
59 | - 멀티 프로세스 환경에서의 자원 할당을 위한 `시스템 콜`이나 `Context Switching`의 오버헤드를 줄일 수 있음
60 | - `메모리 공유` → 통신이 쉽고, 효율적인 자원 사용이 가능
61 | - 하나의 스레드에 문제가 생기면 프로세스 전체가 영향을 받음
62 | - `공유 자원 접근`에 대한 문제가 발생할 수 있음
63 |
64 |
65 |
66 | ---
67 |
68 | ### 참고자료
69 |
70 | - [@kd4](https://brunch.co.kr/@kd4/3)
71 | - [@mangkyu](https://mangkyu.tistory.com/92)
72 | - [@klm03025](https://velog.io/@klm03025/운영체제-프로세스와-스레드의-차이)
73 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/raceCondition.md:
--------------------------------------------------------------------------------
1 | ## 경쟁 상태 (Race Condition)
2 |
3 | : 두 개 이상의 프로세스 또는 스레드들이 동시에 하나의 자원에 접근해 결과값에 영향을 줄 수 있는 상태
4 |
5 |
6 |
7 | > ### Race Condition이 발생하는 경우
8 |
9 | - #### 커널 모드에서 작업 수행 중 `Interrupt` 발생해 같은 데이터를 조작하는 경우
10 | - #### 프로세스가 `System Call`을 하여 커널 모드로 진입해 작업을 수행하는 도중 `Context Switching`이 발생한 경우
11 | - #### 멀티 프로세스 환경에서 공유 메모리 내의 `커널 데이터에 접근`한 경우
12 |
13 |
14 |
15 | > ### Race Condition 해결을 위한 충족조건 3가지
16 |
17 | - `상호 배제` (Mutual Exclusion)
18 | - 어떤 프로세스가 임계 영역에서 수행 중이면 다른 프로세스들은 접근 불가능
19 | - `진행` (Progress)
20 | - 임계영역 내에 있는 프로세스 외에는 다른 프로세스의 임계영역 접근을 막아선 안됨
21 | - `한정 대기` (Bounded Waiting)
22 | - 기아 상태(Starvation)을 방지하기 위해 임계 영역에 들어가려고 요청한 후부터 다른 프로세스들이 임계 영역에 들어가는 `횟수에 한계`가 있어야 함
23 |
24 |
25 |
26 | ---
27 |
28 | ### Reference
29 |
30 | - [@gyoogle](https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Operating%20System/Race%20Condition.md)
31 | - [@zangzangs](https://zangzangs.tistory.com/115)
32 |
--------------------------------------------------------------------------------
/Computer Science/SW Engineering/decorator_pattern.md:
--------------------------------------------------------------------------------
1 | ## 데코레이터 패턴 (Decorator Pattern)
2 |
3 | 기존 객체를 변경하지 않고 새로운 기능을 동적으로 추가할 수 있도록 하는 구조적 패턴
4 |
5 | - 상속을 사용하는 대신 런타임에 기능을 조합(`서브클래스`)할 수 있도록 `유연성` 제공
6 | - 다양한 기능을 독립적인 데코레이터 클래스로 구현 및 조합을 통해 `재사용성` 제공
7 | - 여러 개의 데코레이터를 `중첩`하여 원하는 만큼 기능 추가 가능
8 | - 각 장식자 클래스마다 고유의 책임을 가짐 (`SRP`)
9 | - Client 수정 없이 기능 확장이 필요하면 장식자 클래스 추가 (`OCP`)
10 |
11 | ## 클래스 다이어그램
12 |
13 |
14 |

15 |
16 |
17 | ## 예시
18 |
19 | - Java I/O
20 | - Spring HttpServletRequestWrapper/HttpServletResponseWrapper
21 | - Resilience4j 핵심 모듈
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Computer Science/SW Engineering/design_pattern.md:
--------------------------------------------------------------------------------
1 | ## **🏭Factory Pattern**
2 |
3 |
4 |
5 | 팩토리 패턴의 핵심은 클래스의 인스턴스를 만드는 것을 서브클래스에서 결정하도록 한다는 것이다. 즉, new 키워드를 사용하는 부분을 서브클래스에 위임함으로서 객체 생성을 캡슐화하고 구상 클래스에 대한 의존성이 줄어든다는 이점을 얻을 수 있다.
6 |
7 | 1) 모든 팩토리 패턴에서는 객체 생성을 캡슐화한다.
8 | 2) 팩토리 메소드 패턴과 추상 팩토리 패턴이 존재한다.
9 | 3) 팩토리 메소드 패턴 : 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브 클래스에서 결정한다.
10 | 4) 추상 팩토리 패턴 : 인터페이스를 이용하여 서로 연관된, 또는 의존하는 객체를 구상 클래스를 지정하지 않고도 생성할 수 있다. 추상 팩토리 패턴에는 팩토리 메소드 패턴이 포함될 수 있다.
11 | 5) 디자인 원칙 중 '추상화된 것에 의존하도록 만들어라. 구상 클래스에 의존하지 않도록 만든다.'에 기인한 패턴이다.
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Computer Science/SW Engineering/factoryPattern.md:
--------------------------------------------------------------------------------
1 | ## **🏭Factory Pattern**
2 |
3 |
4 |
5 | 팩토리 패턴의 핵심은 클래스의 인스턴스를 만드는 것을 서브클래스에서 결정하도록 한다는 것이다. 즉, new 키워드를 사용하는 부분을 서브클래스에 위임함으로서 객체 생성을 캡슐화하고 구상 클래스에 대한 의존성이 줄어든다는 이점을 얻을 수 있다.
6 |
7 | 1) 모든 팩토리 패턴에서는 객체 생성을 캡슐화한다.
8 | 2) 팩토리 메소드 패턴과 추상 팩토리 패턴이 존재한다.
9 | 3) 팩토리 메소드 패턴 : 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브 클래스에서 결정한다.
10 | 4) 추상 팩토리 패턴 : 인터페이스를 이용하여 서로 연관된, 또는 의존하는 객체를 구상 클래스를 지정하지 않고도 생성할 수 있다. 추상 팩토리 패턴에는 팩토리 메소드 패턴이 포함될 수 있다.
11 | 5) 디자인 원칙 중 '추상화된 것에 의존하도록 만들어라. 구상 클래스에 의존하지 않도록 만든다.'에 기인한 패턴이다.
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Computer Science/SW Engineering/mvc.md:
--------------------------------------------------------------------------------
1 | ## MVC 패턴
2 |
3 | : 하나의 애플리케이션, 프로젝트를 구성할 때 그 구성요소를 `Model`, `View`, `Controller`, 세 가지의 역할로 구분한 패턴
4 |
5 | 
6 |
7 | 위의 그림과 같이 `User`가 `Controller`를 조작하면 `Controller`는 `Model`을 통해서 데이터를 가져오고 그 정보를 바탕으로 시각적인 표현을 담당하는 `View`를 제어해서 사용자에게 전달한다. MVC 패턴을 사용하면 UI(; User Interface)로부터 비즈니스 로직을 분리하여 애플리케이션의 `시각적 요소`나 그 이면에서 실행되는 `비즈니스 로직`을 서로 영향 없이 쉽게 고칠 수 있는 애플리케이션을 만들 수 있다.
8 |
9 |
10 |
11 | ## MVC의 구성요소
12 |
13 | > ### Model
14 |
15 | `데이터를 가진 객체`를 말한다. 데이터는 `내부의 상태`에 대한 정보를 가질 수 있고, 모델을 표현하는 `이름` 속성을 가질 수 있다. 모델의 상태에 변화가 있을 때 `Controller`와 `View`에 이를 통보합니다. 이 통보를 통해 `View`는 최신의 결과를 보여줄 수 있고, `Controller`는 모델의 변화에 따른 적용 가능한 명령을 `추가`, `삭제`, `수정`할 수 있다.
16 |
17 | - 사용자가 편집하길 원하는 `모든 데이터`를 가지고 있어야 함
18 | - View나 Controller에 대해서 어떠한 정보도 알지 말아야 함
19 | - 변경이 일어나면 `변경 통지`에 대한 처리방법을 구현해야 함
20 |
21 |
22 |
23 | > ### View
24 |
25 | `cilent 측 기술`인 HTML, CSS, Javascript들을 모아둔 컨테이너다. User가 볼 결과물을 생성하기 위해 `Model`로부터 정보를 얻어온다.
26 |
27 | - Model이 가지고 있는 정보를 따로 `저장해서는 안됨`
28 | - Model이나 Controller와 같이 `다른 구성요소를 몰라야 함`
29 | - 변경이 일어나면 변경 통지에 대한 `처리방법`을 구현해야 함
30 |
31 |
32 |
33 | > ### Controller
34 |
35 | Controller는 User가 접근한 URL에 따라 사용자의 `요청사항을 파악`한 후에 그 요청에 맞는 데이터를`Model에 의뢰`하고, 데이터를 `View에 반영`해서 사용자에게 알려준다.
36 |
37 | - Model이나 View에 대해 `알고 있어야 함`
38 | - Model이나 View의 `변경을 모니터링` 해야 함
39 |
40 |
41 |
42 | ## MVC 패턴을 사용해야 하는 이유
43 |
44 | - Model, View, Controller가 각각 하나의 역할만 담당하여 처리가 효율적
45 | - 서로 분리돼 있어 유지보수와 확장이 용이하고, 유연성이 증가
46 | - 중복 코딩의 문제점 제거
47 |
48 |
49 |
50 | ---
51 |
52 | ### **참고자료**
53 |
54 | - Web
55 | - [@cocoon1787](https://cocoon1787.tistory.com/733)
56 | - [@jhc9639](https://m.blog.naver.com/jhc9639/220967034588)
57 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Hyunseok Ko
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Language/Java/Executor와_ExecutorService.md:
--------------------------------------------------------------------------------
1 | # Executor와 ExecutorService
2 |
3 | ## Executor 인터페이스
4 |
5 | - `쓰레드 풀의 구현`을 위한 인터페이스
6 | - 쓰레드 풀을 사용하면 쓰레드 생성 및 종료에 따른 오버헤드를 줄일 수 있음
7 | - 쓰레드 작업 등록과 실행 중 실행에 대한 책임을 가짐 (ISP 준수)
8 |
9 | ```java
10 | @Test
11 | void executorRun() {
12 | final Runnable runnable = () -> System.out.println(Thread.currentThread().getName());
13 | final Executor executor = new TestExecutor();
14 |
15 | executor.execute(runnable);
16 | }
17 |
18 | static class TestExecutor implements Executor {
19 |
20 | @Override
21 | public void execute(final Runnable r) {
22 | new Thread(r).start();
23 | }
24 | }
25 | ```
26 |
27 | ## ExecutorService 인터페이스
28 |
29 | ```java
30 | public interface ExecutorService extends Executor, AutoCloseable {
31 | // 생략
32 | }
33 | ```
34 |
35 | - `작업(Runnable, Callable) 등록`을 위한 인터페이스
36 | - Executor 인터페이스를 상속 받기에 `작업 실행에 대한 책임`도 가짐
37 | - 작업 종료 후 다음 작업을 하기 위해 대기하기 때문에 `shutdown()` 메서드를 통해 명시적으로 종료시켜야 함
38 |
39 | ```java
40 | @Test
41 | void test() {
42 | ExecutorService executorService = Executors.newFixedThreadPool(32);
43 | Runnable runnable = () -> System.out.println(Thread.currentThread().getName());
44 |
45 | executorService.execute(runnable);
46 | executorService.shutdown();
47 | }
48 | ```
49 |
--------------------------------------------------------------------------------
/Language/Java/Java_실행_과정.md:
--------------------------------------------------------------------------------
1 | # Java의 실행과정
2 |
3 | ## JDK, JRE, JVM
4 |
5 | ### JDK
6 |
7 | - 자바 개발 환경 (가장 큰 범위)
8 | - 자바 컴파일러(javac), 자바 클래스 파일을 해석하는 javap
9 |
10 | ### JRE
11 |
12 | - 자바 실행 환경
13 | - JVM, 자바 클래스 라이브러리, 기타 실행에 필요한 파일 포함
14 |
15 | ### JVM
16 |
17 | - 자바 애플리케이션을 실행하는 가상 머신
18 | - 컴퓨터 자원(메모리)을 할당 받아 `Runtime Data Area` 구성
19 | - `인터프리터`와 `JIT 컴파일러`를 통해 바이트 코드를 각 OS에 맞는 기계어로 해석
20 | - 인터프리터
21 | - 바이트코드 명령어를 하나씩 읽어서 실행
22 | - JIT(Just in time)
23 | - 바이트코드 전체를 컴파일해 네이티브 코드로 변경
24 | - 이후 해당 메서드를 더 이상 인터프리팅하지 않고 네이티브 코드로 직접 실행하는 방식
25 | - `GC`를 통해 동적 메모리 관리
26 |
27 | ## Java 실행과정
28 |
29 |
30 |

31 |
출처: https://steady-snail.tistory.com/67
32 |
33 |
34 |
35 |
36 | > ### 1. `.java` → `.class`
37 |
38 | - `javac`라는 Java Compiler에 의해 바이트 코드로 변환
39 | - `Byte Code`: 사람이 작성한 `소스코드`와 기계어의 중간 단계
40 | - 어떤 프로세서에서도 작동할 수 있도록 기계어가 아닌 바이트 코드로 변환함
41 |
42 |
43 |
44 | > ### 2. 컴파일 된 바이트 코드를 JVM의 `Class Loader`로 전달
45 |
46 | - 동적 로딩을 통해 필요한 클래스들을 로딩 및 링크
47 | - JVM의 메모리인 `Runtime Data Area`로 런타임 데이터를 올림
48 |
49 |
50 |
51 | > ### 3. Execute
52 |
53 | - `Execution Engine`은 JVM 메모리에 올라온 바이트 코드들을 명령어 단위로 가져와 실행
54 |
55 |
56 |
57 | ### Reference
58 |
59 | - [@whitepro](https://whitepro.tistory.com/458)
60 | - [@steady-snail](https://steady-snail.tistory.com/67)
61 |
--------------------------------------------------------------------------------
/Language/Java/ThreadLocal과_Atomic.md:
--------------------------------------------------------------------------------
1 | # ThreadLocal과 Atomic
2 |
3 | 멀티스레드 프로그래밍에서는 전역 변수 사용을 지양한다. 전역 변수 사용 시, 동기화 문제, 데드 등의 문제가 발생하기 때문이다. 이러한 문제 때문에 Java에서는 대안을 제공하고 있고, 그 중 하나가 바로 `ThreadLocal`과 `Atomic 변수` 이다.
4 |
5 | ## ThreadLocal
6 |
7 | - Java에서 멀티스레드 프로그래밍을 할 때 사용되는 클래스
8 | - 오직 한 쓰레드에 의해 읽고 쓰여지는 변
9 | - 여러 쓰레드가 같은 코드에서 실행되고, 같은 ThreadLocal을 참조해도 서로의 ThreadLocal을 볼 수도, 영향을 줄 수도 없음
10 |
11 | ### 활용 예시
12 |
13 | - Spring Security에서 각 사용자의 인증 정보 사용
14 |
15 | ```java
16 | final class ThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {
17 | private static final ThreadLocal> contextHolder = new ThreadLocal();
18 |
19 | // 생략
20 | }
21 | ```
22 |
23 | ### 주의사항
24 |
25 | - 메모리 누수의 원인이 될 수 있으므로, 사용 후 반드시 삭제하자.
26 |
27 | ## Atomic
28 |
29 | - `ThreadLocal`과 달리 `Atomic`은 `원자성`을 보장하는 클래스
30 | - Non-blocking`으로 동작
31 | - 쓰레드들이 suspend 되지 않기 때문에 `Context Switching이 발생하지 않음
32 |
33 | ### CAS 알고리즘 (Compare And Swap)
34 |
35 | - 변수의 값을 변경하기 전에 `기존 값`이 내가 예상하던 값과 같을 경우에만 `새로운 값으로 할당`하는 방법
36 | - `Atomic` 클래스는 `CAS` 알고리즘을 사용
37 |
38 | ### AtomicInteger의 내부 코드
39 |
40 | ```java
41 | public class AtomicInteger extends Number implements java.io.Serializable {
42 | private static final long serialVersionUID = 6214790243416807050L;
43 | private static final Unsafe U = Unsafe.getUnsafe();
44 | private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value");
45 |
46 | private volatile int value;
47 |
48 | // 생략
49 |
50 | public final int incrementAndGet() {
51 | return U.getAndAddInt(this, VALUE, 1) + 1;
52 | }
53 |
54 | // 생략
55 |
56 | public final int get() {
57 | return value;
58 | }
59 |
60 | public final void set(int newValue) {
61 | value = newValue;
62 | }
63 |
64 | // 생략
65 | }
66 |
67 | public final class Unsafe {
68 | // 생략
69 |
70 | @IntrinsicCandidate
71 | public final int getAndAddInt(Object o, long offset, int delta) {
72 | int v;
73 | do {
74 | v = getIntVolatile(o, offset);
75 | } while (!weakCompareAndSetInt(o, offset, v, v + delta));
76 | return v;
77 | }
78 |
79 | // 생략
80 | }
81 | ```
82 |
83 | - value 변수를 `volatile`로 선언
84 | - UnSafe 클래스를 통해 `CAS` 알고리즘을 사용
85 | - `getAndAddInt` 메서드를 통해 `AtomicInteger`의 값을 변경
86 | - get()과 set() 자체가 `Atomic 연산`이라 Race Condition이 발생하지 않음
87 |
--------------------------------------------------------------------------------
/Language/Java/aboutJava.md:
--------------------------------------------------------------------------------
1 | ## **Java의 역사**
2 |
3 | Java는 1991년, **Sun Microsystems**의 엔지니어들에 의해 고안된 **Oak**라는 언어에서 부터 출발됐다. **제임스 고슬링** 등의 엔지니어들은 가전제품에 탑재될 SW를 만드는 것이었는데, C++을 확장해서 사용하려 했지만 목적을 이루기에 부족하다는 것을 깨달았다.
4 |
5 |
6 | 그렇게 C++의 장점을 도입하고, 단점을 보완한 새로운 언어를 개발했고, 그것이 바로 **Oak**다. 처음엔 소형기기에 사용될 목적이었으나, 인터넷의 등장으로 인해 OS에 독립적인 Oak가 이에 적합하다고 판단하여 개발 방향을 바꾸었고, 이름을 **Java**로 변경했다. 그렇게 자바로 개발한 **Hot Java**를 발표하고, 1996년 1월에 **Java**의 정식 버전을 발표했다.
7 |
8 |
9 | 그렇게 자바로 작성된 **Applet**이 인기를 끌었고, 보안상의 이유로 Applet을 더 이상 지원하지 않게 되자 **Servlet**과 **JSP**가 많이 사용됐다. 이후 **AOS**에서도 사용되고, **Spring**의 등장으로 많은 기업에서 사용하는 언어가 되었다.
10 |
11 |
12 |
13 | ## **Java의 특징과 OOP**
14 |
15 | Java는 많은 개발자들에게 사랑을 받고 있는 언어다. 기존에 인기 있던 다른 언어에는 없는 장점을 가지고 있기 때문이다. 그럼 어떤 특징이 있는지 알아보자.
16 |
17 | > ### **1. OS에 독립적이다.**
18 |
19 | Windows 환경에서 C 코드를 작성하고 Mac OS에서 실행하면 오류가 발생할 수 있다. 하지만 Java는 그렇지 않다. JVM(; Java Virtual Machine)이 있기 때문이다. 이 부분에 대해선 다음에 다시 자세히 알아보자.
20 |
21 | > ### **2. 객체지향언어이다.**
22 |
23 | Java는 OOP의 특징을 모두 적용하고 있다. 클래스와 접근지정자로 캡슐화를 만족하고, 상속을 지원하며, Overloading, Overriding, Interface를 통해 다형성을 만족한다.
24 |
25 | > ### **3. 가비지 컬렌션**
26 |
27 | Java 파일이 실행되면 **Garbage Collector**가 자동적으로 메모리를 관리해주기 때문에 프로그래머가 메모리 관리를 따로 하지 않아도 된다. C++과 같이 소멸자를 만들 필요가 없다는 말이다.
28 |
29 | > ### **4. 네트워크와 분산처리를 지원한다**
30 |
31 | 풍부하고 다양한 네트워크 프로그래밍 라이브러리를 통해 비교적 짧은 시간에 네트워크 관련 프로그램을 쉽게 개발할 수 있도록 지원한다.
32 |
33 | > ### **5. 멀티 쓰레드를 지원한다.**
34 |
35 | Java에서 개발되는 멀티 쓰레드 프로그램은 시스템과는 관계없이 구현 가능하며, 관련된 라이브러리가 제공되므로 구현이 쉽다. 그리고 여러 쓰레드에 대한 스케줄링을 자바 인터프리터가 담당하게 된다.
36 |
37 | > ### **6. 동적 로딩을 지원한다.**
38 |
39 | 동적 로딩을 지원하기 때문에 실행 시에 모든 클래스가 로딩되지 않고 필요한 시점에 클래스를 로딩하여 사용할 수 있다는 장점이 있다.
40 |
--------------------------------------------------------------------------------
/Language/Java/future.md:
--------------------------------------------------------------------------------
1 | # Java의 Future
2 |
3 | ### Future란?
4 |
5 | - JDK 1.5에서 나온 인터페이스
6 | - `비동기`적 연산 작업을 위해 만들어진 인터페이스
7 | - `멀티 스레드` 환경에서 처리된 어떤 데이터를 다른 스레드에 전달할 수 있음
8 | - 내부적으로 `Thread-Safe` 하게 구현되어 있음 → synchronized block을 사용하지 않아도 됨
9 |
10 | ```java
11 | public interface Future {
12 |
13 | /*
14 | * 작업을 취소하려고 시도함
15 | * @param mayInterruptIfRunning 작업이 실행 중일 때 취소할지 여부
16 | */
17 | boolean cancel(boolean mayInterruptIfRunning);
18 |
19 | /*
20 | * 작업이 취소되었는지 여부를 반환
21 | * @return 작업이 취소되었으면 true, 아니면 false
22 | */
23 | boolean isCancelled();
24 |
25 | /*
26 | * 작업이 완료되었는지 여부를 반환
27 | * @return 작업이 완료되었으면 true, 아니면 false
28 | */
29 | boolean isDone();
30 |
31 | /*
32 | * 작업의 결과를 반환
33 | * @return 작업의 결과
34 | */
35 | V get() throws InterruptedException, ExecutionException;
36 |
37 | /*
38 | * 작업의 결과를 반환
39 | * @param timeout 작업이 완료될 때까지 기다리는 시간
40 | * @param unit timeout의 단위
41 | * @return 작업의 결과
42 | */
43 | V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
44 | }
45 | ```
46 |
47 | ### 장점
48 |
49 | - 비동기 작업의 결과를 쉽게 관리 가능
50 | - 기다리지 않고, 결과가 필요할 때 가져올 수 있음
51 | - `isDone()` 메서드를 통해 작업이 완료됐는지 확인 가능
52 |
53 | ### 단점
54 |
55 | - 작업 완료 알림의 부재
56 | - polling 방식이라 계속 메서드를 호출해 작업 완료 여부를 확인해야 함
57 | - blocking 방식
58 | - `get()` 메서드를 호출하면 작업이 완료될 때까지 블로킹됨
59 |
60 | ### 결론: JDK 8의 [CompletableFuture](https://github.com/lcomment/development-recipes/blob/main/Language/Java/completableFuture.md)을 사용하자.
61 |
--------------------------------------------------------------------------------
/Language/Java/gc_튜닝하기.md:
--------------------------------------------------------------------------------
1 | # GC 튜닝하기
2 |
3 | ## GC 튜닝에 앞서
4 |
5 | - 튜닝이 필요 없다고 판단 되는 경우
6 | - `-Xms` 옵션과 `-Xmx` 옵션으로 메모리 크기를 지정함
7 | - `-server` 옵션이 포함돼 있음
8 | - 시스템에 `Timeout` 같은 로그가 없음
9 | - GC 튜닝은 가장 마지막에 하는 것
10 | - 불필요한 객체 생성을 먼저 줄여라 (ex. String)
11 | - GC 튜닝의 목적
12 | - Old 영역으로 넘어가는 객체 수를 최소화 하자
13 | - Major GC 실행 시간을 줄이자
14 |
15 | ## Old 영역으로 넘어가는 객체 수를 최소화 하자
16 |
17 | - G1 GC를 제외한 대부분의 GC는 Generational GC
18 | - Old 영역으로 가는 객체 수를 줄이면 `Major GC`의 수를 줄일 수 있음
19 | - `Young 영역`의 크기를 잘 조절하면 큰 효과를 볼 수 있음
20 |
21 | ## Major GC 시간 줄이기
22 |
23 | - Major GC는 Minor GC보다 10배 정도 긺
24 | - 실행 시간이 길어지면 여러 부분에서 Timeout이 날 수 있음
25 | - 그렇다고 Old 영역을 줄이면 `OOME`(Out Of Memory Error)가 발생하거나 Major GC 횟수가 늘어감
26 | - 반대로 늘리면 Major GC 횟수는 줄지만, 실행시간이 늘어남
27 | - 따라서 `Old 영역` 크기를 적절하게 설정해야 함
28 |
29 | ## GC 성능을 결정하는 옵션
30 |
31 | - 서비스마다 객체의 크기와 라이프 사이클이 다르므로 다른 사례를 모방하면 안됨
32 | - 옵션을 많이 설정한다고 빨라지지 않음
33 | - 두 대 이상의 서버에 GC 옵션을 다르게 적용하고, `성능이나 GC 시간이 개선`된 때에만 적용하자
34 |
35 | ### Heap 영역 크기
36 |
37 | - -Xms
38 | - JVM 시작 시 힙 영역 크기
39 | - -Xmx
40 | - 최대 힙 영역 크기
41 |
42 | ### Young 영역 크기
43 |
44 | - -XX:NewRatio
45 | - Young 영역과 Old 영역의 비율
46 | - -XX:NewSize
47 | - New 영역의 크기
48 | - -XX:SurvivorRatio
49 | - Eden 영여과 Survivor 영역의 비율
50 |
51 | ### GC 방식
52 |
53 | - -XX:+UseSerialGC
54 | - Serial GC
55 | - -XX:+UseParallelGC
56 | - Parallel GC
57 | - -XX:+UseConcMarkSweepGC
58 | - CMS GC
59 | - -XX:+UseG1GC
60 | - G1 GC
61 | - -XX:+UseZGC
62 | - ZGC
63 |
64 | ---
65 |
66 | ### Reference
67 |
68 | - [@NaverD2](https://d2.naver.com/helloworld/37111)
--------------------------------------------------------------------------------
/Language/Java/java_쓰레드.md:
--------------------------------------------------------------------------------
1 | # 쓰레드
2 |
3 | ## Thread 클래스를 상속 받는 방법
4 |
5 | ### Thread 클래스 내부 코드
6 |
7 | ```java
8 | public class Thread implements Runnable {
9 |
10 | // 생략
11 |
12 | Thread(ThreadGroup g, String name, int characteristics, Runnable task, long stackSize, AccessControlContext acc) {
13 | // 생략
14 | }
15 |
16 | public Thread(Runnable task) {
17 | this(null, null, 0, task, 0, null);
18 | }
19 |
20 | // 생략
21 | }
22 | ```
23 |
24 | ### Thread 구현하기
25 |
26 | ```java
27 | class ThreadEx extends Thread {
28 |
29 | public void run() {
30 | System.out.println("Thread Ex");
31 | }
32 | }
33 |
34 | class Test {
35 |
36 | public static void main(String[] args) {
37 | THreadEx t = new ThreadEx();
38 |
39 | t.start();
40 | }
41 | }
42 | ```
43 |
44 | ## Runnable 인터페이스를 구현하는 방법
45 |
46 | - 보통 Runnable을 구현하여 쓰레드 구현
47 | - Thread 클래스를 상속 받으면 다른 클래스를 상속 받을 수 없음
48 | - 인터페이스 구현이 재사용성이 높고 코드 일관성 유지가 좋음
49 |
50 | ```java
51 | class ThreadEx implements Runnable {
52 |
53 | public void run() {
54 | System.out.println("Thread Ex");
55 | }
56 | }
57 |
58 | class Test {
59 |
60 | public static void main(String[] args) {
61 | Runnable r = new ThreadEx();
62 | Thread t = new Thread(r);
63 |
64 | t.start();
65 | }
66 | }
67 | ```
68 |
69 | ## start()와 run()
70 |
71 | ### run()을 실행한 경우
72 |
73 | - 생성된 쓰레드를 실행시키는게 아님
74 | - 단순히 클래스에 선언된 메서드를 호출한 것
75 | - Call Stack에 main 위에 run 메서드가 쌓임
76 | - main에서 run을 호출
77 |
78 | ### start()를 실행한 경우
79 |
80 | - main에 start가 쌓임
81 | - 실행된 쓰레드의 호출 스택이 생성됨
82 | - 쓰레드의 호출 스택에 run이 쌓임
83 | - 쓰레드가 run 호출
84 | - run 수행 종료 후 쓰레드의 호출 스택도 사라짐
85 |
--------------------------------------------------------------------------------
/Language/Java/jvm_메모리_영역.md:
--------------------------------------------------------------------------------
1 | # JVM의 메모리 영역
2 |
3 |
4 |

5 |
6 |
7 | > ### Heap
8 |
9 | - 객체의 인스턴스나 동적으로 할당된 데이터. 즉 `Reference Type이 저장`
10 | - 모든 스레드가 공유하는 공간
11 | - `GC`가 일어남
12 | - Young Generation: 새로 생성된 인스턴스 저장
13 | - EDEN: 생성된 인스턴스 저장
14 | - Survivor space: Minor GC에서 살아남은 인스턴스 저장
15 | - Old Generation: 일정 횟수의 GC에서 살아남은 인스턴스 저장
16 | - Major GC가 일어남
17 |
18 |
19 |
20 | > ### Thread Stack
21 |
22 | - `Stack 영역`
23 | - 각 `Thread`마다 배정되는 메모리 영역
24 | - 메서드, 메서드 반환값, 지역변수 저장
25 |
26 |
27 |
28 | > ### MetaSpace
29 |
30 | - `메서드 영역`
31 | - 애플리케이션의 class, 메서드 정보, static 멤버 변수 저장
32 |
33 |
34 |
35 | > ### Code Cache
36 |
37 | - JIT(Just In Time) 컴파일러가 데이터를 저장하는 영역
38 | - 컴파일 된 코드 블럭 저장
39 | - 자주 접근 → 미리 바이트 코드를 기계어로 변환된 부분을 저장 (`cache`)
40 |
41 |
42 |
43 | > ### Shared Library
44 |
45 | - 공유 라이브러리를 기계어로 변환한 채로 저장
46 | - OS에서 프로세스당 한 번씩 로드
47 |
48 |
49 |
50 | ---
51 |
52 | ### Reference
53 |
54 | - [@deepu](https://deepu.tech/memory-management-in-jvm/)
55 | - [@inspirit941](https://inspirit941.tistory.com/294)
56 | - [@whitepro](https://whitepro.tistory.com/458)
57 |
--------------------------------------------------------------------------------
/Language/Java/jvm_클래스로더.md:
--------------------------------------------------------------------------------
1 | # JVM 클래스 로더
2 |
3 | - 런타임에 클래스를 `로드`하고 `링크`하는 작업을 수행
4 |
5 | ### 로딩
6 |
7 | - .class를 바이트 코드로 읽고 바이너리 데이터를 생성하여 메모리에 저장
8 | - 로드 후 JVM은 힙 메모리에 이 파일을 나타내기 위해 `Class 타입의 객체` 생성
9 |
10 | ### 링크
11 |
12 | - 생성된 바이트 코드가 적절한지 여부 확인
13 | - Verify
14 | - `.class` 파일의 정확성 검증
15 | - `올바른 형식`인지
16 | - `유효한 컴파일러`에서 생성됐는지
17 | - Preparation
18 | - 클래스에 필요한 `메모리 할당` 및 `기본값 초기화`
19 | - Resolve
20 | - 심볼릭 레퍼런스를 메모리 영역에 있는 `실제 레퍼런스`로 바꾸는 과정
21 | - 어떤 객체가 다른 객체의 참조를 가지고 있는 경우, 링크가 일어나지 않으면 실제 주소를 모름
22 | - Resolve 과정을 통해 힙에 있는 객체를 가리킴
23 | - Initialization
24 | - static 변수의 값 할당 및 static 블록이 있다면 실행
25 |
--------------------------------------------------------------------------------
/Language/Java/set.md:
--------------------------------------------------------------------------------
1 | ## HashSet
2 |
3 | : 내부적으로 HashMap을 이용해 만들어진 Set으로, `해싱(Hashing)`을 이용해서 구현
4 |
5 | - Set 인터페이스를 구현한 `가장 대표적인 컬렉션`
6 | - Set 인터페이스의 특징대로 `중복 허용 X`
7 | - 저장순서를 유지하지 않음 → 순서를 유지하려면 `LinkedHashSet`
8 |
9 | | Method | Explanation |
10 | | :-----------------------------: | :----------------------------------------------: |
11 | | boolean add(Object o) | 새로운 객체 삽입 |
12 | | boolean addAll(Collection c) | 주어진 컬렉션의 모든 객체 삽입 |
13 | | void clear() | 저장된 모든 객체 삭제 |
14 | | boolean contains(Object o) | 지정된 객체를 포함하고 있는지 리턴 |
15 | | boolean contains(Collection c) | 지정된 컬렉션의 모든 객체를 포함하고 있는지 리턴 |
16 | | boolean isEmpty() | HashSet이 비어있는지 리턴 |
17 | | boolean remove(Object o) | 지정된 객체 삭제 |
18 | | boolean removeAll(Collection c) | 지정된 컬렉션의 모든 객체 삭제 |
19 | | boolean retainAll(Collection c) | 지정된 컬렉션의 모든 객체를 제외한 나머지 삭제 |
20 | | int size() | HashSet에 저장된 객체의 수 리턴 |
21 |
--------------------------------------------------------------------------------
/Language/Java/typeOfJava.md:
--------------------------------------------------------------------------------
1 | ## **Java 프로그래밍의 기본 구성**
2 |
3 | ```java
4 | 1 import java.util.*;
5 | 2
6 | 3 public class Sample {
7 | 4 public static void main(String[] args) {
8 | 5 String s = "Hello World";
9 | 6 System.out.println(s);
10 | 7 }
11 | 8 }
12 | ```
13 |
14 | - 1열: 라이브러리 import
15 | - 3열: class 부분으로, 한 파일에 여러 개의 class를 구현할 수는 있으나 public class는 한 개만 구현 가능
16 | - 4열: main() 메서드
17 | - 5, 6열: String 객체 선언 및 생성, 메서드 호출
18 |
19 | ```text
20 | ❗️ Q) 함수(function)와 메서드(method)는 뭐가 다른가요?
21 | A) 간단하게 이야기하면 함수는 메서드를 포함하는 개념이다. 함수란 여러 문장들이 하나의 기능을 구현하도록 구성한 것이다. 그 함수 중에서 클래스 내부에 정의한 함수가 바로 메서드다. 메서드는 객체의 속성을 다루기 위한 행위를 정의하고 있다고 말할 수 있다.
22 | ```
23 |
24 | ## **자료형**
25 |
26 | ### **❖ 기본 타입**
27 |
28 |
29 |

30 |
31 |
32 | ### **❖ 레퍼런스 타입**
33 |
34 | - Class
35 | - Array
36 | - Interface
37 |
--------------------------------------------------------------------------------
/Language/Java/volatile과_synchronized.md:
--------------------------------------------------------------------------------
1 | # volatile과 synchronized
2 |
3 | ## volatile 키워드
4 |
5 | - `volatile` 키워드는 `멀티쓰레드 환경`에서 변수의 `가시성`을 보장하는 키워드
6 | - CPU Cache가 아닌 `Main Memory`에 직접 접근하여 값을 읽고 쓰기 때문에 `쓰레드 간의 가시성`을 보장
7 | - 하나의 쓰레드가 값을 변경하면 다른 쓰레드가 즉시 변경된 값을 읽을 수 있음
8 | - 여러 쓰레드가 값을 변경할 때, `synchronized`로 원자성을 보장해줘야 함
9 |
10 | ## synchronized
11 |
12 | - 멀티 스레드 환경에서는 여러 스레드가 공유자원에 동시에 접근할 수 있음
13 | - `경쟁 상태`(race condition)이 발생할 수 있음
14 | - synchronized는 임계영역(Critical Section)에 대해 Lock을 걸어 공유자원에 대한 `동시접근을 막는 동기화`
15 |
16 | ## synchronized 내부
17 |
18 | ### 모니터 락(Monitor Lock)
19 |
20 | - synchronized는 `모니터 락(Monitor Lock)`을 사용
21 | - 모니터 락은 `객체 단위`로 존재
22 | - Java 객체들은 `모니터`라는 메타데이터를 하나씩 가짐
23 | - 모니터 락은 `오직 하나의 스레드만 소유`할 수 있음
24 | - 모니터 락을 소유한 스레드가 모니터 락을 해제하기 전까지 다른 스레드는 `대기`
25 |
26 | ### 내부 동작
27 |
28 | - 자바 바이트코드 레벨에서 synchronized 키워드는 `monitorenter`와 `monitorexit` 명령어로 구현
29 | - monitorenter
30 | - 스레드가 객체의 모니터를 `획득`할 때 호출
31 | - 만약 모니터가 다른 스레드에 의해 이미 잠겨 있다면, 해당 스레드는 모니터를 획득할 때까지 대기
32 | - monitorexit
33 | - 스레드가 모니터를 `해제`할 때 호출
34 | - 일반적으로 synchronized 블록 또는 메서드의 끝에서 실행
35 |
36 | ## Lock의 범위
37 |
38 | ### 메서드에 synchronized 키워드 추가
39 |
40 | ```java
41 | public class Test {
42 | public synchronized void test() {
43 | // 생략
44 | }
45 | }
46 | ```
47 |
48 | - 메서드가 포함된 객체(this)에 Lock이 걸림
49 | - Object 레벨의 Lock
50 | - 만약 `static 메서드`에 synchronized 키워드를 추가하면 Class 레벨의 Lock
51 |
52 |
53 | ### 블록에 synchronized 키워드 추가
54 |
55 | ```java
56 | public class Test {
57 | public void test() {
58 | synchronized (Product.class) {
59 | // 생략
60 | }
61 |
62 | // 생략
63 | }
64 | }
65 | ```
66 |
67 | - 괄호안에 인자로 넣는 객체가 Lock이 걸림
68 | - Class 레벨의 Lock
69 | - 만약 인스턴스 레벨의 Lock을 걸고 싶다면 `this`를 넣으면 됨
70 |
71 | ## wait(), notify(), notifyAll()
72 |
73 | - Object에 정의되어 있는 메서드
74 | - synchronized 블록 내에서만 사용 가능
75 | - 효율적인 동기화 지원
76 | - `wait()`: waiting pool로 이동
77 | - `notify()`: waiting pool에서 임의의 스레드 하나만 깨움
78 |
79 | ## synchronized로 동시성 제어하기
80 |
81 | - synchronized를 사용하면 `동시성 문제`를 해결할 수 있음
82 | - 하지만 `성능 저하`가 발생할 수 있음
83 | - `Race Condition`
84 | - notify()는 하나를 임의로 선택해서 통지할 뿐이고, 여러 쓰레드가 lock를 얻기 위해 경쟁
85 | - `Starvation`
86 | - notify()는 무작위로 선택되기 때문에, 특정 쓰레드가 계속해서 선택되지 않을 수 있음
87 | - notifyAll()을 사용해도 결국 Lock은 하나의 쓰레드만 획득 가능
88 | - 낮은 지연시간이 요구되거나 분산 환경에서는 다른 방법을 고려하자.
89 | - `ReentrantLock`과 `StampedLock`을 사용하면 성능을 향상시킬 수 있음
90 | - 분산락 활용
91 |
--------------------------------------------------------------------------------
/Language/Java/멀티스레드_환경에서_싱글톤으로_객체_생성하기.md:
--------------------------------------------------------------------------------
1 | # 멀티스레드 환경에서 싱글톤으로 객체 생성하기
2 |
3 | ## static 클래스를 활용할 수 있을까?
4 |
5 | - static 클래스와 싱글톤 모두 클래스를 하나 생성하는 것을 보장
6 | - 하지만, static 클래스는 `Class 레벨, 싱글톤은 Object 레벨
7 | - static 클래스는 직렬화 불가능
8 | - static 클래스는 상속 불가능
9 | - 싱글톤은 구현 방법에 따라 멀티스레드 환경에서 `Thread-safe` 보장 가능
10 |
11 | ## 싱글톤 구현 방법
12 |
13 | - 1번과 2번은 멀티스레드 환경에서 Race Condition이 발생할 수 있음
14 |
15 | ### 1. Eager Initialization
16 |
17 | ```java
18 | public class EagerSingleton {
19 | private static final EagerSingleton instance = new EagerSingleton();
20 |
21 | private EagerSingleton() {}
22 |
23 | public static EagerSingleton getInstance() {
24 | return instance;
25 | }
26 | }
27 | ```
28 |
29 | ### 2. Lazy Initialization
30 |
31 | ```java
32 | public class LazySingleton {
33 | private static LazySingleton instance;
34 |
35 | private LazySingleton() {}
36 |
37 | public static LazySingleton getInstance() {
38 | if (instance == null) {
39 | instance = new LazySingleton();
40 | }
41 | return instance;
42 | }
43 | }
44 | ```
45 |
46 | ### 3. DCL (Double-Checked Locking)
47 |
48 | ```java
49 | public class DCLSingleton {
50 | private static volatile DCLSingleton instance;
51 |
52 | private DCLSingleton() {}
53 |
54 | public static DCLSingleton getInstance() {
55 | if (instance == null) {
56 | synchronized (DCLSingleton.class) {
57 | if (instance == null) {
58 | instance = new DCLSingleton();
59 | }
60 | }
61 | }
62 |
63 | return instance;
64 | }
65 | }
66 | ```
67 |
68 | ### 4. Holder
69 |
70 | ```java
71 | public class HolderSingleton {
72 | private HolderSingleton() {}
73 |
74 | private static class SingletonHolder {
75 | private static final HolderSingleton instance = new HolderSingleton();
76 | }
77 |
78 | public static HolderSingleton getInstance() {
79 | return SingletonHolder.instance;
80 | }
81 | }
82 | ```
83 |
84 | ### 5. Enum
85 |
86 | ```java
87 | public enum EnumSingleton {
88 | INSTANCE;
89 |
90 | public static EnumSingleton getInstance() {
91 | return INSTANCE;
92 | }
93 | }
94 | ```
95 |
--------------------------------------------------------------------------------
/Language/JavaScript/asyncAwait.md:
--------------------------------------------------------------------------------
1 | ## async / await
2 |
3 | ES2015에 추가된 기능에 대해 공부했다면 `프로미스`에 대해 알 것이다. 프로미스는 훌륭한 비동기 처리 방안이지만, 프로미스를 보다 편하고 깔끔하게 활용하는 방안이 고안되었다. ES2017에 추가된 `async/await` 기능이다. ES2017에서 추가된 `async/await`는 콜백 지옥을 해결했지만 여전히 긴 `promise` 코드를 짧게 줄여주었고, 간단한 사용법으로 가독성까지 높였다. 아래 코드는 promise를 활용한 예제다.
4 |
5 | ```javascript
6 | function findAndSaveUser(Users) {
7 | Users.findOne()
8 | .then((user) => {
9 | user.name = "gildong";
10 | return user.save();
11 | })
12 | .then((user) => {
13 | return Users.findOne({ gender: "m" });
14 | })
15 | .then((user) => {
16 | // 생략
17 | })
18 | .catch((err) => {
19 | console.error(err);
20 | });
21 | }
22 | ```
23 |
24 | 프로미스를 활용한 코드는 매우 유용하지만, 여전히 코드가 길어 작성하거나 읽기 힘들다. 아래는 async/await를 활용한 코드다.
25 |
26 | ```javascript
27 | async function findAndSaveUser(Users) {
28 | try {
29 | let user = await Users.findOne({});
30 | user.name = "zero";
31 | user = await user.save();
32 | user = await Users.findOne({ gender: "m" });
33 | // 생략
34 | } catch (error) {
35 | console.error(error);
36 | }
37 | }
38 | ```
39 |
40 | function 키워드 앞에 async를 붙이고, 내부의 promise를 반환하는 비동기 처리 함수 앞에 await를 붙여주기만 하면 된다. `async/await`는 Node 7버전부터 사용할 수 있다.
41 |
42 | ---
43 |
44 | ### **참고자료**
45 |
46 | - 서적: Node.js 교과서
47 |
--------------------------------------------------------------------------------
/Language/Kotlin/dataClass.md:
--------------------------------------------------------------------------------
1 | ## Data Class
2 |
3 | > ### Data Class란?
4 |
5 | : 데이터를 다루는 데 최적화된 클래스
6 |
7 | - POJO 클래스로 구현된 데이터 클래스의 단점
8 | - 보일러 플레이트 코드가 필요
9 | - 이런 고충을 해결하기 위해
10 | - Java → Record
11 | - Kotlin → Data Class
12 | - Data Class 선언의 제한 사항
13 | - 기본 생성자에 `최소 하나`의 파라미터가 있어야 함
14 | - 기본 생성자의 파라미터는 val이나 var여야만 함
15 | - abstract, open, sealed, inner가 안 됨
16 |
17 | > ### Canonical Methods
18 |
19 | - Data Class는 기본적으로 캐노니컬 메서드 지원
20 | - getter & setter, equals(), hashCode(), toString()
21 |
22 | > ### copy()
23 |
24 | : 원하는 파라미터를 Overriding 해서 데이터 클래스의 새로운 인스턴스를 `깊은 복사`하여 생성
25 |
26 | ```kotlin
27 | val americano = Coffee("Americano", 4500)
28 | val latte = americano.cope(name = "Latte")
29 | ```
30 |
31 |
32 |
33 | > ### Destructuring
34 |
35 | : 객체의 구조를 분해 후 할당이나 확장과 같은 연산을 수행
36 |
37 | ```kotlin
38 | val americano = Coffee("Americano", "dark", 4500)
39 | val (name, kind, price) = americano
40 |
41 | // 사용 되지 않는 값은 언더바(_)로 대체
42 | val latte = Coffee("Latte", "sweet", 5000)
43 | val (name, _, price) = latte
44 | ```
45 |
46 |
47 |
48 | > ### Reference
49 |
50 | - [https://readystory.tistory.com/85](https://readystory.tistory.com/85)
51 |
--------------------------------------------------------------------------------
/Language/Kotlin/kotlinSingleton.md:
--------------------------------------------------------------------------------
1 | ## Kotlin의 싱글톤
2 |
3 | Kotlin에는 `static` 키워드 대신 `object`와 `companion object`를 지원한다.
4 |
5 | > ### object
6 |
7 | : 싱글톤 패턴을 위해 Kotlin이 지원하는 키워드로, 자동적으로 싱글톤 패턴이 구현된 클래스가 작성됨
8 |
9 | - 단일 인스턴스 보장
10 | - object로 선언된 클래스는 애플리케이션 전체에서 하나의 인스턴스만 존재
11 | - 인스턴스는 프로그램이 실행될 때 자동으로 생성됩니다.
12 | - 전역 상태 관리
13 | - 전역 상태나 설정 정보를 관리할 때 유용
14 | - 모든 곳에서 동일한 상태나 설정을 참조해야 할 경우 활용
15 | - 동시성 문제 해결
16 | - 싱글톤 패턴을 직접 구현할 때 발생할 수 있는 동시성 문제 해결
17 | - Kotlin이 자체적으로 스레드 안전성(thread safe)을 보장
18 |
19 | ```kotlin
20 | object Logger {
21 | fun log(message: String) {
22 | println("Log: $message")
23 | }
24 | }
25 |
26 | // 활용
27 | Logger.log("This is a log message.")
28 | ```
29 |
30 | > ### companion object
31 |
32 | : 특정 클래스에 종속된 정적 멤버(static member)를 정의하기 위해 클래스 내부에 선언
33 |
34 | - 정적 멤버 구현
35 | - 인스턴스를 생성하지 않고도 클래스 내부의 메서드나 변수를 사용 가능
36 | - 클래스 관련 유틸리티 함수나 상수를 정의할 때 유용
37 | - 팩토리 메서드 패턴 구현
38 | - 객체 생성 로직을 캡슐화하기 위해 팩토리 메서드를 companion object에 정의
39 | - 객체의 확장 가능성
40 | - 다른 클래스나 인터페이스를 상속하지 않고도, companion object에 확장 함수나 속성 추가 가능
41 |
42 | ```kotlin
43 | class Student {
44 | companion object {
45 | const val SCHOOL = "KOTLIN SCHOOL"
46 |
47 | fun create(): MyClass {
48 | return Student()
49 | }
50 | }
51 | }
52 |
53 | // 사용
54 | println(Student.SCHOOL)
55 | val instance = Student.create()
56 | ```
57 |
58 | → companion object는 객체 내에 객체가 생기기 때문에 java의 static과 동일하게 사용하고 싶다면 @JvmField나 @JvmStatic을 활용하자.
59 |
--------------------------------------------------------------------------------
/Programming/Object-Orientation/ood.md:
--------------------------------------------------------------------------------
1 | ## **객체지향 개발 방법론**
2 |
3 | : 현실 세계의 개체(Entity)를 속성(Attribute)과 메서드(Method)가 결합된 형태의 객체(Object)로 표현하는 개념으로, 개체 간의 메시지 통신을 통해 시스템을 구현하는 개발 방법
4 |
5 |
6 |
7 | ### **장점**
8 |
9 | - 규모가 큰 대형 프로젝트에 적합
10 | - SW의 재사용•확장•유지보수 용이
11 | - 신속하게 개발 가능
12 | - 사용자 타입 중심
13 | - 대화식 프로그램 개발에 용이
14 |
15 |
16 |
17 | ### **단점**
18 |
19 | - 설계가 어려움
20 | - 규모가 크기 때문에 실행속도 저하
21 |
22 | ## **구성요소**
23 |
24 | - **클래스** (class)
25 | - 같은 역할을 하는 집단에 속한 속성(Attribute)과 행위(Behavior)를 정의한 것
26 | - **인스턴스** (instance)
27 | - 어떤 클래스에 속하는 구체적인 객체
28 | - **속성** (attribute)
29 | - 객체 안에 존재하는 절대적 자료형
30 | - **메서드** (method)
31 | - 객체가 메시지를 받아 실행해야 할 객체의 구체적인 연산을 정의한 것
32 | - **메시지** (message)
33 | - sender와 receiver 객체들 간의 상호작용 수단
34 |
35 | ## **특징**
36 |
37 | - 모형의 적합성
38 | - 객체 중심 모형은 우리의 사고방식과 매우 유사
39 | - 뚜렷하게 구별되는 객체로 나누고 객체들의 메시지는 상호작용 수단으로 활용
40 | - 재사용 용이
41 | - Openness, Closeness를 다 갖춘 재사용 단위
42 | - 상속, 다형성 등이 적용
43 | - Time-To-Market
44 | - 종래의 폭포수 모형은 단계가 길고 문서 작업이 많음
45 | - 클래스의 재사용과 확장에 의한 빠른 개발 가능
46 | - 설계와 프로그래밍의 매핑
47 | - 개발 각 단계의 전환이 자연스럽고 신속함
48 |
49 |
50 |
51 | ### **추가자료**
52 |
53 | - OOP란? [Object Oriented Programming](https://github.com/lcomment/development-recipes/blob/main/Computer%20Science/SW%20Engineering/oop.md)
54 | - 객체지향 개발 5대 원리! [SOLID](https://github.com/lcomment/development-recipes/blob/main/Computer%20Science/SW%20Engineering/solid.md)
55 |
56 |
57 |
58 | ---
59 |
60 | ### **참고자료**
61 |
62 | - Web
63 | - [_@wiki_](http://wiki.hash.kr/index.php/객체지향_개발방법론)
64 | - [@many258](https://many258.github.io/study/software-engineering-object-oriented/)
65 |
--------------------------------------------------------------------------------
/Programming/Object-Orientation/oop.md:
--------------------------------------------------------------------------------
1 | ## **OOP (; Object Oriented Programming)**
2 |
3 | ### **❖ def)**
4 |
5 | : 객체 지향 프로그래밍으로, 대표적으로 캡슐화, 추상화, 다형성, 상속성 라는 특징을 띄고 있다.
6 |
7 | - 캡슐화
8 | - : 하나의 객체에 대해 그 객체가 특정한 목적을 위해 필요한 변수나 메소드를 하나로 묶는 것
9 | - 캡슐화의 가장 큰 목적은 정보 은닉화
10 | - 추상화
11 | - : 목적과 관련이 없는 부분을 제거하고, 공통의 속성이나 기능을 묶어 이름을 붙이는 것
12 | - 다형성
13 | - : 형태가 같은데 다른 기능을 하는 것
14 | - 코드의 재사용, 코드 길이 감소 → 유지보수 용이
15 | - 상속성
16 | - : 기존 상위클래스에 근거하여 새롭게 클래스와 행위를 정의할 수 있게 도와주는 것
17 | - 부모(상위 클래스)의 특징(멤버변수나 멤버메서드)을 자식(하위 클래스)이 물려받음
18 |
19 | ### **❖ OOP와 PP**
20 |
21 | 컴퓨터공학부에 진학 후 처음 접하는 프로그래밍 언어는 대부분 C laguage일 것이다. 이후 Java를 공부하면서 OOP(; Object Oriented Programming)를 접하게 되고, PP(; Procedure Programming)와의 차이점에 대해서 생각하게 된다. 그리고 의문점이 든다. "프로그램은 어떻게 짜든 절차적으로 돌아가지 않나?" 객체를 지향하든, 절차를 지향하든 프로그램은 기본적으로 절차에 따라서 동작하기 때문이다.
22 |
23 | PP에서 Procedure는 번역하면 절차가 맞지만, 사실 함수라는 뜻도 내포하고 있다. 따라서 PP는 데이터를 모아 함수로 만들어 절차대로 프로그래밍한다고 해석할 수 있다. 실행하고자 하는 절차대로 흐름도(순서도)를 설계하여 이를 기준으로 프로그램을 작성한다. 우리가 사용해봤던 C language가 대표적인 PP다.
24 |
25 | OOP는 말 그대로 객체지향 프로그래밍이다. 데이터의 기능을 모아 하나의 객체를 만들어 프로그래밍 한다는 의미다. 이 때는 객체들의 관계 등에 초점을 맞추어 프로그래밍 한다. 대표적으로 Java와 Python이 있다. (Python은 정확히 객체 지향 언어이면서 함수형 언어다.)
26 |
27 | 그렇다면 어떻게 프로그래밍 해야 PP이고, 또 어떻게 프로그래밍 해야 OOP일까? 현금용 음료수 자판기를 예로 들어보자. "자판기를 어떻게 사용해야 해요?"라는 질문에 우리는 아래와 같이 대답할 수 있다.
28 |
29 | ```text
30 | i) 고객이 자판기에 돈을 넣는다,
31 | ii) 자판기에서 돈을 검사한다.
32 | iii) 고객이 제품을 고르고, 자판기는 계산하여 제품과 잔돈을 불출한다.
33 | iv) 고객이 제품과 잔돈을 가져간다.
34 | ```
35 |
36 |
37 | PP의 방식으로 프로그래밍 한다면 함수와 전역 변수를 통해 하나의 파일에서 개발할 수 있다. 음료 a의 잔여 개수를 전역 변수로 두고, 품절인지 확인하는 함수, 투입된 돈과 가격을 비교해주는 함수 등으로 말이다. 하지만 이렇게 프로그램을 구성한다면 당연히 코드의 길이가 길어질 것이다. 나중에 새로운 음료가 추가되거나 기존의 음료가 더 이상 생산하지 않게 됐을 때 코드를 수정하기 힘들 것이다.
38 |
39 |
40 | 그럼 OOP는 어떻게 프로그래밍 할까? 고객과 자판기, 음료를 객체로 두어 Main에서는 이 객체들의 멤버 변수, 메서드로 간단히 프로그래밍할 수 있다. 위에서 말한 음료에 관한 이슈를 해결하는 것도 수월하다. (나중에 자세히 배우겠지만,) interface(언어마다 다르다)로 음료의 기본적인 틀을 만들어 놓고, 종류별로 그 interface를 구현해주기만 하면 된다. 음료a 생산이 중단되면 음료a 클래스를 지워주면 되고, 음료z가 추가되면 interface를 따라서 구현만 해주면 된다.
41 |
42 |
43 | 당연히 모든 프로그래밍에서 OOP가 답은 아니다. PP와 OOP의 장단점을 정리하면서 이 주제를 넘어가보자.
44 |
45 |
46 |
47 | ```
48 | PP(; Procedure Progamming)
49 |
50 | 📝 장점
51 | - 객체나 클래스를 만들 필요 없이 바로 프로그램 코딩 가능
52 | - 필요한 기능을 함수로 만들어 두기 때문에 같은 코드를 복사하지 않고 호출하여 사용 가능
53 | - 프로그램의 흐름 쉽게 추적 가능
54 |
55 | 📝 단점
56 | - 각 코드가 매우 유기성이 높기 때문에 유지보수가 힘듦
57 | - 프로그램 전체에서 코드를 재사용 불가능
58 | - 디버깅 과정이 어렵움
59 | ```
60 |
61 | ```
62 | OOP(; Object Oriented Programming)
63 | 📝 장점
64 | - 모듈화, 캡슐화 → 유지보수 용이
65 | - 현실 세계와 유사 → 코드를 이해하기 쉬움
66 | - 객체는 그 자체가 하나의 프로그램 → 다른 프로그램에서 재사용이 가능하다.
67 |
68 | 📝 단점
69 | - 대부분의 객체 지향 프로그램은 속도가 상대적으로 느려지고 많은 양의 메모리를 사용
70 | - 현실 세계와 유사성에 의해 코드를 이해하기 쉽게 만드는 만큼 설계 과정에 시간이 많이 투자됨
71 | ```
72 |
--------------------------------------------------------------------------------
/Programming/Object-Orientation/transaction_domain.md:
--------------------------------------------------------------------------------
1 | ## 트랜잭션 스크립트 패턴
2 |
3 | > ### Transaction Script Pattern
4 |
5 | : 소프트웨어 설계에서 비즈니스 로직을 절차적으로 구현하는 패턴
6 |
7 | - 애플리케이션의 비즈니스 로직을 독립된 스크립트(메서드)로 정의
8 | - 스크립트는 특정 비즈니스를 처리하기 위한 모든 로직을 포함
9 |
10 | > ### 예시 코드
11 |
12 | ```java
13 | public class LikeService {
14 |
15 | public void likeCake(final User user, final Long cakeId) {
16 | final Cake cake = cakeRepository.findById(cakeId);
17 | final CakeLike cakeLike = cakeLikeRepository.findOrNullByUserAndCake(user, cake);
18 |
19 | likeOrCancel(cakeLike, user, cake);
20 | }
21 |
22 | private void likeOrCancel(final CakeLike cakeLike, final Cake cake, final User user) {
23 | if (isNull(cakeLike) {
24 | cakeLikeRepository.save(new CakeLike(cake, user));
25 | } else {
26 | cakeLikeRepository.delete(new CakeLike(cake, user));
27 | }
28 | }
29 | }
30 | ```
31 |
32 | > ### 장점
33 |
34 | - 단순한 로직: 로직이 단순한 경우, 구현이 쉽고 유지보수가 간단함
35 | - 명확한 비즈니스 로직: 각 메서드가 특정 비즈니스 트랜잭션을 명확하게 다룸
36 | - 빠른 개발 속도: 초기 개발 단계에서 빠르게 비즈니스 로직 구현 가능
37 |
38 | > ### 단점
39 |
40 | - 힘든 유지보수: 비즈니스 로직이 복잡해지면 코드가 중복되거나 유지보수가 힘들어짐
41 | - 재사용성 저하: 각 스크립트가 독립적으로 동작
42 | - 부족한 도메인 지식: 도메인에 대하여 캡슐화하거나 표현하기 어려움
43 |
44 |
45 |
46 | ## 도메인 모델 패턴
47 |
48 | > ### Domain Model Pattern
49 |
50 | : 비즈니스 도메인 로직을 도메인 객체로 표현하는 설계 방법
51 |
52 | - 엔티티, 값 객체, 애그리게이트 등의 객체 정의 및 비즈니스 로직을 객체에 캡슐화
53 | - 응집도가 높은 도메인 객체를 만들고, 객체 간 결합도를 낮추는 유연한 설계 가능
54 |
55 | > ### 예시 코드
56 |
57 | ```java
58 | public class LikeService {
59 |
60 | public void likeCake(final User user, final Long cakeId) {
61 | final Cake cake = cakeRepository.findByIdWithLike(cakeId);
62 |
63 | if (!cake.isLikedBy(user)) {
64 | user.likeCake(cake);
65 | } else {
66 | user.unLikeCake(cake);
67 | }
68 | }
69 | }
70 | ```
71 |
72 | > ### 장점
73 |
74 | - 비즈니스 로직 캡슐화: 코드가 도메인을 잘 반영하고 이해하기 쉬워짐
75 | - 높은 재사용성: 도메인 객체들은 독립적이고 재사용이 용이
76 | - 용이한 유지보수: 변화하는 요구사항에 맞추어 시스템 확장 및 유지보수가 쉬움
77 | - 도메인 지식 반영: 비즈니스와 코드의 일관성 유지
78 |
79 | > ### 단점
80 |
81 | - 초기 설계 비용: 초기 단계에서 복잡도 증가
82 | - 복잡성 관리: 시스템이 복잡해지면 도메인 모델 자체가 복잡해짐
83 | - 오버엔지니어링: 단순한 애플리케이션에 적용 시, 과도한 설계로 인한 개발 비용 증가
84 |
--------------------------------------------------------------------------------
/Programming/Test/tdd.md:
--------------------------------------------------------------------------------
1 | ## TDD (Test-Driven Development)
2 |
3 | > ### 테스트 주도 개발, TDD
4 |
5 |
6 |
7 | 기존 개발 프로세스(`좌측 사진`)는 설계(디자인) 후 코드 개발을 하고 테스트케이스를 작성했다. 이 때문에 초기 설계가 완벽하지 않다면 재설계로 인해 불필요한 코드가 남거나 중복처리 될 가능성이 있다. 이와 다르게 TDD(`우측 사진`)는 설계 이후 테스트케이스를 작성한 후 코드를 개발하여 리펙토링하는 절차를 따른다.
8 |
9 |
10 |

11 |

12 |
13 |
14 |
15 |
16 | 이와 같이 TDD는 Test-Driven Development의 약자로, `테스트 주도 개발`을 의미한다. `단위 테스트`(Unit Test)를 작성하고, 이를 통과하는 코드를 추가하는 단계를 반복하여 실제 코드를 개발한다. `짧은 개발 주기`의 반복에 의존하는 개발 프로세스이며, 애자일 방법론 중 하나인 XP(eXtream programming)의 `Test-First` 개념에 기반을 둔 단순한 설계를 중요시한다.
17 |
18 |
19 |
20 | ## TDD의 개발주기
21 |
22 |
23 |
24 |
25 |
26 | 위의 그림은 TDD의 개발주기다.
27 |
28 | - `Red` : 실패하는 테스트 코드를 먼저 작성
29 | - `Green` : 테스트 코드를 성공시키기 위한 실제 코드 작성
30 | - `Yellow` : 중복 코드 제거, 일반화 등의 리팩토링 수행
31 |
32 | 여기서 핵심은 `실패`하는 테스트 코드를 작성할 때까지 실제 코드를 작성하면 안 되고, 실패하는 테스트를 통과할 정도의 최소 실제 코드를 작성해야 한다는 것이다. 이 과정을 통해 실제 코드를 명확하게 정의할 수 있고, 불필요한 설계를 피할 수 있으며, 정확한 요구사항에 집중할 수 있다.
33 |
34 |
35 |
36 | ## TDD의 장단점
37 |
38 | - ### 장점
39 |
40 | - 튼튼한 객체지향적인 코드 생산
41 | - 재설계 시간 단축
42 | - 디버깅 시간 단축
43 | - 테스트 문서의 대체 가능
44 | - 추가 구현 용이
45 |
46 | - ### 단점
47 | - 생산성 저하
48 |
49 | ---
50 |
51 | ### **참고자료**
52 |
53 | - Web
54 | - [@clipsoft](http://clipsoft.co.kr/wp/blog/tddtest-driven-development-방법론/)
55 | - [@wooaoe](https://wooaoe.tistory.com/33)
56 |
--------------------------------------------------------------------------------
/Programming/Test/test.md:
--------------------------------------------------------------------------------
1 | ## Test
2 |
3 | > #### Test Code: `코드`나 `비즈니스 로직` 자체를 테스트하기 위해 작성한 코드
4 |
5 | 최근 애플리케이션을 개발할 때 테스트 코드로 로직을 확인하는 과정이 점점 중요해지고 있다. 많은 개발자들이 테스트 코드에 비용을 많이 투자하고, 테스트 주도 개발(TDD; Test-Driven Development)까지 등장했다. 그렇다고 `테스트 코드 작성`과 `테스트 주도 개발`은 같지 않다. 테스트에 대한 이론을 접하며 이해해보자.
6 |
7 |
8 |
9 | ## Test Code의 장점
10 |
11 | - 개발 과정에서 `문제를 미리 발견`할 수 있음
12 | - `리펙토링 리스크 감소`
13 | - 애플리케이션을 직접 테스트하는 것보다 `시간 단축`
14 | - `명세 문서`로서의 역할도 함
15 | - 몇 가지 프레임워크에 맞춰 테스트 코드를 작성하면 좋은 코드 생산 가능
16 | - 코드가 작성된 `목적을 명확히 표현` → 불필요한 내용이 추가되는 것 방지
17 |
18 |
19 |
20 | ## Test 종류
21 |
22 |
23 |
24 |
25 |
26 | - 통합 테스트
27 | - 모듈을 통합하는 과정에서의 호환성 등을 포함해 애플리케이션이 정상적으로 동작하는지 확인하기 위해 수행하는 테스트
28 | - 애플리케이션이 `온전히 동작`하는지 테스트
29 | - `테스트 비용`이 커지는 단점이 있음
30 | - 단위 테스트
31 | - 테스트 대상의 범위를 기준으로 가장 작은 단위의 테스트 방식
32 | - 일반적으로 `메서드` 단위
33 | - 비용이 적게 들어 테스트 피드백을 빠르게 받을 수 있음
34 |
35 |
36 |
37 | ---
38 |
39 | ### 참고자료
40 |
41 | - [도서: 스프링 부트 핵심 가이드](http://www.yes24.com/Product/Goods/110142898?pid=123487&cosemkid=go16558717080451377&gclid=CjwKCAiAvK2bBhB8EiwAZUbP1BUHUQwvsBmN-wOJqiKajet4ToYFinzdksHTDYInTthVj2HEIwn0MhoC4voQAvD_BwE)
42 | - [@galid1](https://galid1.tistory.com/783)
43 |
--------------------------------------------------------------------------------
/Programming/Test/testcodePattern.md:
--------------------------------------------------------------------------------
1 | ## Given-When-Then 패턴
2 |
3 | - ### `Given`
4 | - 테스트를 수행하기 전에 테스트에 필요한 `환경를 설정`하는 단계
5 | - 테스트에 필요한 변수를 정의
6 | - Mock 객체를 통해 특정 상황에 대한 행동 정의
7 | - ### `When`
8 | - 테스트의 `목적`을 보여주는 단계
9 | - 실제 테스트 코드가 포함됨
10 | - 테스트를 통한 결과를 가져옴
11 | - ### `Then`
12 | - 테스트의 `결과를 검증`하는 단계
13 | - 일반적으로 When 단계의 결과를 검증
14 | - 결과가 아니더라도 검증은 모두 Then 단계에 포함
15 |
16 | ```java
17 | . . .
18 |
19 | @Test
20 | void join() {
21 | // given: 이게 주어졌을 때
22 | Member member = new Member(1L, "memberA", Grade.VIP);
23 |
24 | // when: 이런 상황에서
25 | memberService.join(member);
26 | Member findMember = memberService.findMember(1L);
27 |
28 | // then: 이런 결괏값을 기대
29 | Assertions.assertThat(findMember).isEqualTo(member);
30 | }
31 | . . .
32 | ```
33 |
34 |
35 |
36 | ## F.I.R.S.T 전략
37 |
38 | - ### `F`ast
39 | - `빠르게` 수행돼야 한다
40 | - 목적을 단순하게 설정해서 작성
41 | - 외부 환경을 사용하지 않는 단위테스트 작성
42 | - ### `I`solated
43 | - 하나의 테스트 코드는 `하나의 목적`에 대해서만 수행돼야 한다
44 | - ### `R`epeatable
45 | - 어떤 환경에서도 `반복 가능`하도록 작성해야 한다
46 | - 개발 환경의 변화나 네트워크의 연결 여부와 상관없이 수행돼야 함
47 | - ### `S`elf-Validating
48 | - 그 자체만으로도 테스트의 검증이 완료돼야 한다
49 | - 테스트를 `성공`했는지 `실패`했는지 확인할 수 있는 코드가 있어야 함
50 | - 개발자가 직접 결괏값과 기댓값을 비교한다면 좋지 못한 테스트 코드임
51 | - ### `T`imely
52 | - 테스트하려는 애플리케이션 코드를 `구현하기 전`에 테스트 코드가 완성돼야 한다
53 | - 너무 늦게 작성되면 정상적인 역할을 수행하지 못함
54 | - TDD가 아니라면 이 규칙은 `제외 가능`
55 |
--------------------------------------------------------------------------------
/Programming/programming.md:
--------------------------------------------------------------------------------
1 | # Programming Recipe
2 |
3 | 프로그래밍 관련 레시피 입니다. 직접 학습하고 토이 프로젝트 및 실무 프로젝트에서 디자인 패턴 및 테스트 전략 등 적용 및 실험하며 작성 했습니다. 필요한 레시피를 편하게 얻어가시고, 원하는 레시피는 `ISSUE`에 등록, 추가하고 싶은 레시피와 잘못된 레시피는 `PR`에 등록해주시면 감사하겠습니다.
4 |
5 | ## 객체 지향 프로그래밍
6 |
7 | - [객체 지향 프로그래밍 (Object-Oriented Programming)](https://github.com/lcomment/development-recipes/blob/main/Programming/Object-Orientation/oop.md)
8 | - [객체 지향 개발방법론 (Object-Oriented Design)](https://github.com/lcomment/development-recipes/blob/main/Programming/Object-Orientation/ood.md)
9 |
10 | ## Test
11 |
12 | - [테스트와 테스트 코드](https://github.com/lcomment/development-recipes/blob/main/Programming/Test/test.md)
13 | - [Given-When-Then 패턴과 FIRST 전략](https://github.com/lcomment/development-recipes/blob/main/Programming/Test/testcodePattern.md)
14 | - [테스트 주도 개발방법론 (Test-Driven Development)](https://github.com/lcomment/development-recipes/blob/main/Programming/Test/tdd.md)
15 |
--------------------------------------------------------------------------------
/System Design/SNS_시스템_규모_추정.md:
--------------------------------------------------------------------------------
1 | # SNS 시스템 규모 추정
2 |
3 | ## 가정
4 |
5 | - `300,000,000` `monthly` active users
6 | - `50%` of users write `daily`
7 | - Users post `2 postings per day` on average
8 | - `10%` of postings contain `media`
9 | - Data is stored for `5 years`
10 |
11 | ### Post 사이즈
12 |
13 | - post_id: 64 bytes
14 | - text: 140 bytes
15 | - media: 1 MB
16 |
17 | ## 추정
18 |
19 | - 활성 유저
20 | - 3억
21 | - MAU
22 | - 3억
23 | - DAU
24 | - 3억 x 0.5
25 | - `1.5억`
26 | - 하루에 작성되는 게시글
27 | - 1.5억 x 2
28 | - `3억`
29 | - 하루에 쌓이는 미디어 데이터 용량
30 | - 3억 x 0.1 x 1MB
31 | - `30,000,000 MB`
32 | - 30TB
33 | - 5년간 쌓이는 미디어 데이터 용량
34 | - 30TB x 365 x 5
35 | - `54,750TB`
36 | - 54.75PB
37 | - QPS
38 | - 3억 / (24 x 3600)
39 | - `3,472`
40 | - Peek QPS
41 | - 3,472 x 2 = 6,944
42 | - 3,472 x 4 = 13,888
43 |
--------------------------------------------------------------------------------
/System Design/server.md:
--------------------------------------------------------------------------------
1 | # 서버와 로드밸런서
2 |
3 | ## I. 단일 서버
4 |
5 | - 한 서버에 웹 서버, DB, 캐시 등을 모두 실행하는 구성
6 | - 실제 운영 환경에서는 웹 서버와 DB를 각각 다른 서버에 구성
7 | - 이후, 캐시 등 `시스템의 컴포넌트를 분리`하여 각각 독립적으로 확장할 수 있는 환경 구성
8 |
9 | ### 동작 과정
10 |
11 | 1. Client가 DNS로 도메인을 보냄
12 | 2. DNS가 받은 도메인을 IP 주소로 변환하여 Client에게 전달
13 | 3. Client가 해당 IP 주소로 HTTP 요청 전달
14 | 4. 요청 받은 웹 서버가 응답 반환
15 |
16 | ## II. Scale Up과 Scale Out
17 |
18 | ### Scale Up
19 |
20 | - 기존 자원을 고사양 자원을 변경
21 | - 매우 간단하지만, 심각한 단점을 가지고 있음
22 | - 규모 확장에 한계가 있음
23 | - 장애 시 `자동복구`(failover)나 `다중화`(redundancy)가 불가능
24 |
25 | ### Scale Out
26 |
27 | - 서버나 컴퓨팅 리소스를 수평으로 확장하는 방법
28 | - 여러 노드에 작업을 `분산`하여 시스템 전체의 처리 성능을 높임
29 | - 필요에 따라 쉽게 서버를 `추가`하거나 `제거`하여 급격한 트래픽 증가에 유연하게 대응
30 | - Scale Up보다 비용이 저렴
31 |
32 | ## III. 로드밸런서
33 |
34 | - 부하 분산 집합에 속한 웹 서버들에게 트래픽 부하를 고르게 분산하는 역할을 함
35 | - 서버 1 다운 → 모든 트래픽을 서버 2에게 전송
36 | - 트래픽의 양에 따라 서버가 추가되거나 제거될 수 있음
37 | - 사용자는 로드밸런서의 Public IP에 접속
38 | - 서버 간 통신에는 Private IP 이용
39 |
--------------------------------------------------------------------------------
/System Design/systemDesign.md:
--------------------------------------------------------------------------------
1 | # System Design Recipe
2 |
3 | 시스템 설계하거나 시스템 설계 인터뷰를 대비하기 위한 레시피 입니다. 도서 `<가상 면접 사례로 배우는 대규모 시스템 설계 기초>`와 인프런 강의 <[모르면 승진 안되는 시스템 디자인](https://www.inflearn.com/course/%EB%AA%A8%EB%A5%B4%EB%A9%B4-%EC%8A%B9%EC%A7%84%EC%95%88%EB%90%98%EB%8A%94-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EB%94%94%EC%9E%90%EC%9D%B8)>를 바탕으로 학습하며 작성 했습니다. 필요한 레시피를 편하게 얻어가시고, 원하는 레시피는 `ISSUE`에 등록, 추가하고 싶은 레시피와 잘못된 레시피는 `PR`에 등록해주시면 감사하겠습니다.
4 |
5 | ## Ch01. 시스템 설계 인터뷰 Tip
6 |
7 | - [시스템 설계 인터뷰 공략법](https://github.com/lcomment/development-recipes/blob/main/System%20Design/시스템_설계_면접_공략법.md)
8 |
9 | ## Ch02. 시스템 컴포넌트
10 |
11 | - [서버와 로드밸런서](https://github.com/lcomment/development-recipes/blob/main/System%20Design/server.md)
12 | - [RDB와 NoSql](https://github.com/lcomment/development-recipes/blob/main/System%20Design/rdb_nosql.md)
13 | - [캐시와 CDN](https://github.com/lcomment/development-recipes/blob/main/System%20Design/캐시와_CDN.md)
14 | - [데이터 센터](https://github.com/lcomment/development-recipes/blob/main/System%20Design/데이터_센터.md)
15 | - [메시지 큐](https://github.com/lcomment/development-recipes/blob/main/System%20Design/메시지_큐.md)
16 | - 로그, 매트릭, 자동화
17 |
18 | ## Ch03. 개략적 규모 추정
19 |
20 | - [개략적 규모 추정](https://github.com/lcomment/development-recipes/blob/main/System%20Design/개략적_규모_추정.md)
21 | - [예제) SNS 시스템 규모 추정](https://github.com/lcomment/development-recipes/blob/main/System%20Design/SNS_시스템_규모_추정.md)
22 | - [예제) 홈페이지 시스템 규모 추정](https://github.com/lcomment/development-recipes/blob/main/System%20Design/홈페이지_시스템_규모_추정.md)
23 |
24 | ## Ch03. 기출 문제
25 |
26 | - [Rate Limiter 설계](https://github.com/lcomment/development-recipes/blob/main/System%20Design/처리율_제한_장치.md)
27 | - [Consistent Hash 설계](https://github.com/lcomment/development-recipes/blob/main/System%20Design/안정_해시.md)
28 | - Key-Value 저장소 설계
29 | - [분산 시스템을 위한 유일 ID 생성기 설계](https://github.com/lcomment/development-recipes/blob/main/System%20Design/분산_시스템을_위한_유일_ID_생성기.md)
30 | - [URL 단축기 설계](https://github.com/lcomment/development-recipes/blob/main/System%20Design/URL_단축기.md)
31 | - 웹 크롤러 설계
32 | - [알림 시스템 설계](https://github.com/lcomment/development-recipes/blob/main/System%20Design/알림_시스템.md)
33 | - [뉴스 피드 시스템 설계](https://github.com/lcomment/development-recipes/blob/main/System%20Design/뉴스_피드_시스템.md)
34 | - [채팅 시스템 설계](https://github.com/lcomment/development-recipes/blob/main/System%20Design/채팅_시스템.md)
35 | - [검색어 자동완성 시스템 설계](https://github.com/lcomment/development-recipes/blob/main/System%20Design/검색어_자동완성_시스템.md)
36 | - [유튜브 설계](https://github.com/lcomment/development-recipes/blob/main/System%20Design/유튜브_시스템.md)
37 | - 구글 드라이브 설계
38 | - 실시간 투표 시스템 설계
39 | - 실시간 Live 방송 시스템 설계
40 |
--------------------------------------------------------------------------------
/System Design/개략적_규모_추정.md:
--------------------------------------------------------------------------------
1 | # 개략적 규모 추정
2 |
3 | - 시스템 용량이나 성능 요구사항을 개략적으로 추정해 보라는 요구를 종종 받게 됨
4 | - 보편적으로 토용되는 성능 수치상에서 `사고 실험`을 행하여 `추정치를 계산`해야 함
5 |
6 | ## I. 2의 제곱수
7 |
8 | - 최소단위: 1byte = 8bit
9 | - ASCII 문자 하나는 1byte
10 |
11 | | 2의 n제곱 | 근사치 | 이름 | 축약형 |
12 | | --------- | ------- | --------- | ------ |
13 | | 10 | 1천 | 1Kilobyte | 1KB |
14 | | 20 | 1백만 | 1Megabyte | 1MB |
15 | | 30 | 10억 | 1Gigabyte | 1GB |
16 | | 40 | 1조 | 1Terabyte | 1TB |
17 | | 50 | 1,000조 | 1Petabyte | 1PB |
18 |
19 | ## II. 모든 프래그래머가 알아야 하는 응답지연 값
20 |
21 | | 연산명 | 시간 |
22 | | ------------------------------------------------------- | --------------------------------- |
23 | | L1 캐시 참조 | 0.5ns |
24 | | 분기 예측 오류 | 5ns |
25 | | L2 캐시 참조 | 7ns |
26 | | Mutex Lock/Unlock | 100ns |
27 | | 메인 메모리 참조 | 100ns |
28 | | Zippy로 1KB 압축 | 10,000ns = 10μs |
29 | | 1Gbps 네트워크로 2KB 패킷 전송 | 20,000ns = 20μs |
30 | | 메모리에서 1MB 순차적으로 읽기 | 250,000ns = 250μs |
31 | | 같은 데이터 센터 내 메시지 왕복 지연시간 | 500,000ns = 500μs |
32 | | 디스크 탐색 | 10,000,000ns = 10000μs = 10ms |
33 | | 네트워크에서 1MB 순차적으로 읽기 | 10,000,000ns = 10000μs = 10ms |
34 | | 디스크에서 1MB 순차적으로 읽기 | 30,000,000ns = 30000μs = 30ms |
35 | | 한 패킷의 캘리포니아로부터 네덜란드까지의 왕복 지연시간 | 150,000,000ns = 150,000μs = 150ms |
36 |
37 | - 메모리는 빠르지만, 디스크는 느림
38 | - 디스크 탐색은 가능한 피하자
39 | - 단순한 압축 알고리즘을 빠름
40 | - 데이터를 인터넷으로 전송하기 전에 가능한 압축하자
41 | - 데이터 센터는 보통 여러 지역에 분산돼 있고, 센터들 간에 데이터를 주고 받는데는 시간이 걸림
42 |
--------------------------------------------------------------------------------
/System Design/데이터_센터.md:
--------------------------------------------------------------------------------
1 | # 데이터 센터
2 |
3 | - 장애가 없는 상황에서 사용자는 가장 가까운 데이터 센터로 안내됨
4 | - 이를 지리적 라우팅(geoDNS-routing 또는 geo-routing)이라고 함
5 | - `geoDNS` : 사용자의 위치에 따라 도메인 네임을 어떤 IP 주소로 매핑할지 결정하는 기술
6 | - 장애 발생 시, 다른 데이터 센터로 트래픽 전송
7 |
8 | ### 다중 데이터 센터 아키텍처를 만들기 위한 기술적 난재
9 |
10 | - 트래픽 우회
11 | - 올바른 데이터 센터로 트래픽을 보내는 효과적인 방법을 찾아야 함
12 | - GeoDNS → 사용자에게서 가장 가까운 데이터센터로 트래픽 전송
13 | - 데이터 동기화
14 | - 데이터 센터마다 별도의 DB 사용
15 | - 장애가 자동으로 failover 돼도 데이터가 동기화 돼있어야 함
16 | - 보편적 전략 → 데이터를 여러 데이터 센터에 걸쳐 `레플리케이션` 하자
17 | - 테스트와 배포
18 | - 여러 환경(위치)에서 테스트
19 | - 모든 데이터 센터에 동일한 서비스가 설치되도록 배포
20 |
--------------------------------------------------------------------------------
/System Design/메시지_큐.md:
--------------------------------------------------------------------------------
1 | # 메시지 큐
2 |
3 | - 자료구조 중 `Queue`를 채택하여 메세지를 전달하는, `메세지 지향 미들웨어`를 구현한 시스템
4 | - 메시지의 무손실을 보장하는 비동기 통신 방식의 컴포넌트
5 | - 서비스 또는 서버 간 결합이 느슨해짐
6 | - 메시지를 보내는 쪽과 받는 쪽이 독립적으로 동작할 수 있도록 해줌
7 | - 규모 확장성 보장
8 |
9 |
10 |
11 |
12 |
13 | ## 종류
14 |
15 | ### 1. RabbitMQ
16 |
17 | - 특징
18 | - `AMQP`(Advanced Message Queuing Protocol) 기반
19 | - 다양한 프로토콜 지원
20 | - `안정적인 메시지` 전달 보장
21 | - 강력한 라우팅 기능(Direct, Topic, Fanout, Header) 등 제공
22 | - 장점
23 | - 성숙한 커뮤니티와 플러그인 시스템
24 | - 메시지의 신뢰성 보장 기능이 뛰어남
25 | - 다양한 언어의 클라이언트 지원
26 |
27 | ### Apache Kafka
28 |
29 | - 특징
30 | - 분산형 스트리밍 플랫폼으로, 대규모 데이터를 처리하도록 설계되었음
31 | - 동일 파티션 내 이벤트 처리 `순서 보장`
32 | - `적어도 한번 전송 방식`을 통한 멱등성 보장
33 | - 자연스러운 `백프레셔 핸들링`
34 | - 카프카의 클라이언트가 Pull 방식으로 동작
35 | - Push 방식은 브로커가 보내주는 속도에 의존하게 됨
36 | - 주로 로그와 같은 `대용량 이벤트 스트림 처리`에 탁월
37 | - `강력한 파티셔닝`을 통한 수평 확장
38 | - Pub/Sub 모델 지원
39 | - 장점
40 | - 고성능의 처리 능력
41 | - `수평 확장`이 용이
42 | - 이벤트 소싱과 같은 이벤트 기반 아키텍처에 적합
43 |
44 | ### Amazon SQS (Simple Queue Service)
45 |
46 | - 특징
47 | - AWS에서 제공하는 완전 관리형 메시지 큐 서비스
48 | - 서버리스 환경에서 `비용 효율적`으로 사용할 수 있음
49 | - 메시지 `순서가 중요하지 않은` 경우에 적합한 Standard Queue 제공
50 | - `순서와 중복 방지 보장`이 필요한 경우에 적합한 FIFO Queue 제공
51 | - 장점
52 | - 관리가 간편하고 서버 없이 사용할 수 있음
53 | - AWS와의 통합 용이
54 |
55 | ### Redis Pub/Sub
56 |
57 | - 특징
58 | - 인메모리 데이터 저장소인 Redis에서 제공하는 Pub/Sub 기능을 활용하여 메시지를 전달
59 | - 대기열이 아니라 메시지가 즉시 전송
60 | - 메시지 큐보다는 `실시간 데이터 전송`에 더 가까움
61 | - 장점
62 | - 빠른 속도
63 | - 메시지 브로커와 캐싱을 동시에 수행 가능.
64 |
--------------------------------------------------------------------------------
/System Design/분산_시스템을_위한_유일_ID_생성기.md:
--------------------------------------------------------------------------------
1 | # 분산 시스템을 위한 유일 ID 생성기
2 |
3 | ## 문제
4 |
5 | ### 분산 시스템에서 사용될 유일 ID 생성기를 설계하라
6 |
7 | - DB의 auto_increament 속성 사용?
8 | - 여러 DB 서버를 쓰는 경우 지연 시간을 낮추기 힘듦
9 |
10 | ## 1단계
11 |
12 | ### 할 수 있는 질문
13 |
14 |
15 | 펼쳐보기
16 |
17 | 1. ID는 어떤 특성을 갖는지?
18 | 2. 새로운 레코드에 붙는 ID는 항상 이전보다 1만큼 큰 값인지?
19 | 3. 숫자로만 구성되는지?
20 | 4. 시스템 규모는 어느 정도인지?
21 |
22 |
23 |
24 | ### 면접관의 답변 예시
25 |
26 |
27 | 펼쳐보기
28 |
29 | 1. `유일`해야 하고, `정렬` 가능해야 함
30 | 2. 시간의 흐름에 따라 커지지만, 언제나 1만큼 증가하지는 않음
31 | 3. `숫자`로만
32 | 4. `초당 10,000` ID를 생성해야 함
33 |
34 |
35 |
36 | ### 답변으로 정리된 요구사항
37 |
38 |
39 | 펼쳐보기
40 |
41 | 1. ID는 유일해야 한다.
42 | 2. ID는 숫자로만 구성되어야 한다.
43 | 3. ID는 64비트로 표현할 수 있는 값이어야 한다.
44 | 4. ID는 발급 날짜에 따라 정렬 가능해야 한다.
45 | 5. 초당 10,000개의 ID를 만들 수 있어야 한다.
46 |
47 |
48 |
49 | ## 2단계
50 |
51 | ### 다중 마스터 복제
52 |
53 | - DB의 `auto_increament` 활용
54 | - 1이 아닌 `k`만큼 증가
55 |
56 |
57 |
58 |
59 |
60 | #### 한계점
61 |
62 | - 여러 데이터 센터에 걸쳐 규모를 늘리기 어려움
63 | - ID의 유일성 보장, but 시간 흐름에 맞추어 커지도록 보장하기 힘듦
64 | - 서버를 추가하거나 삭제할 때 잘 동작하게 만들기 어려움
65 |
66 | ### UUID
67 |
68 | - 컴퓨터 시스템에 저장되는 정보를 유일하게 식별하기 위한 128비트짜리 수
69 | - 충돌 가능성이 지극히 낮음
70 | - 만드는 방법도 단순하고, 규모 확장도 쉬움
71 |
72 | #### 한계점
73 |
74 | - 길이가 64비트 이상임
75 | - ID를 시간순으로 정렬하기 힘듦
76 | - ID에 숫자가 아닌 문자가 포함될 수 있음
77 |
78 | ### 티켓 서버
79 |
80 | - 티켓 서버(auto_increament 기능을 갖춘 DB 서버)를 중앙 집중형으로 하나만 사용
81 | - `유일성`이 보장되는, 오직 `숫자`로만 수정된 ID 생성
82 | - 구현이 쉽고, 중소 규모 애플리케이션에 적합
83 |
84 |
85 |
86 |
87 |
88 | #### 한계점
89 |
90 | - 티켓 서버가 `SPOF`가 됨
91 | - 그렇다고 서버 여러 대를 구성하면 `동기화 문제` 발생
92 |
93 | ### 트위터 스노플레이크 접근법
94 |
95 |
96 |
97 |
98 |
99 | - Sign
100 | - 음수, 양수 표시
101 | - 1비트 할당
102 | - Timestamp
103 | - 기원 시각 이후 몇 밀리초가 경과됐는지
104 | - 41비트 할당
105 | - 데이터 센터 ID
106 | - 5비트 할당
107 | - 서버 ID
108 | - 5비트 할당
109 | - 일련번호
110 | - 1ms 경과 시 0으로 초기화
111 | - 12비트 할당
112 |
113 | ## 3단계
114 |
115 | ### 타임스탬프
116 |
117 | - 시간 정렬 가능
118 | - 최대값: 2^41 - 1
119 | - 최대 나타낼 수 있는 ms초: 69년
120 | - overflow가 발생하는 시점에 기원 시각을 바꾸거나 ID 체계를 바꿔야 함
121 |
122 | ### 일련번호
123 |
124 | - 총 4096개의 값 생성
125 | - 한 서버에서 1ms 동안 4096개 이상의 데이터를 생성하는 것까지 감당함
126 |
127 | ## 4단계
128 |
129 | - 시계 동기화
130 | - 한 서버의 여러 코어 또는 여러 서버일 경우 시계를 동기화 해야 한다.
131 | - 각 절의 길이 최적화
132 | - 동시성이 낮다면 타임스탬프를 늘리고, 일련번호를 줄이자
133 | - 고가용성
134 | - ID 생성기는 필수 불가결 컴포넌트이므로 고가용성을 제공해야 한다.
135 |
--------------------------------------------------------------------------------
/System Design/안정_해시.md:
--------------------------------------------------------------------------------
1 | # 안정 해시
2 |
3 | ## 해시 키 재배치 문제
4 |
5 | - N개의 캐시 서버가 있을 때, 서버들에게 부하를 균등하게 나누는 보편적인 방법은 `해시 함수`를 사용하는 것
6 |
7 | ```
8 | serverIndex = hash(key) % N
9 | ```
10 |
11 | ### 단점
12 |
13 | - Server Pool의 크기가 고정돼 있을 때, 균등히 동작
14 | - 서버 장애로 새로운 서버가 추가 또는 기존 서버가 삭제될 경우 문제가 생김
15 | - 해당 서버에 존재하던 해시키가 사라지고, 엉뚱한 서버로 접속해 `대규모 캐시 미스` 발생
16 |
17 | ## 안정 해시 (Consistent Hash)
18 |
19 | - 해시 테이블의 크기가 조정될 때, 평균적으로 `k / n`개의 키만 재배치하는 해시 기술
20 | - k: 키의 개수
21 | - n: 슬롯의 개수
22 | - 해시 공간의 양쪽을 구부려 접으면 `해시 링`(hash ring)이 만들어짐
23 | - `균등 분포 해시 함수`를 활용하여 해시 링 위에 해시 서버가 배치됨
24 | - 해시 링 위에 캐시할 키들이 배치됨
25 | - 서버 조회: 해당 키로부터 `시계 방향`으로 링을 탐색해 나가면서 만나는 첫번째 서버
26 |
27 | ### 문제
28 |
29 | - 파티션의 크기를 균등하게 유지하는게 불가능
30 | - 서버가 추가 및 삭제되면 파티션의 크기가 불균등해짐
31 | - 키의 균등 분포를 달성하기 어려움
32 | - 한쪽에만 키가 몰릴 수 있음
33 |
34 | ## 가상 노드
35 |
36 | - 실제 노드 또는 서버를 `가리키는` 노드
37 | - 하나의 서버는 링 위에 여러 개의 가상 노드를 가질 수 있음
38 | - 가상 노드의 개수를 늘리면 표준 편차가 작아져 키의 분포도는 점점 균등해짐
39 | - 가상 노드가 `200`개인 경우, 표준편차 값은 평균의 `5%`
40 | - 가상 노드가 `100`개인 경우, 표준편차 값은 평균의 `10%`
41 | - 가상 노드이 개수를 더 늘리면 표준 편차의 값은 더 떨어짐
42 | - 하지만 가상 노드 데이터를 저장할 공간이 더 많이 필요해지게 됨
43 |
--------------------------------------------------------------------------------
/System Design/캐시와_CDN.md:
--------------------------------------------------------------------------------
1 | # 캐시와 CDN
2 |
3 | ## I. 캐시
4 |
5 | : 값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 두고, 뒤이은 요청이 보다 빨리 처리될 수 있도록 하는 저장소
6 |
7 | ### 캐시 계층
8 |
9 | - 데이터가 잠시 보관되는 곳
10 | - DB보다 훨씬 빠르고, DB의 부하를 줄일 수 있음
11 | - 캐시 계층의 규모를 `독립적`으로 확장 가능
12 |
13 | ### 캐시 사용 시 유의할 점
14 |
15 | - 데이터 갱신이 자주 일어나지 않지만 참조는 빈번하게 일어날 때 사용하자
16 | - `Eviction`은 꽤 큰 비용을 가진다.
17 | - 어떤 데이터를 캐시에 둘 것인가?
18 | - 캐시는 `휘발성`이다.
19 | - `TTL`(Time To Live)을 생각하자.
20 | - `일관성`을 어떻게 유지할 것인가?
21 | - `장애`에는 어떻게 대처할 것인가?
22 | - SPOF에 대처하기 위해 `분산 환경`을 고려하자.
23 | - 캐시의 메모리는 얼마나 크게 잡을 것인가?
24 | - 캐시가 밀려나버리면 성능이 저하됨
25 | - 캐시 메모리를 적당히 `과할당` 하자.
26 | - `데이터 방출 정책`은 무엇인가?
27 | - LRU: 안 쓴지 가장 오래된 데이터 버리기
28 | - LFU: 사용 빈도가 가장 낮은 데이터 버리기
29 | - FIFO: 가장 오래된 캐시 버리기
30 |
31 | ### 캐시 읽기 전략
32 |
33 | - Look-Aside
34 | - 애플리케이션이 캐시에 데이터가 있는지 조회
35 | - 캐시 미스 시, DB에서 조회
36 | - 이후 `애플리케이션`이 DB에서 가져온 데이터를 캐시에 저장
37 | - Read-Through
38 | - 캐시와 데이터베이스를 일렬로 배치
39 | - 캐시 미스 시, `DB`에서 누락된 데이터 로드 및 캐시에 저장
40 | - 이 데이터를 애플리케이션에 반환
41 |
42 | ### 캐시 쓰기 전략
43 |
44 | - Write-Through
45 | - DB와 캐시에 동시 저장
46 | - 항상 동기화 상태 (일관성 보장)
47 | - Write Back
48 | - 캐시와 DB 동기화를 비동기하기 때문에 동기화 과정 생략
49 | - 바로 DB에 저장하지 않고, 모아서 일정 주기 배치 작업으로 저장
50 | - Write Around
51 | - 데이터를 DB에 직접 기록
52 | - 읽은 데이터만 캐시에 저장
53 |
54 | ## II. CDN (Content Delivery Network)
55 |
56 | - 정적 컨텐츠를 전송하는 데 쓰이는 지리적으로 분산된 서버의 네트워크
57 | - Static Content에 대하여 캐시 가능
58 | - 요청 경로, Query string, 쿠키, 헤더 등의 정보에 기반하여 HTML 페이지 캐시
59 |
60 | ### 동작 방식
61 |
62 | 1. 사용자가 이미지 URL을 통해 이미지에 접근 (이미지 URL은 CDN에서 제공)
63 | 2. 이미지가 없는 경우, 원본 서버에 요청하여 파일을 가져옴 (TTL 포함)
64 | 3. CDN 서버에서 가져온 파일을 캐싱하고 사용자에게 반환
65 | 4. 다른 사용자가 이미지에 대한 요청을 CDN에게 보냄
66 | 5. 만료되지 않은 이미지에 대한 요청은 캐시를 통해 처리
67 |
68 | ### 사용 시 고려해야 할 사항
69 |
70 | - 비용
71 | - CDN은 서드 파티에 의해 운영됨
72 | - 데이터 전송 양에 따라 요금을 내야 함
73 | - 자주 사용되지 않는 컨텐츠에 대해 캐싱하지 말아야 함
74 | - 적절한 만료 시한 설정
75 | - 너무 길면 정합성의 문제가 있음
76 | - 너무 짧으면 원본 서버에 빈번히 접속해야 함
77 | - CDN 장애에 대한 대처 방안
78 | - CDN 자체가 죽었을 경우에 애플리케이션이 어떻게 동작할지 고려
79 | - CDN에서 일시적으로 응답이 오지 않을 경우 원본 서버로부터 가져오도록 구성
80 | - 컨텐츠 무효화 방법
81 | - 만료되지 않은 컨텐츠를 제거하는 방법을 고려하자.
82 | - CDN 서비스 사업자가 제공하는 API
83 | - 오브젝트 버저닝: URL의 인자를 통해 컨텐츠의 다른 버전을 서비스하도록 하는 것
84 |
--------------------------------------------------------------------------------
/System Design/홈페이지_시스템_규모_추정.md:
--------------------------------------------------------------------------------
1 | # SNS 시스템 규모 추정
2 |
3 | ## 가정
4 |
5 | - `54,000,000` `monthly` active users
6 | - `3%` of users write `daily`
7 | - Users post `0.01 write per day` on average
8 | - `1%` of write contain `media`
9 | - Data is stored for `5 years`
10 |
11 | ### Post 사이즈
12 |
13 | - write_id: 64 bytes
14 | - text: 140 bytes
15 | - media: 1 MB
16 |
17 | ## 추정
18 |
19 | - 활성 유저
20 | - 54,000,000
21 | - MAU
22 | - 54,000,000
23 | - DAU
24 | - 54,000000 x 0.03
25 | - `1,620,000`
26 | - 하루에 작성되는 게시글
27 | - 1,620,000 x 0.01
28 | - `16,200`
29 | - 하루에 쌓이는 미디어 데이터 용량
30 | - 16,200 x 0.01 x 1MB
31 | - `162 MB`
32 | - 5년간 쌓이는 미디어 데이터 용량
33 | - 162 x 365 x 5
34 | - `295,650 MB`
35 | - QPS
36 | - 16,200 / (24 x 3600)
37 | - `0.1875`
38 | - Peek QPS
39 | - 0.1875 x 2 = `0.375`
40 | - 0.1875 x 4 = 0.75
41 |
--------------------------------------------------------------------------------
/Web-Node/Express js/express.md:
--------------------------------------------------------------------------------
1 | ## **express란?**
2 |
3 | : Node.js의 핵심 모듈인 http와 Connect 컴포넌트(미들웨어라고 부른다)를 기반으로 하는 웹 프레임워크
4 |
5 | ## **express의 특징**
6 |
7 | - 최소화
8 | - express는 사용자에게 최소한의 프레임 워크 제공
9 | - 유연함
10 | - client HTTP 요청을 받고, 응답 반환
11 | - 속도
12 | - 트래픽이 많은 웹 사이트에서 최고의 성능 발휘
13 | - 크기와 다양성
14 | - 개발 시 원하는 구성요소를 쉽게 추가 가능하도록 유연한 미들웨어 시스템을 만듦
15 |
16 |
17 |
18 | ---
19 |
20 | ### **참고자료**
21 |
22 | - Blog
23 | - [wikibook](https://wikibook.co.kr/article/what-is-expressjs/)
24 | - [@rimi0108](https://velog.io/@rimi0108/1.-node-express에-대해-알아보자)
25 |
--------------------------------------------------------------------------------
/Web-Node/Express js/middleware/body-parser.md:
--------------------------------------------------------------------------------
1 | ## **parser란 무엇인가?**
2 |
3 | 가지고 있는 데이터를 원하는 상태로 `가공`하는 과정을 `parsing`이라고 하고, 이를 수행하는 함수나 모듈이 바로 `parser`다. parser의 종류로는 bodyParser, cookieParser, JSON.parse, JSON.stringify 등이 있다.
4 |
5 |
6 |
7 | ## **body-parser란?**
8 |
9 | > Contains key-value pairs of data submitted in the request body.
10 | > By default, it is `undefined`, and is populated when you use `body-parsing middleware` such as body-parser and multer.
11 | > **`< Express documents >`**
12 |
13 | express 문서에 따르면, POST나 PUT 요청 시 미들웨어 없이 `req.body`에 접근하는 경우, 기본으로 `undefined`가 설정돼 있으므로 bodyParser, multer와 같은 미들웨어를 사용하여 요청 데이터 값에 접근해야 한다는 안내를 찾을 수 있다. body가 포함된 요청 시에는 서버 내에서 해석 가능한 형태로 변형해야 사용할 수 있는 것이다.
14 |
15 | ```javascript
16 | const express = require('express')
17 | const bodyParser = require('body-parser')
18 | const app = express();
19 |
20 | app.use(bodyParser().json());
21 | app.post('/sign-up', function(req, res) => {
22 | console.log(req.body);
23 | });
24 | ```
25 |
26 | 따라서 위 코드와 같이 `npm i body-parser`을 통해 body-parser 모듈을 설치하여 express에 붙여 사용하면 body의 값을 불러올 수 있다.
27 |
28 |
29 |
30 | ## **Express v4.16.0**
31 |
32 | > This is a built-in middleware function in Express. It parses incoming requests with JSON payloads and is based on body-parser.
33 | > **`< Express documents >`**
34 |
35 | express.js 4.16.0버전부터는 `built-in body-parser`를 넣었다. 따라서 아래 코드와 같이 body-parser을 import하지 않아도 된다.
36 |
37 | ```javascript
38 | const express = require('express')
39 | const app = express();
40 |
41 | app.use(express.json())l
42 | app.post('/sign-up', function(req, res) => {
43 | console.log(req.body)
44 | });
45 | ```
46 |
47 |
48 |
49 | ---
50 |
51 | ### **참고자료**
52 |
53 | - Blog
54 | - [Express Docs](https://expressjs.com/en/guide/migrating-4.html#example-migration)
55 | - [@yejinh](https://velog.io/@yejinh/express-미들웨어-bodyParser-모듈)
56 | - [@chullino](https://medium.com/@chullino/1분-패키지-소개-body-parser를-소개합니다-하지만-body-parser를-쓰지-마세요-bc3cbe0b2fd)
57 |
--------------------------------------------------------------------------------
/Web-Node/Nest js/Overview/middleware.md:
--------------------------------------------------------------------------------
1 | ## **Middleware란?**
2 |
3 | 미들웨어는 route 핸들러 전에 호출되는 함수다. 미들웨어의 기능은 `request`, `response` 객체에 액세스 할 수 있고, 애플리케이션의 request-response 사이클에서 `next()` 미들웨어 함수에 액세스 할 수 있다. next 미들웨어는 일반적으로 `next`라고 표시한다.
4 |
5 | 
6 |
7 |
8 |
9 | ---
10 |
11 | ### **참고자료**
12 |
13 | - [Nest Docs](https://docs.nestjs.com/exception-filters)
14 |
--------------------------------------------------------------------------------
/Web-Node/Node js/nodejs.md:
--------------------------------------------------------------------------------
1 | ## Node.js란?
2 |
3 | : Chrome V8 Javascript 엔진으로 빌드된 `Javascript 런타임`
4 |
5 | - 이벤트 기반의 Non-Blocking I/O 모델 → 가볍고 효율적
6 | - 기본적으로 `Single-Thread` (Multi-Thread도 지원함)
7 |
8 |
9 |
10 | ## Event-Driven
11 |
12 | : 이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식
13 |
14 | - 이벤트 리스너(Event Listener)에 콜백 함수를 등록해야 함
15 | - 이벤트가 발생하면 미리 지정해둔 콜백 함수 호출
16 |
17 | > ### 용어 정리
18 |
19 | - 이벤트 루프 (Event Loop)
20 | - 이벤트 발생 시 호출할 콜백 함수들을 관리하고, 호출된 콜백 함수의 실행 순서 결정
21 | - 백그라운드 (Background)
22 | - 타이머나 이벤트 리스너들이 대기하는 곳
23 | - 테스크 큐 (Task Queue)
24 | - 이벤트 발생 후 호출돼야 할 콜백 함수들이 기다리는 공간
25 |
26 |
27 |
28 | > ### 예제
29 |
30 | ```javascript
31 | function run() {
32 | console.log("3초 후 실행");
33 | }
34 |
35 | console.log("start");
36 | setTimeout(run, 3000);
37 | console.log("end");
38 | ```
39 |
40 | - setTimeout()이 호출 스택에 쌓였지만, 실행 시 콜백 함수인 run()을 백그라운드로 보내고, 3초 후 테스크 큐로 보내짐
41 | - 이후 호출 스택 실행이 끝나 비워지면 이벤트 루프가 테스트 큐의 run()을 호출 스택에 올림
42 | - run() 실행
43 |
--------------------------------------------------------------------------------
/Web-Node/node.md:
--------------------------------------------------------------------------------
1 | # Spring Framework Recipe
2 |
3 | Node js 관련 레시피 입니다. 학습 및 토이 프로젝트를 진행하면서 작성 했습니다. ~~(많이 빈약하지만)~~ 필요한 레시피를 편하게 얻어가시고, 원하는 레시피는 `ISSUE`에 등록, 추가하고 싶은 레시피와 잘못된 레시피는 `PR`에 등록해주시면 감사하겠습니다.
4 |
5 | ## Node js
6 |
7 | - [Node란?](https://github.com/lcomment/development-recipes/blob/main/Web-Node/Node%20js/nodejs.md)
8 |
9 | ## Express js
10 |
11 | - [express란](https://github.com/lcomment/development-recipes/blob/main/Web-Node/Express%20js/express.md)
12 | - middleware
13 | - [body-parser](https://github.com/lcomment/development-recipes/blob/main/Web-Node/Express%20js/middleware/body-parser.md)
14 |
15 | ## Nest js
16 |
17 | - Overview
18 | - [MiddleWare](https://github.com/lcomment/development-recipes/blob/main/Web-Node/Nest%20js/Overview/middleware.md)
19 | - [Exception Filters](https://github.com/lcomment/development-recipes/blob/main/Web-Node/Nest%20js/Overview/exceptionfilters.md)
20 |
--------------------------------------------------------------------------------
/Web-Spring/Jpa/dirtyChecking.md:
--------------------------------------------------------------------------------
1 | ## 더티 체킹 (Dirty Checking)
2 |
3 | 더티 체킹의 더티(`Dirty`)는 `상태의 변화`를 의미한다. 즉, 더티 체킹이란 `상태 변경 검사`를 의미한다. 이는 `Transaction` 안에서 엔티티의 변경이 일어나면 변경 내용을 DB에 반영하는 JPA의 특징이다.
4 |
5 | ```java
6 | @Getter
7 | @Entity(name = "users")
8 | @NoArgsConstructor(access = AccessLevel.PROTECTED)
9 | @EntityListeners(AuditingEntityListener.class)
10 | public class User {
11 | @Id
12 | @Column(name = "user_id")
13 | private String id;
14 |
15 | @Column("nickname")
16 | private String nickname;
17 |
18 | @Column("age")
19 | private Integer age;
20 |
21 | @Embedded
22 | private AuditEntity auditEntity;
23 |
24 | @Builder
25 | public User(String id, String nickname, int age) {
26 | this.id = id;
27 | this.nickname = nickname;
28 | this.age = age;
29 | this.auditEntity = new AuditEntity();
30 | }
31 |
32 | public void updateNickname(String nickname) {
33 | this.nickname = nickname;
34 | }
35 | }
36 | ```
37 |
38 | 다음과 같은 User 엔티티가 있다고 가정하자. 우리는 `nickname` 컬럼을 업데이트 하고 싶을 때 Service 레이어에 다음과 같이 코드를 작성할 수 있다.
39 |
40 | ```java
41 | . . .
42 | @Transactional
43 | public User updateNickname(String userId, String nickname) {
44 | User user = findById(userId);
45 | user.updateNickname(nickname);
46 |
47 | return user;
48 | }
49 | . . .
50 | ```
51 |
52 | 하지만 여기 문제가 하나 있다. 더티 체킹으로 생성되는 update query는 기본적으로 `모든 필드를 포함`한다. JPA는 모든 필드에 대해 미리 쿼리를 만들어놓고 `재사용`한다. 위와 같이 컬럼이 적은 상황에서는 상관 없지만, 컬럼이 많은 경우엔 query가 부담이 될 수 있다. 따라서 이럴 경우, 엔티티의 최상단에 `@DynamicUpdate` 어노테이션을 추가하여 변경되는 필드만 반영될 수 있도록 할 수 있다.
53 |
--------------------------------------------------------------------------------
/Web-Spring/Jpa/entitySetter.md:
--------------------------------------------------------------------------------
1 | ## Entity에 Setter를 지양해야 하는 이유
2 |
3 | > ### 1. 사용 의도를 파악하기 어렵다
4 |
5 | ```java
6 | Board board = new Board();
7 |
8 | board.setId(1L);
9 | board.setTitle("Test Title");
10 | board.setContent("This is sample Board");
11 | ```
12 |
13 | 위와 같이 setter를 사용했을 때, 저 코드만 봐서는 엔티티를 `생성`하는지, `수정`하는지 의도를 알 수 없다. 위와 같이 간단한 Entity에서는 불편함을 느끼지 못할 수 있지만, 내부가 복잡하면 복잡할수록 불편할 것이다.
14 |
15 |
16 |
17 | > ### 2. 일관성을 유지하기 어렵다
18 |
19 | ```java
20 | public Board update(Long id) {
21 | Board board = findById(id);
22 |
23 | board.setTitle("set title");
24 | board.setContent("set content");
25 | return board;
26 | }
27 | ```
28 |
29 | `public으로 작성된 setter`를 통해 어디서든 접근이 가능하기에 의도치 않게 Board 값이 변경되는 경우가 발생할 수 있다. 이렇게 되면 Board 객체의 일관성이 무너지게 된다.
30 |
31 |
32 |
33 | ## 그렇다면 어떻게 update를 구현할까?
34 |
35 | ```java
36 | @Entity
37 | @NoArgsConstructor(access = AccessLevel.PROTECTED)
38 | public class Board {
39 | @Id
40 | @GeneratedValue(strategy = GenerationType.IDENTITY)
41 | private Long id;
42 |
43 | @Column(nullable = false)
44 | private String title;
45 |
46 | @Column(nullable = false)
47 | private String content;
48 |
49 | @Builder
50 | public Board(String title, String content) {
51 | this.title = title;
52 | this.content = content;
53 | }
54 |
55 | public Board update(String title, String content) {
56 | this.title = title;
57 | this.content = content;
58 | return this;
59 | }
60 | }
61 | ```
62 |
63 | JPA는 상태 변경 검사인 `Dirty Checking`이라는 특성을 가지고 있다. 따라서 위와 같이 `update()` 메서드를 Entity 내부에서 구현해주기만 하면 손쉽게 수정 기능을 구현할 수 있다.
64 |
65 | 또 생성자를 통해 Entity의 `일관성`을 유지시켜 줘야 한다. 만약 column이 3개 이상이라면 `@Builder`를 사용하도록 하자.
66 |
67 | ---
68 |
69 | ### Reference
70 |
71 | - [@langoustine](https://velog.io/@langoustine/setter%EB%A5%BC-%EC%93%B0%EC%A7%80%EB%A7%90%EB%9D%BC%EA%B3%A0)
--------------------------------------------------------------------------------
/Web-Spring/Jpa/jpa.md:
--------------------------------------------------------------------------------
1 | > ### ORM 관련 이론 보러가기 → [Web - ORM](https://github.com/lcomment/development-recipes/blob/main/Web/orm.md)
2 |
3 |
4 |
5 | ## JPA (Java Persistence API)
6 |
7 | : Java 진영에서 ORM 기술 표준으로 사용하는 인터페이스
8 |
9 | 
10 |
11 | - 자바 애플리케이션과 JDBC 사이에서 동작
12 | - ORM 프레임워크가 JPA 구현
13 | - `Hibernate` (가장 대중적)
14 | - EclipseLink
15 | - DataNucleus
16 | - 표준이기에 다른 구현 기술로 손쉽게 변경 가능
17 |
18 |
19 |
20 | ## JPA를 사용해야 하는 이유
21 |
22 | - 생산성
23 | - DDL, DML문 등을 자동으로 생성해주는 기능
24 | - DB 설계 중심의 패러다임을 `객체 설계 중심으로 역전`
25 | - 유지보수
26 | - 개발자가 작성해야 했던 SQL과 JDBC API 코드를 JPA가 대신 처리
27 | - 유지보수 할 코드 수 감소
28 | - 패러다임 불일치 해결
29 | - 성능
30 | - 애플리케이션과 DB 사이에서 다양한 `성능 최적화` 기회 제공
31 | - 데이터 접근 추상화와 벤더 독립성
32 | - 애플리케이션과 DB 사이에 `추상화`된 데이터 접근 계층 제공
33 | - 애플리케이션이 특정 DB 기술에 `독립적`이게 됨
34 |
35 | 
36 |
37 |
38 |
39 | ---
40 |
41 | ### **참고자료**
42 |
43 | - Web
44 | - [@dbjh](https://dbjh.tistory.com/77)
45 | - Book
46 | - [자바 ORM 표준 JPA, 김영한](http://www.yes24.com/Product/Goods/90439472)
47 |
--------------------------------------------------------------------------------
/Web-Spring/Jpa/jpql.md:
--------------------------------------------------------------------------------
1 | ## JPQL (; Java Persistence Query Language)
2 |
3 | : 엔티티 객체를 조회하는 객체지향 쿼리
4 |
5 | - SQL과 비슷한 문법을 가지며, JPQL은 결국 `SQL로 변환`됨
6 | - `검색 조건`이 포함된 SQL 사용에 어려움을 겪은 JPA의 문제 해결
7 |
8 | ### 특징
9 |
10 | - 테이블이 아닌 `엔티티 객체`를 대상으로 쿼리
11 | - SQL을 `추상화` 했기 때문에 특정 벤더에 `독립적`
12 | - JPA는 JPQL을 분석하여 SQL을 생성한 후 DB에서 조회
13 |
14 |
15 |
16 | ---
17 |
18 | ### **참고자료**
19 |
20 | - Book
21 | - [자바 ORM 표준 JPA, 김영한](http://www.yes24.com/Product/Goods/90439472)
22 |
--------------------------------------------------------------------------------
/Web-Spring/MyBatis/myBatis.md:
--------------------------------------------------------------------------------
1 | ## MyBatis
2 |
3 | : Java Object와 SQL 사이의 자동 매핑 기능을 지원하는 ORM 프레임워크
4 |
5 | - 쉬운 접근성과 코드의 간결함
6 | - JDBC의 모든 기능을 대부분 제공
7 | - 복잡한 JDBC 코드 ➝ 깔끔한 소스코드
8 | - 수동적인 파라미터 설정
9 | - 쿼리 결과에 대한 맵핑 구문 제거
10 | - SQL문과 프로그래밍 코드의 분리
11 | - SQL에 변경이 있어도 Java 코드를 수정하지 않아도 됨
12 | - 다양한 프로그래밍 언어로 구현 가능
13 | - Java, C#, .NET, Ruby 등
14 |
15 |
16 |
17 | ## MyBatis 구성
18 |
19 | > ### MyBatis Configuration File
20 |
21 | - MyBatis3의 `작업 설정`을 설명하는 XML 파일
22 | - DB 연결 대상
23 | - 매핑 파일의 경로
24 | - MyBatis3의 작업 설정
25 |
26 | > ### SqlSessionFactoryBuilder
27 |
28 | - MyBatis3 구성 파일을 `읽고 생성`하는 SqlSessionFactory 구성 요소
29 | - Spring과 통합돼 사용할 떄 애플리케이션 클래스에서 직접 처리하지 않음
30 |
31 | > ### SqlSessionFactory
32 |
33 | - SqlSession을 `생성`하는 구성 요소
34 | - Spring과 통합돼 사용할 떄 애플리케이션 클래스에서 직접 처리하지 않음
35 |
36 | > ### SqlSession
37 |
38 | - `SQL 실행` 및 `트랜잭션 제어`를 위한 API를 제공하는 구성 요소
39 | - Spring과 통합돼 사용할 떄 애플리케이션 클래스에서 직접 처리하지 않음
40 |
41 | > ### Mapper interface
42 |
43 | - typesafe에서 매핑 파일에 정의된 SQL을 호출하는 인터페이스
44 |
45 | > ### Mapper File
46 |
47 | - SQL 및 O/R 매핑 설정을 설명하는 XML 파일
48 |
49 |
50 |
51 | ## MyBatis Database Access
52 |
53 |
54 |

55 |
56 |
57 | 1. `Application`이 `SqlSessionFactoryBuilder` 호출
58 | 2. `SqlSessionFactoryBuilder`가 SqlSessionFactory를 생성하기 위해 `MyBatis Config File`을 읽음
59 | 3. SqlSessionFactoryBuilder가 `SqlSessionFactory`를 생성
60 | 4. Client가 `Request`를 보냄
61 | 5. `Application`이 `SqlSessionFactory`에서 SqlSession을 가져옴
62 | 6. SqlSessionFactory가 `SqlSession` 생성 및 `Application`에게 반환
63 | 7. Application이 SqlSession에서 `Mapper Interface`의 구현 개체를 가져옵니다.
64 | 8. Application이 Mapper Interface 메서드 호출
65 | 9. Mapper Interface의 구현 개체가 SqlSession `메서드 호출` 및 `SQL 실행 요청`
66 | 10. SqlSession이 Mapping File에서 실행할 SQL을 가져와 SQL 실행
--------------------------------------------------------------------------------
/Web-Spring/Spring MVC/dao_dto_vo.md:
--------------------------------------------------------------------------------
1 | ## DAO (; Data Access Object)
2 |
3 | - 데이터베이스의 데이터에 접근하기 위한 객체
4 | - DB에 접근하기 위한 로직 및 비즈니스 로직을 분리하기 위해 사용
5 |
6 | ```java
7 | @Repository
8 | @RequiredArgsConstructor
9 | public class MemberRepository {
10 |
11 | private final EntityManager em;
12 |
13 | public void save(Member member) {
14 | em.persist(member);
15 | }
16 |
17 | public Member findOne(Long id) {
18 | return em.find(Member.class, id);
19 | }
20 |
21 | public List findAll() {
22 | return em.createQuery("select m from Member m", Member.class).getResultList();
23 | }
24 |
25 | public List findByName(String name) {
26 | return em.createQuery("select m from Member m where m.name =:name", Member.class)
27 | .setParameter("name", name)
28 | .getResultList();
29 | }
30 | }
31 | ```
32 |
33 |
34 |
35 | ## DTO
36 |
37 | - 계층 간 데이터 교환을 하기 위해 사용하는 객체
38 | - 로직을 가지지 않는 순수한 데이터 객체 (getter와 setter를 가짐)
39 |
40 | ```java
41 | @Setter
42 | @Getter
43 | @AllArgsConstructor
44 | public class PersonDTO {
45 | private String name;
46 | private int age;
47 | }
48 | ```
49 |
50 |
51 |
52 | ## VO
53 |
54 | - 값 오브젝트로써 값을 위해 쓰임
55 | - `read-only` 특징을 가짐
56 |
--------------------------------------------------------------------------------
/Web-Spring/Spring MVC/springMvc.md:
--------------------------------------------------------------------------------
1 | > ### [MVC Pattern에 대해 먼저 알아보자❗️](https://github.com/lcomment/development-recipes/blob/main/Computer%20Science/SW%20Engineering/mvc.md)
2 |
3 |
4 |
5 | ## Spring MVC Framework
6 |
7 | Spring MVC는 Spring에서 제공하는 웹 모듈로, Model, View, Controller를 활용해 사용자의 다양한 `HTTP Request를 처리`하고, `다양한 형식의 Response`, `View를 리턴`하는 응답까지, 다양한 응답을 할 수 있도록 도와주는 프레임워크이다. 아래의 사진을 보며 Spring MVC의 작동원리에 대해 이해해보자.
8 |
9 |
10 |

11 |
출처: https://mangkyu.tistory.com/m/95
12 |
13 |
14 | 1. Client가 URL을 통해 `Request를 보냄`
15 | 2. 프론트 컨트롤러(Front Controller)인 `DispatcherServlet`은 `Handler Mapping을 통해 해당 Request가 어느 컨트롤러에게 온 요청인지 찾음
16 | 3. DispatcherServlet이 `Handler Adapter`에게 Reqeust 전달을 넘김
17 | 4. Handler Adapter가 `Controller`에게 Request 전달
18 | 5. Controller는 `비즈니스 로직`을 처리한 후 `View Name`을 리턴
19 | 6. DispatcherServlet은 `View Resolver`를 통해 해당 View를 찾음
20 | 7. Controller에서 View에 전달할 데이터를 추가
21 | 8. 데이터가 추가된 View 리턴
22 |
23 |
24 |
25 | ## Spring MVC의 장점
26 |
27 | - DI를 통해 컴포넌트 간의 결합도를 낮출 수 있음
28 | - 단위 테스트 용이
29 | - IoC를 통해 Bean의 라이프사이클에 대해 신경쓰지 않고 개발에 집중할 수 있음
30 |
31 |
32 |
33 | ---
34 |
35 | ### 참고자료
36 |
37 | - [@kotlinworld](https://kotlinworld.com/m/326)
38 | - [@mangkyu](https://mangkyu.tistory.com/m/95)
39 | - [@gmlwjd9405](https://gmlwjd9405.github.io/2018/12/20/spring-mvc-framework.html)
40 |
--------------------------------------------------------------------------------
/Web-Spring/Spring REST Docs/springRestDocs.md:
--------------------------------------------------------------------------------
1 | ## Spring REST Docs
2 |
3 | > _Spring REST Docs helps you to document RESTful services._
4 | >
5 | > > It combines hand-written documentation written with `Asciidoctor` and auto-generated snippets produced with `Spring MVC Test`. This approach frees you from `the limitations of the documentation` produced by tools like `Swagger`.
6 |
7 | : 테스트 코드 기반으로 API 문서를 자동으로 작성해주는 프레임워크
8 |
9 | - 테스트가 통과돼야 문서 자동 작성
10 | - API Spec이 추가/변경/삭제 된 경우, 테스트 코드 수정 필요
11 | - 기본적으로 Asciidoctor를 사용하여 문서 작성
12 |
13 |
14 |
15 | ## Spring REST Docs 공식 문서
16 |
17 | > ##### 스니펫(snippet): 재사용 가능한 소스 코드, 기계어, 텍스트의 작은 부분을 일컫는 프로그래밍 용어
18 |
19 | Spring REST Docs의 목적은 RESTful 서비스에 대한 `정확하고 읽기 쉬운 문서`를 만드는 것이다.
20 |
21 | 고품질 문서를 작성하는 것은 어렵다. 이러한 어려움을 완화하는 한 가지 방법은 작업에 적합한 도구를 사용하는 것이다. 이를 위해 Spring REST Docs는 기본적으로 `Asiidoctor를 사용`한다. Asciodoctor는 `일반 텍스트를 처리`하고, 필요에 따라 스타일링되고 레이아웃된 `HTML을 생성`한다. 원하는 경우, `Markdown`을 사용하도록 Spring REST Docs를 구성할 수도 있다.
22 |
23 | Spring REST Docs는 Spring MVC의 테스트 프레임워크인 Spring WebFlux의 WebTestClient 또는 REST Assured 3으로 작성된 `테스트에서 생성된 스니펫을 사용`한다. 이러한 테스트 기반 접근 방식은 서비스 문서의 `정확성을 보장`하는 데 도움이 된다. 스니펫이 올바르지 않으면 스니펫을 생성하는 테스트가 `실패`한다.
24 |
25 | RESTful 서비스를 문서화하는 것은 주로 `리소스를 설명하는 것`이다. 각 리소스 설명의 두 가지 주요 부분은 `사용하는 HTTP 요청`과 `생성하는 HTTP 응답`의 세부 정보다. Spring REST Docs를 사용하면 이러한 리소스와 HTTP 요청 및 응답으로 작업하여 서비스 구현의 내부 세부 사항으로부터 `문서를 보호`할 수 있다.
26 |
27 | 이러한 분리는 서비스 구현보다는 `서비스 API를 문서화`하는 데 도움이 된다. 또한 문서를 다시 작성할 필요 없이 구현을 발전시킬 수 있다.
28 |
29 |
30 |
31 | ## Architecture
32 |
33 |
34 |

35 |
출처: https://devbksheen.tistory.com/m/entry/Spring-REST-Docs
36 |
37 |
38 | 1. Test Case가 성공하면 `.adoc 파일`이 `/build/generate-snippets` 디렉토리에 생성
39 | 2. `src/docs/asciidoc` 디렉토리에 `.adoc 파일`을 include하여 `문서 생성`
40 | - `*.adoc 파일`들은 API Request, Response에 대한 `Spec 파일`
41 | - `*.adoc 파일`들이 `HTML 파일로 변환`돼 API 문서 제공
42 | - `*.adoc 파일`에 API 문서를 작성하고, 필요한 API Request와 Response의 Spec은 자동 생성된 `.adoc 파일`을 이용해 표현
43 | - 이후 API Spec이 변경돼도 문서를 수정하지 않아도 됨
44 | 3. 생성된 `asciidoc 문서`는 AsciidoctorTask를 통해 HTML문서로 처리돼 `/build/asciidoc/html5` 디텔토리에 HTML 문서로 생성
45 |
46 |
47 |
48 | ---
49 |
50 | ### 참고자료
51 |
52 | - [Spring Docs](https://docs.spring.io/spring-restdocs/docs/current/reference/html5/)
53 |
--------------------------------------------------------------------------------
/Web-Spring/basic/aboutBeanFactory.md:
--------------------------------------------------------------------------------
1 | ## **👨🏻💻BeanFactory**
2 |
3 | : 스프링 컨테이너의 최상위 인터페이스
4 |
5 | - 스프링 빈을 관리하고 조회하는 역할 담당
6 | - getBean()제공
7 |
8 |
9 |
10 |
11 | ### ApplicationContext
12 |
13 | BeanFactory기능을 모두 상속받아 제공한다
14 | 빈을 관리하고 검색하는 기능을 BeanFactory가 이미 제공하는데 차이는??
-> 애플리케이션을 개발할때는 빈은 관리하고 조회하는 기능은 물론이고 수 많은 부가 기능이 필요하다.
15 |
16 |
17 | 1) 메시지소스를 활용한 국제화 기능 => (MessageSource)
18 | 2) 환경변수 => (EnvironmentsCapable)
19 | 3) 애플리케이션 이벤트 => (ApplicationPublisher)
20 | 4) 편리한 리소스 조회 => (ResourceLoader)
21 |
22 | 간단하게 BeanFactory나 ApplicationContext를 스프링 컨테이너라고 한다.
23 |
24 |
25 |
26 | ***
27 | ## **🥜BeanDefinition**
28 |
29 |
30 |
31 | 스프링 빈 설정 메타 정보
32 |
33 | 스프링이 다양한 설정 형식을 지원할 수 있는 이유는?
34 |
-> 바로 BeanDefinition 이라는 추상화 때문이다. 즉 설정 정보의 역할과 구현을 개념적으로 분리한 것으로 설정 정보를 추상화 시켰다.
35 |
36 |
37 | 스프링 컨테이너는 BeanDefintion(역할)만 알고 자바 코드인지, XML인지 몰라도 된다.
38 |
39 | 1) XML을 읽어 BeanDefinition 생성
40 | 2) 자바 코드를 읽어 BeanDefinition 생성
41 |
42 |
43 | 쉽게 말해 @Bean / 하나당 하나씩 메타 정보가 생성되고, 스프링 컨테이너는 이 메타 정보를 기반으로 스프링 빈을 생성한다.
44 | ***
45 |
46 | ### **참고자료**
47 |
48 | - Web
49 | - [blog](https://hseungyeon.tistory.com/398)
50 | - [github.io](https://woovictory.github.io/2019/02/07/Design-Pattern-Factory-Pattern/)
51 |
52 |
--------------------------------------------------------------------------------
/Web-Spring/basic/aboutSpring.md:
--------------------------------------------------------------------------------
1 | ## **스프링 프레임워크란?**
2 |
3 | - `로드 존슨`(Rod Johnson)이 2004년에 만든 오픈소스 프레임워크로
4 | - `자바 엔터프라이즈 애플리케이션`(Java Enterprise Application) 개발에 사용되는 애플리케이션 프레임워크
5 | - `IoC`와 `AOP`를 지원하는 경량의 컨테이너 프레임워크
6 |
7 |
8 |
9 | ## **EJB와 Spring**
10 |
11 | 스프링 프레임워크가 등장하기 이전에 자바 기반의 엔터프라이즈 애플리케이션은 대부분 **`EJB`**(; Enterprise Java Beans)로 개발되었다. EHB 기술은 EJB 컨테이너가 제공하는 많은 기능과 나름의 장점이 있었음에도 여러 `문제점`을 가지고 있었다.
12 |
13 | - 스펙이 매우 복잡하여 학습에 많은 시간 필요
14 | - 개발 및 유지보수 복잡
15 | - 컴포넌트 배치 및 실행을 위해 JEUS, Weblogic 등 `고가의 WAS` 필요
16 |
17 | 이러한 단점이 있음에도 사실 EJB 기술 자체는 문제가 없다. 문제가 없으니 오랜 시간동안 수많은 프로젝트에서 사용돼 왔다. 하지만 EJB를 EJB답게 사용하는 것은 매우 어렵다. EJB를 제대로 사용하려면 EJB의 성능을 유지해주고, 유지보수의 편의성을 향상해주는 `다양한 디자인 패턴`을 이해하고 적용할 수 있어야 한다. 이런 디자인 패턴에 대한 이해 없이 사용한다면 문제가 생기고, 또 이런 디자인 패턴을 반드시 사용해야 한다는 것은 EJB의 문제점이라 보아도 무방하다.
18 |
19 | 이와 비교해 `스프링`은 평범한 `POJO`(Plain Old Java Object)를 사용하면서 EJB에서만 가능했던 기능들을 지원하고, 많은 디자인 패턴이 이미 적용돼 배포되었다. 그래서 이름 또한 전통적인 EJB라는 겨울을 넘어 `새로운 시작`이라는 뜻에서 `Spring`이라고 지어졌다.
20 |
21 |
22 |
23 | ## **스프링 프레임워크의 특징**
24 |
25 | - ### 경량 (Lightweight)
26 | - 스프링은 하나 이상의 Jar 파일로 구성된 여러 개의 모듈로 구성
27 | - 이를 통해 개발과 실행이 가능하고, 배포 또한 빠르고 쉬움
28 | - POJO 형태의 객체를 관리하기 때문에 단순하고 가벼움
29 | - ### 제어의 역전
30 | - Inversion of Control, `IoC`
31 | - IoC를 통해 애플리케이션의 낮은 결합도와 높은 응집도 유지
32 | - IoC가 적용되면 객체 생성을 자바 코드가 직접 처리하지 않고 컨테이너가 대신 처리
33 | - 객체간 의존관계(Dependency) 역시 컨테이너가 처리
34 | - 의존관계가 명시되지 않아 결합도가 낮아지고 유지보수가 용이해짐
35 | - ### 관점 지향 프로그래밍
36 | - Aspect Oriented Programming, `AOP`
37 | - 비즈니스 모델을 개발할 때, 핵심 비즈니스 로직과 각 비즈니스 메서드마다 반복해서 등장하는 공통 로직 분리
38 | - 높은 응집도
39 | - 개발 및 유지보수 용이
40 | - ### 컨테이너
41 | - 특정 객체의 라이프 사이클(Life-Cycle) 관리
42 | - 객체 운용에 필요한 다양한 기능 제공
43 | - 애플리케이션 운용에 필요한 객체를 생성하고, 객체 간의 의존관계를 관리한다는 점에서 스프링도 일종의 컨테이너
44 |
--------------------------------------------------------------------------------
/Web-Spring/basic/springContainer.md:
--------------------------------------------------------------------------------
1 | ## **스프링 컨테이너** (Spring Container)
2 |
3 | : Spring에서 Java 객체들을 관리하는 공간
4 |
5 | - Java 객체의 라이프사이클을 관리
6 | - 생성된 Java 객체들에게 추가적인 기능을 제공
7 | - `IoC`와 `DI`의 원리가 적용됨
8 |
9 |
10 |
11 | ### **제어의 역전, IoC**
12 |
13 | 스프링에서 제어의 역전은 스프링 컨테이너가 필요에 따라 Bean들을 `관리`하거나 `제어`하는 행위다.
14 | (여기서 `Bean`은 스프링 컨테이너에 의해 관리되는 `자바 객체(POJO)`를 말한다.) 기존의 프로그램은 클라이언트 구현 객체가 스스로 필요한 서버 구현 객체를 생성하고, 연결 후 실행했다. 하지만 스프링 컨테이너를 사용하면 구현 객체는 `자신의 로직을 실행`하는 역할만 담당하고, 프로그램의 제어 흐름은 스프링 컨테이너가 담당한다.
15 |
16 |
17 |
18 | 이와 같이 프로그램의 제어 흐름을 개발자가 아닌 외부에서 관리하는 것을 제어의 역전, `IoC`(Inversion of Control)이라고 한다.
19 |
20 | ### **의존관계 주입, DI**
21 |
22 |
23 |
24 | "A가 B를 의존한다." 겉으로 보기엔 추상적인 표현이지만, 토비의 스프링에서는 의존한다는 건 의존대상, 위의 그림에서는 B가 변하면 A에 영향을 미친다고 정의돼 있다. 하지만 B는 A의 변화에 영향을 받아서는 안된다. 의존 관계에는 `방향성`이 있기 때문이다.
25 |
26 |
27 |
28 | 위의 그림을 참고해보면, A는 B 인터페이스에 의존하고 있다. 만약 B 인터페이스가 변한다면 A는 영향을 받게 된다. 하지만 정작 B 인터페이스를 구현한 C가 변했을 땐 영향을 받지 않는다. B 인터페이스를 구현한 다른 객체로 바뀌어도 말이다. 이렇게 인터페이스에 대해서만 의존관계를 만들어두면 인터페이스 구현 클래스와의 `관계는 느슨`해지고, `결합도`가 낮아지게 된다. 의존관계 주입, DI는 다음의 조건을 충족하는 작업이라고 말할 수도 있다.
29 |
30 | - 클래스 모델이나 코드에는 런타임 시점의 의존관계는 드러나지 않는다. 그러기 위해서는 `인터페이스에만 의존`하고 있어야 한다.
31 | - 런타임 시점의 의존관계는 `컨테이너`나 `팩토리` 같은 제3의 존재가 결정한다.
32 | - 의존관계는 사용할 오브젝트에 대한 레퍼런스를 `외부에서 제공(주입)`해줌으로써 만들어진다.
33 |
34 | 의존관계 주입(DI)은 스프링이 제공하는 IoC 방법이고,이 밖에도 getBean() 메서드 등을 통한 `의존관계 검색`(DL, Dependency Lookup)도 있다.
35 |
36 |
37 |
38 | ---
39 |
40 | ### **참고자료**
41 |
42 | - Web
43 | - 토비의 스프링 3.1
44 | - [@tecoble](https://tecoble.techcourse.co.kr/post/2021-04-27-dependency-injection/)
45 | - [@steady-coding](https://steady-coding.tistory.com/458)
46 | - [@tank3a](https://velog.io/@tank3a/스프링-컨테이너와-스프링-빈)
47 |
--------------------------------------------------------------------------------
/Web-Spring/basic/springNboot.md:
--------------------------------------------------------------------------------
1 | ## Spring과 Spring Boot
2 |
3 | `EJB`라는 겨울 넘어 등장한 Spring은 많은 장점을 가지고 있었지만 치명적인 단점이 있었다. 바로 환경설정이 복잡하다는 것이다. 이런 이유 때문에 Spring을 시작하다가 포기하는 사람들도 많다고 한다.
4 |
5 |
6 |
7 | > _Spring Boot makes it easy to create `stand-alone`, production-grade Spring based Applications that you can "`just run`"._
8 |
9 |
10 |
11 | 이를 보완하기 위해 나온 것이 `Spring Boot`다. Spring Boot는 Spring Framework를 사용하기 위한 설정의 많은 부분을 `자동화`하여 사용자가 편하게 스프링을 활용할 수 있도록 한다.
12 |
13 | - `내장 톰켓`(Embed Tomcat)을 사용
14 | - `starter`를 통한 Dependency 자동화
15 | - `jar` file을 이용한 손쉬운 배포
16 |
17 |
18 |
19 | ---
20 |
21 | ### 참고자료
22 |
23 | - [@melonicedlatte](https://melonicedlatte.com/2021/07/11/174700.html)
24 | - [@programforlife](https://programforlife.tistory.com/m/68)
25 | - [@courage331](https://velog.io/@courage331/Spring-과-Spring-Boot-차이)
26 |
--------------------------------------------------------------------------------
/Web-Spring/controller.md:
--------------------------------------------------------------------------------
1 | ## @Controller와 @RestController
2 |
3 | Spring에서 컨트롤러를 지정하기 위한 어노테이션으로는 `@Controller`와 `@RestController`가 있다. 이 두 어노테이션의 주요 차이점은 `HTTP Response Body`가 생성되는 방식이다. `@Controller`는 `Model` 객체를 만들어 데이터를 담고, `View를 반환`하기 위해 사용하고, `@RestController`는 단순히 객체만을 반환하고, 객체 데이터는 JSON 또는 XML 형식으로 HTTP 응답에 담아 전송한다.
4 |
5 | - @Controller는 클래스를 Spring MVC 컨트롤러를 `표시`하는 데 사용하고, @RestController는 `RESTful 웹 서비스`에서 사용되는 특수 컨트롤러이며, `@Controller + @ResponseBody`와 동일함.
6 | - @Controller는 `View` 반환 목적이고, @RestController는 `객체` 반환 목적
7 | - @Controller는 `@Component`가 달려있고, @RestController는 `@Controller`와 `ResponseBody`가 달려있음
8 |
9 | ```java
10 | @Target(value=TYEP)
11 | @Retention(value=RUNTIME)
12 | @Documented
13 | @Component
14 | public @interface Controller { . . .}
15 |
16 | @Target(value=TYEP)
17 | @Retention(value=RUNTIME)
18 | @Documented
19 | @Controller
20 | @ResponseBody
21 | public @interface RestController { . . . }
22 | ```
23 |
24 |
25 |
26 | ## Spring MVC Work-flow
27 |
28 | > ### @Controller - View
29 |
30 | 
31 |
32 | 1. Client가 URI 형식으로 `Request`를 보냄
33 | 2. `DispatcherServlet`이 요청을 위임한 `HandlerMapping`을 찾음
34 | 3. HandlerMapping을 통해 Reqeust를 Controller로 위임
35 | 4. Controller는 Request를 처리한 후 `ViewName` 반환
36 | 5. DispatcherServlet이 `ViewResolver`를 통해 해당하는 `View`를 찾아 리턴
37 |
38 |
39 |
40 | > ### @RestController
41 |
42 | 
43 |
44 | 1. Client가 URI 형식으로 `Request`를 보냄
45 | 2. `DispatcherServlet`이 요청을 위임한 `HandlerMapping`을 찾음
46 | 3. HandlerMapping을 통해 Reqeust를 Controller로 위임
47 | 4. Controller는 Request를 처리한 후 `객체` 반환
48 | 5. 반환되는 객체는 `JSON`으로 Serialize 되어 Client에게 반환
49 |
50 | - `@ResponseBody`를 활용한 @Controller와 동작방식이 같음
51 | - 객체를 반환하기 때문에 Client가 예상하는 HttpStatus를 설정해줄 수 없음
52 | - 이럴 경우 `ResponseEntity`로 감싸서 리턴해줘야 함
53 |
54 |
55 |
56 | ---
57 |
58 | ### 참고자료
59 |
60 | - [@dev-coco](https://dev-coco.tistory.com/m/84)
61 | - [@mangkyu](https://mangkyu.tistory.com/m/49)
62 | - [@dyunge_100](https://velog.io/@dyunge_100/Spring-Controller와-RestController의-차이)
63 |
--------------------------------------------------------------------------------
/Web-Spring/devtools.md:
--------------------------------------------------------------------------------
1 | ## devtools
2 |
3 | : Spring Boot에서 제공하는 개발 편의를 위한 모듈
4 |
5 | > → 주로 변경된 코드를 서버 또는 화면에 신속하게 반영해 결과를 확인하기 위해 사용
6 |
7 |
8 |
9 | > ### 기능
10 |
11 | - 클래스 로딩 문제 진단 (Diagnosing Classloading Issues)
12 | - 속성 기본값 (Property Defaults)
13 | - 자동 재시작 (Automaic Restart)
14 | - 라이브 리로드 (LiveReload)
15 | - 전역 설정 (Global Settings)
16 | - 원격 애플리케이션 (Remote Applications)
17 |
18 |
19 |
20 | > ### 의존성 설정
21 |
22 | ```xml
23 | . . .
24 |
25 | org.springframework.boot
26 | spring-boot-devtools
27 | true
28 |
29 | . . .
30 | ```
31 |
32 | - Maven
33 |
34 | ```gradle
35 | . . .
36 | developmentOnly("org.springframework.boot:spring-boot-devtools")
37 | . . .
38 | ```
39 |
40 | - Gradle
41 |
42 |
43 |
44 | > ### LiveReload
45 |
46 | 1. IntelliJ 설정
47 |
48 | - [Preferences] → [Build, Execution, Deployment] → [Compiler] → `Build project automaically`
49 |
50 |
51 |
52 |
53 |
54 | 2. application.\* 설정
55 |
56 | ```yml
57 | # application.properties
58 | spring.devtools.livereload.enabled=true
59 |
60 | # application.yml
61 | spring:
62 | devtools:
63 | livereload:
64 | enabled: true
65 | ```
66 |
67 |
68 |
69 | ---
70 |
71 | ### Reference
72 |
73 | - [@iksflow](https://iksflow.tistory.com/57)
74 | - [@mgyo](https://mgyo.tistory.com/389)
75 |
--------------------------------------------------------------------------------
/Web-Spring/mavenCentral.md:
--------------------------------------------------------------------------------
1 | ## mavenCentral()과 jcenter()
2 |
3 | ```gradle
4 | repositories {
5 | mavenCentral()
6 | jcenter()
7 | }
8 | ```
9 |
10 | **build.gradle**의 `repositories`는 각종 의존성(라이브러리)들을 어떤 원격 저장소에서 받을지를 정해준다. `mavenCentral()`과 `jcenter()`는 Android Studio의 Gradle 플러그인 용 저장소이다.
11 |
12 | 기본적으로 mavenCentral이 이전부터 많이 사용하는 저장소지만, 본인이 만든 라이브러리를 업로드하기 위해서는 많은 과정과 설치가 필요한 문제점이 있었다. 이를 보완하기 위한 라이브러리가 jcenter이다.
13 |
14 | jcenter는 라이브러리 업로드를 간단하게 하였고, jcenter에 라이브러리를 업로드하면 mavenCentral에도 업로드 될 수 있도록 자동화를 할 수 있다. 따라서 jcenter는 최대 java 저장소이고 jcenter를 많이 사용하는 추세이다.
15 |
16 |
17 |
18 | 하지만 현재 jcenter를 이용하려 하면 `Deprecated`라고 표시되는 것을 확인할 수 있다. 많은 Android 프로젝트에서 사용하고 있는 JCenter 아티팩트 저장소의 유지보수 회사 `JFrog`가 최근 JCenter 지원을 중단했기 때문이다. 따라서 서비스 또한 종료될 것이고, 앞으로는 mavenCentral을 사용하도록 하자.
19 |
20 | ---
21 |
22 | ### **참고자료**
23 |
24 | - Web
25 | - [@jack3787](https://velog.io/@jack3787/Springboot-mavenCentral과-jcenter의-차이점)
26 | - [@스프링 부트와 AWS로 혼자 구현하는 웹 서비스](http://www.yes24.com/Product/Goods/83849117)
27 |
--------------------------------------------------------------------------------
/Web-Spring/restTemplate.md:
--------------------------------------------------------------------------------
1 | ## RestTemplate
2 |
3 | : Spring에서 HTTP 통신 기능을 손쉽게 사용하도록 설계한 템플릿
4 |
5 | - RestFul 원칙을 따르는 서비스를 편하게 만들 수 있음
6 | - 기본적으로 `동기` 방식으로 처리
7 | - 비동기 방식을 사용하는 경우 AsyncRestTemplate 활용
8 | - 현재는 deprecated 상태라 많이 사용하는 경우는 `WebClient` 방식 권장
9 |
10 | > ### 특징
11 |
12 | - Http 프로토콜의 멘서드에 맞는 여러 메서드 제공
13 | - HTTP 요청 후 json, xml 문자열 등의 다양한 형식으로 응답을 받을 수 있음
14 | - Blocking IO 기반의 동기 방식
15 | - 다른 API 호출 시 HTTP 헤더에 다양한 값 설정 가능
16 |
17 |
18 |
19 | ## 동작원리
20 |
21 |
22 |
23 |
24 |
25 | - 애플리케이션에서 RestTemplate 선언 및 URI와 HTTP 메서듯 BOdy 등 설정
26 | - 외부 API로 Request 보낼 시, RestTemplate에서 `HttpMessageConverter`를 통해 RequestEntry를 요청 메시지로 반환
27 | - 반환된 Request Message를 `ClientHttpRequestractory`를 통해 ClientHittpRequest로 가져온 후 외부 API 요청을 보냄
28 | - 외부에서 요청에 대한 응답을 받으면 RestTemplate은 RespenseErrarklande로 오류 확인 및 오류가 있을
29 | 시 ClientHoRespanse에서 응답 데이터 처리
30 | - 받은 응답데이터가 정상일 시, HttpMessageConverter를 거쳐 Java 객체로 변환해 애플리케이션으로 반환
31 |
32 |
33 |
34 | ## 대표 메서드
35 |
36 | | 메서드 | HTTP형태 | 설명 |
37 | | --------------- | -------- | ------------------------------------------------------------------------ |
38 | | getForObject | GET | GET 형식으로 요청한 결과를 객체로 반환 |
39 | | getForEntity | GET | GET 형식으로 요청한 결과를 ResponseEntity 형식으로 반환 |
40 | | postForLocation | POST | POST 형식으로 요청한 결과를 헤더에 저장된 URI로 반환 |
41 | | postForObject | POST | POST 형식으로 요청한 결과를 객체로 반환 |
42 | | postForEntity | POST | POST 형식으로 요청한 결과를 ResponseEntity 형식으로 반환 |
43 | | delete | DELETE | DELETE 형식으로 요청 |
44 | | put | PUT | PUT 형식으로 요청 |
45 | | patchForObject | PATCH | PATCH 형식으로 요청한 결과를 객체로 반환 |
46 | | optionsForAllow | OPTIONS | 해당 URI에서 지원하는 HTTP 메서드를 조회 |
47 | | exchange | any | HTTP 헤더를 임으로 추가할 수 있고, 어떤 메서드 형식에서도 사용할 수 있음 |
48 | | execute | any | 요청과 응답에 대한 콜백을 수정 |
49 |
--------------------------------------------------------------------------------
/Web-Spring/test/JUnit5_Extension.md:
--------------------------------------------------------------------------------
1 | # JUnit5의 Extension
2 |
3 | ## Extension 인터페이스
4 |
5 | - Extension을 통해 Test class, method 확장 가능
6 | - 동작 방식은 테스트의 이벤트, Life Cycle에 관여하게 됨
7 | - `ExtendWith`를 통해 Extension 구현체를 지정해 테스트를 실행하는 방법을 커스터마이징 할 수 있음
8 |
9 | ### TestInstancePostProcessor
10 |
11 | ```java
12 | @FunctionalInterface
13 | @API(
14 | status = Status.STABLE,
15 | since = "5.0"
16 | )
17 | public interface TestInstancePostProcessor extends Extension {
18 | void postProcessTestInstance(Object var1, ExtensionContext var2) throws Exception;
19 | }
20 | ```
21 |
22 | ## Lifecycle Callbacks
23 |
24 | ### Lifecycle
25 |
26 | - BeforeAllCallback
27 | - BeforeAll
28 | - BeforeEachCallback
29 | - BeforeEach
30 | - BeforeTestExecutionCallback
31 | - Test
32 | - AfterTestExecutionCallback
33 | - AfterEach
34 | - AfterEachCallback
35 | - AfterAll
36 | - AfterAllCallback
37 |
38 |
39 | ### Callbacks
40 |
41 | - BeforeAllCallback
42 | - BeforeEachCallback
43 | - BeforeTestExecutionCallback
44 | - AfterTestExecutionCallback
45 | - AfterEachCallback
46 | - AfterAllCallback
47 |
48 |
49 |
--------------------------------------------------------------------------------
/Web-Spring/test/TestContainer를_활용한_통합_테스트.md:
--------------------------------------------------------------------------------
1 | # TestContainer를 활용한 통합 테스트
2 |
3 | ## TestContainer란?
4 |
5 | - 통합 테스트를 지원하기 위해 개발된 오픈 소스 Java 라이브러리
6 | - Docker Container 활용
7 | - 외부 의존성들을 포함한 테스트 환경을 구축하고 관리하는 것을 간편하게 해줌
8 | - 실 운영 환경과 유사한 환경에서 통합 테스트를 진행 가능
9 |
10 | ### 장점
11 |
12 | - 개발자 친화적
13 | - 의존성과 환경 구성 최소화
14 | - 개발자가 테스트에만 집중할 수 있게 해줌
15 | - 환경 독립성
16 | - Docker 사용으로 로컬 환경, CI/CD 파이프라인, 프로덕션 환경 등에서 동일한 테스트 환경 구축 가능
17 | - 높은 확장성
18 | - 다양한 서비스와 애플리케이션 지원
19 | - 필요한 경우, 새로운 서비스를 추가와 기존 서비스를 업데이트 용이
20 | - 멱등성 보장
21 | - 비결정적인 테스트 결과 방지
22 |
23 | ### 단점
24 |
25 | - TestContainer 가동을 위해 메모리가 많이 소요됨
26 | - Container를 띄우는 과정 때문에 테스트 속도가 느려짐
27 | - Docker 환경이 구축돼 있어야 함
28 |
--------------------------------------------------------------------------------
/Web/cookieNsession.md:
--------------------------------------------------------------------------------
1 | ## 쿠키 (Cookie)
2 |
3 | : 클라이언트(브라우저) `로컬`에 저장되는 `Key-Value` 형식의 작은 데이터 파일
4 |
5 | - 사용자 인증이 유효한 시간 명시 가능
6 | - 유효시간이 정해지면 브라우저가 종료돼도 `인증 유지`
7 | - 클라이언트에 300개까지 저장 가능
8 | - 한 도메인당 20개의 값만 가질 수 있음
9 | - 하나의 쿠키는 4KB까지 저장 가능
10 | - 브라우저가 `Request` 시 자동으로 넣어서 서버에 전송
11 | - ex. 자동로그인, 장바구니 등
12 |
13 | > ### 구성
14 |
15 | - 이름
16 | - 값
17 | - 유효시간
18 | - 쿠키를 전송할 도메인
19 | - 쿠키를 전송할 요청 경로
20 |
21 | > ### 동작 방식
22 |
23 | - 클라이언트가 페이지 요청
24 | - 서버에서 쿠키 생성
25 | - HTTP 헤더에 쿠키를 포함시켜 응답
26 | - 브라우저가 종료돼도 유효시간이 있다면 보관
27 | - 같은 요청 시 HTTP 헤더에 쿠키를 포함시켜 보냄
28 | - 서버에서 쿠키를 읽고, 쿠키를 업데이트 하여 응답
29 |
30 |
31 |
32 | ## 세션 (Session)
33 |
34 | : 사용자가 웹 브라우저를 통해 웹 서버에 접속한 시점부터 웹 브라우저를 종료하여 연결을 끝내는 시점까지 같은 사용자로부터 오는 일련의 요청을 `하나의 상태`로 보고, 그 상태를 일정하게 유지하는 기술
35 |
36 | - 쿠키를 기반으로 하고 있음
37 | - 클라이언트 구분을 위해 `Session id`를 부여
38 | - 접속 시간 `제한 설정` 가능
39 | - 보안에 좋지만, 메모리 부하가 커질 수 있음
40 |
41 | > ### 동작 방식
42 |
43 | - 클라이언트가 서버에 접속 시 `Session Id 발급`
44 | - 클라이언트는 `쿠키를 사용`해서 Session Id 저장
45 | - 클라이언트가 서버에 Request를 보낼 때, 쿠키의 Session Id도 같이 서버에 전달
46 | - 서버는 Session Id를 받아 `세션에 있는 클라이언트 정보`를 가져와 사용
47 | - 클라이언트 정보를 가지고 서버 요청 처리 후 응답
48 |
49 |
50 |
51 | ---
52 |
53 | ### 참고자료
54 |
55 | - [@interconnection](https://interconnection.tistory.com/74)
56 | - [@cheershennah](https://cheershennah.tistory.com/135)
57 |
--------------------------------------------------------------------------------
/Web/cors.md:
--------------------------------------------------------------------------------
1 | ## CORS (Cross-Origin Resource Sharing Policy)
2 |
3 | : SOP(; Same-Origin Policy)를 위반하고, 적절한 보안 인증을 받기 위한 메커니즘
4 |
5 | - CORS 없이 모든 곳에서 데이터를 요청할 수 있게 하면 다른 사이트에서 원래 사이트를 흉내낼 수 있음
6 | - 브라우저에서 `보호`하고, 필요한 경우에만 `서버와 협의`하여 요청하기 위해 CORS 필요
7 |
8 | ## Front-End에서 CORS 해결
9 |
10 | ##### (React 기준으로 작성했습니다)
11 |
12 | > ### package.json에서 Proxy 설정
13 |
14 | ```json
15 | },
16 | "proxy": "접속하려는 서버의 루트 URL"
17 | }
18 | ```
19 |
20 |
21 |
22 | > ### http-proxy-middleware 사용
23 |
24 | ```typescript
25 | const { createProxyMiddleware } = require("http-proxy-middleware");
26 |
27 | module.exports = function (app) {
28 | app.use(
29 | createProxyMiddleware("/api", {
30 | target: "접속하려는 서버의 루트 URL",
31 | changeOrigin: true,
32 | })
33 | );
34 | };
35 | ```
36 |
37 |
38 |
39 | ## Back-End에서 CORS 해결
40 |
41 | > ### NestJS
42 |
43 | - enableCors() 함수 사용
44 |
45 | ```typescript
46 | // main.ts
47 | const app = await NestFactory.create(AppModule);
48 | app.enableCors({
49 | origin: process.env.CLIENT_URL,
50 | methods: ["GET", "POST", "PUT", "PATCH", "DELETE"],
51 | });
52 | ```
53 |
54 |
55 |
56 | > ### Spring Boot
57 |
58 | - `CorsFilter` 생성하기
59 | - `@CrossOrigin` 사용
60 | - `WebMvcConfigurer` 사용
61 |
--------------------------------------------------------------------------------
/Web/crawling.md:
--------------------------------------------------------------------------------
1 | ## Web Crawling
2 |
3 |
4 |
5 | > ### Web scraping is a computer software technique of extracting information from websites
6 |
7 |
8 |
9 | `크롤링(crawling)` 혹은 `스크레핑(scraping)`은 컴퓨터 소프트웨어 기술로 다른 프로그램으로부터 들어오는 인간이 읽을 수 있는 출력으로부터 데이터를 추출하는 기법으로, 흔히 말하는 `웹 크롤링`은 웹 페이지를 그대로 가져와서 거기서 데이터를 추출해 내는 기법이다. (정식명칭은 `Web Scraping`이라고 한다.)
10 |
11 | 이러한 동작을 하는 프로그램이 바로 `웹 크롤러`다. 웹 크롤러는 한 페이지만 방문하는 것이 아니라 미리 입력된 방식에 따라 끊임없이 새로운 웹 페이지를 찾아 종합하고, 찾은 결과를 이용해 또 새로운 정보를 찾아 색인을 추가하는 작업을 반복 수행하는데, 이처럼 링크를 따라 웹을 돌아다니는 모습이 거미와 비슷하다고 하여 `스파이더`라고 부르기도 한다. 네이버, 구글 등도 이런 봇(BOT)을 이용해 운영된다.
12 |
13 | 웹은 기본적으로 HTML 형식으로 되어 있다. 때문에 규칙이 있고, 이런 규칙을 분석하여 원하는 데이터를 추출해내는 것이 웹 크롤링 작업의 기본 원리라고 생각하면 된다.
14 |
15 |
16 |
17 | ### 관련 소프트웨어
18 |
19 | - 파이썬
20 | - beautifulsoup
21 | - [selenium](https://github.com/lcomment/development-recipes/blob/main/Language/Python/selenium.md)
22 | - 자바
23 | - jsoup
24 | - 툴
25 | - httrack
26 | - wget-curl
27 |
28 |
29 |
30 | ---
31 |
32 | ### **참고자료**
33 |
34 | - Web
35 | - [#wikipedia](https://ko.wikipedia.org/wiki/데이터_스크레이핑)
36 | - [#namu](https://namu.wiki/w/크롤링)
37 | - [@potter777777](https://m.blog.naver.com/potter777777/220605598446)
38 |
--------------------------------------------------------------------------------
/Web/jwt.md:
--------------------------------------------------------------------------------
1 | ## JWT
2 |
3 | : `Json Web Token`의 약자
4 |
5 | - 일반적으로 Client와 Server 사이에서 통신할 때 `권한`을 위해 사용
6 | - 웹 표준 통신규약에 따라 생성한 암호화된 토큰
7 |
8 |
9 |
10 | ## 구성요소
11 |
12 | 
13 |
14 | > ### 헤더 (Header)
15 |
16 | → Token에 대한 `메타 데이터`를 포함하고 있음
17 |
18 | - 어떤 알고리즘으로 암호화 했는지
19 | - 어떤 토큰을 사용했는지
20 |
21 | > ### 페이로드 (Payload)
22 |
23 | → 전달하려는 정보를 포함하고 있음
24 |
25 | - 내용 `수정`이 가능하며, 더 많은 `정보`를 추가할 수 있음
26 | - 인증이 필요한 최소한의 정보
27 | - O → 권한의 범위, 토큰 발급일 및 만료일
28 | - X → 개인정보
29 |
30 | > ### 시그니처 (Signature)
31 |
32 | → 헤더와 정보를 합친 후 발급해준 서버가 지정한 `Secret Key`로 암호화시켜 토큰을 변조하기 어렵게 만듦
33 |
34 |
35 |
36 | ## JWT의 인증과정
37 |
38 | 
39 |
40 | > ### 🔒 Refresh Token을 사용하는 이유
41 | >
42 | > → Access Token을 통한 인증 방식은 제3자에게 탈취 당할 경우 `보안에 취약`하다. Refresh Token은 서버에 저장되기 때문에, Refresh Token이 제3자에게 탈취 당했다고 판단될 때 서버에서 `삭제함`으로써 강제 로그아웃 시킬 수 있다.
43 | >
44 | > ( Access Token은 짧은 만료기간, Refresh Token은 긴 만료기간을 주로 사용한다. )
45 |
--------------------------------------------------------------------------------
/Web/orm.md:
--------------------------------------------------------------------------------
1 | ## **ORM** (Object-Relational Mapping)
2 |
3 | : 애플리케이션의 객체를 RDB 테이블에 자동으로 영속화 해주는 것
4 |
5 | ### 📎 장점
6 |
7 | - `객체 지향`적인 코드로 인해 더 직관적이고 비즈니스 로직에 집중할 수 있게 해줌
8 | - SQL의 절차적이고 순차적 접근이 아닌 객체 지향적 접근
9 | - 내부적으로는 쿼리를 생성
10 | - `개발자는 신경쓰지 않아도 됨`
11 | - `재사용` 및 `유지보수`의 편리성 증가
12 | - 독립적으로 작성돼 재활용 가능
13 | - `모델(model)`에서 가공된 데이터를 `컨트롤러(controller)`에 의해 `뷰(view)`와 합쳐지는 형태
14 | - 디자인 패턴을 견고히 다지는 데에 유리
15 | - 매핑정보가 명확
16 | - DBMS에 대한 `종속성 감소`
17 | - 구현 방법뿐 아니라 자료형 타입까지 종속성 감소
18 | - DBMS를 교체하는 작업 또한 비교적 적은 리스크와 시간 소요
19 |
20 | ### 📎 단점
21 |
22 | - 완벽한 ORM으로만 서비스 구현은 어려움
23 | - 설계가 신중해야 함
24 | - 프로젝트가 복잡하고 클수록
25 | - 난이도 상승
26 | - `속도 저하` 및 일관성 파괴
27 | - 일부 대형 쿼리는 속도를 위해 `별도의 튜닝`이 필요할 수 있음
28 |
29 |
30 |
31 | ---
32 |
33 | ### **참고자료**
34 |
35 | - Web
36 | - [@incodom](http://www.incodom.kr/ORM)
37 | - [@dbjh](https://dbjh.tistory.com/77)
38 |
--------------------------------------------------------------------------------
/Web/putNpatch.md:
--------------------------------------------------------------------------------
1 | ## PUT과 PATCH
2 |
3 | ### PUT
4 |
5 | > The HTTP PUT request method `creates` a new resource or `replaces` a representation of the target resource with the request payload.
6 |
7 | : HTTP PUT 메서드는 요청 페이로드를 사용해 `새로운 리소스를 생성`하거나 대상 리소스를 나타내는 `데이터를 대체`합니다.
8 |
9 |
10 |
11 | ### PATCH
12 |
13 | > The HTTP PATCH request method applies `partial modifications` to a resource.
14 |
15 | : HTTP PATCH 메소드는 리소스의 `부분적인 수정`을 할 때에 사용됩니다.
16 |
17 | ## 차이점
18 |
19 | PUT과 PATCH는 정의에서부터 차이점을 보인다. 아래의 설명을 보면 더 확실히 이해할 수 있을 것이다.
20 |
21 | > ### _리소스 예시_
22 |
23 | | id | name | value |
24 | | :-: | :--: | :---: |
25 | | 1 | a | 100 |
26 | | 2 | b | 200 |
27 | | 3 | c | 300 |
28 |
29 |
30 |
31 | > ### 1. Update 방식
32 |
33 | ```json
34 | 1. PUT /users?id=1
35 | {
36 | name: "d",
37 | value: 400
38 | }
39 |
40 | 2. PUT /users?id=1
41 | {
42 | name: "d"
43 | }
44 | ```
45 |
46 | PUT의 정의에서는 새로운 리소스를 생성하거나 데이터를 대체한다고 했다. `1번`의 경우 자원의 모든 상태에 새로운 값을 대입하여 보낸 요청이다. 반대로 `2번`은 `name` 데이터에만 새로운 값을 보낸 요청이다.
47 |
48 | | id | name | value |
49 | | :-: | :--: | :---: |
50 | | 1 | d | 400 |
51 | | 2 | b | 200 |
52 | | 3 | c | 300 |
53 |
54 | `1번`의 경우, 새로운 자원이 기존 리소스를 대체했다.
55 |
56 | | id | name | value |
57 | | :-: | :--: | :---: |
58 | | 1 | d | null |
59 | | 2 | b | 200 |
60 | | 3 | c | 300 |
61 |
62 | 하지만 `2번`의 경우, 보내지 않은 값이 `null`로 대체된다. 즉, 대상 리소스를 나타내는 데이터를 대체하는 `Update` 방식이다.
63 |
64 | ```json
65 | 1. PATCH /users?id=1
66 | {
67 | name: "d",
68 | value: 400
69 | }
70 |
71 | 2. PATCH /users?id=1
72 | {
73 | name: "d"
74 | }
75 | ```
76 |
77 | 같은 데이터로 PATCH 요청을 보내보면,
78 |
79 | | id | name | value |
80 | | :-: | :--: | :---: |
81 | | 1 | `d` | `400` |
82 | | 2 | b | 200 |
83 | | 3 | c | 300 |
84 |
85 | `1번`의 경우, 보낸 값 모두 수정 되었다.
86 |
87 | | id | name | value |
88 | | :-: | :--: | :---: |
89 | | 1 | d | 100 |
90 | | 2 | b | 200 |
91 | | 3 | c | 300 |
92 |
93 | `2번` 또힌 보내지 않은 값은 그대로 유지되고, `name`만 새로운 데이터로 수정됐다. 즉, 부분적인 수정을 하는 `Update` 방식이다.
94 |
95 |
96 |
97 | > ### 2. 요청한 URI에 자원이 존재하지 않을 때
98 |
99 | ```json
100 | 1. PUT /users?id=4
101 | {
102 | name: "d",
103 | value: 400
104 | }
105 |
106 | 2. PATCH /users?id=4
107 | {
108 | name: "d",
109 | value: 400
110 | }
111 | ```
112 |
113 | `PUT`의 경우, 새로운 자원을 `생성`해준다. 하지만 `PATCH`는 새로운 자원을 생성하지 않고 `오류`를 뱉어낸다.
114 |
115 |
116 |
117 | ---
118 |
119 | ### **참고자료**
120 |
121 | - [@vagabondms](https://velog.io/@vagabondms/기술-스터디-PUT과-PATCH-차이)
122 |
--------------------------------------------------------------------------------
/Web/redirectNforward.md:
--------------------------------------------------------------------------------
1 | ## Forward 방식
2 |
3 | 
4 |
5 | Forward는 서버 내부에서 일어나는 호출이다. 웹 브라우저는 다른 페이지로 이동했는지 알 수 없다. 따라서 웹 브라우저에는 호출한 `기존의 URL이 표시`되고, 호출한 페이지와 forward에 의해 호출된 페이지는 `Request 객체`와 `Response 객체`를 공유한다.
6 |
7 | ### 요약
8 |
9 | - Forwarding 후 URL 표시 없이 페이지 이동
10 | - 요청 정보를 그대로 전달
11 | - 시스템에 변화가 생기지 않는 단순 조회 요청에 적합
12 |
13 |
14 |
15 | ## Redirect 방식
16 |
17 | 
18 |
19 | Redirect는 Server에서 Client가 요청한 URL에 대한 응답으로 다른 URL로 재접속하라는 명령을 보내는 것이다. 웹 브라우저는 해당 URL로 이동하게 되고, 새로운 페이지에서 `Request`와 `Response` 객체가 새롭게 생성된다.
20 |
21 | ### 요약
22 |
23 | - 페이지 전환의 주체가 `Client`
24 | - 기존의 `Request 객체`와 `Response 객체`는 유효하지 않음
25 | - 시스템에 변화가 생기는 요청의 경우에 사용 적합
26 |
27 |
28 |
29 | ---
30 |
31 | ### 참고자료
32 |
33 | - [@kotlinworld](https://kotlinworld.com/329)
34 | - [@doublesprogramming](https://doublesprogramming.tistory.com/m/63)
35 | - [@junhyunny](https://junhyunny.blogspot.com/2019/12/forwarding-redirect.html)
36 |
--------------------------------------------------------------------------------
/Web/requestObject.md:
--------------------------------------------------------------------------------
1 | ## Request 객체의 3가지 메서드
2 |
3 | > ### Param
4 |
5 | - 주소에서 포함된 변수
6 | - http://localhost:8080/user/profile/1 에서 `1`
7 | - Spring → `@PathVariable`
8 | - Nest js → `@Param`
9 |
10 |
11 |
12 | > ### Query
13 |
14 | - 주소 끝, ?뒤에 있는 변수
15 | - http://localhost:8080/user?id=1&name=lcomment 에서 `id`와 `name`
16 | - Spring → `@RequestParam`
17 | - Nest js → `@Query`
18 |
19 |
20 |
21 | > ### Body
22 |
23 | - Json, XML 등의 데이터, 주소에서 알 수 없음
24 | - 툴을 활용하면 알 수 있기 때문에 민감한 정보는 암호화 필요
25 | - Spring → `@RequestBody`
26 | - Nest js → `@Body`
27 |
--------------------------------------------------------------------------------
/Web/restApi.md:
--------------------------------------------------------------------------------
1 | ## REST란?
2 |
3 | : `Representational State Transfer`의 약자로, 자원을 이름으로 구분하여 해당 상태를 주고받는 모든 것을 의미
4 |
5 | - HTTP URI를 통해 `자원을 명시`
6 | - HTTP Method를 통해 해당 자원에 대한 `CRUD Operation 적용`
7 |
8 | ### 구성 요소
9 |
10 | - 자원(resources): HTTP URI
11 | - 행위(verb): HTTP Method
12 | - 내용(representations): HTTP Message Payload
13 |
14 | ### 특징
15 |
16 | - Uniform Interface (유니폼 인터페이스)
17 | - URI로 지정한 리소스에 대한 조작을 `통일되고 한정적인 인터페이스`로 수행하는 아키텍처 스타일
18 | - Stateless (무상태성)
19 | - 작업을 위한 `상태 정보`(세션, 쿠키 등)를 저장 및 관리하지 않음
20 | - API 서버는 클라이언트의 `요청`만 단순히 처리
21 | - Cacheable (캐시 가능)
22 | - `HTTP`라는 웹 표준을 그대로 사용
23 | - 따라서 캐싱 기능 적용 가능
24 | - HTTP 프로토콜 표준에서 사용하는 `Last-Modified Tag`나 `E-Tag` 이용
25 | - Server-Client Structure (서버-클라이언트 구조)
26 | - client와 server의 역할이 확실히 구분됨
27 | - 서로 간 의존성 감소
28 | - Layered System (계층형 구조)
29 | - 다중 계층으로 구성될 수 있음
30 | - 보안, 로드밸런싱, 암호화 계층을 추가해 `구조상 유연성`을 둘 수 있음
31 | - 프록시, 게이트웨이 같은 `네트워크 기반의 중간매체`를 사용할 수 있게 함
32 | - Self-descriptiveness (자체 표현 구조)
33 | - REST API 메시지만 보고도 쉽게 이해 가능
34 |
35 |
36 |
37 | ## REST API 디자인
38 |
39 | - URI는 동사보다는 `명사`를, 대문자보다는 `소문자`를 사용하여야 한다.
40 | - 계층 관계를 나타내는 슬래시(`/`)를 마지막에 사용하지 않는다.
41 | - 언더바(`_`)보단 하이폰(`-`)을 사용한다.
42 | - 파일확장자는 URI에 포함하지 않는다.
43 | - 행위를 포함하지 않는다.
44 |
45 | ---
46 |
47 | ### **참고자료**
48 |
49 | - Web
50 | - [@khj93](https://khj93.tistory.com/entry/네트워크-REST-API란-REST-RESTful이란)
51 | - [@meetup](https://meetup.toast.com/posts/92)
52 |
--------------------------------------------------------------------------------
/Web/web.md:
--------------------------------------------------------------------------------
1 | ## 웹의 동작원리
2 |
3 |
4 |
5 |
6 |
7 | 1. 사용자가 브라우저에 `URL` 입력
8 | 2. URL 전송
9 | 3. 브라우저는 DNS 서버에 URL의 `도메인 네임` 검색
10 | 4. DNS 서버에서 해당 도메인 네임에 해당하는 `IP 주소`를 찾아 사용자가 입력한 URL 정보와 함께 전달
11 | 5. HTTP 프로토콜을 사용하여 HTTP 요청 메시지 생성
12 | 6. HTTP 요청 메시지는 `해당 IP 주소의 컴퓨터`로 전송됨
13 | 7. 도착한 HTTP 요청 메시지가 웹 페이지 `URL` 정보로 변환
14 | 8. 웹 서버는 도착한 웹 페이지 URL 정보에 해당하는 `데이터 검색`
15 | 9. HTTP 응답 메시지 생성
16 | 10. HTTP 응답 메시지는 다시 인터넷을 거쳐 `원래 컴퓨터`로 전송
17 | 11. 도착한 HTTP 응답 메시지는 HTTP 프로토콜을 사용하여 `웹 페이지`로 변환
18 | 12. `웹 브라우저`로 출력
19 |
20 |
21 |
22 | ---
23 |
24 | ### 참고자료
25 |
26 | - [@mangkyu](https://mangkyu.tistory.com/91)
27 | - [@wonhee010](https://velog.io/@wonhee010/웹의-동작-원리)
28 |
--------------------------------------------------------------------------------
/Web/webReadme.md:
--------------------------------------------------------------------------------
1 | # DevOps and Cloud Recipe
2 |
3 | Web 관련 기초 레시피 입니다. 필요한 레시피를 편하게 얻어가시고, 원하는 레시피는 `ISSUE`에 등록, 추가하고 싶은 레시피와 잘못된 레시피는 `PR`에 등록해주시면 감사하겠습니다.
4 |
5 | - [웹의 동작원리](https://github.com/lcomment/development-recipes/blob/main/Web/web.md)
6 | - [CORS란?](https://github.com/lcomment/development-recipes/blob/main/Web/cors.md)
7 | - [Param, Query, Body의 차이](https://github.com/lcomment/development-recipes/blob/main/Web/requestObject.md)
8 | - [쿠키(Cookie)와 세션(Session)](https://github.com/lcomment/development-recipes/blob/main/Web/cookieNsession.md)
9 | - [JWT (Json Web Token)](https://github.com/lcomment/development-recipes/blob/main/Web/jwt.md)
10 | - [OAuth 2.0](https://github.com/lcomment/development-recipes/blob/main/Web/OAuth2.0.md)
11 | - [REST API](https://github.com/lcomment/development-recipes/blob/main/Web/restApi.md)
12 | - [PUT과 PATCH의 차이](https://github.com/lcomment/development-recipes/blob/main/Web/putNpatch.md)
13 | - [Forward 방식과 Redirect 방식](https://github.com/lcomment/development-recipes/blob/main/Web/redirectNforward.md)
14 | - [웹 크롤링 (Web Crawling)](https://github.com/lcomment/development-recipes/blob/main/Web/crawling.md)
15 | - [ORM (Object-Relational Mapping)](https://github.com/lcomment/development-recipes/blob/main/Web/orm.md)
16 |
--------------------------------------------------------------------------------
/resources/1v1_chatting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/1v1_chatting.png
--------------------------------------------------------------------------------
/resources/URL_단축기.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/URL_단축기.png
--------------------------------------------------------------------------------
/resources/active_send.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/active_send.png
--------------------------------------------------------------------------------
/resources/algorithm/bellman1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/bellman1.png
--------------------------------------------------------------------------------
/resources/algorithm/bellman2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/bellman2.jpeg
--------------------------------------------------------------------------------
/resources/algorithm/catalan1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/catalan1.png
--------------------------------------------------------------------------------
/resources/algorithm/catalan2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/catalan2.jpeg
--------------------------------------------------------------------------------
/resources/algorithm/catalan3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/catalan3.jpeg
--------------------------------------------------------------------------------
/resources/algorithm/catalan4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/catalan4.png
--------------------------------------------------------------------------------
/resources/algorithm/catalan5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/catalan5.png
--------------------------------------------------------------------------------
/resources/algorithm/catalan6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/catalan6.png
--------------------------------------------------------------------------------
/resources/algorithm/catalan7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/catalan7.png
--------------------------------------------------------------------------------
/resources/algorithm/catalan8.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/catalan8.jpeg
--------------------------------------------------------------------------------
/resources/algorithm/dijkstra.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/dijkstra.png
--------------------------------------------------------------------------------
/resources/algorithm/greedy1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/greedy1.png
--------------------------------------------------------------------------------
/resources/algorithm/greedy2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/greedy2.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-a.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-b.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-c.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-c.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-d.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-e.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-e.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-f.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-f.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-g.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-g.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-h.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-i.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-i.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-j.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-j.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-k.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-k.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-l.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-l.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-m.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-m.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-n.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-o.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-o.png
--------------------------------------------------------------------------------
/resources/algorithm/kruskal-p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/kruskal-p.png
--------------------------------------------------------------------------------
/resources/algorithm/mst.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/mst.png
--------------------------------------------------------------------------------
/resources/algorithm/spanningTree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/algorithm/spanningTree.png
--------------------------------------------------------------------------------
/resources/aws/cloudService.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/aws/cloudService.png
--------------------------------------------------------------------------------
/resources/aws/ecs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/aws/ecs.png
--------------------------------------------------------------------------------
/resources/chatting_data_model.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/chatting_data_model.png
--------------------------------------------------------------------------------
/resources/chatting_process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/chatting_process.png
--------------------------------------------------------------------------------
/resources/chatting_server_discovery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/chatting_server_discovery.png
--------------------------------------------------------------------------------
/resources/chatting_system_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/chatting_system_1.png
--------------------------------------------------------------------------------
/resources/dag_process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/dag_process.png
--------------------------------------------------------------------------------
/resources/dataStructure/tree/tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/dataStructure/tree/tree.png
--------------------------------------------------------------------------------
/resources/data_collect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/data_collect.png
--------------------------------------------------------------------------------
/resources/db/design.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/db/design.png
--------------------------------------------------------------------------------
/resources/db/identifyingRelationship.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/db/identifyingRelationship.png
--------------------------------------------------------------------------------
/resources/db/non-identifyingRelationship.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/db/non-identifyingRelationship.png
--------------------------------------------------------------------------------
/resources/db/rdb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/db/rdb.png
--------------------------------------------------------------------------------
/resources/decorator_pattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/decorator_pattern.png
--------------------------------------------------------------------------------
/resources/device_synchronization.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/device_synchronization.png
--------------------------------------------------------------------------------
/resources/docker/vm_container.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/docker/vm_container.png
--------------------------------------------------------------------------------
/resources/feed_publish.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/feed_publish.png
--------------------------------------------------------------------------------
/resources/feed_publish_detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/feed_publish_detail.png
--------------------------------------------------------------------------------
/resources/feed_read.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/feed_read.png
--------------------------------------------------------------------------------
/resources/feed_read_detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/feed_read_detail.png
--------------------------------------------------------------------------------
/resources/git/gitflow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/git/gitflow.png
--------------------------------------------------------------------------------
/resources/group_chatting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/group_chatting.png
--------------------------------------------------------------------------------
/resources/java/collection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/java/collection.png
--------------------------------------------------------------------------------
/resources/java/executeJava.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/java/executeJava.png
--------------------------------------------------------------------------------
/resources/java/javaType.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/java/javaType.png
--------------------------------------------------------------------------------
/resources/java/jvm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/java/jvm.png
--------------------------------------------------------------------------------
/resources/java/linkedlist.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/java/linkedlist.jpeg
--------------------------------------------------------------------------------
/resources/long_polling.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/long_polling.png
--------------------------------------------------------------------------------
/resources/message_queue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/message_queue.png
--------------------------------------------------------------------------------
/resources/multi_master_replication.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/multi_master_replication.png
--------------------------------------------------------------------------------
/resources/nest/exceptionFilter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/nest/exceptionFilter.png
--------------------------------------------------------------------------------
/resources/nest/middleware.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/nest/middleware.png
--------------------------------------------------------------------------------
/resources/network/2by2matrix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/network/2by2matrix.png
--------------------------------------------------------------------------------
/resources/network/3way.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/network/3way.jpg
--------------------------------------------------------------------------------
/resources/network/4way.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/network/4way.jpg
--------------------------------------------------------------------------------
/resources/network/http.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/network/http.png
--------------------------------------------------------------------------------
/resources/network/loadbalancing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/network/loadbalancing.png
--------------------------------------------------------------------------------
/resources/network/osi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/network/osi.png
--------------------------------------------------------------------------------
/resources/network/tcp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/network/tcp.png
--------------------------------------------------------------------------------
/resources/network/udp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/network/udp.png
--------------------------------------------------------------------------------
/resources/notification_contact.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/notification_contact.png
--------------------------------------------------------------------------------
/resources/notification_system_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/notification_system_1.png
--------------------------------------------------------------------------------
/resources/notification_system_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/notification_system_2.png
--------------------------------------------------------------------------------
/resources/notification_system_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/notification_system_3.png
--------------------------------------------------------------------------------
/resources/notification_system_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/notification_system_4.png
--------------------------------------------------------------------------------
/resources/os/contextSwitching.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/os/contextSwitching.png
--------------------------------------------------------------------------------
/resources/os/pap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/os/pap.png
--------------------------------------------------------------------------------
/resources/os/pcb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/os/pcb.png
--------------------------------------------------------------------------------
/resources/os/process_thread.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/os/process_thread.png
--------------------------------------------------------------------------------
/resources/os1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/os1.png
--------------------------------------------------------------------------------
/resources/polling.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/polling.png
--------------------------------------------------------------------------------
/resources/port1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/port1.png
--------------------------------------------------------------------------------
/resources/programming/Test/test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/programming/Test/test.png
--------------------------------------------------------------------------------
/resources/proxy1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/proxy1.png
--------------------------------------------------------------------------------
/resources/proxy2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/proxy2.jpeg
--------------------------------------------------------------------------------
/resources/proxy3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/proxy3.jpeg
--------------------------------------------------------------------------------
/resources/python/selenium1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/python/selenium1.png
--------------------------------------------------------------------------------
/resources/rate_limiter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/rate_limiter.png
--------------------------------------------------------------------------------
/resources/sliding_window_counter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/sliding_window_counter.png
--------------------------------------------------------------------------------
/resources/snowflake.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/snowflake.png
--------------------------------------------------------------------------------
/resources/spring/BeanDefinition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/BeanDefinition.png
--------------------------------------------------------------------------------
/resources/spring/Factory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/Factory.png
--------------------------------------------------------------------------------
/resources/spring/MyBatis/myBatisDatabaseAccess.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/MyBatis/myBatisDatabaseAccess.PNG
--------------------------------------------------------------------------------
/resources/spring/RESTDocs/springRestDoc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/RESTDocs/springRestDoc.png
--------------------------------------------------------------------------------
/resources/spring/basic/context.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/basic/context.PNG
--------------------------------------------------------------------------------
/resources/spring/basic/mvc-context.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/basic/mvc-context.png
--------------------------------------------------------------------------------
/resources/spring/controller.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/controller.png
--------------------------------------------------------------------------------
/resources/spring/di.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/di.png
--------------------------------------------------------------------------------
/resources/spring/di2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/di2.png
--------------------------------------------------------------------------------
/resources/spring/jcenter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/jcenter.png
--------------------------------------------------------------------------------
/resources/spring/jpa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/jpa.png
--------------------------------------------------------------------------------
/resources/spring/liveReload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/liveReload.png
--------------------------------------------------------------------------------
/resources/spring/restTemplate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/restTemplate.png
--------------------------------------------------------------------------------
/resources/spring/restcontroller.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/restcontroller.png
--------------------------------------------------------------------------------
/resources/spring/security/google/googleLogin1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/security/google/googleLogin1.png
--------------------------------------------------------------------------------
/resources/spring/security/google/googleLogin2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/security/google/googleLogin2.png
--------------------------------------------------------------------------------
/resources/spring/security/google/googleLogin3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/security/google/googleLogin3.png
--------------------------------------------------------------------------------
/resources/spring/security/google/googleLogin4-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/security/google/googleLogin4-1.png
--------------------------------------------------------------------------------
/resources/spring/security/google/googleLogin4-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/security/google/googleLogin4-2.png
--------------------------------------------------------------------------------
/resources/spring/security/google/googleLogin4-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/security/google/googleLogin4-3.png
--------------------------------------------------------------------------------
/resources/spring/security/google/googleLogin5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/security/google/googleLogin5.png
--------------------------------------------------------------------------------
/resources/spring/security/google/googleLogin6-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/security/google/googleLogin6-1.png
--------------------------------------------------------------------------------
/resources/spring/security/google/googleLogin6-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/security/google/googleLogin6-2.png
--------------------------------------------------------------------------------
/resources/spring/springMVC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/springMVC.png
--------------------------------------------------------------------------------
/resources/spring/vendor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/spring/vendor.png
--------------------------------------------------------------------------------
/resources/sql1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/sql1.png
--------------------------------------------------------------------------------
/resources/swEngineering/mvc1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/swEngineering/mvc1.png
--------------------------------------------------------------------------------
/resources/swEngineering/tdd1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/swEngineering/tdd1.png
--------------------------------------------------------------------------------
/resources/swEngineering/tdd2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/swEngineering/tdd2.png
--------------------------------------------------------------------------------
/resources/swEngineering/tdd3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/swEngineering/tdd3.png
--------------------------------------------------------------------------------
/resources/ticket_server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/ticket_server.png
--------------------------------------------------------------------------------
/resources/token_bucket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/token_bucket.png
--------------------------------------------------------------------------------
/resources/transcoding_process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/transcoding_process.png
--------------------------------------------------------------------------------
/resources/trie_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/trie_example.png
--------------------------------------------------------------------------------
/resources/video_upload_process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/video_upload_process.png
--------------------------------------------------------------------------------
/resources/web/forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/web/forward.png
--------------------------------------------------------------------------------
/resources/web/jwt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/web/jwt.png
--------------------------------------------------------------------------------
/resources/web/jwtProcess.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/web/jwtProcess.png
--------------------------------------------------------------------------------
/resources/web/oauth1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/web/oauth1.png
--------------------------------------------------------------------------------
/resources/web/oauth2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/web/oauth2.png
--------------------------------------------------------------------------------
/resources/web/oauth3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/web/oauth3.png
--------------------------------------------------------------------------------
/resources/web/oauth4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/web/oauth4.png
--------------------------------------------------------------------------------
/resources/web/redirect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/web/redirect.png
--------------------------------------------------------------------------------
/resources/web/web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/web/web.png
--------------------------------------------------------------------------------
/resources/websocket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/websocket.png
--------------------------------------------------------------------------------
/resources/youtube_basic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcomment/development-recipes/9157a24973524ee05e315454041031f49e6f1f31/resources/youtube_basic.png
--------------------------------------------------------------------------------