├── Algorithm
└── temp.md
├── Design Pattern
├── temp.md
├── 싱글톤패턴(Singleton pattern).md
├── factoryMethod.md
├── 어댑터 패턴 (Adapter pattern).md
├── Composite Pattern.md
├── Strategy Pattern.md
└── templateMethod.md
├── Computer Science
├── Software Engineering
│ ├── temp.md
│ ├── Third Party.md
│ ├── Secure Coding.md
│ ├── DevOps.md
│ ├── CleanCode&Recfactoring.md
│ ├── TDD&UnitTest.md
│ └── 함수형 프로그래밍 (Functional Programming).md
├── Network
│ ├── tcp와 Udp.md
│ ├── tcp3 & 4way(전송제어프로그램).md
│ ├── TLS, SSL.md
│ ├── Block, Non-Block IO.md
│ ├── http와 https.md
│ ├── 동기, 비동기 개념(synchronous vs asynchronous).md
│ ├── Load Balancing.md
│ └── tcpIpControlFlow&Congestion(흐름&혼잡제어).md
├── Database
│ ├── Key(키).md
│ ├── 이상(Anomaly).md
│ ├── SQL-vs-NoSQL.md
│ ├── 정규화(Nomalization).md
│ ├── SQL-join.md
│ ├── Transaction Isolation Level (트랜잭션 격리 수준).md
│ ├── SQL-injection.md
│ └── Transaction(트랜잭션).md
├── Operating System
│ ├── memory.md
│ ├── Paging과 Segmentation.md
│ ├── 프로세스주소공간.md
│ ├── IPC.md
│ ├── 경쟁상태 (Race Condition).md
│ ├── 프로세스vs스레드.md
│ ├── fileSystem.md
│ ├── 인터럽트.md
│ ├── PCB와 Context Switching(문맥교환).md
│ ├── SystemCall(시스템콜, 시스템호출).md
│ └── 운영체제.md
├── Data Structure
│ ├── heap(힙).md
│ ├── hash(해시).md
│ ├── Array, Array List, Linked List 차이점.md
│ ├── 트리와 이진트리 (tree, binary-tree).md
│ └── stack, queue(스택, 큐).md
└── Computer Architecture
│ ├── ARM Process.md
│ └── 실수표현방식 (고정 소수점과 부동 소수점).md
├── .github
├── PULL_REQUEST_TEMPLATE.md
├── ISSUE_TEMPLATE
│ ├── julsamo-question-issue.md
│ └── julsamo-scrum-issue.md
└── CODEOWNERS
└── .gitignore
/Algorithm/temp.md:
--------------------------------------------------------------------------------
1 | # temp file
2 |
--------------------------------------------------------------------------------
/Design Pattern/temp.md:
--------------------------------------------------------------------------------
1 | # temp file
2 |
--------------------------------------------------------------------------------
/Computer Science/Software Engineering/temp.md:
--------------------------------------------------------------------------------
1 | # temp file
2 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## 🟣 공부한 내용
2 |
3 |
4 | ## 🟣 공부하면서 생긴 의문점
5 |
6 |
7 | ## 🟣 기타
8 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/julsamo-question-issue.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 질문제목을 입력해주세요
3 | about: 질문있어요
4 | title: "[Question]
"
5 | labels: Question
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## 🟣 질문
11 |
12 |
13 | ## 🟣 나의 견해
14 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Lines starting with '#' are comments.
2 | # Each line is a file pattern followed by one or more owners.
3 |
4 | # These owners will be the default owners for everything in the repo.
5 | * @rookie0031 @GODNOEL @deslog @SeonJeon
6 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/julsamo-scrum-issue.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 스터디 scurm을 입력해주세요
3 | about: scrum
4 | title: "[SCRUM]"
5 | labels: 🔖SCRUM
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## 🌊 오늘 스터디 내용
11 | |챕터명|핵심내용|
12 | |--|--|
13 |
14 | ## 🌊 다음 스터디까지 Homework
15 | - hw
16 | - hw
17 |
18 | ## 🌊 논의사항
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.toptal.com/developers/gitignore/api/macos
2 | # Edit at https://www.toptal.com/developers/gitignore?templates=macos
3 |
4 | ### macOS ###
5 | # General
6 | .DS_Store
7 | .AppleDouble
8 | .LSOverride
9 |
10 | # Icon must end with two \r
11 | Icon
12 |
13 |
14 | # Thumbnails
15 | ._*
16 |
17 | # Files that might appear in the root of a volume
18 | .DocumentRevisions-V100
19 | .fseventsd
20 | .Spotlight-V100
21 | .TemporaryItems
22 | .Trashes
23 | .VolumeIcon.icns
24 | .com.apple.timemachine.donotpresent
25 |
26 | # Directories potentially created on remote AFP share
27 | .AppleDB
28 | .AppleDesktop
29 | Network Trash Folder
30 | Temporary Items
31 | .apdisk
32 |
33 | ### macOS Patch ###
34 | # iCloud generated files
35 | *.icloud
36 |
37 | # End of https://www.toptal.com/developers/gitignore/api/macos
38 |
--------------------------------------------------------------------------------
/Computer Science/Software Engineering/Third Party.md:
--------------------------------------------------------------------------------
1 | // 2020.09.20 Noel
2 |
3 |
4 |
5 |
6 | # ❤️ 써드 파티(3rd party)
7 |
8 |
9 | ### Third Party
10 |
11 | - 사전적 정의 : "제 3자"
12 | - 일반적으로 하드웨어 생산자와 소프트웨어 개발자의 관계를 나타내는 용어
13 | - 분야에 따라 서드파티의 용어의 쓰임새가 달라짐
14 |
15 |
16 |
17 |
18 | ### 🏢 IT 업계에서 서드파티
19 |
20 | - 어떤 분야를 처음 개발하거나 원천 기술을 가지고 있는게 아닌, 원천기술과 호환되는 상품을 출시하거나 해당 기술을 이용한 파생상품을 생산하는 회사, 즉 제 3자의 역할을 함
21 |
22 | ```예시
23 | 하드웨어 생산자 = 퍼스트 파티(First Party), 소프트웨어 개발자 = 서드파티(Third Party)라고 불림
24 |
25 | - 퍼스트 파티(First Party) : 하드웨어 생산자가 **직접 소프트웨어를 개발하는 경우**
26 | - 세컨드 파티(second Party): 하드웨어 생산자인 모기업과 자사간의 관계에서의 소프트웨어 개발자
27 | - 서드파티(Third Party)
28 | - 하드웨어 생산자와 직접적인 관계없이 소프트웨어를 개발하는 회사
29 | ```
30 |
31 |
32 |
33 |
34 | ### 🕹 게임 분야의 Third Party
35 |
36 | 게임 업계에서는 콘솔 게임기 업체에서 라이선스를 받아 게임만 제작하는 게임제작사를 의미
37 |
38 | ```예시
39 | 게임 분야 예시
40 |
41 | 퍼스트 파티 : 소니나 마이크로소프트(MS)와 같이 콘솔게임기를 개발하면서 동시에 게임을 개발
42 | 서드 파티 : 콘솔 게임기 기반으로 게임만 개발함
43 |
44 | ```
45 |
46 |
47 |
48 |
49 | ### 🖥 프로그램 분야의 Third Party
50 |
51 | 프로그래밍을 도와주는 플러그인이나 라이브러리, 프레임워크 등을 만드는 회사
52 |
53 | - 플러그인, 라이브러리, 프레임워크는 공통적으로 개발하는 것을 도와준다는 의미
54 | - 제 3자가 중간다리 역할로서 도움을 주는 것이 서드파티
55 |
56 | ```예시
57 | 플로그인, 라이브러리, 프레임워크
58 | - 음식으로 비유하면 밀키트라고 생각하면됨, 이미 요리된 것을 전자렌지ㅣ에 돌리거나 열을 가하는 등 조리하는 것
59 | ```
60 |
61 |
62 |
63 |
64 | ### 📱스마트폰의 Third Party
65 |
66 | 운영체제(OS) 스토어에서 제공하는 스마트폰 어플리케이션
67 |
68 | ```예시
69 | - 퍼스트 파티 : 제조사가 직접 만들어 스마트폰에 기본으로 탑재된 어플
70 | - 서드 파티 : 일반 개발사가 만든 어플리케이션
71 | ```
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | 출처
80 |
81 | https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Software%20Engineering/%EC%8D%A8%EB%93%9C%ED%8C%8C%ED%8B%B0(3rd%20party)%EB%9E%80.md
82 |
83 | https://contents.premium.naver.com/3mit/wony/contents/220505105924891hK
84 |
--------------------------------------------------------------------------------
/Design Pattern/싱글톤패턴(Singleton pattern).md:
--------------------------------------------------------------------------------
1 | // 2022.09.27 Brown
2 |
3 |
4 |
5 | # 🟣 싱글톤 패턴이란 (Singleton pattern)
6 |
7 | ```
8 | 하나의 프로그램에서 단 하나의 객체만 있어도 되는 경우 해당 객체를 한 번만 생성하고,
9 | 모든 곳에서 접근 가능하게 해주는 패턴
10 | ```
11 | ## 😈 간단한 예시로 살펴보자.
12 |
13 | ```swift
14 | class UserInfo {
15 | var id: String?
16 | var password: String?
17 | var name: String?
18 | }
19 | ```
20 |
21 | 이렇게 User의 정보를 저장하는 클래스가 있다.
22 | 그리고 이제 여기서
23 |
24 | A ViewController에서 id,
25 | B ViewController에서 password,
26 | C ViewController에서 name을 입력받아서 UserInfo라는 클래스에 저장해야한다고 생각해보자.
27 |
28 | 아래와 같은 세 개의 코드를 각각의 ViewController에서 작성할 것이다.
29 |
30 | ```swift
31 | // A ViewController
32 | let userInfo = UserInfo()
33 | userInfo.id = "brown"
34 | ```
35 |
36 | ```swift
37 | // B ViewController
38 | let userInfo = UserInfo()
39 | userInfo.password = "123"
40 | ```
41 |
42 | ```swift
43 | // C ViewController
44 | let userInfo = UserInfo()
45 | userInfo.name = "brown"
46 | ```
47 |
48 | 이런식으로 각각 객체를 만들어서 저장을 한다면, 각 instance의 프로퍼티에만 (세 가지의 인스턴스로 저장) 될 것이다,,,
49 | 우리는 하나의 인스턴스 안에 id, passowrd, name을 넣어야하는데 말이다.
50 |
51 | 
52 |
53 | ```
54 | 💬 다른 방법으로는
55 |
56 | 인스턴스는 참조 타입이기 때문에 UserInfo 인스턴스를 한 번 생성한 후,
57 | 이 인스턴스를 A -> B -> C 로 필요할 때마다 참조로 넘겨주어 하나의 인스턴스로 구성할 수 있음.
58 |
59 | ⁉️ 근데 이렇게 하게되면!!!
60 | 참조 되어야 할 때마다 인스턴스를 넘겨주어야해서 코드가 지저분해진다.
61 | ```
62 |
63 | #### ☝️😃 따라서, 이 클래스에 대한 instance는 최초 생성될 때 한번만 생성해서 전역에다가 두고, 그 이후로는 이 instance만 접근 가능하게 하면 된다. 이것이 바로 싱글톤 패턴,,,
64 |
65 | 싱글톤패턴으로 개발하면, 위의 그림이 아래처럼 수정된다.
66 |
67 | 
68 |
69 | 이렇게 한 인스턴스에 어디 클래스에서든 접근 가능하게 만드는 것이 바로 싱글톤 패턴이다 ^____^
70 |
71 |
72 |
73 |
74 |
75 | # 📖 Reference
76 |
77 | - [싱글톤 소들이](https://babbab2.tistory.com/66)
78 |
79 |
--------------------------------------------------------------------------------
/Computer Science/Software Engineering/Secure Coding.md:
--------------------------------------------------------------------------------
1 | # 시큐어 코딩 (Secure Coding)
2 | ## 시큐어 코딩이란?
3 |
4 | #### 소프트웨어(SW)를 개발함에 있어 개발자의 실수, 논리적 오류 등으로 인해 SW에 내포될 수 있는 보안취약점(vulnerability)을 배제하기 위한 코딩 기법을 뜻 한다
5 |
6 | ## 시큐어 코딩의 발달 배경
7 | - SW 개발보안의 중요성을 인식한 미국의 경우, 국토안보부(DHS)를 중심으로 시큐어코딩을 포함한 SW 개발 전과정(설계ㆍ구현ㆍ시험 등)에 대한 보안활동 연구를 활발히 진행하고 있다.
8 | - 국내의 경우 2009년부터 전자정부서비스 개발단계에서 SW 보안약점을 진단하여 제거하는 시큐어코딩 관련 연구를 진행하면서,2012년까지 전자정부지원사업 등을 대상으로 SW 보안약점 시범진단을 수행하였다.
9 | - 또한, 2012년 년 6월부터는 행정안전부 '정보시스템 구축ㆍ운영 지침(행안부고시 제2012-25호)'이 개정ㆍ고시 됨에 따라 전자정부서비스 개발시 적용토록 의무화 되었다.
10 |
11 | ## 시큐어 코딩의 필요성
12 | - 수많은 과정을 거쳐 소프트웨어를 개발하는데 그만큼의 비용이 발생한다.
13 | - 추가적인 노력은 흔히 말하는 MM(Man Month)를 증가시켜 비용 상승의 주범이 된다.
14 | - 따라서 우리는 '서둘러 개발을 완료하고 제품 출시를 하고 유지 보수를 하면서 수정하는 것이 더 효과적이지 않을까'라고 생각할 수 있다.
15 | - 하지만 아래 연구 결과를 보면 소프트웨어의 결함을 수정하는데 소요되는 비용은 해당 결함을 개발 초기 단계에서 발견할수록 미미하고, 제품이 출시 된 이후에 발견하게 될 경우 약 30배의 비용이 지급된다.
16 | - 계발 초기 단계에서부터 안전한 소프트웨어를 위해 투자하는 비용은 전체적으로 봤을 때 오히려 비용을 절감하는 효과를 불러온다.
17 |
18 | #### 정리하자면
19 | #### 도출 -> 설계 -> 구현(개발) -> 테스트 -> 릴리즈
20 | ##### 구현(개발) 단계에서 해킹 등의 공격을 유발할 가능성이 있는 잠재적인 보안 취약점을 사전에 제기하여, 외부 공격으로부터 안전한 소프트웨어를 개발하는 기법.
21 |
22 | ## 안전한 코딩 VS 안전하지 않은 코딩
23 |
24 | ##### 안전하지 않은 코딩
25 |
26 | - 10번과 11번 줄에서 보이는 strcpy 함수는 NULL 문자를 만나기 전까지의 문자열을 복사한다.
27 | - 따라서 버퍼 오버플로우 기법에 취약한 부분이라고 할 수 있다.
28 | - 이 부분을 파고든다면 사용자의 권한도 탈취할 수 있다.
29 | - 따라서 안전한 코딩 방법을 따라야한다.
30 |
31 | ##### 안전한 코딩
32 |
33 | - 따라서 11번과 12번 줄처럼 strncpy 함수를 이용하여 문자열을 복사해야 한다.
34 | - strncpy는 문자열을 지정된 길이만큼 복사하므로 추가적인 무자열에 취약점을 드러내지 않을 것이다.
35 |
36 |
37 | ## 보안 취약성을 제거하는 법
38 | 1. 시큐어 코딩에 정통한 개발자가 코드를 한 줄씩 검사하는 방법.
39 | 2. 시큐어 코딩이 가능한 솔루션(정적분석도구)를 도입하는 방법.
40 |
41 |
42 | ## Reference
43 | - https://blankspace-dev.tistory.com/33
44 | - https://codelib.tistory.com/18
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/Computer Science/Software Engineering/DevOps.md:
--------------------------------------------------------------------------------
1 | // 2022.09.20
2 |
3 | ## DevOps란?
4 |
5 | ### 정의
6 |
7 | Development + Operation 을 이은 말로, 소프트웨어 개발자와 정보기술 전문가/(소프트웨어 운영팀) 간의 소통, 협업 및 통합을 강조하는 개발 환경이나 문화를 의미함.
8 |
9 | ### 목적
10 |
11 | 소프트웨어 제품과 서비스를 **빠른 시간에 개발 및 배포하는 것**
12 |
13 | 결국, 소프트웨어 제품이나 서비스를 알맞은 시기에 출시하기 위해 개발과 운영이 상호 의존적으로 대응해야 한다는 의미로 많이 사용하고 있다.
14 |
15 | ---
16 |
17 | **근데 뭔지 알겠는데… 갑자기 이게 왜 나온거지??**
18 |
19 | ### 데브옵스 등장 배경
20 |
21 | **데브옵스는 결국에는 애자일처럼 프로덕트를 좀 더 빠르게 발전시키기 위해 고안된 개발 문화이다.**
22 |
23 | 프로덕트를 만들면, 그 프로덕트를 안정적으로 운영하는 팀과 좀 더 기능적으로 개발하는 팀으로 나뉜다.
24 |
25 | 그러면 당연히 새로운 기능을 추가하려면 안정적인 운영에 빈틈이 생길 수 밖에 없고… 그래서 운영팀과 개발팀 사이에 갈등이 생기게 되며 프로덕트의 발전은 더디게 된다.
26 |
27 | **그럼 어떡하면 될까??**
28 |
29 | 개발하는 순간부터 운영까지 고려해서, 새로운 기능을 추가할 때 케어해줘야하는 운영 부분들을 자동화시키면된다. 구성원들이 최대한 개발과 운영의 본질적인 부분에만 집중할수있게 통하환경과 자동화된 시스템을 도입해주면 된다. 이러한 문제로 부터 도커와 쿠버네티스 같은 툴이 나오게 된 것이다!
30 |
31 | 이렇게 개발팀과 운영팀이 나뉘어지지않고 하나의 팀이되어 개발 - 배포 - 운영 등의 작업을 원툴로 관리하는 문화를 데브옵스라고 한다.
32 |
33 |
34 |
35 | ### 예시
36 |
37 | 실제로 AWS 홈페이지에 가보면 데브옵스에 대한 설명과 더불어 기업에서 데브옵스를 채택하기 위한 툴을 제공하고 있다.
38 |
.
39 | https://aws.amazon.com/ko/devops/resources/.
40 |
41 |
42 | ### More
43 |
44 | 데브옵스의 개념은 애자일 기법과 지속적 통합의 개념과도 관련이 있다.
45 |
46 | - **[#](https://gyoogle.dev/blog/computer-science/software-engineering/DevOps.html#%E1%84%8B%E1%85%A2%E1%84%8C%E1%85%A1%E1%84%8B%E1%85%B5%E1%86%AF-%E1%84%80%E1%85%B5%E1%84%87%E1%85%A5%E1%86%B8)애자일 기법**
47 |
48 | 실질적인 코딩을 기반으로 일정한 주기에 따라 지속적으로 프로토타입을 형성하고, 필요한 요구사항을 파악하며 이에 따라 즉시 수정사항을 적용하여 결과적으로 하나의 큰 소프트웨어를 개발하는 적응형 개발 방법
49 |
50 | - **[#](https://gyoogle.dev/blog/computer-science/software-engineering/DevOps.html#%E1%84%8C%E1%85%B5%E1%84%89%E1%85%A9%E1%86%A8%E1%84%8C%E1%85%A5%E1%86%A8-%E1%84%90%E1%85%A9%E1%86%BC%E1%84%92%E1%85%A1%E1%86%B8)지속적 통합**
51 |
52 | 통합 작업을 초기부터 계속 수행해서 지속적으로 소프트웨어의 품질 제어를 적용하는 것
53 |
54 |
55 | ---
56 |
57 | ## Reference
58 |
59 | [https://m.blog.naver.com/ydot/221536323043](https://m.blog.naver.com/ydot/221536323043) (데브옵스 배경)
60 |
61 | [https://machyobe.tistory.com/entry/많은-기업들이-Devops-엔지니어를-뽑는-이유는-무엇일까](https://machyobe.tistory.com/entry/%EB%A7%8E%EC%9D%80-%EA%B8%B0%EC%97%85%EB%93%A4%EC%9D%B4-Devops-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EB%A5%BC-%EB%BD%91%EB%8A%94-%EC%9D%B4%EC%9C%A0%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C)
62 |
63 | [https://www.youtube.com/watch?v=_VEds_73Guc](https://www.youtube.com/watch?v=_VEds_73Guc)
64 |
--------------------------------------------------------------------------------
/Computer Science/Network/tcp와 Udp.md:
--------------------------------------------------------------------------------
1 | # TCP VS UDP
2 |
3 | 
4 |
5 | ## TCP와 UDP 개념 짚고 넘어가기
6 | - TCP와 UDP는 OSI 표준모델과 TCP/IP 모델의 전송계층에서 사용되는 프로토콜이다.
7 | - 전송계층은 송신자와 수신자를 연결하는 통신 서비스를 제공하고 IP에 의해 전달되는 패킷의 오류를 검사하며 재전송 요구 제어등을 담당하는 계층이다.
8 | - 쉽게 말해 데이터의 전달을 담당한다고 생각하면 된다.
9 | - **TCP와 UDP는 포트 번호를 이용하여 주소를 지정하는것과 데이터 오류검사를 위한 체크섬 존재하는 두가지 공통점을 가지고 있다.**
10 | - **그러나 정확성(TCP)을 추구할지 신속성(UDP)을 추구할지를 구분하여 나뉜다.**
11 | - 데이터를 중요하게 생각하여 확실히 주고받고 싶을 때는 TCP를 사용한다.
12 | - 신뢰성 보다 속도가 우선시라면 UDP를 사용한다.
13 |
14 | **패킷이란?: 인터넷 내에서 데이터를 보내기 위한 경로배정(라우팅)을 효율적으로 하기 위해서 데이터를 여러 개의 조각들로 나누어 전송을 하는데 이때, 이 조각을 패킷이라고 한다.**
15 |
16 | ### 🔗포트 번호를 통한 서비스 식별
17 | - TCP와 UDP는 ‘포트 번호’라는 숫자를 이용하여 컴퓨터 안의 어떤 서비스(애플리케이션)에게 데이터를 전달하면 좋은지를 식별한다.
18 | - 포트 번호는 ‘0~65535’(16비트 분)까지의 숫자로 되어 있으며, 범위에 따라 용도가 정해져 있다.
19 | - ‘0~1023’은 ‘잘 알려진 포트(well-known port)’라고 해서 웹 서버나 메일 서버 등과 같이 일반적인 서버 소프트웨어가 클라이언트의 서비스 요청을 대기할 때 사용한다.
20 | - ‘1024~49151’은 ‘등록된 포트(registered port)’로, 제조업체의 독자적인 서버 소프트웨어가 클라이언트의 서비스 요청을 대기할 때 사용한다.
21 | - ‘49152~65535’는 ‘동적 포트(dynamic port)’로, 서버가 클라이언트를 식별하기 위해 사용한다.
22 |
23 | ### 🔗TCP의 특징 및 단점
24 |
25 | #### ✔️특징
26 | - 연결형 서비스로 연결이 성공해야 통신이 가능하다.
27 | - 데이터의 경계를 구분하지 않는다.
28 | - 데이터의 전송 순서를 보장한다.
29 | - 신뢰성 있는 데이터를 전송한다.
30 | - 데이터 흐름을 제어 및 혼잡을 제어한다.
31 | - 연결의 설정과 헤제가 가능하다
32 | - UDP보다 전송 속도가 느리다.
33 |
34 | #### ✔️단점
35 | - 데이터로 보내기 전에 반드시 연결이 형성되어야 한다.
36 | - 1:1 통신만 가능하다.
37 | - 고정된 통신 선로가 최단선이 아닐경우(네트워크 길이) 상대적으로 UDP보다 데이터 전송속도가 느리다.
38 |
39 | ### 🔗UDP란?
40 | - UDP는 전송계층의 비연결 지향적 프로토콜이다.
41 | - 비연결 지향적이란 데이터를 주고받을 때 연결 절차를 거치지 않고 발신자가 일방적으로 데이터를 발신하는 방식을 의미한다.
42 | - 연결 과정이 없기 때문에 TCP보다는 빠른 전송을 할 수 있지만 데이터 전달의 신뢰성은 떨어진다.
43 |
44 |
45 |
46 |
47 | ##### ✔️특징
48 | - 비연결형 서비스로 연결 없이 통신이 가능하며 데이터그램 방식을 제공한다.
49 | - 데이터 경계를 구분한다.
50 | - 정보를 주고 받을 때 정보를 보내거나 받는다는 신호절차를 거치지 않는다.
51 | - 신뢰성 없는 데이터를 전송한다. (데이터 재전송과 데이터 순서 유지를 위한 작업을 하지 않는다.
52 | - 패킷 관리가 필요하다.
53 | - 패킷 오버헤드가 적어 네트워크 부하가 감소되는 장점을 지닌다.
54 | - 상대적으로 TCP보다 전송속도가 빠르다.
55 |
56 | **데이터그램이란?: 독립적인 관계를 갖는 패킷 단위**
57 |
58 | #### ✔️단점
59 | - 데이터의 신뢰성이 없다.
60 | - 의미있는 서버를 구축하기위해서는 일일히 패킷을 관리해주어야 한다.
61 |
62 |
63 | ### 🔗정리
64 |
65 |
66 |
67 |
68 | ## 🔗Reference
69 | - https://coding-factory.tistory.com/614
70 | - https://www.youtube.com/watch?v=ikDVGYp5dhg
71 | - https://mangkyu.tistory.com/15
72 |
--------------------------------------------------------------------------------
/Computer Science/Database/Key(키).md:
--------------------------------------------------------------------------------
1 | # Key
2 |
3 | 키(Key)는 데이터베이스에서 조건에 만족하는 튜플을 찾거나 순서대로 정렬할 때 다른 튜플들과 구별할 수 있는 유일한 기준이 되는 속성(Attribute)이다.
4 |
5 | 튜플(Tuple) : 릴레이션을 구성하는 각각의 행, 속성의 모임으로 구성된다. 파일 구조에서는 레코드와 같은 개념, 튜플의 수 = 카디널리티(Cardinality) = 기수 = 대응수.
6 |
7 | * Swift의 Collection type에 tuple은 없다(array, dictionary, set 만 있음). 튜플은 collection type과 다르게 다른 속성의 값들이 한 Tuple안에 저장 가능.
8 |
9 | 카디널리티(Cardinality) : 전체 행에 대한 특정 컬럼의 중복 수치를 나타내는 지표.
10 |
11 | 차수(degree): 한 릴레이션 안에 있는 attribute(속성)의 개수
12 |
13 | 릴레이션은 무조건 1 이상의 차수를 갖습니다. / 카디널리티는 '전체 튜플의 갯수'를 갖는 만큼 데이터 삽입이 되어있지 않은 경우, 0의 값을 가질 수 있습니다. (릴레이션과 카디널리티 차이)
14 |
15 | #### < 학생 > 릴레이션
16 | |학번|주민번호|성명|성별|
17 | |------|---|---|---|
18 | |1001|800504-1234567|홍길동|남|
19 | |1002|911005-1234568|김철수|남|
20 | |1003|940504-1234569|안영희|여|
21 | |1004|971220-1234560|아무개|여|
22 |
23 | #### < 수강 > 릴레이션
24 | |학번|과목명|
25 | |------|---|
26 | |1001|영어|
27 | |1001|전산|
28 | |1002|영어|
29 | |1003|수학|
30 | |1004|영어|
31 | |1004|전산|
32 |
33 | ## 1. 후보키(Candidate Key)
34 | - 릴레이션을 구성하는 속성들 중에서 튜플을 유일하게 식별할 수 있는 속성들의 부분집합을 의미.
35 | - 모든 릴레이션은 반드시 하나 이상의 후보키를 가져야한다.
36 | - 릴레이션에 있는 모든 튜플에 대해서 유일성과 최소성을 만족시켜야한다.
37 |
38 | * <학생> 릴레이션에서 '학번'이나 '주민번호'는 다른 레코드를 유일하게 구별할 수 있는 기본키로 사용할 수 있으므로 후보키가 될 수 있다. 즉, 기본키가 될 수 있는 키들을 후보키라고 한다.
39 |
40 | ## 2. 기본키(Primary Key)
41 | - 후보키 중에서 선택한 주키(Main Key)
42 | - 한 릴레이션에서 특정 튜플을 유일하게 구별할 수 있는 속성
43 | - Null 값을 가질 수 없다.(개체 무결성의 첫번째 조건)
44 | - 기본키로 정의된 속성에는 동일한 값이 중복되어 저장될 수 없다.(개체 무결성의 두번째 조건)
45 |
46 | * <학생> 릴레이션에는 '학번'이나 '주민번호'가 기본키가 될 수 있고, <수강> 릴레이션에는 '학번' + '과목명'으로 조합해야 기본키가 만들어 질 수 있다. 왜냐하면 <수강> 릴레이션에서는 '학번' 속성과 '과목명' 속성은 개별적으로 기본키로 사용할 수 없다. 다른 튜플들과 구별되지 않기 때문.
47 |
48 | * <학생> 릴레이션에서 '학번'을 기본키로 정의되면 이미 입력된 '1001'은 다른 튜플의 '학번'을 속성 값으로 입력할 수 없다.
49 |
50 | ## 3. 대체키(Alternate Key)
51 | - 후보키가 둘 이상일 때 기본키를 제외한 나머지 후보키들을 말한다.
52 | - 보조키라고도 한다.
53 |
54 | * <학생> 릴레이션에서 '학번'을 기본키로 정의하면 '주민번호'는 대체키가 된다.
55 |
56 | ## 4. 슈퍼키(Super Key)
57 | - 슈퍼키는 한 릴레이션 내에 있는 속성들의 집합으로 구성된 키로써, 릴레이션을 구성하는 모든 튜플 중 슈퍼키로 구성된 속성의 집합과 동일한 값은 나타내지 않는다.
58 | - 릴레이션을 구성하는 모든 튜플에 대해 유일성은 만족하지만, 최소성은 만족시키지 못한다.
59 |
60 | * <학생> 릴레이션에서는 '학번', '주민번호', '학번' + '주민번호', '학번' + '주민번호' + '성명' 등으로 슈퍼키를 구성할 수 있다. 또한 여기서 최소성을 만족시키지 못한다는 말은 '학번' + '주민번호' + '성명'이 슈퍼키인 경우 3개의 속성 조합을 통해 다른 튜플과 구별이 가능하지만, '성명' 단독적으로 슈퍼키를 사용했을 때는 구별이 가능하지 않기 때문에 최소성을 만족시키지 못한다. 즉, 뭉쳤을 경우 유일성이 생기고, 흩어지면 몇몇 속성들은 독단적으로 유일성있는 키로 사용할 수 없다. 이것을 최소성을 만족하지 못한다고 한다.
61 |
62 | ## 5. 외래키(Foreign Key)
63 | - 관계를 맺고 있는 릴레이션 R1, R2에서 릴레이션 R1이 참조하고 있는 릴레이션 R2의 기본키와 같은 R1 릴레이션의 속성
64 | - 외래키는 참조되는 릴레이션의 기본키와 대응되어 릴레이션 간에 참조 관계를 표현하는데 중요한 도구로 사용된다.
65 | - 외래키로 지정되면 참조 테이블의 기본키에 없는 값은 입력할 수 없다. (참조 무결성의 조건)
66 |
67 | * <수강> 릴레이션이 <학생> 릴레이션을 참조하고 있으므로 <학생> 릴레이션의 '학번'은 기본키이고, <수강> 릴레이션의 '학번'은 외래키이다. 즉, 각 릴레이션의 입장에서 속성은 기본키가 되기도 하고, 외래키가 되기도 한다.
68 | * <수강> 릴레이션의 '학번'에는 <학생> 릴레이션의 '학번'에 없는 값은 입력할 수 없다.
69 |
70 |
71 |
72 | # Reference
73 | https://limkydev.tistory.com/108
74 | https://zeddios.tistory.com/238
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/memory.md:
--------------------------------------------------------------------------------
1 | # 메모리(Memory)
2 |
3 | ## 메인 메모리(Main Memory, Physical Memory, 주기억장치)
4 | - CPU가 직접 접근할 수 있는 기억 장치로, 프로세스가 실행되려면 프로그램 코드를 메인 메모리에 적재해 두어야 한다.
5 | - 그런데 만약 프로그램 용량이 메인 메모리보다 크면 어떤 일이 벌어질까?
6 | - 프로그램의 크기가 전체 메모리보다 크면 전체 프로그램을 메모리에 가져오는 대신, 적당한 크기로 잘라서 가져오는데 이를 메모리 오버레이(Memory Overlay)라고 한다. 즉, 실행하는 데 필수적인 모듈만 올려놓고 나머지는 필요할 때마다 메모리에 가져와 사용하는 것이다.
7 |
8 | ## 가상 메모리(Virtual Memory)
9 | - 실제 물리 메모리 개념과 사용자의 논리 메모리 개념을 분리한 것이다.
10 | - 메모리의 공간은 한정적이므로 사용자에게 더 많은 메모리를 제공하기 위해 가상주소를 사용한다.
11 | - 메모리 관리 장치는 가상 주소를 이용해 실제 데이터가 담겨 있는 주소로 변환해 준다.
12 | - 여기서 가상 주소 공간은 하나의 프로세스가 메모리에 저장되는 논리적인 모습을 가상 메모리에 구현한 공간이며,
13 | - 가장 주소는 해당 공간을 가리키는 주소이다.
14 |
15 | ## 가상 메모리가 필요한 이유
16 | - 물리 메모리의 한계
17 | - 모든 프로그램 코드를 물리 메모리에 올릴 수가 없다.
18 | - 그렇다해서 프로그램을 교체하면서 올리면 메모리 교체 성능 문제가 발생한다.
19 |
20 | - 가상 메모리의 장점
21 | - 프로그램 용량이 실제 물리 메모리보다 커도 된다.
22 | - 전체 프로그램이 물리 메모리에 올라와 있지 않아도 된다.
23 | - 더 많은 프로그램을 동시에 실행할 수 있다.
24 | - 응답 시간은 유지
25 | - CPU 이용률과 처리율은 증가
26 | - 즉 다중 프로그래밍을 실현하기 위해 물리 메모리의 제약을 보완하고 프로세스 전체를 메모리에 올리지 않고도 실행할 수 있도록 해준다.
27 |
28 | # 주기억장치 & 보조기억장치
29 |
30 | ## 가상 메모리의 구현
31 | #### 운영체제는 물리 메모리의 제약을 갖고 있는 주기억장치를 보조하기 위해 디스크를 보조기억장치(Paging Space)로 사용한다.
32 | 
33 | #### 즉, 메인 메모리(주기억장치)와 디스크의 페이징 스페이스(보조기억장치)를 묶어 하나의 메모리처럼 동작하게 하며, 이를 통해 메인 메모리의 한계를 넘는 메모리 사용을 가능하게 하는 가상 메모리를 구현한다.
34 |
35 | # Swapping
36 | - CPU 할당 시간이 끝난 프로세스의 메모리에 보조기억장치를 내보내는 작업(Swap-out)
37 | - CPU 할당 시간이 끝난 프로세스의 메모리에 보조기억장치를 불러오는 작업(Swap-in)
38 | - Swap 작업에는 디스크 전송 시간이 돌기 때문에 메모리 공간이 부족할 때 Swapping이 이루어진다.
39 |
40 | # 메모리 관리
41 | - 다중 프로그래밍 시스템에 여러 프로세스를 수용하기 위해 주기억장치(RAM)을 동적 분할하는 메모리 관리 작업이 필요함.
42 | - 즉, 하드 디스크에 있는 프로그램을 어떻게 메인 메모리에 적재할 것인지 판단해야함
43 |
44 | ## 연속 메모리 관리
45 | #### 프로그램 전체가 하나의 커다란 공간에 연속적으로 할당되어야 한다.
46 | - 고정 분할 기법: 주기억장치가 고정된 파티션으로 분할 -> 내부 단편화 발생
47 | - 동적 분할 기법: 파티션들이 동적 생성되며 자신의 크기와 같은 파티션에 적재 -> 외부 단편화 발생
48 | #### 이렇게 연속 메모리 관리 기법을 사용할 경우, 단편화 현상이 발생한다.
49 |
50 | ## 단편화
51 | #### 기억 장치의 빈 공간 또는 자료가 여러 조각으로 나뉘는 현상이다. 프로세스들이 메모리에 적재되고 제거되는 일이 반복되면, 프로세스들이 차지하는 메모리 틈 사이에 사용하지 못할 만큼의 자유 공간이 늘어나게 된다. 이러한 단편화는 2가지로 나뉜다.
52 | - 내부 단편화
53 | - 프로세스가 사용하는 메모리 공간에 남는 부분
54 | - 프로세스가 요청한 양보다 더 많은 메모리를 할당할 때 발생하며, 메모리 분할 자유 공간과 프로세스가 사용하는 공간의 크기 차이를 의미한다.
55 | 
56 |
57 | - 외부 단편화
58 | - 메모리 공간 중 사용하지 못하게 되는 부분
59 | - 메모리 할당 및 해제 작업의 반복으로 작은 메모리가 중간 중간 존재할 수 있다. 이렇게 사용하지 않는 메모리가 존재해서 총 메모리 공간은 충분하지만 실제로 할당할 수 없는 상황이다.
60 | - 외부 단편화를 해결하기 위해 압축을 이용하여 프로세스가 사용하는 공간을 한쪽으로 몰 수 있지만, 작업 효율이 좋지는 않다.
61 | 
62 |
63 | ## 불연속 메모리 관리
64 | #### 프로그램의 일부가 서로 다른 주소 공간에 할당될 수 있는 기법이다. 앞서 봤던 단편화 문제를 해결하기 위해 제시된 기법으로, 외부 단편화 해소를 위한 페이징과 내부 단편화 해소를 위한 세그멘테이션으로 나뉜다.
65 |
66 | ## Reference
67 | - https://aeroej.tistory.com/124
68 |
--------------------------------------------------------------------------------
/Computer Science/Database/이상(Anomaly).md:
--------------------------------------------------------------------------------
1 | // 20220823
2 | // Brown
3 |
4 |
5 |
6 | # 🟠 이상 (Anomaly)
7 | ```
8 | 좋은 관계형 데이터 베이스를 설계하는 목적 중 하나가 정보의 '이상현상(Anomaly)'이 생기지 않도록 설계하는 것
9 | (정규화를 해야하는 이유는, 잘못된 테이블 설계로 인해서 이상현상이 생기기 때문이다.)
10 | ```
11 |
12 | 이상현상은, 세가지로 구성된다.
13 | 1️⃣ 갱신이상 (Modification Anomaly)
14 | - 반복된 데이터 중에 일부를 갱신할 때 데이터의 불일치가 발생하는 현상
15 | 2️⃣ 삽입이상 (Insertion Anomaly)
16 | - 불필요한 정보를 저장하지 않고서는 어떤 정보를 저장하는 것이 불가능한 현상 (내가 삽입하기 싫은 데이터도 넣어야만 할 때)
17 | 3️⃣ 삭제이상 (Deletion Anomaly)
18 | - 필요한 정보를 함께 삭제하지 않고서는 어떤 정보를 삭제하는것이 불가능한 현상
19 |
20 | **즉, 이상현상은, 데이터의 중복성에 의해서 발생되는 데이터 불일치 현상이다.**
21 |
22 | #### 예시를 살펴보자.
23 |
24 | ## 🔸 갱신이상(Modification Anomaly)
25 | 어떤 값을 업데이트 했을 때 그 속성의 다른 속성값들과의 불일치가 발생하는 현상이다.
26 |
27 | 
28 |
29 | 위와 같이 튜플의 이름을 '김소연'으로 바꿀 경우, 동일한 학번 100이라고 적혀있는 세번째 값은 그대로 '김사랑'이라고 남게되어, 불일치가 발생한다.
30 | 이것이 발생되지 않게 하려면, '김사랑'이라는 값을 모두 찾아서 수정해주어야한다.
31 |
32 | 이렇게 무슨값을 update할 때 일어나는 불일치 현상을 의미한다.
33 |
34 | ### 📝 현재 이 데이터는 무슨 문제가 있을까? 어떻게 해결할까?
35 |
36 | 지금, 해당 데이터는 2NF가 이루어지지 않은 것으로 보인다. 하나의 컬럼이 하나의 value를 갖는 1NF는 만족되었지만, 완전함수종속을 만족하지 않는 것으로 판단된다.
37 | 완전함수종속이기 위해서는, 오직 PK만이 종속적인 관계를 갖도록 만들어주어야한다.
38 |
39 | 2NF정규화를 통해 고쳐보자.
40 |
41 | 
42 |
43 | 이렇게 고쳤다. 이렇게 고침으로써, 오직 PK 만이 종속관계를 갖게되었다.
44 |
45 |
46 | ## 🔸 삽입이상(Insertion Anomaly)
47 |
48 | 내가 원하는 값만 테이블에 삽입하고 싶은데, 테이블에 필요하지 않은 필드들 때문에 원치 않는 필드까지 함께 삽입해야하는 경우이다.
49 |
50 | 
51 |
52 | 나는 1,2,3번 필드에 대한 값만 테이블에 넣고 싶은데 테이블의 필드가 4개로 구성되어있기 때문에 마지막 필드값을 무엇을 넣어야할지 결정을 못하는 것이 삽입이상이다.
53 |
54 | ### 📝 이 문제도 정규화로 해결해보자.
55 |
56 | 이것도 마찬가지로 2NF 완전 함수 종속을 만족하지 못하는 것으로 판단되었다.
57 |
58 | 
59 |
60 | 그래서 이렇게 고쳤다. 사실 Faculty와 course code가 무슨관계인지 잘 이해가 안가고, 함게 묶여지는 관계가 모호하지만, 일단 Course code를 PK로 갖는 테이블로 한번 더 분해가 가능하다.
61 | 이렇게 고치면 삽입이상이 해결된다! (빨간글씨가 삽입된 모습)
62 |
63 |
64 | ## 🔸 삭제이상 (Deletion Anomaly)
65 | 내가 원하느 ㄴ값만 테이블에서 삭제하고 싶은데, 하나의 튜플이 삭제를 원하지 않는 속성값도 갖고 있기 때문에 같이 지워져서 발생하는 문제이다.
66 |
67 | 
68 |
69 | 그림처럼 '운영체제' 82점 이라는 정보만 삭제하고 싶은데, 이렇게 삭제하게 되면 102번 학생이 이선균이라는 정보도 함께 삭제된다.
70 |
71 | ### 📝 정규화로 해결해보자.
72 | (그림의 오류: 김사랑 김소연 -> 김사랑임)
73 | 우선, 1NF는 만족하는 것으로 보이고, 2NF를 만족하는지 살펴보자. 아까 위에서 본 예제와 같다. 마찬가지로 2NF가 만족되지 않았다.
74 |
75 | 
76 |
77 | 이렇게 하게 되면, 운영체제 점수를 삭제해도, 이선균이라는 정보는 삭제되지 않는다.
78 |
79 |
80 | **## (결론) 이렇게, 이상현상은 정규화를 통해 해결할 수 있다.**
81 |
82 |
83 | # 📖 Reference
84 | - [그림과 본문 일부](https://1000hg.tistory.com/22)
85 |
86 |
87 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/Paging과 Segmentation.md:
--------------------------------------------------------------------------------
1 | # 페이징(Paging)
2 | #### 프로세스를 일정한 크기의 페이지로 분할해서 메모리에 적재하는 방식
3 | - 페이지: 고정 사이즈의 가상 메모리 내 프로세스 조각
4 | - 프레임: 페이지 크기와 같은 주 기억 장치의 메모리 조각
5 |
6 | #### 하나의 프로세스가 사용하는 메모리 공간이 연속적이어야 한다는 제약을 없애는 메모리 관리 방법이다.
7 |
8 | ## 페이징 테이블(Paging Table)
9 | 
10 | - 위 사진은 페이징 테이블의 매핑을 나타낸다.
11 | - 앞서 봤듯이, 물리 메모리는 고정 크기의 프레임으로, 가상 메미로는 고정크기의 페이지로 분리되어 있다.
12 | - 개별 페이지는 순서에 상관없이 물리 메모리에 있는 프레임에 매핑되어 저장된다.
13 |
14 | #### 즉, 모든 프로세스는 하나의 페이징 테이블을 가지고 있으며, 여기에는 메인 메모리에 적재되어 있는 페이지 번호와 해당 페이지가 위치한 메인 메모리의 시작 주소가 있다. 이를 통해 하나의 프로세스를 나눈 가상 메모리 페이지들이 각각 실제 메인 메모리의 어디 프레임에 적재되어 있는지 알아낼 수 있다.
15 |
16 | 
17 | #### 위 PMT(Page Mapping Table, 페이징 테이블)에는 P1 프로세스의 0번째 페이지가 메인 메모리의 5번째 프레임에 있는 것을 알 수 있다.
18 |
19 | ## 논리 주소와 페이지 테이블
20 | #### 앞서 메모리 관리 장치(MMU, Memory Management Unit)는 가상 주소 (논리 주소)를 이용해 실제 데이터가 담겨 있는 주소로 변환해준다고 하였다.
21 | 
22 |
23 | #### 논리 주소(Logical Address)는 과 같은 형태로 구성되는데, 이를 이용해 물리 주소로 변환해 주는 것이다.
24 |
25 | 
26 |
27 | #### 가상 주소를 물리 주소로 변환하는 전체 과정이다.
28 |
29 | ## 페이징의 장단점
30 | - 장점
31 | - 논리 메모리는 물리 메모리에 저장될 때 연속되어 저장될 필요가 없고
32 | - 물리 메모리의 남는 프레임에 적절히 배치되기 때문에 외부 단편화가 생기지 않는다.
33 |
34 | - 단점
35 | - 내부 단편화 문제가 발생할 수 있다.
36 | - 페이지 단위를 작게하면 해결할 수 있지만, 페이지 매핑 과정이 복잡해져 오히려 비효율적이다.
37 |
38 | 
39 |
40 | # 세그멘테이션(Segmentation)
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 | ## 단순 세그멘테이션
68 | - 각 프로세스는 여러 세그먼트로 나뉜다.
69 | - 내부 단편화가 생기지 않는다.
70 | - 메모리 효율을 개선한다.
71 | - 동적 분할을 통한 오버헤드가 감소한다.
72 | - 외부 단편화가 존재할 수 있다.
73 |
74 | ## 가상 메모리 페이징
75 | - 단순 페이징과 비교해 프로세스 페이지 전부를 로드할 필요가 없다.
76 | - 필요한 페이지가 있으면 나중에 자동으로 불러들인다.
77 | - 외부 단편화가 생기지 않는다.
78 | - 복잡한 메모리 관리로 오버헤드가 발생할 수 있다.
79 |
80 | ## 가상 메모리 세그멘테이션
81 | - 필요하지 않은 세그먼트들은 로드되지 않는다.
82 | - 필요한 세그먼트가 있을 때 나중에 자동으로 불러 들인다.
83 | - 내부 단편화가 생기지 않는다.
84 | - 복잡한 메모리 관리로 오버헤드가 발생할 수 있다.
85 |
86 |
87 | ## Reference
88 | - https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=qbxlvnf11&logNo=221367707105
89 |
90 |
--------------------------------------------------------------------------------
/Computer Science/Data Structure/heap(힙).md:
--------------------------------------------------------------------------------
1 | # 힙(Heap)
2 | 힙은 우선 순위 큐를 위하여 만들어진 자료구조다.
3 |
4 | ## 우선 순위 큐
5 | - 우선순위의 개념을 큐에 도입한 자료 구조.
6 | - 데이터들이 우선순위를 가지고 있고, 들어온 순서와 상관없이 우선순위가 가장 크거나 작은 데이터가 먼저 나간다.
7 | - 만약 두 원소가 같은 우선순위를 가진다면 그들은 큐에서 그들의 순서에 의해 처리된다.
8 | - *스택* - 원소들은 후입선출 순으로 처리된다.
9 | - *큐* - 원소들은 선입선출 순으로 처리된다.
10 | - 우선순위 큐는 배열, 연결리스트, 힙으로 구현이 가능하다. 이 중에서 힙(heap)으로 구현하는 것이 가장 효율적이다.
11 | : 가장 크거나 작은 자료를 찾는데 효율적인 자료구조라서.
12 |
13 |
14 |
15 |
16 | ## 힙이란?
17 | - 완전 이진 트리의 일종으로 우선순위 큐를 위하여 만들어진 자료구조이다.
18 | - 완전 이진 트리 : 마지막을 제외한 모든 노드에서 자식들이 꽉 채워진 이진트리.
19 | - 여러 개의 값들 중에서 최댓값이나 최솟값을 빠르게 찾아내도록 만들어진 자료구조이다.
20 | - 힙은 일종의 반정렬 상태(느슨한 정렬 상태)를 유지한다.
21 | : 큰 값이 상위 레벨에 있고 작은 값이 하위 레벨에 있다는 정도
22 | 간단히 말하면 부모 노드의 키 값이 자식 노드의 키 값보다 항상 큰(작은) 이진 트리를 말한다.
23 | - 힙 트리에서는 중복된 값을 허용한다. (이진 탐색 트리에서는 중복된 값을 허용하지 않는다.)
24 |
25 |
26 | ## 힙의 종류
27 |
28 | - 최대 힙(max heap)
29 | : 부모 노드의 키 값이 자식 노드의 키 값보다 크거나 같은 완전 이진 트리
30 | key(부모 노드) >= key(자식 노드)
31 | - 최소 힙(min heap)
32 | : 부모 노드의 키 값이 자식 노드의 키 값보다 작거나 같은 완전 이진 트리
33 | key(부모 노드) <= key(자식 노드)
34 | - 키값의 대소관계는 오로지 부모노드와 자식노드 간에만 성립하며, 특히 형제 사이에는 대소관계가 정해지지 않는다.
35 |
36 |
37 |
38 |
39 | ## 구현
40 | - 힙을 저장하는 표준적인 자료구조는 배열 이다.
41 | - 구현을 쉽게 하기 위하여 배열의 첫 번째 인덱스인 0은 사용되지 않는다.
42 | - 특정 위치의 노드 번호는 새로운 노드가 추가되어도 변하지 않는다. 예를 들어 루트 노드의 오른쪽 노드의 번호는 항상 3이다.
43 | - 힙에서의 부모 노드와 자식 노드의 관계
44 | - 왼쪽 자식의 인덱스 = (부모의 인덱스) * 2
45 | - 오른쪽 자식의 인덱스 = (부모의 인덱스) * 2 + 1
46 | - 부모의 인덱스 = (자식의 인덱스) / 2
47 |
48 |
49 |
50 |
51 | ## 삽입과 삭제로 깨진 힙을 재구조화하기(heapify)
52 | 최대힙의 부모노드는 항상 자식노드의 값보다 크다는 조건을 가지고 있다. 하지만 힙에서 **삽입** 또는 **삭제**가 일어나게 되면 경우에 따라 **최대힙의 조건이 깨질 수 있다.** 이러한 경우에 최대힙의 조건을 만족할 수 있게 노드들의 위치를 바꿔가며 힙을 **재구조화(heapify)** 해주어야 한다.
53 |
54 | 삽입과 삭제의 경우 모두 **연산 자체는 *O*(1)**로 작동하지만 heapify의 과정을 거치기 때문에 ***O*(*logn*)의 시간복잡도**를 가지게 된다.
55 |
56 | ### 삽입
57 | 1. 힙에 새로운 요소가 들어오면, 일단 새로운 노드를 힙의 마지막 노드에 이어서 삽입한다.
58 | 2. 새로운 노드를 부모 노드들과 교환해서 힙의 성질을 만족시킨다.
59 |
60 |
61 |
62 | ### 삭제
63 | 1. 최대 힙에서 최댓값은 루트 노드이므로 루트 노드가 삭제된다.
64 | : 최대 힙(max heap)에서 삭제 연산은 최댓값을 가진 요소를 삭제하는 것이다.
65 | 2. 삭제된 루트 노드에는 힙의 마지막 노드를 가져온다.
66 | 3. 힙을 재구성한다.
67 |
68 |
69 |
70 |
71 |
72 | ## 활용 예
73 |
74 | - 스택과 다르게 먼저 들어오는 것이 먼저 나가는 FIFO(First In First Out)의 구조를 가지고 있다.
75 | ex) 은행 번호표 : 먼저 온 손님이 먼저 서비스를 받는 것처럼.
76 | - 정해진 한 곳(Top)을 통해서 삽입, 삭제가 이루어지는 스택과 달리 큐는 한쪽 끝에선 삽입 작업이, 다른 쪽 끝에선 꺼내는 작업이 양쪽으로 이루어진다.
77 | - 가득 찬 큐에 요소를 추가하려고 할 때 `Overflow` 가 발생하고, 빈 큐에서 요소를 꺼내려고 할 때 `Underflow` 가 발생한다.
78 |
79 |
80 | ## 큐의 연산
81 | - 우선순위 큐를 구현하는데 사용한다.
82 | - 게임엔진에서 각 액터의 우선순위를 정한다.
83 | - 서버에서 많은 트래픽을 처리할 때 우선 처리해야 할 트래픽을 정한다.
84 | - 시뮬레이션 시스템
85 | - 네트워크 트래픽 제어
86 | - 운영 체제에서의 작업 스케쥴링 (우선 순위가 높은 일을 바로 조회할 수 있다.)
87 | - 수치 해석적인 계산
88 |
89 |
90 |
91 | ## 출처
92 | https://gmlwjd9405.github.io/2018/05/10/data-structure-heap.html
93 | https://ko.wikipedia.org/wiki/%ED%9E%99_(%EC%9E%90%EB%A3%8C_%EA%B5%AC%EC%A1%B0)
94 | https://velog.io/@emplam27/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-%ED%9E%99Heap
95 |
--------------------------------------------------------------------------------
/Computer Science/Computer Architecture/ARM Process.md:
--------------------------------------------------------------------------------
1 | // 220728
2 |
3 | // Seonghun Jeon (Jack)
4 |
5 |
6 |
7 | # ARM 프로세스 (ARM Process)
8 |
9 |
10 |
11 | ## 🔡 ARM을 공부하기 전에..
12 |
13 | CPU의 언어 (ex. 010101011) =! 프로그래밍 언어 (ex. 자바, 파이썬... )
14 |
15 | ISA(Instruction Set Architecture)란 하드웨어와 소프트웨어 사이의 Interface를 정의하는 것. 하드웨어와 프로그램 사이의 매개체 역할을 한다.
16 |
17 | 즉 ISA란, 프로그래밍 언어와 CPU 언어를 이어주는 매개체 역할을 한다.
18 |
19 | 프로그래밍 언어가 컴파일을 거쳐 CPU의 언어로 변환이 되어야 컴퓨터가 이를 인식할 수 있는데 이를 도와주는 대표적인 ISA 언어가 인텔, AMD에서 제작한 x86, x86-64 등이다.
20 |
21 | 인텔, AMD가 독주하던 ISA 시장에 새로운 강자로 등장한 것이 ARM.
22 |
23 | ARM은 CPU의 설계 뼈대까지만 만들어 타사에 판매하며, 설계도를 산 회사는 그 뼈대에 살을 붙여 CPU 칩을 완성시킨다.
24 |
25 | ARM은 주로 핸드폰 같은 작은 디바이스에서 쓰인다.
26 |
27 | 아이폰, 갤럭시 전부 ARM 기반
28 |
29 | 
30 |
31 | 
32 |
33 |
34 |
35 | ## 💪🏻 ARM이란?
36 |
37 | - Advanced RISC Machine의 약자
38 | - 회사 이름: 영국 반도체 기업
39 | - CPU 아키텍쳐 이름: Arm 프로세서
40 |
41 | 
42 |
43 |
44 |
45 | ## 📑 Processor 란?
46 |
47 | - 일반적으로 프로세서란, 이론적으로 메모리에 저장된 명령어들을 실행하는 유한 상태 오토마톤을 의미한다. (오토마톤: 자동적으로 정보 처리를 하는 기계. 또는, 그 추상적인 기능에 착안한 수학적 모델. 기계를 유한개의 입과 내부 상태에서 유한개의 출력을 방출하는 기구로서 다룸)
48 | - 시스템의 상태는 프로세서에 있는 레지스터의 값들과 메모리에 저장된 값들에 의해 결정된다.
49 | - 각각의 명령어는 이들의 상태 변화를 정의하며 또한 다음번에 실행될 명령어를 결정한다.
50 |
51 |
52 |
53 | ## 💪🏻 ARM Processor란?
54 |
55 | - 메모리, 인터페이스, 라디오, 시스템 온 칩, 시스템 온 모듈 등이 포함된다.
56 | - 임베디드 기기에 주로 사용되는 32bit 프로세서
57 | - RISC 아키텍처가 있는 프로세서는 일반적으로 복잡한 명령 세트 컴퓨팅(CISC) 아키텍쳐보다 적은 트랜지스터를 필요로 하여 비용, 전력소비 및 열 방출을 향상시킨다. -> 이러한 특성은 스마트폰, 랩탑, 태블릿, 기타 임베디드 시스템과 같은 가볍고 휴대가능한 배터리 전원 장치에 바람직하지만 서버와 데스크탑에도 어느정도 유용하다.
58 | - 모바일 기기 또는 IoT 디바이스에 많이 사용된다.
59 | - 스마트폰에서 CPU 역할을 하는 AP(Application Processor)가 널리 보급되며 인지도가 올랐다.
60 |
61 | 
62 |
63 | 
64 |
65 |
66 |
67 | ## 💪🏻 ARM Processor를 배워야하는 이유!
68 |
69 | - 소형 기기에서는 ARM 프로세서를 많이 사용한다.
70 | - ARM 프로세서의 기본 원리를 알면 프로그램을 CPU가 어떻게 돌리는지 정확히 파악할 수 있다.
71 | - ARM 프로세서의 원리를 제대로 파악하는 개발자들은 조금 더 안정적인 코드를 작성할 수 있다.
72 | - RTOS나 운영체제의 세부 동작 원리를 배우려면 ARM 프로세서를 알아야한다.
73 | - ARM 프로세서의 기본 원리를 알아야 스타트업이나 익셉션 코드를 작성할 수 있다.
74 |
75 |
76 |
77 | ## 😅 CISC? RISC?
78 |
79 | CISC: Complex Instruction Set Computing
80 |
81 | RISC: Reduced Instruction Set Computing
82 |
83 | CISC 프로세서는 RISC 보다 지시사항이 많음
84 |
85 | RISC의 기본적인 개념: 프로세서가 많은 작업을 수행하면 안된다. 기본 작업을 빠르게 수행하는 것이 중요하다.
86 |
87 | CISC의 기본적인 개념: 시간이 좀 더 걸리더라도 복잡한 작업이 가능해야한다.
88 |
89 | RISC에는 없는 수많은 명령어들이 CISC에는 있었기 때문에 직접 어셈블리 코드를 손으로 입력하던 옛 시대에는 CISC를 선호했다.
90 |
91 | 
92 |
93 |
94 |
95 |
96 |
97 | ### Reference
98 |
99 | < ISA >
100 |
101 | https://inyongs.tistory.com/108
102 |
103 |
104 |
105 | < ARM >
106 |
107 | https://www.youtube.com/watch?v=C_Xb5J5jVzY
108 |
109 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/프로세스주소공간.md:
--------------------------------------------------------------------------------
1 | // 22.09.07 Noel
2 |
3 |
4 |
5 | # ❤️ 프로세스 주소공간
6 |
7 |
8 |
9 | ### 🤔 프로세스란?
10 |
11 | 운영체제가 자원을 할당하는 단위
12 |
13 |
14 |
15 | ### 🤔 프로세스 주소 공간
16 |
17 | > 프로그램이 CPU에 의해 실행 -> 프로세스가 생성되고 메모리에 **프로세스 주소 공간**이 할당됨
18 |
19 | - 프로세스 주소 공간은 대략적으로 아래와 같이 생김
20 |
21 |
22 |
23 | | 구분 | 내용 |
24 | | -------------------------------------- | ------------------------------------------------------------ |
25 | | **Text(Code)영역** | - 우리가 작성하는 **소스코드**가 들어가는 부분, 즉 실행할 프로그램 코드가 저장되는 영역
- 실행 파일을 구성하는 명령어가 올라감 => **함수, 제어문, 상수 등 함수에 대한 기계어 코드**가 여기에 지정
-프로그램이 수정되면 안되므로 ReadOnly 상태로 저장 |
26 | | **Data 영역** | -프로그램의 **초기값이 있는 전역변수, 배열, 정적(Static) 변수**가 저장되는 영역
- 즉, 프로그램이 구동되는 동안 **항상 접근 가능한 변수가 저장**되는 영역
-어떤 프로그램에 전역변수, 정적 변수를 참조하는 코드가 존재한다면, 이 프로그램은 컴파일 된 후에 data 영역을 참조함
-프로그램의 시작과 함께 할당되며, 프로그램 종료 시 소멸
-실행 도중에 전역변수가 변경 될 수도 있어 이 영역은 **Read-Write**로 지정 |
27 | | **BSS 영역
(Block Stated Symbol)** | -초기값이 없는 전역변수, 배열, 정적 변수가 저장되는 영역
- 초기화 된 데이터는 Data 영역에 저장, 초기화되지않은 데이터는 BSS에 저장 |
28 | | **Stack 영역** | - 함수의 호출과 관계되는 **지역변수와 매개변수가 저장**되는 영역
- Stack 영역 값은 함수의 호출과 함께 할당되며, **함수의 호출이 완료되면 소멸**
- 원시타입의 데이터가 값과 함께 할당
-Heap 영역에 생성된 Object 타입의 데이터 참조값이 할당
-**LIFO(가장 나중에 들어간게 먼저 나옴)** 특성을 가짐
- 메모리의 높은 주소에서 낮은 주소로 할당
-컴파일 타임에 크기가 결정되기 때문에 무한히 할당할 수 없음! |
29 | | **Heap 영역** | - 런타임에 크기가 결정되는 영역
- 사용자에 의해 공간이 동적으로 할당 및 해제된다.
- 주로 참조형 데이터(ex.Class, 클로저)등의 데이터가 할당
- 메모리의 낮은 주소에서 높은 주소로 할당 |
30 |
31 |
32 |
33 |
34 |
35 | ### 🤔 그럼 각 구역의 크기는..?
36 |
37 | > 프로그램을 작성하면 Code 영역이 늘어남
38 |
39 | - **Code, Data, BSS**는 Compile time에 크기 **결정되고 이후로 변동되지 않음(고정)
**
40 |
41 | - **Stack, Heap**는 **Runtime**시에 메모리 사용이 결정, Heap는 아래로, Stack는 위로 주소값을 매김
42 |
43 | ``` 참고
44 | Stack과 Heap 영역은 사실 같은 공간을 공유함
45 | Heap이 메모리 위쪽 주소부터 할당되면 Stack는 아래쪽부터 할당되는 식❗️
46 | 그래서 각 영역이 상대 공간을 침범하는 일이 발생할 수 있는데,,,
47 | 이를 각각 Heap Overflowm, Stack overflow라고 부름
48 | ```
49 |
50 | ```요약
51 | 💡 이해를 위한 용어 설명
52 |
53 | ① 컴파일타임(Compile Time)
54 | - 프로그램을 생성하기 위해 개발자는 첫재로 소스코드를 작성하고
55 | - 작성한 코드가 컴파일이라는 과정을 통해 기계어 코드로 변환되어 실행가능한 프로그램이 되는 과정
56 |
57 |
58 | ② 런타임(Run Time)
59 | - 컴파일 과정을 마친 응용 프로그램이 사용자에 의해서 실행되며,
60 | - 이러한 응용프로그램이 동작되어지는 '때(Time)'를 의미
61 | ```
62 |
63 |
64 |
65 |
66 |
67 | #### 이렇게 구역을 나눈 이유는 뭘까?
68 |
69 | > 최대한 데이터를 공유하여 메모리 사용량을 줄이기 위함
70 |
71 | - **Code**는 같은 프로그램 자체에서 모두 같은 내용이기때문에 따로 관리하여 공유!
72 |
73 | - **Stack과 Data**를 나눈 이유는, 스택 구조의 특성과 전역변수의 활용성을 위한 것
74 |
75 | ```참고
76 | 프로그램의 함수와 지역변수는, LIFO(가장 늦게 들어간게 먼저 나옴) 특성을 가진 스택에서 실행
77 | 따라서 이 함수들 안에서 공통적으로 실행하는 '전역 변수'는 따로 지정해주면 메모리를 아낄 수 있음
78 | ```
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | 출처
89 |
90 | https://velog.io/@klm03025/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EC%A3%BC%EC%86%8C-%EA%B3%B5%EA%B0%84
91 |
92 | https://dar0m.tistory.com/258
93 |
--------------------------------------------------------------------------------
/Computer Science/Database/SQL-vs-NoSQL.md:
--------------------------------------------------------------------------------
1 | # SQL vs NoSQL
2 |
3 | SQL과 NoSQL을 비교해보고 어떤 상황에 어떤 언어를 사용하는지 알아보자
4 |
5 | ## SQL
6 |
7 | SQL을 사용하면 RDBMS에서 데이터를 저장, 수정 삭제 및 검색할 수 있다.
8 |
9 | 관계형 데이터베이스에는 핵심적인 두 가지 특징이 있다.
10 |
11 | - 데이터는 정해진 데이터 스키마에 따라 테이블에 저장된다.
12 | - 데이터는 관계를 통해 여러 테이블에 분산된다.
13 |
14 | 데이터는 테이블에 레코드로 저장되는데, 각 테이블마다 명확하게 정의된 구조가 있다. 해당 구조는 필드의 이름과 데이터 유형으로 정의된다.
15 |
16 | *스키마: 데이터베이스를 구성하는 레코드의 크기, 키(key)의 정의, 레코드와 레코드의 관계, 검색 방법 등을 정의한 것.*
17 |
18 | 따라서 스키마를 준수하지 않은 레코드는 테이블에 추가할 수 없다. 즉, 스키마를 수정하지 않는 이상은 정해진 구조에 맞는 레코드만 추가가 가능한 것이 관계형 DB의 특징 중 하나다.
19 |
20 | 또한, 데이터의 중복을 피하기 위해 '관계'를 이용한다.
21 |
22 | 
23 |
24 | 하나의 테이블에서 중복 없이 하나의 데이터만을 관리하기 때문에 다른 테이블에서 부정확한 데이터를 다룰 위험이 없어지는 장점이 있다.
25 |
26 | ### SQL 장점
27 | 1) 명확하게 정의된 스키마, 데이터 무결성 보장
28 | 2) 관계는 각 데이터를 중복없이 한번만 저장
29 |
30 | ### SQL 단점
31 | 1) SQL은 스키마가 사전에 계획되어 있기 때문에, 그대로만 데이터가 들어가야 한다. 내가 넣고 싶은데로 넣을 수가 없다. 그래서 유연하지 못하다.(NoSQL은 스키마가 없음)
32 | 2) 데이터가 여러 테이블로 분산되어 있기 때문에 Join을 이용하여야 한다.
33 | 3) 수평적 확장이 어렵다.
34 |
35 | ** 수직적확장: 서버의 사양을 올리는 확장
36 | ** 수평적확장: 여러 대의 서버를 두어 성능을 올리는 확장
37 |
38 |
39 | ## NoSQL
40 |
41 | NoSQL은 기존 SQL 서버의 복잡성과 용량을 해결하기 위해 탄생했기 때문에 데이터 용량이 더 큰 경향이 있다. SQL은 고정된 스키마를 가지고 있고 NoSQL은 유연한 스키마를 가지고 있으며, SQL 데이터베이스에는 특정 유형의 데이터만 넣을 수 있고, NoSQL에는 그런 개념이 없다.
42 |
43 | NoSQL에서는 레코드를 문서(documents)라고 부른다.
44 |
45 | 여기서 SQL과 핵심적인 차이가 있는데, SQL은 정해진 스키마를 따르지 않으면 데이터 추가가 불가능했다. 하지만 NoSQL에서는 다른 구조의 데이터를 같은 컬렉션에 추가 가능하다.
46 |
47 | 문서(documents)는 Json과 비슷한 형태로 가지고 있다. 관계형 데이터베이스처럼 여러 테이블에 나누어담지 않고, 관련 데이터를 동일한 '컬렉션'에 넣는다.
48 |
49 | 따라서 위 사진에 SQL에서 진행한 Orders, Users, Products 테이블로 나눈 것을 NoSQL에서는 Orders에 한꺼번에 포함해서 저장하게 된다.
50 |
51 | 따라서 여러 테이블에 조인할 필요없이 이미 필요한 모든 것을 갖춘 문서를 작성하는 것이 NoSQL이다.(NoSQL에는 조인이라는 개념이 없다. 조인을 잘 사용하지 않고 자주 변경되지 않는 데이터일때 NoSQL을 쓰면 상당히 효율적이다.)
52 |
53 | ### NoSQL 장점
54 | 1) 스키마가 없어서 유연하다. 언제든지 저장된 데이터를 조정하고 새로운 필드 추가가 가능하다.
55 | 2) 데이터는 애플리케이션이 필요로 하는 형식으로 저장된다. 데이터 읽어오는 속도가 빨라진다.
56 | 3) 수직 및 수평 확장이 가능해서 애플리케이션이 발생시키는 모든 읽기/쓰기 요청이 처리 가능하다.
57 |
58 | ### NoSQL 단점
59 | 1) 유연성으로 인해 데이터 구조 결정을 미루게 될 수 있다.
60 | 2) 데이터 중복을 계속 업데이트 해야 함
61 | 3) 데이터가 여러 컬렉션에 중복되어 있기 때문에 수정 시 모든 컬렉션에서 수행해야 한다.(SQL에서는 중복 데이터가 없으므로 한 번만 수행이 가능하다.)
62 |
63 |
64 | |SQL|NoSQL|
65 | |---|-----|
66 | |관계형 데이터베이스 관리 시스템|분산형 데이터베이스 관리 시스템|
67 | |수직적 확장|수평적 확장|
68 | |스키마에 의해 선정의 되어 있음|스키마가 없거나 다이나믹함(유연함)|
69 | |견고하고 단단함, 부하를 잘 견딤|SQL보다 일반적으로 빠른 경향이 있음|
70 | |역사가 깊은만큼 설치/설정이 쉬워 시간 절약됨|처음 모델링 자체가 요구되지 않아서 시간이 절약됨|
71 | |꾸준한 속도를 보여줌|때때로 응답속도가 느릴 수 있음|
72 | |여러 테이블을 조인하는 등 복잡한 쿼리 사용가능|테이블간 관계가 없어 복잡한 쿼리 사용이 부적합함|
73 |
74 |
75 | ## 사용환경
76 |
77 | **보통 Spring에서 개발할때는 MySQL(SQL), Node.js에서는 MongoDB(NoSQL)을 사용**
78 |
79 | #### SQL 데이터베이스 사용이 더 좋을 때
80 | - 관계를 맺고 있는 데이터가 자주 변경되는 애플리케이션의 경우
81 | - 변경될 여지가 없고, 명확한 스키마가 사용자와 데이터에게 중요한 경우
82 | - 복잡한 쿼리나 리포트를 만들어내야 하는 경우
83 | - 높은 부하가 예상될 경우
84 | - 데이터가 크게 쌓이게 될 여지가 별로 없는 경우
85 |
86 | #### NoSQL 데이터베이스 사용이 더 좋을 때
87 | - 정확한 데이터 구조를 알 수 없거나 변경/확장 될 수 있는 경우
88 | - 읽기를 자주 하지만, 데이터 변경은 자주 없는 경우
89 | - 데이터베이스를 수평으로 확장해야 하는 경우(막대한 양의 데이터를 다뤄야 하는 경우)
90 | - 데이터 정합성이나 일관성이 최고 우선순위가 아닌 경우
91 |
92 |
93 | ## Reference
94 | - https://dingrr.com/blog/post/%EA%B0%9C%EB%B0%9C-sql-vs-nosql-%EC%96%B8%EC%A0%9C-%EB%AC%B4%EC%97%87%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C
95 | - https://gyoogle.dev/blog/computer-science/data-base/SQL%20&%20NOSQL.html
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/Computer Science/Network/tcp3 & 4way(전송제어프로그램).md:
--------------------------------------------------------------------------------
1 | ## TCP N-way Handshake 를 들어가기 전에
2 | #### 포트 상태 정보
3 | - CLOSED: 포트가 닫힌 상태
4 | - LISTEN: 포트가 열린 상태로 연결 요청 대기중
5 | - SYN_RCV: SYNC 요청을 받고 상대방의 응답을 기다리는 중
6 | - ESTABLISHED: 포트 연결 상태
7 |
8 | #### 플래그 정보
9 | - TCP Header에는 CONTROL BIT(플래그 비트, 6bit)가 존재하며, 각각의 bit는 "URG-ACK-PSH-RST-SYN-FIN"의 의미를 가진다.
10 | - 즉, 해당 위치의 bit가 1이면 해당 패킷이 어떠한 내용을 담고 있는 패킷인지를 나타낸다.
11 | - SYN(Synchronize Sequence Number) / 000010
12 | - 연결 설정. Sequence Number를 랜덤으로 설정하여 세션을 연결하는데 사용하며, 초기에 Sequence Number를 전송한다.
13 | - ACK(Acknowledgement) / 010000
14 | - 응답 확인. 패킷을 받았다는 것을 의미한다.
15 | - Acknowlegement Number 필드가 유효한지를 나타낸다.
16 | - 양단 프로세스가 쉬지 않고 데이터를 전송한다고 가정하면 최초 연결 설정 과정에서 전송되는 첫 번째 세그먼트를 제외한 모든 세그먼트의 ACK 비트는 1로 지정된다고 생각할 수 있다.
17 | - FIN(Finish) / 000001
18 | - 연결 해제. 세션 연결을 종료시킬 때 사용되며, 더 이상 전송할 데이터가 없음을 의미한다.
19 |
20 | ## TCP 3way Handshake이란?
21 | #### TCP 3 Way Handshake는 TCP/IP 프로토콜을 이용해서 통신을 하는 응용프로그램이 데이터를 전송하기 전에 먼저 정확한 전송을 보장하기 위해 상대방 컴퓨터와 사전에 세션을 수립하는 과정을 의미한다.
22 | - Client > Server: TCP SYN
23 | - Server > Client: TCP SYN ACK
24 | - Client > Server: TCP ACK
25 |
26 | ## TCP 3way Handshaking 역할 (Connection Establish)
27 | - 양쪽 모두 데이터를 전송할 준비가 되었다는 것을 보장하고, 실제로 데이터 전달이 시작하기 전에 한쪽이 다른 쪽이 준비되었다는 것을 알 수 있도록 한다.
28 | - 양쪽 모두 상대편에 대한 초기 순차일련번호를 얻을 수 있도록 한다.
29 |
30 | ### TCP 3way Handshaking 과정
31 | 
32 |
33 | [Step1]
34 | - 클라이언트는 서버에 접속을 요청하는 SYN 패킷을 보낸다. 이때 클라이언트 는 SYN을 보내고 SYN/ACK 응답을 기다리는 SYN_SENT 상태가 된다.
35 |
36 | [Step2]
37 | - 서버는 SYN요청을 받고 클라이언트에게 요청을 수락한다는 ACK와 SYN flag가 설정된 패킷을 발송하고 클라이언트가 다시 ACK로 응답하기를 기다린다. 이때 서버는 SYN_RECEIVED 상태가 된다.
38 |
39 | [Step3]
40 | - 클라이언트는 서버에게 ACK를 보내고 이후로부터는 연결이 이루어지고 데이터가 오가게 되는 것이다. 이때의 B서버 상태가 ESTABLISHED이다.
41 |
42 |
43 | 위와 같은 방식으로 통신하는 것이 신뢰성 있는 연결을 맺어준다는 TCP의 3 Way Handshake 방식이다.
44 |
45 |
46 | ## TCP 4way Handshaking 역할 (Connection Termination)
47 | - 3way Handshake가 TCP의 연결을 초기화 할 때 사용한다면, 4way Handshake는 세션을 종료하기 위해 수행되는 절차이다.
48 |
49 | ### TCP 4way Handshaking 과정
50 | 
51 |
52 | [Step1]
53 | - 클라이언트가 연결을 종료하겠다는 FIN 플래그를 전송한다.
54 |
55 | [Step2]
56 | - 일단 확인메시지를 보내고 자신의 통신이 끝날때까지 기다리는데 이 상태가 TIME_WAIT 상태다.
57 |
58 | [Step3]
59 | - 서버가 통신이 끝났으면 연결이 종료되었다고 클라이언트에게 FIN 플래그를 전송한다.
60 |
61 | [Step4]
62 | - 클라이언트는 확인했다는 메시지를 보낸다.
63 | - 그런데 만약 서버에서 FIN을 전송하기 전에 전송한 패킷이 Routing 지연이나 패킷 유실로 인한 재전송 등으로 인해 FIN 패킷보다 늦게 도착하는 상황이 발생한다면 어떻게 될까?
64 | - 클라이언트에서 세션을 종료시킨 후 뒤늦게 도착하는 패킷이 있다면 이 패킷은 Drop되고 데이터는 유실될 것이다. 이러한 현상에 대비하여 클라이언트는 서버로부터 FIN을 수신하더라도 일정시간(디폴트 240초) 동안 세션을 남겨놓고 잉여 패킷을 기다리는 과정을 거치게 된다.
65 | - 이를 TIME_WAIT이라고 한다.
66 |
67 | +)
68 |
69 | - Q. TCP의 연결 설정 과정(3단계)과 연결 종료 과정(4단계)이 단계가 차이나는 이유?
70 | - A. 클라이언트가 데이터 전송을 마쳤다고 하더라도 서버는 아직 보낼 데이터가 남아있을 수 있기 때문에 일단 FIN에 대한 ACK만 보내고, 데이터를 모두 전송한 후에 자신도 FIN 메시지를 보내기 때문.
71 |
72 | - Q. 초기 Sequence Number인 ISN을 0부터 시작하지 않고 난수를 생성해서 설정하는 이유?
73 | - A. Connection을 맺을 때 사용하는 포트(Port)는 유한 범위 내에서 사용하고 시간이 지남에 따라 재사용된다. 따라서 두 통신 호스트가 과거에 사용된 포트 번호 쌍을 사용하는 가능성이 존재한다. 서버 측에서는 패킷의 SYN을 보고 패킷을 구분하게 되는데 난수가 아닌 순차적인 Number가 전송된다면 이전의 Connection으로부터의 오는 패킷으로 인식할 수 있다. 이런 문제가 발생할 가능성을 줄이기 위해서 난수로 ISN을 설정한다.
74 |
75 |
76 |
77 |
78 |
79 |
80 | ## Reference
81 | - https://mindnet.tistory.com/entry/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%89%BD%EA%B2%8C-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-22%ED%8E%B8-TCP-3-WayHandshake-4-WayHandshake
82 | - https://velog.io/@averycode/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-TCPUDP%EC%99%80-3-Way-Handshake4-Way-Handshake
83 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/Computer Science/Network/TLS, SSL.md:
--------------------------------------------------------------------------------
1 | // 20220830
2 | // Brown
3 |
4 |
5 |
6 |
7 | # ✅ SSL과 TLS의 차이
8 | 밑에 글을 읽다보면 아시다시피, SSL/TLS는 같은 역할을 하는 프로토콜입니다.
9 | 가장 최신버전인 SSL3.0은 2015년에 사용이 종료되면서 TLS와의 혼란을 없앴다.
10 | TLS는 1.0버전은 1999년 IETF에서 개발했지만, 사실상 SSL3.1 버전이나 마찬가지입니다. 지금은 TLS1.3까지 나온 상태고, 그것을 사용중이다!
11 |
12 |
13 | # 🟠 SSL (Secure Socket Layer)
14 | 원래 웹에서 데이터는 가로채면 누구나 읽을 수 있는 일반 텍스트 형태로 전송되었다. 이러한 문제 때문에 인터넷 통신의 개인정보보호, 인증, 데이터 무결성을 보장하기 위해 Netscape가 1995년 처음으로 SSL을 개발하였다.
15 |
16 | SSL/TLS를 사용하는 웹사이트의 URL은 ```HTTP``` 대신 ```HTTPS```가 사용된다.
17 |
18 | 
19 |
20 | SSL은 1996년 SSL3.0 이후 업데이트 되지 않았으며, 앞으로 사라지게 될것이라고 여겨지고 있다.(😱) 또한 알려진 취약성이 여러가지 있으며, 보안 전문가들은 SSL 사용중단을 권장한다고 한다. 그 대안으로 앞에서 언급한 TLS가 있다.
21 |
22 | TLS는 최신 암호화 프로토콜로, SSL 암호화로 혼용해서 부르는 경우도 많다. 실제로 현재 SSL을 인증한 업체 및 제공하는 업체는 사실상 TLS 암호화를 제공하고 있다. (HTTPS는 특정 프로토콜이 정해져 있지 않고, TLS, SSL이라고 불리는 프로토콜이 만들어주는 안전한 연결방법을 사용하고 이를 기반으로 통신한다. 그래서 혼용해서 쓴다고 하는것이다.)
23 |
24 |
25 | # 🟠 TLS (Transport Layer Security)
26 | TLS는 SSL의 업데이트 버젼으로, SSL의 최종버전인 SSL3.0과 TLS의 최초버전은 큰 차이는 없다. 이름이 바뀐 것은 SSL 초기 개발사 Netscape가 업데이트에 참여하지 않게 되어 소유권을 변경하기 위해서 바꿨다고 한다. (🤔 차이점이 고작 이건가?)
27 |
28 | SSL/TLS는 클라이언트와 서버간의 핸드셰이크를 통해 인증이 이루어진다. 또한 데이터 무결성을 위해 데이터에 디지털 서명을 하여, 데이터가 의도적으로 도착하기 전에 조작된 여부를 확인한다.
29 |
30 |
31 | # 🟠 SSL과 TLS의 역할
32 | - 인증이나 암호키 교환
33 | - 정보의 암호화에 사용하는 각 알고리즘(처리방법)을 여러개 중 선택해서 사용한다.
34 | - 어떤 알고리즘을 선택하는 가는, 통신의 초기 단계에서 서버와 클라이언트가 서로 대화하여 서로가 공통적으로 대응할 수 있는 것을 선택한다.
35 | - SSL/TLS의 주요 역할은 다음과 같다.
36 | - 암호화: 도청되더라도 내용을 알 수 없도록 암호화한다.
37 | - 인증: 올바른 대상인지 확인한다.
38 | - 조작검사: 내용이 조작되었는지 확인한다.
39 |
40 | ```
41 | SSL/TLS는 안전한 보안 채널을 형성해주는 역할을 수행하는 보안용 프로토콜이라고 이해하자.
42 | ```
43 |
44 | ## 🔸 SSL/TLS의 위치
45 | SSL/TLS는 응용계층(HTTP)와 전송계층(TCP)사이에 존재한다.
46 |
47 | 
48 |
49 |
50 | ## 🔸 SSL/TLS 핸드셰이크
51 | ```
52 | 핸드셰이크는 클라이언트와 서버의 메시지 교환이며, HTTPS웹에 처음 커넥션할 때 진행된다.
53 | 일반적으로 RSA 키 교환 알고리즘이 사용된다.
54 | ```
55 |
56 | ### 👉 RSA 키 교환 알고리즘 순서
57 |
58 | 
59 |
60 | 1. 클라이언트 → 서버에 메세지 전송: 이때 핸드셰이크가 시작된다. 이 메세지에는 TLS버전, 암호화 알고리즘, 무작위 바이트 문자열이 포함된다.
61 | 2. 서버 → 클라이언트 메세지 전송: 클라이언트의 메세지에 응답으로 서버의 SSL인증서ㅓ, 선태한 암호화 알고리즘, 서버에서 생성한 무작위 바이트 문자열을 포함한 메세지를 전송한다.
62 | 3. 인증: 클라이언트가 서버의 SSL인증서가 믿을만한지 확인한다.
63 | 4. 예비 마스터 암호: 클라이언트는 무작위 바이트 문자열을 공개키로 암호화된 premater secret 키를 서버로 전송한다.
64 | 5. 개인키 사용: 서버가 premaster secret값을 개인키를 통해 복호화한다. (개인키로만 복호화가능)
65 | 6. 세션키 생성: 클라이언트와 서버는 클라이언트가 생성한 무작위키, 서버가 생성한 무작위키, premaster secret키를 통해 세션키를 생성한다. 양쪽은 같은키가 생성되어야한다.
66 | 7. 클라이언트 완료 전송: 클라이언트는 세션키로 암호화된 완료 메세지를 전송한다.
67 | 8. 서버 완료 전송: 서버도 세션키로 암호화된 완료 메세지를 전송한다.
68 | 9. 핸드셰이크 완료: 핸드셰이크가 완료되고, 세션키를 이용해 HTTPS 통신을 진행한다.
69 |
70 | ```
71 | 🤔 왜 알아야 하는가?
72 | 대부분의 클라우드 서비스들은 HTTPS를 사용하여 스토리지 파일 업로드/다운로드, DB의 CRUD작업, 미디어 서비스의 스트리밍 작업, REST API 호출 등을 하기 때문에 HTTPS의 적용 방법을 이해하기 위한 SSL 핸드셰이크는 매우 중요한 지식이다.
73 | ```
74 |
75 | ## 🔸 SSL/TLS 인증서
76 | SSL은 SSL/TLS인증서가 있는 웹페이지만 실행할 수 있다. 인증서는 사람의 신분증과 유사하다고 볼 수 있다.
77 | SSL인증서(=TLS인증서)에는 공개키가 포함된다. 이 공개키 덕분에 암호화가 가능하게 된다. 클라이언트의 요청은 공개키를 이용해 서버에 암호화하여 전달한다. 서버에도 공개되지 않은 개인키가 있는데, 이 개인키를 이용해 암호화된 데이터를 복호화한다.
78 |
79 | 해당 인증서를 발급해주는 기관은 CA(certificate authority)라고 한다.
80 |
81 |
82 |
83 | ## 📖 Reference
84 | - [SSL 핸드셰이크, 개념 출처](https://kanoos-stu.tistory.com/46)
85 | - [SSL 핸드셰이크 사진 출처](https://brunch.co.kr/@sangjinkang/38)
86 | - [SSL/TLS역할 개념 참고](https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=hai0416&logNo=221623579719)
87 | - [SSL/TLS 차이점 (만화)](https://howhttps.works/ko/https-ssl-tls-differences/)
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/Computer Science/Data Structure/hash(해시).md:
--------------------------------------------------------------------------------
1 | # 해시(Hash) 자료구조
2 | - 키(Key)와 값(Value) 쌍으로 이루어진 데이터 구조.
3 | - 해시 구조에서는 Key를 이용하여 데이터(value)를 빠르게 찾을 수 있는 장점이 있다.
4 |
5 | ## 용어
6 | - **키 (Key)** : 해시 함수의 input 이 되는 고유한 값. 키(key)는 해시함수(hash function)를 통해 해시(hash)로 변경되어 value 값과 매칭되어 저장소에 저장된다.
7 | - **해시 (Hash)** : 임의의 값을 고정 길이로 변환하는 것. *key 값 그대로 저장소에 저장되게 되면 다양한 길이의 저장소를 구성해야하기 때문에 효율성을 위해 일관적으로 해시(hash)로 변경하여 저장함으로써 공간 효율성을 최적화한다.*.
8 | - **해시 테이블 (Hash Table)** : Key 값의 연산에 의해 직접 접근이 가능한 데이터 구조.
9 | - **버킷 (Bucket), 슬롯 (Slot)** : Hash table 에서 하나의 데이터가 저장되는 공간.
10 | - **해시 함수 (Hashing Function)** : Key 값에 대해 연산을 통해 데이터(value) 위치를 찾는 함수.
11 | - **Hash Value, Hask Address** : Key 값을 이용해 Hashing function 을 연산하여 Value 를 알아낼 수 있고, 이를 기반으로 Hash table 에서 해당 key 에 대한 데이터 위치(주소)를 찾을 수 있음.
12 |
13 |
14 |
15 |
16 |
17 |
18 | ## 해시 함수
19 | - 데이터의 효율적 관리를 목적으로 임의의 길이를 갖는 임의의 데이터를 고정된 길이의 데이터로 매핑하는 함수.
20 | - Key를 Hash로 바꿔 메모리를 효율적으로 관리하도록 함. 빠른 연산 속도가 특징.
21 | - 매핑 전 원래 데이터의 값 : **키(Key)**
22 | 매핑 후 데이터의 값 : **해시값(Hashvalue)**
23 | 매핑하는 과정 : **해싱(Hashing)**.
24 |
25 |
26 | ## 해시테이블(Hashtable)
27 | - (Key, Value)로 데이터를 저장하는 자료구조.
28 | - 각각의 Key에 해시함수를 사용 → key를 해시값으로 매핑 → 배열의 고유한 Index or 주소를 생성 → 데이터의 값(Value)를 key와 함께 저장.
29 | - Key값으로 데이터를 찾을 때 해시 함수를 1번만 수행하면 되기 때문에 저장/삭제/조회시 매우 빠름.
30 | - 해시함수는 해쉬값의 개수보다 대개 많은 키값을 해쉬값으로 변환(many-to-one 대응)하기 때문에 해시함수가 서로 다른 두 개의 키에 대해 동일한 해시값을 내는 해시충돌(collision)이 발생하게 됨.
31 |
32 |
33 | ## 해시충돌 해결
34 | ### Chaining
35 | 버켓 내에 연결 리스트를 할당하여, 버켓에 데이터를 삽입하다가 해시 충돌이 발생하면 연결 리스트로 데이터들을 연결하는 방식.
36 |
37 | - 장점
38 | - 한정된 저장소(Bucket)을 효율적으로 사용할 수 있다.
39 | - 해시 함수를 선택할 때 hash collision을 걱정하지 않아도 된다.
40 | - 상대적으로 적은 메모리를 사용한다. (미리 공간을 잡을 필요가 없다.)
41 | - 단점
42 | - 한 Hash에 자료들이 계속 연결된다면 쏠림 현상으로 검색 효율을 낮출 수 있다.
43 | - 외부 저장 공간을 사용
44 |
45 |
46 | ### 개방 주소법(Open Addressing)
47 | 체이닝의 경우 버켓이 꽉 차더라도 연결 리스트로 계속 늘려가기에 데이터의 주소값은 바뀌지 않는다.(Closed Addressing)
48 |
49 | 하지만 개방 주소법은 충돌이 일어나면 다른 버켓에 데이터를 삽입하는 방식이다. 개방 주소법은 대표적으로 3가지가 있다.
50 |
51 | 1. 선형 탐색(Linear Probing) : 해시충돌 시 다음 버켓, 혹은 몇개를 건너뛰어 데이터를 삽입한다.
52 | 2. 제곱 탐색(Quadratic Probing) : 해시충돌 시 제곱만큼 건너뛴 버켓에 데이터를 삽입한다.
53 | 3. 이중 해시(Double Hashing) : 해시충돌 시 다른 해시함수를 한번 더 적용한 결과를 이용한다.
54 | - 장점
55 | - 추가 저장 공간이 필요 없다.
56 | - 단점
57 | - 해시 함수의 성능에 전체 해시테이블의 성능이 좌지우지된다.
58 | - 데이터 길이가 늘어나면 그에 해당하는 저장소를 마련해야한다.
59 |
60 |
61 | ## 해시의 장점
62 | 1. 적은 리소스로 많은 데이터를 효율적으로 관리.
63 | 해시함수로 하드디스크나 클라우드에 존재하는 무한에 가까운 데이터(key)들을 유한한 개수의 해시값으로 매핑함으로써 작은 크기의 캐쉬 메모리로도 프로세스를 관리할 수 있음.
64 | 2. index에 해시값을 사용함으로써 모든 데이터를 살피지 않아도 검색과 삽입/삭제를 빠르게 수행할 수 있음.
65 | 3. 해시함수는 언제나 동일한 해시값을 리턴하고, 해당 인덱스만 알면 해시테이블의 크기에 상관없이 데이터에 빠르게 접근할 수 있으며, 인덱스 계산이 간단한 함수로 작동하기 때문에 매우 효율적.
66 | 4. 해시는 보안 분야에서도 널리 사용. 키와 해시값 사이에 직접적인 연관이 없기 때문에 해시값만 가지고는 키를 온전히 복원하기 어렵기 때문. 값을 해시로 변환하면, 기존의 값을 알아볼 수 없다.
67 | 5. 해시함수는 길이가 서로 다른 입력데이터에 대해 일정한 길이의 출력을 만들 수 있어서 ‘데이터 축약’ 기능도 수행할 수 있음.
68 |
69 |
70 | ## Swift에서
71 | - 스위프트에서 `Dictionary의 키와 Set`로 사용되기 위해서는 해당 타입은 반드시 `Hashable 프로토콜`을 준수해야 함 ⇒ 그래서 String, Int, Boolean 타입과 같은 `Standard Library`에 속한 많은 타입들은 Hashable 프로토콜을 준수함. 사용자가 만든 타입도 Hashable 프로토콜을 준수한다면 딕셔너리의 키나 세트로 사용이 가능.
72 | [https://baked-corn.tistory.com/123](https://baked-corn.tistory.com/123)
73 | - 사용자 정의 타입을 딕셔너리의 키나 세트에서 사용하기 위해서는 `Hashable` 프로토콜을 준수해야 함. `Hashable` 프로토콜은 `Equatable` 프로토콜을 상속 받음. 그렇기 때문에 이 두 프로토콜의 요구 사항을 모두 충족시켜야 함.
74 | 사용자 정의 타입은 선언부에 `Hashable`을 작성해주어 해당 프로토콜을 준수한다 명시하고
75 | 만일 해당 타입이 **구조체**라면 **저장 프로퍼티의 타입**들이 모두 Hashable 프로토콜을 준수해야 하고
76 | **열거형**이라면 **연관 값의 타입**이 Hashable 프로토콜을 준수해야 합니다.
77 | - **Hashable 프로토콜을 준수하는 모든 타입의 인스턴스는 hashValue 라는 정수형 프로퍼티를 갖고 있으며 이 값은 각각의 인스턴스를 식별하는 값이 됨. 그렇기 때문에 반드시 하나만 존재해야 하는 딕셔너리의 키값이나 중복된 값은 허용하지 않는 자료구조인 세트에 들어가는 값들은 Hashable해야 한다는 것.**
78 |
79 |
80 |
81 | ## 출처
82 | https://ratsgo.github.io/data%20structure&algorithm/2017/10/25/hash/
83 | https://preamtree.tistory.com/20
84 | https://dean30.tistory.com/113
85 |
--------------------------------------------------------------------------------
/Design Pattern/factoryMethod.md:
--------------------------------------------------------------------------------
1 | # Factory Method
2 | ## 🏭 Factory Method란?
3 | ##### 객체를 만들기 위한 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 하위 클래스가 정하도록 하는 방법.
4 | ##### 간단하게 말해서 객체 생성을 서브 클래스가 하도록 처리하는 패턴.
5 |
6 | ##### 즉, 객체 생성을 캡슐화할 수 있으며 이로 인해 부모 클래스는 자식 클래스가 어떤 객체를 생성하는지 몰라도 된다.
7 |
8 |
9 |
10 | ##### 팩토리 메서드 패턴은 위와 같은 구조를 갖는다.
11 | - Product
12 | - Creator와 하위 클래스가 생성할 수 있는 모든 객체에 동일한 인터페이스를 선언.
13 | - Concrete Product
14 | - Product가 선언한 인터페이스로 만든 실제 객체.
15 | - Creator
16 | - 새로운 객체를 반환하는 팩토리 메서드를 선언.
17 | - 여기서 반환하는 객체는 Product 인터페이스를 준수하고 있어야 함.
18 | - Concrete Creator
19 | - 기본 팩토리 메서드를 override 하여 서로 다른 Product 객체를 만든다.
20 |
21 | > 즉, 팩토리 메서드 패턴은 객체를 만드는 Factory를 만드는 패턴이라고 할 수 있음.
22 |
23 | ## 🏭 Factory Method는 언제 쓰나?
24 | ##### 팩토리 메서드 패턴을 사용하는 예를 들어볼게요. 예를 들어 음악 재생 앱을 만들었다고 해보겠습니다. 처음 앱을 만들 땐 MusicPlayer라는 객체를 통해 음악만 재생 가능한 앱을 만들었는데, 앱이 잘 팔려서 비디오도 넣어야 하는 상황이 된거예요. 현재 음악만 재생할 수 있도록 만든 MusicPlayer만 있었기 때문에 만약 VideoPlayer를 추가하려고 한다면 코드 전체를 수정해야합니다. 또한 나중에 VR Player, AR Player 등과 같은 기능들이 추가된다면 추가 될 때 마다 코드 전체를 수정해야하는 문제가 생기겠죠?
25 | ##### 이럴 때 사용할 수 있는 패턴이 팩토리 메서드 패턴입니다. 객체를 직접 만드는 것이 아닌 팩토리 메서드를 통해서 만드는 거에요. 아까의 예로 다시 돌아가 보면, MusicPlayer가 필요한 곳에서는 MusicPlayer를 생성하는 메서드를 호출하고 VideoPlayer가 필요한 곳에서는 VideoPlayer를 생성하는 메서드를 호출하는 거죠.
26 | ##### 이렇게 된다면 새로운 유형의 Player를 만들어야 한다고 하더라도 팩토리 부분에 메서드를 추가해서 간단하게 처리할 수 있습니다. 하지만 각각의 Player들은 서로 다른 콘텐츠를 취급하더라도 궁극적인 기능은 같기 때문에 동일한 인터페이스를 사용해야 할 거예요.
27 |
28 | > 새로운 기능이 추가되더라도 팩토리 메서드를 사용하여 새로운 객체를 만들 수 있음
29 |
30 | > 기존 객체에 수정이 생기더라도 팩토리 메서드만 수정하면 됨
31 |
32 |
33 | ## 🔡 예제
34 | ##### 그럼 실제로 팩토리 메서드 패턴을 간단한 에제를 통해 사용해보도록 하겠습니다.
35 | ##### 아까 예로 들었던 음악, 비디오 앱에 사용할 플레이어 객체를 만드는 것을 Swift 언어로 간단하게 만들어보겠습니다.
36 |
37 | > 일단 Product에 해당하는 Player 프로토콜부터 만들어 볼게요
38 | ```
39 | protocol Player {
40 | var content: String { get set }
41 | init(content: String)
42 | func play()
43 | func pause()
44 | func changeContent(name: String)
45 | }
46 | ```
47 |
48 | > 이렇게 만들어진 프로토콜을 채택하는 Concrete Product들이 바로 MusicPlayer, VideoPlayer겠죠?
49 | ```
50 | class MusicPlayer: Player {
51 | var content: String
52 | required init(content: String) {
53 | self.content = content
54 | }
55 |
56 | func play() {
57 | print("MusicPlayer Play")
58 | }
59 |
60 | func pause() {
61 | print("MusicPlayer Pause")
62 | }
63 |
64 | func changeContent(name: String) {
65 | print("\(self.content)에서 \(name)로 음악 변경")
66 | self.content = name
67 | }
68 | }
69 |
70 | class VideoPlayer: Player {
71 | var content: String
72 | required init(content: String) {
73 | self.content = content
74 | }
75 |
76 | func play() {
77 | print("VideoPlayer Play")
78 | }
79 |
80 | func pause() {
81 | print("VideoPlayer Pause")
82 | }
83 |
84 | func changeContent(name: String) {
85 | print("\(self.content)에서 \(name)로 비디오 변경")
86 | self.content = name
87 | }
88 | }
89 | ```
90 | > 그럼 이젠 Creator를 만들어야 합니다. Creator는 특정 프로토콜을 채택한 객체만 반환할 수 있으니 지금 예제에서는 Player 프로토콜을 재책한 객체들을 반화하면 됩니다.
91 | > 그리고 Music, Video를 구분하기 위해 열거형을 하나 정의 합니다.
92 | ```
93 | protocol PlayerCreator {
94 | func createPlayer(content: String, contentType: ContentType) -> Player
95 | }
96 |
97 | enum ContentType {
98 | case music
99 | case video
100 | }
101 | ```
102 | > 이렇게 만들었다면 이제 Player 객체를 만들 때 Factory 객체를 통해서 만들면 됩니다.
103 |
104 |
105 |
106 | ##### 이렇게 손쉽게 서로 다른 Player를 만들어서 사용할 수 있게 되었습니다. 만약 다른 Player를 추가하고 싶다면 위의 코드는 전혀 수정할 필요없이 팩토리 부분만 수정해주면 됩니다.
107 | ##### 만약 어떤 프로그램에서 100개의 플레이어를 사용한다고 한다면, 100번을 수정할 필요없이 팩토리 부분만 수정하면 되도록 해주는 패턴이 팩토리 메서드 패턴입니다.
108 |
109 | ## Reference
110 | - https://icksw.tistory.com/237
111 | - https://velog.io/@ryan-son/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-Factory-pattern-in-Swift
112 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/IPC.md:
--------------------------------------------------------------------------------
1 | // 20220907
2 |
3 | // Brown
4 |
5 | # 🟠 IPC (Inter Process Communication)
6 |
7 | 
8 |
9 | - 위 사진처럼 프로세스는 각자 독립된 메모리 공간을 가지고 있어서 서로간의 데이터를 공유할 방법이 없다.
10 | - 그렇기 때문에 나온 방식이 IPC로 프로세스 간 통신을 하는 방법이다.
11 | - 프로세스간 통신이란, 프로세스 간의 데이터 송수신이 있다는 뜻이고, 메모리를 공유해야 한다는 뜻이다. 이러기 위해서는 '통신을 위한 도구'가 필요하다. == IPC
12 |
13 | ```
14 | 즉 IPC 란, 프로세스 간의 통신을 가능하게 해주는 통신 방법이다
15 | ```
16 |
17 | 프로세스는 Kernel(커널)이 제공하는 IPC설비를 이용하여 프로세스간에 통신을 할 수 있게 된다.
18 |
19 | ### 📝 커널이란?
20 |
21 | 운영체제 중 항상 필요한 부분만을 전원이 켜짐과 동시에 메모리에 올려놓고, 그렇지 않은 부분은 필요할 때 메모리에 올려서 사용하게 되는데, 이때 메모리에 상주하는 운영체제들을 Kernel 이라고 한다. 보통 Kernel 이라고 칭하면, 가장 중요한 '운영체제들'이라고 생각하면 편하다.
22 |
23 | # 🟠 IPC 종류
24 |
25 | IPC종류에도 여러가지가 있다. 필요에 따라 IPC 통신 방식을 선택해서 잘 사용해야 한다. IPC는 아래와 같이 분류할 수 있다
26 |
27 | 
28 |
29 | ```
30 | 메시지 전달 시스템
31 | 공유 메모리 시스템
32 | ```
33 |
34 | ## 🔸 메시지 전달 시스템
35 | - 커널을 경유하여 고정 길이 메시지, 가변길이 메시지를 송/수신자 끼리 주고받으며, 커널에서는 데이터를 버퍼링한다.
36 | - 프로세스간 메모리 공유 없이 동작이 가능하다..
37 | - 서버-클라이언트 방식의 통신이 메시지 전달 시스템의 가장 대표적인 예시라고 보면 된다.
38 | - 메시지 전달 모델에서 iPC는 해당 프로세스 입장에서 일종의 I/O로 볼 수 있다. 그래서 IPC를 하면 할 수록 컨텍스트 스위칭이 많이 일어난다.
39 |
40 | ### 👉 메시지 전달 모델의 구현 IPC 종류
41 |
42 | ```
43 | PIPE
44 | Message Queue
45 | Socket 등
46 | ```
47 |
48 | ### 🥕 PIPE (익명 PIPE)
49 |
50 | 
51 |
52 | - 공유 매개체는 '파일'이다.
53 | - 부모 프로세스와 자식 프로세스 간 통신을 할 때 사용한다.
54 | - 해당 방식의 목적은 fork() 를 사용하여 부모, 자식 프로세스를 만들어 각 프로세스를 각 코어에 동시 실행이 가능하게 하여 빠른 실행을 하기 위함. 즉 병렬 처리를 하여 빠른 프로그램 실행이 목적이다.
55 | - 익명 PIPE는 하나의 프로세스는 데이터를 쓰기만, 다른 하나는 읽기만 가능하다.
56 | - 한쪽 방향으로만 통신이 가능하기 때문에 Half-Duplex(반이중) 통신 이라고 부른다. (이는 PIPE두개를 사용해서 양방향으로 만들 수 있지만, 구현이 매우 복잡해질 수 있다.)
57 | - 통신을 할 프로세스가 뭔지 명확하게 알 수 있는 경우 사용한다.
58 | - 구현이 매우 간단하다는 장점이 있다.
59 |
60 | ### 🥕 Named PIPE
61 |
62 | - 공유 매개체는 '파일' 이다.
63 | - FIFO 방식을 사용한다.
64 | - 익명 PIPE와는 다르게 부모 프로세스와 무관하게 전혀 다른 프로세스들 사이에서 통신이 가능하다.
65 | - 통신을 위해서 이름이 있는 파일들을 사용한다.
66 | - 익명 PIPE와 같이 단방향 통신만 가능하지만, 이름이 있는 파일 두개를 사용해서 이를 해결할 수는 있다.
67 |
68 | ### 🥕 Message Queue (메시지 큐)
69 |
70 | - 양방향 통신방식이다.
71 | - 공유 매개체는 '메모리'이다.
72 | - Named PIPE와 같은 입출력 방식을 사용 (FIFO) 하지만, Named PIPE는 데이터의 흐름이라면, 메시지큐는 '메모리 공간'이라는 차이가 존재한다.
73 | - 데이터를 주고받기 위한 '메시지 큐'를 커널에서 관리하는 방식이다.
74 | - 모든 프로세스에서 접근이 가능하다. (메시지큐의 접근자(식별자)를 아는 모든 프로세서는 동일한 메시지큐에 접근해서 데이터를 공유할 수 있다.)
75 |
76 | ### 🥕 Socket (소켓)
77 | - 네트워크 소켓 통신을 통해 데이터를 공유한다.
78 | - 클라이언트와 서버가 소켓을 통해서 통신하는 구조로, 원격에서 프로세스간 데이터를 공유할 때 사용한다.
79 |
80 |
81 | ## 🔸 공유 메모리 시스템
82 |
83 | - 양방향 통신이다.
84 | - 공유 매개체는 메모리이다.
85 | - 두 개 이상의 프로세스들이 주소공간의 일부를 공유하며, 공유한 메모리 영역에 읽기/쓰기를 통해 통신한다.
86 | - 공유 메모리가 설정되면, 그 이후 통신은 커널의 관여 없이 진행 가능하다.
87 | - 중개자 없이 곧바로 메모리에 접근할 수 있기 때문에 모든 IPC 중에서 가장 빠르게 작동한다. (커널에 관여가 없이 메모리에 직접 접근하기 때문에!)
88 | - 프로그램 레벨에서 통신기능을 제공하여 자유로운 통신이 가능하다.
89 | - 프로세스가 공유 메모리 할당을 커널에 요청하면, 커널은 해당 프로세스에 대한 메모리 공간을 할당해주고, 이후 모든 프로세스는 해당 메모리 영역에 접근할 수 있게 된다. (공유 메모리의 ID를 알면 누구나 해당 메모리에 접근 가능)
90 |
91 |
92 | ### 🥕 File - Memory mapping (메모리 맵)
93 | - 메모리 맵은 열린 파일을 메모리에 매핑시켜서 공유하는 방식이다 (즉, 공유 매개체가 파일 + 메모리이다.)
94 | - 주로 파일로 대용량 데이터를 공유해야할 때 사용한다.
95 |
96 |
97 | # ✅ 면접때 나올 만한 질문들
98 |
99 | - 프로세스간 통신이 필요한 이유는?
100 | - 특정 테스크를 빨리 실행하고자 한다면 병렬처리가 필요합니다. 그렇다면 서로 데이터의 공유가 필요합니다.
101 | - 프로세스는 각자 독립된 메모리 공간을 가지고 있는데, 서로의 데이터를 공유하는 도구가 필요할 것입니다.
102 |
103 | # 📖 References
104 | - [운영체제 IPC](https://dong-wook94.github.io/cs/2020/11/10/cs-os-ipc/)
105 | - [Github gyoogle](https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Operating%20System/IPC(Inter%20Process%20Communication).md)
106 | - [IPC](https://velog.io/@qweadzs/CS-IPCInter-Process-Communication)
107 | - [github 신입개발자 - ipc](https://github.com/workhardslave/cs-study/blob/main/OS/IPC%26RPC.md)
108 | - [ipc종류와 특징](https://parkgaebung.tistory.com/64)
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/Computer Science/Network/Block, Non-Block IO.md:
--------------------------------------------------------------------------------
1 |
2 | // 2022.08.30 Rookie
3 |
4 |
5 |
6 | ## 요약
7 |
8 |
9 |
10 | Block과 non Block은 작업을 수행하는 방식의 일종이며 데이터를 input, output하는 동안 작업을 중단하느냐 안하느냐로 구분한다.
11 |
12 |
13 |
14 | ---
15 |
16 |
17 |
18 | ## **Blocking I/O**
19 |
20 |
21 |
22 | Blocking I/O 는 다음과 같은 순서로 이루어지는 작업을 뜻합니다.
23 |
24 |
25 |
26 | ### (1) Process(Thread)가 Kernel에게 I/O를 요청하는 함수를 호출합니다.
27 |
28 |
29 |
30 | - Process와 thread
31 |
32 |
33 |
34 | **Process**
35 |
36 |
37 |
38 | Process는 컴퓨터에서 연속적으로 실행되는 컴퓨터 프로그램이다. 지금 이 글을 읽고 있다면 gitHub를 켜놨을터이니, gitHub가 프로세스가 되는 것이다.
39 |
40 |
41 |
42 | 프로세스는 각각 독립된 메모리 영역(code,data,stack,heap)을 할당받는다. 당연히 gitHub를 실행하면 이전에 했던 데이터들이 메모리에 올라가있어야 빠르게 프로세스가 수행되겠죠?
43 |
44 |
45 |
46 | **Thread**
47 |
48 |
49 |
50 | 쓰레드는 프로세스 내에서 실행되는 작업 흐름 단위입니다.
51 |
52 |
53 |
54 | gitHub를 켜면 우리는 다양한 작업을 수행합니다. 브랜치 옮기기, 커밋 남기기 등등… 이러한 작업이 한번에 딱 이뤄지지는 않겠죠? 예를 들어 커밋을 남긴다고하면 git 서버에 명령을 전달하고, 아이디에 맞는 기록을 찾는 복잡한 과정이 이루어지는데, 이 때 작업 단위를 쓰레드라고 합니다.
55 |
56 |
57 |
58 | - Kernel
59 |
60 | 운영체제는 **항상 필요한 부분**만 전원이 켜짐과 동시에 메모리에 올려놓고 그렇지 않은 부분은 필요할 때마다 메모리에 올려서 사용하게 된다. 이 때 **메모리에 상주하는 운영체제의 일부분을 커널**이라 한다.
61 |
62 |
63 |
64 | **Reference**
65 |
66 |
67 |
68 | [https://goodmilktea.tistory.com/23](https://goodmilktea.tistory.com/23)
69 |
70 |
71 |
72 |
73 |
74 | 프로그램이 수행되려면 당연히 자료(데이터)를 받아와야겟죠? 그러니 컴퓨터 운영체제 OS에게 자료의 입,출입을 요청하는 것입니다.
75 |
76 |
77 |
78 | ### (2) Kernel이 작업을 완료하면 작업 결과를 반환 받음.
79 |
80 |
81 |
82 | - 특징
83 |
84 | - I/O 작업이 진행되는 동안 user Process(Thread) 는 자신의 작업을 중단한 채 대기
85 |
86 | - Resource 낭비가 심함 (I/O 작업이 CPU 자원을 거의 쓰지 않으므로)
87 |
88 |
89 |
90 | `여러 Client 가 접속하는 서버를 Blocking 방식으로 구현하는 경우` -> I/O 작업을 진행하는 작업을 중지 -> 다른 Client가 진행중인 작업을 중지하면 안되므로, client 별로 별도의 Thread를 생성해야 함 -> 접속자 수가 매우 많아짐 이로 인해, 많아진 Threads 로 *컨텍스트 스위칭 횟수가 증가함,,, 비효율적인 동작 방식*
91 |
92 |
93 |
94 | - 컨텍스트 스위칭이란?
95 |
96 |
97 |
98 | 동시에 다수의 프로세스를 수행하기 위해, 아주 짧은 시간간격으로 프로세스를 전환시켜 수행하는 작업 방식
99 |
100 |
101 |
102 | 원래 한 프로세스를 실행하면 cpu가 점유되서 다른 프로세스를 할 수 없다고 한다.
103 |
104 |
105 |
106 | ## Reference
107 |
108 |
109 |
110 | [https://www.youtube.com/watch?v=1grtWKqTn50](https://www.youtube.com/watch?v=1grtWKqTn50) (우아한테크 유튜브 5분~7분)
111 |
112 |
113 |
114 | - 정의
115 |
116 | **멀티 프로세스 환경에서 CPU가 어떤 하나의 프로세스를 실행하고 있는 상태에서, **인터럽트 요청에 의해** 다음 우선 순위의 프로세스가 실행되어야 할 때, 기존의 프로세스의 상태 또는 레지스터 값(Context)을 저장하고 CPU가 다음 프로세스를 수행하도록 새로운 프로세스의 상태 또는 레지스터 값(Context)으로 **교체**
117 |
118 | 하는 작업을 컨텍스트 스위칭 이라고 한다
119 |
120 |
121 |
122 | [https://velog.io/@taehee-kim-dev/컨텍스트-스위칭](https://velog.io/@taehee-kim-dev/%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8-%EC%8A%A4%EC%9C%84%EC%B9%AD)
123 |
124 |
125 |
126 |
127 |
128 | ---
129 |
130 |
131 |
132 | ## No**n-Blocking I/O**
133 |
134 |
135 |
136 | 마찬가지로 non Blocking I/O 는 다음과 같은 순서로 이루어지는 작업을 뜻합니다.
137 |
138 |
139 |
140 | 하지만!!! I/O 작업이 진행되는 동안 User Process의 작업을 중단하지 않습니다. (매우 중요)
141 |
142 |
143 |
144 | - 진행 순서
145 |
146 | 1. User Process가 recvfrom 함수 호출 (커널에게 해당 Socket으로부터 data를 받고 싶다고 요청함)
147 |
148 | ** Socket: 네트워크상에서 동작하는 프로그램 간 통신의 종착점(Endpoint). 간단히 말해서는 특정 문자들을 조합하여 만든 네트워크 주소이다.
149 |
150 |
151 |
152 | 2. Kernel은 이 요청에 대해서, 곧바로 recvBuffer를 채워서 보내지 못하므로, "EWOULDBLOCK"을 return함.
153 |
154 |
155 |
156 | ** buffer: 데이터를 한 곳에서 다른 한 곳으로 전송하는 동안 일시적으로 그 데이터를 보관하는 메모리의 공간. buffer가 가득차게 되면 목적지로 데이터를 보내게 된다. buffer에 저장된 데이터들은 이진수 데이터들이며 buffer의 크기가 데이터 처리 단위가 된다고 한다.
157 |
158 | 여기서 revbuffer는 데이터를 받아오는 동안 사용하는 buffer이다.
159 |
160 |
161 |
162 | 3. **Blocking 방식과 달리, User Process는 다른 작업을 진행할 수 있음!!**
163 |
164 |
165 |
166 | 4. recvBuffer에 user가 받을 수 있는 데이터가 있는 경우, Buffer로부터 데이터를 복사하여 받아옴.
167 |
168 |
169 |
170 | 이때, recvBuffer는 Kernel이 가지고 있는 메모리에 적재되어 있으므로, Memory간 복사로 인해, I/O보다 훨씬 빠른 속도로 data를 받아올 수 있음.
171 |
172 |
173 |
174 | 이미지를 서버에서 통신해서 가져와서 휴대폰에 띄운다고 생각해보자! 이전에 내가 다운 받은 이미지가 buffer로 메모리 공간 어디에 저장되어있다면 굳이 URL을 사용하여 통신하지 않고 memory에서 꺼내쓸 수 있으니 훨씬 빠르다!
175 |
176 |
177 |
178 |
179 |
180 | 5. recvfrom 함수는 빠른 속도로 data를 복사한 후, 복사한 data의 길이와 함께 반환함.
181 |
182 |
183 |
184 |
185 |
186 | ---
187 |
188 |
189 |
190 | ## References
191 |
192 |
193 |
194 | [https://velog.io/@rhdmstj17/소켓과-웹소켓-한-번에-정리-1](https://velog.io/@rhdmstj17/%EC%86%8C%EC%BC%93%EA%B3%BC-%EC%9B%B9%EC%86%8C%EC%BC%93-%ED%95%9C-%EB%B2%88%EC%97%90-%EC%A0%95%EB%A6%AC-1) (소켓에 대한 깊이있는 이해…)
195 |
196 |
197 |
198 | [https://medium.com/@su_bak/term-socket이란-7ca7963617ff](https://medium.com/@su_bak/term-socket%EC%9D%B4%EB%9E%80-7ca7963617ff) (소켓에 대한 얕은 이해)
199 |
200 |
201 |
202 | [https://m.blog.naver.com/ginameee/220839976258](https://m.blog.naver.com/ginameee/220839976258) (소켓, 버퍼 등 기본 개념 정리)
203 |
--------------------------------------------------------------------------------
/Computer Science/Database/정규화(Nomalization).md:
--------------------------------------------------------------------------------
1 | # 🟠 정규화
2 | ```
3 | DB 정규화는 데이터의 중복을 줄이고,
4 | 무결성을 개선하기 위해 정규화 단계에 따라 관계형 데이터 베이스를 구조화하는 프로세스
5 | ```
6 | 정규화 단계에 따라 이루어지는 만큼, 이전단계를 충족시키지 못하면 다음 단계로 가는 것은 불가능하다.
7 | 즉, 비정규화의 형태를 가지고 최고 레벨의 정규화를 달성하는 것을 목표로 첫번째 레벨부터 정규화가 충족되도록 해야한다.
8 |
9 | ## 🔸 제 1정규화 (1NF)
10 |
11 | 테이블의 column이 원자값(하나의 값, Atomic Value)를 갖도록 테이블을 분해해야 햔다.
12 | 하나의 컬럼안에는 하나의 데이터 value만 가질 수 있다는 뜻이다.
13 |
14 | 지금 예시 데이터에서는 '박세리', '추신수' 라는 사람들은 여러개의 취미를 갖고있다. _**이는 '제1정규화를 만족하지 못했다'라고 부른다**_.
15 | 그렇기 때문에 제 1정규화(1NF)를 진행하여 제 1정규화(1NF)를 만족하는 테이블로 만들어줘야한다.
16 |
17 | 
18 |
19 | 이렇게 하게 되면 하나의 컬럼에 하나의 value가 들어간, 원자값을 갖는, 제 1정규화를 만족시키는 데이터 테이블이 된다.
20 |
21 | ## 🔸 제 2정규화 (2NF)
22 | 제 2정규화란, 1NF를 진행한 테이블에 대해, 완전함수종속을 만족하도록 테이블을 분해하는 것이다.
23 |
24 | #### 📌 완전함수 종속이란?
25 | 완전함수 종속이란? 기본키의 부분집합이 결정자가 되어서는 안된다는 것을 의미한다. 그니까, 한 테이블에서 오직 'primary key'만 종속적인 관계를 가질 수 있다.
26 | 정규화가 잘 된 테이블을 수록, 결정자 X는 한개, 그리고 Y값은 여러개를 갖는다.
27 |
28 | 
29 |
30 | 조금 더 쉽게 보고자 데이터를 가져와봤다.
31 |
32 | 
33 |
34 | 위 데이터를 보면, 이름, 성별, 주소를 판별할 수 있는 고유값은 '주민번호'이다. 그래서 '주민번호'가 PK가 될 것이다.
35 | 하지만, '이름'을 보자. '이름'은, 성춘향이라는 여자도 있고 남자도 있다. 주민번호도 다르고, 주소도 다르다.
36 | 때문에 이름, 그리고 성별, 주소는 고유의 값을 판별할 수 없기 때문에, PK가 될 수 없다.
37 |
38 | 이것을 위에서 말한 X 와 Y에 대입해서 생각해보면
39 | ```
40 | X: 주민번호 -> Y1: 이름 식별 가능
41 | X: 주민번호 -> Y2: 성별 직별 가능
42 | X: 주민번호 -> Y3: 주소 식별 가능
43 | ```
44 |
45 | 이렇게 된다. 이런 구조가 되어야만, '완전 함수 종속'이다! 라고 말한다!
46 |
47 | ---
48 |
49 | ## 다시, 2NF로 돌아와서
50 |
51 | 2NF는 완전함수종속을 만족하도록 만든다고 했다. 즉, 위에서 말한 '완전함수종속'을 지킬 수 있도록 테이블을 고쳐주어야한다.
52 | 예시로 살펴보자.
53 |
54 | 
55 |
56 |
57 | 이 테이블에서는, 학생번호와 수강강좌번호가 PK가 될 수 있어보인다. '수강과목'을 식별하는 PK와, 사람을 식별하는 PK 두개가 있는 것이다.
58 | 이것이 완전함수종속을 만족시키지 못햇다고 말하면서, 2NF를 만족시키지 못했다고 말한다. (오직 PK 1개에만 모든 것들이 종속되어야한다.)
59 |
60 | 이 데이터를 2NF를 진행해보자.
61 |
62 | 
63 |
64 |
65 | ## 🔸 제 3정규화 (3NF)
66 |
67 | 제 3정규화(3NF)란, 제2정규화(2NF)를 만족한 테이블에 대해서 '이행적 종속'을 없애도록 테이블을 분해하는 것이다.
68 |
69 | #### 📌 이행적 종속이란?
70 | XYZ라는 3개의 속성이 있을 때, X->Y, Y->Z라는 종속관계가 있을 경우, X->Z 가 성립될때! 이행적 함수 종속이라고 한다.
71 |
72 |
73 |
74 | 이 데이터로 보면,
75 | ```
76 | X(이름, 성별) -> Y: 주소
77 | X(주소) -> Y: 지역번호
78 | ```
79 |
80 | 이렇게 성립한다. 하지만, '주소'도 '지역번호' 통해 알 수있다. 이럴 경우, 이행함수 종속이라고 부르고, 이런 관계를 없애버리는것이 3NF이다.
81 |
82 | ---
83 |
84 | ## 다시 3NF로 돌아와서
85 |
86 | 위에서 설명한 방식대로 3NF를 진행해보자. (이행 함수 종속을 없애보자.)
87 |
88 | 
89 |
90 | 지금 학생들이 수강할 계절학기 데이터는 위와 같다. 이 테이블에서는 학생번호는 강좌이름을 결정하고 있고, 강좌번호는 수강료를 결정하고 있다.
91 | 이 테이블로 보면, '학생번호'를 탐색할 때 '수강료'까지 같이 탐색하게 된다.
92 | 즉, 학생번호를 통해 수강료를 알 수 있기 때문에, 3NF를 만족하지 못하고 있다.
93 | 3NF를 진행하면, (학생번호, 강좌이름) 테이블과, (강좌이름, 수강료) 테이블로 분해할 수 있다.
94 |
95 | 왜 굳이 이렇게 해야할까?
96 |
97 | 현재 테이블에서 501번 학생이 수강할 강좌를 '데이터베이스'에서 '스포츠경영학'으로 바꿨다고 치자.
98 | 이런경우, 501학생 데이터에서 강좌이름을 update하여 바꿔줄 것이다. 이럴때 스포츠 경영학은 수강료가 20000원이 아닌데, 501학생 데이터는수강료를 그대로 20000으로 저장하게 된다.
99 | 즉, 강좌이름을 바꾸면서 수강료까지 바꿔줘야하는 불상사가 생기고, 이는 DB가 커질수록 관리의 효율을 떨어뜨린다.
100 |
101 | 그렇기 때문에 이행적 함수 종속을 꼭 제거해주어야하며, 3NF까지 모두 완료시켜주어야한다.
102 |
103 | 이 데이터를 3NF 시키면 다음과 같다.
104 |
105 | 
106 |
107 |
108 |
109 | ## 🔸 BCNF 정규화
110 |
111 | BCNF정규화란 3NF를 진행한 테이블에 대해 모든 결정자가 후보키가 되도록 테이블을 분해하는 것이다.
112 | 예를들어 다음과같은 테이블이 존재한다고 해보자.
113 |
114 | 
115 |
116 | 이예시로 보면,
117 | ```
118 | 1. (학생번호, 특강이름) -> (교수)
119 | 2. (교수) -> (특강이름)
120 | ```
121 | 이런 함수적 종속 관계를 갖는다. 이때, ```2.```를 보면, PK가 아닌 교수가 '특강이름'과 함수적 종속관계를 갖는다.
122 | 여기서의 문제는, 교수가 특강이름을 결정짓는 결정자이지만, 후보키가 아니라는 점이다. 그렇기 때문에 BCNF를 만족하지 못했다 라고 말한다.
123 |
124 | 그래서 이를 BCNF를 만족시키는 아래와 같은 형태로 분해할 수 있다.
125 |
126 | 
127 |
128 |
129 | # 📝 Reference
130 | [함수 종속 설명](https://developer111.tistory.com/80)
131 | [메인 글](https://mangkyu.tistory.com/110)
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
--------------------------------------------------------------------------------
/Computer Science/Network/http와 https.md:
--------------------------------------------------------------------------------
1 | // 20220830
2 |
3 | // Brown
4 |
5 |
6 | 
7 |
8 | ### 🍯 재미난 이야기
9 | 2014년 구글에서는 HTTP를 HTTPS로 모두 바꾸라고 권고했었다고 합니다.
10 | 그 전까지는 전자상거래가 있는 웹 사이트에서만 번거로운 HTTPS를 사용했는데, 보안이 더 강한 HTTPS로 전환을 장려하기 위해서 구글은 HTTPS를 사용하는 웹 사이트에 대해서 검색 순위 결과에 약간의 가산점을 준다면서 발표했다고 합니다. 그래서 이렇게 대대적인 전환이 이뤄졌다고 볼 수 있겠군요!!
11 |
12 |
13 | # ✅ 면접 대비 요약
14 | ```Question``` HTTP 와 HTTPS의 차이점에 대해서 설명해보세요.
15 |
16 | ```Answer``` HTTP는 따로 암호화 과정을 거치지 않기 때문에 중간에 패킷을 가로챌 수 있고, 수정할 수 있습니다. 따라서 보안이 취약해집니다. 이를 보완하기 위해 나온것이 HTTPS이고, HTTPS는 중간에 암호화 계층을 거쳐서 패킷을 암호화합니다.
17 |
18 |
19 |
20 | # 🟠 HTTP (Hypertext Transfer Protocol)
21 | 서로 다른 시스템들 사이에서 통신을 주고받게 해주는 가장 기초적인 프로토콜이다. 웹서핑을 할 때 서버에서 자신의 브라우저로 데이터를 전송해주는 용도로 가장 많이 사용된다. 인터넷 초기에 모든 웹사이트에서 기본적으로 사용됐던 프로토콜이기도 하다.
22 |
23 | 즉, HTTP는 인터넷에서 하이퍼텍스트를 교환하기 위한 통신규약으로, 80번 포트를 사용하고 있다. 따라서 HTTP 서버가 80번 포트에서 요청을 기다리고 있으며, 클라이언트는 80번 포트로 요청을 보내게 된다.
24 |
25 | ```
26 | 💡 여기서 말하는 프로토콜이란?
27 | 컴퓨터 내부에서 또는 컴퓨터 사이에서 데이터 교환 방식을 정의하는 규칙 체계이다.
28 | 기기 간 통신은 교환되는 데이터의 형식에 대해 상호 합의를 요구한다.
29 | 이런 형식을 정의하는 규칙의 집합이라고 보면 된다.
30 | ```
31 |
32 | ## 🔸 HTTP의 구조
33 | HTTP는 애플리케이션 레벨의 프로토콜로 TCP/IP 위에서 작동한다. HTTP는 상태를 가지고 있지 않는 ```Stateless 프로토콜``` 이며 Method, Path, Versionn, Headers, Body로 구성된다.
34 |
35 | 
36 |
37 | ### 🔸 HTTP의 문제점
38 | 하지만 HTTP는 암호화가 되지 않은 평문 데이터르 런송하는 프로토콜 이기 때문에, HTTP로 비밀번호나 주민번호 등을 주고받으면 제 3자가 정보를 조회할 수 있었다. 즉, 데이터가 쉽게 도난당할 수 있는 구조다.
39 |
40 | # 🟠 HTTPS (Hypertext Transfer Protocol Secure)
41 |
42 | HTTPS는 SSL(Secure Socket Layer)를 사용함으로써 HTTP의 문제점을 해결했다. SSL은 서버와 브라우저 사이에 안전하게 암호화된 연결을 만들 수 있게 도와주고, 서버 브라우저가 민감한 정보를 주고받을 때 이것이 도난당하는 것을 막아준다.
43 |
44 | HTTPS는 443번 포트를 사용하며, 네트워크 상에서 중간에 제 3자가 정보를 볼 수 없도록 암호화를 지원한다.
45 |
46 | ```
47 | 💡 SSL (Secure Socket Layer)란
48 | 암호화 기반 인터넷 보안 프로토콜이다.
49 | 인터넷 통신의 개인정보 보호, 인증, 데이터 무결성을 보장하기 위해서 개발되었다.
50 | ```
51 |
52 |
53 | ## ✋🏻 여기서 잠깐, 대칭키 암호화, 비대칭키(공개키) 암호화에 대해서 알고 가야한다!
54 | HTTPS는 대칭키 암호화 방식과 비대칭키 암호화방식 모두를 사용한다. 각각의 암호화방식은 다음과 같다.
55 |
56 | ```
57 | < 대칭키 암호화>
58 | - 클라이언트와 서버가 동일한 키를 사용해 암호화/복호화를 진행함
59 | - 키가 노출되면 매우 위험하지만 연산 속도가 빠름
60 | ```
61 |
62 |
63 | ```
64 | < 비대칭키 암호화 >
65 | - 1개의 쌍으로 구성된 공개키와 개인키를 암호화/복호화 하는데 사용함
66 | - 키가 노출되어도 비교적 안전하지만 연산 속도가 느림
67 | ```
68 |
69 | 비대칭키 암호화는 공개키/개인키 암호화 방식을 이용해 데이터를 암호화 하고 있다. 공개키와 개인키는 서로를 위한 1쌍의 키다.
70 | - 공개키 : 모두에게 공개하는 키
71 | - 개인키 : 나만 가지고 알아야하는 키
72 |
73 | 암호화를 공개키로 하느냐, 개인키로 하느냐에 따라 얻는 효과가 다른데, 공개키와 개인키로 암호화하면 각각 다음과 같은 효과를 얻을 수 있다.
74 | - 공개키 암호화: 공개키로 암호화를 하면 개인키로만 복호화할 수 있다. (즉, 나만 볼 수 있다.)
75 | - 개인키 암호화: 개인키로 암호화하면 공개키로만 복호화할 수 있다. (공개키는 모두에게 공개되어 있으므로, 내가 인증한 정보임을 알려 신뢰성을 보장할 수 있다.)
76 |
77 | 
78 |
79 | ### ✨ 조금 더 쉬운 이해를 위해 공개키와 개인키에 대한 그림 첨부!
80 |
81 | 
82 |
83 |
84 | ## 🔸 HTTPS의 동작 과정
85 | 대칭키 암호화와 비대칭키 암호화를 모두 사용해서 빠른속도와 안정성을 모두 얻고있는 것이 장점이다.
86 | HTTPS 연결과정에서는 먼저 서버와 클라이언트 간에 세션키를 교환한다. 여기서 세션키는 주고받는 데이터를 암호화하기 위해서 사용되는 대칭키이며, 데이터간의 교환에는 빠른연산속도가 필요하므로 세션키는 대칭키로 만들어진다.
87 |
88 | 문제는 이 세션키를 클라이언트와 서버가 어떻게 교환할 것이냐 인데, 이 과정에서 비대칭키가 사용된다. 즉, 처음 연결을 성립하여 안전하게 세션키를 공유하는 과정에서 비대칭키가 사용되는 것이고, 이후에 데이터를 교환하는 과정에서 빠른 연산속도를 위해 대칭키가 사용되는 것이다.
89 |
90 | 
91 |
92 | (사진에서 2번은 세션키를 교환하기 위해 안전하게 비대칭키 사용, 이후의 과정에서 빠른 연산속도를 위해 3) 대칭키 사용)
93 |
94 | ## 📝 실제 HTTPS 연결 과정이 성립되는 흐름을 살펴보자.
95 | 1. 클라이언트 (브라우저)가 서버로 최초 연결을 시도함.
96 |
97 | 
98 |
99 | 2. 서버는 공개키를 브라우저에게 넘겨줌
100 |
101 | 
102 |
103 | 3. 브라우저는 인증서의 유효성을 검사하고 세션키를 발급함.
104 | 4. 브라우저는 세션키를 보관하며, 추가로 서버의 공개키로 세션키를 암호화하여 서버로 전송함
105 |
106 | 
107 |
108 | 5. 서버는 개인키로 암호화된 세션키를 복호화하여 세션키를 얻음.
109 |
110 | 
111 |
112 | 6. 클라이언트와 서버는 동일한 세션키를 공유하므로, 데이터를 전달할 때 세션키로 암호화/복호화를 진행함
113 |
114 | 
115 |
116 |
117 | ## 📖 Reference
118 | [그림출처, 전반적인 내용, 대칭/비대칭 암호화 방식 설명](https://mangkyu.tistory.com/98)
119 |
120 | [요약 출처](https://zeroco.tistory.com/70)
121 |
122 | [기본개념 출처](https://brunch.co.kr/@hyoi0303/10)
123 |
124 |
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/Design Pattern/어댑터 패턴 (Adapter pattern).md:
--------------------------------------------------------------------------------
1 | // 2022.09.27 Brown
2 |
3 |
4 |
5 | # 🟣 어댑터 패턴 (Adapter Pattern)
6 |
7 | ```
8 | - 서로 다른 인터페이스를 가진 객체를 함께 사용할 수 있도록 해주는 디자인 패턴
9 | - 어댑터를 이용하여 인터페이스 호환성 문제를 해결할 수 있다.
10 | ```
11 |
12 | # 🟣 어댑터 패턴이 왜 필요할까?
13 |
14 | ```
15 | 🤔 맥북에서 쓰이는 포트는 전부 C-Type이다. 만약 USB를 연결하고 싶으면? Adapter가 필요하다!
16 | ```
17 |
18 | 
19 |
20 | 이 어댑터를 이용하면 호환되지 않는 충전기도 사용할 수 있다.
21 | 이처럼 어댑터 디자인 패턴을 사용하는 이유는, ```서로 호환되지 않는 인터페이스를 사용하는 클라이언트를 그대로 활용할 수 있게``` 해준다.
22 |
23 | 인터페이스를 변환해주는 어댑터만 만들면 되니까 그대로 활용할 수 있게 된다. (충전기 어댑터와 정말 같은 맥락이다!)
24 |
25 | 이를 통해 클라이언트와 구현된 인터페이스를 분리할 수 있고, 나중에 인터페이스가 바뀌더라도 변경 내역은 어댑터에 캡슐화 되기 때문에 클라이언트는 바뀔 필요가 없어진다.
26 |
27 | ## 😈 어댑터는 언제 사용될까?
28 |
29 | - 기존 클래스를 사용하고 싶은데, 인터페이스가 맞지 않을 때
30 | - 이미 만든 것을 재사용하고자 하나, 이 재사용 가능한 라이브러리를 수정할 수 없을 때
31 |
32 |
33 | # 🟣 어댑터 패턴의 역할
34 |
35 | - 어떤 인터페이스를 클라이언트에서 요구하는 형태의 인터페이스에 적응 시켜주는 역할, 즉 중개인역할을 한다.
36 | - 한 인터페이스를 다른 인터페이스로 변환하기 위한 용도이다.
37 |
38 | # 🟣 어댑터 패턴의 주요 객체
39 |
40 | 
41 |
42 | - ```Target```: 인터페이스를 정의하는 클래스 (Client가 사용중인 인터페이스), (다른 클래스가 현재로직에 포함되려면 따라야하는 프로토콜)
43 | - ```Client```: Target 인터페이스를 만족하는 객체와 동작할 대상, 프로그램의 기존 로직을 포함하는 클래스
44 | - ```Adaptee```: 현재 존재하는 클래스가 아닌 외부에서 가지고 온 유용한 클래스. 따라서 인터페이스가 다르기 때문에 바로 사용할 수 없음.
45 | - ```Adapter```: 이러한 Client, Adaptee를 모두 사용할 수 있도록 도와줌. Adapter는 Client, Adaptee 객체를 모두 다룰 수 있고 Adaptee 객체를 Client 인터페이스로 래핑 하거나 Client 객체를 Adaptee 클래스가 사용할 수 있는 형식으로 변환해줌.
46 |
47 | # 🟣 어댑터 패턴을 예시로 살펴보자. (Swift)
48 |
49 | ## 1️⃣ Target: 인터페이스 정의
50 |
51 | ```swift
52 | protocol LightningPhone {
53 | func recharge()
54 | func useLightning()
55 | }
56 |
57 | protocol MicroUSBPhone {
58 | func recharge()
59 | func useMicroUSB()
60 | }
61 | ```
62 |
63 | ## 2️⃣ Adaptee 정의
64 |
65 | ```swift
66 | class Iphone: LightningPhone {
67 | var connector: Bool = false
68 | public func recharge() {
69 | if connector {
70 | print("Recharge Started")
71 | print("Recharge finished")
72 | } else {
73 | print("Connect Lightning first")
74 | }
75 | }
76 |
77 | public func useLightning() {
78 | connector = true
79 | print("Lightning connected")
80 | }
81 | }
82 |
83 | class Android: MicroUSBPhone {
84 | var connector: Bool = false
85 |
86 | func recharge() {
87 | if connector {
88 | print("Recharge Started")
89 | print("Recharge finished")
90 | } else {
91 | print("Connect MicroUSB first")
92 | }
93 | }
94 |
95 | func useMicroUSB() {
96 | connector = true
97 | print("MicroUSB connected")
98 | }
99 | }
100 | ```
101 |
102 | ## 3️⃣ Adapter 정의
103 |
104 | ```swift
105 | class LightningToMicroUSBAdapter: MicroUSBPhone {
106 | private final var lightningPhone: LightningPhone
107 |
108 | init(_ lightningPhone: LightningPhone) {
109 | self.lightningPhone = lightningPhone
110 | }
111 |
112 | public func lightningToMicroUSBAdapter(lightningPhone: LightningPhone) {
113 | self.lightningPhone = lightningPhone
114 | }
115 |
116 | func recharge() {
117 | lightningPhone.recharge()
118 | }
119 |
120 | func useMicroUSB() {
121 | print("MicroUSB connected")
122 | lightningPhone.useLightning()
123 | }
124 | }
125 | ```
126 |
127 | ## 4️⃣ Client 정의
128 |
129 | - 우선, 이 부분이 프로그램에서 동작할 부분이다.
130 | - MicroUSBPhone과 LightningPhone 프로토콜을 따르는 충전 함수를 만들자.
131 |
132 | ```swift
133 | func rechargeMicroUSBPhone(phone: MicroUSBPhone) {
134 | phone.useMicroUSB()
135 | phone.recarge()
136 | }
137 |
138 | func rechargeLightningPhone(phone: LightningPhone) {
139 | phone.useLightning()
140 | phone.recharge()
141 | }
142 | ```
143 |
144 | - 그다음 인스턴스를 생성하자.
145 |
146 | ```swift
147 | let anroid = Android()
148 | let iphone = Iphone()
149 | ```
150 |
151 | - 각각의 인스턴스는 관련된 충전함수에 접근이 가능하다.
152 |
153 | ```swift
154 | print("Recharging android with MicroUSB")
155 | rechargeMicroUSBPhone(phone: android)
156 | print("Recharging iphone with Lighting")
157 | rechargeLightingPhone(phone: iphone)
158 | ```
159 |
160 | - 하지만 ```rechargeMicroUSBPhone(phone: _)``` 에는 iphone이 접근할 수 없다. 다른 인터페이스이기떄문!
161 | - 그래서 Adapter를 만들어서 접근해보려고 한다.
162 | - Adapter는 Target(MicroUSBPhone 프로토콜)를 준수하는 인터페이스로 만들었다.
163 | - 그래서 이제 Adaptee가 사용할 수 있는 형태가 되었다!!
164 |
165 | ```swift
166 | print("Recharging iphone with MicroUSB")
167 | rechargeMicroUSBPhone(phone: LightningToMicroUSBAdapter(iphone)
168 | ```
169 |
170 | (💬 코드 결과 캡쳐 넣기!!)
171 |
172 | # 🟣 어댑터 패턴의 장단점
173 |
174 | ## 😈 장점
175 |
176 | - 기존 코드를 변경하지 않아도 된다.
177 | - 기존코드를 변경하지 않기 때문에 클래스 재활용성을 증가시킨다.
178 |
179 | ## 😈 단점
180 |
181 | - 구성요소를 위해 클래스를 증가시켜야 하기 때문에 복잡도가 증가한다.
182 | - 클래스 Adapter의 경우 상속을 사용하기 때문에 유연하지는 못하다.
183 | - 객체 Adapter의 경우는 대부분의 코드를 다시 작성해야 하기 때문에 효율적이지 못하다.
184 |
185 |
186 | # 📖 Reference
187 | - [어댑터 패턴 설명 및 이미지 및 코드](https://velog.io/@ellyheetov/%EC%96%B4%EB%8C%91%ED%84%B0-%ED%8C%A8%ED%84%B4AdapterWrapper-Pattern)
188 | - [어댑터 패턴 기초 pingu님 블로그](https://icksw.tistory.com/241)
189 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/경쟁상태 (Race Condition).md:
--------------------------------------------------------------------------------
1 | / 2022.09.07
2 |
3 | ### 경쟁 상태란?
4 |
5 | 공유 자원에 대해 여러 프로세스(쓰레드)가 동시에 접근할 때, 결과값에 영향을 줄 수 있는 상태
6 |
7 | 경쟁 상태시 동시 접근 시 자료의 일관성을 해칠 수 있다는 문제가 발생함
8 |
9 | ### **WWDC에서 나온 Example**
10 |
11 | 아래 코드는 글로벌 쓰레드에서 어떤 배열에 요소를 추가하는 작업을 비동기적으로 처리하게 설정한 것이다.
12 |
13 | Granpa와 Cub이라는 문자열을 sleepingBears에 넣는 작업.
14 |
15 |
16 |
17 |
18 |
19 |
20 | sleepingBears라는 배열에 접근하는데, 글로벌 쓰레드 두개가 경쟁하는 상황이다. 누가 이길지 모르니, 추가된 요소의 순서가 달라져 다른 배열이 되는 모습을 볼 수 있다.
21 |
22 | 이러면 참 골 때리는 상황이 연출되겟죠??
23 |
24 | ### **[#](https://gyoogle.dev/blog/computer-science/operating-system/Race%20Condition.html#race-condition%E1%84%8B%E1%85%B5-%E1%84%87%E1%85%A1%E1%86%AF%E1%84%89%E1%85%A2%E1%86%BC%E1%84%92%E1%85%A1%E1%84%82%E1%85%B3%E1%86%AB-%E1%84%80%E1%85%A7%E1%86%BC%E1%84%8B%E1%85%AE)Race Condition이 발생하는 경우**
25 |
26 | 자원에 동시에 접근할 때가 언제있을까? 를 생각하시고 보면 이해하시기 수월합니다!
27 |
28 | 1. **[#](https://gyoogle.dev/blog/computer-science/operating-system/Race%20Condition.html#%E1%84%8F%E1%85%A5%E1%84%82%E1%85%A5%E1%86%AF-%E1%84%8C%E1%85%A1%E1%86%A8%E1%84%8B%E1%85%A5%E1%86%B8%E1%84%8B%E1%85%B3%E1%86%AF-%E1%84%89%E1%85%AE%E1%84%92%E1%85%A2%E1%86%BC%E1%84%92%E1%85%A1%E1%84%82%E1%85%B3%E1%86%AB-%E1%84%8C%E1%85%AE%E1%86%BC%E1%84%8B%E1%85%A6-%E1%84%8B%E1%85%B5%E1%86%AB%E1%84%90%E1%85%A5%E1%84%85%E1%85%A5%E1%86%B8%E1%84%90%E1%85%B3-%E1%84%87%E1%85%A1%E1%86%AF%E1%84%89%E1%85%A2%E1%86%BC)커널 작업을 수행하는 중에 인터럽트 발생할 때 !!**
29 | - 문제점 : 커널모드에서 데이터를 로드하여 작업을 수행하다가 인터럽트가 발생하여 같은 데이터를 조작하는 경우
30 | - 해결법 : 커널모드에서 작업을 수행하는 동안, 인터럽트를 disable 시켜 CPU 제어권을 가져가지 못하도록 한다.
31 |
32 | ** 커널모드와 유저모드란?
33 |
34 | - **정의**
35 | “커널모드와 유저모드는 프로그램이 운행되는 방식”입니다.
36 | 일반적으로 사용자가 프로그램을 쓴다면 CPU는 유저모드에서 수행되고 필요에 따라 커널모드가 되었다가 다시 유저모드로 돌아오기를 반복합니다.
37 |
38 | **유저모드는 유저가 프로그램의 자원에 함부로 침범하지 못하는 운영 방식이며 커널모드는 드라이버, 메모리, CPU등 모든 자원에 접근, 명령을 내릴 수 있는 운영 방식입니다.**
39 |
40 | “인터럽트가 발생하거나 시스템 콜을 호출하게 되면” 운영체제는 유저모드에서 커널 모드로 전환하게 됩니다.
41 | - **목적**
42 | 두 모드를 분리해서 왔다갔다 하는이유는 I/O 장치를 보호하기 위함입니다. 유저가 드라이버나 메모리에 있는 데이터를 삭제하거나 조작하는 악성 프로그램을 다운받더라도, 그 프로그램이 유저모드에서 수행되기 때문에 CPU는 I/O 관련 데이터를 조작하는 명령어는 자체적으로 판단해서 수행시키지 않는다고 합니다.
43 |
44 | ** 시스템콜과 인터럽트?
45 |
46 | 인터럽트란? :
47 | 운영 체제에서 컴퓨터에 예기치 않은 일이 발생하더라도 작동이 중단되지 않고 계속적으로 업무 처리를 할 수 있도록 해 주는 기능입니다.
48 | 예를 들어보자면, 전원이 갑자기 나가거나, 데이터 전달 과정에서 오류가 나거나.. 연산을 하다가 0으로 나눈다거나.. 하는 그런 상황입니다. 참고로 인터럽트가 발생하면 이를 처리하기 위해 즉각적으로 커널모드에 들어갑니다.
49 |
50 | **시스템콜?:**
51 |
52 | 시스템 호출(system call)은 운영 체제의 커널이 제공하는 서비스에 대해, 응용 프로그램의 요청에 따라 커널에 접근하기 위한 인터페이스입니다.
53 |
54 | 대부분 프로그램이 유저 모드에서 수행되지만 중요한 정보를 가져와야할때 커널의 도움이 필요합니다. 그래서 이 때 시스템 콜이라는 인터페이스를 이용해서 커널이 제공하는 함수나 데이터 등을 프로그램에 가져올 수 있는 것이지요
55 | 예를 들어, 파일을 읽고 쓰고 하는 작업, 스레드 배정, 프로세스 끼리 통신하는 작업 등에 시스템 콜이 필요하다고 합니다.
56 |
57 | 2. **[#](https://gyoogle.dev/blog/computer-science/operating-system/Race%20Condition.html#%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%89%E1%85%A6%E1%84%89%E1%85%B3%E1%84%80%E1%85%A1-system-call-%E1%84%8B%E1%85%B3%E1%86%AF-%E1%84%92%E1%85%A1%E1%84%8B%E1%85%A7-%E1%84%8F%E1%85%A5%E1%84%82%E1%85%A5%E1%86%AF-%E1%84%86%E1%85%A9%E1%84%83%E1%85%B3%E1%84%85%E1%85%A9-%E1%84%8C%E1%85%B5%E1%86%AB%E1%84%8B%E1%85%B5%E1%86%B8%E1%84%92%E1%85%A1%E1%84%8B%E1%85%A7-%E1%84%8C%E1%85%A1%E1%86%A8%E1%84%8B%E1%85%A5%E1%86%B8%E1%84%8B%E1%85%B3%E1%86%AF-%E1%84%89%E1%85%AE%E1%84%92%E1%85%A2%E1%86%BC%E1%84%92%E1%85%A1%E1%84%82%E1%85%B3%E1%86%AB-%E1%84%83%E1%85%A9%E1%84%8C%E1%85%AE%E1%86%BC-%E1%84%86%E1%85%AE%E1%86%AB%E1%84%86%E1%85%A2%E1%86%A8-%E1%84%80%E1%85%AD%E1%84%92%E1%85%AA%E1%86%AB%E1%84%8B%E1%85%B5-%E1%84%87%E1%85%A1%E1%86%AF%E1%84%89%E1%85%A2%E1%86%BC%E1%84%92%E1%85%A1%E1%86%AF-%E1%84%84%E1%85%A2)프로세스가 'System Call'을 하여 커널 모드로 진입하여 작업을 수행하는 도중 문맥 교환(context switching)이 발생할 때!**
58 | - 문제점 : 프로세스1이 커널모드에서 데이터를 조작하는 도중, 시간이 초과되어 CPU 제어권이 프로세스2로 넘어가 같은 데이터를 조작하는 경우 ( 프로세스2가 작업에 반영되지 않음 )
59 | - 해결법 : 프로세스가 커널모드에서 작업을 하는 경우 시간이 초과되어도 CPU 제어권이 다른 프로세스에게 넘어가지 않도록 함
60 | 3. **[#](https://gyoogle.dev/blog/computer-science/operating-system/Race%20Condition.html#%E1%84%86%E1%85%A5%E1%86%AF%E1%84%90%E1%85%B5-%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%89%E1%85%A6%E1%84%89%E1%85%A5-%E1%84%92%E1%85%AA%E1%86%AB%E1%84%80%E1%85%A7%E1%86%BC%E1%84%8B%E1%85%A6%E1%84%89%E1%85%A5-%E1%84%80%E1%85%A9%E1%86%BC%E1%84%8B%E1%85%B2-%E1%84%86%E1%85%A6%E1%84%86%E1%85%A9%E1%84%85%E1%85%B5-%E1%84%82%E1%85%A2%E1%84%8B%E1%85%B4-%E1%84%8F%E1%85%A5%E1%84%82%E1%85%A5%E1%86%AF-%E1%84%83%E1%85%A6%E1%84%8B%E1%85%B5%E1%84%90%E1%85%A5%E1%84%8B%E1%85%A6-%E1%84%8C%E1%85%A5%E1%86%B8%E1%84%80%E1%85%B3%E1%86%AB%E1%84%92%E1%85%A1%E1%86%AF-%E1%84%84%E1%85%A2)멀티 프로세서 환경에서 공유 메모리 내의 커널 데이터에 접근할 때**
61 | - 문제점 : 멀티 프로세서 환경에서 2개의 CPU가 동시에 커널 내부의 공유 데이터에 접근하여 조작하는 경우
62 | - 해결법 : 커널 내부에 있는 각 공유 데이터에 접근할 때마다, 그 데이터에 대한 lock/unlock을 하는 방법이 있다.
63 |
64 | ## Additional Reference
65 |
66 | [https://sujinnaljin.medium.com/ios-차근차근-시작하는-gcd-12-c06b599fe7f5](https://sujinnaljin.medium.com/ios-%EC%B0%A8%EA%B7%BC%EC%B0%A8%EA%B7%BC-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-gcd-12-c06b599fe7f5) (경쟁 상태)
67 |
68 | [https://dev-workplace.tistory.com/10](https://dev-workplace.tistory.com/10) (디스패치 큐란?)
69 |
70 | [https://developer.apple.com/documentation/dispatch/dispatchqueue](https://developer.apple.com/documentation/dispatch/dispatchqueue) (Apple Documentation)
71 |
--------------------------------------------------------------------------------
/Computer Science/Data Structure/Array, Array List, Linked List 차이점.md:
--------------------------------------------------------------------------------
1 |
2 | Array, Array List, Linked List 의 차이점을 공부해보자.
3 |
4 | # 🟣 개념 살펴보기
5 |
6 | ## ⚠️ swift에서도 Array vs. List , Array vs. Array List 를 비교하는 것이 맞는 것일까?
7 | 잠깐, 인터넷을 찾아보니 Swift에서는 Array와 ArrayList를 구별해서 사용하지 않는 것 같다. 기본적으로 JAVA에서는 Array는 크기가 정해져있는 배열, Array List는 크기가 동적으로 움직이는 배열을 의미하는데, Swift에서는 Array의 capacity는 동적으로 움직인다. 그리고 크기가 정해진채로 Array를 선언 가능하지만, append로 자유롭게 데이터를 삽입할 수 있고, 이에 따라 capacity가 동적으로 움직일 수 있다.
8 |
9 | 더불어 타 언어는 List와 Array가 따로 존재하는데, swift는 List 자료형이 따로 있지 않다. 보통 List와 Array는 'index'가 무엇을 의미하는가에 차이가 있다.
10 |
11 | ### ⁉️ 여기서 궁금한건, 진짜로 Swift에서는 이런 비교가 무의미한 것인가?
12 |
13 |
14 | 일단 기본적인 개념은 알고 가야 자료구조를 이해하기 편할 것 같으니, 마저 공부해보자.
15 |
16 | ## 🟪 Array 란?
17 | ##### 👉 Array 섹션 보러가기 (머지되면 링크 붙여넣기)
18 |
19 | - 데이터가 많아지고 그룹 관리의 필요에 따라 배열을 사용
20 | - 고정된 크기를 갖는 같은 자료형의 원소들이 연속적인 형태로 구성된 자료구조
21 | - 인덱스에 따라 값을 유지하므로, 원소가 삭제되어도 빈자리가 남게되어 메모리가 낭비될 수 있다.
22 | - 처음 크기를 10으로 지정했다면, 5개의 데이터만 저장하더라도 실제 크기는 10이다
23 | - Index의 의미: 각 원소의 번호로 0부터 시작하며, 해당 원소에 접근할대 이용한다. (해당 값의 고유 식별자)
24 | - 데이터의 갯수가 확실하게 정해져 있다.
25 | - 연속적인 만큼 인덱스로 random access가 가능하다.
26 | - 삽입과 삭제의 경우, 연속적인 형태 유지를 위해 shift연산을 수행해야하므로 O(n)의 시간복잡도를 갖는다.
27 |
28 | 앞에서 공부했듯이, 배열은 새로운 데이터를 추가할 수 없다는 한계를 갖고 있다. (수정과 삭제는 가능)
29 | 그럼, 이런 배열의 처음, 중간, 끝에 데이터를 추가하기 위해서는 어떻게 해야할까?
30 |
31 | 바로 list를 사용하는 방법이 있다.
32 |
33 |
34 | ## 🟪 List 란?
35 |
36 | - 배열의 문제점을 해결하기 위한 자료구조
37 | - 빈틈없는 데이터의 적재
38 | - 원소를 삭제했을 때, 삭제된 데이터 뒤 원소로 빈틈없이 연속적으로 위치 -> 메모리낭비 X
39 | - Index의 의미: 배열에서는 인덱스가 유일무이한 식별자이지만, 리스트에서는 몇번째에 위치하는지 정도의 의미만 갖는다.
40 | - 빈 element를 허용하지 않음.
41 | - 언어별로 지원하는 list가 다르다.
42 | - **최근언어: 리스트를 기본으로 제공**
43 | - 아무래도 swift는 array라고 칭하는 것이 모두 list의 특징을 갖는것 같다. 즉, list로 제공된다.
44 | - C: list지원 x
45 | - JS: 배열에 리스트 기능 포함
46 | - Python: 기본 리스트, 배열을 지원하지 않음. (배열과 리스트 구분이 없음)
47 | - JAVA: 배열과 리스트 모두 지원, ArrayList, LinkedList로 나뉜다.
48 |
49 | List는 배열과 같이 그룹화된 자료구조이지만, 순서가있다. 배열의 index도 순서가 있지만, 배열의 index는 위치를 나타내는 개념이 강하다. 하지만 List의 index는 '몇번째 데이터인가'에 대한 개념이다. 즉, array에서의 index는 유일무이 식별자, List에서는 데이터의 순서를 나타내는 수!
50 |
51 |
52 | ## 🟣 List를 만드는 방법
53 | List를 만드는 방법은 두 가지가 있다.
54 |
55 | ### 🟪 Array List
56 | Array의 주요 특성인 index 라는 특성을 이용해서 데이터에 접근 및 조작한다. 이 index를 활용하면 해당 index의 element값을 바로 반환해줄 수 있는 장점이 있다.
57 |
58 | 하지만 Array 의 특성을 그대로 가져오기때문에, 메로리에 일렬로 저장된다. 그래서 추가 및 삭제 시 해당 인덱스 뒤에있는 모든 값들을 당겨주거나, 밀어주면서 동작한다. (비효율!)
59 |
60 |
61 | ### 🟪 Linked List
62 | 👉 Linked List 섹션 보러가기 (여기서는 간단하게 설명) (머지되면 링크 업로드하기)
63 | Linked List는 array처럼 일렬로 메모리에 저장되지 않는다. 하나의 '노드'라는 객체로 구성되며, 객체는 본인의 value와, 다음 노드에 대한 정보를 가지고 있다. 그래서 추가 및 삭제가 발생했을때, 다음 노드에 대한 정보만 바꿔주면 되기 때문에 array보다 효율적이다. 하지만 head부터 순차적으로 탐색해야한다는 단점이 있다.
64 |
65 | # 🟣 비교하기
66 |
67 | ## 🟪 Array vs. ArrayList , Array vs. Linked List (Array를 기준으로만 비교)
68 | 해당 비교는 자바 기준으로, '자료구조 관점'에서만 비교한 내용이다. Swift에는 해당하지 않을 수 있다.
69 |
70 | | **-** | **Array** | Array List | Linked List |
71 | | --- | --- | --- | --- |
72 | | 사이즈 | 길이 고정 | dynamic한 길이. ArrayList는 사이즈를 나타내는 capacity 인스턴스 변수를 가진다. ArrayList에 요소들이 더해지면, ArrayList의 capacity가 자동으로 늘어난다. | 동적인 길이를 갖는다 |
73 | | 속도 | 초기화 시 메모리에 할당되어 속도가 빠름 | 추가 시 메모리를 재할당해야해서 속도가 느림 |
74 | | 변경 | 사이즈 변경 불가 | 삽입, 삭제 가능 (O(N)) | 삽입 삭제 가능 (O(1)), 새로운 요소에 할당된 메모리 위치 주소가 linkedlist 이전 요소에 저장된다. |
75 | | 다차원 | 가능 | 불가능|
76 | | element로 가능한 타입 | primitive type (int, char, byte), object type 모두 가능 | object type 만 가능 |
77 | | 제네릭 | 사용 불가능 | 사용가능 (타입안정성 보장) |
78 | | 길이구할때 | length 변수 | size() 메서드 사용 |
79 | | 변수 추가할 때 | assignment 연산자 사용 | add() 메서드 이용 |
80 | | 접근 | random access를 지원. 요소들을 인덱스를 통해 접근할 수 있다. 특정 요소에 접근하는 시간은 O(1) | array와 같음 | sequential Access를 지원. 어떤 요소에 접근할 때 순차적으로 검색해야한다. O(N)이 걸린다|
81 |
82 |
83 | ## 🟪 ArrayList vs. LinkedList
84 | | - | Array List | Linked List |
85 | | --- | --- | --- |
86 | | 공간적 제약 | 결국 배열이므로 크기가 고정. 새로운 요소를 추가하려고 할 때, 배열의 용량이 이미 가득 차있다면 새로운 배열 생성해주어야함. | 한개의 Node는 다른 Node에 대한 참조만 가지고 있다. 공간적 제약을 Array list에 비해 받지 않음|
87 | | 새로운 요소 삽입 (맨뒤나 맨앞) | 새로운 요소를 추가할 때, 여유 공간이 있는경우엔 O(1), 여유공간이 없으면 O(N) | 항상 O(1), 이유는 마지막 요소에서 참조값을 가지게만 하면 되기 때문에 |
88 | | access 방법 | Random Access (어떤 요소에 바로 접근하는 것). O(1) | Sequential Access (순차접근, 어떤 요소에 접근할 때 차례대로 접근하는 것, O(N) |
89 | | 중간에 요소 삽입하기 | 해당 요소의 뒤에 있는 값들을 전부 옮기고 삽입 | 앞뒤요소의 참조값만 변경 |
90 | | 중간에 요소 삭제 | 뒤에있는 요소들을 전부 앞으로 한칸씩 이동 | 앞뒤 요소의 참조값만 변경 |
91 |
92 | 이를 간단하게 요약하자면 아래 이미지와 같다.
93 |
94 |
95 |
96 |
97 | # 핵심 포인트 정리!!
98 | 지금까지 작성한 내용은 모두 '자바'에 기반한, 자료구조적 설명이다. swift에서는 Array와 Array list를 따로 지원하지 않지만, 자료구조를 공부하면서 이들의 차이점은 정확하게 알고 넘어가야하기 때문에 알아두도록 하자.
99 |
100 | - 핵심 포인트는, Array는 random access , linked list는 sequential access 기 때문에 시간복잡도에서 차이가 난다는 점
101 |
102 |
103 |
104 |
105 | ## 📖 References
106 | [Array 와 List](https://jinsangjin.tistory.com/80)
107 | [마지막 세가지 핵심포인트 설명 캡쳐 이미지 출처](https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Data%20Structure/Array%20vs%20ArrayList%20vs%20LinkedList.md)
108 | [ArrayList vs LinkedList](https://velog.io/@humblechoi/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-ArrayList-vs-LinkedList)
109 | [Array vs ArrayList](https://velog.io/@humblechoi/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Array-vs-ArrayList)
110 | [Array vs LinkedList](https://velog.io/@humblechoi/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-Array-vs-LinkedList)
111 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/프로세스vs스레드.md:
--------------------------------------------------------------------------------
1 | // 22.09.07 Noel
2 |
3 |
4 |
5 | # ❤️ 프로세스 VS 스레드
6 |
7 |
8 |
9 | ### 🤔 프로그램(Program)이란?
10 |
11 | > 컴퓨터에서 실행할 수 있는 파일
12 |
13 | - 윈도우의 경우 확장자가 .exe 인 파일들
14 |
15 |
16 |
17 | ### 🤔 프로세스(Process)란
18 |
19 | > 컴퓨터에서 연속적으로 실행되고 있는 컴퓨터 프로그램
20 |
21 | - 메모리에 올라와 실행되고 있는 프로그램의 인스턴스(독립적인 개체)
22 | - 운영체제로부터 시스템 자원을 항당 받는 작업의 단위
23 |
24 | - 프로그램(program)이 실행되서 돌아가고 있는 상태, 즉 컴퓨터가 어떤 일을 하고 있는 상태
25 | - 프로세스는 관리의 단위 (관리 주체는 OS)
26 |
27 | #### 특징
28 |
29 |
30 |
31 | - 프로세스는 `각각 독립된 메모리 영역(Code, Data, Stack, Heap의 구조)을 할당` 받음
32 |
33 | | 구분 | 내용 |
34 | | --------- | ------------------------------------------------------------ |
35 | | **Code** | 코드 자체를 구성하는 메모리 영역(프로그램 명령) |
36 | | **Data** | 전역변수, 정적변수, 배열 등
- 초기화 된 데이터는 Data 영역에 저장
- 초기화 되지 않은 데이터는 bss 영역에 저장 |
37 | | **Heap** | 동적 할당 시 사용 (new(), malloc() 등) |
38 | | **Stack** | 지역변수, 매개변수, 리턴 값 (임시 메모리 영역) |
39 |
40 | - 프로세스(Process) 하나당 `최소 1개의 스레드(Thread)가 존재`
41 | - 각 프로세스는 `OS에서 별도의 주소공간을 할당`해줘 그 곳에서 실행되며,
42 | - 한 프로세스는 `다른 프로세스의 변수나 자료구조에 접근할 수 없음`
43 | - 한 프로세스가 다른 프로세스의 자원에 접근하려면 `프로세스 간의 통신(IPC, inter-process communication)을 사용`해야함
44 |
45 |
46 |
47 |
48 |
49 | ### 🤔 스레드(Thread)란
50 |
51 | > 프로세스 내에서 실행되는 여러 흐름 단위
52 | >
53 | > 프로그램 내에서 다른 코드와 독립되어 실행될 수 있는 최소단위의 *instruction Sequence*
54 |
55 | - 프로세스가 할당받은 자원을 이용하는 실행의 단위
56 |
57 | - 프로세스 = 연산꺼리, 고로 흐름(스레드)이 있는데 `최소 1개 ~ n개`가 있을 수 있음
58 |
59 | - 한 프로세스 안에도 여러 개의 작업들이 동시에 진행 될 필요가 있음
60 | - 여러 개의 흐름(스레드)이 있는 경우, 동시에 각자 작동❗️
61 | - 한 프로세스에서 개별화된 코드의 실행이 스레드!
62 |
63 | ``` 예시
64 | 크롬에서
65 | ① 게임을 다운받는 동시에,
66 | ② 웹 서핑도 할 수 있어야하고
67 | ③ 유튜브 영상의 데이터를 받아오면서, 받아진 데이터로 영상을 재생할 수 있어야함
68 | ```
69 |
70 | - 특징
71 |
72 | - 스레드는 프로세스 내에서 각각` Stack만 할당`받고 `Code, Data, Heap 영역은 공유`한다.
73 | - 스레드는 한 프로세스 내의 주소 공간이나 자원들(힙 공간 등)을 `같은 프로세스 내의 스레드끼리 공유`하면서 실행
74 | - 반면 프로세스는 다른 프로세스의 메모리에 직접 접근할 수 없음
75 | - 각각의 스레드는 별도의 레지스터와 스택을 갖고 있지만, 힙 메모리는 서로 읽고 쓸 수 있음
76 | - 한 스레드가 프로세스 자원을 변경하면, 다른 이웃 스레드(sibling thread)도 변경 결과를 즉시 볼 수 있음
77 |
78 |
79 |
80 |
81 | ```요약
82 | 🗒 요약
83 | - 하나의 프로세스는 최소 하나의 스레드를 가짐
84 | - 프로세스는 독립된 공간에 할당되어 다른 프로세스에 접근이 어려움
85 | - 하나의 프로세스에는 여러 스레드가 있을 수 있음
86 | > 스레드가 여러개인 경우,스레드는 프로세스 내의 자원들을 공유하면서 동시에 각자 실행
87 | - 운영체체(OS)의 작업 최소 단위 : 프로세스(Process) / CPU의 작업 최소 단위 : 스레드(Thread)
88 | ```
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | # ❤️ 멀티 프로세스 / 멀티 스레드
99 |
100 |
101 |
102 | ### 🤔 멀티 프로세스란?
103 |
104 | - 하나의 응용프로그램을 여러 개의 프로세스로 구성하여 `각 프로세스가 하나의 작업(테스크)을 처리`하도록 하는 것
105 |
106 | | 장단점 | 내용 |
107 | | -------- | ------------------------------------------------------------ |
108 | | **장점** | ① 메모리 침범 문제를 OS 차원에서 해결
② 여러개의 자식 프로세스 중 하나에 문제가 발생 시, 그 프로세스만 타격, 다른 영향이 확산되지 않음 |
109 | | **단점** | **① Context Switching에서의 오버헤드**
> 각 프로세스가 독립된 메모리 영역을 할당받아, 프로세스 사이에서 공유되는 메모리가 없어 Context Switching 발생 시, 캐쉬에 있는 모든 데이터를 리셋하고 다시 캐쉬 정보를 불러와야 함
**② 프로세스 간의 복잡한 통신(IPC)가 필요**
>프로세스는 독립된 메모리 영역을 할당 받아, 하나의 프로그램에 속하는 프로세스 사이의 변수를 공유할 수 없음 |
110 |
111 | ```단어
112 | 💡 이해를 위한 용어 설명
113 |
114 | ① Context Switching
115 | - CPU에서 여러 프로세스를 돌아가면서 작업을 처리하는데 이 과정을 Context Switching이라고 함
116 | > 구체적으로, 동작 중인 프로세스가 대기를 하면서 해당 프로세스의 상태(Context)를 보관하고,
117 | > 대기하고 있던 다음 순서의 프로세스가 동작하면서 이전에 보관했던 프로세스의 상태를 복구하는 작업
118 |
119 | ```
120 |
121 |
122 |
123 | ### 🤔 멀티 스레드란?
124 |
125 | - 하나의 응용프로그램에서 여러 스레드를 구성해 각 스레드에게 하나의 작업을 처리하게 하는 것
126 | - 윈도우, 리눅스 등 많은 운영체제들이 멀티 프로세싱을 지원하고있지만 멀티 스레딩을 기본으로 함
127 |
128 | | 장단점 | 내용 |
129 | | -------- | ------------------------------------------------------------ |
130 | | **장점** | **① 시스템 자원 소모 감소 (자원의 효율성 증대)**
> 프로세스를 생성 해 자원을 할당하는 시스템 콜이 줄어 자원을 효율적으로 관리 할 수 있음
**② 시스템 처리량 증가 (처리 비용 감소)**
> 스레드 간 데이터를 주고 받는 것이 간단해지고 시스텀 자원 소모가 줄어듦
> 스레드 사이의 작업량이 작아 Context Switcing이 빠름
**③ 간단한 통신 방법으로 인한 프로그램 응답 시간 단축**
> 스레드는 프로세스 내의 Stack 영역을 제외한 모든 메모리를 공유하기때문에 통신의 부담이 적음 |
131 | | **단점** | ① 주의 깊은 설계가 필요
② 디버깅이 까다로움
③ 단일 프로세스 시스템의 경우 효과를 기대하기 어려움
④ 다른 프로세스에서 스레드를 제어할 수 없음 (프로세스 밖에서도 스레드 각각을 제어할 수 없음)
⑤ 멀티 스레드의 경우, 자원 공유의 문제가 발생 (동기화 문제)
⑥ 하나의 스레드에 문제 발생 시, 전체 프로세스가 영향을 받음 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 | 출처
140 |
141 | https://youtu.be/x-Lp-h_pf9Q
142 |
143 | https://youtu.be/iks_Xb9DtTM
144 |
145 | https://gmlwjd9405.github.io/2018/09/14/process-vs-thread.html
146 |
147 | https://velog.io/@nnnyeong/OS-%EB%A9%80%ED%8B%B0%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EB%A9%80%ED%8B%B0%EC%8A%A4%EB%A0%88%EB%93%9C-%EB%A9%80%ED%8B%B0-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EB%A9%80%ED%8B%B0%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EB%A9%80%ED%8B%B0%EC%8A%A4%EB%A0%88%EB%93%9C%EC%97%90%EC%84%9C%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%86%B5%EC%8B%A0
148 |
--------------------------------------------------------------------------------
/Computer Science/Software Engineering/CleanCode&Recfactoring.md:
--------------------------------------------------------------------------------
1 | # 클린코드와 리팩토링
2 |
3 | ## 클린코드란? (Clean Code)
4 |
5 | ### * 읽기 쉬운 코드가 클린 코드이다. *
6 |
7 | ```
8 | “I like my code to be elegant and efficient.
9 | The logic should be straightforward and make it hard for bugs to hide,
10 | the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy,
11 | and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations.
12 | Clean code does one thing well.”
13 |
14 | - Bjarne Stroustrup, inventor of ‘C++
15 | ```
16 |
17 | - C++의 창시자인 Bjarne Stroustrup은 C에는 객체 개념이 없기 때문에 객체지향 효과를 극대화하기 위해서 C++를 만든 것으로 유명합니다.
18 | - Bjarne Stroustrup은 위와 같이 클린코드에 대하여 정의했는데, 코드가 우아하다는 의미는 군더더기 없이 깔끔하다는 의미이고, 효과적이라는 것은 기능을 수행하는 코드를 최대한 작은 라인으로 구현한다는 의미로 보면 됩니다.
19 | - 또한 클린코드는 직접적이고 에러 처리가 잘 되어 있으며 하나의 역할을 수행한다고 합니다.
20 |
21 | ```
22 | “Clean code is simple and direct. Clean code reads like well-written prose.
23 | Clean code never obscures the designers’ intent but rather is full of crisp abstractions and straightforward lines of control.”
24 |
25 | - Grady Booch, author of ‘Object-Oriented Analysis and Design with Applications’
26 | ```
27 |
28 | - Grady Booch는 James Rumbaugh, Ivar Jacobson과 함께 UML(Unified Modeling Language)을 창시한 사람입니다.
29 | - Grady Booch의 '클린코드가 단순하고 직접적이다’라는 말은 앞에서 설명한 내용과 동일한 의미입니다.
30 | - 또한 그렇게 함으로써 클린코드는 결코 원작자의 의도를 숨기지 않는다고 합니다.
31 |
32 |
33 | __이렇듯 Bjarne Stroustrup과 Grady Booch의 의견을 종합해 볼 때 클린코드의 가장 중요한 요소 중 하나는 가독성이라고 볼 수 있습니다.__
34 | __즉, 모든 팀원이 이해(understandability)하기 쉽도록 작성된 코드인 것이죠.__
35 |
36 | ## 클린코드 작성의 이유: 가독성 그리고 Technical Debt
37 |
38 | ### * 가독성은 왜 중요한걸까? *
39 | > 일반적으로 기존 코드를 변경하고자 할 때, 해석하는 시간과 수정하는 비율이 10:1이라고 합니다.
40 | > 예를 들면 코드를 변경하기 위해서 걸리는 전체 시간이 10시간이라고 하면, 사전에 코드를 분석하는 시간이 9시간 이상 걸린다는 말로 이해하면 쉬울 것 같습니다.
41 |
42 | > 그렇다면 해석이 어려운 코드는 그만큼 분석에 소요되는 시간이 더 오래 걸리겠죠?
43 | > 더욱이 대부분의 결함은 기존 코드를 수정하는 동안에 발생한다고 하니 이해하기 쉬운 코드야말로 오류의 위험성을 최소화하는 셈입니다.
44 | > 따라서 이해하기 쉽게 코드를 작성하는 것이 가장 중요하다고 볼 수 있습니다.
45 |
46 | ### * Technical Debt의 발생 *
47 |
48 |
49 |
50 | > 이 그림을 보면 왜 클린코드를 작성해야 하는지에 대한 또 다른 설명이 될 것 같습니다. 변경 비용과 대응속도에 대한 이상치와 실제 프로젝트에서 발생하는 수치를 비교해 보았습니다.
51 |
52 | - 왼쪽의 그래프는 시간이 지나감에 따라 들어가는 변경비용으로, 이상적인 변경비용은 일관되게 낮지만 실제 변경비용은 증가함을 볼 수 있습니다.
53 | - 오른쪽의 그래프는 시간이 지나감에 따른 고객 요구사항의 대응속도로, 이상적인 대응속도는 일관되게 높지만 실제 대응속도는 점점 낮아짐을 볼 수 있습니다.
54 |
55 | > 이러한 차이가 생기는 이유는 프로젝트 초기에 클린코드로 개발하기 보다는 좀더 빠르고 쉬운 방법을 선택하기 때문입니다.
56 | > 대표적인 것이 'copy & paste'인데요. 이로 인하여 이상적인 변경 비용과의 차이가 나는 부분이 다음 그림의 Technical Debt입니다.
57 | > 즉 클린코드 작성을 위해 개발자들이 언젠가 해결해야 되는 부채인 셈입니다.
58 |
59 |
60 |
61 | ## 클린코드 작성 원칙
62 |
63 |
64 |
65 |
66 | > 일반적인 사항으로는 다들 잘 알고 있는 것처럼 Coding 표준을 준수하고 단순하게 만들어서 가독성을 높이는 방법입니다.
67 | > Boy Scout Rule은 개발자로서 내가 담당하게 된 시스템을 내가 담당하기 이전의 코드보다 더 클린하게 만들자는 원칙인데요,
68 | > 그런 과정을 거치면서 대규모 레가시 코드들도 점점 더 클린해질 수 있겠죠?
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | 이 외에 클린 코드를 위한 고려사항들
77 | - 1. 의미 있는 변수명
78 | - 2. 명확하고 간결한 주석
79 | - 함수의 주요 세부사항은 주석으로 남기기 (함수 선언으로는 알 수 없는 내용들)
80 | - 보기 좋게 배치하고 꾸미기 (여러개의 그룹-문단으로 나누기) + 열 정렬
81 | - 3. 읽기 쉽게 흐름제어 만들기
82 | - 삼항 연산자는 꼭 필요할때만
83 | - do-while은 피하라
84 | - 부정문 보다는 긍정문을 사용하라
85 | - 4. 함수는 가급적 작게, 하나의 작업만 수행하도록
86 |
87 |
88 | #### ** Swift 기준의 클린코드 예시는 아래 링크를 참고하면 좋을듯 **
89 | - https://ios-development.tistory.com/category/Clean%20Code%20%28%ED%81%B4%EB%A6%B0%20%EC%BD%94%EB%93%9C%29?page=2
90 |
91 |
92 | ## 리팩토링이란? (Refactoring)
93 | - 리팩토링은 외부 동작을 바꾸지 않으면서 내부 구조를 개선하는 방법으로, 소프트웨어 시스템을 변경하는 프로세스이다.
94 | - 소프트웨어를 보다 이해하기 쉽고, 수정하기 쉽도록 만드는 것,
95 | - 겉으로 보이는 소프트웨어의 기능을 변경하지 않는 것.
96 |
97 | ## 리팩토링의 목적
98 | - 리팩토링은 성능을 최적화시키는 것이 아니다.
99 | - 코드를 신속하게 개발할 수 있게 만들어주고, 코드 품질을 좋게 만들어준다.
100 |
101 | ## 리팩토링이 필요한 상황 및 코드
102 | - 상황: 소프트웨어에 새로운 기능을 추가해야할 때
103 | - 코드:
104 | - 중복코드
105 | - 긴 메소드
106 | - 거대한 클래스
107 | - Switch문
108 | - 절차지향으로 구현한 코드
109 |
110 | ## 리팩토링의 과정
111 | #### 테스트
112 | - 현재 작동하는 코드들이 정상적으로 작동하는 것을 유지하되,
113 | - 내부적으로 코드를 개선해 이해하고 수정하기 쉽게 만드는 작업
114 | #### 함수 쪼개기
115 | - 추상화 수준을 높여 같은 일을 하는 것들을 추출하라
116 | - 추출한 것들을 따로 함수로 만들어 함수는 최대한 작게 만들어라
117 | #### 임시 변수 제거하기
118 | - 임시변수란 값이 한 번만 대입되고 변경되지 않는 변수이다.
119 | - 임시변수는 과감히 지우고 부수효과를 테스트하자.
120 |
121 | ## 클린코드와 리팩토링의 차이??
122 | - 비슷하지만 리팩토링이 클린코드에 비해 조금 더 큰 개념이라고 볼 수 있다.
123 | - 클린 코드는 단순하게 가독성을 높이기 위한 작업이라면,
124 | - 리팩토링은 클린 코드를 포함하여 유지보수를 위한 코드의 개선이라고 볼 수 있다.
125 | - 클린 코드와 같은 부분은 설계단계에서 잘 이루어져 있는 것이 중요하고, 리팩토링은 결과물이 나온 이후 수정이나 추가 작업이 진행될 때 개선해 나가야 한다.
126 |
127 |
128 | ## Reference
129 | - Clean Code - Robert C Martin
130 | - Clean Code Cheat Sheet - Urs Enzler
131 | - https://www.samsungsds.com/kr/insights/cleancode-0823.html
132 | - https://beforb.tistory.com/3#recentEntries
133 | - https://ablue-1.tistory.com/83
134 |
135 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/fileSystem.md:
--------------------------------------------------------------------------------
1 | # File and File System
2 | ### 파일(File)
3 | #### 파일은 논리적인 저장 단위로, 관련된 정보 자료들의 집합에 이름을 붙인 것이다. 컴퓨터 시스템의 편리한 사용을 위해 정보 저장의 일괄된 논리적 관점을 제공한다. 일반적으로 레코드(Record) 혹은 블록(Block) 단위로 비휘발성 보조기억장치에 저장된다.
4 |
5 | ### 파일 속성(File Attribute) 또는 파일의 메타데이터(metadata)
6 | #### 파일을 관리하기 위한 각종 정보들이다. 파일 자체의 내용은 아니다. 파일 이름, 유형, 저장된 위치, 파일 사이즈, 접근 권한, 소유자, 시간(생성/변경/사용) 등 파일에 대한 전반적인 정보를 말한다.
7 |
8 | ### 파일 시스템(File System)
9 | #### 운영체제와 모든 데이터, 프로그램의 저장과 접근을 위한 기법을 제공한다. 시스템 내의 모든 파일에 관한 정보를 제공하는 계층적 디렉토리 구조이고, 파일 및 파일의 메타데이터, 디렉토리 정보 등을 관리한다.
10 |
11 | ### 파티션(Partition)
12 | #### 연속된 저장 공간을 하나 이상의 연속되고 독립적인 영역으로 나누어 사용할 수 있도록 정의한 규약이다. 하나의 물리적 디스크 안에 여러 파티션을 두는 게 일반적이지만, 여러 물리적 디스크를 하나의 파티션으로 구성하기도 한다.
13 |
14 | # Access Methods
15 | #### 시스템이 제공하는 파일 정보의 접근 방식으로는 순차 접근(Sequential Access)과 직접 접근(Direct Acceess, Random Access), 색인 접근(Index Access)으로 나뉜다.
16 |
17 | ### 순차 접근(Sequential Access)
18 | #### 가장 단순한 방법으로 파일의 정보가 레코드 순서대로 처리된다. 카세트테이프를 사용하는 방식돠 동일하다. 현재 위치에서 읽거나 쓰면 offset이 자동으로 증가하고, 뒤로 돌아가기 위해선 되감기가 필요하다.
19 | 
20 |
21 | ### 직접 접근(Random Access)
22 | #### 파일의 레코드를 임의의 순서로 접근할 수 있다. LP판을 사용하는 방식과 동일하다. 읽기나 쓰기의 순서에 제약이 없으며 현재 위치를 유지할 수 있다면 이를 통해 순차 접근 기능도 구현할 수 있다.
23 |
24 | ### 색인 접근(Index Access)
25 | #### 파일에서 레코드를 찾기 위해 색인을 먼저 찾고 대응되는 포인터를 얻는다. 이를 통해 파일에 직접 접근하여 원하는 데이터를 얻을 수 있다. 따라서 크기가 큰 파일에서 유용하다.
26 | 
27 |
28 | # Directory
29 | #### 디렉토리는 파일의 메타데이터 중 일부를 보관하고 있는 일종의 특별한 파일이다. 해당 디렉토리에 속한 파일 이름과 속성들을 포함하고 있고, 다음과 같은 기능들을 제공한다.
30 | - 파일 찾기(Search)
31 | - 파일 생성(Create)
32 | - 파일 삭제(Delete)
33 | - 디렉터리 나열(List)
34 | - 파일 재명명(Rename)
35 | - 파일 시스템 순회(Traverse)
36 |
37 | #### 디렉토리는 어떻게 구성되어야 할까?
38 | #### 기본적으로 디렉토리의 파일을 빠르게 탐색할 수 있어야 할 것이다. 또 적절한 이름으로 사용자들이 편리하게 사용할 수 있으면 좋을 것이다. 그리고 파일들을 적절한 분류로 그룹화해두면 사용하기 편리할 것이다. 이를 위해 티렉토리의 논리적 구조를 정의하는 여러 방법들이 있다ㅏ.
39 |
40 | ### 1단계 디렉토리(Single-Level Directory)
41 | #### 1단계 디렉터리는 모든 파일들이 디렉터리 밑에 존재하는 형태이다. 파일들은 서로 유일한 이름을 가지고 서로 다른 사용자라도 같은 이름을 사용할 수 없다. 지원하기도 쉽고 이해하기도 쉽지만, 파일이 많아지거나 다수의 사용자가 사용하는 시스템에서는 심각한 제약을 갖는다.
42 |
43 | 
44 |
45 | ### 2단계 디렉토리(Two-Level Directory)
46 | #### 2단계 디렉토리는 각 사용자별로 별도의 디렉토리를 갖는 형태이다.
47 |
48 | 
49 |
50 | #### UFD : 자신만의 사용자 파일 디렉토리
51 | #### MFD : 사용자의 이름과 계정 번호로 색인되어 있는 디렉토리. 각 엔트리는 사용자의 UFD를 가리킨다.
52 | #### 서로 다른 사용자가 같은 이름의 파일을 가질 수 있고 효율적인 탐색이 가능하다. 하지만 그룹화가 불가능하고, 다른 사용자의 파일에 접근해야 하는 경우에는 단점이 된다.
53 |
54 | ### 트리 구조 디렉토리(Tree-Structured Directory)
55 | #### 사용자들이 자신의 서브 디렉토리(Sub-Directory)를 만들어서 파일을 구성할 수 있다. 하나의 루트 디렉토리를 가지며 모든 파일은 고유한 경로(절대 경로/상대 경로)를 가진다. 이를 통해 효율적인 탐색이 가능하고, 그룹화가 가능하다. 디렉터리는 일종의 파일이므로 일반 파일인지 디렉터리인지 구분할 필요가 있다. 이를 bit를 사용하여 0이면 일반 파일, 1이면 디렉터리로 구분한다.
56 |
57 | 
58 |
59 | ### 비순환 그래프 디렉토리(Acyclic-Graph Directory)
60 | #### 디렉토리들이 서브 디렉토리들과 파일을 공유할 수 있도록 한다. 트리 구조의 디렉토리를 일반화한 형태이다. 단순한 트리 구조보다는 더 복잡한 구조이기 때문에 몇몇 문제가 발생할 수 있다. 파일을 무작정 삭제하게 되면 현재 파일을 가리키는 포인터는 대상이 사라지게 된다. 따라서 참조되는 파일에 참조 계수를 두어서, 참조 계수가 0이 되면 파일을 참조하는 링크가 존재하지 않는다는 의미이므로 그때 파일을 삭제할 수 있도록 한다.
61 |
62 | 
63 |
64 | ### 일반 그래프 디렉토리(General Graph Directory)
65 | #### 순환을 허용하는 그래프 구조이다. 순환이 허용되면 무한 루프에 빠질 수 있다. 따라서, 하위 디렉터리가 아닌 파일에 대한 링크만 허용하거나 garbage collection을 통해 전체 파일 시스템을 순회하고, 접근 가능한 모든 것을 표시한다.
66 |
67 | 
68 |
69 | # Allocation of File Data in Disk
70 | #### 파일 데이터를 디스크에 할당하는 방법으로 다음 세 방식이 존재한다.
71 | - Contiguous Allocation
72 | - Linked Allocation
73 | - Indexed Allocation
74 |
75 | ### 1. Contiguous Allocation
76 | #### 연속 할당(Contiguous Allocation)은 말 그대로 파일을 디스크에 연속되게 저장하는 방식이다. 디렉터리에는 파일이 시작 부분의 위치와 파일의 길이에 대한 정보를 저장하면 전체를 탐색할 수 있다.
77 |
78 | 
79 |
80 | #### 이 방식은 연속적으로 저장되어 있으므로 한 번의 탐색으로 많은 양을 전송할 수 있다. 그리고 Random access가 가능하다. 하지만, 외부 단편화가 발생하며, 파일의 크기를 키우기가 어렵다. 파일의 커질 가능성을 고려해서 미리 큰 공간을 할당한다면 내부 단편화가 발생할 수도 있다.
81 |
82 | ### 2. Linked Allocation
83 | #### 연결 할당(Linked Allocation)은, 연속적으로 할당하지 않고 빈 위치면 자유롭게 할당될 수 있다. 그리고 다음 읽어야 할 위치를 연결 리스트처럼 포인터로 가리킨다. 따라서 디렉터리에는 파일이 시작하는 위치와 끝나는 위치만 저장된다.
84 |
85 | 
86 |
87 | #### 이 방식은 외부 단편화가 발생하지 않는다는 단점이 있다. 하지만, Random access가 불가능하고, 포인터를 위한 공간이 block의 일부가 되어 공간 효율성을 떨어뜨린다. 주로 한 sector당 512byte를 배정하는데, 4byte의 포인터를 위한 공간이 사용되면 512byte의 배수로 할당하기 위해서는 포인터를 위해 한 sector만큼 공간이 소모되는 비효율이 발생한다. 또, 만약 한 sector가 고장 나 포인터가 유실되면 많은 부분을 잃게 되는 신뢰성 문제도 있다.
88 |
89 | #### 이러한 단점을 보완하기 위해 FAT(File-allocation table)이라는 파일 시스템을 사용한다. 이는 포인터를 별도의 위치에 보관하여 신뢰성 문제와 공간 효율성 문제를 해결한다.
90 |
91 | ### 3. Indexed Allocation
92 | #### 색인 할당(Indexed Allocation)은 한 블록에 하나의 파일에 대한 데이터의 index들을 모두 저장하는 방식이다. 따라서 디렉터리에는 해당 블록의 위치만 담게 된다.
93 |
94 | 
95 |
96 | #### 이 방식은 외부 단편화가 발생하지 않으며 Random access가 가능하다. 다만, 작은 파일인 경우 위치를 저장하는 블록의 공간 낭비가 생기고, 너무 큰 파일인 경우엔 하나의 블록으로 파일의 index들을 모두 저장하기에 부족하게 되는 단점이 있다.
97 |
--------------------------------------------------------------------------------
/Computer Science/Software Engineering/TDD&UnitTest.md:
--------------------------------------------------------------------------------
1 | // 2022.09.19 Rookie
2 |
3 | ### **TDD(Test Driven Development) : 테스트 주도 개발**
4 |
5 | 테스트 주도 개발은 말 그대로 개발을 하는데에 있어서 테스트가 주가 된다는 하나의 개발 방법론이다. 먼저 테스트를 하면서 코드를 작성하고 그 후에 본 코드를 구현하는 방식이다. 테스트를 거친 후에 코드를 작성한다면 추후에 신경 써줘야할 많은 부분들에 대해서 해결을 하면서 코드를 작성할 수 있겠다
6 |
7 |
8 |
9 |
10 | 문서를 잘 작성하는 방법은 검토와 고쳐쓰기라고 생각한다
11 | 어떤 책에서 개발자는 “컴퓨터가 잘 알아듣는 문서를 작성하는 사람” 이라는 문구를 본적이 있다. 그리고 개인적으로 저는 여기에 아주 동감…
12 |
13 | 따라서 좋은 코드를 만들기위해 반복적으로 코드를 검사하고 다시 고치는 방식으로 소프트웨어를 개발하는 방법을 고안해낸 것을 **TDD 라고 한다!**
14 |
15 | 앱을 몇번 개발해보면 나중에 이거는 어떻게 고쳐야하나… 처음부터 잘 짤걸하는 깨달음을 얻은 적이 있으실 텐데요… 그런것들을 방지할 수 있는 방법론입니다.
16 |
17 | ### 장점
18 |
19 | 1. 작업과 동시에 테스트를 진행하면서 실시간으로 오류 파악이 가능함 ( 시스템 결함 방지 )
20 |
21 | 2. 짧은 개발 주기를 통해 고객의 요구사항 빠르게 수용 가능. 피드백이 가능하고 진행 상황 파악이 쉬움
22 |
23 | 3. 자동화 도구를 이용한 TDD 테스트케이스를 단위 테스트로 사용이 가능함
24 |
25 | (자바는 JUnit, C와 C++은 CppUnit 등)
26 |
27 | 개발자가 기대하는 앱의 동작에 관한 문서를 테스트가 제공해줌
28 | 또한 이 테스트 케이스는 코드와 함께 업데이트 되므로 문서 작성과 거리가 먼 개발자에게 매우 좋다고 한다!
29 |
30 | ### 단점
31 |
32 | 1. 기존 개발 프로세스에 테스트케이스 설계가 추가되므로 생산 비용 증가
33 |
34 | 2. 테스트의 방향성, 프로젝트 성격에 따른 테스트 프레임워크 선택 등 추가로 고려할 부분의 증가
35 |
36 |
37 |
38 | #### 아니 근데,,, 상식적으로 테스트를 할려면 뭘 만들어야 테스트 할 수 있는 거아님?? 작업과 테스트를 동시에 진행한다는게 무슨 말일까?? 그래서 제가 한번 찾아봤습니다..
39 |
40 | #### xCode는 UnitTest라는 기능을 사용해서 TDD를 주도할 수 있습니다.
41 |
42 | #### 다음 예시를 따라가보면서 어떤식으로 TDD를 한다는건지 알아봅시다
43 |
44 |
45 | ## TDD 실습
46 | #### Xcode 프로젝트 생성시 Include Tests를 사용해서 TDD를 진행할 수 있다.
47 |
48 |
49 | ### 혹은
50 | #### 하단 툴바에서 + 버튼을 눌러 UnitTest 번들을 추가할 수 있다.
51 |
52 |
53 | ## Objective
54 | 10진수를 넣으면 소수점 뒷 자리까지 잘 표기해주는 텍스트 포매팅 함수 기능을 TDD 방식으로 개발해보자
55 |
56 | ## Test Setting
57 |
58 |
59 | swift 파일안에는 test를 위한 클래스와 메소드들이 내장되어있는데, 빌드를 하면 다음과 같은 함수의 실행여부를 체크해준다. 그리고 저 체크박스를 클릭하면, 개별적인 함수의 수행여부도 테스트할 수 있음
60 |
61 | ## Customize
62 | #### Test 케이스를 커스텀하기 위해서는 일단 UnitTest Class 파일을 만들어여한다.
63 |
64 |
65 | ##
66 | #### 테스트 할 앱과 테스트 코드는 별개의 파일이므로 테스트 할 앱을 구성하는 코드를 다음 방법으로 가져와야한다.
67 | 1. 테스트할 모듈을 import
68 | 2. @testable 키워드 붙이기
69 |
70 |
71 | #### 그리고 XCTest 클래스 안에는 테스트를 위한 여러 메소드들이 내장되어있다. 조건을 입력하고 T/F 에 따라 결과를 반환하는 것과, 두 개의 함수 반환값을 비교해서 성공/실패를 나눌 수 있는 함수등...
72 |
73 |
74 | ## Test Code
75 |
76 | #### 다음과 같이 decimal 타입을 문자열로 반환해주는 함수가 있다. 이 함수의 결과값을 예시로 다음과 같이 비교해서 테스트를 해볼 수 있다
77 |
78 |
79 |
80 |
81 |
82 | #### 내 생각에 TDD 방식은 일종의 퀴즈 같은 것이다.
83 | 내가 이 테스트를 통과하도록 코드를 짜고 싶으면 어떻게 해야하지? 를 먼저 설정해놓고 그에 맞게 돌아가서 코드를 고치는 것임!
84 | 예를 들어서 위의 테스트를 통과하려면 stirng 함수의 반환값을 "0.00"에 맞춰야한다. 그럼 MoneyFormatter 파일에 들어가서 그 부분만 고치는 방식의 상당히 목적지향?적이고 재밌는 방식이라는 생각이 들었다
85 |
86 |
87 |
88 | ###
89 |
90 | 다음과 같이 여러 케이스에 대해서 테스트를 진행해서 에러없는 기능을 개발할 수 있습니다.
91 |
92 |
93 | ### 예시
94 | 이렇게 개발했는데 테스트에서는 전부 오류다. 엥 뭐가 문제지?
95 |
96 |
97 | #### 함수에서 반환하는 스트링에 빈 문자열이 껴있는 실수를 발견할 수 있었다.
98 |
99 | ### 고치고 다시해보면....
100 |
101 |
102 | ### 잘 빌드되는 모습을 볼 수 있다
103 |
104 |
105 | ## 테스트 추가, 기능 추가
106 | #### 자 이제 1.1은 1.10이 되도록 변환하는 테스트를 만들어놓고 (목적설정) 그에 맞게 기존 함수를 수정해보자
107 |
108 | ###
109 |
110 | 이렇게 끝자리수 조정을 해주면 끝!
111 |
112 | ## 응용
113 | 내가 만든 계산기에 Unit Test를 시도해봤다.
114 | ###
115 |
116 |
117 | #### 0으로 나눈 값에서는 에러를, 곱셉 연산 예시에서는 통과를 나타내는 것을 볼 수 있다.
118 |
119 | ## Summary
120 | #### iOS 개발에서 TDD는 xCode의 UnitTest를 사용해서 진행한다.
121 | #### TDD는 개발자가 특정 기능을 구현하는 단계에서 초기부터 에러나 예외사항 없이 꼼꼼한 개발을 도와준다.
122 | #### 꼼꼼한 만큼 정확하겠지만 위에 보는 바와같이 시간이 많이 걸릴 수 밖에 없다
123 |
124 | ## Reference
125 | https://www.youtube.com/watch?v=B4yJ85IaTUw
126 |
127 |
128 |
129 | https://github.com/Rookie0031/Swift-Questions/issues/27
130 |
131 |
132 |
--------------------------------------------------------------------------------
/Computer Science/Data Structure/트리와 이진트리 (tree, binary-tree).md:
--------------------------------------------------------------------------------
1 | # 트리와 이진트리 (Tree & Binary Tree)
2 |
3 | 자료구조에는 선형 자료구조와 비선형 자료구조가 있는데, 트리와 이진트리에 대한 개념은 비선형 자료구조에 속한다.
4 |
5 | 간단하게 선형 자료구조와 비선형 자료구조의 특징을 이야기하자면,
6 | 선형 자료구조는 요소가 일렬로 나열되어 있는 자료 구조를 말하고, 연결리스트 / 배열 / 벡터 / 스택 / 큐 등이 이에 속한다.
7 | 비선형 자료구조는 일렬로 나열하지 않고 자료 순서나 관계가 복잡한 구조를 말한다, 그래프 / 트리 / 힙 / 우선순위 큐 / 맵 / 셋(set) / 해시테이블 등이 이에 속한다.
8 |
9 |
10 | ## 그래프 (Graph)
11 |
12 | 그래프는 정점과 간선으로 이루어진 자료구조를 말한다.
13 |
14 | 정점(Vertex): 위치라는 개념, 노드라고도 불림
15 | 간선(Edge): 위치간의 관계, 노드를 연결하는 선
16 |
17 |
18 | ## 트리 (Tree)
19 |
20 | 트리는 그래프 중 하나로 그래프의 특징처럼 정점과 간선으로 이루어져 있고, 트리 구조로 배열된 일종의 계층적 데이터의 집합이다. 루트 노드, 내부 노드, 리프 노드 등으로 구성된다.
21 | 트리로 이루어진 집합을 숲이라고 한다.
22 |
23 | 
24 |
25 |
26 | ### 트리의 특징
27 | - 부모, 자식 계층 구조를 가진다.
28 | - 간선 수 = 노드 수 - 1 (V - 1 = E)
29 | - 트리 내의 어떤 노드와 어떤 노드까지의 경로는 반드시 존재한다.
30 |
31 | ### 트리의 구성
32 | - 루트 노드: 가장 위에 있는 노드. 보통 트리 문제가 나오고 트리를 탐색할때 루트 노드를 중심으로 탐색하면 문제가 쉽게 풀리는 경우가 많다.
33 | - 내부 노드: 루트 노드와 내부 노드 사이에 있는 노드를 뜻함.
34 | - 리프 노드: 리프 노드는 자식 노드가 없는 마지막 노드를 뜻함
35 |
36 | ### 트리의 높이와 레벨
37 |
38 | 
39 |
40 | - 깊이: 트리에서의 깊이는 각 노드마다 다르며, 루트 노드부터 특정 노드까지 최단 거리로 갔을 때의 거리를 말한다. 예를 들어 D 노드의 깊이는 2이다.
41 | - 높이: 트리의 높이는 루트 노드부터 리프 노드까지 거리 중 가장 긴 거리를 의미하며, 앞 그림의 트리 높이는 3이다.
42 | - 레벨: 트리의 레벨은 보통 깊이와 같은 의미를 지닌다. A 노드를 0레벨, B / C 노드를 1레벨... 로 본다.
43 | - 서브트리: 트리 내의 하위 집합을 서브트리라고 한다.
44 |
45 | ### 그래프와 트리의 차이
46 |
47 |
48 |
49 | ### 트리구조는 왜 사용할까?
50 |
51 | **트리구조에 저장하면 더 효율적인 자료들이 존재하기 때문**
52 | 예를들면, 계층적인 자료들은 트리구조를 이용하여 나타낼 경우 더 효율적이다.
53 | - 회사나 정부의 조직 구조
54 | - 나라, 지방, 시군별 계층적 데이터
55 | - 인덱스(인덱스는 계층적 자료 구조로 검색을 쉽게 해준다.)
56 |
57 | ## 이진트리 (Binary Tree)
58 |
59 | 이진 트리는 자식의 노드 수가 두 개 이하인 트리를 의미한다.
60 |
61 |
62 | ### 이진트리의 분류
63 |
64 | 
65 | 
66 | 
67 |
68 | - 정이진 트리(Full Binary Tree): 자식 노드가 0 또는 두 개인 이진 트리를 의미한다.
69 | - 완전 이진 트리(Complete Binary Tree): 왼쪽에서부터 채워져 있는 이진 트리를 의미한다. 마지막 레벨을 제외하고는 모든 레벨이 완전히 채워져 있으며, 마지막 레벨의 경우 왼쪽부터 채워져있다.
70 | - 변질 이진 트리(Degenerate Binary Tree): 자식 노드가 하나밖에 없는 이진 트리를 의미한다.
71 | - 포화 이진 트리(Perfect Binary Tree): 모든 노드가 꽉 차 있는 이진 트리를 의미한다.
72 | - 균형 이진 트리(Balanced Binary Tree): 왼쪽과 오른쪽 노드의 높이 차이가 1 이하인 이진 트리를 의미한다. map, set을 구성하는 레드 블랙 트리는 균형 이진 트리중 하나이다.
73 |
74 | ### 이진 탐색 트리
75 |
76 | 이진 탐색 트리는 노드의 오른쪽 하위 트리에는 '노드 값보다 큰 값'이 있는 노드만 포함되고, 왼쪽 하위 트리에는 '노드 값보다 작은 값'이 들어 있는 트리를 말한다.
77 | 이때 왼쪽 및 오른쪽 하위 트리도 해당 특성을 가진다. 이러면 '검색'을 하기가 용이하다.
78 | 보통 요소를 찾을 때 이진 탐색 트리의 경우 O(logn)이 걸린다. 하지만 최악의 경우 O(n)이 걸린다.
79 | 그 이유는 이진 탐색 트리는 삽입 순서에 따라 선형적일 수 있기 때문이다.
80 |
81 | ### 이진 트리 순회 방식
82 |
83 | 
84 |
85 | - 1. 전위 순회(Preorder Traverse): 뿌리(root)를 먼저 방문
86 | - 2. 중위 순회(Inorder Traverse): 왼쪽 하위 트리를 방문 후 뿌리(root)를 방문
87 | - 3. 후위 순회(Postorder Traverse): 하위 트리 모두 방문 후 뿌리(root)를 방문
88 | - 4. 층별 순회(Level Order Traverse): 위 쪽 node들 부터 아래방향으로 차례로 방문
89 |
90 | - 1. 전위 순회: 0 -> 1 -> 3 -> 7 -> 8 -> 4 -> 9 -> 10 -> 2 -> 5 -> 11 -> 6
91 | - 2. 중위 순회: 7 -> 3 -> 8 -> 1 -> 9 -> 4 -> 10 -> 0 -> 11 -> 5 -> 2 -> 6
92 | - 3. 후위 순회: 7 -> 8 -> 3 -> 9 -> 10 -> 4 -> 1 -> 11 -> 5 -> 6 -> 2 -> 0
93 | - 4. 층별 순회: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11
94 |
95 |
96 | ### 실전 코딩
97 |
98 | ```swift
99 | class Node {
100 | let value: Int
101 | var leftChild: Node?
102 | var rightChild: Node?
103 |
104 | init(value: Int, leftChild: Node?, rightChild: Node?) {
105 | self.value = value
106 | self.leftChild = leftChild
107 | self.rightChild = rightChild
108 | }
109 | }
110 |
111 | //left branch
112 | let oneNode = Node(value: 1, leftChild: nil, rightChild: nil)
113 | let fiveNode = Node(value: 5, leftChild: oneNode, rightChild: nil)
114 |
115 | //right branch
116 | let elevenNode = Node(value: 11, leftChild: nil, rightChild: nil)
117 | let twentyNode = Node(value: 20, leftChild: nil, rightChild: nil)
118 | let fourteenNode = Node(value: 14, leftChild: elevenNode, rightChild: twentyNode)
119 |
120 | let tenRootNode = Node(value: 10, leftChild: fiveNode, rightChild: fourteenNode)
121 |
122 | func search(node: Node?, searchValue: Int) -> Bool {
123 | if node == nil {
124 | return false
125 | }
126 |
127 | if node?.value == searchValue {
128 | return true
129 | } else if searchValue < node!.value {
130 | return search(node: node?.leftChild, searchValue: searchValue)
131 | } else {
132 | return search(node: node?.rightChild, searchValue: searchValue)
133 | }
134 | }
135 |
136 | search(node: tenRootNode, searchValue: 14)
137 |
138 |
139 | //What is the point of all this?
140 | //Let's talk about efficiency
141 | let list = [1,5,10,11,14,20]
142 | let index = list.firstIndex(where: {$0 == 14})
143 | ```
144 |
145 |
146 | ## < Reference >
147 |
148 | - 트리 이미지: https://en.wikipedia.org/wiki/Tree_%28data_structure%29
149 | - 그래프와 트리의 차이: https://gmlwjd9405.github.io/2018/08/13/data-structure-graph.html
150 | - 순회 방식: https://m.blog.naver.com/rlakk11/60159303809
151 |
152 |
--------------------------------------------------------------------------------
/Computer Science/Database/SQL-join.md:
--------------------------------------------------------------------------------
1 | # SQL을 알기 전에...
2 |
3 | Database의 백그라운드부터 알고 가보자
4 |
5 | ## 데이터베이스(DB)란?
6 |
7 | 데이터베이스를 한 마디로 정의하면 '데이터의 집합'이라고 할 수 있다.
8 | 데이터베이스에는 일상생활 대부분의 정보가 저장되고 관리됨.
9 | * ex) 카카오 메시지, 인스타그램 업로드 사진, 교통카드 등등...
10 |
11 | ## DBMS(Database Management System)란?
12 |
13 | 데이터베이스를 '데이터의 집합'이라고 정의한다면, 이런 데이터 베이스를 관리하고 운영하는 소프트웨어를 DBMS라고 한다.
14 | 다양한 데이터가 저장되어 있는 데이터베이스는 여러 명의 사용자나 응용 프로그램과 공유하고 동시에 접근이 가능해야 한다.
15 | * ex) 여러 명의 은행 예금 계좌 정보 -> 데이터베이스
16 | * ex) 은행이 가지고 있는 예금 계좌 데이터베이스에 여러 명이 동시 접근 가능.(예금 계좌 주인, 은행 직원, ATM 등) -> DBMS가 있기에 가능
17 |
18 | ### DBMS의 종류
19 |
20 | 데이터베이스를 사용하기 위해 소프트웨어, 즉 DBMS를 설치해야하는데 대표적으로 MySQL, 오라클, SQL 서버, MariaDB 등이 있다.
21 |
22 | |DBMS|제작사|작동 운영체제|기타|
23 | |----|----|----------|---|
24 | |MySQL|Oracle|Unix, Linux, Windows, Mac|오픈 소스(무료), 상용|
25 | |MariaDB|MariaDB|Unix, Linux, Windows|오픈 소스(무료), MySQL 초기 개발자들이 독립해서 만듬|
26 | |PostgreSQL|PostgreSQL|Unix, Linux, Windows, Mac|오픈 소스(무료)|
27 | |Oracle|Oracle|Unix, Linux, Windows|오픈 소스(무료), 상용 시장 점유율 1위|
28 | |SQL Server|Microsoft|Windows|오픈 소스(무료), 주로 중/대형급 시장에서 사용|
29 | |DB2|IBM|Unix, Linux, Windows|오픈 소스(무료), 메인프레임 시장 점유율 1위|
30 | |Access|Microsoft|Windows|오픈 소스(무료), PC용|
31 | |SQLite|SQLite|Android, iOS|오픈 소스(무료), 모바일 전용, 오픈 소스(무료)|
32 |
33 |
34 | ## DBMS의 분류
35 |
36 | DBMS의 유형은 계층형, 망형, 관계형, 객체지향형, 객체관계형 등으로 분류된다. 현재 사용되는 DBMS 중에는 관계형 DBMS가 가장 많은 부분을 차지하며, MySQL도 관계형 DBMS에 포함된다.
37 |
38 | ### 계층형 DBMS
39 |
40 | 계층형 DBMS는 처음으로 등장한 DBMS 개념으로 1960년대에 시작되었다. 아래 그림과 같이 각 계층은 트리 형태를 갖는다.
41 | 계층형 DBMS의 문제는 처음 구성을 완료한 후에 이를 변경하기가 상당히 까다롭다는 것이다. 또한 다른 노드를 찾아가는 것이 비효율적이다. 근래는 사용하지 않는 형태이다.
42 |
43 |
44 |
45 | ### 망형 DBMS
46 |
47 | 망형 DBMS는 계층형 DBMS의 문제점을 개선하기 위해 1970년대에 등장했다. 각 노드끼리도 연결된 유연한 구조다.
48 | 하지만 망형 DBMS를 잘 활용하려면 프로그래머가 모든 구조를 이해해야만 프로그램 작성이 가능하다는 단점이 존재한다.
49 |
50 |
51 |
52 | ### 관계형 DBMS
53 |
54 | MySQL 뿐만 아니라, 대부분의 DBMS가 RDBMS 형태로 사용된다. RDBMS의 데이터베이스는 테이블(table)이라는 최소 단위로 구성되며, 이 테이블은 하나 이상의 열과 행으로 이루어져 있다.
55 | RDBMS에서는 모든 데이터가 테이블에 저장된다. 이 구조가 가장 기본적이고 중요한 구성이기 때문에 RDBMS는 테이블로 이루어져 있으며, 테이블은 열과 행으로 구성되어 있다.
56 |
57 |
58 |
59 |
60 | ## SQL이란?
61 |
62 | SQL은 DBMS에서 사용하는 언어이다.
63 |
64 | SQL은 특정 회사에서 만드는 것이 아니라 국제표준화기구에서 SQL에 대한 표준을 정해서 발표하고 있다. 이를 표준 SQL이라고 부른다. 그런데 문제는 SQL을 사용하는 DBMS를 만드는 회사가 여러 곳이기 때문에 표준 SQL이 각 회사 제품의 특성을 모두 포용하지 못한다는 점이다. 그래서 DBMS를 만드는 회사에서는 되도록 표준 SQL을 준수하되, 각 제품의 특성을 반영한 SQL을 사용한다.
65 |
66 |
67 |
68 |
69 | * SQL은 구조화된 쿼리 언이이며, 데이터베이스에 쿼리를 보내 원하는 데이터를 가져오거나 삽입할 수 있다.
70 | * 쿼리란? : 쿼리는 '질의문'이라는 뜻을 지님. 쿼리는 저장되어 있는 데이터를 필터링하기 위한 질의문으로 볼 수 있음.
71 | * SQL을 사용할 수 있는 데이터베이스와 달리, 데이터의 구조가 고정되어 있지 않은 데이터베이스를 NoSQL이라고 한다. 관계형 데이터베이스와는 달리, 테이블을 사용하지 않고 데이터를 다흔 형태로 저장한다. NoSQL의 대표적인 예시는 MongoDB와 같은 문서 지향 데이터베이스이다.
72 |
73 |
74 | ## SQL Join
75 |
76 | 하나의 테이블에 원하는 데이터가 모두 있다면 좋겠지만, 두 개의 테이블을 엮어야 원하는 결과가 나오는 경우도 있다. 조인을 쓰면 두개의 테이블을 엮어서 원하는 데이터를 추출할 수 있다.
77 |
78 | 두 테이블의 조인을 위해서는 기본키(Primary Key)와 외래키(Foreign Key)관게로 맺어져야 하고, 이를 일대다 관계라고 한다. 조인은 네가지 형태로 이루어져있다. Inner Join, Outer Join, Cross Join, Self Join.
79 |
80 | ### 1. Inner Join(내부 조인)
81 |
82 | 두 테이블을 연결할 때 가장 많이 사용하는 것이 내부 조인. 보통 그냥 조인이라고 부른다.
83 |
84 | ```
85 | SELECT <열 목록>
86 | FROM <첫 번째 테이블>
87 | INNER JOIN <두 번째 테이블>
88 | ON <조인될 조건>
89 | [WHERE 검색 조건]
90 | ```
91 |
92 | 
93 |
94 |
95 | ### 2. Outer Join(외부 조인)
96 |
97 | 내부 조인은 두 테이블에 모두 데이터가 있어야만 결과가 나오지만, 외부 조인은 한쪽에만 데이터가 있어도 결과가 나온다.
98 |
99 | ```
100 | SELECT <열 목록>
101 | FROM <첫 번째 테이블(LEFT 테이블)>
102 | OUTER JOIN <두 번째 테이블(RIGHT 테이블)>
103 | ON <조인될 조건>
104 | [WHERE 검색 조건]
105 | ```
106 |
107 | #### OUTER JOIN의 종류
108 | - LEFT OUTER JOIN: 왼쪽 테이블의 모든 값이 출력되는 조인
109 | - RIGHT OUTER JOIN: 오른쪽 테이블의 모든 값이 출력되는 조인
110 | - FULL OUTER JOIN: 왼쪽 또는 오른쪽 테이블의 모든 값이 출력되는 조인
111 |
112 | 
113 |
114 | ### 3. CROSS JOIN(상호 조인)
115 |
116 | 한쪽 테이블의 모든 행과 다른 쪽 테이블의 모든 행을 조인시키는 기능. 상호 조인 결과의 전체 행 개수는 두 테이블의 각 행의 개수를 곱한 수만큼 된다. 카디션 곱(Cartesian Product)라고도 한다.
117 |
118 | ```
119 | SELECT *
120 | FROM <첫 번째 테이블>
121 | CROSS JOIN <두 번째 테이블>
122 | ```
123 |
124 | 
125 |
126 | ### 4. SELF JOIN(자체 조인)
127 |
128 | 자체 조인은 자기 자신과 조인하므로 1개의 테이블을 사용한다. 별도의 문법이 있는 것은 아니고 1개로 조인하면 자체 조인이 된다.
129 |
130 | ```
131 | SELECT <열 목록>
132 | FROM <테이블> 별칭A
133 | INNER JOIN <테이블> 별칭B
134 | ON <조인될 조건>
135 | [WHERE 검색 조건]
136 | ```
137 |
138 | 
139 |
140 |
141 |
142 | ## Reference
143 | - https://hongong.hanbit.co.kr/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-databasedb-dbms-sql%EC%9D%98-%EA%B0%9C%EB%85%90/
144 | - https://velog.io/@estell/SQL-1-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4DB-SQL%EC%9D%B4%EB%9E%80
145 | - https://hongong.hanbit.co.kr/sql-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95-joininner-outer-cross-self-join/
146 |
147 |
--------------------------------------------------------------------------------
/Computer Science/Database/Transaction Isolation Level (트랜잭션 격리 수준).md:
--------------------------------------------------------------------------------
1 | // 2022.08.23 Noel
2 |
3 |
4 |
5 |
6 | # ❤️트랜잭션 격리 수준(Transaction Isolation Level)
7 |
8 |
9 |
10 | #### 🧡 트랜잭션 격리수준(isolation level)이란?
11 |
12 | > 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것
13 |
14 | - 트랜잭션에서 일관성 없는 데이터를 허용하도록 하는 수준
15 | - 특정 트랜잭션이 다른 트랜잭션에 변경한 데이터를 볼 수 있도록 허용할지 말지를 결정
16 |
17 |
18 |
19 | **트랜잭션 격리수준의 필요성**
20 |
21 | - 데이터베이스는 ACID 특징과 같이 트랜잭션이 독립적인 수행을 하도록함
22 | - Locking을 통해, 트랜잭션이 DB를 다루는 동안 다른 트랜잭션이 관여하지 못하도록 막는 것이 필요!
23 | - 하지만 무조건 Locking으로 동시에 수행되는 수많은 트랜잭션들을 순서대로 처리하는 방식으로 구현하게 되면 데이터베이스의 성능이 떨어짐
24 | - But! 성능을 높이기 위해 Locking의 범위를 줄인다면, 잘못된 값이 처리될 문제가 발생할 수 있음
25 |
26 | => 따라서 최대한 효율적인 Locking 방법이 필요함!
27 |
28 |
29 |
30 | ```참고
31 | 🤔 Lock이 뭐야..?
32 | Lock
33 | - 트랜잭션 처리의 순차성을 보장하기 위한 방법 (동시성 제어)
34 | - DBMS마다 Lock를 구현하는 방식이 다르기 때문에 DBMS을 효과적으로 이용하기 위해 해당 DB의 Lock에 대한 이해가 요구
35 |
36 | ① 공유 락(Shared lock)
37 | - 데이터를 읽을떄, 사용되어지는 Lock
38 | - Shared lock은 Shared lock끼지 동시 접근이 가능
39 | - 하지만, Shared lock이 설정된 데이터에 Exclusive lock을 사용할 수 없음
40 |
41 | ② 베타 락(Exclusive lock)
42 | - 데이터를 변경하고자 할때 사용되며, 트랜잭션이 완료될 때까지 유지된다.
43 | - Lock이 해제될 때까지 다른 트랜잭션(읽기 포함)은 해당 리소스에 접근할 수 없음
44 | - 해당 Lock는 트랜잭션이 수행되고 있는 데이터에 대해서는 접근하여 함께 Lock를 설정할 수 없음
45 |
46 | ```
47 |
48 |
49 |
50 |
51 |
52 | #### 🧡 트랜잭션 격리수준(isolation level) 종류
53 |
54 | 1. **Read Uncommitted (레벨 0)**
55 |
56 | > SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock이 걸리지 않는 계층
57 |
58 | - 트랜잭션에 처리중이거나, 아직 Commit되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용함
59 | - 데이터베이스의 **일관성을 유지하는 것이 불가능함**
60 | - Dirty Read 발생
61 |
62 | ``` 참고
63 | A 트랜잭션 : 10번 사원의 나이를 27 -> 28로 바꾸고 커밋하지 않음
64 | B 트랜잭션 : 10번 사원의 나이 조회 : 결과 28 -> 더티 리드(Dirty Read)
65 |
66 | 이 이후 A 트랜잭션에서 문제가 발생해 Rollback함
67 | B 트랜잭션은 10번 사원이 여전히 28이라고 생각하고 로직 수행
68 |
69 | 이런식으로 사용자1이 데이터를 변경하는 동안,
70 | 아직 완료 되지 않은(Uncommitted) 트랜잭션이지만 변경하는 데이터를 읽을 수 있음
71 | 데이터 정합성에 문제가 많아짐
72 | ```
73 |
74 |
75 |
76 | 2. **Read committed (레벨 1)**
77 |
78 | > SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock이 걸리는 계층
79 |
80 | - 트랜잭션이 수행되는 동안 **다른 트랜잭션이 접근할 수 없어 대기**하게 됨
81 |
82 | - Commit이 이루어진 트랜잭션만 조회 가능
83 |
84 | - 대부분의 SQL 서버가 Default로 사용하는 Isolation Level임
85 | - Non-Repeatable Read 발생
86 |
87 | ``` 예시
88 | B 트랜잭션 : 10번 사원 나이 조회 : 결과 27
89 | A 트랜잭션 : 10번 사원나이 27 -> 28로 바꾸고 커밋
90 | B 트랜잭션 : 10번 사원 나이 조회 : 결과 28
91 |
92 | 사용자1이 데이터를 변경하는 동안 사용자2는 해당 데이터에 접근 불가능
93 | ```
94 |
95 |
96 |
97 | 3. **Repeatable Read (레벨 2)**
98 |
99 | > 트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리는 계층
100 |
101 | - 트랜잭션이 범위 내에서 **조회한 데이터 내용이 항상 동일함을 보장**함
102 |
103 | - 다른 사용자는 **트랜잭션 영역에 해당되는 데이터에 대한 수정 불가능**
104 |
105 | - MySQL에서 Default로 사용하는 Isolation Level
106 | - Non-Repeatable Read 부정합이 발생하지 않음
107 |
108 | ```예시
109 | 10번 트랜잭션 : 500번 사원 조회
110 | 12번 트랜잭션 : 500번 사원 이름 변경 후 커밋
111 | 10번 트랜잭션 : 500번 사원 다시 조회 -> undo 영역에 백업된 데이터 반환
112 |
113 | 즉 자신의 트랜잭션 번호보다 낮은 트랜잭션 번호에서 변경된(커밋된) 것만 보게됨
114 | - 모든 InnoDB의 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 갖고있음
115 | - undo 영역에 백업된 모든 레코드는 변경을 발생기킨 트랜잭션의 번호 포함
116 | ```
117 |
118 |
119 |
120 | 4. **Serializable (레벨 3)**
121 |
122 | > 트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리는 계층
123 |
124 | - 완벽한 읽기 일관성 모드를 제공함
125 |
126 | - 다른 사용자는 **트랜잭션 영역에 해당되는 데이터에 대한 수정 및 입력 불가능**
127 |
128 |
129 |
130 | ```결론
131 | 결론
132 | - 레벨이 높아질수록 트랜잭션 간 고립 정도가 높아지며, 성능이 덜어지는 것이 일반적
133 | - 일반적인 온라인 서비스에서는 Read committed (레벨 1) / Repeatable Read (레벨 2)을 사용함
134 | ```
135 |
136 |
137 |
138 |
139 |
140 | #### 🧡 트랜잭션 격리수준(isolation level) 선택 시 고려사항
141 |
142 | Isolation Level에 대한 조정은, `동시성`과 데이터 `무결성`에 연관되어 있음
143 |
144 | > 동시성을 증가시키면 데이터 무결성에 문제가 발생하고, 데이터 무결성을 유지하면 동시성이 떨어지게 됨
145 |
146 | - 레벨을 높게 조정할 수록 발생하는 비용이 증가함
147 |
148 |
149 |
150 |
151 | ```참고
152 | 🤔 무결성(integrity)
153 | - 데이터의 정확성, 일관성, 유효성이 유지되는 것
154 |
155 | ① 개채 무결성
156 | - 모든 테이블이 기본키로 선택된 필드를 가져야함 (기본 키를 가져야함)
157 | - 고유햔 값, NULL 허용 하지 않음
158 |
159 | ② 참조 무결성
160 | - 참조 관계에 있는 두 테이블의 데이터가 항상 일관된 값을 갖도록 유지
161 | - 참조 대상이 존재하지 않는 외래 키를 허용하지 않음
162 | > RESTRICTED : 레코드를 참고하고 있는 개체가 있다면, 변경 또는 삭제 연산 취소
163 | > CASCADE : 레코드를 참조하고 있는 개체도 변경 또는 삭제
164 | > SET NULL : 레코드를 참고하고 있는 개체의 값을 NULL로 설정
165 |
166 | ③ 도메인 무결성
167 | - 테이블에 존재하는 필드의 무결성 보장
168 | - 필드의 타입, null 값의 허용 등 사항을 저으이하고 올바른 데이터가 입력되었는지 확인
169 |
170 | ④ 무결성 규칙
171 | - 데이터의 무결성을 지키기 위한 모든 제약사항, 데이터 베이스 전체에 공통적으로 적용되는 규칙
172 |
173 | ```
174 |
175 |
176 |
177 |
178 |
179 | #### 🧡 낮은 단계 트랜잭션 격리수준(isolation level) 활용 시 발생하는 현상
180 |
181 | **Dirty Read**
182 |
183 | - 커밋되지 않은 수정중인 데이터를 다른 트랜잭션에서 읽을 수 있도록 허용할 때 발생하는 현상
184 |
185 | - 어떤 트랜잭션에서 아직 실행이 끝나지 않은 다른 트랜잭션에 의한 변경사항을 보게되는 경우
186 |
187 |
188 |
189 |
190 | **Non-Repeatable Read**
191 |
192 | - 한 트랜잭션에서 같은 쿼리를 두 번 수행할 때 그 사이에 다른 트랜잭션 값을 수정 또는 삭제하면서 두 쿼리의 결과가 상이하게 나타나는 일관성이 깨진 현상
193 |
194 |
195 |
196 | **Phantom Read**
197 |
198 | - 한 트랜잭션 안에서 일정 범위의 레코드를 두 번 이상 읽었을 때, 첫번째 쿼리에서 없던 레코드가 두번째 쿼리에서 나타나는 현상
199 |
200 | - 트랜잭션 도중 새로운 레코드 삽입을 허용하기 때문에 나타나는 현상임
201 |
202 | | 격리수준 | Dirty Read | Non-Repeatable Read | Phantom Read |
203 | | ----------------------------- | ---------- | ------------------- | ------------ |
204 | | Read Uncommitted
(레벨 0) | O | O | O |
205 | | Read committed
(레벨 1) | - | O | O |
206 | | Repeatable Read
(레벨 2) | - | - | O |
207 | | Serializable
(레벨 3) | - | - | - |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 | 출처
217 |
218 | https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Database/Transaction%20Isolation%20Level.md#%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B2%A9%EB%A6%AC-%EC%88%98%EC%A4%80transaction-isolation-level
219 |
220 | https://dar0m.tistory.com/225
221 |
222 | https://code-lab1.tistory.com/51
223 |
--------------------------------------------------------------------------------
/Computer Science/Network/동기, 비동기 개념(synchronous vs asynchronous).md:
--------------------------------------------------------------------------------
1 | // 2022.08.28 Rookie
2 |
3 | # block, non block / 동기, 비동기에 관한 개념을 정리함
4 | #### 노션에 작성한 후 옮겨 가독성이 안좋네요. 관련 링크는 다음과 같습니다 https://www.notion.so/d6429faca47a42cc9770e9aa1cd850fb
5 |
6 | ## 3줄 요약
7 |
8 | 1. block, non block과 동기, 비동기 개념은 컴퓨터가 개발자가 작성한 코드를 수행하는 방식 중 하나이다. 그리고 둘은 엄연히 다른 개념이다!
9 | 2. 작업 수행을 요청받은 함수가 작업 실행 순서(제어권)를 바로 돌려준다면 non block, 작업이 끝날 때 까지 제어권을 돌려주지 않으면 block 이라고 한다.
10 | 3. 작업수행을 요청한 함수가 직접 작업 완료 여부를 체크한다면 동기, 그렇지 않다면 비동기이다. 따라서 비동기 함수는 요청을 받은 함수가 작업 완료 여부를 알려줘야하는데, 이 때 사용되는 것이 completion handler 같은 escaping closure 이다.
11 |
12 |
13 |
14 |
15 | ## blocking, non blocking
16 |
17 | 블로킹(blocking) vs 논블로킹(non-blocking)우리가 어떤 프로그램을 만들었다고 해보자.
18 | 아마 어떤 코드를 작성해서 만들었을 것이고, 이 코드는 수많은 함수들이 순서대로 나열되어있는 모습일 것이다.
19 | 이렇게 한 프로그램은 여러개의 함수들로 이루어져 있다.어떤 함수 안에 여러개의 함수들이 있다고 가정해보자. 아마 이런 모습일 것이다. (설명의 편의를 위해 부모함수와 자식함수 A, B라고 부르도록 하겠다)
20 |
21 | ```
22 | function 부모함수() {
23 | A();
24 | B();
25 | ...
26 | }
27 | ```
28 |
29 | - 제어권이란?
30 |
31 | 제어권은 말 그대로 '권한'이다. A 함수의 내용이 아래와 같다고 했을 때, A에게제어권이 있어야 함수 안에 있는 작업들이 실행될 수 있다.
32 | 결과값은 우리가 보통 말하는 함수의 리턴값이다. 여기서 결과값은 3이 될 것이라고 쉽게 예상할 수 있다. 그런데 여기서 주의할 점이 하나 더 있다.
33 | 꼭 결과값은 3이 아니어도 된다는 것이다. 만약 A가 아직 계산을 끝마치지 못했는데, 갑자기 결과값을 요구한다면 '아직 계산못함'을 임시 결과값으로 내보낼 수도 있다
34 |
35 | ```
36 | example
37 |
38 | function A() {
39 | let a = 1;
40 | let b = 2;
41 | let sum = a + b;
42 | return sum;
43 | }
44 | ```
45 |
46 |
47 | ```
48 | function 부모함수() {
49 | A();
50 | B();
51 | ...
52 | }
53 |
54 | function A() {
55 | let a = 1;
56 | let b = 2;
57 | let sum = a + b;
58 | return sum;
59 | }
60 | ```
61 |
62 | #### 블로킹은다른 함수를 호출할 때, 제어권도 아예 함께 넘겨주고 작업이 끝난 후에 돌려받는 방식이다.
63 | 위의 예시에선 부모함수가 A를 실행시킬 때 제어권을 아예 넘겨주게 되어서, 본인은 다른 일을 하지 못하고 A의 작업이 끝날때까지 마냥 기다리는 것이다.
64 | 그러다 A의 작업이 끝나면 제어권을 돌려받고 다음함수인 B를 실행시킨다.논블로킹도 마찬가지로호출할 때 제어권을 넘겨주기는 하지만, 바로 돌려받는다.
65 | A의 작업이 안끝나도 바로 제어권을 돌려받고 부모함수는 B작업을 시작하는 것이다. 호출된 A는 알아서 실행되도록 놔둔다.
66 |
67 | #### 결론적으로 블로킹/논블로킹을 구분짓는 기준은 '요청받은 함수가 제어권을 언제 돌려주는지'이다.
68 |
69 |
70 |
71 | ## 동기, 비동기
72 |
73 | #### 동기는 '시간을 맞춘다'는 뜻이다! 이게 뭔말일까?
74 | 쉽게 말해 함수가 두 개 이상 존재할 때, 이함수들이 작업을 동시에 시작하거나, 끝나는 타이밍을 맞추거나, 하나가 끝나고 다른 하나를 차례로 실행하는 것을 시간을 맞춘다고 한다.
75 | 함수들끼리 어느정도 작업 시간에 대한 규칙(?)을 정해놓는 방식이라고 표현할 수 있을 것 같다.이런 규칙을 정하고 지킬 수 있는 이유는, 요청자가 요청한 일들이 완료되었는지를 계속 확인하기 때문이다.
76 | 요청하는 함수는 요청을 보내놓고, 요청을 처리하는 함수들이 작업을 마쳤는지 계속해서 물어본다. 요청자는 완료가 되었다는 응답을 받으면, 그때 다른 함수의 실행을 시작하거나 하는 것이다.
77 |
78 | 동기는 또 다른 관점에서는, 제어권과 결과값을 동시에 반환하는 것을 말하기도 한다. 아까 봤던 예시를 그림으로 표현한 것인데, 여기서 호출된 A는 작업을 마치고 자신을 호출한 부모함수에게 결과값(3)을 알려주면서, 동시에 제어권도 함께 돌려준다.
79 |
80 |
81 |
82 |
83 |
84 | #### 비동기(Async)비동기는 동기적이지 않은 방식을 말한다.
85 | 다시말해 두 함수는 서로가 언제 시작하고, 언제 일을 마치는지 전혀 신경쓰지 않는 것이다.
86 | 이 경우에는 요청자는 작업을 요청해놓고 계속 완료되었는지 확인하는게 아니라, 알아서 알려주겠거니 하고 있는다. 다시말해 요청받은 함수가 완료되었는지 여부를 알아서 알려주는 방식이다.
87 | 이렇게 작업을 시작하고 끝내는 시간을 아는 것은 호출된 함수 본인뿐이기 때문에, 여러 함수들이시작되고 끝나는 시간은 맞춰지지 않을 수 있게 된다.혹은결과값과 제어권이 다른 시점에 따로따로 반환되는 것도 비동기라고 할 수 있다.
88 |
89 | ## 차이점 정리
90 | 블로킹 :요청받는 함수가 작업을 모두 마치고 나서야 요청자에게 제어권을 넘겨줌 (그동안 요청자는 아무것도 하지않고 기다림).
91 | 논블로킹 :요청받은 함수가 요청자에게 제어권을 바로 넘겨줌 (그동안 요청자는 다른 일을 할 수 있음)
92 |
93 | 동기 :요청자가 요청받은 함수의 작업이 완료되었는지 계속 확인 (여러 함수들이 시간을 맞춰 실행됨).
94 | 비동기 :요청자는 요청후 신경X, 요청받은 함수가 작업을 마치면 알려줌 (함수들의 작업 시작/종료 시간이 맞지 않을수도)
95 |
96 | ## But!
97 |
98 | 근데 솔직히 여기까지 읽으면 걍 이런거군..? 근데 어쩌란거지? 딱 이정도만 생각든다. 그러니 코드를 통해 알아보도록합시다!!! (아래 코드는 자체제작한거로 이상한게 있으면 말씀해주세요)
99 |
100 | ## Practices
101 |
102 | ### 블로킹, 동기 예시
103 |
104 | 특정 구문을 완료할 때 까지 제어권을 돌려주지 않으며, 작업을 요청한 함수가 직접 그 완료여부를 체크함
105 |
106 |
107 |
108 |
109 |
110 |
111 | ## 블로킹, 비동기 예시
112 |
113 | 특정 구문을 완료할 때 까지 제어권을 돌려주지 않지만 작업을 요청받은 함수가 끝나면 알려줌.
114 |
115 |
116 |
117 |
118 |
119 | + calculate 함수와 requestMultiplier 함수는 작업을 비동기적으로 수행한다.
120 | ++ requestMultiplier은 작업이 끝났음을 response in 이하의 escaping closure 구문을 통해 알려준다)
121 |
122 | ## 논블로킹, 동기 예시
123 |
124 | 제어권을 바로 돌려주지만 작업을 요청한 함수가 직접 그 완료여부를 체크함
125 |
126 |
127 |
128 |
129 |
130 | 1, 2, 3 프린트 함수문이 동기적으로(순차적) 진행되며, a+b 반환 결과에 아무런 영향도 미치지 않으니 calculate 함수의 작업을 block 하지도 않음.
131 |
132 | ## 논블로킹, 비동기 예시
133 |
134 | 제어권을 바로 돌려주고 작업을 요청받은 함수가 끝나면 직접 알려줌.
135 |
136 |
137 |
138 |
139 |
140 |
141 | ## More
142 |
143 | iOS프로그래밍에서는 **동기는 Blocking의 개념**으로, 그리고 **비동기는 Non-Blocking의 개념**으로만 사용하고 있다는 찌라시가 있으나 공식적인 출처가 없음.
144 |
145 | ## Reference
146 |
147 | [https://www.inflearn.com/questions/25632](https://www.inflearn.com/questions/25632) (iOS에서의 동기비동기, block non block)
148 |
149 | [https://joooing.tistory.com/entry/동기비동기-블로킹논블로킹](https://joooing.tistory.com/entry/%EB%8F%99%EA%B8%B0%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%B8%94%EB%A1%9C%ED%82%B9%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9) (동기 비동기 잘 정리한 글)
150 |
151 | [https://sujinnaljin.medium.com/swift-async-await-concurrency-bd7bcf34e26f](https://sujinnaljin.medium.com/swift-async-await-concurrency-bd7bcf34e26f) (필독 !!! 동기 비동기 swift 문법)
152 |
153 | [https://deveric.tistory.com/99](https://deveric.tistory.com/99)( 동기 비동기 예시)
154 |
--------------------------------------------------------------------------------
/Design Pattern/Composite Pattern.md:
--------------------------------------------------------------------------------
1 | #### 2022.09.26 Rookie
2 |
3 | ## 디자인 패턴이란?
4 |
5 | 디자인 패턴이란 기존 환경 내에서 반복적으로 일어나는 문제들을 어떻게 풀어나갈 것인가에 대한 일종의 솔루션입니다. 개발을 하다보면 아시겠지만 일부 구조는 반복되서 사용되는 것을 경험했을 것입니다. 개발자들이 개발하면서 겪은 문제들을 정리해서 상황 별 솔루션 컨셉을 분류해놓았다고 이해하면 됩니다.
6 |
7 | ---
8 |
9 | ## 컴포지트 패턴이란??
10 |
11 | 컴포지트 패턴은 디자인 패턴의 일종입니다. 위 맥락에서 나온 디자인패턴의 의미로 봤을 때, 컴포지트 패턴도 특정 문제를 잘 풀 수 있게 정해놓은 솔루션 컨셉입니다. 어떤 상황에서 이런게 나오게 됬을까요?
12 |
13 | **컴포지트 패턴은** 클라이언트가 객체 구성과 개별 객체 간 차이를 무시하고 싶을 때 사용합니다. 또한 일반적으로 객체 구조가 트리 구조일떄 사용합니다.
14 |
15 | **객체는 클래스나 구조체 같은걸 뜻한다고 쳐도 객체 구성과 객체 간 차이를 무시한다는게 무슨의미일까여?? 그리고 객체를 트리 구조로 나타낸다는 건 또 뭔 말일까요?? 바로 예시를 알아보러 갑시다!**
16 |
17 | ---
18 |
19 | ### 대표적인 예시는 폴더입니다.
20 |
21 | 폴더는 일반적으로 파일들로 이루어져있습니다. 이처럼 비슷한 속성의 객체들이 상위 객체에 속해있는 구조를 트리 구조라고 합니다!
22 |
23 | 근데 폴더와 파일은 비슷한점이 많습니다. 이름도 잇고 용량도 있고, 삭제할 수도 잇고… 그래서 폴더라는 객체가 파일이라는 객체의 집합이지만, 파일과 폴더 두 객체의 차이는 트리구조밖에 없습니다. 이 경우, 파일과 폴더라는 객체는 구조적인 차이를 가지지만 그 특성은 같다고 볼 수 있습니다.
24 |
25 | 이런 경우 이 공통된 속성을 추출해서 코드를 짤 수 있는데 이것을 개별 객체와 객체 구성간 차이를 무시한다고 표현합니다. 이러면 하나의 로직 가지고 두 객체를 커버할 수 있으니 클린하면서도 유지보수가 용이한 코드가 될 수 있습니다!
26 |
27 | ---
28 |
29 | **컴포지트 패턴은 일반적으로 3가지로 나눠서 작성합니다**
30 |
31 | component: 객체(파일)과 객체집합(폴더) 의 공통 속성을 추출한 것입니다.
32 |
33 | leaf: 파일과 같은 개별 객체입니다.
34 |
35 | composite: 폴더와 같이 하위 객체들의 집합입니다.
36 |
37 | Swift 예시를 한번 봐보겟습니다!
38 |
39 | ```swift
40 |
41 | #1 Component 만들기
42 |
43 | protocol FileComponent {
44 | var size: Int { get set }
45 | var name: String { get set }
46 | func open()
47 | func getSize() -> Int
48 | }
49 |
50 | 재가 느끼기에 Component 추출이 컴포지트 패턴의 가장 중요한 부분입니다.
51 | 먼저 객체집합과 개별 객체의 공통 속성을 추출하여 component를 만듭니다. 이러한 작업을 추상화라고 하며 스위프트에서는 프로토콜을 사용할 수 있습니다.
52 |
53 | #2 Composite 만들기
54 |
55 | final class Directory: FileComponent {
56 | var size: Int
57 | var name: String
58 | var files: [FileComponent] = []
59 | func open() {
60 | print("\(self.name) Directory의 모든 File Open")
61 | for file in files {
62 | file.open()
63 | }
64 | print("\(self.name) Directory의 모든 File Open 완료\n")
65 | }
66 |
67 | func getSize() -> Int {
68 | var sum: Int = 0
69 | for file in files {
70 | sum += file.getSize()
71 | }
72 | return sum
73 | }
74 |
75 | func addFile(file: FileComponent) {
76 | self.files.append(file)
77 | self.size += file.size
78 | }
79 |
80 | init(size: Int, name: String) {
81 | self.size = size
82 | self.name = name
83 | }
84 | }
85 |
86 | 디렉토리이니까 File들을 모을 수 있는 배열을 하나 가지고 있어야 합니다.(디렉토리를 폴더라고 생각하시면 편할 듯 합니다). 디렉토리의 size는 자신이 가지고 있는 모든 파일,size의 합을 반환해줘야 합니다. 파일은 여러 종류가 존재할 수 있겠죠?
87 |
88 | #3 leaf 만들기
89 |
90 | final class MusicFile: FileComponent {
91 | var size: Int
92 | var name: String
93 | var artist: String
94 |
95 | func open() {
96 | print("\(self.name) Music Artist : \(self.artist)")
97 | }
98 |
99 | func getSize() -> Int {
100 | return self.size
101 | }
102 |
103 | init(size: Int, name: String, artist: String) {
104 | self.size = size
105 | self.name = name
106 | self.artist = artist
107 | }
108 | }
109 |
110 | final class CodeFile: FileComponent {
111 | var size: Int
112 | var name: String
113 | var language: String
114 |
115 | func open() {
116 | print("\(self.name) Code Language : \(self.language)")
117 | }
118 |
119 | func getSize() -> Int {
120 | return self.size
121 | }
122 |
123 | init(size: Int, name: String, language: String) {
124 | self.size = size
125 | self.name = name
126 | self.language = language
127 | }
128 | }
129 |
130 | 파일은 여러 개의 종류가 존재할 수 있고 각각의 종류마다 갖는 프로퍼티도 다를 수 있습니다.저는 Music, Code 파일을 만들어봤어요. 이렇게 하면 컴포지트 패턴에 필요한 모든 요소를 구현한 거예요.바로 한 번 사용해볼게요!
131 |
132 | import Foundation
133 |
134 | // 디렉토리 만들기
135 | let rootDirectory = Directory(size: 0, name: "Root")
136 | let musicDirectory = Directory(size: 0, name: "Music")
137 | let codeDirectory = Directory(size: 0, name: "Code")
138 |
139 | // 여러 종류의 파일 만들기
140 | let iUMusicFile = MusicFile(size: 10, name: "Lilac", artist: "IU")
141 | let pinguMusicFile = MusicFile(size: 12, name: "PinguBGM", artist: "Pingu")
142 |
143 | let swiftCodeFile = CodeFile(size: 3, name: "iOS", language: "Swift")
144 | let kotlinCodeFile = CodeFile(size: 5, name: "Android", language: "kotlin")
145 |
146 | // 디렉토리 안에 파일 넣기 (트리 구조 만들기)
147 | musicDirectory.addFile(file: iUMusicFile)
148 | musicDirectory.addFile(file: pinguMusicFile)
149 |
150 | codeDirectory.addFile(file: swiftCodeFile)
151 | codeDirectory.addFile(file: kotlinCodeFile)
152 |
153 | rootDirectory.addFile(file: musicDirectory)
154 | rootDirectory.addFile(file: codeDirectory)
155 |
156 | rootDirectory.open()
157 |
158 | // 디렉토리 크기 구하기
159 | print("RootDirectory Size : \(rootDirectory.getSize())")
160 | print("MusicDirectory Size : \(musicDirectory.getSize())")
161 | print("CodeDirectory Size : \(codeDirectory.getSize())")
162 | ```
163 |
164 | ### 결론
165 |
166 | 컴포지트 패턴을 적용해서 getSize함수로 파일(개별 객체)과 디렉토리(객체 집합)의 용량을 같은 함수를 적용해서 구할 수 있게되었습니다!
167 |
168 | ### More
169 |
170 | swift에서는 프로토콜을 사용하는데 다른 함수는 클래스로 선언하고 override 하는 방식으로 구현할 수 있을 것 같습니다.
171 |
172 | ---
173 |
174 | ## **[#](https://gyoogle.dev/blog/design-pattern/Composite%20Pattern.html#%E1%84%80%E1%85%AA%E1%86%AB%E1%84%85%E1%85%A7%E1%86%AB-%E1%84%91%E1%85%A2%E1%84%90%E1%85%A5%E1%86%AB)관련 패턴**
175 |
176 | ### **[#](https://gyoogle.dev/blog/design-pattern/Composite%20Pattern.html#decorator)Decorator**
177 |
178 | 공통점 : composition이 재귀적으로 발생한다.
179 |
180 | 차이점 : decorator 패턴은 responsibilites를 추가하는 것이 목표이지만 composite 패턴은 hierarchy를 표현하기 위해서 사용된다.
181 |
182 | ### **[#](https://gyoogle.dev/blog/design-pattern/Composite%20Pattern.html#iterator)Iterator**
183 |
184 | 공통점 : aggregate object을 순차적으로 접근한다.
185 |
186 | ---
187 |
188 | ## Reference
189 |
190 | [https://icksw.tistory.com/243](https://icksw.tistory.com/243) (컴포지트 디자인패턴)
191 |
192 | [https://github.com/iDevPingu/Swift_Design_Pattern_Study](https://github.com/iDevPingu/Swift_Design_Pattern_Study)
193 |
194 | [https://readystory.tistory.com/114](https://readystory.tistory.com/114) (디자인 패턴이란)
195 |
196 | https://github.com/Rookie0031/WWDC_Study/issues/3
197 | (protocol과 추상화 관련하여 제가 공부했던 자료를 공유합니다)
198 |
--------------------------------------------------------------------------------
/Computer Science/Data Structure/stack, queue(스택, 큐).md:
--------------------------------------------------------------------------------
1 | # 스택(Stack) & 큐(Queue)
2 |
3 |
4 |
5 | ## 스택
6 | - 데이터를 임시 저장하는 기본 자료구조.
7 | - 같은 구조와 크기의 자료를 정해진 방향으로만 쌓을 수 있고, top으로 정한 곳을 통해서만 접근해 자료를 넣고 뺄 수 있다.
8 | - 데이터가 순서대로 쌓이며 가장 마지막에 삽입된 데이터가 가장 먼저 삭제되는 LIFO(Last In First Out) 구조다.
9 | ex) 식당에 순서대로 쌓인 접시처럼. 접시가 필요하면 제일 위에 있는 접시부터 사용하며 가장 아래 있는 접시는 마지막에 사용된다.
10 | - 스택이 완전히 꽉 찼을 때 `Overflow` 상태라고 하며 완전히 비어 있으면 `Underflow` 상태라고 한다.
11 |
12 |
13 |
14 |
15 | ## 스택의 연산
16 |
17 |
18 | - push(data): 스택 맨 위에 데이터를 삽입한다.
19 | - 1단계 - 스택이 가득 찼는 지 확인한다.
20 | - 2단계 - 스택이 가득 차면 오류가 발생하고 종료된다.
21 | - 3단계 - 스택이 가득 **차지** 않으면 Top을 증가시킨다.
22 | - 4단계 - Top이 가리키는 스택 위치에 데이터를 추가한다.
23 | - pop(): 스택 맨 위에 있는 데이터를 제거한다.
24 | - 1단계 - 스택이 비어 있는지 확인한다.
25 | - 2단계 - 스택이 비어 있으면 오류가 발생하고 종료된다.
26 | - 3단계 - 스택이 비어 있지 않으면 Top이 가리키는 데이터를 제거한다.
27 | - 4단계 - Top 값을 감소시킨다.
28 | - 5단계 - 성공을 반환한다.
29 | - peek(): 스택의 가장 위에 있는 항목을 반환한다.(가장 상단에 있는 데이터를 삭제하지 않고 확인만 하고 싶을 때)
30 | - isEmpty(): 스택이 비어 있을 때에 true를 반환한다.
31 | - isFull() : 스택이 가득 차 있을 때에 true를 반환한다.
32 | - getSize : 스택에 있는 요소 수를 반환한다.
33 |
34 |
35 | ## 스택의 구현
36 |
37 |
38 |
39 | - 배열 사용
40 | - 장점 : 구현하기 쉬움. 원하는 데이터의 접근 속도가 빠름. ex) 만약 내가 원하는 데이터가 배열의 3번째 위치에 있으면 arr[2]를 사용한다면 한번에 접근이 가능하기 때문.
41 | - 단점: 데이터 최대 개수를 미리 정해야 한다. 데이터의 삽입과 삭제에 있어 매우 비효율적 ⇒ 특정 위치에 삽입하기 위해 다른 데이터들을 다 한칸씩 뒤로 밀어야 하기 때문.
42 | - 데이터 양이 많지만 삽입/삭제가 거의 없고, 데이터의 접근이 빈번히 이뤄질 때 유리!!
43 |
44 |
45 |
46 |
47 |
48 |
49 | - 연결 리스트 사용
50 | - 장점 : 데이터의 최대 개수가 한정되어있지 않음. 데이터의 삽입 삭제가 용이 ⇒ 다음 위치에 해당하는 노드의 주소값만 바꿔주면 되기 때문.
51 | - 단점 : 한번에 원하는 데이터의 접근이 불가능 ⇒ 연결되어 있는 링크를 따라 차근차근 하나씩 확인하며 데이터를 찾아야 하기 때문.
52 | - 삽입/삭제가 빈번히 이뤄지고, 데이터의 접근이 거의 없을 때 유리!!
53 |
54 |
55 | ## 스택의 활용
56 | - 웹 브라우저 방문기록(뒤로 가기) : 가장 나중에 열린 페이지부터 다시 보여준다.
57 | - 실행 취소(undo) : 가장 나중에 실행된 것부터 실행을 취소한다.
58 | - 괄호의 짝 검사 : 괄호의 짝, 괄호의 순서 검사.
59 | - 역순 문자열 만들기 : 가장 나중에 입력된 문자부터 출력한다.
60 | - 수식의 괄호 검사 : 연산자 우선순위 표현을 위한 괄호검사.
61 |
62 |
63 |
64 |
65 | # 큐(Queue)
66 |
67 |
68 | - 스택과 다르게 먼저 들어오는 것이 먼저 나가는 FIFO(First In First Out)의 구조를 가지고 있다.
69 | ex) 은행 번호표 : 먼저 온 손님이 먼저 서비스를 받는 것처럼.
70 | - 정해진 한 곳(Top)을 통해서 삽입, 삭제가 이루어지는 스택과 달리 큐는 한쪽 끝에선 삽입 작업이, 다른 쪽 끝에선 꺼내는 작업이 양쪽으로 이루어진다.
71 | - 가득 찬 큐에 요소를 추가하려고 할 때 `Overflow` 가 발생하고, 빈 큐에서 요소를 꺼내려고 할 때 `Underflow` 가 발생한다.
72 |
73 |
74 | ## 큐의 연산
75 |
76 | - front : 큐의 가장 첫 원소. 출력 연산만 이루어지는 곳.
77 | - rear : 큐의 가장 끝 원소. 삽입 연산만 이루어지는 곳.
78 | - dequeue() : 큐의 맨 앞(front)의 요소를 꺼내는 연산. **front + 1**을 하고 그 자리에 있던 요소를 출력한다.
79 | - enqueue() : 큐의 맨 끝(rear)에 요소를 추가하는 연산. **rear + 1**을 하고 그 자리에 요소를 추가한다.
80 | - isfull() : 큐가 가득 찼는지 확인. **rear = n - 1**, 즉 rear가 마지막 인덱스를 가리키면 꽉 찬 것이다.
81 | - isempty() : 큐가 비어 있는지 확인. **front = rear**이면 큐가 비었다고 판단한다.
82 | - peek() : front에 위치한 데이터를 반환.
83 |
84 |
85 | ## 큐의 특징
86 |
87 | - 큐는 들어올 때 rear로 들어오지만, 나올 때는 front부터 빠지는 특성.
88 | - 접근방법은 가장 첫 원소와 끝 원소로만 가능.
89 |
90 |
91 | ## 큐의 종류
92 |
93 | ### 선형 큐
94 |
95 |
96 |
97 | - 배열을 선형으로 사용하여 구현된 큐.
98 | - 문제점
99 | - 크기가 제한되어 있고, 이미 사용한 영역인 front의 앞부분에 대해서 다시 활용을 못하기 때문에 메모리를 낭비한다.
100 | - rear와 front의 값(인덱스)이 자꾸 증가하기만 해서 결국 배열의 앞부분이 비어있더라도 큐는 꽉 찼다고 인식하기 때문에.
101 | - 이런 공간 낭비를 배열의 요소들의 인덱스를 하나씩 당겨주는 방법으로 해결할 수 있지만, 원형 큐로 구현하면 더 쉽게 해결할 수 있다.
102 |
103 |
104 |
105 |
106 |
107 |
108 | ### 원형 큐
109 |
110 | - 일반적으로, 배열을 사용한 큐라면 위 상황에서 자료를 더 push하고 싶다면, 456을 앞으로 당기거나 배열의 크기를 늘리는 수 밖에 없다. 하지만 앞으로 당기는 것도 비용이 발생하고, 배열의 크기를 늘리는 일 또한 공간적 낭비가 심하다. 그래서 생각해낸 방법이 앞에 비워진 공간을 활용하는 방법이다.
111 | - front와 rear가 Inqueue와 dequeue를 반복해 증가하다가 배열의 끝 인덱스에서 증가하면은 인덱스 0을 가리키도록 하면 된다. 이는 나머지 연산으로 쉽게 구현할 수 있다.⇒ (index + 1) % size.
112 | - 배열의 포화상태 여부를 판단하기 위하여 배열의 1칸은 비워둔다. (rear+1)%arraysize == front 라면 배열이 포화상태인걸로 판단하여 데이터 삽입이 이루어지지 않게 된다.
113 | - rear==front 조건이라면 배열이 공백상태인걸로 판단하여 Dequeue가 실행되지 않는다.
114 |
115 | ### 연결리스트 큐
116 |
117 | - 배열로 구현한 큐의 단점은 크기를 미리 정해야 하고, 그 크기를 넘어서면 error가 발생한다는 것이다. 반면 연결리스트로 구현하면 큐의 크기(size)를 미리 정할 필요가 없다.
118 | - 배열 대신 연결리스트로 원소들을 관리
119 | - 큐의 원소 : 단순 연결 리스트의 노드
120 | - 큐의 원소의 순서 : 노드의 링크 포인터로 연결
121 | - 변수 front : 첫 번째 노드를 가리키는 포인터 변수 (초기 null)
122 | - 변수 rear : 마지막 노드를 가리키는 포인터 변수 (초기 null)
123 | - 주요 특징
124 | - 배열을 이용할 경우에 비해, 크기 제한이 거의 없음
125 | - 동적 메모리 할당으로 기억장소 사용에 제한이 적음
126 | - 큐에서 enQueue 및 deQueue 방법은 단순연결리스트의 삽입/삭제 방법과 거의 동일
127 | - 배열의 인덱스 대신 포인터 사용에 따른 부담은 존재
128 | - 큐의 상태
129 | - 초기 상태 : front = rear = null
130 | - 공백 상태 : front = rear = null
131 | - 초기 상태와 공백 상태가 동일!
132 | - 큐가 꽉 차서 더 이상의 원소를 추가하지 못하는 경우는 거의 없음
133 |
134 | ## 큐의 활용
135 |
136 | - 프린터의 출력 처리
137 | - 은행 업무
138 | - 콜센터 고객 대기시간
139 | - 프로세스 관리
140 | - 너비 우선 탐색(BFS, Breadth-First Search) 구현
141 | - 캐시(Cache) 구현
142 | - 컴퓨터 버퍼에서 주로 사용, 마구 입력이 되었으나 처리를 하지 못할 때, 버퍼(큐)를 만들어 대기 시킨다. 먼저 들어온 입력먼저 처리
143 |
144 | ⇒ 데이터가 입력된 시간 순서대로 처리해야 할 필요가 있는 상황에 이용
145 |
146 |
147 |
148 | ## 출처
149 | ### 스택
150 | https://yoongrammer.tistory.com/45
151 | https://monsieursongsong.tistory.com/4
152 | https://propercoding.tistory.com/17
153 |
154 | ### 큐
155 | https://devuna.tistory.com/22
156 | https://velog.io/@dongchyeon/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%ED%81%90-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%9D%98-%EA%B5%AC%ED%98%84
157 | https://lktprogrammer.tistory.com/59
158 | https://monsieursongsong.tistory.com/5?category=754667
159 | https://currygamedev.tistory.com/17
160 | https://ppomelo.tistory.com/58
161 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/인터럽트.md:
--------------------------------------------------------------------------------
1 | // 22.09.07
2 |
3 |
4 |
5 | # ❤️ 인터럽트
6 |
7 |
8 |
9 | ### 🤔 운영체제와 하드웨어 간의 상호 동작
10 |
11 | - 운영체제는 `레지스터(상태, 명령, 데이터 레지스터)`를 읽고 쓰는 것을 통해 `하드웨어 장치의 동작을 제어`할 수 있음
12 |
13 | | 레지스터 | 하는일 |
14 | | ---------------------- | ---------------------------------------------------- |
15 | | 상태(Status) 레지스터 | 하드웨어 장치의 `현재상태`를 읽을 수 있는 레지스터 |
16 | | 명령(Command) 레지스터 | 하드웨어 장치가 `특정동작을 하도록 요청`할 때 사용 |
17 | | 데이터(Data) 레지스터 | 하드웨어 장치가 `데이터를 보내거나 받거나`할 때 사용 |
18 |
19 |
20 |
21 | **운영체제와 하드웨어 장치 간에 폴링을 통한 상호작용**
22 |
23 | 1. **폴링(Polling)**을 한다
24 |
25 | ```뜻
26 | 폴링(Polling)
27 | - 운영체제가 하드웨어 장치의 상태 레지스터를 읽음으로써 명령 수신 여부를 주기적으로 확인하는 것
28 | - 즉. 하드웨어장치의 상태를 수시로 체크해 명령을 받을 수 있는지 확인하는 것
29 |
30 | 2. 운영체제가 **데이터 레지스터에 데이터를 전달**함
31 | 3. 운영체제가 **명령 레지스터에 명령을 기록**함
32 | 4. 운영체제는 하드웨어 장치가 **특정 동작을 처리하였는지 폴링 반복문**을 돌면서 기다린다. (성공/실패 코드를 받게 됨)
33 |
34 |
35 |
36 | 👉폴링을 하는 동안에는 다른 프로세스에게 CPU를 양도하지 않고 하드웨어 장치가 동작을 완료할떄까지, 계속 루프를 돌면서 하드웨어 상태를 체크함
37 |
38 | 👉하드웨어 장치의 속도는 매우 느리기 때문에 **CPU를 많이 낭비**하게 된다.
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | ### 🤔 인터럽트란?
47 |
48 | > CPU가 프로그램을 실행하고 있을때, I/O 하드웨어 등의 장치에 예외 상황이 발생하여 처리가 필요한 경우,
49 | >
50 | > 현재 실행중인 작업을 즉시 중단하고, 발생된 상황에 대한 우선처리가 필요함을 CPU에게 알리는 것
51 |
52 | - 지금 수행 중인 일보다 `더 중요한일`(Ex. 입출력, 우선 순위 연산 등)이 발생하면 `그 일을 먼저 처리`하고 나서 하던 일을 계속해야함
53 |
54 |
55 |
56 | #### 인터럽트 발생 시!
57 |
58 | - 운영체제는 디바이스를 폴링하는 대신 I/O 요청한 프로세스를 **블록** 시키고 **CPU를 다른 프로세스에게 양도
**
59 | - 장치가 끝마치면 하드웨어 인터럽트를 발생시키고 CPU는 운영체제가 미리 정의해놓은 `인터럽트 서비스 루틴(ISR)` 또는 `인터럽트 핸들러(Interrput Handler)`를 실행
60 | - `인터럽트 핸들러(Interrput Handler)`는 입출력 요청, I/O 대기중인 프로세스 꺠우기 등을 해 프로세스가 작업을 계속 할 수 있도록 함
61 |
62 |
63 |
64 | #### 인터럽트 종류
65 |
66 | - 외부 인터럽트, 내부 인터럽트, 소프트웨어 인터럽트가 있음
67 |
68 | | 구분 | 내용 |
69 | | ---------------------------- | ------------------------------------------------------------ |
70 | | **외부
인터럽트** | 입출력 장치, 타이밍 장치, 전원 등 외부적인 요인으로 발생
- 타이머 인터럽트 : 타이머가 일정한 시간 간격으로 중앙처리장치에 인터럽트 요청
- 입출력 인터럽트 : 속토가 느린 입출력장치가 입출력 준비가 완료되었음을 알리기 위해 인터럽트 요청 |
71 | | **내부 인터럽트
(Trap)** | 잘못된 명령이나 데이터를 사용할 때 발생
0으로 나누기, 오버플로우, 명령어를 잘못 사용한 경우(Exception)
-하드웨어 인터럽트 : 컴퓨터 고장, 데이터 전달 과정에서 비트 오류, 전원이 나간 경우
-실행할 수 없는 명령어 : 기억장치에서 인출한 명령어의 비트 패턴이 정의되어 있지 않은 경우
-명령어 실행 오류 : 나누기 0ㅇ을 하는 경우
-사용 권한 위배 : 사용자가 운영체제만 사용할 수 있는 자원에 액세스하는 경우 |
72 | | **소프트웨어
인터럽트** | 프로그램 처리 중 명령의 요청에 의해 발생한 것(SVC 인터럽트)
-사용자가 프로그램을 실행시킬떄 발생 : 소프트웨어 이용 중에 다른 프로세스를 실행시키면 시분할처리를 위해 자원 할당 동작이 수행 |
73 |
74 |
75 |
76 |
77 |
78 | ### 🤔 인터럽트 처리과정
79 |
80 |
81 |
82 | - 명령어 사이클은 `인출(Fetch Stage)`과 `실행(Execution Stage)` 두 단계를 반복 수행
83 |
84 | - 이때, 인터럽트 요청이 들어오면 ❗️바로 이를 처리하는 것이 아니라 `명령어 N의 실행 단계를 마쳐야함`
85 | - 명령어의 실행 단계를 마칠때마다, 중앙처리장치(CPU)는 반복적으로 인터럽트 요청이 있는지 확인
86 | - 인터럽트 요청이 있으면 `인터럽트 서비스 단계를 진행`
87 |
88 |
89 |
90 | #### 좀 더 큰 개념으로 살펴본다면
91 |
92 |
93 |
94 | **주 프로그램이 실행되다가 인터럽트 발생 시❗️
**
95 |
96 | - 현재 수행 중인 프로그램을 멈추고, **상태 레지스터와 PC 등을 스택에 잠시 저장**한 뒤에 **인터럽트 서비스**으로 간다.
97 | - 잠시 저장하는 이유는, 인터럽트 서비스 루틴이 끝난뒤 다시 원래 작업으로 돌아와야 하기 때문
98 |
99 | ```요약
100 | ⁉️ Process A 실행 중 디스크에서 어떤 데이터를 읽어오라는 명령을 받음
101 |
102 | 1. Process A는 System Call을 통해 인터럽트를 발생
103 | 2. CPU는 현재 진행중인 기계어 코드를 완료
104 | 3. 현재까지 수행중이였던 상태를 해당 Process의 PCB(Process Control Block)에 저장함
105 | (수행중이던 메모리주소, 레지스터 값, 하드웨어 상태 등..)
106 | 4. PC(Program Counter, 레지스터)에 다음에 실행할 명령의 주소를 저장
107 | 5. 인터럽트 벡터를 읽고 ISR 주소 값을 얻어 ISR(Interrupt Service Routine)러 점프하여 루틴을 실행
108 | 6. 해당 코드를 실행함
109 | 7. 해당 일을 다 처리하면, 대피시킨 레지스터를 복원
110 | 8. ISR의 끝에 IRET 명령어에 의해 인터럽트가 해제된다.
111 | - IRET : Intel 아키테처의 어셈블리 명령어 중 하나로
112 | '인터럽트 처리 시에 모튼 처리를 완료하고 다시 태스트로 복구하는 명령어'
113 | 9. IRET 명령어가 실행되면, 대피시킨 PC 값을 복원하여 이전 실행 위치로 복원
114 | - 인터럽트 번호는 예외상황 인터럽트를 제외하고 운영체제가 결정!
115 | ```
116 |
117 |
118 |
119 |
120 |
121 | ### 🤔 폴링 VS 인터럽트
122 |
123 | - 컨트롤러가 입력을 받아드리는 방법(우선순위 판별방법)에는 두가지가 있음
124 |
125 | **폴링**
126 |
127 | - 사용자가 명형어를 사용해 입력 핀의 값을 계속 읽어 변화를 알아내는 방식
128 |
129 | - 인터럽트 요청 플래그를 차례로 비교하여 우선순위가 가장 높은 인터럽트 자원을 찾아 이에 맞는 인터럽트 서비스 루틴을 실행(하드웨어에 비해 속도느림)
130 |
131 |
132 |
133 | ```폴링
134 | 프로세스 1이 실행 중에 Disk로부터 I/O 요청이 발생 시
135 |
136 | - 운영체제는 I/O 요청이 완료될때까지 반복적으로 폴링한다.
137 | - 디스트가 I/O 요정의 처리를 완료하면 프로세스 1이 다시 동작한다.
138 |
139 | => 플링을 하는 시간에는 원래하던 일에 집중할 수 없어 더 많은 기능을 제대로 수행하지 못함
140 | ```
141 |
142 |
143 |
144 | **인터럽트**
145 |
146 | - MUC(Micro Controller Unit, 컴퓨터) 자체가 하드웨어적으로 변화를 체크하여 변화시에만 일정한 동작을 하는 방식
147 | - 인터럽트 방식은 하드웨어로 지원받아야하는 제약이 있지만, 폴링에 비해 신속하게 대응하는 것이 가능!
148 | - 따라서 **실시간 대응이 필요할 때 필수적인 기능!**
149 | - 즉, 인터럽트는 **발생 시기를 예측하기 힘든 경우에 컨트롤러가 가장 빠르게 대응할 수 있는 방법!
**
150 |
151 |
152 |
153 | ```요약
154 | 프로세스 1이 실행 중에 Disk로부터 I/O 요청이 발생 시
155 |
156 | - 요청을 처리하는 동안에 운영체제는 프로세스 2를 CPU에서 실행
157 | - 프로세스 1에 대한 디스크 요청이 완료되면, 인터럽트를 발생 시켜 운영체제는 프로세스 1을 다시 CPU에서 실행
158 |
159 | => 이처럼 인터럽트를 사용하면 CPU 연산과 I/O 장치 작업을 중첩시켜 수행할 수 있게 됨
160 | => 그렇기 때문에 폴링보다 CPU 사용률을 높일 수 있음
161 | =>
162 | ```
163 |
164 |
165 |
166 |
하지만 인터럽트가 무조건 폴링보다 좋다고 할 수 없음
167 |
168 | ```예시
169 | - 단 한번의 폴링으로만 끝날 정도의 빠른 하드웨어 장치라면 인터럽트보다 폴링이 더 효율적
170 | - 인트럽트를 시용하면 현재 실행중인 프로세스를 다른 프로세스로 문액교환(COntext Switcing)하게되고 이때 많은 비용이 수반
171 | => 그렇기 때문에 빠른 하드웨어 장치라면 폴링이 더 효율적이고, 느린 하드웨어 장치라면 인터럽트가 더 효율적❗️
172 | ```
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 | 출처
181 |
182 | https://dar0m.tistory.com/257?category=976685
183 |
184 | https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Operating%20System/Interrupt.md
185 |
--------------------------------------------------------------------------------
/Computer Science/Computer Architecture/실수표현방식 (고정 소수점과 부동 소수점).md:
--------------------------------------------------------------------------------
1 | // 2022.07.26
2 |
3 | // JI SOO (Brown)
4 |
5 |
6 |
7 | # 실수의 표현 방식
8 |
9 | ## 🟣 실수란?
10 |
11 | - 실수는 주로 실직선 위의 점, 또는 십진법 전개로 표현되는 수 체계이다. 실수는 0보다 큰 양수, 0보다 작은 음수, 0으로 구분되며, 실직선 위에 모든 수를 표현하기 떄문에 ```소수점도 포함된다```.
12 |
13 |
14 |
15 | ### 🟣 실수의 표현 방식
16 |
17 | - 고정 소수점
18 | - 부동 소수점
19 |
20 | 컴퓨터에서 실수를 표현하는 방법은 정수에 비해 훨씬 복잡하다. 컴퓨터에서 실수는 정수와 마찬가지로 0과 1 즉, 2진법으로만 표현해야하기 떄문이다. 따라서 실수를 표현하기 위한 방법으로 ```고정소수점``` 과 ```부동소수점```을 사용하고 있다.
21 |
22 |
23 |
24 | ## 🟣 고정소수점 (Fized Point)
25 |
26 | 실수는 보통 정수부와 소수부로 나뉜다. 따라서 실수를 표현하는 가장 간단한 방식은 소수부 자릿수를 미리 정하여 고정된 자릿수의 소수를 표현하는 것이 고정 소수점이다.
27 |
28 | ### 🟣 고정소수점 구성
29 |
30 |
31 |
32 | ### 🟣 위 그림을 바탕으로 예시를 살펴보자.
33 |
34 | 고정소수점이 32비트일 때, ```부호비트는 1비트만 가져간다.``` 부호비트는 실수의 부호를 나타내는 비트 자리로, 실수가 음수라면 1을 양수라면 0을 입력해준다.
35 |
36 | 정수부에서는 실수의 정수부분을 2진법으로 표현하여 입력해준다. 15비트를 차지한다. 소수부에서도 마찬가지로 동일하게 2진법으로 표현하여 입력해준다. 16비트를 차지한다. (하지만, 이렇게 15, 16비트만 차지할 수 있어서 너무 범위가 적다는 것이 단점이다)
37 |
38 |
39 |
40 | #### 📝 ```12.125```실수를 예시로 표현해보자.
41 |
42 | 1. 가장 먼저 ```12.125```실수를 부호, 정수부, 소수부로 나누어 2진법으로 구한다.
43 |
44 | | 분류 | 이진법 |
45 | | ------ | ------------ |
46 | | 부호 | 0 (양수라서) |
47 | | 정수부 | 1100 |
48 | | 소수부 | 001 |
49 |
50 | > 💁🏻 여기서 잠깐, 소수부는 어떻게 2진법으로 구할까?
51 | >
52 | > 소수점 뒤에있는 숫자들은 하나씩 2진법으로 바꿔버리면 되지 않을까? 라고 생각할 수도 있지만, 그렇게 되면 아래 처럼 서로다른 10진수가 2진수로 변환됐을때 중복이 되는 문제가 생긴다.
53 | >
54 | > | 10진수 | 2진수 |
55 | > | ------ | ------- |
56 | > | 1.41 | 1.100 1 |
57 | > | 1,9 | 1.1001 |
58 | >
59 | > 그렇기 때문에 소수부를 구하는 방식은 조금 다르다.
60 | >
61 | > 소수부는 10진수에 2를 곱해가면서 1이나 0을 뽑아내는 방식으로 진행한다. 정수부를 변환할때면 1이나오면 종료했다면, 여기서는 0이 나오면 종료하고 결과를 밑에서부터가 아니라 위에서부터 읽어준다.
62 | >
63 | > 📝 ```0.625```를 이진수로 변환하는 예시
64 | >
65 | > ```
66 | > 0.625 * 2 = 1.25 = 1 + 0.25 -> 1
67 | > 0.25 * 2 = 0.5 = 0 + 0.5 -> 0
68 | > 0.5 * 2 = 1.0 = 1 + 0 -> 1
69 | >
70 | > 나머지가 0이 나왔으니까, 빼낸 숫자들을 위에서부터 읽어주면, 0.101
71 | >
72 | > ```
73 |
74 | 2. 이렇게 구한 각각의 부호, 정수부, 소수부를 각 비트 파트에 입력해주면 고정소수점이 완성된다!
75 |
76 | 
77 |
78 |
79 |
80 | ## 🟣 부동 소수점 (Floating Point)
81 |
82 | 고정소수점에서 실수를 정수부와 소수부로 나눴지만, 부동소수점에서는 ```가수부```와 ```지수부```로 나눈다.
83 |
84 | ### 🟣 부동소수점 구성
85 |
86 | 아래처럼 작성하는 방식이 부동소수점 방식으로 저장된 실수라고 볼 수 있다. 이처럼 부동소수점은 고정소수점과 다르게 소수점 ```.```이 유동적이다.
87 |
88 |
89 |
90 |
91 |
92 | - 지수부: bias(32비트 bias = 127, 64 비트 bias = 1023)을 더한 값을 넣어준다. 지수가 마이너스일때 지수의 부호 비트를 하나 더 만드는 것이 애매해서 8자리 음수 양수를 둘 다 쉽게 표현하고자 bias를 더하는 방식이 생겼다. (읭?)
93 |
94 | - > 지수부 범위
95 | >
96 | > | 0 - 127 | 음수 |
97 | > | --------- | ---- |
98 | > | 128 - 255 | 양수 |
99 |
100 | - 가수부: 가수부에 정규화 결과 소수점 오른쪽에 있는 숫자들을 왼쪽부터 그대로 넣고 남는 자리는 0으로 채운다. 소수점 왼쪽은 정규화를 하면 항상 1이어서 굳이 정하지 않는다. 1을 hidden bit 이라고 부른다.
101 |
102 |
103 |
104 | ### 🟣 위 그림을 바탕으로 예시를 살펴보자.
105 |
106 | ```부호비트는 1비트```만 가져간다. 부호비트는 실수의 부호를 나타내는 비트자리로 실수가 음수면 1, 양수면 0을 입력해준다. ```지수부는 8비트```, ```가수부는 23비트```를 가져간다.
107 |
108 | #### 📝 `12.125`실수를 예시로 표현해보자.
109 |
110 | 1. ```12.125```에서 ```.```을 기준으로 12는 정수부, 125는 실수부에 속한다.
111 | 2. 정수부에 해당하는 12를 2진법으로 바꾸면, 1100값이 나온다.
112 |
113 |
114 |
115 | 3. 소수부에 해당하는 ```0.125```를 이진법으로 구하면 아래와 같다. 현재까지는 '고정소수점'을 구하는 방식이랑 똑같다. 그래서 12.125를 이진법으로 바꾸면 ```1100.001```이라는 숫자가 나온다.
116 |
117 |
118 |
119 | 4. ```1100.001``` 의 소수점을 맨 앞까지 가져간 만큼 수를 지수로 가져온다.
120 |
121 | - ```1100.001```의 소수점을 가장 첫번째 자리로 옮기기 위해 총 ```3```만큼 움직이게 된다. 3을 2의 지수로 가져와 입력해준다.
122 |
123 | 
124 |
125 | 5. 부호비트, 지수부, 가수를 구한다.
126 |
127 | - 부호비트는 양수이기때문에 0
128 |
129 | - 지수부를 구하는 방법으로 우선 ```bias값인 127```에 전단계에서 구한 2의 지수 3을 더하여 130을 구한다. 그 다음 ```130```을 이진법으로 바꾸어 ```10000010```을 구하면 해당 값이 지수부가 된다.
130 |
131 | 
132 |
133 | 6. 가수부는 전 단계에서 소수점을 맨 앞으로 가져간 1.100001의 소수부분인 100001이 된다.
134 |
135 | 
136 |
137 | 7. 구한 부호, 지수부, 가수부를 각 비트 파트에 입력한다.
138 |
139 | 
140 |
141 |
142 |
143 | ## 🟣 고정소수점과 부동소수점의 의의
144 |
145 | 부동소수점 방식을 사용하면 고정 소수점보다 훨씬 많은 범위까지 표현할 수 있다. 하지만 부동소수점 방식에 의한 실수 표현은 항상 오차가 존재한다는 단점을 가지고 있다.
146 |
147 | 부동소수점은 옛날에 메모리가 부족할 당시, float 자료형을 담을 메모리 공간은 한정되어있는데, 소수점은 무한히 늘어날 수 있기 때문에 이를 효율적으로 담기 위해서 생겨난 개념이라고 한다. (효율적 = 정확한건 아니다, 그래서 오차가 존재하는 것!)
148 |
149 | 어쨋든 그래서, 컴퓨터에서 실수를 표현하는 방법은 정확한 표현이 아닌 언제나 근사치를 표현할 뿐이라고 한다.
150 |
151 |
152 |
153 | ## 📖 References
154 |
155 | - [본문에 있는 이미지 출처](https://velog.io/@alicesykim95/%EC%8B%A4%EC%88%98%ED%91%9C%ED%98%84-%EB%B0%A9%EC%8B%9D-%EA%B3%A0%EC%A0%95-%EC%86%8C%EC%88%98%EC%A0%90%EA%B3%BC-%EB%B6%80%EB%8F%99-%EC%86%8C%EC%88%98%EC%A0%90)
156 |
157 | - [본문내용도 마찬가지로 위와 같은 링크](https://velog.io/@alicesykim95/%EC%8B%A4%EC%88%98%ED%91%9C%ED%98%84-%EB%B0%A9%EC%8B%9D-%EA%B3%A0%EC%A0%95-%EC%86%8C%EC%88%98%EC%A0%90%EA%B3%BC-%EB%B6%80%EB%8F%99-%EC%86%8C%EC%88%98%EC%A0%90)
158 |
159 | - [고정소수점 계산 방식, 부동소수점 정규화 방식 참고](https://developer-eun-diary.tistory.com/9)
160 |
161 |
--------------------------------------------------------------------------------
/Computer Science/Database/SQL-injection.md:
--------------------------------------------------------------------------------
1 | # SQL Injection
2 |
3 | ### 1. SQL injection 이란??
4 |
5 | SQL injection 이란 악의적인 사용자가 보안상의 취약점을 이용하여, 임의의 SQL문을 주입하고 실행되기 하여 데이터베이스가 비정상적인 동작을 하도록 조작하는 행위를 말한다. 인젝션 공격은 OWSAP Top10 중 첫번째에 속해 있으며, 공격이 비교적 쉬운 편이고 공격에 성공할 경우 큰 피해를 입힐 수 있는 공격이다.
6 |
7 | 
8 | * OWASP TOP 10은 웹 애플리케이션 취약점 중에서 빈도가 많이 발생하고, 보안상 영향을 크게 줄 수 있는 것들 10가지를 선정한 문서이다.
9 |
10 |
11 |
12 | injection의 실 예시로 2017년 3월에 일어난 '여기어때'의 대규모 개인정보 유출 사건이 있다.
13 | * https://show-me-the-money.tistory.com/entry/%EC%97%AC%EA%B8%B0-%EC%96%B4%EB%95%8C-%ED%95%B4%ED%82%B9-%EC%82%AC%EA%B1%B4%EC%9D%84-%ED%8C%8C%ED%97%A4%EC%B9%98%EB%8B%A4
14 |
15 |
16 |
17 | ### 2. SQL injection 공격 종류 및 방법
18 |
19 | 1) 논리적 에러를 이용한 SQL injection(Error based SQL injection)
20 | - 가장 많이 쓰이고, 대중적인 공격 기법.
21 | - 사진에서 보이는 쿼리문은 일반적으로 로그인 시 많이 사용되는 SQL 구문.
22 | - 해당 구문에서 입력값에 대한 검증이 없음을 확인하고, 악의적인 사용자가 임의의 SQL 구문을 주입하였다.
23 | - 주입된 내용은 'OR=1 --'로 WHERE 절에 있는 싱글쿼터를 닫아주기 위한 싱글쿼터와 OR 1=1 라는 구문을 이용해 WHERE 절을 모두 참으로 만들고
24 | - --를 넣어 줌으로 뒤의 구문을 모두 주석 처리 해주었다.
25 | - 매우 간단한 구문이지만, 결론적으로 Users 테이블에 있는 모든 정보를 조회하게 됨으로써 가장 먼저 만들어진 계정으로 로그인에 성공하게 된다.
26 | - 보통은 관리자 계정을 맨 처음 만들기 때문에 관리자 게정에 로그인할 수 있게 된다.
27 | - 관리자 계정을 탈취한 악의적인 사용자는 관리자의 권한을 이용해 또 다른 2차피해를 발생시킬 수 있게 된다.
28 | 
29 |
30 |
31 |
32 | 2) 유니언 명령어를 이용한 SQL injection(Union based SQl injection)
33 | - SQL에서 Union 키워드는 두 개의 쿼리문에 대한 결과를 통합해서 하나의 테이블로 보여주게 하는 키워드
34 | - 정상적인 쿼리문에 Union 키워드를 사용하여 인젝션에 성공하면 원하는 쿼리문을 실행할 수 있게 됨
35 | - 유니언 인젝션을 성공하기 위해서는 두 가지의 조건이 있다. (1. Union하는 두 테이블의 컬럼 수가 같아야하고, 2. 데이터의 형태가 같아야한다.)
36 | - 사진에서 보이는 쿼리문은 Board라는 테이블에서 게시글을 검색하는 쿼리문이다.
37 | - 입력값을 title과 contents 컬럼의 데이터랑 비교한 뒤 비슷한 글자가 있는 게시글을 출력한다.
38 | - 여기서 입력값으로 Union 키워드와 함께 컬럼 수를 맞춰서 SELECT 구문을 넣어주게 되면 두 쿼리문이 합쳐져서 하나의 테이블로 보여지게 된다.
39 | - 현재 인젝션 한 구문은 사용자의 id와 password를 요청하는 쿼리문이다.
40 | - 인젝션이 성공하게 되면, 사용자의 개인정보가 게시글과 함께 화면에 보여지게 된다.
41 | 
42 |
43 |
44 |
45 | 3) 블라인드 SQL injection - based Boolean
46 | - Blind SQL injection은 DB로부터 특정한 값이나 데이터를 전달받지 않고, 단순히 참과 거짓의 정보만 알 수 있을때 사용한다.
47 | - 로그인 폼에 SQL injection이 가능하다고 가정 했을때, 서버가 응답하는 로그인 성공과 로그인 실패 메시지를 이용하여
48 | - DB의 테이블 정보 등을 추출해 낼 수 있다.
49 | - 이미지는 Blind injection을 이용하여 데이터베이스의 테이블 명을 알아내는 방법이다.
50 | - MySQL 인젝션이 가능한 로그인 폼을 통하여 악의적인 사용자는 임의로 가입한 abc123 이라는 아이디와 함께 abc123' and ASCI ~~~ 구문을 주입한다.
51 | - 해당 구문은 MySQL에서 테이블 명을 조회하는 구문으로 limit 키워드를 통해 하나의 테이블만 조회하고, SUBSTR 함수로 첫 글자만, 마지막으로 ASCII를 통해 ascii 값으로 변환해준다.
52 | - 만약에 조회되는 테이블 명이 Users라면 'U'자가 ascii 값으로 조회가 될 것이고, 뒤의 100이라는 숫자 값과 비교를 하게 된다.
53 | - 거짓이면 로그인 실패가 될 것이고, 참이 될 때까지 뒤의 100이라는 숫자를 변경해 가면서 비교를 하면 된다.
54 | - 공격자는 이 포르세스를 자동화 스크립트를 통하여 단기간 내에 테이블 명을 알아 낼 수 있다.
55 | 
56 |
57 |
58 |
59 | 4) 블라인드 SQL injection - based Time
60 | - Time Based SQL injection도 마찬가지로 서버로부터 특정한 응답 대신에 참 혹은 거짓의 응답을 통해서 DB의 정보를 유추하는 기법이다.
61 | - 사용되는 함수는 MySQL 기준으로 SLEEP과 BENCHMARK이다.
62 | - 이미지는 Time based SQL injection을 사용하여 현재 사용하고 있는 데이터베이스의 길이를 알아내는 방법이다.
63 | - 로그인 폼에 주입이 되었으며 임의로 abc123이라는 계정을 생성해 둔다.
64 | - 악의적인 사용자가 abc123' OR ~~~ 구문을 주입한다.
65 | - 여기서 LENGTH 함수는 문자열의 길이를 반환하고, DATABASE 함수는 데이터베이스의 이름을 반환한다.
66 | - 위의 그림은 Time based SQL injection을 사용하여 현재 사용하고 있는 데이터베이스의 길이를 반환한다.
67 | - 주입된 구문에서, LENGTH(DATABASE()) = 1가 참이면 SLEEP(2)가 동작하고, 거짓이면 동작하지 않는다.
68 | - 이를 통해 숫자 1부분을 조작하여 데이터베이스의 길이를 알아낼 수 있다.
69 | - 만약에 SLEEP이라는 단어가 치환처리 되어있다면, 또 다른 방법으로 BENCHMARK나 WAIT 함수를 사용할 수 있다.
70 | 
71 |
72 |
73 |
74 | 5) 저장된 프로시저에서의 SQL injection(Stored Procedure SQL injection)
75 | - 저장 프로시저는 일련의 쿼리들을 모아 하나의 함수처럼 사용하기 위한 것임.
76 | - 공격에 사용되는 대표적인 저장 프로시저는 MS-SQL에 있는 xp_cmdshell로 윈도우 명령어를 사용할 수 있게 된다.
77 | - 단, 공격자가 시스템 권한을 획득해야 하므로 공격 난이도가 높으나 공격에 성공한다면
78 | - 서버에 직접적인 피해를 입힐 수 있는 공격이다.
79 |
80 |
81 | 6) 다량의 SQL injection(Mass SQL injection)
82 | - 2008년에 처음 발견된 공격기법으로 기존 SQL injection과 달리 한번의 공격으로 다량의 데이터베이스가 조작되어 큰 피해를 입히는 것을 의미
83 | - 보통 MS-SQL을 사용하는 ASP 기반 웹 애플리케이션에서 많이 사용되며
84 | - 쿼리문은 HEX 인코딩 방식으로 인코딩하여 공격한다.
85 | - 보통 데이터베이스 값을 변조하여 데이터베이스에 악성스크립트를 삽입하고
86 | - 사용자들이 변조된 사이트에 접속 시 좀비PC로 감염되게 한다.
87 | - 이렇게 감염된 좀비PC들은 DDoS 공격에 사용된다.
88 |
89 |
90 | ### 3. 대응방안
91 | #### 1) 입력 값에 대한 검증
92 | 사용자의 입력이 DB Query에 동적으로 영향을 주는 경우, 입력된 값이 개발자가 의도한 값(유효값)인지 검증한다.
93 | - ID, PASSWORD, 게시판 제목, 본문, 검색창, 주소창 등의 모든 입력란에 특수문자(등호, 부등호, 인용 부호등)를 입력하지 못하도록 소스코드 수정
94 | - 입력 값에 정의된 문자 길이를 검증하여 SQL 문이 추가 삽입되지 않도록 예외처리
95 | - 파라미터가 숫자인 경우 isnumeric과 같은 함수를 이용하여 검증하며, 문자인 경우 정규표현식을 이용하여 특수문자를 치환(특히 SQL문에서 활용되는 문자(',",--,or 등)는 반드시
96 |
97 | #### 2) Prepared Statement 구문 사용
98 | - Prepared Statement 구문을 사용하게 되면
99 | - 사용자의 입력 값이 데이터베이스의 파라미터로 들어가기 전에 DBMS가 미리 컴파일 하여 실행하지 않고 대기한다.
100 | - 그 후 사용자의 입력 값을 문자열로 인식하게 하여 공격 쿼리가 들어간다고 하더라도
101 | - 사용자의 입력은 이미 의미 없는 단순 문자열이기 때문에 전체 쿼리문도 공격자의 의도대로 작동하지 않는다.
102 |
103 | #### 3) Error Message 노출 금지
104 | - 공격자가 SQL injection을 수행하기 위해서는 데이터베이스의 정보(테이블명, 컬럼명 등)가 필요하다.
105 | - 데이터베이스 에러 발생 시 따로 처리를 해주지 않았다면, 에러가 발생한 쿼리문과 함께 에러에 관한 내용을 반환해 준다.
106 | - 여기서 테이블명 및 컬럼명 그리고 쿼리문이 노출이 될 수 있기 때문에
107 | - 데이터베이스에 대한 오류발생시 사용자에게 보여줄 수 있는 페이지를 제작해야함.
108 |
109 | #### 4) 웹 방화벽 사용
110 | - 웹 공격 방어에 특화되어있는 웹 방화벽을 사용하는 것도 하나의 방법이다.
111 | - 웹 방화벽은 소프트웨어형, 하드웨어형, 프록시형 이렇게 세가지 종류로 나눌 수 있다.
112 | - 소프트웨어형은 서버 내에 직접 설치하는 방밥이다.
113 | - 하드웨어형은 네트워크 상에서 서버 앞 단에 직접 하드웨어 장비로 구성하는 것이다.
114 | - 프록시 형은 DNS 서버 주소를 웹 방화벽으로 바꾸고 서버로 가는 트래픽이 웹 방화벽을 먼저 거치도록 하는 방법이다.
115 |
116 |
117 | ## Reference
118 | - https://noirstar.tistory.com/264
119 | - https://12bme.tistory.com/98
120 | - https://qh5944.tistory.com/m/156
121 |
122 |
123 |
--------------------------------------------------------------------------------
/Computer Science/Software Engineering/함수형 프로그래밍 (Functional Programming).md:
--------------------------------------------------------------------------------
1 | // 2022.09.19 Brown
2 |
3 |
4 |
5 | # 🟠 프로그래밍 패러다임 (Programming Paradigm)
6 |
7 | 프로그래밍 패러다임은 프로그래머에게 프로그래밍의 관점으 락젝하고 코드를 어떻게 작성할 지 결정하는 역할을 한다.
8 | 새로운 프로그래밍 패러다임을 통해서 새로운 방식으로 생각하는 법을 배우게 되고, 이를 바탕으로 코드를 작성하게 된다.
9 |
10 | 프로그래밍 패러다임은 아래와 같이 구별할 수 있다.
11 |
12 | ## 🔸 명령형 프로그래밍
13 |
14 | ```bash
15 | 무엇(what)을 할 것인지 나타내기보다 어떻게(How) 할 것인지를 설명하는 방식
16 | 프로그래밍의 상태, 상태를 변경시키는 구문의 관점에서 연산을 설명한다.
17 | ```
18 | - 절차지향 프로그래밍
19 | - 수행되어야할 순차적인 처리 과정을 포함하는 방식 (C, C++)
20 | - 객체지향 프로그래밍
21 | - 객체들의 집합으로 프로그램의 상호작용을 표현 (C++, Java, C#)
22 |
23 | ## 🔸 선언형 프로그래밍
24 |
25 | ```bash
26 | 어떻게 할건지(HOW)보다는 무엇을 (WHAT)을 할 건지 설명하는 방식
27 | ```
28 |
29 | - 함수형 프로그래밍
30 | - 순수 함수를 조합하고 소프트웨어를 만드는 방식 (클로저, 하스켈, 리스프)
31 |
32 | 
33 |
34 |
35 | ```
36 | 🦁 이해를 돕기위한 선언형과 명령형 프로그래밍의 차이점!
37 |
38 | <명령형 프로그래밍> How 에 집중
39 | - 자리에서 일어난다
40 | - 부엌으로 이동한다
41 | - 컵과 물을 찾는다
42 | - 컵에 물을 부어 마신다
43 |
44 | <선언형 프로그래밍> What에 집중
45 | - 물을 찾아 마셔보자!
46 | ```
47 |
48 | # 🟠 함수형 프로그래밍
49 |
50 | - 명령형 프로그래밍으로 개발하던 개발자들은 소프트웨어의 크기가 점점 커짐에 따라 복잡하게 엉켜있는 코드를 유지보수하기 힘들다는 것을 느낌
51 | - 이러한 단점을 해결하기 위해서 함수형 프로그래밍을 사용하게됨.
52 | - 함수형 프로그래밍은 거의 모든 것을 순수함수로 나누어 문제를 해결하므로, 작은 문제를 해결하기 위한 함수를 작성하여 ```가독성을 높이고 유지보수를 용이```하게 해줌
53 | - 값이나 상태 변화 보다는 함수 자체의 응용을 중요하게 여긴다
54 | - 프로그램 동작 과정에서 상태가 변하지 않으면 홤수 호출이 각각 상호 간섭 없이 실행되므로 병렬처리를 할 때 부작용이 거의 없다는 장점이 있음.
55 |
56 | ## 🔸 함수형 프로그래밍에 대한 이해
57 |
58 | 함수형 프로그래밍은 작은 문제를 해결하기 위한 함수를 작성한다. 그렇기 때문에 함수형 프로그래밍에서는 n까지 반복문을 돌면서 숫자를 출력하고 싶을때, 아래와 같이 코드를 작성할 수 있다.
59 | (아래 process 코드는 이해를 돕기위한 수도코드이다.)
60 |
61 | ```swift
62 | process(10, print(num))
63 | ```
64 |
65 | 첫번째 인자는 몇 번 iteration을 돌 것인지 매개변수로 받았고, 두번째 인자로 전달받은 값을 출력하라는 함수를 매개변수로 받고 있다.
66 | 즉, 출력하는 함수를 파라미터로 넘겼다는 뜻인데, 이렇게 넘길 수 있는 이유는 ```'함수형 프로그래밍의 기본원리, 함수는 1급객체로 취급한다'라는 특징``` 때문이다.
67 | (이 함수형 프로그래밍에 대한 설명은 뒤에서 추가로 더 있어염)
68 |
69 | ### 🦁 명령형 프로그래밍과 다른점
70 |
71 | 명령형 프로그래밍에서는 메소드를 호출하면 상황에 따라 내부의 값이 바뀔 수 있다.
72 | 우리가 개발한 함수 내에서 선언된 변수의 메모리에 할당된 값이 바뀌는 등의 변화가 일어날 수 있기 때문이다.
73 |
74 | 하지만 함수형 프로그래밍은 메모리에 한 번 할당된 값은 새로운 값으로 변할 수 없다.
75 | 즉, 코드 이해와 실행결과의 관점에서 순수하게 함수에 전달된 인자 값만 결과에 영향을 주므로, 다른 상태값을 갖지 않고 순수하게 함수만으로 동작하여 언제나 일정한 결과값을 도출한다.
76 |
77 |
78 |
79 | ## 🔸 함수형 프로그래밍의 특징
80 |
81 | ```
82 | ✨ 부수효과 (side Effect)가 없는 순수 함수를 1급 객체 (first-class object)로 간주하여 파라미터나 반환값으로 사용할 수 있으며, 참조 투명성을 지킬 수 있다.
83 | ```
84 |
85 | ### 🦁 부수효과 (Side Effect) 란
86 |
87 | 부수효과란, 다음과 같은 변화 또는 변화가 발생하는 작업을 의미한다.
88 |
89 | - 변수의 값이 변경됨
90 | - 자료구조를 제자리에서 수정함
91 | - 콘솔 또는 I/O가 발생함
92 |
93 | 지금은 부수효과가 이해가 안갈 수 있다. 순수함수랑 부수효과를 함께 이해해보자.
94 |
95 | ### 🦁 순수함수 (Pure Function) 란
96 |
97 | 위의 부수효과들을 제거한 함수들을 순수함수라고 한다.
98 | 함수형 프로그래밍에서 이용하는 함수는 이러한 순수함수이다!
99 | 즉, 부수효과가 없는 것이 순수함수이므로, 들어온 인자가 같으면 결과가 항상 같은 함수
100 |
101 | ### 💬 예시를 통해 알아보자.
102 |
103 | ```swift
104 | var testName = "hello world"
105 |
106 | func getName() -> String {
107 | return testName
108 | }
109 | ```
110 |
111 | ```
112 | 위 함수는 순수함수일까? ❌
113 | - getName함수는 외부에 있는 name에 영향을 받는다.
114 | - name이 var로 선언되어 있어서 side-effect가 존재할 가능성이 높기 때문에 순수함수가 아니다.
115 | ```
116 |
117 | 그럼 위 함수를 순수함수로 바꿔보자.
118 | ```swift
119 | func getName(_ name: String) -> String {
120 | return name
121 | }
122 | ```
123 |
124 | ```
125 | 이렇게 바꾸면 순수함수이다. ✅
126 | - 함수 자체에 파라미터로 받은 name의 데이터로만 결정되기 때문에
127 | 외부의 영향을 전혀 받지 않고 파라미터의 입력에 대해서는 동일한 결과를 나타낸다.
128 | ```
129 |
130 | 하지만!!! 위에서 ```var``` 로 선언되어 side effect가 발생할 가능성이 존재한다고 했잖음?
131 |
132 | ```swift
133 | let testName = "hello world"
134 |
135 | func getName() -> String {
136 | return testName
137 | }
138 | ```
139 | ```
140 | 이렇게 바꿔도 순수함수이다!! ✅
141 | ```
142 |
143 | ### 💬 순수함수의 장점을 알아보자
144 |
145 | - 함수 자체가 독립적이며 side-effect가 없기 때문에 Thread에 안전성을 보장받을 수 있다. (순수함수는 메모리, I/O의 관점에서 side effect가 없기 때문에 안전성을 보장받는 것이다.)
146 | - Thread에 안전성을 보장받아 병렬처리를 동기화없이 진행할 수 있다.
147 |
148 | ### 🦁 1급객체 (first class object)란
149 |
150 | 1급 객체는 다음과 같은 조건을 만족하는 것들이 1급객체가 될 수 있다.
151 |
152 | ```
153 | - 변수나 데이터 구조 안에 담을 수 있다.
154 | - 파라미터로 전달 할 수 있다.
155 | - 반환값으로 사용할 수 있다.
156 | - 할당에 사용된 이름과 무관하게 고유한 구별이 가능하다.
157 | ```
158 |
159 | 함수형 프로그래밍에서 함수는 1급객체로 취급받기 때문에 위 예제에서 본 ```process(10, print(num))``` 처럼 함수를 파라미터로 넘기는 등의 작업이 가능한 것이다.
160 |
161 | ### 🦁 참조 투명성 (Referential Transparency)
162 |
163 | ```
164 | - 동일한 인자에 대해 항상 동일한 결과를 받아야 한다.
165 | - 참조 투명성을 통해 기존의 값은 변경되지 않고 유지된다.
166 | ```
167 |
168 | 명령평 프로그래밍과 함수형 프로그래밍에서 사용하는 함수는 ```side effect의 유무``` 에 따라 차이가 있다. 이에 따라서 함수가 참조에 투명한지 안한지 나눠지는데, 참조에 투명하다는 것은 말 그대로 함수를 실행하여도 어떠한 상태 변화 없이 항상 동일한 결과를 반환하여 항당 동일하게(투명하게) 실행 결과를 참조(예측)할 수 있다는 것을 의미한다.
169 |
170 | ## 🔸 함수형 프로그래밍의 장점을 알아보자!
171 |
172 | - 여러가지 연산 처리 작업이 동시에 일어나는 프로그램을 짜기 쉽다.
173 | - 멀티코어 혹은 여러 연산 프로세서를 사용하는 시스템에서 효율적인 프로그램을 만들기 쉽다.
174 | - 상태변화에 따른 부작용에서 자유로워지므로 순수하게 기능 구현에 초점을 맞춰 설계가 가능하다.
175 |
176 | # 🟠 명령형 프로그래밍과 함수형 프로그래밍 코드로 비교해보기
177 |
178 | doSomething 함수와 doAnotherThing 함수를 동시에 실행하는 코드를 작성했다고 치자.
179 |
180 | ```swift
181 | // ✅ 명령형 프로그래밍
182 | class CommandProgramming {
183 | func doSomething() {
184 | print("doSomething")
185 | }
186 |
187 | func doAnotherThing() {
188 | print("doAnotherThing")
189 | }
190 |
191 | func executeAll() {
192 | doSomething()
193 | doAnotherThing()
194 | }
195 | }
196 |
197 | // 호출
198 | excuteAll()
199 | ```
200 |
201 | ```swift
202 | // ✅ 함수형 프로그래밍
203 | class CommandProgramming {
204 | func doSomething() {
205 | print("doSomething")
206 | }
207 |
208 | func doAnotherThing() {
209 | print("doAnotherThing")
210 | }
211 |
212 | func executeAll(tasks: [() -> Void)) {
213 | for task in tasks {
214 | task()
215 | }
216 | }
217 | }
218 |
219 | // 호출
220 | excute(tasks: [doAnotherThing, doSomething])
221 | ```
222 |
223 | 함수형 프로그래밍 안에서는 함수가 일급객체 이므로, 함수를 전달인자 또는 반환값으로 사용할 수 있다.
224 | 차이점을 표로 보면 다음과 같다.
225 |
226 | 
227 |
228 |
229 |
230 | ## 📖 REFERENCE
231 | - [swift에서 명령형과 선언형 비교](https://borabong.tistory.com/5)
232 | - [망나니 개발자 함수형 프로그래밍 이란?](https://mangkyu.tistory.com/111)
233 | - [순수함수](https://jinnify.tistory.com/54)
234 |
235 |
236 |
--------------------------------------------------------------------------------
/Computer Science/Database/Transaction(트랜잭션).md:
--------------------------------------------------------------------------------
1 | // 2022.08.23 Noel
2 |
3 |
4 |
5 |
6 |
7 | # ❤️ DB 트랜잭션(Transaction)
8 |
9 |
10 |
11 | #### 🧡 트랜잭션 이란?
12 |
13 | > 트랜잭션(Transaction)은 **데이터베이스의 상태를 변환시키는 하나의 논리적 작업 단위** 라고 할 수 있으며, 트랜잭션에는 여러개의 연산이 수행될 수 있음
14 |
15 | - 하나의 트랜잭션은 `Commit`되거나 `Rollback `된다.
16 | - 트랜잭션은 `SELECT` `UPDATE` `INSERT` `DELETE`와 같은 연산을 수행하여 데이터 베이스의 상태를 변화시키는 작업 단위❗️
17 |
18 |
19 |
20 | - 트랜잭션은 하나의 논리적인 작업 단위이기 떄문에, `여러개의 작업을 하나의 논리적인 단위로 묶어서 반영과 복구를 조정할 수 있기 위해 사용`한다.
21 | - 따라서 데이터의 부정합이 일어났을 경우, `Rollback`해 데이터의 부정합의 방지할 수 있음
22 |
23 |
24 |
25 | - 트랜잭션은 작업의 완전성을 보장해줌
26 | - 논리적인 작업 set를 모두 완벽하게 처리하거나 또는 처리못할 경우에는 원상태로 복구해서 작업의 일부만 적용되는 현상이 발생하지 않게 만들어 주는 기능
27 | - `사용자 입장에서는 작업을 논리적 단위`로 이해 가능하고 `시스템 입장에서는 데이터들을 접근 또는 변경하는 프로그램의 단위`가 됨
28 |
29 |
30 |
31 |
32 | 작업 단위 → **많은 SQL 명령문들을 사람이 정하는 기준에 따라 정하는 것**
33 |
34 | ```
35 | 예시) 사용자 A가 사용자 B에게 만원을 송금한다.
36 |
37 | * 이때 DB 작업
38 | - 1. 사용자 A의 계좌에서 만원을 차감한다 : UPDATE 문을 사용해 사용자 A의 잔고를 변경
39 | - 2. 사용자 B의 계좌에 만원을 추가한다 : UPDATE 문을 사용해 사용자 B의 잔고를 변경
40 |
41 | 현재 작업 단위 : 출금 UPDATE문 + 입금 UPDATE문
42 | → 이를 통틀어 하나의 트랜잭션이라고 한다.
43 | - 위 두 쿼리문 모두 성공적으로 완료되어야만 "하나의 작업(트랜잭션)"이 완료되는 것이다. `Commit`
44 | - 작업 단위에 속하는 쿼리 중 하나라도 실패하면 모든 쿼리문을 취소하고 이전 상태로 돌려놓아야한다. `Rollback`
45 | ```
46 |
47 | 즉, **하나의 트랜잭션 설계를 잘 만드는 것이 데이터를 다룰 때 많은 이점을 가져옴**
48 |
49 |
50 |
51 |
52 |
53 | #### 🧡 트랜잭션 특징(ACID)
54 |
55 | 1. **원자성 (Atomicity)**
56 |
57 | > 트랜잭션이 데이터베이스에 모두 반영되거나 혹은 전혀 반영 되지 않아야함
58 |
59 | - 트랜잭션 내의 모든 명령은 반드시 완벽히 수행되어야하며, 모두가 완벽히 수행되지 않고 어느 하나라도 오류가 발생하면 트랜잭션 전부가 취소 되어야함
60 |
61 |
62 |
63 | 2. **일관성(Consistency)**
64 |
65 | > 트랜잭션의 작업 처리결과가 항상 일관성 있어야함
66 |
67 | - 시스템이 가지고 있는 고정요소는 트랜잭션 수행 전과 수행 완료 후의 `상태`가 같아야함
68 | - 상태 : `트랜잭션 수행이 보존해야할 일관성`
69 | - 명시적인 일관성
70 | - 기본 키, 외래 키 등과 같은 무결성 제약조건
71 | - 무결성 제약조건을 해치지 않는 데이터들에 대해서만 트랜잭션이 성공적으로 수행되어야함
72 | - 비명시적인 일관성
73 | - ex. 계좌 이체에서 A 계좌 출금 -> B 계좌 입금한다면?
74 | - 트랜잭션의 전과 후 두 계좌 잔고의 합이 같아야함
75 |
76 |
77 |
78 | 3. **독립성(Isolation)**
79 |
80 | > 둘 이상의 트랜잭션이 동시에 실행되고 있을 경우,
81 | >
82 | > 어떤 하나의 트랜잭션이라도 다른 트랜잭션 연산에 끼어 들 수 없음
83 |
84 | - 수행 중인 트랜잭션은 완전히 완료될 때까지 다른 트랜잭션에서 수행결과를 참조 할 수 없음
85 |
86 |
87 |
88 | 4. **지속성(Durability)**
89 |
90 | > 트랜잭션이 성공적으로 완료 되었을 경우, 결과는 영구적으로 반영되어야 함
91 |
92 |
93 |
94 |
95 |
96 | #### 🧡 트랜잭션의 Comnit과 Rollback
97 |
98 | **Commit**
99 |
100 | - Commit 연산은 하나의 트랙잭션이 성공적으로 끝났고, 데이터베이스가 일관성 있는 상태에 있을때, 하나의 트랜잭션이 끝났음을 알려주기 위해 사용하는 연산
101 |
102 |
103 |
104 | **Rollback**
105 |
106 | - Rollback 연산은 하나의 트랜잭션 처리가 비정상적으로 종료되어 데이터베이스의 일관성을 깨뜨렸을 때, 이 트랜잭션의 일부가 정상적으로 처리되었더라도 트랜잭션의 원자성을 구현하기 위해 이 **트랜잭션이 행한 모든 연산을 취소(Undo)하는 연산**
107 |
108 |
109 |
110 | ``` 참고!
111 | ⚠️ 면접 대비
112 | 상황이 주어지면 DB 측면에서 어떻게 해결할 수 있을지 대답할 수 있어야함
113 | ```
114 |
115 |
116 |
117 |
118 |
119 | #### 🧡 트랜잭션의 상태
120 |
121 |
122 |
123 | - 활동(Active)
124 | - 트랜잭션의 활동 상태, 트랜잭션이 실행중이며 동작 중인 상태
125 | - 부분 완료 (Partially Committed)
126 | - 트랜잭션의 Commit 명령이 도착한 상태
127 | - 트랜잭션의 Commit 이전의 SQL문이 수행되고, commit만 남은 상태를 말함
128 | - 완료(Committed)
129 | - 트랜잭션 완료 상태, 트랜잭션이 정상적으로 완료된 상태
130 | - 실패(Failed)
131 | - 트랜잭션 실패 상태, 트랜잭션이 더 이상 정상적으로 진행될 수 없는 상태
132 | - 취소(Aborted)
133 | - 트랜잭션 취소 상태, 트랜잭션이 취소되고 트랜잭션 실행 이전 데이터로 돌아간 상태
134 |
135 |
136 |
137 | **부분완료와 완료의 차이점**
138 |
139 | - Commit 요청이 들어오면 ➡︎ 부분완료 상태
140 | - 이후 Commit을 문제없이 수행 할 수 있다면 ➡︎ 완료 상태
141 | - 만약 오류가 발생하면 ➡︎ 실패상태
142 |
143 | - 부분완료는 Commit 요청이 들어왔을때, 완료는 Commit을 정상적으로 완료했을때
144 |
145 |
146 |
147 |
148 |
149 | #### 🧡 Transaction 관리를 위한 DBMS의 전략
150 |
151 | 이해를 하기위한 2가지 개념 DBMS의 개략적인 구조와 버퍼 관리자 및 트랜잭션 관리와 연관된 버퍼 관리 정책에 대한 이해가 필요
152 |
153 |
154 |
155 | 1. **DBMS의 구조**
156 |
157 |
158 |
159 |
160 | - 크게 2가지로 구분
161 | - Query Processor (질의 처리기)
162 | - Storage System (저장 시스템)
163 |
164 |
165 |
166 | - 데이터 베이스 시스템 저장공간
167 | - 보통 비휘발성 저장 장치인 디스크에 데이터 저장
168 | - 일부분은 Main Memory에 저장
169 | - 입출력 단위
170 | - 고정 길이의 page 단위로 disk에 읽거나 씀
171 |
172 |
173 |
174 |
175 | 2. **Page Buffer Manager or Buffer Manager**
176 |
177 | DBMS의 Storage System에 속하는 모듈 중 하나로, Main Memory에 유지하는 페이지를 관리하는 모듈
178 |
179 | > Buffer 관리 정책에 따라, UNDO 복구와 REDO 복구가 요구되거나 그렇지 않게 되므로, transaction 관리에 매우 중요한 결정을 가져온다.
180 |
181 |
182 |
183 |
184 |
185 | #### 🧡 UNDO는 왜 필요할까?
186 |
187 | > 수정된 Page들이 **Buffer 교체 알고리즘에 따라서 디스크에 출력**될 수 있음.
188 | >
189 | > Buffer 교체는 **transaction과는 무관하게 buffer의 상태에 따라서, 결정됨**.
190 | >
191 | > 이로 인해, 정상적으로 종료되지 않은 transaction이 변경한 page들은 원상 복구 되어야 하는데, 이 복구를 undo라고 함
192 |
193 |
194 |
195 | - 트랜잭션 종료전에 수정된 Page를 디스크에 쓰지 않은 경우
196 |
197 | - UNDO 오퍼레이션은 메모리 버퍼에 대해서만 이루어지면됨
198 | - 매우 간단하지만 매우 큰 크기의 메모리 버퍼가 필요
199 |
200 |
201 |
202 | - 트랜잭션 종료전에 수정된 Page를 디스크에 쓴 경우
203 |
204 | - steal
205 |
206 | - 수정된 페이지를 언제든지 디스크에 쓸 수 있는 정책
207 | - 대부분의 DBMS가 채택하는 Buffer 관리 정책
208 |
209 | - 수정된 페이지가 어떠한 시점에도 디스크에 써질 수 있기 때문에 필연적으로 UNDO logging과 복구를 필요로 함.
210 |
211 | - ¬steal
212 |
213 | - 수정된 페이지들을 최소한 트랜잭션 종료시점 EOT (End Of Transaction)까지는 버퍼에 유지하는 정책
214 |
215 | - UNDO 작업이 필요하지 않지만, 매우 큰 메모리 버퍼가 필요함.
216 |
217 |
218 |
219 |
220 |
221 | #### 🧡 REDO는 왜 필요할까?
222 |
223 | > commit한 트랜잭션의 수정은 어떤 경우에도 유지(durability)되어야 한다.
224 | >
225 | > 이미 commit한 트랜잭션의 수정을 재반영하는 복구 작업을 **REDO 복구**라고 함
226 | >
227 | > UNDO와 마찬가지로 Buffer 관리 정책에 영향을 받음
228 |
229 |
230 |
231 | - 트랜잭션이 종료되는 시점에 수정한 페이지들을 디스크에 쓰는 경우
232 |
233 | - FORCE
234 | - 수정했던 모든 페이지를 트랜잭션 커밋 시점에 디스크에 반영하는 정책
235 | - Transaction이 commit 되었을 때 수정된 페이지들이 disk 상에 반영되므로 redo 필요 없음
236 |
237 | - ¬FORCE
238 | - 수정했던 페이지를 트랜잭션 커밋 시점에 디스크에 반영하지 않는 정책
239 | - transaction이 disk 상의 db에 반영되지 않을 수 있기에 redo 복구가 필요
240 | - 대부분의 DBMS 정책
241 |
242 |
243 |
244 | ```요약
245 | 🗄정리
246 | DBMS는 버퍼 관리 정책으로 STEAL과 ¬FORCE 정책을 채택
247 | -> 이로 인해서 UNDO 복구와 REDO 복구가 모두 필요
248 | ```
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 | 출처
259 |
260 | https://d2.naver.com/helloworld/407507
261 |
262 | https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Database/Transaction.md
263 |
264 | https://github.com/NKLCWDT/cs/blob/main/Database/Transaction.md
265 |
266 | https://code-lab1.tistory.com/51
267 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/PCB와 Context Switching(문맥교환).md:
--------------------------------------------------------------------------------
1 | // 20220907
2 |
3 | // Brown
4 |
5 | # 🔸 Process Management
6 |
7 | CPU가 프로세스가 어러개일 때, CPU 스케쥴링을 통해 관리하는 것을 말한다.
8 |
9 | [process management 단계별로 살펴보기](https://velog.io/@hyehello/CS-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-OS-04.-Process-Management)
10 |
11 |
12 | # 🟠 PCB (Process Control Block) 이란?
13 |
14 | - 운영체제가 프로세스를 제어하기 위해 정보를 저장해 놓는 곳으로, 프로세스의 상태 정보를 저장하기 위한 구조체이다.
15 | - 프로세스 상태 관리와 Context Switching을 위해 필요하다.
16 | - PCB는 프로세스 생성 시 만들어지며 주기억장치에 유지된다.
17 | - CPU에 급한 프로세스 처리 때문에 긴급 요청이 왔을 때, 기존에 작업하던 프로세스를 어딘가에 임시저장해놓아야 급한 애를 빨리 처리한 후에 다시 불러올 수 있을 것이다. 즉, 프로세스에 관한 정보들을 어딘가에 놓을 공간이 필요하고, 이 공간이 PCB 이다.
18 |
19 | ```
20 | PCB란 운영체제가 프로세스에 대한 중요한 정보를 저장해 놓을 수 있는 저장 장소
21 | ```
22 |
23 | 
24 |
25 | ```
26 | 프로그램 실행 → 프로세스 생성 → 프로세스 주소 공간에 (코드, 데이터, 스택) 생성 → 이 프로세스의 메타데이터들이 PCB에 저장
27 | ```
28 |
29 | ## 🔸PCB 안에 들어있는 정보, Process Metadata
30 |
31 | 프로세스들의 특징을 갖고 있는 것을 Process Metadata 라고 한다 .
32 |
33 | 
34 |
35 | - Process ID: 프로세스를 구분하는 ID
36 | - PID라고도 부르기도하고, 프로세스의 고유 번호이다.
37 | - Process State: 각 프로세스들의 상태를 저장한다
38 | - 준비, 대기, 실행 등의 상태
39 | - Program Counter: 다음 Instruction의 주소를 저장하는 카운터. CPU는 이 값을 통해 Process의 Instruction을 수행한다.
40 | - 컴퓨터에서 말하는 Instruction는 컴퓨터에게 일을 시키는 단위로, 컴퓨터가 알아들을 수 있는 기계어로 이루어진 명령이다.
41 | - 하드웨어에서 사용하는 명령어이다. (사용자가 수행하는명령은 command, 소프트웨어적인 명령은 statement)
42 | - Register: Accumulator, CPU Register, General Register 등을 포함한다.
43 | - CPU Scheduling Information: 우선순위, 최종 실행 시간, CPU 점유 시간 등이 포함된다.
44 | - Memory Information: 해당 프로세스 주소 공간 (lower bound~upper bound) 정보를 저장한다.
45 | - Process Information: 페이지 테이블, 스케쥴링 큐 포인터, 소유자, 부모 등
46 | - Device I/O Status: 프로세스에 할당된 입출력 장치 목록, 열린 팔린 목록 등
47 | - Pointer: 부모/자식 프로세스에 대한 포인터, 자원에 대한 포인터 등
48 | - Open File List: 프로세스를 위해 열려있는 파일의 리스트
49 |
50 |
51 | 위의 PCB정보가 아래 테이블처럼 저장된다!!
52 |
53 | 
54 |
55 |
56 | ## 🔸 PCB 관리 방법
57 | - Linked List 방식으로 관리한다.
58 | - PCB List Head에 PCB가 생성될 때마다 하나씩 데이터가 붙게 된다. 주소 값으로 연결이 이루어져있는 연결리스트이기 때문에 삽입과 삭제가 용이하다.
59 |
60 | ```
61 | 즉, 프로세스가 생성되면 해당 PCB가 생성되고, 프로세스 완료 시 제거된다. 이렇게 수행중인 프로세스를 변경할 때 CPU의 레지스터 정보가 변경되는 것을 Context Switching 이라고 한다.
62 | ```
63 |
64 | ```
65 | < 프로세스 생성 과정 >
66 | 1. 새로운 프로세스를 위한 프로세스 식별자를 할당한다.
67 | 2. 새로운 프로세스에 한 주소 공간과 프로세스 제어블록(PCB)를 할당한다.
68 | 3. 새로운 프로세스의 프로세서 제어 블록을 초기화한다. (상태정보, 카운터, 우선순위 등)
69 | 4. 새로운 프로세스를 스케줄링 큐의 준비/보류 리스트에 연결한다.
70 | ```
71 |
72 | # 🟠 Context Switching
73 |
74 | ## 🔸 Context Switching 이란?
75 |
76 | ```
77 | 멀티프로세스 환경에서 CPU가 어떤 하나의 프로세스를 실행하고 있는 상태에서 인터럽트 요청에 의해 다음 우선 순위의 프로세스가 실행되어야할 때 기존의 프로세스 상태 또는 레지스터값 (Context)를 저장하고 CPU가 다음 프로세스를 수행하도록 새로운 프로세스의 상태 또는 레지스터값(Context)으로 교체하는 작업
78 | ```
79 |
80 | - 인터럽트 (Interrupt) : CPU가 프로그램을 실행하고 있을 때 실행중인 프로그램 밖에서 예외 상황이 발생하여 처리가 필요한 경우 CPU에게 알려 예외 상황을 처리할 수 있도록 하는 것을 말한다. (I/O request, CPU 사용 시간이 만료됐을때, 자식 프로세스를 만들 때 등과 같은 상황이 인터럽트 요청이다)
81 |
82 | (쉬운말로 프로세스가 하던 일을 멈추고 이미 정해진 코드에서 요청에 대한 처리를 수행한다.)
83 |
84 | ### 📝 Context(레지스터 값)이란?
85 | 사용자와 다른 사용자, 사용자와 시스템 또는 디바이스간의 상호작용에 영향을 미치는 사람, 장소, 개체 등의 현재 상황(상태)를 규정하는 정보들을 말한다. 즉 여기서 나온 Context의 의미는 CPU가 해당 프로세스를 실행하기 위한 해당 프로세스의 정보들이다. (이 정보들은 위에 나온 PCB에 저장된다, 즉 PCB에 저장되는 정보들이 Context = 레지스터값!)
86 |
87 | ### ⚠️ 주의
88 |
89 | 참고로 Context Switching이 발생할 때, 해당 CPU는 아무런 일을 하지 못한다. 따라서 Context Switching이 잦아지면 오히려 오버헤드가 발생해서 효율(성능)이 떨어진다.
90 |
91 | ## 🔸 Context Switching 은 어떻게 진행되는가?
92 | - Task의 대부분 정보는 Register에 저장되고 PCB로 관리되고 있다.
93 | - 현재 실행하고 있는 Task의 PCB정보를 저장하게 된다. (Process Stack, Ready Queue)
94 | - 다음 실행할 Task의 PCB 정보를 읽어 Register에 적재하고 CPU가 이전에 진행했던 과정을 연속적으로 수행할 수 있다.
95 |
96 |
97 | ## 🔸 Context Switching 과정
98 |
99 | - 인터럽트 시스템콜이 발생하면 p0에서 해당 데이터를 저장하고
100 | - p1 실행하기 위해서 p1의 정보들을 가지고옴
101 | - 그리고 p1이 실행되고, 다시 p0로 돌아가려면
102 | - 다시 진행
103 |
104 | 
105 |
106 |
107 | ## 🔸 Context switching의 오버헤드
108 |
109 | 
110 |
111 | - idle : 아무것도 동작하지 않는 상태를 의미
112 |
113 | ```
114 | 이렇게 Idle가 겹치는 시기들을 오버헤드라고 한다. 이때 CPU가 메모리에 적재하는 중이라 아무것도 하지 않는 상태이다. Thread가 많아지면 Context swtiching이 많아져서 오버헤드가 점점 증가해서 성능에 영향을 미친다.
115 | ```
116 |
117 | ## 🔸 Context Switching swift에서는 어떻게 사용되나?
118 |
119 | ```swift
120 | Task.yield()
121 | ```
122 |
123 | 이 키워드를 찾아보면 될것 같다. 공식 문서에서는 아래와 같이 설명했다.
124 |
125 | ```
126 | 현재 작업을 일시 중단하고 다른 작업을 실행할 수 있도록 하는 것
127 | ```
128 | [yield() 애플 공식 문서](https://developer.apple.com/documentation/swift/task/yield())
129 |
130 |
131 |
132 | # ✅ 면접에서 나왔던 질문 [출처](https://nesoy.github.io/articles/2018-11/Context-Switching)
133 |
134 | - Computer 가 매번 하나의 Task만 처리할 수 있다면?
135 | - 하나의 Task가 끝날 때 까지 다음 Task는 기다릴수밖에 없고, 동시에 작업할 수 없는 환경이 만들어지게 되면서 반응속도가 매우 느릴 것입니다.
136 |
137 | - 그렇다면 다양한 사람들이 동시에 사용하는 것처럼 하기 위해선 어떻게 해야할까?
138 | - computer 멀티태스킹을 통해 빠른 반응속도로 응답할 수 있습니다.
139 | - 빠른속도로 Task 를 바꿔가며 실행하기 때문에 사람의 눈으로 봣을때는 동시에 진행되는 것처럼하는 장점이 있습니다.
140 | - CPU 가 Task를 빠르게 바꿔가며 실행하기 위해서 Context Switchng이 필요하게 되었습니다.
141 |
142 | - Context Switching이란 무엇입니까?
143 | - CPU가 어느 프로세스를 실행하고 있을때, 인터럽트 요청이 있을 경우 기존의 프로세스의 상태를 PCB에 저장하고, 새로운 프로세스를 수행하도록 프로세스를 교체하는 작업을 의미합니다.
144 |
145 | - 왜 Context Switching이 필요한가?
146 | - Context Switching이 있기 때문에, 동시에 여러개의 프로세스가 동작하는 것처럼 프로세스를 실행시킬 수 있습니다. 하지만 사실은 context switching이 일어날 때는 CPU의 동작이 멈추는 '오버헤드'가 발생하여 성능저하의 원인이 되기도 합니다. 그렇기 때문에 CPU 스케줄링 알고리즘에서도 특별히 신경써서 고려해야하는 점이기 때문에 중요합니다!
147 |
148 | - Context Switching 은 어떻게 진행되나요?
149 | - 멀티쓰레드로 작업중인 환경에서, 기존 프로세스를 실행하고 있는 도중 인터럽트 요청이 있는 경우 기존 테스크를 PCB에 저장합니다. 그리고 새로운 프로세스로부터 정보를 reload 하여 실행을 진행합니다. 이렇게 Context switching 하는 과정에서는 CPU는 동작을 멈추게 됩니다. 새로운 프로세스의 테스크를 끝내면 PCB에 저장하고, 기존의 프로세스 태스크를 다시 reload하여 태스크를 진행합니다.
150 |
151 |
152 | ## 📖 References
153 |
154 | - [command, instruction, statement 차이점](https://foxtrotin.tistory.com/295)
155 | - [운영체제-PCB란?](https://dev-mystory.tistory.com/119)
156 | - [PCB](https://velog.io/@hoyun7443/PCB)
157 | - [context switching이란?](https://nesoy.github.io/articles/2018-11/Context-Switching)
158 | - [10분 테코톡 interrupt와 context switching](https://www.youtube.com/watch?v=-4HKhwlH3FQ)
159 |
160 |
--------------------------------------------------------------------------------
/Computer Science/Network/Load Balancing.md:
--------------------------------------------------------------------------------
1 | //220830 Noel
2 |
3 |
4 |
5 |
6 |
7 | # ❤️ 로드 밸런싱(Load Balancing)
8 |
9 | > 둘 이상의 CPU or 저장장치와 같은 컴퓨터 자원들에게 작업을 나누는 것
10 |
11 |
12 |
13 | #### 🧡 로드 밸런싱의 필요성
14 |
15 | - 현대의 모든 정보는 인터넷을 통해 연결되어있음
16 | - 인터넷의 발달은 데이터 통신을 활발하게 많음 -> **트래픽의 폭팔적인 증가**로 이어짐
17 | - 그 결과 아무리 성능이 뛰어난 서버라고해도 모든 트래픽을 감당할 수 없음
18 | - 따라서 기업들은 **여러대의 서버에 동일한 데이터를 저장해 수많은 트래픽을 효과적으로 분산**
19 | - 이떄 **쏟아지는 트래픽을 여러 대의 서버로 분산해 주는것이 로드 밸런싱!
**
20 |
21 | ``` 참고
22 | 💡이해를 위한 용어 설명
23 |
24 | 트래픽이란?
25 | - 서버와 스위치 등의 네트워크 장치에서 일정시간 흐르는 데이터 양
26 | - 웹사이트에 트래픽이 많다는것은 사용자 접속이 많아 전송하는 데이터 양이 많다는 의미
27 | - 트래픽이 너무 많으면 서버에 과부하가 걸려 기능에 문제가 생실 수 있음
28 | - 예) 홈페이지를 인터넷 브라우저에 띄우기 위해
29 | -> 서버에 파일을 올려놓고 사용자가 웹페이지에 접속 할때마다 필요한 정보를 다운로드 해야하는데
30 | -> 여기서 다운로드 되는 정보의 양이 바로 트래픽!
31 | -> 홈페이지에서 여러페이지를 보거나 이미지, 동영상을 내 컴으로 받을때 홈페이지와 연결된 트래픽의 양이 증가함
32 | ```
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | #### 🧡 증가한 트래픽에 대처하는 방법
41 |
42 |
43 |
44 | **Scale-up
**
45 |
46 | - **서버 자체의 성능을 올리는 것**
47 | - 비유하자면 CPU가 i3인 컴퓨터를 i7으로 **업그레이드**하는 것과 비슷
48 |
49 |
50 |
51 | **Scale-out
**
52 |
53 | - 기존 서버와 동일하거나 낮은 성능의 서버를 **두 대 이상 증설하여 운영하는 것**
54 | - CPU가 i3인 컴퓨터를 **여러 대 추가 구입해 운영**하 것과 비슷
55 | - **Scale-out**의 방식으로 서버를 증설한다면, 여러 대의 서버로 트래픽을 균등하게 분산해주는 **로드밸런싱**이 반드시 필요
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | #### 🧡로드 밸런싱 이란?
64 |
65 |
66 |
67 | - 로드 밸런싱은 **여러 대의 서버를 두고 서비스를 제공하는 분산처리 시스템에서 필요한 기술**
68 | - 분산식 웹 서비스로, **여러 서버에 부하(Load)를 나누어주는 역할**
69 | - 로드밸런서(Load Balancer)를 **Client와 Server Pool 사이에 위치에 두고, 부하기 일어나지 않도록 트래픽을 여러 서버에 분산**
70 | - 서비스를 운영하는 사이트의 규모에 따라 웹 서버를 추가로 증설하면서 로드 밸런서로 관리해주면 웹 서버의 부하를 해결할 수 있다.
71 |
72 | ```참고
73 | 💡이해를 위한 용어 설명
74 |
75 | 로드 벨런서 (Load Balancer)
76 | - 서버에 가해지는 부하(=load)를 분산(=balancing)해주는 장치 또는 기술을 통칭
77 |
78 | 서버 풀 (Sever Pool)
79 | - 분산 네트워크를 구성하는 서버들의 그룹
80 | ```
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | #### 🧡 다양한 부하 분산 방식(로드밸런싱 알고리즘)
89 |
90 | - 클라이언트의 요청을 특정 서버에 분배하는 로드밸런싱 기법은 여러 가지가 있음
91 | - 활용할 수 있는 부하 분산 방식(로드밸런싱 알고리즘)에 어떠한 것들이 있는지 알아보겠습니다.
92 |
93 | | 구분 | 내용 |
94 | | ---------------------------------------------------------- | ------------------------------------------------------------ |
95 | | **라운드로빈 방식
(Round Robin Method)** | - 서버에 들어온 요청을 순서대로 돌아가며 배정하는 방식
- 클라이언트의 요청을 순서대로 분배하기 때문에 여러 대의 서버가 동일한 스펙을 갖고 있고, 서버와의 연결(세션)이 오래 지속되지 않는 경우에 활용하기 적합 |
96 | | **가중 라운드로빈 방식
(Weighted Round Robin Method)** | - 각각의 서버마다 가중치를 매기고 가중치가 높은 서버에 클라이언트 요청을 우선적으로 배분
- 주로 서버의 트래픽 처리 능력이 상이한 경우 사용되는 부하 분산 방식.
- 예) A 서버 (가중치:5) / B 서버가 (가중치:2) 일 때,
> 로드밸런서는 라운드로빈 방식으로 A 서버에 5개 B 서버에 2개의 요청을 전달 |
97 | | **IP 해시 방식
(IP Hash Method)** | - 클라이언트의 IP 주소를 특정 서버로 매핑하여 요청을 처리하는 방식,
- 사용자의 IP를 해싱해 Load를 분배하기 때문에 사용자가 항상 동일한 서버로 연결되는 것을 보장
*해싱(Hashing) : 임의의 길이를 지닌 데이터를 고정된 길이의 데이터로 매핑하는 것, 또는 그러한 함수 |
98 | | **최소 연결 방식
(Least Connection Method)** | - 요청이 들어온 시점에 가장 적은 연결상태를 보이는 서버에 우선적으로 트래픽을 배분
-자주 세션이 길어지거나, 서버에 분배된 트래픽들이 일정하지 않은 경우에 적합한 방식 |
99 | | **최소 리스폰타임
(Least Response Time Method)** | - 서버의 현재 연결 상태와 응답시간을 모두 고려하여 트래픽을 배분
- 가장 적은 연결 상태와 가장 짧은 응답시간을 보이는 서버에 우선적으로 Load를 배분하는 방식
*응답시간 (Response Time) : 서버에 요청을 보내고 최초 응답을 받을 때까지 소요되는 시간 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | #### 🧡 L4 로드밸런싱과 L7 로드밸런싱
108 |
109 | - 부하 분산에는 **L4 로드밸런서와 L7 로드밸런서가 가장 많이 활용**
110 | - L4 로드밸런서부터 **포트(Port)정보를 바탕으로 로드를 분산하는 것이 가능**하기 때문
111 | - **한 대의 서버에 각기 다른 포트 번호를 부여하여 다수의 서버 프로그램을 운영하는 경우라면 최소 L4 로드밸런서 이상을 사용**
112 |
113 | ```참고
114 | 💡이해를 위한 용어 설명
115 |
116 | L4? L7?
117 | - 네트워크 통신 시스템은 크게 일곱 가지의 계층(OSI 7 layers)로 나뉨
118 | - 각각의 계층(Layer)이 L1/L2/L3‥‥L7에 해당
119 | - 상위 계층에서 사용되는 장비는 하위 계층의 장비가 갖고 있는 기능을 모두 가지고 있으며, 상위 계층으로 갈수록 더욱 정교한 로드밸런싱이 가능
120 | ```
121 |
122 |
123 |
124 | ##### 💚 L4 로드밸런싱
125 |
126 |
127 |
128 | - L4 로드밸런서는 네트워크 계층(IP, IPX)이나 트랜스포트 계층(TCP, UDP)의 정보를 바탕으로 로드를 분산
129 | - IP주소나 포트번호, MAC주소, 전송 프로토콜에 따라 트래픽을 나누는 것이 가능
130 |
131 |
132 |
133 | ##### 💚 L7 로드밸런싱
134 |
135 |
136 |
137 | - L7 로드밸런서의 경우 애플리케이션 계층(HTTP, FTP, SMTP)에서 로드를 분산하기 때문에 HTTP 헤더, 쿠키 등과 같은 **사용자의 요청을 기준으로 특정 서버에 트래픽을 분산**하는 것이 가능
138 | - 쉽게 말해 **패킷의 내용을 확인하고 그 내용에 따라 로드를 특정 서버에 분배**하는 것이 가능
139 | - 위 그림과 같이 URL에 따라 부하를 분산시키거나, HTTP 헤더의 쿠키값에 따라 부하를 분산하는 등 **클라이언트의 요청을 보다 세분화해 서버에 전달 가능**
140 | - 또한 L7 로드밸런서의 경우 **특정한 패턴을 지닌 바이러스를 감지해 네트워크를 보호**할 수 있으며, **DoS/DDoS와 같은 비정상적인 트래픽을 필터링할 수 있어 네트워크 보안 분야에서도 활용**
141 |
142 |
143 |
144 | ##### L4 로드밸런서와 L7 로드밸런서 비교
145 |
146 | | | L4 로드밸런서 | L7 로드밸런서 |
147 | | ------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
148 | | 네트워크 계층 | 4계층 전송 계층
(Transport Layer) | 7계층 응용 계층
(Application Layer) |
149 | | 특징 | TCP/UDP 포트정보를 바탕으로 함 | TCP/UDP 포트정보는
물론 HTTP의 URL,
FTP의 파일명,
쿠키정보 등을 바탕으로 함 |
150 | | 장점 | - 데이터 안을 들여다보지 않고 패킷 레벨에서만 로드를 분산하기 때문에 속도가 빠르고 효율이 높음
-데이터의 내용을 복호화할 필요가 없기 떄문에 안전함
* 복호화(decryption) : 부호화(암호문)된 데이터를 부호되기 전 형태로 바꿔 사람이 읽을 수 있는 형태로 되돌리는 것 | - 상위계층에서 로드를 분사한기떄문에 더 섬세한 라우팅이 가능
-캐싱 기능을 제공
-비정상적인 트래픽을 사전에 필터링할 수 있어 서비스 안전성이 높음 |
151 | | 단점 | - 패킷의 내용을 살펴 볼 수 없기 때문에 섬세한 라우팅이 불가능
-사용자의 IP가 수시로 바뀌는 경우라면 연속적인 서비스를 제공하기 어려움 | -페킷의 내용을 복호화 해야하기에 더 높은 비용을 지불해야함
-클라이언트가 로드밸런서와 인증서를 공유해야하기 떄문에 공격자가 로드밸런서를 통해 클라이언트에 데이터에 접근할 보안 상의 위험성이 존잽 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 | 출처
160 |
161 | https://m.post.naver.com/viewer/postView.naver?volumeNo=27046347&memberNo=2521903
162 |
163 | https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Network/%EB%A1%9C%EB%93%9C%20%EB%B0%B8%EB%9F%B0%EC%8B%B1(Load%20Balancing).md
164 |
165 |
--------------------------------------------------------------------------------
/Design Pattern/Strategy Pattern.md:
--------------------------------------------------------------------------------
1 | // 2022.09.27 Noel🎸
2 |
3 |
4 |
5 | # ❤️🔥 스트레티지 패턴(Strategy Pattern)
6 |
7 |
8 |
9 | ### 🤔 전략 패턴(Strategy Pattern)이란?
10 |
11 | > 전략 패턴은 **알고리즘의 집합(Algorithm Family)**을 사용하는 **행위 패턴
**
12 |
13 | - 여러 알고리즘을 각각 객체로 **캡슐화**하고, 동일한 목적을 하는 알고리즘을 하나의 인터페이스로 묶음
14 |
15 | - 그럼 이 알고리즘들이 클라이언트 객체에서 교체되면서 사용 할 수 있음
16 |
17 | - 따라서 알고리즘이 클라이언트 객체에 독립적으로 구성되기 때문에 **느슨한 연결(Decoupling)**이 됨
18 |
19 | - 느슨하게 연결되면 클라이언트 객체가 알고리즘이 변할때 영향을 받지 않는 것을 의미!
20 |
21 | ```
22 | 예) 알고리즘 수정이 필요한 상황에서
23 | - 캡슐화된 해당 알고리즘만 수정하면 되고 내부적으로 어떻게 수정되고 어떻게 구현되었는지 클라이언트 객체는 알지못함
24 | ```
25 |
26 |
27 |
28 |
29 |
30 | ### 전략 패턴 구조
31 |
32 |
33 |
34 | 🔵 **Context (Composition)**
35 |
36 | - `Concrete Strategy` 객체로 구성
37 | - `Strategy` 객체에 대한 참조를 유지
38 | - `Strategy`가 데이터에 접근 할 수 있는 인터페이스를 정의
39 |
40 |
41 |
42 | 🔴 **Strategy (Compositor)**
43 |
44 | - 지원되는 모든 알고리즘에 사용되는 공통적인 인터페이스를 정의
45 | - `Context`는 `Strategy` 인터페이스를 사용하여 `Concrete Strategy`에 정의된 알고리즘을 호출
46 |
47 |
48 |
49 | **🔴 Concrete Strategy**
50 |
51 | - `Strategy` 인터페이스를 사용하여 알고리즘을 구현
52 |
53 |
54 |
55 |
56 |
57 | ### 전략 패턴은 언제 사용할까?
58 |
59 | 전략패턴은 **어떤 상황에서 사용할 알고리즘이 여러 개 존재할 때** 사용하면 좋음
60 |
61 | - 알고리즘을 런타임에서 바꿀 수 있기 때문에 이런 상황에서 효과적으로 대응할 수 있음
62 |
63 | ```예시
64 | 예시 상황
65 |
66 | 자동차의 경로만 알려주는 내비게이션 제작함
67 | > 그러다 사용자가 늘어 [도보로 이동하는 사람의 경로], [대중교통을 이동하는 사람의 경로]와 같이 다양한 알고리즘이 필요해짐
68 | > 이때❗️ 클래스 안에 계속해서 구현하다 보면, 하나의 변경으로 인해 많은 곳을 수정해야 하는 문제가 발생합
69 |
70 | 이를 해결하기 위해 전략 패턴을 사용
71 | > [자동차의 경로], [도보로 이동하는 경로], [대중교통 경로]에 대한 알고리즘을 따로 구현하고 이들을 캡슐화
72 | > 각각의 알고리즘을 서로에게 영향을 주지도 않고 각자 독립적으로 작동하도록 만들어줌으로써 위의 문제 해결가능!
73 |
74 | 출처: https://icksw.tistory.com/259 [PinguiOS:티스토리]
75 | ```
76 |
77 |
78 |
79 |
80 |
81 | ### 장단점
82 |
83 | 👍**장점**
84 |
85 | - 런타임에서 객체 내부에서 사용되는 알고리즘을 변경할 수 있음
86 | - `알고리즘을 사용하는 코드`와 `알고리즘을 구현하는 코드`를 분리 할 수 있음
87 | - `Open / Closed Principle`(개방 폐쇄 원칙)을 준수
88 | - `Context`를 변경하지 않고도 새로운 `Strategy`를 추가할 수 있음
89 |
90 |
91 |
92 | 👎**단점**
93 |
94 | - 알고리즘이 몇 개 없고 변경되는 일도 거의 없는 경우, 전략 패턴의 도입이 오히려 복잡성을 증가
95 | - 클라이언트가 적절한 `Strategy`를 선택하기 위해서는 각각의 차이점을 알고 있어야 합니다.
96 | - `Strategy`, `Context` 간 통신 오버헤드가 발생
97 |
98 |
99 |
100 | ## 🕊 Swift 예제!
101 |
102 | 그럼 Swift로 한번 만들어 볼까요?
103 |
104 | 예제는 개발하는 훈이님 블로그 기반으로 작성되었습니다!
(원문 : https://jeonyeohun.tistory.com/379)
105 |
106 |
107 |
108 |
109 |
110 | 어떤 문자열이 들어왔을때 조건을 검사해주는 `Validator` 객체가 있음
111 |
112 | 지금은 별 문제 없지만 나중에 추가적 요구사항이 생겨 요 객체에 알고리즘을 추가하게 되면
113 |
114 | 기존 객체에 변경사항이 생기기 때문에 `개방페쇄원칙(OCP)`에 어긋남!
115 |
116 |
117 |
118 | ### ‼️ 따라서 전략패턴을 사용해야함!
119 |
120 |
121 | 전략패턴은 클라이언트 객체는 `Strategy(알고리즘 집합의 인터페이스)`를 가지고 필요에 따라 주입할 수 있음
122 |
123 | 또 새로운 요구사항인 아스키 코드를 검사하는 알고리즘을 `Strategy`에 추가함에 따라 `개방페쇄원칙(OCP)`을 지킬 수 있음
124 |
125 |
126 |
127 | #### 그럼 이제 Swift 코드로 구현해보자!
128 |
129 | 위의 예시 상황을 토대로 코드로 작성
130 |
131 |
132 |
133 | #### ① `Context` `Strategy`가 될 프로토콜 정의
134 |
135 | ```swift
136 | //Strategy = 알고리즘의 인터페이스가 될 프로토콜
137 | protocol Validatable {
138 | func validate(text: String) -> Bool
139 | // validate() : 인자로 문자열을 받으면 적절한 알고리즘 수행뒤에 Bool타입 반환
140 | // 전략에 맞는 알고리즘들은 이 프로토콜을 채택해 validate를 구현하면 됨
141 | }
142 |
143 | //Context = 클라이언트 객체 내부의 인터페이스를 제공할 프로토콜
144 | protocol Validator {
145 | var validationStrategy: Validatable { get set }
146 | //검증에 사용할 알고리즘의 인터페이스를 가지게됨
147 | func validate(text: String) -> Bool
148 | // 실제로 사용자가 호출하고 결과를 반환하게될 메소드
149 | }
150 | ```
151 |
152 |
153 |
154 | #### ② Context (클라이언트 객체) 정의
155 |
156 | - `StringValidator`의 `validate` 메서드
157 | - 알고리즘 없음
158 | - 대신 `Strategy(validationStrategy)`이 가진 알고리즘을 실행해 그 결과를 반환
159 | - 즉! 이것이 **알고리즘의 구현과 알고리즘을 사용하는 객체가 완전히 분리**된 것!!
160 |
161 | ```swift
162 | // Context (클라이언트 객체) 정의
163 | final class StringValidator: Validator {
164 | var validationStrategy: Validatable
165 |
166 | init(strategy: Validatable) {
167 | self.validationStrategy = strategy
168 | }
169 |
170 | func change(strategy: Validatable) {
171 | self.validationStrategy = strategy
172 | }
173 | // change 메서드를 통해 현재 알고리즘을 다른 알고리즘으로 변경 가능
174 |
175 | func validate(text: String) -> Bool {
176 | return validationStrategy.validate(text: text)
177 | }
178 | //검증 알고리즘을 수행
179 | }
180 | ```
181 |
182 |
183 |
184 | #### ③ Concrete Strategy (알고리즘) 구현!
185 |
186 | - `Strategy`을 채택하는 두개의 알고리즘 제작!
187 |
188 | ```swift
189 | // 문자열이 숫자인지 확인하는 알고리즘
190 | class NumberValidator: Validatable {
191 | func validate(text: String) -> Bool {
192 | return text.allSatisfy({ $0.isNumber })
193 | }
194 | }
195 |
196 | // 문자열의 길이가 10 미만인지 확인하는 알고리즘
197 | class LengthValidator: Validatable {
198 | func validate(text: String) -> Bool {
199 | return text.count < 10
200 | }
201 | }
202 | ```
203 |
204 |
205 |
206 | #### ④ Context (클라이언트 객체) 사용 및 변경
207 |
208 | - 클라이언트 객체 사용 시 : 생성자를 통해 사용할 알고리즘을 선택
209 | - 클라인언트에서 사용할 알고리즘 변경 : `change` 메서드를 통해
210 |
211 | ```swift
212 | // Context 에서 사용할 알고리즘 선택
213 | let validator = StringValidator(strategy: LengthValidator())
214 | print(validator.validate(text: "12345678910")) // false
215 |
216 | //Context 에서 사용할 알고리즘 변경
217 | validator.change(strategy: NumberValidator())
218 | print(validator.validate(text: "12345678910")) // true
219 | ```
220 |
221 |
222 |
223 | #### ➄ 새로운 Concrete Strategy (알고리즘) 추가
224 |
225 | ```swift
226 | // 새로운 알고리즘 추가 : 문자열이 아스키 코드로 표현가능한지 확인하는 알고리즘
227 | class AsciiValidator: Validatable {
228 | func validate(text: String) -> Bool {
229 | return text.allSatisfy({ $0.isASCII })
230 | }
231 | }
232 | ```
233 |
234 | ```swift
235 | // 클라이언트 객체에 적용
236 | validator.change(strategy: AsciiValidator())
237 | print(validator.validate(text: "12345678910")) // true
238 | ```
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 | 출처
247 |
248 | https://icksw.tistory.com/259
249 |
250 | https://jeonyeohun.tistory.com/379
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/SystemCall(시스템콜, 시스템호출).md:
--------------------------------------------------------------------------------
1 | // 20220907
2 |
3 | // Brown
4 |
5 | # 🟠 들어가며
6 | ## 📝 운영체제와 응용프로그램
7 | ```
8 | 운영체제(OS) : Window, DOS, UNIX, Linux, Mac OS 등
9 | 응용 프로그램 : 한글, 엑셀, 메모장 등 컴퓨터 내의 다양한 프로그램들
10 | ```
11 |
12 | - 운영체제 는 컴퓨터의 자원들을 효율적으로 관리하며 사용자가 컴퓨터를 편리하고 효과적으로 사용할 수 있도록 환경을 제공하는 여러 프로그램의 모임이라고 이해하면 된다. (추후 더 자세하게 다룬 포스팅을 올릴 예정이댜)
13 | - 운영 체제는 컴퓨터 사용자와 컴퓨터 하드웨어 간의 인터페이스로서 동작하는 시스템 소프트웨어의 일종으로, 다른 응용프로그램이 유용한 작업을 할 수 있도록 환경을 제공해 준다.
14 |
15 | 
16 |
17 |
18 | ## 📝 커널 (kernel)
19 |
20 | 컴퓨터와 전원을 켜면 운영체제는 이와 동시에 수행된다. 소프트웨어가 컴퓨터 시스템에서 수행되기 위해서는 메모리에 그 프로그램이 올라가 있어야 한다. 마찬가지로 운영체제 자체도 소프트웨어로서 전원이 켜짐과 동시에 메모리에 올라가야한다.
21 |
22 | 하지만 운영체제처럼 규모가 큰 프로그램이 모두 메모리에 올라가면 한정된 메모리 공간이 낭비가 심할 것이다.
23 |
24 | 따라서 운영체제 중 항상 필요한 부분만을 전원이 켜짐과 동시에 메모리에 올려놓고, 그렇지 않은 부분은 필요할 때 메모리에 올려서 사용하게 된다. 이때 메모리에 상주하는 운영체제의 부분을 kernel(커널)이라고 한다.
25 |
26 | ```
27 | 즉, 커널은 메모리에 상주하는 부분으로써 운영체제의 핵심적인 부분을 뜻한다.
28 | (그래서 보통은 '운영체제'라고 하면 kernel을 뜻하기도 한다)
29 | ```
30 |
31 | ## 📝 CPU 모드
32 |
33 | CPU는 사용자 애플리케이션 (User application)이 시스템을 손상시키는 것을 방지하기 위해 2가지 모드를 제공한다. CPU에 있는 Mode bit로 모드를 구분하여 0은 ```커널모드(kernel mode)```, 1은 ```사용자모드 (user mode)```로 나뉘어서 구동된다.
34 |
35 | 운영체제에서 프로그램이 구동되는데 있어서 파일을 읽어오거나, 파일을 쓰거나, 혹은 화면에 메세지를 출력하는 등 많은 부분이 커널 모드를 사용한다.
36 |
37 | ### 🔸 사용자 모드 (User Mode)
38 |
39 | - 사용자 모드에서 사용자 애플리케이션 코드가 실행된다.
40 | - 사용자가 접근할 수 있는 영역에 제한이 있기 때문에 해당 모드에서는 하드웨어(디스크, I/O 등)에 접근할 수 없다.
41 | (이전에 Blocking I/O를 배울 때 직접 하드웨어에 접근하지 못한다고 배웠다! 우후후)
42 | - 접근을 위해서는 '시스템 콜(System Call)'을 사용해야 한다. 사용자 애플리케이션의 각 스레드들은 고유의 사용자 모드 스택을 갖는다.(?)
43 |
44 | ### 🔸 커널 모드 (Kernel Mode)
45 |
46 | - 운영체제(OS)가 CPU를 사용하는 모드이다.
47 | - 시스템 콜을 통해 커널모드로 전환이 되면 운영체제는 하드웨어를 제어하는 명령어(Privileged Instructions)를 실행한다.
48 | - Privileged Instructions는 사용자 모드에서 실행되면 exception이 발생한다.
49 |
50 | 
51 |
52 | ```
53 | 위 그림과 같이 사용자 process는 User Mode에서 실행되다가 시스템 자원을 사용해야할 때 시스템 콜을 호출해서 커널 모드로 전환되어 작업을 수행하고 완료 시 다시 사용자 모드로 전환한다.
54 | ```
55 |
56 |
57 | # 🟠 시스템콜 (System Call, = 시스템 호출)
58 |
59 | 위에서 CPU 모드에 대해서 설명이 나올때 대충~! 시스템콜이 무슨 역할을 하는지 감이 왔을 것이다. 더 자세히 알아보자.
60 |
61 | OS는 다양한 서비스 들을 수행하기 위해 하드웨어를 직접적으로 관리한다. 이와 반면 응용 프로그램은 OS가 제공하는 인터페이스를 통해서만 자원을 사용할 수 있다. OS가 제공하는 이러한 인터페이스를 '시스템 콜 (system call)' 이라고 한다.
62 |
63 | 시스템콜은 이러한 커널 영역의 기능을 사용자 모드가 사용 가능하게, 즉, 프로세스가 하드웨어에 직접 접근해서 필요한 기능을 할 수 있게 해준다. (즉, 응용프로그램은 시스템 콜을 사용해서 원하는 기능을 수행할 수 있음.)
64 |
65 | 보통 직접적으로 시스템콜을 사용하기 보다는 API(라이브러리 함수)를 통해 사용하게 된다.
66 |
67 | 
68 |
69 | ```
70 | 위 그림처럼 운영체제(OS)는 메모리에 프로그램 적재, I/O처리, 파일시스템 처리 등 여러 서비스들을 제공하는데 사용자 프로세스는 이에 직접적인 접근이 아닌 시스템 콜 호출을 통해 서비스를 제공받을 수 있다.
71 | ```
72 |
73 | ## 🔸 시스템콜 종류
74 |
75 | 시스템콜은 크게 6가지로 분류할 수 있다.
76 |
77 | ### 1. 프로세스 제어 (Process Control)
78 | - 끝내기(exit), 중지 (abort)
79 | - 적재(load), 실행(execute)
80 | - 프로세스 생성(create process) - fork
81 | - 프로세스 속성 획득과 속성 설정
82 | - 시간 대기 (wait time)
83 | - 사건 대기 (wait event)
84 | - 사건을 알림 (signal event)
85 | - 메모리 할당 및 해제
86 | ### 2. 파일 조작 (File Manipulation)
87 | - 파일 생성 / 삭제 (create, delete)
88 | - 열기 / 닫기 / 읽기 / 쓰기 (open, close, read, wirte)
89 | - 위치 변경 (reposition)
90 | - 파일 속성 획득 및 설정 (get file attribute, set file attribute)
91 | ### 3. 장치 관리 (Device Manipulation)
92 | - 하드웨어의 제어와 상태 정보를 얻음 (ioctl)
93 | - 장치를 요구(request device), 장치를 방출 (relese device)
94 | - 읽기 (read), 쓰기(write), 위치 변경
95 | - 장치 속성 획득 및 설정
96 | - 장치의 논리적 부착 및 분리
97 | ### 4. 정보 유지 (Information Maintenance)
98 | - getpid(), alarm(), sleep()
99 | - 시간과 날짜의 설정과 획득 (time)
100 | - 시스템 데이터의 설정과 획득 (date)
101 | - 프로세스 파일, 장치 속성의 획득 및 설정
102 | ### 5. 통신 (Communication)
103 | - pipe(), shm_open(), mmap()
104 | - 통신 연결의 생성, 제거
105 | - 메시지의 송신, 수신
106 | - 상태 정보 전달
107 | - 원격 장치의 부착 및 분리
108 | ### 6. 보호 (Protection)
109 | - chmod()
110 | - umask()
111 | - chown()
112 |
113 |
114 | 위에서 나온 명령어들은,,, UNIX에서 사용하는 명령어이다... (시스템콜은 스위프트에서는 어떻게 사용될까?)
115 |
116 | 
117 |
118 | # 🟠 Swift에서의 시스템 콜
119 |
120 | ### 📝 그전에, 시스템콜을 API(라이브러리 함수)로 접근한다는 게 무슨 뜻일까?
121 |
122 | OS는 다양한 서비스들을 수행하기 위해 하드웨어를 직접적으로 관리한다. 이와 반면에 응용프로그램은 OS가 제공하는 인터페이스를 통해서만 자원을 사용할수 있다고 했다. 그래서 시스템콜이라는 개념이 나왔다고 까지 배웠다.
123 |
124 | 이러한 시스템 콜은 직접 사용하게 많은 어려움이 있다고 한다. (왜?) 때문에 프로그래밍 언어들은 시스템콜을 편리하게 사용하기 위한 수단으로 API를 제공한다.
125 |
126 | 
127 |
128 | ### 📝 대부분 C언어와 관련있는 설명이던데, C언어를 사용한 간단한 프로그램을 예시로 시스템콜을 우선적으로 이해해보자.
129 |
130 | ```C++
131 | #include
132 | int main()
133 | {
134 | ...
135 | printf("Hello World!");
136 | ...
137 | return 0;
138 | }
139 | ```
140 |
141 | - printf() 함수는 user mode에서 수행되어 stdio 라이브러리를 호출한다.
142 | - stdio 라이브러리는 시스템콜인 write()를 호출하고, 실행의 흐름은 kernel mode 로 바뀐다.
143 | - 커널은 호출을 실행하여 모니터에 문자열을 출력하고 실행의 흐름은 다시 user mode 로 넘어와 printf()의 함수의 다음단계를 진행한다.
144 |
145 | 
146 |
147 | ### 📝 C언어에서의 시스템 콜 (그냥 알아만 두기..)
148 |
149 | C언어에서 제공하고 있는 표준함수는 POSIX(Portable Operating System Interface)의 규정에 따라 함수를 제공하고 있으며, OS개발사 또는 컴파일러 개발사에서 추가적인 확장 API들을 제공하는 것이 일반적이다.
150 |
151 | C언어를 활용하여 개발하는 개발자 입장에서는 시스템콜 함수이든, 라이브러리 콜 함수이든 단지 함수의 형태이므로 특별히 구별되지는 않을 것이다. 그러나 system call function이 자주 호출되면 시스템 성능에 영향을 주기 때문에 최대한 알고쓰고 자제해야한다.
152 |
153 | system call function 과 library call function의 차이점은 아래 게시글에서 추가로 확인해보자. (C언어에 집중된 설명이므로, 나는 간략하게 훑고 넘어갔다) [👉 시스템콜과 라이브러리콜 함수의 차이 보러가기](https://www.it-note.kr/3)
154 |
155 |
156 | ## 💡 아니 그럼 swift에서도 따로 system call 함수가 있는걸까?
157 |
158 | 과연 이게 Swift에서는 어떻게 사용되고 어떻게 쓰이는 것일까.
159 |
160 | 단순하게 생각해보자. 우리가 사용하는 Xcode도 응용프로그램이다. Xcode내부에서도 시스템콜을 통해서 파일을 가져오고 print를 하고 하지 않을까?
161 |
162 | [스위프트 system 오픈소스 공개](https://www.swift.org/blog/swift-system/)
163 |
164 | 2020년쯤 스위프트에서도 시스템 콜과 관련한 함수들을 전부 오픈소스화 해놓았다고 말했다고 한다.
165 | 즉, 원래는 C 인터페이스에 의존하여 시스템콜 함수를 호출했었는데 이 이후로부터 스위프트 독자적인 함수를 사용할 수 있게 했나보다...!
166 |
167 | (근데 왜 예시를 찾질 못하니,,)
168 |
169 | 일단 스위프트에서 어떤 방식으로 사용하는지에 대해서 전혀 찾지 못해서 여기까지만 조사했다.
170 |
171 | ## 📖 Reference
172 | - [운영체제와 커널이란?](https://goodmilktea.tistory.com/23)
173 | - [운영체제와 응요프로그램이란?](https://m.blog.naver.com/zerozero/60000338473)
174 | - [운영체제 서비스와 시스템 콜](https://cloudstudying.kr/lectures/189)
175 | - [시스템 콜](https://codybuilder.com/41)
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
--------------------------------------------------------------------------------
/Design Pattern/templateMethod.md:
--------------------------------------------------------------------------------
1 | # 🔗 Template Method
2 | ## Template Method란?
3 | #### Template Method(템플릿 메서드)는 부모 클래스에서 여러 메서드로 이루어진 알고리즘의 틀을 정의합니다. 이러한 알고리즘 틀을 Template Method라고 하며, 하위 클래스는 Template Method에서 단계별로 이루어진 메서드들을 override 할 수 있도록 만들어 구조를 변경하지 않고 알고리즘의 특정 단계를 재정의 할 수 있도록 하는 디자인 패턴입니다.
4 |
5 |
6 |
7 | - Abstract Class: Abstract Class는 알고리즘을 단계적으로 작동하는 메서드들과 이들을 실제로 호출하는 Template Method를 정의합니다.
8 | - Concrete Class: Abstract Class에서 정의한 단계적으로 작동하는 메서드들은 override 할 수 있지만 Template Method는 override 할 수 없습니다.
9 |
10 |
11 | ## Template Method는 언제 쓰는 걸까?
12 | #### 클라이언트가 알고리즘의 특정 단계만 제어하고 전체 알고리즘이나 구조를 변경할 수 없도록 하고 싶을 때 템플릿 메서드 패턴을 사용하면 좋습니다. 혹은 특정 단계에서의 구현만 다르고 다른 부분은 대부분 동일한 동작을 하는 알고리즘을 사용하는 경우에도 사용하면 좋습니다.
13 | #### 예를 들어 여러 확장자의 파일들에서 원하는 데이터를 추출하는 작업을 한다고 가정해볼게요. PDF, Word, Excel 파일에서 원하는 데이터를 얻고 싶은 경우 어떤 과정으로 데이터를 얻을 수 있을까요? 일단 간단하게 생각해보면 아래와 같은 단계가 필요할 거 같습니다.
14 |
15 | - 1번. 특정 파일에서 데이터를 가지고 온다.
16 | - 2번. 가지고 온 데이터를 원하는 데이터로 처리한다.
17 | - 3번. 처리된 데이터를 분석한다.
18 |
19 | #### 즉 1번 과정만 다르고 2,3번 과정은 모두 동일하게 작동되어도 문제가 없어보입니다. 하지만 만약 3개의 파일을 처리하기 위한 코드를 모두 따로 구현하면 비효율적이겠죠? 또한 다른 확장자를 분석하는 코드도 추가하려면 더 많은 작업이 필요하게 됩니다. 따라서 동일한 코드를 3번 쓰기보다는 템플릿 메서드 패턴을 사용해서 1번 과정만 3개 만들고 나머지 2,3번 과정은 동일한 코드로 구현하면 이와 같은 문제를 해결할 수 있습니다.
20 |
21 | ## Template Method의 장단점
22 | #### 👍🏻 장점
23 | - 클라이언트가 알고리즘의 특정 부분을 구현해도 알고리즘의 다른 부분은 영향을 덜 받도록 할 수 있다.
24 | - 중복된 코드를 슈퍼 클래스에서 한 번만 정의해도 되기 때문에 효율적이다.
25 | #### 👎🏻 단점
26 | - 일부 클라이언트는 이미 정의된 알고리즘만 사용할 수 있기 때문에 제한받는 상황이 올 수 있습니다.
27 | - Liskov Subsititution Priciple을 위반 할 수 있습니다.
28 | - 템플릿 메서드에 필요한 단계가 많다면 유지하기 어려울 수 있습니다.
29 |
30 |
31 |
32 | > 👀 LSP란?
33 |
34 | #### 리스코프 치환 원칙(LSP): 자료형 S가 자료형 T의 하위형이라면 필요한 프로그램의 속성의 변경 없이 자료형 T의 객체를 자료형 S의 객체로 치환할 수 있어야 한다는 원칙
35 |
36 |
37 | ```
38 | class Rectangle {
39 | var width: Int
40 | var height: Int
41 |
42 | init(width: Int, height: Int) {
43 | self.width = width
44 | self.height = height
45 | }
46 |
47 | func area() -> Int {
48 | return width * height
49 | }
50 | }
51 |
52 | class Square: Rectangle {
53 | override var width: Int {
54 | didSet {
55 | super.height = width
56 | }
57 | }
58 |
59 | override var height: Int {
60 | didSet {
61 | super.width = height
62 | }
63 | }
64 | }
65 | ```
66 |
67 | - Rectangle class와 이를 상속한 Square class가 있다.
68 | - Square에서는 width와 height를 override 하고 있으며, didSet을 설정해 width 혹은 height가 set 될 때 다른 속성을 해당 값과 똑같이 set 하도록 해주었다.
69 |
70 | #### 이는 LSP를 위반하는 예시이다. 만약 Rectangle 객체의 height 속성을 7로 설정하고, width 속성을 5로 설정했다고 해보자. 이러한 Rectangle 객체의 area() 메서드 결과는 35이다. 이런 상황에서 Rectangle 객체가 Square 객체로 변경되었다고 생각해보자. 그럼 width 설정과 함께 height 속성이 함께 설정되면서 결과는 25가 된다.
71 |
72 | ```
73 | func main() {
74 | let square = Square(width: 10, height: 10)
75 |
76 | let rectangle: Rectangle = square
77 |
78 | rectangle.height = 7
79 | rectangle.width = 5
80 |
81 | print(rectangle.area())
82 | }
83 | ```
84 | #### 이러한 변화가 별 문제가 없어보일 수도 있다. Square라는 사실을 알고만 있으면 정상적으로 동작하는 것으로 볼 수도 있기 때문이다. 하지만 추상화라는 개념에서 보면 우리는 해당 객체가 Rectangle인지, Square인지 전혀 모르고 있어야 한다. 우리는 그저 이를 Rectangle로만 판단해야 한다. 이는 Rectangle로 판단해도 전혀 문제가 발생해선 안된다. 하지만 위의 예시에선 Rectangle과 전혀 다르게 동작한다. 그래서 LSP를 위반한 것으로 보아야 한다.
85 |
86 | ```
87 | protocol Geometrics {
88 | func area() -> Int
89 | }
90 |
91 | class Rectangle: Geometrics {
92 | var width: Int
93 | var height: Int
94 |
95 | init(width: Int, height: Int) {
96 | self.width = width
97 | self.height = height
98 | }
99 |
100 | func area() -> Int {
101 | return width * height
102 | }
103 | }
104 |
105 | class Square: Geometrics {
106 | var edge: Int
107 |
108 | init(edge: Int) {
109 | self.edge = edge
110 | }
111 |
112 | func area() -> Int {
113 | return edge * edge
114 | }
115 | }
116 | ```
117 |
118 | #### Geometrics라는 새로운 protocol을 이들이 상속하도록 하여, 간단하게 문제를 해결했다. 이렇게 되면 우리가 객체를 Geometrics로 추상화하여 판단해도 문제 되지 않는다.
119 |
120 | ## 🔡 Template Method 예제
121 | #### 아까 본 다양한 확장자 파일에서 데이터를 가져와서 분석하는 상황을 만들어보도록 할게요. 먼저 아까 정의해본 과정을 한 번 다시 보겠습니다.
122 |
123 | - 1번. 특정 파일에서 데이터를 가지고 온다.
124 | - 2번. 가지고 온 데이터를 원하는 데이터로 처리한다.
125 | - 3번. 처리된 데이터를 분석한다.
126 |
127 | 여기서 각각의 Concrete Class에서 override 할 메서드는 1번에 해당하는 메서드입니다.
128 | 그럼 먼저 Template Method 및 다른 메서드들을 구현한 Abstract Class를 먼저 구현해볼게요.
129 |
130 | ```
131 | // Abstract Class
132 | class DataMining {
133 | // Template Method
134 | final func dataMining() {
135 | getData()
136 | dataProcess()
137 | dataAnalysis()
138 | }
139 |
140 | func getData() {
141 | print("데이터를 불러옵니다.")
142 | }
143 | func dataProcess() {
144 | print("데이터 처리완료")
145 | }
146 | func dataAnalysis() {
147 | print("데이터 분석완료\n")
148 | }
149 | }
150 | ```
151 | Template Method 역할을 하는 dataMining()메서드는 더 이상 override 할 수 없도록 만들어 줬습니다.
152 | 그럼 이제 Concrete Class를 구현해야하는데요, 각각의 Concrete Class에서 override 할 메서드는 getData()뿐입니다.
153 |
154 | ```
155 | // Concrete Class
156 | class PDFFileDataMining: DataMining {
157 | override func getData() {
158 | print("PDF File 데이터를 불러옵니다.")
159 | }
160 | }
161 | // Concrete Class
162 | class WordFileDataMining: DataMining {
163 | override func getData() {
164 | print("Word File 데이터를 불러옵니다.")
165 | }
166 | }
167 | // Concrete Class
168 | class ExcelFileDataMining: DataMining {
169 | override func getData() {
170 | print("Excel File 데이터를 불러옵니다.")
171 | }
172 | }
173 | ```
174 | 이렇게 3개의 Concrete Class를 구현했지만 실제로 각각의 class에서 구현한 메서드는 getData() 하나뿐인 것을 볼 수 있습니다.
175 |
176 |
177 | 이젠 실제로 이를 사용할 Client를 구현해볼게요.
178 | ```
179 | enum FileType {
180 | case pdf
181 | case word
182 | case excel
183 | }
184 | class Client {
185 | static func dataMining(fileType: FileType) {
186 | switch fileType {
187 | case .pdf:
188 | PDFFileDataMining().dataMining()
189 | case .word:
190 | WordFileDataMining().dataMining()
191 | case .excel:
192 | ExcelFileDataMining().dataMining()
193 | }
194 | }
195 | }
196 | ```
197 | 3개의 파일 타입이 있기 때문에 열거형도 하나 만들어줬습니다.
198 |
199 |
200 |
201 |
202 | #### 이렇게 3개의 파일 타입을 처리 할 수 있는 코드를 만들었지만 데이터 처리와 분석 코드는 모두 Abstract Class에서 구현한 메서드를 그대로 사용하고 getData()만 각각의 서브 클래스에서 구현해준 것을 볼 수 있습니다.
203 |
204 |
205 |
206 |
207 |
208 | ## Reference
209 | - https://icksw.tistory.com/260
210 | - https://huisam.tistory.com/entry/LSP
211 | - https://medium.com/movile-tech/liskov-substitution-principle-96f15559e363
212 | - https://inuplace.tistory.com/943
213 |
214 |
215 |
--------------------------------------------------------------------------------
/Computer Science/Operating System/운영체제.md:
--------------------------------------------------------------------------------
1 | // 22.09.04 Noel
2 |
3 |
4 |
5 | # ❤️ 운영체제란?
6 |
7 |
8 |
9 | ### 운영체제(Operating System)
10 |
11 | ### 🤔 운영체제가 뭔가요?
12 |
13 | - 우리가 흔히 아는 맥 OS(Mac OS), 윈도우(Window), 리눅스(Linux), 유닉스(Unix) 등
14 |
15 | - Operating System
16 |
17 | - 컴퓨터(하드웨어) 시스템을 운영하는 소프트웨어
18 |
19 | ```참고
20 | 💡 알아두면 좋은 상식..!
21 |
22 | 🤔 그럼 컴퓨터는 뭘까?
23 | - 컴퓨터는 `정보`를 처리하는 기기
24 |
25 | 🤔 그럼 정보가 뭘까?
26 | - 정보량 = 깜놀도 /I(x) = -log2 P(x)
27 | - `확률이 적은 사건은 큰 정보량`을 갖고, `발생 확률이 큰 사건은 작은 정보량`을 가짐
28 | - 정보의 최소단위 : 1 bit
29 | = 즉 정보는 불확실한 상황을 측정해서 수치적으로 표현한 것
30 |
31 | 🤔 그럼 프로그램은 뭘까?
32 | - 컴퓨터 하드웨어에 어떤 테스크를 실행시키는 명령어들의 집합
33 | ```
34 |
35 |
36 |
37 |
38 |
39 | #### 👉 운영체제도 프로그램(소프트웨어)인가요? : YES
40 |
41 | - 컴퓨터 시스템(하드웨어)의 자원들을 효율적으로 관리하며, 사용자가 컴퓨터를 편리하고 효과적으로 사용할 수 있도록 환경을 제공하는 여러 프로그램의 모임
42 | - 운영체제는 `컴퓨터 사용자`와 `컴퓨터 하드웨어` 간의 `인터페이스로서 동작하는 시스템 소프트웨어`의 일종으로, 다른 응용프로그램이 유용한 작업을 할 수 있도록 하는 환경 제공
43 | - 즉, `응용프로그램(Application Program)`이 `System Service`(하드웨어)를 직접 건드리기 는 어려우니 OS가 중간에 위치해 사용자의 요청을 처리해줌
44 |
45 | ``` 요약
46 | 프로그램(소프트웨어)
47 | => 크게 운영체제 / 응용프로그램(= Application, App)으로 구분
48 | => 운영체제는 응용프로그램을 관리해 사용자가 사용하기 편하게 도와줌
49 | ```
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | ### 🤔 운영체제의 기능
58 |
59 | > 운영체제의 일은 컴퓨터 하드웨어를 관리 하는 것!
60 | >
61 | > 프로그래머들이 하드웨어를 모르더라도 쉽게 사용할 수 있도록 지원해줌
62 |
63 | | 번호 | 내용 |
64 | | ---- | ------------------------------------------------------------ |
65 | | 1 | 프로세서, 기억장치, 입출력장치, 파일 및 정보 등의 지원을 관리 |
66 | | 2 | 자원을 효율적으로 관리하기 위해 자원의 스케줄링 기능을 제공 |
67 | | 3 | 사용자와 시스템간의 편리한 인터페이스(UI)를 제공 |
68 | | 4 | 시스템의 각종 하드웨어와 네트워크를 관리, 제어 |
69 | | 5 | 데이터를 관리하고, 데이터 및 자원의 공유 기능을 제공 |
70 | | 6 | 시스템의 오류를 검사하고 복구 |
71 | | 7 | 자원 보호 기능을 제공 |
72 | | 8 | 입출력에 대한 보조 기능을 제공 |
73 | | 9 | 가상 계산기 능력을 제공
*가상 계산기란?
한대의 컴퓨터를 여러 대의 컴퓨터처럼 보이게하는 가상 컴퓨터 운영체체에 의해 만들어지며
사용자 관점에서는 실제 컴퓨터처럼 보일 수도 있고 아주 다르게 보일 수도 있음 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | ### 🤔 운영체제의 목적
82 |
83 | > 운영체제의 목적은 컴퓨터를 잘 쓰자..!
84 |
85 | - 운영체제 목적은 `처리능력 향상`, `사용 가능동 향상`, `신뢰도 향상`, `반환 시간 단축` 이 있음
86 | - 아래 4가지 항목은 운영체체 성능을 평가하는 기준이 됨
87 |
88 | | 구분 | 내용 |
89 | | ----------------------------------- | ------------------------------------------------------------ |
90 | | **처리능력
(Throughput)** | 일정 시간 내에 시스템이 처리하는 일의 양 |
91 | | **반환시간
(Turn Around Time)** | 시스템에 작업을 의뢰한 시간부터 처리가 완료될 떄까지 걸린 시간 |
92 | | **사용가능도
(Availability)** | 시스템을 사용할 필요가 있을 때 즉시 사용 가능한 정도 |
93 | | **신뢰도
(Reliabilty)** | 시스템이 주어진 문제를 정확하게 해결하는 정도 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | ### 🤔 운영체제의 구성
102 |
103 | 운영체제란 `제어프로그램(Control Program)`과 `처리 프로그램(Process Program)`으로 구성
104 |
105 | - 제어 프로그램 : 컴퓨터 안의 정보들과 자원을 제어, 상태를 감시하고 실행하는 과정을 지시하고 관리
106 | - 처리 프로그램 : 실제로 데이터 처리를 실행하고 결과를 보여줌
107 |
108 |
109 |
110 | #### ① 제어프로그램 (Control Program)
111 |
112 | - 각종 처리 프로그램의 실행과 기억장소 및 데이터 제오 또는 연초처리작업의 스케줄링을 감시하는 기능을 수행
113 | - `데이터 관리 기능` / `작업 관리 기능` / `테스트 관리 기능` 을 가짐
114 |
115 | | 구분 | 내용 |
116 | | ------------------------ | ------------------------------------------------------------ |
117 | | **감시 프로그램** | - 시스템 전체의 동작 상태를 감독하고 지원 (제어프로그램의 중추적 역할)
- 수퍼바이저(Supervisor) : 시스템의 모든 동작 상태를 관리, 감독하는 제어프로그램 |
118 | | **작업 관리 프로그램** | - 어떤 작업을 처리하고 다른 작업으로 자동적 이행을 위한 준비와 처리를 수행 |
119 | | **데이터 관리 프로그램** | - 주기억 장치와 외부 보조 기억 장치 사이의 데이터 전송, 입출력 데이터와 프로그램의 논리적 연결, 파일 조적 및 처리를 담당 |
120 |
121 |
122 |
123 | #### ② 처리 프로그램 (Process Program)
124 |
125 | - 제어 프로그램 감시 하에 컴퓨터의 특정한 문제를 해결하기 위해 필요한 여러가지 기능을 처리할 수 있도록 해주는 프로그램
126 | - 회사측에서 제공하는 프로그램과 사용자가 작성한 문제 해결 프로그램이 있음
127 |
128 | | 구분 | 내용 |
129 | | ------------------ | ------------------------------------------------------------ |
130 | | 언어 번역 프로그램 | - 원시 프로그램을 컴퓨터가 알 수 있는 기계어로 번역시키는 프로그램
-종류 : 컴파일러, 어셈블로, 인터프리터 등 |
131 | | 서비스 프로그램 | - 시스템에서 사용빈도가 높은 프로그램을 미리 개발하여 놓은 프로그램
-종류 : 연계 편집 프로그램, 로더, 디버깅 프로그램, 정렬/병합 프로그램, 라이브러리 등 |
132 | | 문제 처리 프로그램 | - 컴퓨터 사용자가 필요한 업무에 맞게 개발한 프로그램
-종류 : 급여관리, 인사관리, 회계관리 등 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 | ### 🤔 운영체제의 역할
141 |
142 |
143 |
144 | #### ① 프로세스 관리
145 |
146 | - 운영체제에서 작동하는 응용 프로그램을 관리하는 기능
147 | - 어떤 의미에서는 프로세서(CPU)를 관리하는 것이라고 볼 수 있음
148 | - 현재 CPU를 점유해야할 프로세스를 결정하고, 실제로 CPU를 프로세스에 할당하며, 이 프로세스 간 공유 자원 접근과 통신을 관리
149 |
150 | ```하는일
151 | 👉하는 일
152 | - 프로세스, 스레드
153 | - 스케줄링
154 | - 동기화
155 | - ICP 통신
156 | ```
157 |
158 |
159 |
160 | #### ② 저장장치 관리
161 |
162 | - 주기억장치와 보조기억장치(하드디스크/NAND등)을 관리하는 기능
163 | - 주기억장치(Main Memory)
164 | - 프로세스에 할당하는 메모리 영역의 할당과 해제
165 | - 각 메모리 영영 간의 침범 방지
166 | - 메인 메모리의 효율적 활용을 위한 가상 메모리 기능
167 | - 보조기억창지(HDD, NAND, Flash Memory 등)
168 | - 파일 형식의 데이터 저장
169 | - 이런 파일 데이터 관리를 위한 파일 시스템을 OS에서 관리
170 | - `FAT`, `NTFS`, `EXT2`, `JFS`, `XFS` 등 많은 파일 스스템들이 개발되어 사용중
171 |
172 | ```참고
173 | 👉 하는 일
174 | - 메모리 관리
175 | - 가상 메모리
176 | - 파일 시스템
177 | ```
178 |
179 |
180 |
181 | #### ③ 네트워킹
182 |
183 | - 네트워킹은 컴퓨터 활용의 핵심
184 | - TCP/IP 기반의 인터넷에 연결하거나, 응용프로그램이 네트워크를 사용하려면 운영체제에서 **네트워크 프로토콜을 지원**해야한다.
185 | - => 이처럼 운영체제는 사용자와 컴퓨터 하드웨어 사이에 위치해서, 하드웨어 운영 및 관리하고 명령어를 제어하여 응용 프로그램 및 하드웨어를 소프트웨어적으로 제어 및 관리 해야한다.
186 |
187 | ```요약
188 | 👉 하는 일
189 | - TCP/IP
190 | - 기타 프로토콜
191 | ```
192 |
193 |
194 |
195 | #### ④ 사용자 관리
196 |
197 | - 운영체제는 한 컴퓨터를 여러사람이 사용하는 환경도 지원해야함
198 | - 따라서, 운영체제는 각 계정을 관리할 수 있는 기능이 필요
199 | - 사용자 별로 프라이버시와 보안을 위해개인 파일에 대해서는 다른 사용자가 접근 할 수 없도록 해야함
200 | - 이 밖에도 파일이나 접근권한을 지정할 수 있도록 지원하는 것이 사용자 관리 기능
201 |
202 | ```하는일
203 | 👉 하는 일
204 | - 계정 관리
205 | - 접근권한 관리
206 | ```
207 |
208 |
209 |
210 | #### ⑤ 디바이스 드라이버
211 |
212 | - 운영체제는 시스템의 자원, 하드웨어를 관리
213 | - 시스템에는 여러 하드웨어가 붙어있음
214 | - -> 이들을 운영체제에서 인식하고 관리해 응용 프로그램이 하드웨어를 사용할 수 있게 해야함
215 | - 따라서, 운영체제 안에서 하드웨어를 추상화 해주는 계층이 필요
216 | - => 이 계층이 바로 디바이스 드라이버!
217 | - 하드웨어 종류가 많은 만큼, 운영체제 내부의 디바이스 드라이버도 많이 존재
218 | - 여러 디바이스 드라이버들을 관리하는 기능 또한 운영체제가 맡음
219 |
220 | ```하는 일
221 | 👉 하는 일
222 | - 순차접근 장치
223 | - 임의접근 장치
224 | - 네트워크 장치
225 | ```
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 | **출처**
234 |
235 | https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Operating%20System/Operation%20System.md
236 |
237 | https://youtu.be/zGBm37kze9I?list=PLHqxB9kMLLaOs2BM2KbuvttBYCgDoFm-5
238 |
239 |
240 |
241 |
--------------------------------------------------------------------------------
/Computer Science/Network/tcpIpControlFlow&Congestion(흐름&혼잡제어).md:
--------------------------------------------------------------------------------
1 | ## TCP를 배우기 전에
2 | #### 🔗전송계층이란?
3 |
4 |
5 | - 컴퓨터 처리와 전자 통신에서 전송 계층(Transport layer)은 계층 구조의 네트워크 구성요소와 프로토콜 내에서 송신자와 수신자를 연결하는 통신 서비스를 제공한다.
6 | - 전송 계층은 연결 지향 데이터 스트림 지원, 신뢰성, 흐름 제어, 그리고 다중화와 같은 편리한 서비스를 제공한다.
7 | - 전송 계층은 인터넷의 기반인 TCP/IP 참조 모델과 일반적인 네트워크 모델인 개방형 시스템 간 상호 접속 (Open Systems Interconnection, OSI) 모두 포함하고 있다.
8 | - 전송 프로토콜 중 가장 잘 알려진 것은 연결 지향 전송 방식을 사용하는 전송 제어 프로토콜(TCP)이다. 보다 단순한 전송에 사용되는 사용자 데이터그램 프로토콜(UDP)도 있다.
9 |
10 | #### "한 마디로 정의하자면 End Point 간 신뢰성 있는 데이터 전송을 담당하는 계층이다!"
11 |
12 |
13 |
14 | #### 🔗전송 계층이 없다면?
15 | - 데이터의 순차 전송이 원활히 이루어지지 않는다.
16 | - Flow(흐름문제) -> 송수신자 간의 데이터 처리 속도 차이
17 | - Congestion(혼잡문제) -> 네트워크의 데이터 처리 속도 (ex. 라우터)
18 |
19 |
20 | ## TCP로 넘어가보자
21 |
22 | ### ✔️TCP(Transmission Control Protocol)란 무엇일까?
23 | #### 컴퓨터가 다른 컴퓨터와 데이터 통신을 하기 위한 규약(프로토콜)의 일종이다. 한국어로 번역하면 전송 제어 프로토콜. TCP는 세계 통신표준으로 개발된 OSI 모형에서 4번째 계층인 전송 계층(Transport Layer)에서 사용하는 규약으로, 보통 하위 계층에서 사용하는 IP와 엮어서 TCP/IP로 표현하는 경우가 많다. 동일 계층에서 사용하는 또 다른 프로토콜로 UDP가 존재한다.
24 |
25 | ### ✔️왜 TCP가 개발되었을까?
26 | ##### TCP의 개발 동기는 군사적인 목적과도 닿아있다. 미국 국방부 산하의 고등 연구국에서 ARPANET을 연구할 때 관심을 가진 주제가 적국의 폭격, 심지어 핵전쟁이 발발하더라도 죽지 않고 정상적으로 동작하는 네트워크였다. 당시 일반적으로 사용되던 통신방식은 회선교환(Circuit Switching) 방식이었다. 예를 들어 서울에서 부산으로 간다고 할 때 미리 이동할 경로를 "경부고속도로만 이용한다"로 정해놓는 방식이다. 이러한 방식은 통신을 중계해 주던 곳이 개박살나거나 중간에 선 하나가 단락되는 것만으로도 통신이 바로 끊어지는 상황이 벌어졌다.
27 |
28 | ##### 이에 따라 사용된 것이 패킷교환(Packet Switching) 방식인데, 앞서의 사례와는 달리 경로가 정해져 있지 않다. 경부고속도로가 심하게 막히면 다른 고속도로나 국도로 우회를 해서 갈 수 있는 방식이다. 따라서 서로 연결이 가능한 회선 하나만 남아있어도 통신이 끊어지지 않고 계속될 수 있는 환경을 구축하게 된 셈이었다. 다만 이 방식은 어떻게든 통신을 유지하는 것이 목적이므로 네트워크 환경의 안정성은 떨어질 수밖에 없었다. 이로 인해 중간에 데이터가 유실되거나, 너무 늦게 전달되는 등 신뢰성이 떨어지는 문제점이 있었다. 이러한 문제점들을 해결하고자 신뢰성을 보장할 수 있는 통신 규약을 연구하게 됐고, 이에 따라 나온 것이 TCP이다.
29 |
30 | ### ✔️TCP의 특징
31 | - 3Way Handshake, 4Way Handshake 기능을 통해 통신을 연결하고 종료할 수 있다.(3way 내용 참고)
32 |
33 | - 신뢰성 보장과 흐름 제어(Flow Control)
34 | - 연결설정을 통해 통신 준비를 마치면 서로 데이터를 주고 받을 수 있다.
35 | - 다만 네트워크를 통해서 한 번에 보낼 수 있는 데이터의 양은 제한이 되어 있으므로 분할해서 보내야 된다.
36 | - 분할된 데이터에는 고유번호가 부여된다.
37 | - 이를 바탕으로 데이터 수신, 발신자 모두 데이터의 정보를 알 수 있다.
38 | - 또한 데이터의 고유번호를 알고 있기 때문에 데이터가 제대로 왔는지 안왔는지 신뢰성을 확인할 수 있다.
39 | - 서버에서 수신할 수 있는 자료양 혹은 클라이언트가 서버로부터 수신할 수 있는 자료양 등을 서로 알려준느 방식을 통해 효율적으로 데이터 전송이 가능하다.
40 | - 이를 위해 TCP의 헤더파일을 살펴보면 목적지주소, 확인 응답, 오류검출및복원, 실제데이터 등이 포함된다.
41 | - 따라서 이 과정을 전부 이행하기 위해 신뢰성은 높지만 수신속도가 떨어진다는 단점을 지닌다.
42 |
43 | - 혼잡 제어(Congestion Control)
44 | - 초기 TCP에는 없던 요소이다. 한정된 네트워크 대역폭에서 사용자가 점점 늘어나다 보니 네트워크 회선이 그 부하를 감당하지 못하고 사망하는 일들이 발생했다.
45 | - 부하가 발생하는 예시는 다음과 같다.
46 | - 송신자 A: '이상하네, 벌써 'ABC'를 보낸지 한참 됐는데 왜 받았다는 연락이 안올까?. 한 번 더 보내야겠다.
47 | - 송신자 B: '이상하네, 벌써 'ABC'를 보낸지 한참 됐는데 왜 받았다는 연락이 안올까?. 한 번 더 보내야겠다.
48 | - 송신자 C: '이상하네, 벌써 'ABC'를 보낸지 한참 됐는데 왜 받았다는 연락이 안올까?. 한 번 더 보내야겠다.
49 | - 여기서 A, B, C는 라우터로 송신하는 사람들이다. 이미 라우터에는 아직 라우터가 미처 다 송신하지 못한 A, B, C의 데이터들이 남아있다. 그런데 A,B,C가 각각 데이터를 또 보낸다. 이것은 두 가지 문제가 있다.
50 | - 라우터의 저장에도 한계 용량이 있다. 라우터 내의 저장 공간에 저장되지 못한 데이터들은 손실된다.
51 | - 데이터에 대한 답신이 없으면 또 같은 데이터에 대한 요청을 보낸다. 만약 라우터가 무한한 저장공간을 가진다는 가정하에라도, 결국 라우터에 쌓여가는 데이터들 때문에 사용되는 전력이 비효율적이다.
52 | - 그래서 이를 제어하기 위한 방법이 1980년대에 추가됐다.
53 | - 단순한 예로 통신을 시작할 때 일단 보내는 쪽에서 30~35쪽까지 자료를 보내본다.
54 | - 그래서 상대가 잘 받았으면 이후 보내는 양을 조금씩 늘려보는 방식을 취한다.
55 | - 그러다가 상대가 데이터를 제대로 받지 못한 것이 확인되면 그 즉시 보내는 양을 확 줄인다.
56 | - 그리고 다시 슬금슬금 보내는 양을 늘렸다가 또 못 받았으면 줄여버리는 형태로 보내는 양을 조절하게 된다.
57 | - 보내는 양을 늘리고 줄이는 방법은 AIMD(Additive Increase/Multiplicative Decrease)를 채택하고 있으나 구체적으로 적용되는 방식은 TCP 버전마다 약간씩 차이가 있다.
58 | - 이 방법은 버스트(burst)를 줄이기 위한 것이다.
59 | - 깨진 독에 어떻게 물이 차오르기 시작하는지를 생각해보면 어렵지 않다.
60 | - 어느 순간에 빠지는 속도보다 들어오는 속도가 커지는 순간이다. 이것을 버스트라고 부르는데, 요점은 버스트가 나지 않으면 물이 차오르기 시작할 일도 없다는 것이고, 버스트가 발생해서 물이 차오르기 시작했다면 일단 물이 다 빠진 다음에 물을 부으면 되겠다는 생각이다.
61 | - 이를 네트워크 환경에 맞추어 해석하면, 처음에 버스트가 생기지 않을 적절한 양을 보내고, 버스트가 일어나 라우터에 낱장들이 쌓이기 시작하는 것이 의심된다면 일단 라우터에서 그 낱장들이 빠지는 것을 기다린다는 방법이 되는 것이다.
62 | - 위 방법을 통해 TCP로 통신하는 모든 사용자들이 네트워크 상황에 따라 속도를 조절할 수 있게 되었으며, 많은 사용자들이 동시에 통신을 시도하면 속도에서 손해를 보게 되지만 죽지는 않게 만들었다. 이론적으로 100 Mbps 회선에서 5명의 사람이 동시에 TCP로 통신을 시도하면 초반에는 서로 차이가 있지만 궁극적으로는 100 Mbps 회선을 각각 20 Mbps씩 공평하게 나눠 가지는 효과를 얻게 된다.
63 |
64 | ### ✔️TCP/IP 계층에 대해서
65 | - TCP/IP는 통신 규칙의 모음이며, 프로토콜 스위트라고 부르기도 한다.
66 | - TCP/IP의 4계층은 이러한 규칙이나 프로토콜이 적용되는 특정한 조건을 의미한다.
67 | - 이 시스템은 TCP/IP 모델이 다양한 기기와 앱에서 효율적으로 ‘통신’하고 데이터를 전송할 수 있도록 하는 방식이다.
68 |
69 |
70 |
71 | #### 응용 계층
72 | - 응용 계층 (Application Layer) 프로토콜은 TCP/IP 프로토콜 (TCP IP protocol)의 범위에 포함되어있다.
73 | - 이러한 프로토콜은 앱에 구축되기 때문에 사용자가 상호작용하기 가장 쉬운 계층이다.
74 | - 응용 계층은 사용자 (사람 또는 소프트웨어)가 네트워크에 접근할 수 있도록 한다. 게다가, 사용자 인터페이스를 제공할 뿐만 아니라 이메일, 원격 파일 접근 및 전송, 공유 데이터베이스 관리 등의 서비스를 제공한다.
75 | - 메일 프로그램에서는 인터넷에서 전자우편을 보낼 때 이용하게 되는 표준 통신 규약인 SMPT (Simple Mail Transfer Protocol)를 이용한다.
76 | - 인터넷 브라우저는 웹 서버와 사용자의 인터넷 브라우저 사이에 문서를 전송하기 위해 사용되는 통신 규약인 HTTP (Hypertext Transfer Protocol) 등을 이용한다.
77 | - 이외에도 흔히 이용되는 응용 계층 프로토콜로는 파일 전송 규약 (File Transfer Protocol: FTP), 동적 호스트 설정 통신 규약 (Dynamic host Configuration protocol: DHCP), 간이 망 관리 프로토콜(Simple Network Management Protocol: SNMP) 등이 있다.
78 |
79 | #### 전송 계층
80 | - 전송 계층은 전송을 담당하는 계층이다.
81 | - 전송 계층에는 TCP뿐만 아니라 사용자 데이터그램 통신 규약(User Datagram Protocol: UDP)도 있다.
82 | - UDP는 TCP보다 단순하며 다른 데이터에 비해 안전하게 보호되어야 할 필요가 없는 실시간 응용 프로그램에서 흔히 이용된다.
83 | - UDP는 TCP보다 신뢰도가 낮고 오류 검출, 흐름 제어 등의 기능을 제공하지 않아 패킷을 빠르게 전송하는 응용 계층에서 이용되고있다.
84 | - TCP는 두 네트워크 사이에 연결을 형성하고 효율적인 작업을 위해 데이터를 작은 패킷으로 나눠서 데이터를 전송한다. TCP는 연결형 서비스이지만, UDP는 비연결형 서비스이다.
85 | - TCP는 신뢰도가 높지만 속도가 느리고, 이에 비해서 UDP는 신뢰도가 낮지만 속도가 빠르다. TCP의 패킷 교환 방식은 가상 회선 방식인 반면, 반면에 UDP는 데이터그램 방식을 따르고 있다. TCP에서는 전송 순서를 보장하지만 UDP의 경우 전송 순서가 바뀔 수 있다.
86 |
87 | #### 인터넷 계층
88 | - 인터넷 계층 (Internet Layer) 프로토콜에는 IP뿐만 아니라 주소 변환 규약(Address Resolution Protocol: ARP), 인터넷 그룹 관리 프로토콜(Internet Group Management Protocol: IGMP), 인터넷 제어 메시지 프로토콜 (Internet Control Message Protocol: ICMP)도 있다.
89 | - 인터넷 계층은 네트워크 간 데이터 패킷의 전송을 관리한다.
90 | - 여기서 ARP는 네트워크 계층 주소와 링크 계층 주소 사이의 변환을 담당하는 프로토콜이며, IGMP는 그룹 멤버십을 구성하거나, 그룹 관리를 위한 프로토콜이며, ICMP는 인터넷 통신 서비스 환경에서 오류에 대한 알림과 관련된 메시지를 전달하는 목적의 프로토콜이다.
91 |
92 | #### 데이터 링크 계층
93 | - 데이터 링크 계층 (Datalink Layer)은 데이터 전송의 최하위 계층으로, 네트워크 인터페이스 계층(Network Interface Layer)이라고도 부른다.
94 | - 이 계층에서 하는 일은 데이터가 원하는 IP 주소 (즉, 공유기)에 도달할 뿐만 아니라 해당 네트워크 내의 연결된 기기에 연결되어 있는지 확인하는 역할이다.
95 | - 데이터 링크 계층은 원하는 기기의 MAC 주소를 확인하고 이더넷 케이블 및 와이파이를 통한 데이터 전송을 관리하는 등의 작업을 담당한다.
96 |
97 |
98 |
99 |
100 |
101 |
102 | ## Reference
103 | - https://ko.wikipedia.org/wiki/%EC%A0%84%EC%86%A1_%EA%B3%84%EC%B8%B5
104 | - https://namu.wiki/w/TCP
105 | - https://www.youtube.com/watch?v=ikDVGYp5dhg
106 |
--------------------------------------------------------------------------------