├── .DS_Store ├── .github └── FUNDING.yml ├── Algorithm ├── .DS_Store ├── Binary Search.md ├── DFS & BFS.md ├── Hash Table 구현하기.md ├── HeapSort.md ├── LCA(Lowest Common Ancestor).md ├── LIS (Longest Increasing Sequence).md ├── MergeSort.md ├── QuickSort.md ├── README.md ├── SAMSUNG Software PRO등급 준비.md ├── Sort_Counting.md ├── Sort_Radix.md ├── code │ ├── Heap.java │ ├── InsertionSort.java │ ├── QuickSort.java │ ├── bubbleSort.java │ └── mergeSort.java ├── professional │ └── 프로 준비법.md ├── 간단하지만 알면 좋은 최적화들.md ├── 다익스트라(Dijkstra).md ├── 동적 계획법 (Dynamic Programming).md ├── 비트마스크(BitMask).md ├── 순열 & 조합.md └── 최대공약수 & 최소공배수.md ├── Computer Science ├── Computer Architecture │ ├── ARM 프로세서.md │ ├── 고정 소수점 & 부동 소수점.md │ ├── 명령어 Cycle.md │ ├── 중앙처리장치(CPU) 작동 원리.md │ ├── 캐시 메모리(Cache Memory).md │ ├── 컴퓨터구조 기초.pdf │ ├── 컴퓨터의 구성.md │ └── 패리티 비트 & 해밍 코드.md ├── Data Structure │ ├── Array vs ArrayList vs LinkedList.md │ ├── Array.md │ ├── B Tree & B+ Tree.md │ ├── Binary Search Tree.md │ ├── Hash.md │ ├── Heap.md │ ├── Linked List.md │ ├── README.md │ ├── Stack & Queue.md │ ├── Tree.md │ ├── Trie.md │ └── code │ │ ├── MaxHeap.java │ │ ├── MinHeap.java │ │ ├── binarySearchTree.java │ │ ├── juggling_array.cpp │ │ ├── linked_list.java │ │ ├── linked_list_push.java │ │ ├── maxvalue_array.cpp │ │ ├── rearrange_array.cpp │ │ ├── reversal_array.cpp │ │ └── rotate_array.cpp ├── Database │ ├── Redis.md │ ├── SQL Injection.md │ ├── SQL과 NOSQL의 차이.md │ ├── Transaction Isolation Level.md │ ├── Transaction.md │ ├── [DB] Anomaly.md │ ├── [DB] Index.md │ ├── [DB] Key.md │ ├── [Database SQL] JOIN.md │ ├── 저장 프로시저(Stored PROCEDURE).md │ └── 정규화(Normalization).md ├── Network │ ├── DNS.md │ ├── HTTP & HTTPS.md │ ├── OSI 7 계층.md │ ├── TCP (흐름제어혼잡제어).md │ ├── TCP 3 way handshake & 4 way handshake.md │ ├── TLS HandShake.md │ ├── UDP.md │ ├── [Network] Blocking Non-Blocking IO.md │ ├── [Network] Blocking,Non-blocking & Synchronous,Asynchronous.md │ ├── 대칭키 & 공개키.md │ └── 로드 밸런싱(Load Balancing).md ├── Operating System │ ├── CPU Scheduling.md │ ├── DeadLock.md │ ├── File System.md │ ├── IPC(Inter Process Communication).md │ ├── Interrupt.md │ ├── Memory.md │ ├── Operation System.md │ ├── PCB & Context Switcing.md │ ├── Page Replacement Algorithm.md │ ├── Paging and Segmentation.md │ ├── Paging and Segmentation.pdf │ ├── Process Address Space.md │ ├── Process Management & PCB.md │ ├── Process vs Thread.md │ ├── Race Condition.md │ ├── Semaphore & Mutex.md │ └── [OS] System Call (Fork Wait Exec).md └── Software Engineering │ ├── Clean Code & Refactoring.md │ ├── Fuctional Programming.md │ ├── Object-Oriented Programming.md │ ├── TDD(Test Driven Development).md │ ├── 데브옵스(DevOps).md │ ├── 마이크로서비스 아키텍처(MSA).md │ ├── 써드파티(3rd party)란.md │ ├── 애자일(Agile).md │ ├── 애자일(Agile)2.md │ └── 클린코드(Clean Code) & 시큐어코딩(Secure Coding).md ├── Design Pattern ├── Adapter Pattern.md ├── Composite Pattern.md ├── Design Pattern_Adapter.md ├── Design Pattern_Factory Method.md ├── Design Pattern_Template Method.md ├── Observer pattern.md ├── SOLID.md ├── Singleton Pattern.md ├── Strategy Pattern.md ├── Template Method Pattern.md └── [Design Pattern] Overview.md ├── ETC ├── Collaborate with Git on Javascript and Node.js.md ├── Git Commit Message Convention.md ├── Git vs GitHub vs GitLab Flow.md ├── GitHub Fork로 협업하기.md ├── GitHub 저장소(repository) 미러링.md ├── OPIC.md ├── [인적성] 명제 추리 풀이법.md ├── 반도체 개념정리.md ├── 시사 상식.md └── 임베디드 시스템.md ├── Interview ├── Interview List.md ├── Mock Test │ ├── 2019년 #기업 2차 필기테스트 유형.md │ ├── 2019년 #기업 필기테스트.md │ ├── 2019년 면접질문.md │ └── GML Test (2019-10-03).md ├── README.md └── [Java] Interview List.md ├── LICENSE ├── Language ├── [C++] Vector Container.md ├── [C++] 가상 함수(virtual function).md ├── [C++] 입출력 실행속도 줄이는 법.md ├── [C] 구조체 메모리 크기 계산.md ├── [C] 동적할당.md ├── [C] 포인터(Pointer).md ├── [Cpp] shallow copy vs deep copy.md ├── [Java] Auto Boxing & Unboxing.md ├── [Java] Interned String in JAVA.md ├── [Java] Intrinsic Lock.md ├── [Java] Java 8 정리.md ├── [Java] wait notify notifyAll.md ├── [Java] 직렬화(Serialization).md ├── [Java] 컴포지션(Composition).md ├── [Javascript] Closure.md ├── [Javascript] ES2015+ 요약 정리.md ├── [Javascript] 데이터 타입.md ├── [Javasript] Object Prototype.md ├── [Python] 매크로 라이브러리.md ├── [c] C언어 컴파일 과정.md ├── [java] Call by value와 Call by reference.md ├── [java] Casting(업캐스팅 & 다운캐스팅).md ├── [java] Java major feature changes.md ├── [java] Java에서의 Thread.md ├── [java] Record.md ├── [java] Stream.md ├── [java] String StringBuilder StringBuffer 차이.md ├── [java] 자바 가상 머신(Java Virtual Machine).md └── [java] 자바 컴파일 과정.md ├── Linux ├── Linux Basic Command.md ├── Permission.md └── Von Neumann Architecture.md ├── New Technology ├── AI │ ├── Linear regression 실습.md │ └── README.md ├── Big Data │ ├── DBSCAN 클러스터링 알고리즘.md │ └── 데이터 분석.md └── IT Issues │ ├── 2020 ICT 이슈.md │ ├── AMD vs Intel.md │ ├── README.md │ ├── [2019.08.07] 이메일 공격 증가로 보안업계 대응 비상.md │ ├── [2019.08.08] IT 수다 정리.md │ └── [2019.08.20] Google, 크롬 브라우저에서 FTP 지원 중단 확정.md ├── README.md ├── Seminar ├── 2019 삼성전자 비전캠프.md ├── 2019 삼성전자 오픈소스 컨퍼런스(SOSCON).md ├── NCSOFT 2019 JOB Cafe.md └── NHN 2019 OPEN TALK DAY.md ├── Web ├── CSR & SSR.md ├── CSRF & XSS.md ├── Cookie & Session.md ├── DevOps │ ├── [AWS] 스프링 부트 배포 스크립트 생성.md │ ├── [Travis CI] 프로젝트 연동하기.md │ └── 시스템 규모 확장.md ├── HTTP Request Methods.md ├── HTTP status code.md ├── JWT(JSON Web Token).md ├── Logging Level.md ├── Nuxt.js.md ├── OAuth.md ├── PWA (Progressive Web App).md ├── README.md ├── REST API.pptx ├── React │ ├── React & Spring Boot 연동하여 환경 구축하기.md │ ├── React Fragment.md │ └── React Hook.md ├── Spring │ ├── JPA.md │ ├── Spring MVC.md │ ├── Spring Security - Authentication and Authorization.md │ ├── [Spring Boot] SpringApplication.md │ ├── [Spring Boot] Test Code.md │ ├── [Spring Data JPA] 더티 체킹 (Dirty Checking).md │ └── [Spring] Bean Scope.md ├── UI와 UX.md ├── Vue.js와 React의 차이.md ├── Vue │ ├── Vue CLI + Spring Boot 연동하여 환경 구축하기.md │ ├── Vue.js + Firebase로 이메일 회원가입로그인 구현.md │ ├── Vue.js + Firebase로 페이스북(facebook) 로그인 연동하기.md │ └── Vue.js 라이프사이클 이해하기.md ├── Web Server와 WAS의 차이.md ├── [Travis CI] 프로젝트 연동하기.md ├── [Web] REST API.md ├── 네이티브 앱 & 웹 앱 & 하이브리드 앱.md ├── 브라우저 동작 방법.md └── 인증방식.md └── resources ├── CPU 스케줄링.PNG ├── CPU점유.PNG ├── Main Image.png ├── authentication.JPG ├── composite_pattern_1.PNG ├── composite_pattern_2.PNG ├── composite_pattern_3.PNG ├── login.JPG ├── ncsoft.jpg ├── roadmap.PNG ├── run 화면.JPG ├── signup.JPG ├── vue init.JPG ├── 로그인 성공.JPG ├── 비밀번호 불일치시.JPG ├── 사용자확인.JPG ├── 웹앱 추가.JPG ├── 파이어베이스 프로젝트 추가.JPG ├── 파이어베이스 프로젝트 추가2.JPG ├── 활성화.JPG └── 회원가입성공.JPG /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/.DS_Store -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: gyoogle 4 | patreon: 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: https://www.paypal.me/gyoogle 13 | -------------------------------------------------------------------------------- /Algorithm/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/Algorithm/.DS_Store -------------------------------------------------------------------------------- /Algorithm/Binary Search.md: -------------------------------------------------------------------------------- 1 | ## 이분 탐색(Binary Search) 2 | 3 | > 탐색 범위를 두 부분으로 분할하면서 찾는 방식 4 | 5 | 처음부터 끝까지 돌면서 탐색하는 것보다 훨~~~씬 빠른 장점을 지님 6 | 7 | ``` 8 | * 시간복잡도 9 | 전체 탐색 : O(N) 10 | 이분 탐색 : O(logN) 11 | ``` 12 | 13 |
14 | 15 | #### 진행 순서 16 | 17 | - 우선 정렬을 해야 함 18 | - left와 right로 mid 값 설정 19 | - mid와 내가 구하고자 하는 값과 비교 20 | - 구할 값이 mid보다 높으면 : left = mid+1 21 | 구할 값이 mid보다 낮으면 : right = mid - 1 22 | - left > right가 될 때까지 계속 반복하기 23 | 24 |
25 | 26 | #### Code 27 | 28 | ```java 29 | public static int solution(int[] arr, int M) { // arr 배열에서 M을 찾자 30 | 31 | Arrays.sort(arr); // 정렬 32 | 33 | int start = 0; 34 | int end = arr.length - 1; 35 | int mid = 0; 36 | 37 | while (start <= end) { 38 | mid = (start + end) / 2; 39 | if (M == arr[mid]) { 40 | return mid; 41 | }else if (arr[mid] < M) { 42 | start = mid + 1; 43 | }else if (M < arr[mid]) { 44 | end = mid - 1; 45 | } 46 | } 47 | throw new NoSuchElementException("타겟 존재하지 않음"); 48 | } 49 | ``` 50 | 51 | -------------------------------------------------------------------------------- /Algorithm/LCA(Lowest Common Ancestor).md: -------------------------------------------------------------------------------- 1 | ## LCA(Lowest Common Ancestor) 알고리즘 2 | 3 | > 최소 공통 조상 찾는 알고리즘 4 | > 5 | > → 두 정점이 만나는 최초 부모 정점을 찾는 것! 6 | 7 | 트리 형식이 아래와 같이 주어졌다고 하자 8 | 9 | 10 | 11 | 4와 5의 LCA는? → 4와 5의 첫 부모 정점은 '2' 12 | 13 | 4와 6의 LCA는? → 첫 부모 정점은 root인 '1' 14 | 15 | ***어떻게 찾죠?*** 16 | 17 | 해당 정점의 depth와 parent를 저장해두는 방식이다. 현재 그림에서의 depth는 아래와 같을 것이다. 18 | 19 | ``` 20 | [depth : 정점] 21 | 0 → 1(root 정점) 22 | 1 → 2, 3 23 | 2 → 4, 5, 6, 7 24 | ``` 25 | 26 |
27 | 28 | parent는 정점마다 가지는 부모 정점을 저장해둔다. 위의 예시에서 저장된 parent 배열은 아래와 같다. 29 | 30 | ```java 31 | // 1 ~ 7번 정점 (root는 부모가 없기 때문에 0) 32 | int parent[] = {0, 1, 1, 2, 2, 3, 3} 33 | ``` 34 | 35 | 이제 36 | 37 | 이 두 배열을 활용해서 두 정점이 주어졌을 때 LCA를 찾을 수 있다. 과정은 아래와 같다. 38 | 39 | ```java 40 | // 두 정점의 depth 확인하기 41 | while(true){ 42 | if(depth가 일치) 43 | if(두 정점의 parent 일치?) LCA 찾음(종료) 44 | else 두 정점을 자신의 parent 정점 값으로 변경 45 | else // depth 불일치 46 | 더 depth가 깊은 정점을 해당 정점의 parent 정점으로 변경(depth가 감소됨) 47 | } 48 | ``` 49 | 50 |
51 | 52 | 트리 문제에서 공통 조상을 찾아야하는 문제나, 정점과 정점 사이의 이동거리 또는 방문경로를 저장해야 할 경우 사용하면 된다. -------------------------------------------------------------------------------- /Algorithm/LIS (Longest Increasing Sequence).md: -------------------------------------------------------------------------------- 1 | ## LIS (Longest Increasing Sequence) 2 | 3 | > 최장 증가 수열 : 가장 긴 증가하는 부분 수열 4 | 5 | [ 7, **2**, **3**, 8, **4**, **5** ] → 해당 배열에서는 [2,3,4,5]가 LIS로 답은 4 6 | 7 |
8 | 9 | ##### 구현 방법 (시간복잡도) 10 | 11 | 1. DP : O(N^2) 12 | 2. Lower Bound : O(NlogN) 13 | 14 |
15 | 16 | ##### DP 활용 코드 17 | 18 | ```java 19 | int arr[] = {7, 2, 3, 8, 4, 5}; 20 | int dp[] = new int[arr.length]; // LIS 저장 배열 21 | 22 | 23 | for(int i = 1; i < dp.length; i++) { 24 | for(int j = i-1; j>=0; j--) { 25 | if(arr[i] > arr[j]) { 26 | dp[i] = (dp[i] < dp[j]+1) ? dp[j]+1 : dp[i]; 27 | } 28 | } 29 | } 30 | 31 | for (int i = 0; i < dp.length; i++) { 32 | if(max < dp[i]) max = dp[i]; 33 | } 34 | 35 | // 저장된 dp 배열 값 : [0, 0, 1, 2, 2, 3] 36 | // LIS : dp배열에 저장된 값 중 최대 값 + 1 37 | ``` 38 | 39 |
40 | 41 | 하지만, N^2으로 해결할 수 없는 문제라면? (ex. 배열의 길이가 최대 10만일 때..) 42 | 43 | 이때는 Lower Bound를 활용한 LIS 구현을 진행해야한다. 44 | 45 | -------------------------------------------------------------------------------- /Algorithm/README.md: -------------------------------------------------------------------------------- 1 | ## 알고리즘(코딩테스트) 문제 접근법 2 | 3 |
4 | 5 | #### Data Structure 6 | 7 | 1. **배열** : 임의의 사이즈를 선언 (Heap, Queue, Binary Tree, Hashing 사용) 8 | 2. **스택** : 행 특정조건에 따라 push, pop 적용 9 | 3. **큐** : BFS를 통해 순서대로 접근할 때 적용 10 | 4. **연결리스트** : 배열 구현, 포인터 구현 2가지 방법 - 삽입,삭제가 많이 일어날 때 활용하기 11 | 5. **그래프** : 경우의 수, 연결 관계가 있을 때 적용 12 | 6. **해싱** : 데이터 수만큼 메모리에 생성할 수 없는 상황에 적용 13 | 7. **트리** : Heap과 BST(이진탐색) 14 | 15 |
16 | 17 | #### Algorithm 18 | 19 | 1. **★재귀(Recursion)** : 가장 많이 활용. 중요한 건 호출 횟수를 줄여야 함 (반복 조건, 종료 조건 체크) 20 | 2. **★BFS, DFS** : 2차원 배열에서 확장 시, 경우의 수를 탐색할 때 구조체(class)와 visited 체크를 사용함 21 | 3. **★정렬** : 퀵소트나 머지소트가 대표적이지만, 보통 퀵소트를 사용함 22 | 4. **★메모이제이션(memoization)** : 이전 결과가 또 사용될 때, 반복 작업을 안하도록 저장 23 | 5. **★이분탐색(Binary Search)** : logN으로 시간복잡도를 줄일 수 있는 간단하면서 핵심적인 알고리즘 24 | 6. **최소신장트리(MST)** : 사이클이 포함되지 않고 모든 정점이 연결된 트리에 사용 (크루스칼, 프림) 25 | 7. **최소공통조상(LCA)** : 경우의 수에서 조건이 겹치는 경우. 최단 경로 탐색시 공통인 경우가 많을 때 적용 26 | 8. **Disjoint-Set** : 서로소 집합. 인접한 집함의 모임으로 Tree의 일종이며 시간복잡도가 낮음 27 | 9. **분할 정복** : 머지 소트에 사용되며 범위를 나누어 확인할 때 사용 28 | 10. **트라이(Trie)** : 모든 String을 저장해나가며 비교하는 방법 29 | 11. **비트마스킹** : `|는 OR, &는 AND, ^는 XOR` <<를 통해 메모리를 절약할 수 있음 30 | 31 |
32 | 33 | - Sort 시간복잡도 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Algorithm/Sort_Counting.md: -------------------------------------------------------------------------------- 1 | #### Comparison Sort 2 | 3 | ------ 4 | 5 | > N개 원소의 배열이 있을 때, 이를 모두 정렬하는 가짓수는 N!임 6 | > 7 | > 따라서, Comparison Sort를 통해 생기는 트리의 말단 노드가 N! 이상의 노드 갯수를 갖기 위해서는, 2^h >= N! 를 만족하는 h를 가져야 하고, 이 식을 h > O(nlgn)을 가져야 한다. (h는 트리의 높이,,, 즉 Comparison sort의 시간 복잡도임) 8 | 9 | 이런 O(nlgn)을 줄일 수 있는 방법은 Comparison을 하지 않는 것 10 | 11 | 12 | 13 | #### Counting Sort 과정 14 | 15 | ---- 16 | 17 | 시간 복잡도 : O(n + k) -> k는 배열에서 등장하는 최대값 18 | 19 | 공간 복잡도 : O(k) -> k만큼의 배열을 만들어야 함. 20 | 21 | Counting이 필요 : 각 숫자가 몇 번 등장했는지 센다. 22 | 23 | ```c 24 | int arr[5]; // [5, 4, 3, 2, 1] 25 | int sorted_arr[5]; 26 | // 과정 1 - counting 배열의 사이즈를 최대값 5가 담기도록 크게 잡기 27 | int counting[6]; // 단점 : counting 배열의 사이즈의 범위를 가능한 값의 범위만큼 크게 잡아야 하므로, 비효율적이 됨. 28 | 29 | // 과정 2 - counting 배열의 값을 증가해주기. 30 | for (int i = 0; i < arr.length; i++) { 31 | counting[arr[i]]++; 32 | } 33 | // 과정 3 - counting 배열을 누적합으로 만들어주기. 34 | for (int i = 1; i < counting.length; i++) { 35 | counting[i] += counting[i - 1]; 36 | } 37 | // 과정 4 - 뒤에서부터 배열을 돌면서, 해당하는 값의 인덱스에 값을 넣어주기. 38 | for (int i = arr.length - 1; i >= 0; i--) { 39 | sorted_arr[counting[arr[i]] - 1] = arr[i]; 40 | counting[arr[i]]--; 41 | } 42 | ``` 43 | 44 | * 사용 : 정렬하는 숫자가 특정한 범위 내에 있을 때 사용 45 | 46 | (Suffix Array 를 얻을 때, 시간복잡도 O(nlgn)으로 얻을 수 있음.) 47 | 48 | * 장점 : O(n) 의 시간복잡도 49 | 50 | * 단점 : 배열 사이즈 N 만큼 돌 때, 증가시켜주는 Counting 배열의 크기가 큼. 51 | 52 | (메모리 낭비가 심함) -------------------------------------------------------------------------------- /Algorithm/Sort_Radix.md: -------------------------------------------------------------------------------- 1 | #### Comparison Sort 2 | 3 | --- 4 | 5 | > N개 원소의 배열이 있을 때, 이를 모두 정렬하는 가짓수는 N!임 6 | > 7 | > 따라서, Comparison Sort를 통해 생기는 트리의 말단 노드가 N! 이상의 노드 갯수를 갖기 위해서는, 2^h >= N! 를 만족하는 h를 가져야 하고, 이 식을 h > O(nlgn)을 가져야 한다. (h는 트리의 높이,,, 즉 Comparison sort의 시간 복잡도임) 8 | 9 | 이런 O(nlgn)을 줄일 수 있는 방법은 Comparison을 하지 않는 것 10 | 11 | 12 | 13 | #### Radix sort 14 | 15 | ---- 16 | 17 | 데이터를 구성하는 기본 요소 (Radix) 를 이용하여 정렬을 진행하는 방식 18 | 19 | > 입력 데이터의 최대값에 따라서 Counting Sort의 비효율성을 개선하기 위해서, Radix Sort를 사용할 수 있음. 20 | > 21 | > 자릿수의 값 별로 (예) 둘째 자리, 첫째 자리) 정렬을 하므로, 나올 수 있는 값의 최대 사이즈는 9임 (범위 : 0 ~ 9) 22 | 23 | * 시간 복잡도 : O(d * (n + b)) 24 | 25 | -> d는 정렬할 숫자의 자릿수, b는 10 (k와 같으나 10으로 고정되어 있다.) 26 | 27 | ( Counting Sort의 경우 : O(n + k) 로 배열의 최댓값 k에 영향을 받음 ) 28 | 29 | * 장점 : 문자열, 정수 정렬 가능 30 | 31 | * 단점 : 자릿수가 없는 것은 정렬할 수 없음. (부동 소숫점) 32 | 33 | 중간 결과를 저장할 bucket 공간이 필요함. 34 | 35 | #### 소스 코드 36 | 37 | ```c 38 | void countSort(int arr[], int n, int exp) { 39 | int buffer[n]; 40 | int i, count[10] = {0}; 41 | 42 | // exp의 자릿수에 해당하는 count 증가 43 | for (i = 0; i < n; i++){ 44 | count[(arr[i] / exp) % 10]++; 45 | } 46 | // 누적합 구하기 47 | for (i = 1; i < 10; i++) { 48 | count[i] += count[i - 1]; 49 | } 50 | // 일반적인 Counting sort 과정 51 | for (i = n - 1; i >= 0; i--) { 52 | buffer[count[(arr[i]/exp) % 10] - 1] = arr[i]; 53 | count[(arr[i] / exp) % 10]--; 54 | } 55 | for (i = 0; i < n; i++){ 56 | arr[i] = buffer[i]; 57 | } 58 | } 59 | 60 | void radixsort(int arr[], int n) { 61 | // 최댓값 자리만큼 돌기 62 | int m = getMax(arr, n); 63 | 64 | // 최댓값을 나눴을 때, 0이 나오면 모든 숫자가 exp의 아래 65 | for (int exp = 1; m / exp > 0; exp *= 10) { 66 | countSort(arr, n, exp); 67 | } 68 | } 69 | int main() { 70 | int arr[] = {170, 45, 75, 90, 802, 24, 2, 66}; 71 | int n = sizeof(arr) / sizeof(arr[0]); // 좋은 습관 72 | radixsort(arr, n); 73 | 74 | for (int i = 0; i < n; i++){ 75 | cout << arr[i] << " "; 76 | } 77 | return 0; 78 | } 79 | ``` 80 | 81 | 82 | 83 | #### 질문 84 | 85 | --- 86 | 87 | Q1) 왜 낮은 자리수부터 정렬을 합니까? 88 | 89 | MSD (Most-Significant-Digit) 과 LSD (Least-Significant-Digit)을 비교하라는 질문 90 | 91 | MSD는 가장 큰 자리수부터 Counting sort 하는 것을 의미하고, LSD는 가장 낮은 자리수부터 Counting sort 하는 것을 의미함. (즉, 둘 다 할 수 있음) 92 | 93 | * LSD의 경우 1600000 과 1을 비교할 때, Digit의 갯수만큼 따져야하는 단점이 있음. 94 | 그에 반해 MSD는 마지막 자리수까지 확인해 볼 필요가 없음. 95 | * LSD는 중간에 정렬 결과를 알 수 없음. (예) 10004와 70002의 비교) 96 | 반면, MSD는 중간에 중요한 숫자를 알 수 있음. 따라서 시간을 줄일 수 있음. 그러나, 정렬이 되었는지 확인하는 과정이 필요하고, 이 때문에 메모리를 더 사용 97 | * LSD는 알고리즘이 일관됨 (Branch Free algorithm) 98 | 그러나 MSD는 일관되지 못함. --> 따라서 Radix sort는 주로 LSD를 언급함. 99 | * LSD는 자릿수가 정해진 경우 좀 더 빠를 수 있음. -------------------------------------------------------------------------------- /Algorithm/code/Heap.java: -------------------------------------------------------------------------------- 1 | public class Heap { 2 | 3 | static int N, heapSize; 4 | static int[] arr; 5 | 6 | static void init(int n) { 7 | N = n; 8 | arr = new int[N+1]; 9 | heapSize = 0; 10 | } 11 | 12 | static void add(int n) { 13 | arr[++heapSize] = n; 14 | 15 | for (int i = heapSize; i > 1; i/=2) { 16 | if(arr[i] < arr[i/2]) { 17 | swap(i/2, i); 18 | } 19 | else break; 20 | } 21 | } 22 | static int remove(int[] arr) { 23 | if(heapSize == 0) return 0; 24 | 25 | int rm = arr[1]; 26 | arr[1] = arr[heapSize]; 27 | arr[heapSize--] = 0; 28 | 29 | for (int i = 1; i*2 <= heapSize;) { 30 | 31 | if(i*2+1 <= heapSize) { 32 | 33 | if(arr[i] < arr[i*2] && arr[i] < arr[i*2+1]) break; 34 | 35 | else if(arr[i*2] < arr[i*2+1]) { 36 | swap(i, i*2); 37 | i = i*2; 38 | } 39 | else { 40 | swap(i, i*2+1); 41 | i = i*2+1; 42 | } 43 | } 44 | else { 45 | if(arr[i] > arr[i*2]) { 46 | swap(i, i*2); 47 | i = i*2; 48 | } 49 | else 50 | break; 51 | } 52 | } 53 | 54 | return rm; 55 | } 56 | 57 | static void swap(int a, int b) { 58 | int temp = arr[a]; 59 | arr[a] = arr[b]; 60 | arr[b] = temp; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Algorithm/code/InsertionSort.java: -------------------------------------------------------------------------------- 1 | public class InsertionSort { 2 | 3 | static int[] arr = {10, 2, 6, 4, 3, 7, 5}; 4 | 5 | public static void insertionSort(int[] arr) { 6 | for(int i = 1; i < arr.length; i++) { 7 | int num = arr[i]; // 기준 8 | int aux = i - 1; // 비교대상 9 | 10 | while(aux >= 0 && num < arr[aux]) { 11 | arr[aux+1] = arr[aux]; 12 | aux--; 13 | } 14 | arr[aux+1] = num; 15 | } 16 | } 17 | 18 | public static void main(String[] args) { 19 | 20 | insertionSort(arr); 21 | System.out.println(Arrays.toString(arr)); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Algorithm/code/QuickSort.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | 3 | public class QuickSort { 4 | 5 | static int[] arr = {5, 1, 1, 2, 1, 4, 4, 4, 5, 5}; 6 | 7 | public static void main(String[] args) throws Exception { 8 | 9 | quickSort(arr, 0, arr.length-1); 10 | 11 | System.out.println(Arrays.toString(arr)); 12 | 13 | } 14 | 15 | public static void quickSort(int[] arr, int start, int end) { 16 | 17 | if(start >= end) return; 18 | 19 | if(start < end) { 20 | 21 | int i = start-1; 22 | int j = end+1; 23 | int pivot = arr[(start+end)/2]; 24 | 25 | while(i < j) { 26 | 27 | while(arr[++i] < pivot) {} 28 | while(arr[--j] > pivot) {} 29 | 30 | if (i >= j) break; 31 | 32 | int temp = arr[i]; 33 | arr[i] = arr[j]; 34 | arr[j] = temp; 35 | } 36 | 37 | quickSort(arr, start, i-1); 38 | quickSort(arr, j+1, end); 39 | } 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Algorithm/code/bubbleSort.java: -------------------------------------------------------------------------------- 1 | void bubbleSort(int[] arr) { 2 | int temp = 0; 3 | for(int i = 0; i < arr.length; i++) { 4 | for(int j= 1 ; j < arr.length-i; j++) { 5 | if(arr[j-1] > arr[j]) { 6 | temp = arr[j-1]; 7 | arr[j-1] = arr[j]; 8 | arr[j] = temp; 9 | } 10 | } 11 | } 12 | System.out.println(Arrays.toString(arr)); 13 | } 14 | -------------------------------------------------------------------------------- /Algorithm/code/mergeSort.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.Random; 3 | 4 | public class mergeSort { 5 | // SIZE 십 만 6 | static int MAX_LEN = 100_000; 7 | 8 | public static void main(String[] args) { 9 | 10 | Random r = new Random(100); 11 | int merge_idx, collections_idx; 12 | int arr_merge[], arr_collections[]; 13 | 14 | merge_idx = 0; 15 | collections_idx = 0; 16 | arr_merge = new int[MAX_LEN]; 17 | arr_collections = new int[MAX_LEN]; 18 | 19 | // 랜덤으로 배열을 생성하는 부분 20 | for (int i = 0; i < MAX_LEN; i++) { 21 | int temp = (r.nextInt() % 10000); 22 | arr_merge[merge_idx++] = temp; 23 | arr_collections[collections_idx++] = temp; 24 | } 25 | 26 | Arrays.sort(arr_collections); 27 | mergeSort(arr_merge, 0, MAX_LEN - 1); 28 | 29 | // 정렬이 제대로 되었는지 확인하는 부분. 30 | for (int i = 0; i < MAX_LEN; i++) { 31 | if (arr_collections[i] != arr_merge[i]) { 32 | System.out.println("MergeSort 실패!"); 33 | return; 34 | } 35 | } 36 | System.out.println("MergeSort 성공"); 37 | return; 38 | } 39 | 40 | private static void mergeSort(int[] arr, int left, int right) { 41 | 42 | // (1) 재귀 호출을 통해 더이상 쪼개지지 않을 때까지 쪼개야 된다. 43 | if (left >= right) 44 | return; 45 | 46 | int mid = (left + right) / 2; 47 | int i = left; 48 | int j = mid+1; 49 | 50 | mergeSort(arr, left, mid); 51 | mergeSort(arr, mid+1, right); 52 | 53 | // (2) 배열을 인덱스를 통해서 절반으로 쪼개고, 한쪽이 다 쓸 때까지 반복문을 돌린다. 54 | int[] buffer = new int[right - left + 1]; 55 | int bidx = 0; 56 | 57 | // 왼쪽이랑 오른쪽 각각 비교 58 | while (true) { 59 | if(arr[i] <= arr[j]) { // stable 60 | buffer[bidx++] = arr[i]; 61 | i++; 62 | } else { 63 | buffer[bidx++] = arr[j]; 64 | j++; 65 | } 66 | 67 | if(i > mid || j > right) 68 | break; 69 | } 70 | 71 | // (3) 남은 것(오른쪽 or 왼쪽)을 전부 buffer에 넣어야 한다. 72 | // 왼쪽 전부 써버리기 73 | while(i <= mid) { 74 | buffer[bidx++] = arr[i++]; 75 | } 76 | //오른쪽 전부 써버리기 77 | while(j <= right) { 78 | buffer[bidx++] = arr[j++]; 79 | } 80 | 81 | // (4) buffer에 있는 것을 기존 배열의 인덱스 위에 덮어준다. 82 | for (int k = 0; k < bidx; k++) { 83 | arr[left+k] = buffer[k]; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Algorithm/professional/프로 준비법.md: -------------------------------------------------------------------------------- 1 | # 프로 준비법 2 | 3 |
4 | 5 | #### Professional 시험 주요 특징 6 | 7 | - 4시간동안 1문제를 푼다. 8 | - 언어는 `c, cpp, java`로 가능하다. 9 | - 라이브러리를 사용할 수 없으며, 직접 자료구조를 구현해야한다. (`malloc.h`만 가능) 10 | - 전체적인 로직은 구현이 되어있는 상태이며, 사용자가 구현해야 할 메소드 부분이 빈칸으로 제공된다. (`main.cpp`와 `user.cpp`가 주어지며, 우리는 `user.cpp`를 구현하면 된다) 11 | - 시험 유형 2가지 12 | - 1) 내부 테스트케이스를 제한 메모리, 시간 내에 해결해야한다. (50개 3초, 메모리 256MB 이내) 13 | - 2) 주어진 쿼리 함수를 최소한으로 호출하여 문제를 해결해야 한다. 14 | - 주로 샘플 테스트케이스는 5개가 주어지며, 이를 활용해 디버깅을 해볼 수 있다. 15 | - 시험장에서는 Reference Code가 주어지며 사용할 수 있다. (자료구조, 알고리즘) 16 | 17 |
18 | 19 | #### 핵심 자료구조 20 | 21 | - Queue, Stack 22 | - Sort 23 | - Linked List 24 | - Hash 25 | - Heap 26 | - Binary Search 27 | 28 |
29 | 30 | ### 학습 시작 31 | 32 | --- 33 | 34 | #### 1) Visual Studio 설정하기 35 | 36 | 1. Visual C++ 빈 프로젝트 생성 37 | 38 | 2. `user.cpp`와 `main.cpp` 생성 39 | 40 | 3. 프로젝트명 오른쪽 마우스 클릭 → 속성 41 | 42 | 4. `C/C++`에서 SDL 검사 아니요로 변경 43 | 44 | > 디버깅할 때 scanf나 printf를 사용하기 위함 45 | 46 | 5. `링커/시스템`에서 맨위 `하위 시스템`이 공란이면 `콘솔(/SUBSYSTEM:CONSOLE)`로 설정 47 | 48 | > 공란이면 run할 때 콘솔창이 켜있는 상태로 유지가 되지 않음 (반드시 설정) 49 | 50 |
51 | 52 | #### 2) cpp로 프로 문제 풀 때 알아야 할 것 53 | 54 | - printf로 출력 확인해보기 위한 라이브러리 : `#include `. 제출시에는 꼭 지우기 55 | 56 | - 구조체 : `struct` 57 | 58 | - 포인터 : 주소값 활용 59 | 60 | - 문자열 61 | 62 | > 문자열의 맨 마지막에는 항상 `'\0'`로 끝나야한다. 63 | 64 | - 문자열 복사 (a에 b를 복사) 65 | 66 | ```cpp 67 | char a[5]; 68 | char b[5] = {'a', 'b', 'c', 'd', '\0'}; 69 | 70 | void strcopy(char *a, char *b) { 71 | while(*a++ = *b++); 72 | } 73 | 74 | int main(void) { 75 | strcopy(a, b); // a 배열에 b의 'abcd'가 저장됌 76 | } 77 | ``` 78 | 79 | - 문자열 비교 80 | 81 | ```cpp 82 | char a[5] = {'b', 'b', 'c', 'd', '\0'}; 83 | char b[5] = {'a', 'b', 'c', 'd', '\0'}; 84 | 85 | int strcompare(char *a, char *b) { 86 | int i; 87 | for(i = 0; a[i] && a[i] == b[i]; ++i); 88 | 89 | return a[i] - b[i]; 90 | } 91 | 92 | int main(void) { 93 | int res = strcompare(a, b); // a가 b보다 작으면 음수, 크면 양수, 같으면 0 94 | } 95 | ``` 96 | 97 | - 문자열 초기화 98 | 99 | > 특수히 중간에 초기화가 필요할 때만 사용 100 | 101 | ```cpp 102 | void strnull(char *a) { 103 | *a = 0; 104 | } 105 | ``` -------------------------------------------------------------------------------- /Algorithm/간단하지만 알면 좋은 최적화들.md: -------------------------------------------------------------------------------- 1 | ## [알고리즘] 간단하지만 알면 좋은 최적화들 2 | 3 | **1. for문의 ++i와 i++ 차이** 4 | 5 | ``` 6 | for(int i = 0; i < 1000; i++) { ... } 7 | 8 | for(int i = 0; i < 1000; ++i) { ... } 9 | ``` 10 | 11 | 내부 operator 로직을 보면 i++은 한번더 연산을 거친다. 12 | 13 | 따라서 ++i가 미세하게 조금더 빠르다. 14 | 15 | 하지만 요즘 컴파일러는 거의 차이가 없어지게 되었다고 한다. 16 | 17 | 18 | 19 | **2. if/else if vs switch case** 20 | 21 | > '20개의 가지 수, 10억번의 연산이 진행되면?' 22 | 23 | if/else 활용 : 약 20초 24 | 25 | switch case : 약 15초 26 | 27 | 28 | 29 | **switch case**가 더 빠르다. (경우를 찾아서 접근하기 때문에 더 빠르다) 30 | 31 | if-else 같은 경우는 다 타고 들어가야하기 때문에 더 느리다. 32 | 33 | 34 | 35 | **3. for문 안에서 변수 선언 vs for문 밖에서 변수 선언** 36 | 37 | 임시 변수의 선언 위치에 따른 비교다. 38 | 39 | for문 밖에서 변수를 선언하는 것이 더 빠르다. 40 | 41 | 42 | 43 | 44 | 45 | **4. 재귀함수 파라미터를 전역으로 선언한 것 vs 재귀함수를 모두 파라미터로 넘겨준 것** 46 | 47 | > '10억번의 연산을 했을 때?' 48 | 49 | 전역으로 선언 : 약 6.8초 50 | 51 | 파라미터로 넘겨준 것 : 약 9.6초 52 | 53 | 54 | 55 | 함수를 계속해서 호출할 때, 스택에서 쌓인다. 파라미터들은 함수를 호출할 때마다 메모리 할당하는 동작을 반복하게 된다. 따라서 지역 변수로 사용하지 않는 것들은 전역 변수로 빼야한다. -------------------------------------------------------------------------------- /Algorithm/다익스트라(Dijkstra).md: -------------------------------------------------------------------------------- 1 | # 다익스트라(Dijkstra) 알고리즘 2 | 3 |
4 | 5 | ``` 6 | DP를 활용한 최단 경로 탐색 알고리즘 7 | ``` 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 다익스트라 알고리즘은 특정한 정점에서 다른 모든 정점으로 가는 최단 경로를 기록한다. 18 | 19 | 여기서 DP가 적용되는 이유는, 굳이 한 번 최단 거리를 구한 곳은 다시 구할 필요가 없기 때문이다. 이를 활용해 정점에서 정점까지 간선을 따라 이동할 때 최단 거리를 효율적으로 구할 수 있다. 20 | 21 |
22 | 23 | 다익스트라를 구현하기 위해 두 가지를 저장해야 한다. 24 | 25 | - 해당 정점까지의 최단 거리를 저장 26 | 27 | - 정점을 방문했는 지 저장 28 | 29 | 시작 정점으로부터 정점들의 최단 거리를 저장하는 배열과, 방문 여부를 저장하는 것이다. 30 | 31 |
32 | 33 | 다익스트라의 알고리즘 순서는 아래와 같다. 34 | 35 | 1. ##### 최단 거리 값은 무한대 값으로 초기화한다. 36 | 37 | ```java 38 | for(int i = 1; i <= n; i++){ 39 | distance[i] = Integer.MAX_VALUE; 40 | } 41 | ``` 42 | 43 | 2. ##### 시작 정점의 최단 거리는 0이다. 그리고 시작 정점을 방문 처리한다. 44 | 45 | ```java 46 | distance[start] = 0; 47 | visited[start] = true; 48 | ``` 49 | 50 | 3. ##### 시작 정점과 연결된 정점들의 최단 거리 값을 갱신한다. 51 | 52 | ```java 53 | for(int i = 1; i <= n; i++){ 54 | if(!visited[i] && map[start][i] != 0) { 55 | distance[i] = map[start][i]; 56 | } 57 | } 58 | ``` 59 | 60 | 4. ##### 방문하지 않은 정점 중 최단 거리가 최소인 정점을 찾는다. 61 | 62 | ```java 63 | int min = Integer.MAX_VALUE; 64 | int midx = -1; 65 | 66 | for(int i = 1; i <= n; i++){ 67 | if(!visited[i] && distance[i] != Integer.MAX_VALUE) { 68 | if(distance[i] < min) { 69 | min = distance[i]; 70 | midx = i; 71 | } 72 | } 73 | } 74 | ``` 75 | 76 | 5. ##### 찾은 정점을 방문 체크로 변경 후, 해당 정점과 연결된 방문하지 않은 정점의 최단 거리 값을 갱신한다. 77 | 78 | ```java 79 | visited[midx] = true; 80 | for(int i = 1; i <= n; i++){ 81 | if(!visited[i] && map[midx][i] != 0) { 82 | if(distance[i] > distance[midx] + map[midx][i]) { 83 | distance[i] = distance[midx] + map[midx][i]; 84 | } 85 | } 86 | } 87 | ``` 88 | 89 | 6. ##### 모든 정점을 방문할 때까지 4~5번을 반복한다. 90 | 91 |
92 | 93 | #### 다익스트라 적용 시 알아야할 점 94 | 95 | - 인접 행렬로 구현하면 시간 복잡도는 O(N^2)이다. 96 | 97 | - 인접 리스트로 구현하면 시간 복잡도는 O(N*logN)이다. 98 | 99 | > 선형 탐색으로 시간 초과가 나는 문제는 인접 리스트로 접근해야한다. (우선순위 큐) 100 | 101 | - 간선의 값이 양수일 때만 가능하다. 102 | 103 |
104 | 105 |
106 | 107 | #### [참고사항] 108 | 109 | - [링크](https://ko.wikipedia.org/wiki/%EB%8D%B0%EC%9D%B4%ED%81%AC%EC%8A%A4%ED%8A%B8%EB%9D%BC_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98) 110 | - [링크](https://bumbums.tistory.com/4) -------------------------------------------------------------------------------- /Algorithm/동적 계획법 (Dynamic Programming).md: -------------------------------------------------------------------------------- 1 | ## 동적 계획법 (Dynamic Programming) 2 | 3 | > 복잡한 문제를 간단한 여러 개의 문제로 나누어 푸는 방법 4 | 5 |
6 | 7 | 흔히 말하는 DP가 바로 '동적 계획법' 8 | 9 | **한 가지 문제**에 대해서, **단 한 번만 풀도록** 만들어주는 알고리즘이다. 10 | 11 | 즉, 똑같은 연산을 반복하지 않도록 만들어준다. 실행 시간을 줄이기 위해 많이 이용되는 수학적 접근 방식의 알고리즘이라고 할 수 있다. 12 | 13 |
14 | 15 | 동적 계획법은 **Optimal Substructure**에서 효과를 발휘한다. 16 | 17 | *Optimal Substructure* : 답을 구하기 위해 이미 했던 똑같은 계산을 계속 반복하는 문제 구조 18 | 19 |
20 | 21 | #### 접근 방식 22 | 23 | 커다란 문제를 쉽게 해결하기 위해 작게 쪼개서 해결하는 방법인 분할 정복과 매우 유사하다. 하지만 간단한 문제로 만드는 과정에서 중복 여부에 대한 차이점이 존재한다. 24 | 25 | 즉, 동적 계획법은 간단한 작은 문제들 속에서 '계속 반복되는 연산'을 활용하여 빠르게 풀 수 있는 것이 핵심이다. 26 | 27 |
28 | 29 | #### 조건 30 | 31 | - 작은 문제에서 반복이 일어남 32 | - 같은 문제는 항상 정답이 같음 33 | 34 | 이 두 가지 조건이 충족한다면, 동적 계획법을 이용하여 문제를 풀 수 있다. 35 | 36 | 같은 문제가 항상 정답이 같고, 반복적으로 일어난다는 점을 활용해 메모이제이션(Memoization)으로 큰 문제를 해결해나가는 것이다. 37 | 38 |
39 | 40 | *메모이제이션(Memoization)* : 한 번 계산한 문제는 다시 계산하지 않도록 저장해두고 활용하는 방식 41 | 42 | > 피보나치 수열에서 재귀를 활용하여 풀 경우, 같은 연산을 계속 반복함을 알 수 있다. 43 | > 44 | > 이때, 메모이제이션을 통해 같은 작업을 되풀이 하지 않도록 구현하면 효율적이다. 45 | 46 | ``` 47 | fibonacci(5) = fibonacci(4) + fibonacci(3) 48 | fibonacci(4) = fibonacci(3) + fibonacci(2) 49 | fibonacci(3) = fibonacci(2) + fibonacci(1) 50 | 51 | 이처럼 같은 연산이 계속 반복적으로 이용될 때, 메모이제이션을 활용하여 값을 미리 저장해두면 효율적 52 | ``` 53 | 54 | 피보나치 구현에 재귀를 활용했다면 시간복잡도는 O(2^n)이지만, 동적 계획법을 활용하면 O(N)으로 해결할 수 있다. 55 | 56 |
57 | 58 | #### 구현 방식 59 | 60 | - Bottom-up : 작은 문제부터 차근차근 구하는 방법 61 | - Top-down : 큰 문제를 풀다가 풀리지 않은 작은 문제가 있다면 그때 해결하는 방법 (재귀 방식) 62 | 63 | > Bottom-up은 해결이 용이하지만, 가독성이 떨어짐 64 | > 65 | > Top-down은 가독성이 좋지만, 코드 작성이 힘듬 66 | 67 |
68 | 69 | 동적 계획법으로 문제를 풀 때는, 우선 작은 문제부터 해결해나가보는 것이 좋다. 70 | 71 | 작은 문제들을 풀어나가다보면 이전에 구해둔 더 작은 문제들이 활용되는 것을 확인하게 된다. 이에 대한 규칙을 찾았을 때 **점화식**을 도출해내어 동적 계획법을 적용시키자 72 | 73 |
74 | 75 |
76 | 77 | ##### [참고 자료] 78 | 79 | - [링크](https://namu.wiki/w/%EB%8F%99%EC%A0%81%20%EA%B3%84%ED%9A%8D%EB%B2%95) -------------------------------------------------------------------------------- /Algorithm/순열 & 조합.md: -------------------------------------------------------------------------------- 1 | # 순열 & 조합 2 | 3 |
4 | 5 | ### Java 코드 6 | 7 | ```java 8 | import java.util.ArrayList; 9 | import java.util.Arrays; 10 | 11 | public class 순열조합 { 12 | static char[] arr = { 'a', 'b', 'c', 'd' }; 13 | static int r = 2; 14 | 15 | //arr배열에서 r개를 선택한다. 16 | //선택된 요소들은 set배열에 저장. 17 | public static void main(String[] args) { 18 | 19 | set = new char[r]; 20 | 21 | System.out.println("==조합=="); 22 | comb(0,0); 23 | 24 | System.out.println("==중복조합=="); 25 | rcomb(0, 0); 26 | 27 | visit = new boolean[arr.length]; 28 | System.out.println("==순열=="); 29 | perm(0); 30 | 31 | System.out.println("==중복순열=="); 32 | rperm(0); 33 | 34 | System.out.println("==부분집합=="); 35 | setList = new ArrayList<>(); 36 | subset(0,0); 37 | } 38 | 39 | static char[] set; 40 | 41 | public static void comb(int len, int k) { // 조합 42 | if (len == r) { 43 | System.out.println(Arrays.toString(set)); 44 | return; 45 | } 46 | if (k == arr.length) 47 | return; 48 | 49 | set[len] = arr[k]; 50 | 51 | comb(len + 1, k + 1); 52 | comb(len, k + 1); 53 | 54 | } 55 | 56 | public static void rcomb(int len, int k) { // 중복조합 57 | if (len == r) { 58 | System.out.println(Arrays.toString(set)); 59 | return; 60 | } 61 | if (k == arr.length) 62 | return; 63 | 64 | set[len] = arr[k]; 65 | 66 | rcomb(len + 1, k); 67 | rcomb(len, k + 1); 68 | 69 | } 70 | 71 | static boolean[] visit; 72 | 73 | public static void perm(int len) {// 순열 74 | if (len == r) { 75 | System.out.println(Arrays.toString(set)); 76 | return; 77 | } 78 | 79 | for (int i = 0; i < arr.length; i++) { 80 | if (!visit[i]) { 81 | set[len] = arr[i]; 82 | visit[i] = true; 83 | perm(len + 1); 84 | visit[i] = false; 85 | } 86 | } 87 | } 88 | 89 | public static void rperm(int len) {// 중복순열 90 | if (len == r) { 91 | System.out.println(Arrays.toString(set)); 92 | return; 93 | } 94 | 95 | for (int i = 0; i < arr.length; i++) { 96 | set[len] = arr[i]; 97 | rperm(len + 1); 98 | } 99 | } 100 | 101 | static ArrayList setList; 102 | 103 | public static void subset(int len, int k) {// 부분집합 104 | System.out.println(setList); 105 | if (len == arr.length) { 106 | return; 107 | } 108 | for (int i = k; i < arr.length; i++) { 109 | setList.add(arr[i]); 110 | subset(len + 1, i + 1); 111 | setList.remove(setList.size() - 1); 112 | } 113 | } 114 | } 115 | ``` 116 | 117 | -------------------------------------------------------------------------------- /Algorithm/최대공약수 & 최소공배수.md: -------------------------------------------------------------------------------- 1 | ### [알고리즘] 최대공약수 & 최소공배수 2 | 3 | --- 4 | 5 | 면접 손코딩으로 출제가 많이 되는 유형 - 초등학교 때 배운 최대공약수와 최소공배수를 구현하기 6 | 7 | 최대 공약수는 `유클리드 공식`을 통해 쉽게 도출해낼 수 있다. 8 | 9 | ex) 24와 18의 최대공약수는? 10 | 11 | ##### 유클리드 호제법을 활용하자! 12 | 13 | > 주어진 값에서 큰 값 % 작은 값으로 나머지를 구한다. 14 | > 15 | > 나머지가 0이 아니면, 작은 값 % 나머지 값을 재귀함수로 계속 진행 16 | > 17 | > 나머지가 0이 되면, 그때의 작은 값이 '최대공약수'이다. 18 | > 19 | > **최소 공배수**는 간단하다. 주어진 값들끼리 곱한 값을 '최대공약수'로 나누면 끝! 20 | 21 | ```java 22 | public static void main(String[] args) { 23 | int a = 24; int b = 18; 24 | int res = gcd(a,b); 25 | System.out.println("최대공약수 : " + res); 26 | System.out.println("최소공배수 : " + (a*b)/res); // a*b를 최대공약수로 나눈다 27 | } 28 | 29 | public static int gcd(int a, int b) { // 최대공약수 30 | 31 | if(a < b) swap(a,b)// b가 더 크면 swap 32 | 33 | int num = a%b; 34 | if(num == 0) return b; 35 | 36 | return gcd(b, num); 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /Computer Science/Computer Architecture/ARM 프로세서.md: -------------------------------------------------------------------------------- 1 | ## ARM 프로세서 2 | 3 |
4 | 5 | *프로세서란?* 6 | 7 | > 메모리에 저장된 명령어들을 실행하는 유한 상태 오토마톤 8 | 9 |
10 | 11 | ##### ARM : Advanced RISC Machine 12 | 13 | 즉, `진보된 RISC 기기`의 약자로 ARM의 핵심은 RISC이다. 14 | 15 | RISC : Reduced Instruction Set Computing (감소된 명령 집합 컴퓨팅) 16 | 17 | `단순한 명령 집합을 가진 프로세서`가 `복잡한 명령 집합을 가진 프로세서`보다 훨씬 더 효율적이지 않을까?로 탄생함 18 | 19 |
20 | 21 |
22 | 23 | #### ARM 구조 24 | 25 | --- 26 | 27 | 28 | 29 |
30 | 31 | ARM은 칩의 기본 설계 구조만 만들고, 실제 기능 추가와 최적화 부분은 개별 반도체 제조사의 영역으로 맡긴다. 따라서 물리적 설계는 같아도, 명령 집합이 모두 다르기 때문에 서로 다른 칩이 되기도 하는 것이 ARM. 32 | 33 | 소비자에게는 칩이 논리적 구조인 명령 집합으로 구성되면서, 이런 특성 때문에 물리적 설계 베이스는 같지만 용도에 따라 다양한 제품군을 만날 수 있는 특징이 있다. 34 | 35 | 아무래도 아키텍처는 논리적인 명령 집합을 물리적으로 표현한 것이므로, 명령어가 많고 복잡해질수록 실제 물리적인 칩 구조도 크고 복잡해진다. 36 | 37 | 하지만, ARM은 RISC 설계 기반으로 '단순한 명령집합을 가진 프로세서가 복잡한 것보다 효율적'임을 기반하기 때문에 명령 집합과 구조 자체가 단순하다. 따라서 ARM 기반 프로세서가 더 작고, 효율적이며 상대적으로 느린 것이다. 38 | 39 |
40 | 41 | 단순한 명령 집합은, 적은 수의 트랜지스터만 필요하므로 간결한 설계와 더 작은 크기를 가능케 한다. 반도체 기본 부품인 트랜지스터는 전원을 소비해 다이의 크기를 증가시키기 때문에 스마트폰이나 태블릿PC를 위한 프로세서에는 가능한 적은 트랜지스터를 가진 것이 이상적이다. 42 | 43 | 따라서, 명령 집합의 수가 적기 때문에 트랜지스터 수가 적고 이를 통해 크기가 작고 전원 소모가 낮은 ARM CPU가 스마트폰, 태블릿PC와 같은 모바일 기기에 많이 사용되고 있다. 44 | 45 |
46 | 47 |
48 | 49 | #### ARM의 장점은? 50 | 51 | --- 52 | 53 | 54 | 55 |
56 | 57 | 소비자에 있어 ARM은 '생태계'의 하나라고 생각할 수 있다. ARM을 위해 개발된 프로그램은 오직 ARM 프로세서가 탑재된 기기에서만 실행할 수 있다. (즉, x86 CPU 프로세서 기반 프로그램에서는 ARM 기반 기기에서 실행할 수 없음) 58 | 59 | 따라서 ARM에서 실행되던 프로그램을 x86 프로세서에서 실행되도록 하려면 (혹은 그 반대로) 프로그램에 수정이 가해져야만 한다. 60 | 61 |
62 | 63 | 하지만, 하나의 ARM 기기에 동작하는 OS는 다른 ARM 기반 기기에서도 잘 동작한다. 이러한 장점 덕분에 수많은 버전의 안드로이드가 탄생하고 있으며 또한 HP나 블랙베리의 태블릿에도 안드로이드가 탑재될 수 있는 가능성이 생기게 된 것이다. 64 | 65 | (하지만 애플사는 iOS 소스코드를 공개하지 않고 있기 때문에 애플 기기는 불가능하다) 66 | 67 | ARM을 만드는 기업들은 전력 소모를 줄이고 성능을 높이기 위해 설계를 개선하며 노력하고 있다. 68 | 69 |
70 | 71 |
72 | 73 |
74 | 75 | ##### [참고 자료] 76 | 77 | - [링크](https://sergeswin.com/611) 78 | -------------------------------------------------------------------------------- /Computer Science/Computer Architecture/고정 소수점 & 부동 소수점.md: -------------------------------------------------------------------------------- 1 | ## 고정 소수점 & 부동 소수점 2 | 3 |
4 | 5 | 컴퓨터에서 실수를 표현하는 방법은 `고정 소수점`과 `부동 소수점` 두가지 방식이 존재한다. 6 | 7 |
8 | 9 | 1. #### 고정 소수점(Fixed Point) 10 | 11 | > 소수점이 찍힐 위치를 미리 정해놓고 소수를 표현하는 방식 (정수 + 소수) 12 | > 13 | > ``` 14 | > -3.141592는 부호(-)와 정수부(3), 소수부(0.141592) 3가지 요소 필요함 15 | > ``` 16 | 17 | ![고정 소수점 방식](http://tcpschool.com/lectures/img_c_fixed_point.png) 18 | 19 | **장점** : 실수를 정수부와 소수부로 표현하여 단순하다. 20 | 21 | **단점** : 표현의 범위가 너무 적어서 활용하기 힘들다. (정수부는 15bit, 소수부는 16bit) 22 | 23 |
24 | 25 |
26 | 27 | 2. #### 부동 소수점(Floating Point) 28 | 29 | > 실수를 가수부 + 지수부로 표현한다. 30 | > 31 | > - 가수 : 실수의 실제값 표현 32 | > - 지수 : 크기를 표현함. 가수의 어디쯤에 소수점이 있는지 나타냄 33 | 34 | **지수의 값에 따라 소수점이 움직이는 방식**을 활용한 실수 표현 방법이다. 35 | 36 | 즉, 소수점의 위치가 고정되어 있지 않는다. 37 | 38 | ![32비트 부동 소수점](http://tcpschool.com/lectures/img_c_floating_point_32.png) 39 | 40 | **장점** : 표현할 수 있는 수의 범위가 넓어진다. (현재 대부분 시스템에서 활용 중) 41 | 42 | **단점** : 오차가 발생할 수 있다. (부동소수점으로 표현할 수 있는 방법이 매우 다양함) 43 | 44 |
45 | 46 |
47 | 48 | 3. #### 고정 소수점과 부동 소수점의 일반적인 사용 사례. 49 | 50 | **고정 소수점 사용 상황.** 51 | 1. 임베디드 시스켐과 마이크로컨트롤러 52 | - 메모리와 처리 능력이 제한된 환경에서 고정 소수점 연산이 일반적입니다. 이는 부동 소수점 연산을 지원하는 하드웨어가 없거나, 그러한 연산이 배터리 수명이나 다른 자원을 과도하게 소모할 수 있기 때문입니다. 53 | 54 | 2. 실시간 시스템 55 | - 예측 가능한 실행 시간이 중요한 실시간 응용 프로그램에서는 고정 소수점 연산이 선호됩니다. 이는 부동 소수점 연산이 가변적인 실행 시간을 가질 수 있기 때문입니다. 56 | 57 | 3. 비용 민감형 하드웨어 58 | - 부동 소수점 연산자를 지원하는 비용이 더 들 수 있어, 가격을 낮추기 위해 고정 소수점 연산을 사용하는 경우가 있습니다. 59 | 60 | 4. 디지털 신호 처리(DSP) 61 | - 일부 디지털 신호 처리 알고리즘은 정확하게 정의된 범위 내의 값을 사용하기 때문에 고정 소수점 연산으로 충분한 경우가 많습니다. 62 | 63 | **부동 소수점 사용 상황.** 64 | 1. 과학적 계산 65 | - 넓은 범위의 값과 높은 정밀도가 요구되는 과학적 및 엔지니어링 계산에는 부동 소수점이 사용됩니다. 66 | 67 | 2. 3D 그래픽스 68 | - 3D 모델링과 같은 그래픽 작업에서는 부동 소수점 연산이 광범위하게 사용되며, 높은 정밀도와 다양한 크기의 값을 처리할 수 있어야 합니다. 69 | 70 | 3. 금융 분석 71 | - 복잡한 금융 모델링과 위험 평가에서는 높은 수준의 정밀도가 필요할 수 있으며, 부동 소수점 연산이 적합할 수 있습니다. 72 | 73 | 4. 컴퓨터 시뮬레이션 74 | - 물리적 시스템의 시뮬레이션은 넓은 범위의 값과 높은 정밀도를 요구하기 때문에, 부동 소수점 연산이 필수적입니다. 75 | 76 | **결론.** 77 | - 고정 소수점은 주로 리소스가 제한적이고 높은 정밀도가 필요하지 않은 환경에서 사용됩니다. 78 | - 부동 소수점은 더 넓은 범위와 높은 정밀도를 필요로 하는 복잡한 계산에 적합합니다. 79 | - 현대 프로세서의 경우, 부동 소수점 연산의 속도도 매우 빨라져서 예전만큼 고정 소수점과 부동 소수점 사이의 성능 차이가 크지 않을 수 있습니다. 80 | -------------------------------------------------------------------------------- /Computer Science/Computer Architecture/명령어 Cycle.md: -------------------------------------------------------------------------------- 1 | ## 명령어 Cycle 2 | 3 | - PC : 다음 실행할 명령어의 주소를 저장 4 | - MAR : 다음에 읽거나 쓸 기억장소의 주소를 지정 5 | - MBR : 기억장치에 저장될 데이터 혹은 기억장치로부터 읽은 데이터를 임시 저장 6 | - IR : 현재 수행 중인 명령어 저장 7 | - ALU : 산술연산과 논리연산 수행 8 | 9 |
10 | 11 | #### Fetch Cycle 12 | 13 | --- 14 | 15 | > 명령어를 주기억장치에서 CPU 명령어 레지스터로 가져와 해독하는 단계 16 | 17 | 1) PC에 있는 명령어 주소를 MAR로 가져옴 (그 이후 PC는 +1) 18 | 19 | 2) MAR에 저장된 주소에 해당하는 값을 메모리에서 가져와서 MBR에 저장 20 | 21 | (이때 가져온 값은 Data 또는 Opcode(명령어)) 22 | 23 | 3) 만약 Opcode를 가져왔다면, IR에서 Decode하는 단계 거침 (명령어를 해석하여 Data로 만들어야 함) 24 | 25 | 4) 1~2과정에서 가져온 데이터를 ALU에서 수행 (Excute Cycle). 연산 결과는 MBR을 거쳐 메모리로 다시 저장 -------------------------------------------------------------------------------- /Computer Science/Computer Architecture/컴퓨터구조 기초.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/Computer Science/Computer Architecture/컴퓨터구조 기초.pdf -------------------------------------------------------------------------------- /Computer Science/Computer Architecture/패리티 비트 & 해밍 코드.md: -------------------------------------------------------------------------------- 1 | ## 패리티 비트 & 해밍 코드 2 | 3 |
4 | 5 | ### 패리티 비트 6 | 7 | > 정보 전달 과정에서 오류가 생겼는 지 검사하기 위해 추가하는 비트를 말한다. 8 | > 9 | > 전송하고자 하는 데이터의 각 문자에 1비트를 더하여 전송한다. 10 | 11 |
12 | 13 | **종류** : 짝수, 홀수 14 | 15 | 전체 비트에서 (짝수, 홀수)에 맞도록 비트를 정하는 것 16 | 17 |
18 | 19 | ***짝수 패리티일 때 7비트 데이터가 1010001라면?*** 20 | 21 | > 1이 총 3개이므로, 짝수로 맞춰주기 위해 1을 더해야 함 22 | > 23 | > 답 : 11010001 (맨앞이 패리티비트) 24 | 25 |
26 | 27 |
28 | 29 | ### 해밍 코드 30 | 31 | > 데이터 전송 시 1비트의 에러를 정정할 수 있는 자기 오류정정 코드를 말한다. 32 | > 33 | > 패리티비트를 보고, 1비트에 대한 오류를 정정할 곳을 찾아 수정할 수 있다. 34 | > (패리티 비트는 오류를 검출하기만 할 뿐 수정하지는 않기 때문에 해밍 코드를 활용) 35 | 36 |
37 | 38 | ##### 방법 39 | 40 | 2의 n승 번째 자리인 1,2,4번째 자릿수가 패리티 비트라는 것으로 부터 시작한다. 이 숫자로부터 시작하는 세개의 패리티 비트가 짝수인지, 홀수인지 기준으로 판별한다. 41 | 42 |
43 | 44 | ***짝수 패리티의 해밍 코드가 0011011일때 오류가 수정된 코드는?*** 45 | 46 | 1) 1, 3, 5, 7번째 비트 확인 : 0101로 짝수이므로 '0' 47 | 48 | 2) 2, 3, 6, 7번째 비트 확인 : 0111로 홀수이므로 '1' 49 | 50 | 3) 4, 5, 6, 7번째 비트 확인 : 1011로 홀수이므로 '1' 51 | 52 |
53 | 54 | 역순으로 패리티비트 '110'을 도출했다. 10진법으로 바꾸면 '6'으로, 6번째 비트를 수정하면 된다. 55 | 56 | 따라서 **정답은 00110'0'1**이다. -------------------------------------------------------------------------------- /Computer Science/Data Structure/Array vs ArrayList vs LinkedList.md: -------------------------------------------------------------------------------- 1 | ## Array vs ArrayList vs LinkedList 2 | 3 |
4 | 5 | 세 자료구조를 한 문장으로 정의하면 아래와 같이 말할 수 있다. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | - **Array**는 index로 빠르게 값을 찾는 것이 가능함 16 | - **LinkedList**는 데이터의 삽입 및 삭제가 빠름 17 | - **ArrayList**는 데이터를 찾는데 빠르지만, 삽입 및 삭제가 느림 18 | 19 |
20 | 21 | 좀 더 자세히 비교하면? 22 | 23 |
24 | 25 | 우선 배열(Array)는 **선언할 때 크기와 데이터 타입을 지정**해야 한다. 26 | 27 | ```java 28 | int arr[10]; 29 | String arr[5]; 30 | ``` 31 | 32 | 이처럼, **array**은 메모리 공간에 할당할 사이즈를 미리 정해놓고 사용하는 자료구조다. 33 | 34 | 따라서 계속 데이터가 늘어날 때, 최대 사이즈를 알 수 없을 때는 사용하기에 부적합하다. 35 | 36 | 또한 중간에 데이터를 삽입하거나 삭제할 때도 매우 비효율적이다. 37 | 38 | 4번째 index 값에 새로운 값을 넣어야 한다면? 원래값을 뒤로 밀어내고 해당 index에 덮어씌워야 한다. 기본적으로 사이즈를 정해놓은 배열에서는 해결하기엔 부적합한 점이 많다. 39 | 40 | 대신, 배열을 사용하면 index가 존재하기 때문에 위치를 바로 알 수 있어 검색에 편한 장점이 있다. 41 | 42 |
43 | 44 | 이를 해결하기 위해 나온 것이 **List**다. 45 | 46 | List는 array처럼 **크기를 정해주지 않아도 된다**. 대신 array에서 index가 중요했다면, List에서는 순서가 중요하다. 47 | 48 | 크기가 정해져있지 않기 때문에, 중간에 데이터를 추가하거나 삭제하더라도 array에서 갖고 있던 문제점을 해결 가능하다. index를 가지고 있으므로 검색도 빠르다. 49 | 50 | 하지만, 중간에 데이터를 추가 및 삭제할 때 시간이 오래걸리는 단점이 존재한다. (더하거나 뺄때마다 줄줄이 당겨지거나 밀려날 때 진행되는 연산이 추가, 메모리도 낭비..) 51 | 52 |
53 | 54 | 그렇다면 **LinkedList**는? 55 | 56 | 연결리스트에는 단일, 다중 등 여러가지가 존재한다. 57 | 58 | 종류가 무엇이든, **한 노드에 연결될 노드의 포인터 위치를 가리키는 방식**으로 되어있다. 59 | 60 | > 단일은 뒤에 노드만 가리키고, 다중은 앞뒤 노드를 모두 가리키는 차이 61 | 62 |
63 | 64 | 이런 방식을 활용하면서, 데이터의 중간에 삽입 및 삭제를 하더라도 전체를 돌지 않아도 이전 값과 다음값이 가르켰던 주소값만 수정하여 연결시켜주면 되기 때문에 빠르게 진행할 수 있다. 65 | 66 | 이렇게만 보면 가장 좋은 방법 같아보이지만, `List의 k번째 값을 찾아라`에서는 비효율적이다. 67 | 68 |
69 | 70 | array나 arrayList에서 index를 갖고 있기 때문에 검색이 빠르지만, LinkedList는 처음부터 살펴봐야하므로(순차) 검색에 있어서는 시간이 더 걸린다는 단점이 존재한다. 71 | 72 |
73 | 74 | 따라서 상황에 맞게 자료구조를 잘 선택해서 사용하는 것이 중요하다. -------------------------------------------------------------------------------- /Computer Science/Data Structure/B Tree & B+ Tree.md: -------------------------------------------------------------------------------- 1 | ## B Tree & B+ Tree 2 | 3 |
4 | 5 | > **이진 트리**는 하나의 부모가 두 개의 자식밖에 가지질 못하고, 균형이 맞지 않으면 검색 효율이 선형검색 급으로 떨어진다. 하지만 이진 트리 구조의 간결함과 균형만 맞다면 검색, 삽입, 삭제 모두 O(logN)의 성능을 보이는 장점이 있기 때문에 계속 개선시키기 위한 노력이 이루어지고 있다. 6 | 7 |
8 | 9 | #### B Tree 10 | 11 | --- 12 | 13 | 데이터베이스, 파일 시스템에서 널리 사용되는 트리 자료구조의 일종이다. 14 | 15 | 이진 트리를 확장해서, 더 많은 수의 자식을 가질 수 있게 일반화 시킨 것이 B-Tree 16 | 17 |
18 | 19 | 자식 수에 대한 일반화를 진행하면서, 하나의 레벨에 더 저장되는 것 뿐만 아니라 트리의 균형을 자동으로 맞춰주는 로직까지 갖추었다. 단순하고 효율적이며, 레벨로만 따지면 완전히 균형을 맞춘 트리다. 20 | 21 | ``` 22 | 대량의 데이터를 처리해야 할 때, 검색 구조의 경우 하나의 노드에 많은 데이터를 가질 수 있다는 점은 상당히 큰 장점이다. 23 | 24 | 대량의 데이터는 메모리보다 블럭 단위로 입출력하는 하드디스크 or SSD에 저장해야하기 때문! 25 | 26 | ex) 한 블럭이 1024 바이트면, 2바이트를 읽으나 1024바이트를 읽으나 똑같은 입출력 비용 발생. 따라서 하나의 노드를 모두 1024바이트로 꽉 채워서 조절할 수 있으면 입출력에 있어서 효율적인 구성을 갖출 수 있다. 27 | 28 | → B-Tree는 이러한 장점을 토대로 많은 데이터베이스 시스템의 인덱스 저장 방법으로 애용하고 있음 29 | ``` 30 | 31 |
32 | 33 | ##### 규칙 34 | 35 | - 노드의 자료수가 N이면, 자식 수는 N+1이어야 함 36 | - 각 노드의 자료는 정렬된 상태여야함 37 | - 루트 노드는 적어도 2개 이상의 자식을 가져야함 38 | - 루트 노드를 제외한 모든 노드는 적어도 M/2개의 자료를 가지고 있어야함 39 | - 외부 노드로 가는 경로의 길이는 모두 같음. 40 | - 입력 자료는 중복 될 수 없음 41 | 42 |
43 | 44 |
45 | 46 | #### B+ Tree 47 | 48 | --- 49 | 50 | 데이터의 빠른 접근을 위한 인덱스 역할만 하는 비단말 노드(not Leaf)가 추가로 있음 51 | 52 | (기존의 B-Tree와 데이터의 연결리스트로 구현된 색인구조) 53 | 54 |
55 | 56 | B-Tree의 변형 구조로, index 부분과 leaf 노드로 구성된 순차 데이터 부분으로 이루어진다. 인덱스 부분의 key 값은 leaf에 있는 key 값을 직접 찾아가는데 사용함. 57 | 58 |
59 | 60 | ##### 장점 61 | 62 | > 블럭 사이즈를 더 많이 이용할 수 있음 (key 값에 대한 하드디스크 액세스 주소가 없기 때문) 63 | > 64 | > leaf 노드끼리 연결 리스트로 연결되어 있어서 범위 탐색에 매우 유리함 65 | 66 | ##### 단점 67 | 68 | > B-tree의 경우 최상 케이스에서는 루트에서 끝날 수 있지만, B+tree는 무조건 leaf 노드까지 내려가봐야 함 69 | 70 |
71 | 72 |
73 | 74 |
75 | 76 | ##### B-Tree & B+ Tree 77 | 78 | > B-tree는 각 노드에 데이터가 저장됨 79 | > 80 | > B+tree는 index 노드와 leaf 노드로 분리되어 저장됨 81 | > 82 | > (또한, leaf 노드는 서로 연결되어 있어서 임의접근이나 순차접근 모두 성능이 우수함) 83 | 84 |
85 | 86 | B-tree는 각 노드에서 key와 data 모두 들어갈 수 있고, data는 disk block으로 포인터가 될 수 있음 87 | 88 | B+tree는 각 노드에서 key만 들어감. 따라서 data는 모두 leaf 노드에만 존재 89 | 90 | B+tree는 add와 delete가 모두 leaf 노드에서만 이루어짐 91 | 92 |
93 | 94 | **참고자료** : [링크]() -------------------------------------------------------------------------------- /Computer Science/Data Structure/Binary Search Tree.md: -------------------------------------------------------------------------------- 1 | ## [자료구조] 이진탐색트리 (Binary Search Tree) 2 | 3 |
4 | 5 | ***이진탐색트리의 목적은?*** 6 | 7 | > 이진탐색 + 연결리스트 8 | 9 | 이진탐색 : **탐색에 소요되는 시간복잡도는 O(logN)**, but 삽입,삭제가 불가능 10 | 11 | 연결리스트 : **삽입, 삭제의 시간복잡도는 O(1)**, but 탐색하는 시간복잡도가 O(N) 12 | 13 | 이 두가지를 합하여 장점을 모두 얻는 것이 **'이진탐색트리'** 14 | 15 | 즉, 효율적인 탐색 능력을 가지고, 자료의 삽입 삭제도 가능하게 만들자 16 | 17 |
18 | 19 | 20 | 21 |
22 | 23 | #### 특징 24 | 25 | - 각 노드의 자식이 2개 이하 26 | - 각 노드의 왼쪽 자식은 부모보다 작고, 오른쪽 자식은 부모보다 큼 27 | - 중복된 노드가 없어야 함 28 | 29 | ***중복이 없어야 하는 이유는?*** 30 | 31 | 검색 목적 자료구조인데, 굳이 중복이 많은 경우에 트리를 사용하여 검색 속도를 느리게 할 필요가 없음. (트리에 삽입하는 것보다, 노드에 count 값을 가지게 하여 처리하는 것이 훨씬 효율적) 32 | 33 |
34 | 35 | 이진탐색트리의 순회는 **'중위순회(inorder)' 방식 (왼쪽 - 루트 - 오른쪽)** 36 | 37 | 중위 순회로 **정렬된 순서**를 읽을 수 있음 38 | 39 |
40 | 41 | #### BST 핵심연산 42 | 43 | - 검색 44 | - 삽입 45 | - 삭제 46 | - 트리 생성 47 | - 트리 삭제 48 | 49 |
50 | 51 | #### 시간 복잡도 52 | 53 | - 균등 트리 : 노드 개수가 N개일 때 O(logN) 54 | - 편향 트리 : 노드 개수가 N개일 때 O(N) 55 | 56 | > 삽입, 검색, 삭제 시간복잡도는 **트리의 Depth**에 비례 57 | 58 |
59 | 60 | #### 삭제의 3가지 Case 61 | 62 | 1) 자식이 없는 leaf 노드일 때 → 그냥 삭제 63 | 64 | 2) 자식이 1개인 노드일 때 → 지워진 노드에 자식을 올리기 65 | 66 | 3) 자식이 2개인 노드일 때 → 오른쪽 자식 노드에서 가장 작은 값 or 왼쪽 자식 노드에서 가장 큰 값 올리기 67 | 68 |
69 | 70 | 편향된 트리(정렬된 상태 값을 트리로 만들면 한쪽으로만 뻗음)는 시간복잡도가 O(N)이므로 트리를 사용할 이유가 사라짐 → 이를 바로 잡도록 도와주는 개선된 트리가 AVL Tree, RedBlack Tree 71 | 72 |
73 | 74 | [소스 코드(java)]() -------------------------------------------------------------------------------- /Computer Science/Data Structure/Hash.md: -------------------------------------------------------------------------------- 1 | ## 해시(Hash) 2 | 3 | 데이터를 효율적으로 관리하기 위해, 임의의 길이 데이터를 고정된 길이의 데이터로 매핑하는 것 4 | 5 | 해시 함수를 구현하여 데이터 값을 해시 값으로 매핑한다. 6 | 7 |
8 | 9 | ``` 10 | Lee → 해싱함수 → 5 11 | Kim → 해싱함수 → 3 12 | Park → 해싱함수 → 2 13 | ... 14 | Chun → 해싱함수 → 5 // Lee와 해싱값 충돌 15 | ``` 16 | 17 | 결국 데이터가 많아지면, 다른 데이터가 같은 해시 값으로 충돌나는 현상이 발생함 **'collision' 현상** 18 | 19 | **_그래도 해시 테이블을 쓰는 이유는?_** 20 | 21 | > 적은 자원으로 많은 데이터를 효율적으로 관리하기 위해 22 | > 23 | > 하드디스크나, 클라우드에 존재하는 무한한 데이터들을 유한한 개수의 해시값으로 매핑하면 작은 메모리로도 프로세스 관리가 가능해짐! 24 | 25 | - 언제나 동일한 해시값 리턴, index를 알면 빠른 데이터 검색이 가능해짐 26 | - 해시테이블의 시간복잡도 O(1) - (이진탐색트리는 O(logN)) 27 | 28 |
29 | 30 | ##### 충돌 문제 해결 31 | 32 | 1. **체이닝** : 연결리스트로 노드를 계속 추가해나가는 방식 33 | (제한 없이 계속 연결 가능, but 메모리 문제) 34 | 35 | 2. **Open Addressing** : 해시 함수로 얻은 주소가 아닌 다른 주소에 데이터를 저장할 수 있도록 허용 (해당 키 값에 저장되어있으면 다음 주소에 저장) 36 | 37 | 3. **선형 탐사** : 정해진 고정 폭으로 옮겨 해시값의 중복을 피함 38 | 4. **제곱 탐사** : 정해진 고정 폭을 제곱수로 옮겨 해시값의 중복을 피함 39 | 40 |
41 | 42 | ## 해시 버킷 동적 확장 43 | 44 | 해시 버킷의 크기가 충분히 크다면 해시 충돌 빈도를 낮출 수 있다 45 | 46 | 하지만 메모리는 한정된 자원이기 때문에 무작정 큰 공간을 할당해 줄 수 없다 47 | 48 | 때문에 `load factor`가 일정 수준 이상 이라면 (보편적으로는 0.7 ~ 0.8) 해시 버킷의 크기를 확장하는 동적 확장 방식을 사용한다 49 | 50 | - **load factor** : 할당된 키의 개수 / 해시 버킷의 크기 51 | 52 | 해시 버킷이 동적 확장 될 때 `리해싱` 과정을 거치게 된다 53 | 54 | - **리해싱(Rehashing)** : 기존 저장되어 있는 값들을 다시 해싱하여 새로운 키를 부여하는 것을 말한다 55 | 56 |
57 | 58 |
59 | 60 | 참고자료 : [링크](https://ratsgo.github.io/data%20structure&algorithm/2017/10/25/hash/) 61 | -------------------------------------------------------------------------------- /Computer Science/Data Structure/Linked List.md: -------------------------------------------------------------------------------- 1 | ### Linked List 2 | 3 | --- 4 | 5 | ![img](https://www.geeksforgeeks.org/wp-content/uploads/gq/2013/03/Linkedlist.png) 6 | 7 | 연속적인 메모리 위치에 저장되지 않는 선형 데이터 구조 8 | 9 | (포인터를 사용해서 연결된다) 10 | 11 | 각 노드는 **데이터 필드**와 **다음 노드에 대한 참조**를 포함하는 노드로 구성 12 | 13 |
14 | 15 | **왜 Linked List를 사용하나?** 16 | 17 | > 배열은 비슷한 유형의 선형 데이터를 저장하는데 사용할 수 있지만 제한 사항이 있음 18 | > 19 | > 1) 배열의 크기가 고정되어 있어 미리 요소의 수에 대해 할당을 받아야 함 20 | > 21 | > 2) 새로운 요소를 삽입하는 것은 비용이 많이 듬 (공간을 만들고, 기존 요소 전부 이동) 22 | 23 | **장점** 24 | 25 | > 1) 동적 크기 26 | > 27 | > 2) 삽입/삭제 용이 28 | 29 | **단점** 30 | 31 | > 1) 임의로 액세스를 허용할 수 없음. 즉, 첫 번째 노드부터 순차적으로 요소에 액세스 해야함 (이진 검색 수행 불가능) 32 | > 33 | > 2) 포인터의 여분의 메모리 공간이 목록의 각 요소에 필요 34 | 35 | 36 | 37 | 노드 구현은 아래와 같이 데이터와 다음 노드에 대한 참조로 나타낼 수 있다 38 | 39 | ``` 40 | // A linked list node 41 | struct Node 42 | { 43 | int data; 44 | struct Node *next; 45 | }; 46 | ``` 47 | 48 | 49 | 50 | **Single Linked List** 51 | 52 | 노드 3개를 잇는 코드를 만들어보자 53 | 54 | ``` 55 | head second third 56 | | | | 57 | | | | 58 | +---+---+ +---+---+ +----+----+ 59 | | 1 | o----->| 2 | o-----> | 3 | # | 60 | +---+---+ +---+---+ +----+----+ 61 | ``` 62 | 63 | [소스 코드]() 64 | 65 | 66 | 67 |
68 | 69 |
70 | 71 | **노드 추가** 72 | 73 | - 앞쪽에 노드 추가 74 | 75 | ``` 76 | void push(struct Node** head_ref, int new_data){ 77 | struct Node* new_node = (struct Node*) malloc(sizeof(struct Node)); 78 | 79 | new_node->data = new_data; 80 | 81 | new_node->next = (*head_ref); 82 | 83 | (*head_ref) = new_node; 84 | } 85 | ``` 86 | 87 |
88 | 89 | - 특정 노드 다음에 추가 90 | 91 | ``` 92 | void insertAfter(struct Node* prev_node, int new_data){ 93 | if (prev_node == NULL){ 94 | printf("이전 노드가 NULL이 아니어야 합니다."); 95 | return; 96 | } 97 | 98 | struct Node* new_node = (struct Node*) malloc(sizeof(struct Node)); 99 | 100 | new_node->data = new_data; 101 | new_node->next = prev_node->next; 102 | 103 | prev_node->next = new_node; 104 | 105 | } 106 | ``` 107 | 108 |
109 | 110 | - 끝쪽에 노드 추가 111 | 112 | ``` 113 | void append(struct Node** head_ref, int new_data){ 114 | struct Node* new_node = (struct Node*)malloc(sizeof(struct Node)); 115 | 116 | struct Node *last = *head_ref; 117 | 118 | new_node->data = new_data; 119 | 120 | new_node->next = NULL; 121 | 122 | if (*head_ref == NULL){ 123 | *head_ref = new_node; 124 | return; 125 | } 126 | 127 | while(last->next != NULL){ 128 | last = last->next; 129 | } 130 | 131 | last->next = new_node; 132 | return; 133 | 134 | } 135 | ``` 136 | 137 | -------------------------------------------------------------------------------- /Computer Science/Data Structure/Tree.md: -------------------------------------------------------------------------------- 1 | # Tree 2 | 3 |
4 | 5 | ``` 6 | Node와 Edge로 이루어진 자료구조 7 | Tree의 특성을 이해하자 8 | ``` 9 | 10 |
11 | 12 | 13 | 14 |
15 | 16 | 트리는 값을 가진 `노드(Node)`와 이 노드들을 연결해주는 `간선(Edge)`으로 이루어져있다. 17 | 18 | 그림 상 데이터 1을 가진 노드가 `루트(Root) 노드`다. 19 | 20 | 모든 노드들은 0개 이상의 자식(Child) 노드를 갖고 있으며 보통 부모-자식 관계로 부른다. 21 | 22 |
23 | 24 | 아래처럼 가족 관계도를 그릴 때 트리 형식으로 나타내는 경우도 많이 봤을 것이다. 자료구조의 트리도 이 방식을 그대로 구현한 것이다. 25 | 26 | 27 | 28 |
29 | 30 | 트리는 몇 가지 특징이 있다. 31 | 32 | - 트리에는 사이클이 존재할 수 없다. (만약 사이클이 만들어진다면, 그것은 트리가 아니고 그래프다) 33 | - 모든 노드는 자료형으로 표현이 가능하다. 34 | - 루트에서 한 노드로 가는 경로는 유일한 경로 뿐이다. 35 | - 노드의 개수가 N개면, 간선은 N-1개를 가진다. 36 | 37 |
38 | 39 | 가장 중요한 것은, `그래프`와 `트리`의 차이가 무엇인가인데, 이는 사이클의 유무로 설명할 수 있다. 40 | 41 | 사이클이 존재하지 않는 `그래프`라 하여 무조건 `트리`인 것은 아니다 사이클이 존재하지 않는 그래프는 `Forest`라 지칭하며 트리의 경우 싸이클이 존재하지 않고 모든 노드가 간선으로 이어져 있어야 한다 42 | 43 |
44 | 45 | ### 트리 순회 방식 46 | 47 | 트리를 순회하는 방식은 총 4가지가 있다. 위의 그림을 예시로 진행해보자 48 | 49 |
50 | 51 | 52 | 53 |
54 | 55 | 1. #### 전위 순회(pre-order) 56 | 57 | 각 부모 노드를 순차적으로 먼저 방문하는 방식이다. 58 | 59 | (부모 → 왼쪽 자식 → 오른쪽 자식) 60 | 61 | > 1 → 2 → 4 → 8 → 9 → 5 → 10 → 11 → 3 → 6 → 13 → 7 → 14 62 | 63 |
64 | 65 | 2. #### 중위 순회(in-order) 66 | 67 | 왼쪽 하위 트리를 방문 후 부모 노드를 방문하는 방식이다. 68 | 69 | (왼쪽 자식 → 부모 → 오른쪽 자식) 70 | 71 | > 8 → 4 → 9 → 2 → 10 → 5 → 11 → 1 → 6 → 13 → 3 →14 → 7 72 | 73 |
74 | 75 | 3. #### 후위 순회(post-order) 76 | 77 | 왼쪽 하위 트리부터 하위를 모두 방문 후 부모 노드를 방문하는 방식이다. 78 | 79 | (왼쪽 자식 → 오른쪽 자식 → 부모) 80 | 81 | > 8 → 9 → 4 → 10 → 11 → 5 → 2 → 13 → 6 → 14 → 7 → 3 → 1 82 | 83 |
84 | 85 | 4. #### 레벨 순회(level-order) 86 | 87 | 부모 노드부터 계층 별로 방문하는 방식이다. 88 | 89 | > 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10 → 11 → 13 → 14 90 | 91 |
92 | 93 |
94 | 95 | ### Code 96 | 97 | ```java 98 | public class Tree { 99 | private Node root; 100 | 101 | public Tree(T rootData) { 102 | root = new Node(); 103 | root.data = rootData; 104 | root.children = new ArrayList>(); 105 | } 106 | 107 | public static class Node { 108 | private T data; 109 | private Node parent; 110 | private List> children; 111 | } 112 | } 113 | ``` 114 | 115 |
116 | 117 |
118 | 119 | #### [참고 자료] 120 | 121 | - [링크](https://www.geeksforgeeks.org/binary-tree-data-structure/) 122 | -------------------------------------------------------------------------------- /Computer Science/Data Structure/Trie.md: -------------------------------------------------------------------------------- 1 | ## 트라이(Trie) 2 | 3 | > 문자열에서 검색을 빠르게 도와주는 자료구조 4 | 5 | ``` 6 | 정수형에서 이진탐색트리를 이용하면 시간복잡도 O(logN) 7 | 하지만 문자열에서 적용했을 때, 문자열 최대 길이가 M이면 O(M*logN)이 된다. 8 | 9 | 트라이를 활용하면? → O(M)으로 문자열 검색이 가능함! 10 | ``` 11 | 12 |
13 | 14 | 15 | 16 | > 예시 그림에서 주어지는 배열의 총 문자열 개수는 8개인데, 트라이를 활용한 트리에서도 마지막 끝나는 노드마다 '네모' 모양으로 구성된 것을 확인하면 총 8개다. 17 | 18 |
19 | 20 | 해당 자료구조를 풀어보기 위해 좋은 문제 : [백준 5052(전화번호 목록)]() 21 | 22 | ##### 문제에서 Trie를 java로 구현한 코드 23 | 24 | ```java 25 | static class Trie { 26 | boolean end; 27 | boolean pass; 28 | Trie[] child; 29 | 30 | Trie() { 31 | end = false; 32 | pass = false; 33 | child = new Trie[10]; 34 | } 35 | 36 | public boolean insert(String str, int idx) { 37 | 38 | //끝나는 단어 있으면 false 종료 39 | if(end) return false; 40 | 41 | //idx가 str만큼 왔을때 42 | if(idx == str.length()) { 43 | end = true; 44 | if(pass) return false; // 더 지나가는 단어 있으면 false 종료 45 | else return true; 46 | } 47 | //아직 안왔을 때 48 | else { 49 | int next = str.charAt(idx) - '0'; 50 | if(child[next] == null) { 51 | child[next] = new Trie(); 52 | pass = true; 53 | } 54 | return child[next].insert(str, idx+1); 55 | } 56 | 57 | } 58 | } 59 | ``` 60 | 61 | -------------------------------------------------------------------------------- /Computer Science/Data Structure/code/MaxHeap.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/Computer Science/Data Structure/code/MaxHeap.java -------------------------------------------------------------------------------- /Computer Science/Data Structure/code/MinHeap.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/Computer Science/Data Structure/code/MinHeap.java -------------------------------------------------------------------------------- /Computer Science/Data Structure/code/binarySearchTree.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/Computer Science/Data Structure/code/binarySearchTree.java -------------------------------------------------------------------------------- /Computer Science/Data Structure/code/juggling_array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // 최대공약수 gcd 활용 5 | int gcd(int a, int b) 6 | { 7 | if (b == 0) 8 | return a; 9 | 10 | else 11 | return gcd(b, a % b); 12 | } 13 | 14 | 15 | void leftRotate(int arr[], int d, int n) 16 | { 17 | for (int i = 0; i < gcd(d, n); i++) { 18 | 19 | int temp = arr[i]; 20 | int j = i; 21 | 22 | while (1) { 23 | int k = j + d; 24 | if (k >= n) 25 | k = k - n; 26 | 27 | if (k == i) 28 | break; 29 | 30 | arr[j] = arr[k]; 31 | j = k; 32 | } 33 | arr[j] = temp; 34 | } 35 | } 36 | 37 | void printArray(int arr[], int size) 38 | { 39 | for (int i = 0; i < size; i++) 40 | cout << arr[i] << " "; 41 | } 42 | 43 | int main() 44 | { 45 | int arr[] = { 1, 2, 3, 4, 5, 6, 7 }; 46 | int n = sizeof(arr) / sizeof(arr[0]); 47 | 48 | // Function calling 49 | leftRotate(arr, 2, n); 50 | printArray(arr, n); 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /Computer Science/Data Structure/code/linked_list.java: -------------------------------------------------------------------------------- 1 | class LinkedList{ 2 | 3 | Node head; 4 | 5 | static class Node { 6 | int data; 7 | Node next; 8 | Node(int d) { // 생성자 9 | data = d; next = null; 10 | } 11 | } 12 | 13 | public void printList() 14 | { 15 | Node n = head; 16 | while (n != null) 17 | { 18 | System.out.print(n.data+" "); 19 | n = n.next; 20 | } 21 | } 22 | 23 | public static void main(String[] args){ 24 | 25 | LinkedList llist = new LinkedList(); 26 | 27 | llist.head = new Node(1); 28 | Node second = new Node(2); 29 | Node third = new Node(3); 30 | 31 | /* 32 | llist.head second third 33 | | | | 34 | | | | 35 | +----+------+ +----+------+ +----+------+ 36 | | 1 | null | | 2 | null | | 3 | null | 37 | +----+------+ +----+------+ +----+------+ 38 | */ 39 | 40 | llist.head.next = second; // 첫번째 노드에 두번째 노드 연결 41 | second.next = third; // 두번째 노드에 세번째 노드 연결 42 | 43 | /* 44 | 45 | llist.head second third 46 | | | | 47 | | | | 48 | +----+------+ +----+------+ +----+------+ 49 | | 1 | o-------->| 2 | o-------->| 3 | null | 50 | +----+------+ +----+------+ +----+------+ 51 | 52 | */ 53 | llist.printList(); 54 | } 55 | } -------------------------------------------------------------------------------- /Computer Science/Data Structure/code/linked_list_push.java: -------------------------------------------------------------------------------- 1 | class LinkedList 2 | { 3 | Node head; 4 | 5 | class Node 6 | { 7 | int data; 8 | Node next; 9 | Node(int d) {data = d; next = null; } 10 | } 11 | 12 | public void push(int new_data) 13 | { 14 | Node new_node = new Node(new_data); 15 | 16 | new_node.next = head; 17 | 18 | head = new_node; 19 | } 20 | 21 | public void insertAfter(Node prev_node, int new_data) 22 | { 23 | if (prev_node == null) 24 | { 25 | System.out.println("The given previous node cannot be null"); 26 | return; 27 | } 28 | 29 | Node new_node = new Node(new_data); 30 | 31 | new_node.next = prev_node.next; 32 | 33 | prev_node.next = new_node; 34 | } 35 | 36 | public void append(int new_data) 37 | { 38 | Node new_node = new Node(new_data); 39 | 40 | if (head == null) 41 | { 42 | head = new Node(new_data); 43 | return; 44 | } 45 | 46 | new_node.next = null; 47 | 48 | Node last = head; 49 | while (last.next != null) 50 | last = last.next; 51 | 52 | last.next = new_node; 53 | return; 54 | } 55 | 56 | public void printList() 57 | { 58 | Node tnode = head; 59 | while (tnode != null) 60 | { 61 | System.out.print(tnode.data+" "); 62 | tnode = tnode.next; 63 | } 64 | } 65 | 66 | public static void main(String[] args) 67 | { 68 | LinkedList llist = new LinkedList(); 69 | 70 | //6->NUllist 71 | llist.append(6); 72 | 73 | // 7->6->NUllist 74 | llist.push(7); 75 | 76 | // 1->7->6->NUllist 77 | llist.push(1); 78 | 79 | // 1->7->6->4->NUllist 80 | llist.append(4); 81 | 82 | // 1->7->8->6->4->NUllist 83 | llist.insertAfter(llist.head.next, 8); 84 | 85 | System.out.println("\nCreated Linked list is: "); 86 | llist.printList(); 87 | } 88 | } -------------------------------------------------------------------------------- /Computer Science/Data Structure/code/maxvalue_array.cpp: -------------------------------------------------------------------------------- 1 | // 지정된 배열에서 하나씩 회전을 해서 i*arr[i]의 합이 가장 컸을 때 값을 출력하는 문제 2 | 3 | #include 4 | using namespace std; 5 | 6 | int maxVal(int arr[], int n){ 7 | 8 | int arrSum = 0; // arr[i]의 전체 합 9 | int curSum = 0; // i*arr[i]의 전체 합 10 | 11 | for(int i = 0; i < n; i++){ 12 | arrSum = arrSum + arr[i]; 13 | curSum = curSum + (i*arr[i]); 14 | } 15 | 16 | int maxSum = curSum; 17 | 18 | for (int j = 1; j < n; j++){ 19 | curSum = curSum + arrSum - n*arr[n-j]; 20 | 21 | if ( curSum > maxSum ) 22 | maxSum = curSum; 23 | } 24 | 25 | return maxSum; 26 | 27 | } 28 | 29 | 30 | int main(void){ 31 | 32 | int arr[] = {1,20,2,10}; 33 | int n = sizeof(arr) / sizeof(arr[0]); 34 | cout << maxVal(arr, n); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Computer Science/Data Structure/code/rearrange_array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int fix(int A[], int len){ 5 | 6 | for(int i = 0; i < len; i++) { 7 | 8 | 9 | if (A[i] != -1 && A[i] != i){ // A[i]가 -1이 아니고, i도 아닐 때 10 | 11 | int x = A[i]; // 해당 값을 x에 저장 12 | 13 | while(A[x] != -1 && A[x] != x){ // A[x]가 -1이 아니고, x도 아닐 때 14 | 15 | int y = A[x]; // 해당 값을 y에 저장 16 | A[x] = x; 17 | 18 | x = y; 19 | } 20 | 21 | A[x] = x; 22 | 23 | if (A[i] != i){ 24 | A[i] = -1; 25 | } 26 | } 27 | } 28 | 29 | } 30 | 31 | void printArray(int A[], int len){ 32 | for(int i = 0; i < len; i++){ 33 | cout << A[i] << " "; 34 | } 35 | } 36 | 37 | int main() { 38 | 39 | int A[] = { -1, -1, 6, 1, 9, 40 | 3, 2, -1, 4, -1 }; 41 | 42 | int len = sizeof(A) / sizeof(A[0]); 43 | fix(A, len); 44 | printArray(A, len); 45 | 46 | return 0; 47 | } -------------------------------------------------------------------------------- /Computer Science/Data Structure/code/reversal_array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // swap을 활용한 reverse 구현 5 | void reverseArr(int arr[], int start, int end){ 6 | 7 | while (start < end){ 8 | int temp = arr[start]; 9 | arr[start] = arr[end]; 10 | arr[end] = temp; 11 | 12 | start++; 13 | end--; 14 | } 15 | } 16 | 17 | 18 | // d로 나눠서 역전 알고리즘 수행 19 | void rotateLeft(int arr[], int d, int n){ 20 | reverseArr(arr, 0, d-1); 21 | reverseArr(arr, d, n-1); 22 | reverseArr(arr, 0, n-1); 23 | } 24 | 25 | void printArray(int arr[], int n){ 26 | for(int i = 0; i < n; i++){ 27 | cout << arr[i] << " "; 28 | } 29 | } 30 | 31 | 32 | int main(void){ 33 | 34 | int arr[10] = {1,2,3,4,5,6,7,8,9,10}; 35 | int n = sizeof(arr) / sizeof(arr[0]); 36 | int d = 3; 37 | 38 | rotateLeft(arr, d, n); 39 | printArray(arr, n); 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /Computer Science/Data Structure/code/rotate_array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | //왼쪽으로 한번 회전 5 | void leftRotatebyOne(int arr[], int n){ 6 | int temp = arr[0], i; 7 | for(i = 0; i < n-1; i++){ 8 | arr[i] = arr[i+1]; 9 | } 10 | arr[i] = temp; 11 | } 12 | 13 | // d만큼 회전 14 | void leftRotate(int arr[], int d, int n){ 15 | for(int i = 0; i < d; i++) 16 | leftRotatebyOne(arr, n); 17 | } 18 | 19 | void printArray(int arr[], int n){ 20 | for(int i = 0; i < n; i++) 21 | cout << arr[i] << " "; 22 | } 23 | 24 | 25 | int main(){ 26 | int arr[] = { 1, 2, 3, 4, 5, 6, 7 }; 27 | int n = sizeof(arr) / sizeof(arr[0]); 28 | 29 | leftRotate(arr, 2, n); 30 | printArray(arr, n); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Computer Science/Database/Redis.md: -------------------------------------------------------------------------------- 1 | ## Redis 2 | 3 | > 빠른 오픈 소스 인 메모리 키 값 데이터 구조 스토어 4 | 5 | 보통 데이터베이스는 하드 디스크나 SSD에 저장한다. 하지만 Redis는 메모리(RAM)에 저장해서 디스크 스캐닝이 필요없어 매우 빠른 장점이 존재함 6 | 7 | 캐싱도 가능해 실시간 채팅에 적합하며 세션 공유를 위해 세션 클러스터링에도 활용된다.` 8 | 9 | ***RAM은 휘발성 아닌가요? 껐다키면 다 날아가는데..*** 10 | 11 | 이를 막기위한 백업 과정이 존재한다. 12 | 13 | - snapshot : 특정 지점을 설정하고 디스크에 백업 14 | - AOF(Append Only File) : 명령(쿼리)들을 저장해두고, 서버가 셧다운되면 재실행해서 다시 만들어 놓는 것 15 | 16 | 데이터 구조는 key/value 값으로 이루어져 있다. (따라서 Redis는 비정형 데이터를 저장하는 비관계형 데이터베이스 관리 시스템이다) 17 | 18 | ##### value 5가지 19 | 20 | 1. String (text, binary data) - 512MB까지 저장이 가능함 21 | 2. set (String 집합) 22 | 3. sorted set (set을 정렬해둔 상태) 23 | 4. Hash 24 | 5. List (양방향 연결리스트도 가능) -------------------------------------------------------------------------------- /Computer Science/Database/SQL Injection.md: -------------------------------------------------------------------------------- 1 | ## SQL Injection 2 | 3 | > 해커에 의해 조작된 SQL 쿼리문이 데이터베이스에 그대로 전달되어 비정상적 명령을 실행시키는 공격 기법 4 | 5 |
6 | 7 | #### 공격 방법 8 | 9 | ##### 1) 인증 우회 10 | 11 | 보통 로그인을 할 때, 아이디와 비밀번호를 input 창에 입력하게 된다. 쉽게 이해하기 위해 가벼운 예를 들어보자. 아이디가 abc, 비밀번호가 만약 1234일 때 쿼리는 아래와 같은 방식으로 전송될 것이다. 12 | 13 | ``` 14 | SELECT * FROM USER WHERE ID = "abc" AND PASSWORD = "1234"; 15 | ``` 16 | 17 | SQL Injection으로 공격할 때, input 창에 비밀번호를 입력함과 동시에 다른 쿼리문을 함께 입력하는 것이다. 18 | 19 | ``` 20 | 1234; DELETE * USER FROM ID = "1"; 21 | ``` 22 | 23 | 보안이 완벽하지 않은 경우, 이처럼 비밀번호가 아이디와 일치해서 True가 되고 뒤에 작성한 DELETE 문도 데이터베이스에 영향을 줄 수도 있게 되는 치명적인 상황이다. 24 | 25 | 이 밖에도 기본 쿼리문의 WHERE 절에 OR문을 추가하여 `'1' = '1'`과 같은 true문을 작성하여 무조건 적용되도록 수정한 뒤 DB를 마음대로 조작할 수도 있다. 26 | 27 |
28 | 29 | ##### 2) 데이터 노출 30 | 31 | 시스템에서 발생하는 에러 메시지를 이용해 공격하는 방법이다. 보통 에러는 개발자가 버그를 수정하는 면에서 도움을 받을 수 있는 존재다. 해커들은 이를 역이용해 악의적인 구문을 삽입하여 에러를 유발시킨다. 32 | 33 | 즉 예를 들면, 해커는 **GET 방식으로 동작하는 URL 쿼리 스트링을 추가하여 에러를 발생**시킨다. 이에 해당하는 오류가 발생하면, 이를 통해 해당 웹앱의 데이터베이스 구조를 유추할 수 있고 해킹에 활용한다. 34 | 35 |
36 | 37 |
38 | 39 | #### 방어 방법 40 | 41 | ##### 1) input 값을 받을 때, 특수문자 여부 검사하기 42 | 43 | > 로그인 전, 검증 로직을 추가하여 미리 설정한 특수문자들이 들어왔을 때 요청을 막아낸다. 44 | 45 | ##### 2) SQL 서버 오류 발생 시, 해당하는 에러 메시지 감추기 46 | 47 | > view를 활용하여 원본 데이터베이스 테이블에는 접근 권한을 높인다. 일반 사용자는 view로만 접근하여 에러를 볼 수 없도록 만든다. 48 | 49 | ##### 3) preparestatement 사용하기 50 | 51 | > preparestatement를 사용하면, 특수문자를 자동으로 escaping 해준다. (statement와는 다르게 쿼리문에서 전달인자 값을 `?`로 받는 것) 이를 활용해 서버 측에서 필터링 과정을 통해서 공격을 방어한다. 52 | 53 | -------------------------------------------------------------------------------- /Computer Science/Database/[DB] Anomaly.md: -------------------------------------------------------------------------------- 1 | #### [DB] Anomaly 2 | 3 | --- 4 | 5 | > 정규화를 해야하는 이유는 잘못된 테이블 설계로 인해 Anomaly (이상 현상)가 나타나기 때문이다. 6 | > 7 | > 이 페이지에서는 Anomaly가 무엇인지 살펴본다. 8 | 9 | 예) {Student ID, Course ID, Department, Course ID, Grade} 10 | 11 | 1. 삽입 이상 (Insertion Anomaly) 12 | 13 | 기본키가 {Student ID, Course ID} 인 경우 -> Course를 수강하지 않은 학생은 Course ID가 없는 현상이 발생함. 결국 Course ID를 Null로 할 수밖에 없는데, 기본키는 Null이 될 수 없으므로, Table에 추가될 수 없음. 14 | 15 | 굳이 삽입하기 위해서는 '미수강'과 같은 Course ID를 만들어야 함. 16 | 17 | > 불필요한 데이터를 추가해야지, 삽입할 수 있는 상황 = Insertion Anomaly 18 | 19 | 20 | 21 | 2. 갱신 이상 (Update Anomaly) 22 | 23 | 만약 어떤 학생의 전공 (Department) 이 "컴퓨터에서 음악"으로 바뀌는 경우. 24 | 25 | 모든 Department를 "음악"으로 바꾸어야 함. 그러나 일부를 깜빡하고 바꾸지 못하는 경우, 제대로 파악 못함. 26 | 27 | > 일부만 변경하여, 데이터가 불일치 하는 모순의 문제 = Update Anomaly 28 | 29 | 30 | 31 | 3. 삭제 이상 (Deletion Anomaly) 32 | 33 | 만약 어떤 학생이 수강을 철회하는 경우, {Student ID, Department, Course ID, Grade}의 정보 중 34 | 35 | Student ID, Department 와 같은 학생에 대한 정보도 함께 삭제됨. 36 | 37 | > 튜플 삭제로 인해 꼭 필요한 데이터까지 함께 삭제되는 문제 = Deletion Anomaly 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Computer Science/Database/[DB] Index.md: -------------------------------------------------------------------------------- 1 | # Index(인덱스) 2 | 3 |
4 | 5 | #### 목적 6 | 7 | ``` 8 | 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조 9 | ``` 10 | 11 | 테이블의 칼럼을 색인화한다. 12 | 13 | > 마치, 두꺼운 책의 목차와 같다고 생각하면 편하다. 14 | 15 | 데이터베이스 안의 레코드를 처음부터 풀스캔하지 않고, B+ Tree로 구성된 구조에서 Index 파일 검색으로 속도를 향상시키는 기술이다. 16 | 17 |
18 | 19 |
20 | 21 | #### 파일 구성 22 | 23 | 테이블 생성 시, 3가지 파일이 생성된다. 24 | 25 | - FRM : 테이블 구조 저장 파일 26 | - MYD : 실제 데이터 파일 27 | - MYI : Index 정보 파일 (Index 사용 시 생성) 28 | 29 |
30 | 31 | 사용자가 쿼리를 통해 Index를 사용하는 칼럼을 검색하게 되면, 이때 MYI 파일의 내용을 활용한다. 32 | 33 |
34 | 35 | #### 단점 36 | 37 | - Index 생성시, .mdb 파일 크기가 증가한다. 38 | - **한 페이지를 동시에 수정할 수 있는 병행성**이 줄어든다. 39 | - 인덱스 된 Field에서 Data를 업데이트하거나, **Record를 추가 또는 삭제시 성능이 떨어진다.** 40 | - 데이터 변경 작업이 자주 일어나는 경우, **Index를 재작성**해야 하므로 성능에 영향을 미친다. 41 | 42 |
43 | 44 | #### 상황 분석 45 | 46 | - ##### 사용하면 좋은 경우 47 | 48 | (1) Where 절에서 자주 사용되는 Column 49 | 50 | (2) 외래키가 사용되는 Column 51 | 52 | (3) Join에 자주 사용되는 Column 53 | 54 |
55 | 56 | - ##### Index 사용을 피해야 하는 경우 57 | 58 | (1) Data 중복도가 높은 Column 59 | 60 | (2) DML이 자주 일어나는 Column 61 | 62 |
63 | 64 | #### DML이 일어났을 때의 상황 65 | 66 | - ##### INSERT 67 | 68 | 기존 Block에 여유가 없을 때, 새로운 Data가 입력된다. 69 | 70 | → 새로운 Block을 할당 받은 후, Key를 옮기는 작업을 수행한다. 71 | 72 | → Index split 작업 동안, 해당 Block의 Key 값에 대해서 DML이 블로킹 된다. (대기 이벤트 발생) 73 | 74 | → 이때 Block의 논리적인 순서와 물리적인 순서가 달라질 수 있다. (인덱스 조각화) 75 | 76 | - ##### DELETE 77 | 78 | 79 | 80 | Table에서 data가 delete 되는 경우 : Data가 지워지고, 다른 Data가 그 공간을 사용 가능하다. 81 | 82 | Index에서 Data가 delete 되는 경우 : Data가 지워지지 않고, 사용 안 됨 표시만 해둔다. 83 | 84 | → **Table의 Data 수와 Index의 Data 수가 다를 수 있음** 85 | 86 | - ##### UPDATE 87 | 88 | Table에서 update가 발생하면 → Index는 Update 할 수 없다. 89 | 90 | Index에서는 **Delete가 발생한 후, 새로운 작업의 Insert 작업** / 2배의 작업이 소요되어 힘들다. 91 | 92 |
93 | 94 |
95 | 96 | #### 인덱스 관리 방식 97 | 98 | - ##### B-Tree 자료구조 99 | 100 | 이진 탐색트리와 유사한 자료구조 101 | 102 | 자식 노드를 둘이상 가질 수 있고 Balanced Tree 라는 특징이 있다 → 즉 탐색 연산에 있어 O(log N)의 시간복잡도를 갖는다. 103 | 104 | 모든 노드들에 대해 값을 저장하고 있으며 포인터 역할을 동반한다. 105 | 106 | - ##### B+Tree 자료구조 107 | 108 | B-Tree를 개선한 형태의 자료구조 109 | 110 | 값을 리프노드에만 저장하며 리프노드들 끼리는 링크드 리스트로 연결되어 있다 → 때문에 부등호문 연산에 대해 효과적이다. 111 | 112 | 리프 노드를 제외한 노드들은 포인터의 역할만을 수행한다. 113 | 114 | - ##### HashTable 자료구조 115 | 116 | 해시 함수를 이용해서 값을 인덱스로 변경 하여 관리하는 자료구조 117 | 118 | 일반적인 경우 탐색, 삽입, 삭제 연산에 대해 O(1)의 시간 복잡도를 갖는다. 119 | 120 | 다른 관리 방식에 비해 빠른 성능을 갖는다. 121 | 122 | 최악의 경우 해시 충돌이 발생하는 것으로 탐색, 삽입, 삭제 연산에 대해 O(N)의 시간복잡도를 갖는다. 123 | 124 | 값 자체를 변경하기 때문에 부등호문, 포함문등의 연산에 사용할 수 없다. 125 | 126 | ##### [참고사항] 127 | 128 | - [링크](https://lalwr.blogspot.com/2016/02/db-index.html) 129 | -------------------------------------------------------------------------------- /Computer Science/Database/[DB] Key.md: -------------------------------------------------------------------------------- 1 | ### [DB] Key 2 | 3 | --- 4 | 5 | > Key란? : 검색, 정렬시 Tuple을 구분할 수 있는 기준이 되는 Attribute. 6 | 7 |
8 | 9 | #### 1. Candidate Key (후보키) 10 | 11 | > Tuple을 유일하게 식별하기 위해 사용하는 속성들의 부분 집합. (기본키로 사용할 수 있는 속성들) 12 | 13 | 2가지 조건 만족 14 | 15 | * 유일성 : Key로 하나의 Tuple을 유일하게 식별할 수 있음 16 | * 최소성 : 꼭 필요한 속성으로만 구성 17 | 18 |
19 | 20 | #### 2. Primary Key (기본키) 21 | 22 | > 후보키 중 선택한 Main Key 23 | 24 | 특징 25 | 26 | * Null 값을 가질 수 없음 27 | * 동일한 값이 중복될 수 없음 28 | 29 |
30 | 31 | #### 3. Alternate Key (대체키) 32 | 33 | > 후보키 중 기본키를 제외한 나머지 키 = 보조키 34 | 35 |
36 | 37 | #### 4. Super Key (슈퍼키) 38 | 39 | > 유일성은 만족하지만, 최소성은 만족하지 못하는 키 40 | 41 |
42 | 43 | #### 5. Foreign Key (외래키) 44 | 45 | > 다른 릴레이션의 기본키를 그대로 참조하는 속성의 집합 46 | 47 |
48 | -------------------------------------------------------------------------------- /Computer Science/Database/저장 프로시저(Stored PROCEDURE).md: -------------------------------------------------------------------------------- 1 | # 저장 프로시저(Stored PROCEDURE) 2 | 3 |
4 | 5 | ``` 6 | 일련의 쿼리를 마치 하나의 함수처럼 실행하기 위한 쿼리의 집합 7 | ``` 8 | 9 |
10 | 11 | 데이터베이스에서 SQL을 통해 작업을 하다 보면, 하나의 쿼리문으로 원하는 결과를 얻을 수 없을 때가 생긴다. 원하는 결과물을 얻기 위해 사용할 여러줄의 쿼리문을 한 번의 요청으로 실행하면 좋지 않을까? 또한, 인자 값만 상황에 따라 바뀌고 동일한 로직의 복잡한 쿼리문을 필요할 때마다 작성한다면 비효율적이지 않을까? 12 | 13 | 이럴 때 사용할 수 있는 것이 바로 프로시저다. 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 프로시저를 만들어두면, 애플리케이션에서 여러 상황에 따라 해당 쿼리문이 필요할 때 인자 값만 전달하여 쉽게 원하는 결과물을 받아낼 수 있다. 24 | 25 |
26 | 27 | #### 프로시저 생성 및 호출 28 | 29 | ```plsql 30 | CREATE OR REPLACE PROCEDURE 프로시저명(변수명1 IN 데이터타입, 변수명2 OUT 데이터타입) -- 인자 값은 필수 아님 31 | IS 32 | [ 33 | 변수명1 데이터타입; 34 | 변수명2 데이터타입; 35 | .. 36 | ] 37 | BEGIN 38 | 필요한 기능; -- 인자값 활용 가능 39 | END; 40 | 41 | EXEC 프로시저명; -- 호출 42 | ``` 43 | 44 |
45 | 46 | #### 예시1 (IN) 47 | 48 | ```plsql 49 | CREATE OR REPLACE PROCEDURE test( name IN VARCHAR2 ) 50 | IS 51 | msg VARCHAR2(5) := '내 이름은'; 52 | BEGIN 53 | dbms_output.put_line(msg||' '||name); 54 | END; 55 | 56 | EXEC test('규글'); 57 | ``` 58 | 59 | ``` 60 | 내 이름은 규글 61 | ``` 62 | 63 |
64 | 65 | #### 예시2 (OUT) 66 | 67 | ```plsql 68 | CREATE OR REPLACE PROCEDURE test( name OUT VARCHAR2 ) 69 | IS 70 | BEGIN 71 | name := 'Gyoogle' 72 | END; 73 | 74 | DECLARE 75 | out_name VARCHAR2(100); 76 | 77 | BEGIN 78 | test(out_name); 79 | dbms_output.put_line('내 이름은 '||out_name); 80 | END; 81 | ``` 82 | 83 | ``` 84 | 내 이름은 Gyoogle 85 | ``` 86 | 87 |
88 | 89 |
90 | 91 | ### 프로시저 장점 92 | 93 | --- 94 | 95 | 1. #### 최적화 & 캐시 96 | 97 | 프로시저의 최초 실행 시 최적화 상태로 컴파일이 되며, 그 이후 프로시저 캐시에 저장된다. 98 | 99 | 만약 해당 프로세스가 여러번 사용될 때, 다시 컴파일 작업을 거치지 않고 캐시에서 가져오게 된다. 100 | 101 | 2. #### 유지 보수 102 | 103 | 작업이 변경될 때, 다른 작업은 건드리지 않고 프로시저 내부에서 수정만 하면 된다. 104 | (But, 장점이 단점이 될 수도 있는 부분이기도.. ) 105 | 106 | 3. #### 트래픽 감소 107 | 108 | 클라이언트가 직접 SQL문을 작성하지 않고, 프로시저명에 매개변수만 담아 전달하면 된다. 즉, SQL문이 서버에 이미 저장되어 있기 때문에 클라이언트와 서버 간 네트워크 상 트래픽이 감소된다. 109 | 110 | 4. #### 보안 111 | 112 | 프로시저 내에서 참조 중인 테이블의 접근을 막을 수 있다. 113 | 114 |
115 | 116 | ### 프로시저 단점 117 | 118 | --- 119 | 120 | 1. #### 호환성 121 | 122 | 구문 규칙이 SQL / PSM 표준과의 호환성이 낮기 때문에 코드 자산으로의 재사용성이 나쁘다. 123 | 124 | 2. #### 성능 125 | 126 | 문자 또는 숫자 연산에서 프로그래밍 언어인 C나 Java보다 성능이 느리다. 127 | 128 | 3. #### 디버깅 129 | 130 | 에러가 발생했을 때, 어디서 잘못됐는지 디버깅하는 것이 힘들 수 있다. 131 | 132 |
133 | 134 |
135 | 136 | #### [참고 자료] 137 | 138 | - [링크](https://ko.wikipedia.org/wiki/%EC%A0%80%EC%9E%A5_%ED%94%84%EB%A1%9C%EC%8B%9C%EC%A0%80) 139 | - [링크](https://itability.tistory.com/51) -------------------------------------------------------------------------------- /Computer Science/Network/DNS.md: -------------------------------------------------------------------------------- 1 | # DNS (Domain Name Server) 2 | 3 | 모든 통신은 IP를 기반으로 연결된다. 하지만 사용자에게 일일히 IP 주소를 입력하기란 UX적으로 좋지 않다 4 | 5 | 때문에 DNS 가 등장 했으며 DNS 는 IP 주소와 도메인 주소를 매핑하는 역할을 수행한다 6 | 7 | ## 도메인 주소가 IP로 변환되는 과정 8 | 9 | 1. 디바이스는 hosts 파일을 열어 봅니다 10 | - hosts 파일에는 로컬에서 직접 설정한 호스트 이름과 IP 주소를 매핑 하고 있습니다 11 | 2. DNS는 캐시를 확인 합니다 12 | - 기존에 접속했던 사이트의 경우 캐시에 남아 있을 수 있습니다 13 | - DNS는 브라우저 캐시, 로컬 캐시(OS 캐시), 라우터 캐시, ISP(Internet Service Provider)캐시 순으로 확인 합니다 14 | 3. DNS는 Root DNS에 요청을 보냅니다 15 | - 모든 DNS에는 Root DNS의 주소가 포함 되어 있습니다 16 | - 이를 통해 Root DNS에게 질의를 보내게 됩니다 17 | - Root DNS는 도메인 주소의 최상위 계층을 확인하여 TLD(Top Level DNS)의 주소를 반환 합니다 18 | 4. DNS는 TLD에 요청을 보냅니다 19 | - Root DNS로 부터 반환받은 주소를 통해 요청을 보냅니다 20 | - TLD는 도메인에 권한이 있는 Authoritative DNS의 주소를 반환 합니다 21 | 5. DNS는 Authoritative DNS에 요청을 보냅니다 22 | - 도메인 이름에 대한 IP 주소를 반환 합니다 23 | 24 | - 이때 요청을 보내는 DNS의 경우 재귀적으로 요청을 보내기 때문에 `DNS 리쿼서`라 지칭 하고 요청을 받는 DNS를 `네임서버`라 지칭 합니다 25 | -------------------------------------------------------------------------------- /Computer Science/Network/HTTP & HTTPS.md: -------------------------------------------------------------------------------- 1 | ## HTTP & HTTPS 2 | 3 |
4 | 5 | - ##### HTTP(HyperText Transfer Protocol) 6 | 7 | 인터넷 상에서 클라이언트와 서버가 자원을 주고 받을 때 쓰는 통신 규약 8 | 9 |
10 | 11 | HTTP는 텍스트 교환이므로, 누군가 네트워크에서 신호를 가로채면 내용이 노출되는 보안 이슈가 존재한다. 12 | 13 | 이런 보안 문제를 해결해주는 프로토콜이 **'HTTPS'** 14 | 15 |
16 | 17 | #### HTTP의 보안 취약점 18 | 19 | 1. **도청이 가능하다** 20 | 21 | - 평문으로 통신하기 때문에 도청이 가능하다 22 | - 이를 해결하기 위해서 통신자체를암호화(HTTPS)하거나 데이터를 암호화 하는 방법등이 있다 23 | - 데이터를 암호화 하는 경우 수신측에서는 보호화 과정이 필요하다 24 | 25 | 2. **위장이 가능하다** 26 | 27 | - 통신 상대를 확인하지 않기 깨문에 위장된 상대와 통신할 수 있다 28 | - HTTPS는 CA 인증서를 통해 인증된 상대와 통신이 가능하다 29 | 30 | 3. **변조가 가능하다** 31 | 32 | - 완전성을 보장하지 않기 때문에 변조가 가능하다 33 | - HTTPS는 메세지 인증 코드(MAC), 전자 서명등을 통해 변조를 방지 한다 34 | 35 |
36 | 37 | - ##### HTTPS(HyperText Transfer Protocol Secure) 38 | 39 | 인터넷 상에서 정보를 암호화하는 SSL 프로토콜을 사용해 클라이언트와 서버가 자원을 주고 받을 때 쓰는 통신 규약 40 | 41 | HTTPS는 텍스트를 암호화한다. (공개키 암호화 방식으로!) : [공개키 설명](https://github.com/kim6394/tech-interview-for-developer/blob/master/Computer%20Science/Network/%EB%8C%80%EC%B9%AD%ED%82%A4%20%26%20%EA%B3%B5%EA%B0%9C%ED%82%A4.md) 42 | 43 |
44 | 45 |
46 | 47 | #### HTTPS 통신 흐름 48 | 49 | 1. 애플리케이션 서버(A)를 만드는 기업은 HTTPS를 적용하기 위해 공개키와 개인키를 만든다. 50 | 51 | 2. 신뢰할 수 있는 CA 기업을 선택하고, 그 기업에게 내 공개키 관리를 부탁하며 계약을 한다. 52 | 53 | **_CA란?_** : Certificate Authority로, 공개키를 저장해주는 신뢰성이 검증된 민간기업 54 | 55 | 3. 계약 완료된 CA 기업은 해당 기업의 이름, A서버 공개키, 공개키 암호화 방법을 담은 인증서를 만들고, 해당 인증서를 CA 기업의 개인키로 암호화해서 A서버에게 제공한다. 56 | 57 | 4. A서버는 암호화된 인증서를 갖게 되었다. 이제 A서버는 A서버의 공개키로 암호화된 HTTPS 요청이 아닌 요청이 오면, 이 암호화된 인증서를 클라이언트에게 건내준다. 58 | 59 | 5. 클라이언트가 `main.html` 파일을 달라고 A서버에 요청했다고 가정하자. HTTPS 요청이 아니기 때문에 CA기업이 A서버의 정보를 CA 기업의 개인키로 암호화한 인증서를 받게 된다. 60 | 61 | CA 기업의 공개키는 브라우저가 이미 알고있다. (세계적으로 신뢰할 수 있는 기업으로 등록되어 있기 때문에, 브라우저가 인증서를 탐색하여 해독이 가능한 것) 62 | 63 | 6. 브라우저는 해독한 뒤 A서버의 공개키를 얻게 되었다. 64 | 65 | 7. 클라이언트가 A서버와 HandShaking 과정에서 주고받은 난수를 조합하여 pre-master-secret-key 를 생성한 뒤, A서버의 공개키로 해당 대칭키를 암호화하여 서버로 보냅니다. 66 | 67 | 8. A서버는 암호화된 대칭키를 자신의 개인키로 복호화 하여 클라이언트와 동일한 대칭키를 획득합니다. 68 | 69 | 9. 클라이언트, 서버는 각각 pre-master-secret-key를 master-secret-key으로 만듭니다. 70 | 71 | 10. master-secret-key 를 통해 session-key를 생성하고 이를 이용하여 대칭키 방식으로 통신합니다. 72 | 73 | 11. 각 통신이 종료될 때마다 session-key를 파기합니다. 74 | 75 |
76 | 77 | HTTPS도 무조건 안전한 것은 아니다. (신뢰받는 CA 기업이 아닌 자체 인증서 발급한 경우 등) 78 | 79 | 이때는 HTTPS지만 브라우저에서 `주의 요함`, `안전하지 않은 사이트`와 같은 알림으로 주의 받게 된다. 80 | 81 |
82 | 83 | ##### [참고사항] 84 | 85 | [링크](https://jeong-pro.tistory.com/89) 86 | -------------------------------------------------------------------------------- /Computer Science/Network/OSI 7 계층.md: -------------------------------------------------------------------------------- 1 | ## OSI 7 계층 2 | 3 |
4 | 5 | 6 | 7 |
8 | 9 | #### 7계층은 왜 나눌까? 10 | 11 | 통신이 일어나는 과정을 단계별로 알 수 있고, 특정한 곳에 이상이 생기면 그 단계만 수정할 수 있기 때문이다. 12 | 13 |
14 | 15 | ##### 1) 물리(Physical) 16 | 17 | > 리피터, 케이블, 허브 등 18 | 19 | 단지 데이터를 전기적인 신호로 변환해서 주고받는 기능을 진행하는 공간 20 | 21 | 즉, 데이터를 전송하는 역할만 진행한다. 22 | 23 |
24 | 25 | ##### 2) 데이터 링크(Data Link) 26 | 27 | > 브릿지, 스위치 등 28 | 29 | 물리 계층으로 송수신되는 정보를 관리하여 안전하게 전달되도록 도와주는 역할 30 | 31 | Mac 주소를 통해 통신한다. 프레임에 Mac 주소를 부여하고 에러검출, 재전송, 흐름제어를 진행한다. 32 | 33 |
34 | 35 | ##### 3) 네트워크(Network) 36 | 37 | > 라우터, IP 38 | 39 | 데이터를 목적지까지 가장 안전하고 빠르게 전달하는 기능을 담당한다. 40 | 41 | 라우터를 통해 이동할 경로를 선택하여 IP 주소를 지정하고, 해당 경로에 따라 패킷을 전달해준다. 42 | 43 | 라우팅, 흐름 제어, 오류 제어, 세그먼테이션 등을 수행한다. 44 | 45 |
46 | 47 | ##### 4) 전송(Transport) 48 | 49 | > TCP, UDP 50 | 51 | TCP와 UDP 프로토콜을 통해 통신을 활성화한다. 포트를 열어두고, 프로그램들이 전송을 할 수 있도록 제공해준다. 52 | 53 | - TCP : 신뢰성, 연결지향적 54 | 55 | - UDP : 비신뢰성, 비연결성, 실시간 56 | 57 |
58 | 59 | ##### 5) 세션(Session) 60 | 61 | > API, Socket 62 | 63 | 데이터가 통신하기 위한 논리적 연결을 담당한다. TCP/IP 세션을 만들고 없애는 책임을 지니고 있다. 64 | 65 |
66 | 67 | ##### 6) 표현(Presentation) 68 | 69 | > JPEG, MPEG 등 70 | 71 | 데이터 표현에 대한 독립성을 제공하고 암호화하는 역할을 담당한다. 72 | 73 | 파일 인코딩, 명령어를 포장, 압축, 암호화한다. 74 | 75 |
76 | 77 | ##### 7) 응용(Application) 78 | 79 | > HTTP, FTP, DNS 등 80 | 81 | 최종 목적지로, 응용 프로세스와 직접 관계하여 일반적인 응용 서비스를 수행한다. 82 | 83 | 사용자 인터페이스, 전자우편, 데이터베이스 관리 등의 서비스를 제공한다. 84 | -------------------------------------------------------------------------------- /Computer Science/Network/TCP 3 way handshake & 4 way handshake.md: -------------------------------------------------------------------------------- 1 | ## [TCP] 3 way handshake & 4 way handshake 2 | 3 | > 연결을 성립하고 해제하는 과정을 말한다 4 | 5 |
6 | 7 | ### 3 way handshake - 연결 성립 8 | 9 | TCP는 정확한 전송을 보장해야 한다. 따라서 통신하기에 앞서, 논리적인 접속을 성립하기 위해 3 way handshake 과정을 진행한다. 10 | 11 | 12 | 13 | 1) 클라이언트가 서버에게 SYN 패킷을 보냄 (sequence : x) 14 | 15 | 2) 서버가 SYN(x)을 받고, 클라이언트로 받았다는 신호인 ACK와 SYN 패킷을 보냄 (sequence : y, ACK : x + 1) 16 | 17 | 3) 클라이언트는 서버의 응답은 ACK(x+1)와 SYN(y) 패킷을 받고, ACK(y+1)를 서버로 보냄 18 | 19 |
20 | 21 | 이렇게 3번의 통신이 완료되면 연결이 성립된다. (3번이라 3 way handshake인 것) 22 | 23 |
24 | 25 |
26 | 27 | ### 4 way handshake - 연결 해제 28 | 29 | 연결 성립 후, 모든 통신이 끝났다면 해제해야 한다. 30 | 31 | 32 | 33 | 1) 클라이언트는 서버에게 연결을 종료한다는 FIN 플래그를 보낸다. 34 | 35 | 2) 서버는 FIN을 받고, 확인했다는 ACK를 클라이언트에게 보낸다. (이때 모든 데이터를 보내기 위해 CLOSE_WAIT 상태가 된다) 36 | 37 | 3) 데이터를 모두 보냈다면, 연결이 종료되었다는 FIN 플래그를 클라이언트에게 보낸다. 38 | 39 | 4) 클라이언트는 FIN을 받고, 확인했다는 ACK를 서버에게 보낸다. (아직 서버로부터 받지 못한 데이터가 있을 수 있으므로 TIME_WAIT을 통해 기다린다.) 40 | 41 | - 서버는 ACK를 받은 이후 소켓을 닫는다 (Closed) 42 | 43 | - TIME_WAIT 시간이 끝나면 클라이언트도 닫는다 (Closed) 44 | 45 |
46 | 47 | 이렇게 4번의 통신이 완료되면 연결이 해제된다. 48 | 49 |
50 | 51 |
52 | 53 | ##### [참고 자료] 54 | 55 | [링크]() 56 | -------------------------------------------------------------------------------- /Computer Science/Network/TLS HandShake.md: -------------------------------------------------------------------------------- 1 | # TLS/SSL HandShake 2 | 3 |
4 | 5 | ``` 6 | HTTPS에서 클라이언트와 서버간 통신 전 7 | SSL 인증서로 신뢰성 여부를 판단하기 위해 연결하는 방식 8 | ``` 9 | 10 |
11 | 12 | ![image](https://user-images.githubusercontent.com/34904741/139517776-f2cac636-5ce5-4815-981d-33905283bf13.png) 13 | 14 |
15 | 16 | ### 진행 순서 17 | 18 | 1. 클라이언트는 서버에게 `client hello` 메시지를 담아 서버로 보낸다. 19 | 이때 암호화된 정보를 함께 담는데, `버전`, `암호 알고리즘`, `압축 방식` 등을 담는다. 20 | 21 |
22 | 23 | 2. 서버는 클라이언트가 보낸 암호 알고리즘과 압축 방식을 받고, `세션 ID`와 `CA 공개 인증서`를 `server hello` 메시지와 함께 담아 응답한다. 이 CA 인증서에는 앞으로 통신 이후 사용할 대칭키가 생성되기 전, 클라이언트에서 handshake 과정 속 암호화에 사용할 공개키를 담고 있다. 24 | 25 |
26 | 27 | 3. 클라이언트 측은 서버에서 보낸 CA 인증서에 대해 유효한 지 CA 목록에서 확인하는 과정을 진행한다. 28 | 29 |
30 | 31 | 4. CA 인증서에 대한 신뢰성이 확보되었다면, 클라이언트는 난수 바이트를 생성하여 서버의 공개키로 암호화한다. 이 난수 바이트는 대칭키를 정하는데 사용이 되고, 앞으로 서로 메시지를 통신할 때 암호화하는데 사용된다. 32 | 33 |
34 | 35 | 5. 만약 2번 단계에서 서버가 클라이언트 인증서를 함께 요구했다면, 클라이언트의 인증서와 클라이언트의 개인키로 암호화된 임의의 바이트 문자열을 함께 보내준다. 36 | 37 |
38 | 39 | 6. 서버는 클라이언트의 인증서를 확인 후, 난수 바이트를 자신의 개인키로 복호화 후 대칭 마스터 키 생성에 활용한다. 40 | 41 |
42 | 43 | 7. 클라이언트는 handshake 과정이 완료되었다는 `finished` 메시지를 서버에 보내면서, 지금까지 보낸 교환 내역들을 해싱 후 그 값을 대칭키로 암호화하여 같이 담아 보내준다. 44 | 45 |
46 | 47 | 8. 서버도 동일하게 교환 내용들을 해싱한 뒤 클라이언트에서 보내준 값과 일치하는 지 확인한다. 일치하면 서버도 마찬가지로 `finished` 메시지를 이번에 만든 대칭키로 암호화하여 보낸다. 48 | 49 |
50 | 51 | 9. 클라이언트는 해당 메시지를 대칭키로 복호화하여 서로 통신이 가능한 신뢰받은 사용자란 걸 인지하고, 앞으로 클라이언트와 서버는 해당 대칭키로 데이터를 주고받을 수 있게 된다. 52 | 53 |
54 | 55 |
56 | 57 | #### [참고 자료] 58 | 59 | - [링크](https://wangin9.tistory.com/entry/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%97%90-URL-%EC%9E%85%EB%A0%A5-%ED%9B%84-%EC%9D%BC%EC%96%B4%EB%82%98%EB%8A%94-%EC%9D%BC%EB%93%A4-5TLSSSL-Handshake) -------------------------------------------------------------------------------- /Computer Science/Network/[Network] Blocking Non-Blocking IO.md: -------------------------------------------------------------------------------- 1 | #### Blocking I/O & Non-Blocking I/O 2 | 3 | --- 4 | 5 | > I/O 작업은 Kernel level에서만 수행할 수 있다. 따라서, Process, Thread는 커널에게 I/O를 요청해야 한다. 6 | 7 |
8 | 9 | 1. #### Blocking I/O 10 | 11 | I/O Blocking 형태의 작업은 12 | 13 | (1) Process(Thread)가 Kernel에게 I/O를 요청하는 함수를 호출 14 | 15 | (2) Kernel이 작업을 완료하면 작업 결과를 반환 받음. 16 | 17 | 18 | 19 | * 특징 20 | * I/O 작업이 진행되는 동안 user Process(Thread) 는 자신의 작업을 중단한 채 대기 21 | * Resource 낭비가 심함
(I/O 작업이 CPU 자원을 거의 쓰지 않으므로) 22 | 23 |
24 | 25 | `여러 Client 가 접속하는 서버를 Blocking 방식으로 구현하는 경우` -> I/O 작업을 진행하는 작업을 중지 -> 다른 Client가 진행중인 작업을 중지하면 안되므로, client 별로 별도의 Thread를 생성해야 함 -> 접속자 수가 매우 많아짐 26 | 27 | 이로 인해, 많아진 Threads 로 *컨텍스트 스위칭 횟수가 증가함,,, 비효율적인 동작 방식* 28 | 29 |
30 | 31 | 2. #### Non-Blocking I/O 32 | 33 | I/O 작업이 진행되는 동안 User Process의 작업을 중단하지 않음. 34 | 35 | * 진행 순서 36 | 37 | 1. User Process가 recvfrom 함수 호출 (커널에게 해당 Socket으로부터 data를 받고 싶다고 요청함) 38 | 39 | 2. Kernel은 이 요청에 대해서, 곧바로 recvBuffer를 채워서 보내지 못하므로, "EWOULDBLOCK"을 return함. 40 | 41 | 3. Blocking 방식과 달리, User Process는 다른 작업을 진행할 수 있음. 42 | 43 | 4. recvBuffer에 user가 받을 수 있는 데이터가 있는 경우, Buffer로부터 데이터를 복사하여 받아옴. 44 | 45 | > 이때, recvBuffer는 Kernel이 가지고 있는 메모리에 적재되어 있으므로, Memory간 복사로 인해, I/O보다 훨씬 빠른 속도로 data를 받아올 수 있음. 46 | 47 | 5. recvfrom 함수는 빠른 속도로 data를 복사한 후, 복사한 data의 길이와 함께 반환함. 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Computer Science/Network/대칭키 & 공개키.md: -------------------------------------------------------------------------------- 1 | ## 대칭키 & 공개키 2 | 3 |
4 | 5 | #### 대칭키(Symmetric Key) 6 | 7 | > 암호화와 복호화에 같은 암호키(대칭키)를 사용하는 알고리즘 8 | 9 | 동일한 키를 주고받기 때문에, 매우 빠르다는 장점이 있음 10 | 11 | but, 대칭키 전달과정에서 해킹 위험에 노출 12 | 13 |
14 | 15 | #### 공개키(Public Key)/비대칭키(Asymmetric Key) 16 | 17 | > 암호화와 복호화에 사용하는 암호키를 분리한 알고리즘 18 | 19 | 대칭키의 키 분배 문제를 해결하기 위해 고안됨.(대칭키일 때는 송수신자 간만 키를 알아야하기 때문에 분배가 복잡하고 어렵지만 공개키와 비밀키로 분리할 경우, 남들이 알아도 되는 공개키만 공개하면 되므로) 20 | 21 | 자신이 가지고 있는 고유한 암호키(비밀키)로만 복호화할 수 있는 암호키(공개키)를 대중에 공개함 22 | 23 |
24 | 25 | ##### 공개키 암호화 방식 진행 과정 26 | 27 | 1) A가 웹 상에 공개된 'B의 공개키'를 이용해 평문을 암호화하여 B에게 보냄 28 | 2) B는 자신의 비밀키로 복호화한 평문을 확인, A의 공개키로 응답을 암호화하여 A에개 보냄 29 | 3) A는 자신의 비밀키로 암호화된 응답문을 복호화함 30 | 31 | 하지만 이 방식은 Confidentiallity만 보장해줄 뿐, Integrity나 Authenticity는 보장해주지 못함 32 | 33 | -> 이는 MAC(Message Authentication Code)나 전자 서명(Digital Signature)으로 해결 34 | (MAC은 공개키 방식이 아니라 대칭키 방식임을 유의! T=MAC(K,M) 형식) 35 | 36 | 대칭키에 비해 암호화 복호화가 매우 복잡함 37 | 38 | (암호화하는 키가 복호화하는 키가 서로 다르기 때문) 39 | 40 |
41 | 42 |
43 | 44 | ##### 대칭키와 공개키 암호화 방식을 적절히 혼합해보면? (하이브리드 방식) 45 | 46 | > SSL 탄생의 시초가 됨 47 | 48 | ``` 49 | 1. A가 B의 공개키로 암호화 통신에 사용할 대칭키를 암호화하고 B에게 보냄 50 | 2. B는 암호문을 받고, 자신의 비밀키로 복호화함 51 | 3. B는 A로부터 얻은 대칭키로 A에게 보낼 평문을 암호화하여 A에게 보냄 52 | 4. A는 자신의 대칭키로 암호문을 복호화함 53 | 5. 앞으로 이 대칭키로 암호화를 통신함 54 | ``` 55 | 56 | 즉, 대칭키를 주고받을 때만 공개키 암호화 방식을 사용하고 이후에는 계속 대칭키 암호화 방식으로 통신하는 것! 57 | 58 |
59 | -------------------------------------------------------------------------------- /Computer Science/Network/로드 밸런싱(Load Balancing).md: -------------------------------------------------------------------------------- 1 | ## 로드 밸런싱(Load Balancing) 2 | 3 | > 둘 이상의 CPU or 저장장치와 같은 컴퓨터 자원들에게 작업을 나누는 것 4 | 5 |
6 | 7 | 8 | 9 | 요즘 시대에는 웹사이트에 접속하는 인원이 급격히 늘어나게 되었다. 10 | 11 | 따라서 이 사람들에 대해 모든 트래픽을 감당하기엔 1대의 서버로는 부족하다. 대응 방안으로 하드웨어의 성능을 올리거나(Scale-up) 여러대의 서버가 나눠서 일하도록 만드는 것(Scale-out)이 있다. 하드웨어 향상 비용이 더욱 비싸기도 하고, 서버가 여러대면 무중단 서비스를 제공하는 환경 구성이 용이하므로 Scale-out이 효과적이다. 이때 여러 서버에게 균등하게 트래픽을 분산시켜주는 것이 바로 **로드 밸런싱**이다. 12 | 13 |
14 | 15 | **로드 밸런싱**은 분산식 웹 서비스로, 여러 서버에 부하(Load)를 나누어주는 역할을 한다. Load Balancer를 클라이언트와 서버 사이에 두고, 부하가 일어나지 않도록 여러 서버에 분산시켜주는 방식이다. 서비스를 운영하는 사이트의 규모에 따라 웹 서버를 추가로 증설하면서 로드 밸런서로 관리해주면 웹 서버의 부하를 해결할 수 있다. 16 | 17 |
18 | 19 | #### 로드 밸런서가 서버를 선택하는 방식 20 | 21 | - 라운드 로빈(Round Robin) : CPU 스케줄링의 라운드 로빈 방식 활용 22 | - Least Connections : 연결 개수가 가장 적은 서버 선택 (트래픽으로 인해 세션이 길어지는 경우 권장) 23 | - Source : 사용자 IP를 해싱하여 분배 (특정 사용자가 항상 같은 서버로 연결되는 것 보장) 24 | 25 |
26 | 27 | #### 로드 밸런서 장애 대비 28 | 29 | 서버를 분배하는 로드 밸런서에 문제가 생길 수 있기 때문에 로드 밸런서를 이중화하여 대비한다. 30 | 31 | > Active 상태와 Passive 상태 32 | 33 |
34 | 35 | ##### [참고자료] 36 | 37 | - [링크]() 38 | 39 | - [링크]() 40 | 41 | -------------------------------------------------------------------------------- /Computer Science/Operating System/File System.md: -------------------------------------------------------------------------------- 1 | ## 파일 시스템(File System) 2 | 3 |
4 | 5 | 컴퓨터에서 파일이나 자료를 쉽게 발견할 수 있도록, 유지 및 관리하는 방법이다. 6 | 7 | 저장매체에는 수많은 파일이 있기 때문에, 이런 파일들을 관리하는 방법을 말한다. 8 | 9 | #####
10 | 11 | ##### 특징 12 | 13 | - 커널 영역에서 동작 14 | - 파일 CRUD 기능을 원활히 수행하기 위한 목적 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 | 1. ##### 순차 접근(Sequential Access) 44 | 45 | > 가장 간단한 접근 방법으로, 대부분 연산은 read와 write 46 | 47 | 48 | 49 | 현재 위치를 가리키는 포인터에서 시스템 콜이 발생할 경우 포인터를 앞으로 보내면서 read와 write를 진행. 뒤로 돌아갈 땐 지정한 offset만큼 되감기를 해야 한다. (테이프 모델 기반) 50 | 51 | 2. ##### 직접 접근(Direct Access) 52 | 53 | > 특별한 순서없이, 빠르게 레코드를 read, write 가능 54 | 55 | 56 | 57 | 현재 위치를 가리키는 cp 변수만 유지하면 직접 접근 파일을 가지고 순차 파일 기능을 쉽게 구현이 가능하다. 58 | 59 | 무작위 파일 블록에 대한 임의 접근을 허용한다. 따라서 순서의 제약이 없음 60 | 61 | 대규모 정보를 접근할 때 유용하기 때문에 '데이터베이스'에 활용된다. 62 | 63 | 3. 기타 접근 64 | 65 | > 직접 접근 파일에 기반하여 색인 구축 66 | 67 | 68 | 69 | 크기가 큰 파일을 입출력 탐색할 수 있게 도와주는 방법임 70 | 71 |
72 | 73 |
74 | 75 | ### 디렉터리와 디스크 구조 76 | 77 | --- 78 | 79 | - ##### 1단계 디렉터리 80 | 81 | > 가장 간단한 구조 82 | 83 | 파일들은 서로 유일한 이름을 가짐. 서로 다른 사용자라도 같은 이름 사용 불가 84 | 85 | 86 | 87 | - ##### 2단계 디렉터리 88 | 89 | > 사용자에게 개별적인 디렉터리 만들어줌 90 | 91 | - UFD : 자신만의 사용자 파일 디렉터리 92 | - MFD : 사용자의 이름과 계정번호로 색인되어 있는 디렉터리 93 | 94 | 95 | 96 | - ##### 트리 구조 디렉터리 97 | 98 | > 2단계 구조 확장된 다단계 트리 구조 99 | 100 | 한 비트를 활용하여, 일반 파일(0)인지 디렉터리 파일(1) 구분 101 | 102 | 103 | 104 | - 그래프 구조 디렉터리 105 | 106 | > 순환이 발생하지 않도록 하위 디렉터리가 아닌 파일에 대한 링크만 허용하거나, 가비지 컬렉션을 이용해 전체 파일 시스템을 순회하고 접근 가능한 모든 것을 표시 107 | 108 | 링크가 있으면 우회하여 순환을 피할 수 있음 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | ##### [참고 자료] 125 | 126 | - [링크]( https://noep.github.io/2016/02/23/10th-filesystem/ ) -------------------------------------------------------------------------------- /Computer Science/Operating System/Interrupt.md: -------------------------------------------------------------------------------- 1 | ## 인터럽트(Interrupt) 2 | 3 | ##### 정의 4 | 5 | 프로그램을 실행하는 도중에 예기치 않은 상황이 발생할 경우 현재 실행 중인 작업을 즉시 중단하고, 발생된 상황에 대한 우선 처리가 필요함을 CPU에게 알리는 것 6 |
7 | 8 | 지금 수행 중인 일보다 더 중요한 일(ex. 입출력, 우선 순위 연산 등)이 발생하면 그 일을 먼저 처리하고 나서 하던 일을 계속해야한다. 9 | 10 |
11 | 12 | 외부/내부 인터럽트는 `CPU의 하드웨어 신호에 의해 발생` 13 | 14 | 소프트웨어 인터럽트는 `명령어의 수행에 의해 발생` 15 | 16 | - ##### 외부 인터럽트 17 | 18 | 입출력 장치, 타이밍 장치, 전원 등 외부적인 요인으로 발생 19 | 20 | `전원 이상, 기계 착오, 외부 신호, 입출력` 21 | 22 |
23 | 24 | - ##### 내부 인터럽트 25 | 26 | Trap이라고 부르며, 잘못된 명령이나 데이터를 사용할 때 발생 27 | 28 | > 0으로 나누기가 발생, 오버플로우, 명령어를 잘못 사용한 경우 (Exception) 29 | 30 | - ##### 소프트웨어 인터럽트 31 | 32 | 프로그램 처리 중 명령의 요청에 의해 발생한 것 (SVC 인터럽트) 33 | 34 | > 사용자가 프로그램을 실행시킬 때 발생 35 | > 36 | > 소프트웨어 이용 중에 다른 프로세스를 실행시키면 시분할 처리를 위해 자원 할당 동작이 수행된다. 37 | 38 |
39 | 40 | #### 인터럽트 발생 처리 과정 41 | 42 | 43 | 44 | 주 프로그램이 실행되다가 인터럽트가 발생했다. 45 | 46 | 현재 수행 중인 프로그램을 멈추고, 상태 레지스터와 PC 등을 스택에 잠시 저장한 뒤에 인터럽트 서비스 루틴으로 간다. (잠시 저장하는 이유는, 인터럽트 서비스 루틴이 끝난 뒤 다시 원래 작업으로 돌아와야 하기 때문) 47 | 48 | 만약 **인터럽트 기능이 없었다면**, 컨트롤러는 특정한 어떤 일을 할 시기를 알기 위해 계속 체크를 해야 한다. (이를 **폴링(Polling)**이라고 한다) 49 | 50 | 폴링을 하는 시간에는 원래 하던 일에 집중할 수가 없게 되어 많은 기능을 제대로 수행하지 못하는 단점이 있었다. 51 | 52 |
53 | 54 | 즉, 컨트롤러가 입력을 받아들이는 방법(우선순위 판별방법)에는 두가지가 있다. 55 | 56 | - ##### 폴링 방식 57 | 58 | 사용자가 명령어를 사용해 입력 핀의 값을 계속 읽어 변화를 알아내는 방식 59 | 60 | 인터럽트 요청 플래그를 차례로 비교하여 우선순위가 가장 높은 인터럽트 자원을 찾아 이에 맞는 인터럽트 서비스 루틴을 수행한다. (하드웨어에 비해 속도 느림) 61 | 62 | - ##### 인터럽트 방식 63 | 64 | MCU 자체가 하드웨어적으로 변화를 체크하여 변화 시에만 일정한 동작을 하는 방식 65 | 66 | - Daisy Chain 67 | - 병렬 우선순위 부여 68 | 69 |
70 | 71 | 인터럽트 방식은 하드웨어로 지원을 받아야 하는 제약이 있지만, 폴링에 비해 신속하게 대응하는 것이 가능하다. 따라서 **'실시간 대응'**이 필요할 때는 필수적인 기능이다. 72 | 73 |
74 | 75 | 즉, 인터럽트는 **발생시기를 예측하기 힘든 경우에 컨트롤러가 가장 빠르게 대응할 수 있는 방법**이다. 76 | 77 | -------------------------------------------------------------------------------- /Computer Science/Operating System/Operation System.md: -------------------------------------------------------------------------------- 1 | ## 운영 체제란 무엇인가? 2 | 3 | > **운영 체제(OS, Operating System)** 4 | > 5 | > : 하드웨어를 관리하고, 컴퓨터 시스템의 자원들을 효율적으로 관리하며, 응용 프로그램과 하드웨어 간의 인터페이스로써 다른 응용 프로그램이 유용한 작업을 할 수 있도록 환경을 제공해준다. 6 | > 7 | > 즉, 운영 체제는 **사용자가 컴퓨터를 편리하고 효과적으로 사용할 수 있도록 환경을 제공하는 시스템 소프트웨어**라고 할 수 있다. 8 | > 9 | > (*종류로는 Windows, Linux, UNIX, MS-DOS 등이 있으며, 시스템의 역할 구분에 따라 각각 용이점이 있다.*) 10 | 11 |
12 | 13 | --- 14 | 15 | ### [ 운영체제의 역할 ] 16 | 17 |
18 | 19 | ##### 1. 프로세스 관리 20 | 21 | - 프로세스, 스레드 22 | - 스케줄링 23 | - 동기화 24 | - IPC 통신 25 | 26 | ##### 2. 저장장치 관리 27 | 28 | - 메모리 관리 29 | - 가상 메모리 30 | - 파일 시스템 31 | 32 | ##### 3. 네트워킹 33 | 34 | - TCP/IP 35 | - 기타 프로토콜 36 | 37 | ##### 4. 사용자 관리 38 | 39 | - 계정 관리 40 | - 접근권한 관리 41 | 42 | ##### 5. 디바이스 드라이버 43 | 44 | - 순차접근 장치 45 | - 임의접근 장치 46 | - 네트워크 장치 47 | 48 |
49 | 50 | --- 51 | 52 | ### [ 각 역할에 대한 자세한 설명 ] 53 | 54 |
55 | 56 | ### 1. 프로세스 관리 57 | 58 | 운영체제에서 작동하는 응용 프로그램을 관리하는 기능이다. 59 | 60 | 어떤 의미에서는 프로세서(CPU) 관리하는 것이라고 볼 수도 있다. 현재 CPU를 점유해야 할 프로세스를 결정하고, 실제로 CPU를 프로세스에 할당하며, 이 프로세스 간 공유 자원 접근과 통신 등을 관리하게 된다. 61 | 62 |
63 | 64 | ### 2. 저장장치 관리 65 | 66 | 1차 저장장치에 해당하는 메인 메모리와 2차 저장장치에 해당하는 하드디스크, NAND 등을 관리하는 기능이다. 67 | 68 | - 1차 저장장치(Main Memory) 69 | - 프로세스에 할당하는 메모리 영역의 할당과 해제 70 | - 각 메모리 영역 간의 침범 방지 71 | - 메인 메모리의 효율적 활용을 위한 가상 메모리 기능 72 | - 2차 저장장치(HDD, NAND Flash Memory 등) 73 | - 파일 형식의 데이터 저장 74 | - 이런 파일 데이터 관리를 위한 파일 시스템을 OS에서 관리 75 | - `FAT, NTFS, EXT2, JFS, XFS` 등 많은 파일 시스템들이 개발되어 사용 중 76 |
77 | ### 3. 네트워킹 78 | 79 | 네트워킹은 컴퓨터 활용의 핵심과도 같아졌다. 80 | 81 | TCP/IP 기반의 인터넷에 연결하거나, 응용 프로그램이 네트워크를 사용하려면 **운영체제에서 네트워크 프로토콜을 지원**해야 한다. 현재 상용 OS들은 다양하고 많은 네트워크 프로토콜을 지원한다. 82 | 83 | 이처럼 운영체제는 사용자와 컴퓨터 하드웨어 사이에 위치해서, 하드웨어를 운영 및 관리하고 명령어를 제어하여 응용 프로그램 및 하드웨어를 소프트웨어적으로 제어 및 관리를 해야한다. 84 |
85 | ### 4. 사용자 관리 86 | 87 | 우리가 사용하는 PC는 오직 한 사람만의 것일까? 아니다. 88 | 89 | 하나의 PC로도 여러 사람이 사용하는 경우가 많다. 그래서 운영체제는 한 컴퓨터를 여러 사람이 사용하는 환경도 지원해야 한다. 가족들이 각자의 계정을 만들어 PC를 사용한다면, 이는 하나의 컴퓨터를 여러 명이 사용한다고 말할 수 있다. 90 | 91 | 따라서, 운영체제는 각 계정을 관리할 수 있는 기능이 필요하다. 사용자 별로 프라이버시와 보안을 위해 개인 파일에 대해선 다른 사용자가 접근할 수 없도록 해야 한다. 이 밖에도 파일이나 시스템 자원에 접근 권한을 지정할 수 있도록 지원하는 것이 사용자 관리 기능이다. 92 |
93 | ### 5. 디바이스 드라이버 94 | 95 | 운영체제는 시스템의 자원, 하드웨어를 관리한다. 시스템에는 여러 하드웨어가 붙어있는데, 이들을 운영체제에서 인식하고 관리하게 만들어 응용 프로그램이 하드웨어를 사용할 수 있게 만들어야 한다. 96 | 97 | 따라서, 운영체제 안에 하드웨어를 추상화 해주는 계층이 필요하다. 이 계층이 바로 디바이스 드라이버라고 불린다. 하드웨어의 종류가 많은 만큼, 운영체제 내부의 디바이스 드라이버도 많이 존재한다. 98 | 99 | 이러한 수많은 디바이스 드라이버들을 관리하는 기능 또한 운영체제가 맡고 있다. 100 | 101 | --- 102 | 103 |
104 | 105 | ##### [참고 자료 및 주제와 관련하여 참고하면 좋은 곳 링크] 106 | 107 | - 도서 - '도전 임베디드 OS 만들기' *( 이만우 저, 인사이트 출판 )* 108 | - 글 - '운영체제란 무엇인가?' *( https://coding-factory.tistory.com/300 )* -------------------------------------------------------------------------------- /Computer Science/Operating System/PCB & Context Switcing.md: -------------------------------------------------------------------------------- 1 | ## PCB & Context Switching 2 | 3 |
4 | 5 | #### Process Management 6 | 7 | > CPU가 프로세스가 여러개일 때, CPU 스케줄링을 통해 관리하는 것을 말함 8 | 9 | 이때, CPU는 각 프로세스들이 누군지 알아야 관리가 가능함 10 | 11 | 프로세스들의 특징을 갖고있는 것이 바로 `Process Metadata` 12 | 13 | - Process Metadata 14 | - Process ID 15 | - Process State 16 | - Process Priority 17 | - CPU Registers 18 | - Owner 19 | - CPU Usage 20 | - Memeory Usage 21 | 22 | 이 메타데이터는 프로세스가 생성되면 `PCB(Process Control Block)`이라는 곳에 저장됨 23 | 24 |
25 | 26 | #### PCB(Process Control Block) 27 | 28 | > 프로세스 메타데이터들을 저장해 놓는 곳, 한 PCB 안에는 한 프로세스의 정보가 담김 29 | 30 | 31 | 32 | ##### 다시 정리해보면? 33 | 34 | ``` 35 | 프로그램 실행 → 프로세스 생성 → 프로세스 주소 공간에 (코드, 데이터, 스택) 생성 36 | → 이 프로세스의 메타데이터들이 PCB에 저장 37 | ``` 38 | 39 |
40 | 41 | ##### PCB가 왜 필요한가요? 42 | 43 | > CPU에서는 프로세스의 상태에 따라 교체작업이 이루어진다. (interrupt가 발생해서 할당받은 프로세스가 waiting 상태가 되고 다른 프로세스를 running으로 바꿔 올릴 때) 44 | > 45 | > 이때, **앞으로 다시 수행할 대기 중인 프로세스에 관한 저장 값을 PCB에 저장해두는 것**이다. 46 | 47 | ##### PCB는 어떻게 관리되나요? 48 | 49 | > Linked List 방식으로 관리함 50 | > 51 | > PCB List Head에 PCB들이 생성될 때마다 붙게 된다. 주소값으로 연결이 이루어져 있는 연결리스트이기 때문에 삽입 삭제가 용이함. 52 | > 53 | > 즉, 프로세스가 생성되면 해당 PCB가 생성되고 프로세스 완료시 제거됨 54 | 55 |
56 | 57 |
58 | 59 | 이렇게 수행 중인 프로세스를 변경할 때, CPU의 레지스터 정보가 변경되는 것을 `Context Switching`이라고 한다. 60 | 61 | #### Context Switching 62 | 63 | > CPU가 이전의 프로세스 상태를 PCB에 보관하고, 또 다른 프로세스의 정보를 PCB에 읽어 레지스터에 적재하는 과정 64 | 65 | 보통 인터럽트가 발생하거나, 실행 중인 CPU 사용 허가시간을 모두 소모하거나, 입출력을 위해 대기해야 하는 경우에 Context Switching이 발생 66 | 67 | `즉, 프로세스가 Ready → Running, Running → Ready, Running → Waiting처럼 상태 변경 시 발생!` 68 | 69 |
70 | 71 | ##### Context Switching의 OverHead란? 72 | 73 | overhead는 과부하라는 뜻으로 보통 안좋은 말로 많이 쓰인다. 74 | 75 | 하지만 프로세스 작업 중에는 OverHead를 감수해야 하는 상황이 있다. 76 | 77 | ``` 78 | 프로세스를 수행하다가 입출력 이벤트가 발생해서 대기 상태로 전환시킴 79 | 이때, CPU를 그냥 놀게 놔두는 것보다 다른 프로세스를 수행시키는 것이 효율적 80 | ``` 81 | 82 | 즉, CPU에 계속 프로세스를 수행시키도록 하기 위해서 다른 프로세스를 실행시키고 Context Switching 하는 것 83 | 84 | CPU가 놀지 않도록 만들고, 사용자에게 빠르게 일처리를 제공해주기 위한 것이다. 85 | -------------------------------------------------------------------------------- /Computer Science/Operating System/Paging and Segmentation.md: -------------------------------------------------------------------------------- 1 | ### 페이징과 세그먼테이션 2 | 3 | --- 4 | 5 | ##### 기법을 쓰는 이유 6 | 7 | > 다중 프로그래밍 시스템에 여러 프로세스를 수용하기 위해 주기억장치를 동적 분할하는 메모리 관리 작업이 필요해서 8 | 9 |
10 | 11 | #### 메모리 관리 기법 12 | 13 | 1. 연속 메모리 관리 14 | 15 | > 프로그램 전체가 하나의 커다란 공간에 연속적으로 할당되어야 함 16 | 17 | - 고정 분할 기법 : 주기억장치가 고정된 파티션으로 분할 (**내부 단편화 발생**) 18 | - 동적 분할 기법 : 파티션들이 동적 생성되며 자신의 크기와 같은 파티션에 적재 (**외부 단편화 발생**) 19 | 20 |
21 | 22 | 2. 불연속 메모리 관리 23 | 24 | > 프로그램의 일부가 서로 다른 주소 공간에 할당될 수 있는 기법 25 | 26 | 페이지 : 고정 사이즈의 작은 프로세스 조각 27 | 28 | 프레임 : 페이지 크기와 같은 주기억장치 메모리 조각 29 | 30 | 단편화 : 기억 장치의 빈 공간 or 자료가 여러 조각으로 나뉘는 현상 31 | 32 | 세그먼트 : 서로 다른 크기를 가진 논리적 블록이 연속적 공간에 배치되는 것 33 |
34 | 35 | **고정 크기** : 페이징(Paging) 36 | 37 | **가변 크기** : 세그먼테이션(Segmentation) 38 |
39 | 40 | - 단순 페이징 41 | 42 | > 각 프로세스는 프레임들과 같은 길이를 가진 균등 페이지로 나뉨 43 | > 44 | > 외부 단편화 X 45 | > 46 | > 소량의 내부 단편화 존재 47 | 48 | - 단순 세그먼테이션 49 | 50 | > 각 프로세스는 여러 세그먼트들로 나뉨 51 | > 52 | > 내부 단편화 X, 메모리 사용 효율 개선, 동적 분할을 통한 오버헤드 감소 53 | > 54 | > 외부 단편화 존재 55 | 56 | - 가상 메모리 페이징 57 | 58 | > 단순 페이징과 비교해 프로세스 페이지 전부를 로드시킬 필요X 59 | > 60 | > 필요한 페이지가 있으면 나중에 자동으로 불러들어짐 61 | > 62 | > 외부 단편화 X 63 | > 64 | > 복잡한 메모리 관리로 오버헤드 발생 65 | 66 | - 가상 메모리 세그먼테이션 67 | 68 | > 필요하지 않은 세그먼트들은 로드되지 않음 69 | > 70 | > 필요한 세그먼트 있을때 나중에 자동으로 불러들어짐 71 | > 72 | > 내부 단편화X 73 | > 74 | > 복잡한 메모리 관리로 오버헤드 발생 75 | 76 | -------------------------------------------------------------------------------- /Computer Science/Operating System/Paging and Segmentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/Computer Science/Operating System/Paging and Segmentation.pdf -------------------------------------------------------------------------------- /Computer Science/Operating System/Process Address Space.md: -------------------------------------------------------------------------------- 1 | ## 프로세스의 주소 공간 2 | 3 | > 프로그램이 CPU에 의해 실행됨 → 프로세스가 생성되고 메모리에 '**프로세스 주소 공간**'이 할당됨 4 | 5 | 프로세스 주소 공간에는 코드, 데이터, 스택으로 이루어져 있다. 6 | 7 | - **코드 Segment** : 프로그램 소스 코드 저장 8 | - **데이터 Segment** : 전역 변수 저장 9 | - **스택 Segment** : 함수, 지역 변수 저장 10 | 11 |
12 | 13 | ***왜 이렇게 구역을 나눈건가요?*** 14 | 15 | 최대한 데이터를 공유하여 메모리 사용량을 줄여야 합니다. 16 | 17 | Code는 같은 프로그램 자체에서는 모두 같은 내용이기 때문에 따로 관리하여 공유함 18 | 19 | Stack과 데이터를 나눈 이유는, 스택 구조의 특성과 전역 변수의 활용성을 위한 것! 20 | 21 |
22 | 23 | 24 | 25 | ``` 26 | 프로그램의 함수와 지역 변수는, LIFO(가장 나중에 들어간게 먼저 나옴)특성을 가진 스택에서 실행된다. 27 | 따라서 이 함수들 안에서 공통으로 사용하는 '전역 변수'는 따로 지정해주면 메모리를 아낄 수 있다. 28 | ``` 29 | -------------------------------------------------------------------------------- /Computer Science/Operating System/Process Management & PCB.md: -------------------------------------------------------------------------------- 1 | ## PCB & Context Switching 2 | 3 |
4 | 5 | #### Process Management 6 | 7 | > CPU가 프로세스가 여러개일 때, CPU 스케줄링을 통해 관리하는 것을 말함 8 | 9 | 이때, CPU는 각 프로세스들이 누군지 알아야 관리가 가능함 10 | 11 | 프로세스들의 특징을 갖고있는 것이 바로 `Process Metadata` 12 | 13 | - Process Metadata 14 | - Process ID 15 | - Process State 16 | - Process Priority 17 | - CPU Registers 18 | - Owner 19 | - CPU Usage 20 | - Memeory Usage 21 | 22 | 이 메타데이터는 프로세스가 생성되면 `PCB(Process Control Block)`이라는 곳에 저장됨 23 | 24 |
25 | 26 | #### PCB(Process Control Block) 27 | 28 | > 프로세스 메타데이터들을 저장해 놓는 곳, 한 PCB 안에는 한 프로세스의 정보가 담김 29 | 30 | 31 | 32 | ##### 다시 정리해보면? 33 | 34 | ``` 35 | 프로그램 실행 → 프로세스 생성 → 프로세스 주소 공간에 (코드, 데이터, 스택) 생성 36 | → 이 프로세스의 메타데이터들이 PCB에 저장 37 | ``` 38 | 39 |
40 | 41 | ##### PCB가 왜 필요한가요? 42 | 43 | > CPU에서는 프로세스의 상태에 따라 교체작업이 이루어진다. (interrupt가 발생해서 할당받은 프로세스가 wating 상태가 되고 다른 프로세스를 running으로 바꿔 올릴 때) 44 | > 45 | > 이때, **앞으로 다시 수행할 대기 중인 프로세스에 관한 저장 값을 PCB에 저장해두는 것**이다. 46 | 47 | ##### PCB는 어떻게 관리되나요? 48 | 49 | > Linked List 방식으로 관리함 50 | > 51 | > PCB List Head에 PCB들이 생성될 때마다 붙게 된다. 주소값으로 연결이 이루어져 있는 연결리스트이기 때문에 삽입 삭제가 용이함. 52 | > 53 | > 즉, 프로세스가 생성되면 해당 PCB가 생성되고 프로세스 완료시 제거됨 54 | 55 |
56 | 57 |
58 | 59 | 이렇게 수행 중인 프로세스를 변경할 때, CPU의 레지스터 정보가 변경되는 것을 `Context Switching`이라고 한다. 60 | 61 | #### Context Switching 62 | 63 | > CPU가 이전의 프로세스 상태를 PCB에 보관하고, 또 다른 프로세스의 정보를 PCB에 읽어 레지스터에 적재하는 과정 64 | 65 | 보통 인터럽트가 발생하거나, 실행 중인 CPU 사용 허가시간을 모두 소모하거나, 입출랙을 위해 대기해야 하는 경우에 Context Switching이 발생 66 | 67 | `즉, 프로세스가 Ready → Running, Running → Ready, Running → Waiting처럼 상태 변경 시 발생!` 68 | 69 |
70 | 71 | ##### Context Switching의 OverHead란? 72 | 73 | overhead는 과부하라는 뜻으로 보통 안좋은 말로 많이 쓰인다. 74 | 75 | 하지만 프로세스 작업 중에는 OverHead를 감수해야 하는 상황이 있다. 76 | 77 | ``` 78 | 프로세스를 수행하다가 입출력 이벤트가 발생해서 대기 상태로 전환시킴 79 | 이때, CPU를 그냥 놀게 놔두는 것보다 다른 프로세스를 수행시키는 것이 효율적 80 | ``` 81 | 82 | 즉, CPU에 계속 프로세스를 수행시키도록 하기 위해서 다른 프로세스를 실행시키고 Context Switching 하는 것 83 | 84 | CPU가 놀지 않도록 만들고, 사용자에게 빠르게 일처리를 제공해주기 위한 것이다. -------------------------------------------------------------------------------- /Computer Science/Operating System/Process vs Thread.md: -------------------------------------------------------------------------------- 1 | # 프로세스 & 스레드 2 | 3 |
4 | 5 | > **프로세스** : 프로그램을 메모리 상에서 실행중인 작업 6 | > 7 | > **스레드** : 프로세스 안에서 실행되는 여러 흐름 단위 8 | 9 |
10 | 11 | 기본적으로 프로세스마다 최소 1개의 스레드 소유 (메인 스레드 포함) 12 | 13 |
14 | 15 | ![img](https://camo.githubusercontent.com/3dc4ad61f03160c310a855a4bd68a9f2a2c9a4c7/68747470733a2f2f74312e6461756d63646e2e6e65742f6366696c652f746973746f72792f393938383931343635433637433330363036) 16 | 17 | 프로세스는 각각 별도의 주소공간 할당 (독립적) 18 | 19 | - Code : 코드 자체를 구성하는 메모리 영역(프로그램 명령) 20 | 21 | - Data : 전역변수, 정적변수, 배열 등 22 | - 초기화 된 데이터는 data 영역에 저장 23 | - 초기화 되지 않은 데이터는 bss 영역에 저장 24 | - Heap : 동적 할당 시 사용 (new(), malloc() 등) 25 | 26 | - Stack : 지역변수, 매개변수, 리턴 값 (임시 메모리 영역) 27 | 28 |
29 | 30 | 스레드는 Stack만 따로 할당 받고 나머지 영역은 서로 공유 31 | 32 | - Stack 영역만 따로 할당 받는 이유 33 | - 쓰레드는 독립적인 동작을 수행하기 위해 존재 한다 34 | - 즉 독립적으로 함수를 호출 할 수 있어야 한다 35 | - 때문에 함수의 매개변수, 지역변수등을 저장하는 스택 메모리 영역은 독립적으로 할당 받아야 한다 36 | 37 |
38 | 39 | 하나의 프로세스가 생성될 때, 기본적으로 하나의 스레드 같이 생성 40 | 41 |
42 | 43 | **프로세스는 자신만의 고유 공간과 자원을 할당받아 사용**하는데 반해, **스레드는 다른 스레드와 공간, 자원을 공유하면서 사용**하는 차이가 존재함 44 | 45 |
46 | 47 |
48 | 49 | ##### 멀티프로세스 50 | 51 | > 하나의 프로그램을 여러개의 프로세스로 구성하여 각 프로세스가 병렬적으로 작업을 수행하는 것 52 | 53 | **장점** : 안전성 (메모리 침범 문제를 OS 차원에서 해결) 54 | 55 | **단점** : 각각 독립된 메모리 영역을 갖고 있어, 작업량 많을 수록 오버헤드 발생. Context Switching으로 인한 성능 저하 56 | 57 |
58 | 59 | ***Context Switching*이란?** 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 | - 멀티스레드의 안전성에 대한 단점은 Critical Section 기법을 통해 대비함 85 | 86 | > 하나의 스레드가 공유 데이터 값을 변경하는 시점에 다른 스레드가 그 값을 읽으려할 때 발생하는 문제를 해결하기 위한 동기화 과정 87 | > 88 | > ``` 89 | > 상호 배제, 진행, 한정된 대기를 충족해야함 90 | > ``` 91 | -------------------------------------------------------------------------------- /Computer Science/Operating System/Race Condition.md: -------------------------------------------------------------------------------- 1 | ## [OS] Race Condition 2 | 3 | 공유 자원에 대해 여러 프로세스가 동시에 접근할 때, 결과값에 영향을 줄 수 있는 상태 4 | 5 | > 동시 접근 시 자료의 일관성을 해치는 결과가 나타남 6 | 7 |
8 | 9 | #### Race Condition이 발생하는 경우 10 | 11 | 1. ##### 커널 작업을 수행하는 중에 인터럽트 발생 12 | 13 | - 문제점 : 커널모드에서 데이터를 로드하여 작업을 수행하다가 인터럽트가 발생하여 같은 데이터를 조작하는 경우 14 | - 해결법 : 커널모드에서 작업을 수행하는 동안, 인터럽트를 disable 시켜 CPU 제어권을 가져가지 못하도록 한다. 15 | 16 | 2. ##### 프로세스가 'System Call'을 하여 커널 모드로 진입하여 작업을 수행하는 도중 문맥 교환이 발생할 때 17 | 18 | - 문제점 : 프로세스1이 커널모드에서 데이터를 조작하는 도중, 시간이 초과되어 CPU 제어권이 프로세스2로 넘어가 같은 데이터를 조작하는 경우 ( 프로세스2가 작업에 반영되지 않음 ) 19 | - 해결법 : 프로세스가 커널모드에서 작업을 하는 경우 시간이 초과되어도 CPU 제어권이 다른 프로세스에게 넘어가지 않도록 함 20 | 21 | 3. ##### 멀티 프로세서 환경에서 공유 메모리 내의 커널 데이터에 접근할 때 22 | 23 | - 문제점 : 멀티 프로세서 환경에서 2개의 CPU가 동시에 커널 내부의 공유 데이터에 접근하여 조작하는 경우 24 | - 해결법 : 커널 내부에 있는 각 공유 데이터에 접근할 때마다, 그 데이터에 대한 lock/unlock을 하는 방법 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Computer Science/Software Engineering/데브옵스(DevOps).md: -------------------------------------------------------------------------------- 1 | ## 데브옵스(DevOps) 2 | 3 |
4 | 5 | > Development + Operations의 합성어 6 | 7 | 소프트웨어 개발자와 정보기술 전문가 간의 소통, 협업 및 통합을 강조하는 개발 환경이나 문화를 의미한다. 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 | - [링크](https://post.naver.com/viewer/postView.nhn?volumeNo=16319612&memberNo=202219) -------------------------------------------------------------------------------- /Computer Science/Software Engineering/마이크로서비스 아키텍처(MSA).md: -------------------------------------------------------------------------------- 1 | # 마이크로서비스 아키텍처(MSA) 2 | 3 |
4 | 5 | ``` 6 | MSA는 소프트웨어 개발 기법 중 하나로, 어플리케이션 단위를 '목적'으로 나누는 것이 핵심 7 | ``` 8 | 9 |
10 | 11 | ## Monolithic vs MSA 12 | 13 | MSA가 도입되기 전, Monolithic 아키텍처 방식으로 개발이 이루어졌다. Monolithic의 사전적 정의에 맞게 '한 덩어리'에 해당하는 구조로 이루어져 있다. 모든 기능을 하나의 어플리케이션에서 비즈니스 로직을 구성해 운영한다. 따라서 개발을 하거나 환경설정에 있어서 간단한 장점이 있어 작은 사이즈의 프로젝트에서는 유리하지만, 시스템이 점점 확장되거나 큰 프로젝트에서는 단점들이 존재한다. 14 | 15 | - 빌드/테스트 시간의 증가 : 하나를 수정해도 시스템 전체를 빌드해야 함. 즉, 유지보수가 힘들다 16 | - 작은 문제가 시스템 전체에 문제를 일으킴 : 만약 하나의 서비스 부분에 트래픽 문제로 서버가 다운되면, 모든 서비스 이용이 불가능할 것이다. 17 | - 확장성에 불리 : 서비스 마다 이용률이 다를 수 있다. 하나의 서비스를 확장하기 위해 전체 프로젝트를 확장해야 한다. 18 | 19 |
20 | 21 | MSA는 좀 더 세분화 시킨 아키텍처라고 말할 수 있다. 한꺼번에 비즈니스 로직을 구성하던 Monolithic 방식과는 다르게 기능(목적)별로 컴포넌트를 나누고 조합할 수 있도록 구축한다. 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | MSA에서 각 컴포넌트는 API를 통해 다른 서비스와 통신을 하는데, 모든 서비스는 각각 독립된 서버로 운영하고 배포하기 때문에 서로 의존성이 없다. 하나의 서비스에 문제가 생겨도 다른 서비스에는 영향을 끼치지 않으며, 서비스 별로 부분적인 확장이 가능한 장점이 있다. 30 | 31 | 32 | 33 | 즉, 서비스 별로 개발팀이 꾸려지면 다른 팀과 의존없이 팀 내에서 피드백을 빠르게 할 수 있고, 비교적 유연하게 운영이 가능할 것이다. 34 | 35 | 좋은 점만 있지는 않다. MSA는 서비스 별로 호출할 때 API로 통신하므로 속도가 느리다. 그리고 서비스 별로 통신에 맞는 데이터로 맞추는 과정이 필요하기도 하다. Monolithic 방식은 하나의 프로세스 내에서 진행되기 때문에 속도 면에서는 MSA보다 훨씬 빠를 것이다. 또한, MSA는 DB 또한 개별적으로 운영되기 때문에 트랜잭션으로 묶기 힘든 점도 있다. 36 | 37 |
38 | 39 | 따라서, 서비스별로 분리를 하면서 얻을 수 있는 장점도 있지만, 그만큼 체계적으로 준비돼 있지 않으면 MSA로 인해 오히려 프로젝트 성능이 떨어질 수도 있다는 점을 알고있어야 한다. 정답이 정해져 있는 것이 아니라, 프로젝트 목적, 현재 상황에 맞는 아키텍처 방식이 무엇인지 설계할 때부터 잘 고민해서 선택하자. 40 | 41 |
42 | 43 |
44 | 45 | #### [참고 자료] 46 | 47 | - [링크](https://medium.com/@shaul1991/%EC%B4%88%EB%B3%B4%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%9D%BC%EC%A7%80-%EB%8C%80%EC%84%B8-msa-%EB%84%88-%EB%AD%90%EB%8B%88-efba5cfafdeb) 48 | - [링크](http://clipsoft.co.kr/wp/blog/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98msa-%EA%B0%9C%EB%85%90/) -------------------------------------------------------------------------------- /Computer Science/Software Engineering/써드파티(3rd party)란.md: -------------------------------------------------------------------------------- 1 | ## 써드 파티(3rd party)란? 2 | 3 |
4 | 5 | 간혹 써드 파티라는 말을 종종 볼 수 있다. 경제 용어가 IT에서 쓰이는 부분이다. 6 | 7 | ##### *3rd party* 8 | 9 | > 하드웨어 생산자와 소프트웨어 개발자의 관계를 나타낼 때 사용한다. 10 | > 11 | > 그 중에서 **서드파티**는, 프로그래밍을 도와주는 라이브러리를 만드는 외부 생산자를 뜻한다. 12 | > 13 | > ``` 14 | > ex) 게임제조사와 소비자를 연결해주는 게임회사(퍼플리싱) 15 | > 스마일게이트와 같은 회사 16 | > ``` 17 | 18 |
19 | 20 | ##### *개발자 측면으로 보면?* 21 | 22 | - 하드웨어 생산자가 '직접' 소프트웨어를 개발하는 경우 : 퍼스트 파티 개발자 23 | - 하드웨어 생산자인 기업과 자사간의 관계(또는 하청업체)에 속한 소프트웨어 개발자 : **세컨드 파티 개발자** 24 | - 아무 관련없는 제3자 소프트웨어 개발자 : 서드 파티 개발자 25 | 26 |
27 | 28 | 주로 편한 개발을 위해 `플러그인`이나 `라이브러리` 혹은 `프레임워크`를 사용하는데, 이처럼 제 3자로 중간다리 역할로 도움을 주는 것이 **서드 파티**로 볼 수 있고, 이런 것을 만드는 개발자가 **서드 파티 개발자**다. 29 | 30 |
31 | 32 |
33 | 34 | ##### [참고 사항] 35 | 36 | - [링크](https://ko.wikipedia.org/wiki/%EC%84%9C%EB%93%9C_%ED%8C%8C%ED%8B%B0_%EA%B0%9C%EB%B0%9C%EC%9E%90) -------------------------------------------------------------------------------- /Design Pattern/Design Pattern_Adapter.md: -------------------------------------------------------------------------------- 1 | #### Design Pattern - Adapter Pattern 2 | 3 | --- 4 | 5 | [어댑터 패턴] 6 | 7 | 국가별 사용하는 전압이 달라서 220v를 110v형으로 바꿔서 끼우는 경우를 생각해보기. 8 | 9 | - 실행 부분 (Main.java) 10 | 11 | ```java 12 | public class Main { 13 | public static void main (String[] args) { 14 | MediaPlayer player = new MP3(); 15 | player.play("file.mp3"); 16 | 17 | // MediaPlayer로 실행 못하는 MP4가 있음. 18 | // 이것을 mp3처럼 실행시키기 위해서, 19 | // Adapter를 생성하기. 20 | player = new FormatAdapter(new MP4()); 21 | player.play("file.mp4"); 22 | } 23 | } 24 | ``` 25 | 26 | - 변환 장치 부분 (FormatAdapter.java) 27 | 28 | ```java 29 | // MediaPlayer의 기능을 활용하기 위해 FormatAdapter라는 새로운 클래스를 생성 30 | // 그리고 그 클래스 내부에 (MP4, MKV와 같은) 클래스를 정리하려고 함. 31 | public class FormatAdapter implements MediaPlayer { 32 | private MediaPackage media; 33 | public FormatAdapter(MediaPackage m) { 34 | media = m; 35 | } 36 | // 그리고 반드시 사용해야하는 클래스의 함수를 선언해 둠 37 | @Override 38 | public void play(String filename) { 39 | System.out.print("Using Adapter"); 40 | media.playFile(filename); 41 | } 42 | } 43 | ``` 44 | 45 | -------------------------------------------------------------------------------- /Design Pattern/Design Pattern_Factory Method.md: -------------------------------------------------------------------------------- 1 | #### Design Pattern - Factory Method Pattern 2 | 3 | --- 4 | 5 | 한 줄 설명 : 객체를 만드는 부분을 Sub class에 맡기는 패턴. 6 | 7 | > Robot (추상 클래스) 8 | > 9 | > ​ ㄴ SuperRobot 10 | > 11 | > ​ ㄴ PowerRobot 12 | > 13 | > RobotFactory (추상 클래스) 14 | > 15 | > ​ ㄴ SuperRobotFactory 16 | > 17 | > ​ ㄴ ModifiedSuperRobotFactory 18 | 19 | 즉 Robot이라는 클래스를 RobotFactory에서 생성함. 20 | 21 | - RobotFactory 클래스 생성 22 | 23 | ```java 24 | public abstract class RobotFactory { 25 | abstract Robot createRobot(String name); 26 | } 27 | ``` 28 | 29 | * SuperRobotFactory 클래스 생성 30 | 31 | ```java 32 | public class SuperRobotFactory extends RobotFactory { 33 | @Override 34 | Robot createRobot(String name) { 35 | switch(name) { 36 | case "super" : 37 | return new SuperRobot(); 38 | case "power" : 39 | return new PowerRobot(); 40 | } 41 | return null; 42 | } 43 | } 44 | ``` 45 | 46 | 생성하는 클래스를 따로 만듬... 47 | 48 | 그 클래스는 factory 클래스를 상속하고 있기 때문에, 반드시 createRobot을 선언해야 함. 49 | 50 | name으로 건너오는 값에 따라서, 생성되는 Robot이 다르게 설계됨. 51 | 52 | --- 53 | 54 | 정리하면, 생성하는 객체를 별도로 둔다. 그리고, 그 객체에 넘어오는 값에 따라서, 다른 로봇 (피자)를 만들어 낸다. 55 | 56 | -------------------------------------------------------------------------------- /Design Pattern/Design Pattern_Template Method.md: -------------------------------------------------------------------------------- 1 | #### 디자인 패턴 _ Template Method Pattern 2 | 3 | --- 4 | 5 | [디자인 패턴 예] 6 | 7 | 1. 템플릿 메서드 패턴 8 | 9 | 특정 환경 or 상황에 맞게 확장, 변경할 때 유용한 패턴 10 | 11 | **추상 클래스, 구현 클래스** 둘로 구분. 12 | 13 | 추상클래스 (Abstract Class) : 메인이 되는 로직 부분은 일반 메소드로 선언해 둠. 14 | 15 | 구현클래스 (Concrete Class) : 메소드를 선언 후 호출하는 방식. 16 | 17 | - 장점 18 | - 구현 클래스에서는 추상 클래스에 선언된 메소드만 사용하므로, **핵심 로직 관리가 용이** 19 | - 객체 추가 및 확장 가능 20 | - 단점 21 | - 추상 메소드가 많아지면, 클래스 관리가 복잡함. 22 | 23 | * 설명 24 | 25 | 1) HouseTemplate.java 26 | 27 | > Template 추상 클래스를 하나 생성. (예, HouseTemplate) 28 | > 29 | > 이 HouseTemplate을 사용할 때는, 30 | > 31 | > "HouseTemplate houseType = new WoodenHouse()" 이런 식으로 넣음. 32 | > 33 | > HouseTemplate 내부에 **buildHouse**라는 변해서는 안되는 핵심 로직을 만들어 놓음. (장점 1) 34 | > 35 | > Template 클래스 내부의 **핵심 로직 내부의 함수**를 상속하는 클래스가 직접 구현하도록, abstract를 지정해 둠. 36 | 37 | ```java 38 | public abstract class HouseTemplate { 39 | 40 | // 이런 식으로 buildHouse라는 함수 (핵심 로직)을 선언해 둠. 41 | public final void buildHouse() { 42 | buildFoundation(); // (1) 43 | buildPillars(); // (2) 44 | buildWalls(); // (3) 45 | buildWindows(); // (4) 46 | System.out.println("House is built."); 47 | } 48 | 49 | // buildFoundation(); 정의 부분 (1) 50 | // buildWalls(); 정의 부분 (2) 51 | 52 | // 위의 두 함수와는 다르게 이 클래스를 상속받는 클래스가 별도로 구현했으면 하는 메소드들은 abstract로 선언하여, 정의하도록 함 53 | public abstract void buildWalls(); // (3) 54 | public abstract void buildPillars();// (4) 55 | 56 | } 57 | 58 | ``` 59 | 60 | 61 | 62 | 2) WoodenHouse.java (GlassHouse.java도 가능) 63 | 64 | > HouseTemplate을 상속받는 클래스. 65 | > 66 | > Wooden이나, Glass에 따라서 buildHouse 내부의 핵심 로직이 바뀔 수 있으므로, 67 | > 68 | > 이 부분을 반드시 선언하도록 지정해둠. 69 | 70 | ```java 71 | public class WoodenHouse extends HouseTemplate { 72 | @Override 73 | public void buildWalls() { 74 | System.out.println("Building Wooden Walls"); 75 | } 76 | @Override 77 | public void buildPillars() { 78 | System.out.println("Building Pillars with Wood coating"); 79 | } 80 | } 81 | ``` 82 | 83 | -------------------------------------------------------------------------------- /Design Pattern/Strategy Pattern.md: -------------------------------------------------------------------------------- 1 | ## 스트레티지 패턴(Strategy Pattern) 2 | 3 | > 어떤 동작을 하는 로직을 정의하고, 이것들을 하나로 묶어(캡슐화) 관리하는 패턴 4 | 5 | 새로운 로직을 추가하거나 변경할 때, 한번에 효율적으로 변경이 가능하다. 6 | 7 |
8 | 9 | ``` 10 | [ 슈팅 게임을 설계하시오 ] 11 | 유닛 종류 : 전투기, 헬리콥터 12 | 유닛들은 미사일을 발사할 수 있다. 13 | 전투기는 직선 미사일을, 헬리콥터는 유도 미사일을 발사한다. 14 | 필살기로는 폭탄이 있는데, 전투기에는 있고 헬리콥터에는 없다. 15 | ``` 16 | 17 |
18 | 19 | Strategy pattern을 적용한 설계는 아래와 같다. 20 | 21 | 22 | 23 | > 상속은 무분별한 소스 중복이 일어날 수 있으므로, 컴포지션을 활용한다. (인터페이스와 로직의 클래스와의 관계를 컴포지션하고, 유닛에서 상황에 맞는 로직을 쓰게끔 유도하는 것) 24 | 25 |
26 | 27 | - ##### 미사일을 쏘는 것과 폭탄을 사용하는 것을 캡슐화하자 28 | 29 | ShootAction과 BombAction으로 인터페이스를 선언하고, 각자 필요한 로직을 클래스로 만들어 implement한다. 30 | 31 | - ##### 전투기와 헬리콥터를 묶을 Unit 추상 클래스를 만들자 32 | 33 | Unit에는 공통적으로 사용되는 메서드들이 들어있고, 미사일과 폭탄을 선언하기 위해 variable로 인터페이스들을 선언한다. 34 | 35 |
36 | 37 | 전투기와 헬리콥터는 Unit 클래스를 상속받고, 생성자에 맞는 로직을 정의해주면 끝난다. 38 | 39 | ##### 전투기 예시 40 | 41 | ```java 42 | class Fighter extends Unit { 43 | private ShootAction shootAction; 44 | private BombAction bombAction; 45 | 46 | public Fighter() { 47 | shootAction = new OneWayMissle(); 48 | bombAction = new SpreadBomb(); 49 | } 50 | } 51 | ``` 52 | 53 | `Fighter.doAttack()`을 호출하면, OneWayMissle의 attack()이 호출될 것이다. 54 | 55 |
56 | 57 | #### 정리 58 | 59 | 이처럼 Strategy Pattern을 활용하면 로직을 독립적으로 관리하는 것이 편해진다. 로직에 들어가는 '행동'을 클래스로 선언하고, 인터페이스와 연결하는 방식으로 구성하는 것! 60 | 61 |
62 | 63 |
64 | 65 | ##### [참고] 66 | 67 | [링크]() 68 | 69 | -------------------------------------------------------------------------------- /Design Pattern/Template Method Pattern.md: -------------------------------------------------------------------------------- 1 | ## [디자인 패턴] Template Method Pattern 2 | 3 | > 로직을 단계 별로 나눠야 하는 상황에서 적용한다. 4 | > 5 | > 단계별로 나눈 로직들이 앞으로 수정될 가능성이 있을 경우 더 효율적이다. 6 | 7 |
8 | 9 | #### 조건 10 | 11 | - 클래스는 추상(abstract)로 만든다. 12 | - 단계를 진행하는 메소드는 수정이 불가능하도록 final 키워드를 추가한다. 13 | - 각 단계들은 외부는 막고, 자식들만 활용할 수 있도록 protected로 선언한다. 14 | 15 |
16 | 17 | 예를 들어보자. 피자를 만들 때는 크게 `반죽 → 토핑 → 굽기` 로 3단계로 이루어져있다. 18 | 19 | 이 단계는 항상 유지되며, 순서가 바뀔 일은 없다. 물론 실제로는 도우에 따라 반죽이 달라질 수 있겠지만, 일단 모든 피자의 반죽과 굽기는 동일하다고 가정하자. 그러면 피자 종류에 따라 토핑만 바꾸면 된다. 20 | 21 | ```java 22 | abstract class Pizza { 23 | 24 | protected void 반죽() { System.out.println("반죽!"); } 25 | abstract void 토핑() {} 26 | protected void 굽기() { System.out.println("굽기!"); } 27 | 28 | final void makePizza() { // 상속 받은 클래스에서 수정 불가 29 | this.반죽(); 30 | this.토핑(); 31 | this.굽기(); 32 | } 33 | 34 | } 35 | ``` 36 | 37 | ```java 38 | class PotatoPizza extends Pizza { 39 | 40 | @Override 41 | void 토핑() { 42 | System.out.println("고구마 넣기!"); 43 | } 44 | 45 | } 46 | 47 | class TomatoPizza extends Pizza { 48 | 49 | @Override 50 | void 토핑() { 51 | System.out.println("토마토 넣기!"); 52 | } 53 | 54 | } 55 | ``` 56 | 57 | abstract 키워드를 통해 자식 클래스에서는 선택적으로 메소드를 오버라이드 할 수 있게 된다. 58 | 59 |
60 | 61 |
62 | 63 | #### abstract와 Interface의 차이는? 64 | 65 | - abstract : 부모의 기능을 자식에서 확장시켜나가고 싶을 때 66 | - interface : 해당 클래스가 가진 함수의 기능을 활용하고 싶을 때 67 | 68 | > abstract는 다중 상속이 안된다. 상황에 맞게 활용하자! 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Design Pattern/[Design Pattern] Overview.md: -------------------------------------------------------------------------------- 1 | ### [Design Pattern] 개요 2 | 3 | --- 4 | 5 | > 일종의 설계 기법이며, 설계 방법이다. 6 | 7 | 8 | 9 | * #### 목적 10 | 11 | SW **재사용성, 호환성, 유지 보수성**을 보장. 12 | 13 |
14 | 15 | * #### 특징 16 | 17 | **디자인 패턴은 아이디어**임, 특정한 구현이 아님. 18 | 19 | 프로젝트에 항상 적용해야 하는 것은 아니지만, 추후 재사용, 호환, 유지 보수시 발생하는 **문제 해결을 예방하기 위해 패턴을 만들어 둔 것**임. 20 | 21 |
22 | 23 | * #### 원칙 24 | 25 | ##### SOLID (객체지향 설계 원칙) 26 | 27 | (간략한 설명) 28 | 29 | 1. ##### Single Responsibility Principle 30 | 31 | > 하나의 클래스는 하나의 역할만 해야 함. 32 | 33 | 2. ##### Open - Close Principle 34 | 35 | > 확장 (상속)에는 열려있고, 수정에는 닫혀 있어야 함. 36 | 37 | 3. ##### Liskov Substitution Principle 38 | 39 | > 자식이 부모의 자리에 항상 교체될 수 있어야 함. 40 | 41 | 4. ##### Interface Segregation Principle 42 | 43 | > 인터페이스가 잘 분리되어서, 클래스가 꼭 필요한 인터페이스만 구현하도록 해야함. 44 | 45 | 5. ##### Dependency Inversion Property 46 | 47 | > 상위 모듈이 하위 모듈에 의존하면 안됨. 48 | > 49 | > 둘 다 추상화에 의존하며, 추상화는 세부 사항에 의존하면 안됨. 50 | 51 |
52 | 53 | * #### 분류 (중요) 54 | 55 | `3가지 패턴의 목적을 이해하기!` 56 | 57 | 1. 생성 패턴 (Creational) : 객체의 **생성 방식** 결정 58 | 59 | Class-creational patterns, Object-creational patterns. 60 | 61 | ```text 62 | 예) DBConnection을 관리하는 Instance를 하나만 만들 수 있도록 제한하여, 불필요한 연결을 막음. 63 | ``` 64 | 65 |
66 | 67 | 2. 구조 패턴 (Structural) : 객체간의 **관계**를 조직 68 | 69 | ```text 70 | 예) 2개의 인터페이스가 서로 호환이 되지 않을 때, 둘을 연결해주기 위해서 새로운 클래스를 만들어서 연결시킬 수 있도록 함. 71 | ``` 72 | 73 |
74 | 75 | 3. 행위 패턴 (Behavioral): 객체의 **행위**를 조직, 관리, 연합 76 | 77 | ```text 78 | 예) 하위 클래스에서 구현해야 하는 함수 및 알고리즘들을 미리 선언하여, 상속시 이를 필수로 구현하도록 함. 79 | ``` 80 | 81 |
82 | 83 | -------------------------------------------------------------------------------- /ETC/Git Commit Message Convention.md: -------------------------------------------------------------------------------- 1 | # Git Commit Message Convention 2 | 3 |
4 | 5 | Git은 컴퓨터 파일의 변경사항을 추적하고 여러 명의 사용자들 간에 해당 파일들의 작업을 조율하기 위한 분산 버전 관리 시스템이다. 따라서, 커밋 메시지를 작성할 때 사용자 간 원활한 소통을 위해 일관된 형식을 사용하면 많은 도움이 된다. 6 | 7 | 기업마다 다양한 컨벤션이 존재하므로, 소속된 곳의 규칙에 따르면 되며 아래 예시는 'Udacity'의 커밋 메시지 스타일로 작성되었다. 8 | 9 |
10 | 11 | ### 커밋 메시지 형식 12 | 13 | ```bash 14 | type: Subject 15 | 16 | body 17 | 18 | footer 19 | ``` 20 | 21 | 기본적으로 3가지 영역(제목, 본문, 꼬리말)으로 나누어졌다. 22 | 23 | 메시지 type은 아래와 같이 분류된다. 아래와 같이 소문자로 작성한다. 24 | 25 | - `feat` : 새로운 기능 추가 26 | - `fix` : 버그 수정 27 | - `docs` : 문서 내용 변경 28 | - `style` : 포맷팅, 세미콜론 누락, 코드 변경이 없는 경우 등 29 | - `refactor` : 코드 리팩토링 30 | - `test` : 테스트 코드 작성 31 | - `chore` : 빌드 수정, 패키지 매니저 설정, 운영 코드 변경이 없는 경우 등 32 | 33 |
34 | 35 | #### Subject (제목) 36 | 37 | `Subject(제목)`은 최대 50글자가 넘지 않고, 마침표와 특수기호는 사용하지 않는다. 38 | 39 | 영문 표기 시, 첫글자는 대문자로 표기하며 과거시제를 사용하지 않는다. 그리고 간결하고 요점만 서술해야 한다. 40 | 41 | > Added (X) → Add (O) 42 | 43 |
44 | 45 | #### Body (본문) 46 | 47 | `Body (본문)`은 최대한 상세히 적고, `무엇`을 `왜` 진행했는 지 설명해야 한다. 만약 한 줄이 72자가 넘어가면 다음 문단으로 나눠 작성하도록 한다. 48 | 49 |
50 | 51 | #### Footer (꼬리말) 52 | 53 | `Footer (꼬리말)`은 이슈 트래커의 ID를 작성한다. 54 | 55 | 어떤 이슈와 관련된 커밋인지(Resolves), 그 외 참고할 사항이 있는지(See also)로 작성하면 좋다. 56 | 57 |
58 | 59 | ### 커밋 메시지 예시 60 | 61 | 위 내용을 작성한 커밋 메시지 예시다. 62 | 63 | ```markdown 64 | feat: Summarize changes in around 50 characters or less 65 | 66 | More detailed explanatory text, if necessary. Wrap it to about 72 67 | characters or so. In some contexts, the first line is treated as the 68 | subject of the commit and the rest of the text as the body. The 69 | blank line separating the summary from the body is critical (unless 70 | you omit the body entirely); various tools like `log`, `shortlog` 71 | and `rebase` can get confused if you run the two together. 72 | 73 | Explain the problem that this commit is solving. Focus on why you 74 | are making this change as opposed to how (the code explains that). 75 | Are there side effects or other unintuitive consequences of this 76 | change? Here's the place to explain them. 77 | 78 | Further paragraphs come after blank lines. 79 | 80 | - Bullet points are okay, too 81 | 82 | - Typically a hyphen or asterisk is used for the bullet, preceded 83 | by a single space, with blank lines in between, but conventions 84 | vary here 85 | 86 | If you use an issue tracker, put references to them at the bottom, 87 | like this: 88 | 89 | Resolves: #123 90 | See also: #456, #789 91 | ``` 92 | 93 |
94 | 95 |
96 | 97 | #### [참고 자료] 98 | 99 | - [링크](https://udacity.github.io/git-styleguide/) -------------------------------------------------------------------------------- /ETC/GitHub Fork로 협업하기.md: -------------------------------------------------------------------------------- 1 | ### GitHub Fork로 협업하기 2 | 3 | --- 4 | 5 | 1. Fork한 자신의 원격 저장소 확인 (최초에는 존재하지 않음) 6 | 7 | ```bash 8 | git remote -v 9 | ``` 10 | 11 | 2. Fork한 자신의 로컬 저장소에 Fork한 원격 저장소 등록 12 | 13 | ```bash 14 | git remote add upstream {원격저장소의 Git 주소} 15 | ``` 16 | 17 | 3. 등록된 원격 저장소 확인 18 | 19 | ```bash 20 | git remote -v 21 | ``` 22 | 23 | 4. 원격 저장소의 최신 내용을 Fork한 자신의 저장소에 업데이트 24 | 25 | ```bash 26 | git fetch upstream 27 | git checkout master 28 | git merge upstream/master 29 | ``` 30 | 31 | - pull : fetch + merge 32 | 33 |
34 | 35 | - [ref] 36 | - https://help.github.com/articles/configuring-a-remote-for-a-fork/ 37 | - https://help.github.com/articles/syncing-a-fork/ 38 | 39 | -------------------------------------------------------------------------------- /ETC/GitHub 저장소(repository) 미러링.md: -------------------------------------------------------------------------------- 1 | ### GitHub 저장소(repository) 미러링 2 | 3 | --- 4 | 5 | - ##### 미러링 : commit log를 유지하며 clone 6 | 7 | #####
8 | 9 | 1. #### 저장소 미러링 10 | 11 | 1. 복사하고자 하는 저장소의 bare clone 생성 12 | 13 | ```bach 14 | git clone --bare {복사하고자하는저장소의 git 주소} 15 | ``` 16 | 17 | 2. 새로운 저장소로 mirror-push 18 | 19 | ```bash 20 | cd {복사하고자하는저장소의git 주소} 21 | git push --mirror {붙여놓을저장소의git주소} 22 | ``` 23 | 24 | 3. 1번에서 생성된 저장소 삭제 25 | 26 |
27 | 28 | 1. #### 100MB를 넘어가는 파일을 가진 저장소 미러링 29 | 30 | 1. [git lfs](https://git-lfs.github.com/)와 [BFG Repo Cleaner](https://rtyley.github.io/bfg-repo-cleaner/) 설치 31 | 32 | 2. 복사하고자 하는 저장소의 bare clone 생성 33 | 34 | ```bach 35 | git clone --mirror {복사하고자하는저장소의 git 주소} 36 | ``` 37 | 38 | 3. commit history에서 large file을 찾아 트랙킹 39 | 40 | ```bash 41 | git filter-branch --tree-filter 'git lfs track "*.{zip,jar}"' -- --all 42 | ``` 43 | 44 | 4. BFG를 이용하여 해당 파일들을 git lfs로 변경 45 | 46 | ```bash 47 | java -jar ~/usr/bfg-repo-cleaner/bfg-1.13.0.jar --convert-to-git-lfs '*.zip' 48 | java -jar ~/usr/bfg-repo-cleaner/bfg-1.13.0.jar --convert-to-git-lfs '*.jar' 49 | ``` 50 | 51 | 5. 새로운 저장소로 mirror-push 52 | 53 | ```bash 54 | cd {복사하고자하는저장소의git 주소} 55 | git push --mirror {붙여놓을저장소의git주소} 56 | ``` 57 | 58 | 6. 1번에서 생성된 저장소 삭제 59 | 60 |
61 | 62 | - ref 63 | - [GitHub Help](https://help.github.com/articles/duplicating-a-repository/) 64 | - [stack overflow](https://stackoverflow.com/questions/37986291/how-to-import-git-repositories-with-large-files) 65 | 66 | -------------------------------------------------------------------------------- /ETC/OPIC.md: -------------------------------------------------------------------------------- 1 | ## OPIC 2 | 3 | > 인터뷰 형식의 영어 스피킹 시험 4 | 5 |
6 | 7 | 정형화된 비즈니스 영어에 가까운 토익스피킹과는 다르게 자유로운 실전 영어 스타일 8 | 9 | 문법, 단어의 완성도가 떨어져도 괜찮음. '나의 이야기'를 전달하고 내가 관심있는 소재에 대한 답변을 하는 스피킹 시험 10 | 11 |
12 | 13 | ### 출제 유형 14 | 15 | --- 16 | 17 | 1. #### 묘사하기 18 | 19 | ``` 20 | 'Describe your favourite celebrity.' 21 | 당신이 가장 좋아하는 연예인을 묘사해보세요 22 | ``` 23 | 24 |
25 | 26 | 2. #### 설명하기 27 | 28 | ``` 29 | 'Can you describe your typical day?' 30 | 당신의 일상을 말해줄 수 있나요? 31 | ``` 32 | 33 |
34 | 35 | 3. #### 가정하기 36 | 37 | ``` 38 | 'Your credit card stopped working. Ask a question to your card company.' 39 | 당신의 신용카드가 정지되었습니다. 카드 회사에 문의하세요. 40 | ``` 41 | 42 |
43 | 44 | 4. #### 콤보 (같은 주제에 대한 2~3문제) 45 | 46 | ``` 47 | 'What is your favorite food?' 48 | 'Can you tell me the steps to make your favorite food?' 49 | 'You are in restarurant. Can you order your favorite food?' 50 | ``` 51 | 52 |
53 | 54 |
55 | 56 | ### 참고사항 57 | 58 | --- 59 | 60 | - Survey에서 선택한 항목들이 나옴 61 | - 외운 답변은 감점한다는 항목이 있음 62 | 63 | - 40분간 15개에 대한 질문을 답변하는 형식 64 | 65 | - 오픽은 한 문제당 정해진 답변시간이 없음 66 | - 15문제를 다 못 끝내도 점수에는 영향이 없음 67 | 68 |
69 | 70 | 단어를 또박또박 발음하도록 연습하고, 이해가 되는 수준의 단어와 문법을 지키자 71 | 72 | 이야기를 할 때 논리적으로 말하자 73 | 74 | ``` 75 | First ~, Second ~ 76 | In the morning ~, In the afternoon ~ 77 | ``` 78 | 79 | -------------------------------------------------------------------------------- /ETC/[인적성] 명제 추리 풀이법.md: -------------------------------------------------------------------------------- 1 | ## [인적성] 명제 추리 풀이법 2 | 3 |
4 | 5 | 모든, 어떤이 들어간 문장에 대한 명제 추리는 항상 까다롭다. 이를 대우로 바꾸며 옳은 문장을 찾기 위한 문제는 인적성에서 꼭 나온다. 6 | 7 | 실제로 정확한 답을 유추하기 위해 벤다이어그램을 그리는 등 다양한 해결책을 제시하지만 실제 문제 풀이는 **1분안에 풀어야하므로 비효율적**이다. 약간 암기형으로 접근하자. 8 | 9 |
10 | 11 | 문장을 수식 기호로 간단히 바꾸기 12 | 13 | ``` 14 | 모든 = → 15 | 어떤 = & 16 | 부정 = ~ 17 | ``` 18 | 19 |
20 | 21 | #### ex) 모든 남자는 사람이다. 22 | 23 | `남자 → 사람` 24 | 25 | **모든**은 포함의 개념이므로 **대우도 가능** `~사람 → ~남자` 26 | 27 |
28 | 29 | #### ex) 어떤 여자는 사람이 아니다. 30 | 31 | `여자 & ~사람` 32 | 33 | **어떤**은 일부의 개념이므로 **대우X** 34 | 35 |
36 | 37 | #### 유형 1 38 | 39 | ``` 40 | 전제1 : 모든 취업준비생은 열심히 공부를 하는 사람이다. 41 | 전제2 : _______________________________________ 42 | 43 | 결론 : 어떤 열심히 공부하는 사람은 독서를 좋아하지 않는다. 44 | ``` 45 | 46 | **전제1,2에 모든으로 시작하는 문장과 어떤으로 시작하는 문장으로 구성되고, 결론에는 어떤으로 시작하는 문장으로 구성된 상황** 47 | 48 | 결론의 두 부분은 전제1의 **모든**으로 시작하는 뒷 부분, 전제2의 **어떤**으로 시작하는 문장 앞뒤 중 한개가 포함 49 | 50 | or 51 | 52 | 전제2의 **어떤** 중 나머지 한개는 전제1을 성립시키기위한 **모든**으로 시작하는 앞부분이 되야 함 53 | 54 | ``` 55 | 취업준비생 → 공부하는 사람 56 | ______________________ : 취업준비생 & ~독서를 좋아하는 사람 57 | 공부하는 사람 & ~독서를 좋아하는 사람 58 | ``` 59 | 60 |
61 | 62 | #### 유형 2 63 | 64 | ``` 65 | 전제1 : 모든 기술개발은 미래를 예측해야 한다. 66 | 전제2 : _________________________________ 67 | 68 | 결론 : 어떤 기술개발은 기업을 성공시킨다. 69 | ``` 70 | 71 | 유형 1의 전제2와 결론의 위치가 바뀐 상황 (즉, 전제1의 앞의 조건으로 전제2가 나오지 않고 결론으로 간 상황) 72 |
73 | 74 | ``` 75 | 기술개발 → 미래예측 76 | __________________ : 미래예측 → 기업성공 77 | 기술개발 & 기업성공 78 | ``` 79 | 80 |
81 | 82 |
83 | 84 | 확실히 이해가 안되면 그냥 외워서 맞추자. 여기에 시간낭비할 필요가 없으므로 빠르게 풀고 지나가야 함 -------------------------------------------------------------------------------- /ETC/임베디드 시스템.md: -------------------------------------------------------------------------------- 1 | ## 임베디드 시스템 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 | 30 | - 입출력 장치 31 | - Flash Memory 32 | - CPU 33 | - RAM 34 | - 통신장치 35 | - 회로기판 36 | 37 |
38 | 39 | #### 임베디드 소프트웨어 분류 40 | 41 | - 시스템 소프트웨어 : 시스템 전체 운영 담당 42 | - 응용 소프트웨어 : 입출력 장치 포함 특수 용도 작업 담당 (사용자와 대면) 43 | 44 |
45 | 46 | #### 펌웨어 기반 소프트웨어 47 | 48 | - 운영체제없이 하드웨어 시스템을 구동하기 위한 응용 프로그램 49 | - 간단한 임베디드 시스템의 소프트웨어 50 | 51 |
52 | 53 | #### 운영체제 기반 소프트웨어 54 | 55 | - 소프트웨어가 복잡해지면서 펌웨어 형태로는 한계 도달 56 | - 운영체제는 하드웨어에 의존적인 부분, 여러 프로그램이 공통으로 이용할 수 있는 부분을 별도로 분리하는 프로그램 57 | 58 |
59 | 60 |
61 | 62 | ##### [참고사항] 63 | 64 | - [링크](https://myeonguni.tistory.com/1739) 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /Interview/Mock Test/2019년 #기업 2차 필기테스트 유형.md: -------------------------------------------------------------------------------- 1 | 1. 데드락 2 | 2. IP 프로토콜 3 | 3. 서브넷 마스크(브로드캐스팅) 4 | 4. Isolation Level 5 | 5. 이진 탐색 트리 6 | 6. 버블 정렬 7 | 7. Round Robin 스케줄링 8 | 8. 페이징 번호 9 | 9. DB JOIN 10 | 10. C언어 Struct variable byte size 11 | 11. LRU 캐싱 12 | 12. Max Heap 13 | 13. 다익스트라 14 | 14. 부동소수점 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Interview/Mock Test/2019년 #기업 필기테스트.md: -------------------------------------------------------------------------------- 1 | 1. ##### 일치하는 자료구조 작성하기 2 | 3 | > 1) 문자열이 주어지고 빠른 검색 ~~ : 해시 4 | > 5 | > 2) 운영체제 라운드 로빈에서 사용 ~~ : 연결리스트 6 | > 7 | > 3) 우선순위로 뽑고 ~~~ : 힙 8 | > 9 | > 4) 후위연산하는 ~~ : 스택 10 | 11 | 2. ##### FCFS 스케줄링 평균반환시간, 평균대기시간 구하기 12 | 13 | 3. ##### 고객 - 주문 - 주문서의 (일대일, 일대다, 다대일, 다대다) 관계 구하기 14 | 15 | 4. ##### Binary Tree 수도코드 16 | 17 | > Tree node size 구하기 : left + right + 1 18 | > 19 | > Tree node depth 구하기 : max(left, right) + 1 20 | 21 | 5. ##### 배열 x와 배열 y의 일치값 찾는 시간복잡도의 최악과 최선은? 22 | 23 | ```java 24 | boolean chk = false; 25 | for(int i = 0; i < arr1.length i++) { 26 | for(int j = 0; j < arr2.length; j++) { 27 | if(arr1[i] == arr[j]) { 28 | chk = true; 29 | return; 30 | } 31 | } 32 | } 33 | ``` 34 | 35 | 6. ##### BFS 수도코드 36 | 37 | ``` 38 | 1) queue 생성 39 | 2) enqueue() 40 | while() { 41 | 3) dequeue() 42 | 43 | if() { 44 | 4) enqueue() 45 | } 46 | } 47 | ``` 48 | 49 | 6. ##### Binary Search 수도코드 50 | 51 | > start와 end를 어떻게 바꿔가야하는 지 작성 52 | > 53 | > ``` 54 | > if(arr[mid] < value) { 55 | > 1) start = mid + 1; 56 | > } 57 | > else(arr[mid] > value) { 58 | > 2) end = mid - 1; 59 | > } 60 | > ``` 61 | 62 | 7. ##### 데드락 교착 상태 4가지 63 | 64 | 8. ##### 제 2정규화 만들기 65 | 66 | > 1) 판매번호, 판매일자, 판매처 코드, 판매처명 67 | > 68 | > 2) 판매번호, 상품번호, 상품명, 단가, 수량 69 | > 70 | > 이 두개를 제2정규화 써서 다시 나누기 71 | 72 | -------------------------------------------------------------------------------- /Interview/Mock Test/2019년 면접질문.md: -------------------------------------------------------------------------------- 1 | 1. 퀵소트 구현하고 시간복잡도 설명 2 | 2. 최악으로 바꾸고 진행 3 | 3. 공간복잡도 4 | 4. 디자인패턴이 뭐로 나눠지는지 5 | 5. 아는거 다말하고 뭔지설명하면서 어디 영역에 해당하는지 6 | 6. PWA랑 SPA 차이점 7 | 7. Vue 라이프사이클 8 | 8. vue router를 어떻게 활용했는지 9 | 9. CPU 스케줄링 알고리즘이 뭐고 있는거 설명 10 | 10. 더블링크드리스트 구현 11 | 11. 페이지 교체 알고리즘 종류 12 | 12. 자바 빈 태그 그냥말고 커스터마이징해서 활용한 경험 13 | 14 | 15 | 16 | - Java와 Javascript의 차이 17 | - 객체 지향이란? 18 | - 캐시에 대해 설명해보면? 19 | - 스택에 대해 설명해보면? 20 | - UI와 UX의 차이 21 | - 네이티브 앱, 웹 앱, 하이브리드 앱의 차이는? 22 | - 애플리케이션 개발 경험이 있는지? 23 | - 가장 관심있는 신기술 트렌드는? 24 | - PWA가 뭔가? 25 | - 데브옵스가 뭔지 아는지? 26 | - 마이크로 서비스 애플리케이션(MSA)에 대해 아는가? 27 | - REST API란? -------------------------------------------------------------------------------- /Interview/README.md: -------------------------------------------------------------------------------- 1 | ### 기술 면접 준비하기 2 | 3 | ------ 4 | 5 | - #### 시작하기 6 | 7 | *기술면접을 준비할 때는 절대 문제와 답을 읽는 식으로 하지 말고, 문제를 직접 푸는 훈련을 해야합니다.* 8 | 9 | 1. ##### 직접 문제를 풀수 있도록 노력하자 10 | 11 | - 포기하지말고, 최대한 힌트를 보지말고 답을 찾자 12 | 13 | 2. ##### 코드를 종이에 적자 14 | 15 | - 컴퓨터를 이용하면 코드 문법 강조나, 자동완성 기능으로 도움 받을 수 있기 때문에 손으로 먼저 적는 연습하자 16 | 17 | 3. ##### 코드를 테스트하자 18 | 19 | - 기본 조건, 오류 발생 조건 등을 테스트 하자. 20 | 21 | 4. ##### 종이에 적은 코드를 그대로 컴퓨터로 옮기고 실행해보자 22 | 23 | - 종이로 적었을 때 실수를 많이 했을 것이다. 컴퓨터로 옮기면서 실수 목록을 적고 다음부터 저지르지 않도록 유의하자 24 | 25 |
26 | 27 | - #### 기술면접에서 필수로 알아야 하는 것 28 | 29 | 1. ##### 자료구조 30 | 31 | - 연결리스트(Linked Lists) 32 | - 트리, 트라이(Tries), 그래프 33 | - 스택 & 큐 34 | - 힙(Heaps) 35 | - Vector / ArrayList 36 | - 해시테이블 37 | 38 | 2. ##### 알고리즘 39 | 40 | - BFS (너비 우선 탐색) 41 | - DFS (깊이 우선 탐색) 42 | - 이진 탐색 43 | - 병합 정렬(Merge Sort) 44 | - 퀵 정렬 45 | 46 | 3. ##### 개념 47 | 48 | - 비트 조작(Bit Manipulation) 49 | - 메모리 (스택 vs 힙) 50 | - 재귀 51 | - DP (다이나믹 프로그래밍) 52 | - big-O (시간과 공간 개념) 53 | 54 |
55 | 56 | - #### 면접에서 문제가 주어지면 해야할 순서 57 | 58 | *면접관은 우리가 문제를 어떻게 풀었는 지, 과정을 알고 싶어하기 때문에 끊임없이 설명해야합니다!* 59 | 60 | 1. ##### 듣기 61 | 62 | - 문제 설명 관련 정보는 집중해서 듣자. 중요한 부분이 있을 수 있습니다. 63 | 64 | 2. ##### 예제 65 | 66 | - 직접 예제를 만들어서 디버깅하고 확인하기 67 | 68 | 3. ##### 무식하게 풀기 69 | 70 | - 처음에는 최적의 알고리즘을 생각하지말고 무식하게 풀어보기 71 | 72 | 4. ##### 최적화 73 | 74 | - BUD (병목현상, 불필요 작업, 중복 작업)을 최적화 시키며 개선하기 75 | 76 | 5. ##### 검토하기 77 | 78 | - 다시 처음부터 실수가 없는지 검토하기 79 | 80 | 6. ##### 구현하기 81 | 82 | - 모듈화된 코드 사용하기 83 | - 에러를 검증하기 84 | - 필요시, 다른 클래스나 구조체 사용하기 85 | - 좋은 변수명 사용하기 86 | 87 | 7. ##### 테스트 88 | 89 | - 개념적 테스트 - 코드 리뷰 90 | - 특이한 코드들 확인 91 | - 산술연산이나 NULL 노드 부분 실수 없나 확인 92 | - 작은 크기의 테스트들 확인 93 | 94 |
95 | 96 | - #### 오답 대처법 97 | 98 | *또한 면접은 '상대평가'입니다. 즉, 문제가 어렵다면 다른 사람도 마찬가지이므로 너무 두려워하지 말아야합니다.* 99 | 100 | - 면접관들은 답을 평가할 때 맞춤, 틀림으로 평가하지 않기 때문에, 면접에서 모든 문제의 정답을 맞춰야 할 필요는 없습니다. 101 | - 중요하게 여기는 부분 102 | - 얼마나 최종 답안이 최적 해법에 근접한가 103 | - 최종 답안을 내는데 시간이 얼마나 걸렸나 104 | - 얼마나 힌트를 필요로 했는가 105 | - 얼마나 코드가 깔끔한가 106 | 107 |
-------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Gyuseok Kim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Language/[C++] Vector Container.md: -------------------------------------------------------------------------------- 1 | # [C++] Vector Container 2 | 3 |
4 | 5 | ```cpp 6 | #include 7 | ``` 8 | 9 | 자동으로 메모리를 할당해주는 Cpp 라이브러리 10 | 11 | 데이터 타입을 정할 수 있으며, push pop은 스택과 유사한 방식이다. 12 | 13 |
14 | 15 | ## 생성 16 | 17 | - `vector<"Type"> v;` 18 | - `vector<"Type"> v2(v); ` : v2에 v 복사 19 | 20 | ### Function 21 | 22 | - `v.assign(5, 2);` : 2 값으로 5개 원소 할당 23 | - `v.at(index);` : index번째 원소 참조 (범위 점검 o) 24 | - `v[index];` : index번째 원소 참조 (범위 점검 x) 25 | - `v.front(); v.back();` : 첫번째와 마지막 원소 참조 26 | - `v.clear();` : 모든 원소 제거 (메모리는 유지) 27 | - `v.push_back(data); v.pop_back(data);` : 마지막 원소 뒤에 data 삽입, 마지막 원소 제거 28 | - `v.begin(); v.end();` : 첫번째 원소, 마지막의 다음을 가리킴 (iterator 필요) 29 | - `v.resize(n);` : n으로 크기 변경 30 | - `v.size();` : vector 원소 개수 리턴 31 | - `v.capacity();` : 할당된 공간 크기 리턴 32 | - `v.empty();` : 비어있는 지 여부 확인 (true, false) 33 | 34 | ``` 35 | capacity : 할당된 메모리 크기 36 | size : 할당된 메모리 원소 개수 37 | ``` 38 | 39 |
40 | 41 | ```cpp 42 | #include 43 | #include 44 | #include 45 | using namespace std; 46 | 47 | int main(void) { 48 | vector v; 49 | 50 | v.push_back(1); 51 | v.push_back(2); 52 | v.push_back(3); 53 | 54 | vector::iterator iter; 55 | for(iter = v.begin(); iter != v.end(); iter++) { 56 | cout << *iter << endl; 57 | } 58 | } 59 | ``` 60 | 61 |
62 | 63 |
64 | 65 | #### [참고 자료] 66 | 67 | - [링크](https://blockdmask.tistory.com/70) -------------------------------------------------------------------------------- /Language/[C++] 가상 함수(virtual function).md: -------------------------------------------------------------------------------- 1 | ### 가상 함수(virtual function) 2 | 3 | --- 4 | 5 | > C++에서 자식 클래스에서 재정의(오버라이딩)할 것으로 기대하는 멤버 함수를 의미함 6 | > 7 | > 멤버 함수 앞에 `virtual` 키워드를 사용하여 선언함 → 실행시간에 함수의 다형성을 구현할 때 사용 8 | 9 |
10 | 11 | ##### 선언 규칙 12 | 13 | - 클래스의 public 영역에 선언해야 한다. 14 | - 가상 함수는 static일 수 없다. 15 | - 실행시간 다형성을 얻기 위해, 기본 클래스의 포인터 또는 참조를 통해 접근해야 한다. 16 | - 가상 함수는 반환형과 매개변수가 자식 클래스에서도 일치해야 한다. 17 | 18 | ```c++ 19 | class parent { 20 | public : 21 | virtual void v_print() { 22 | cout << "parent" << "\n"; 23 | } 24 | void print() { 25 | cout << "parent" << "\n"; 26 | } 27 | }; 28 | 29 | class child : public parent { 30 | public : 31 | void v_print() { 32 | cout << "child" << "\n"; 33 | } 34 | void print() { 35 | cout << "child" << "\n"; 36 | } 37 | }; 38 | 39 | int main() { 40 | parent* p; 41 | child c; 42 | p = &c; 43 | 44 | p->v_print(); 45 | p->print(); 46 | 47 | return 0; 48 | } 49 | // 출력 결과 50 | // child 51 | // parent 52 | ``` 53 | 54 | parent 클래스를 가리키는 포인터 p를 선언하고 child 클래스의 객체 c를 선언한 상태 55 | 56 | 포인터 p가 c 객체를 가리키고 있음 (몸체는 parent 클래스지만, 현재 실제 객체는 child 클래스) 57 | 58 | 포인터 p를 활용해 `virtual`을 활용한 가상 함수인 `v_print()`와 오버라이딩된 함수 `print()`의 출력은 다르게 나오는 것을 확인할 수 있다. 59 | 60 | > 가상 함수는 실행시간에 값이 결정됨 (후기 바인딩) 61 | 62 | print()는 컴파일 시간에 이미 결정되어 parent가 호출되는 것으로 결정이 끝남 -------------------------------------------------------------------------------- /Language/[C++] 입출력 실행속도 줄이는 법.md: -------------------------------------------------------------------------------- 1 | ## [C++] 입출력 실행속도 줄이는 법 2 | 3 |
4 | 5 | C++로 알고리즘 문제를 풀 때, `cin, cout`은 실행속도가 느리다. 하지만 최적화 방법을 이용하면 실행속도 단축에 효율적이다. 6 | 7 | 만약 `cin, cout`을 문제풀이에 사용하고 싶다면, 시간을 단축하고 싶다면 사용하자 8 | 9 | ``` 10 | 최적화 시 거의 절반의 시간이 단축된다. 11 | ``` 12 | 13 |
14 | 15 | ```c++ 16 | int main(void) 17 | { 18 | ios_base :: sync_with_stdio(false); 19 | cin.tie(NULL); 20 | cout.tie(NULL); 21 | } 22 | ``` 23 | 24 | `ios_base`는 c++에서 사용하는 iostream의 cin, cout 등을 함축한다. 25 | 26 | `sync_with_stdio(false)`는 c언어의 stdio.h와 동기화하지만, 그 안에서 활용하는 printf, scanf, getchar, fgets, puts, putchar 등은 false로 동기화하지 않음을 뜻한다. 27 | 28 |
29 | 30 | ***주의*** 31 | 32 | ``` 33 | 따라서, cin/scanf와 cout/printf를 같이 쓰면 문제가 발생하므로 조심하자 34 | ``` 35 | 36 | 또한, 이는 싱글 스레드 환경에서만 효율적일뿐(즉, 알고리즘 문제 풀이할 때) 실무에선 사용하지 말자 37 | 38 | 그리고 크게 차이 안나므로 그냥 `printf/scanf` 써도 된다! -------------------------------------------------------------------------------- /Language/[C] 구조체 메모리 크기 계산.md: -------------------------------------------------------------------------------- 1 | ## [C] 구조체 메모리 크기 (Struct Memory Size) 2 | 3 | typedef struct 선언 시, 변수 선언에 대한 메모리 공간 크기에 대해 알아보자 4 | 5 | > 기업 필기 테스트에서 자주 나오는 유형이기도 함 6 | 7 |
8 | 9 | - char : 1바이트 10 | - int : 4바이트 11 | - double : 8바이트 12 | 13 | `sizeof` 메소드를 통해 해당 변수의 사이즈를 알 수 있음 14 | 15 |
16 | 17 | #### 크기 계산 18 | 19 | --- 20 | 21 | ```c 22 | typedef struct student { 23 | char a; 24 | int b; 25 | }S; 26 | 27 | void main() { 28 | printf("메모리 크기 = %d/n", sizeof(S)); // 8 29 | } 30 | ``` 31 | 32 | char는 1바이트고, int는 4바이트라서 5바이트가 필요하다. 33 | 34 | 하지만 메모리 공간은 5가 아닌 **8이 찍힐 것이다**. 35 | 36 | ***Why?*** 37 | 38 | 구조체가 메모리 공간을 잡는 원리에는 크게 두가지 규칙이 있다. 39 | 40 | 1. 각각의 멤버를 저장하기 위해서는 **기본 4바이트 단위로 구성**된다. (4의 배수 단위) 41 | 즉, char 데이터 1개를 저장할 때 이 1개의 데이터를 읽어오기 위해서 1바이트를 읽어오는 것이 아니라 이 데이터가 포함된 '4바이트'를 읽는다. 42 | 2. 구조체 각 멤버 중에서 가장 큰 멤버의 크기에 영향을 받는다. 43 | 44 |
45 | 46 | 이 규칙이 적용된 메모리 공간은 아래와 같을 것이다. 47 | 48 | a는 char형이지만, 기본 4바이트 단위 구성으로 인해 3바이트의 여유공간이 생긴다. 49 | 50 | 51 | 52 |
53 | 54 | 그렇다면 이와 같을 때는 어떨까? 55 | 56 | ```c 57 | typedef struct student { 58 | char a; 59 | char b; 60 | int c; 61 | }S; 62 | ``` 63 | 64 | 65 | 66 | 똑같이 8바이트가 필요하며, char형으로 선언된 a,b가 4바이트 안에 함께 들어가고 2바이트의 여유 공간이 생긴다. 67 | 68 |
69 | 70 | 이제부터 헷갈리는 경우다. 71 | 72 | ```c 73 | typedef struct student { 74 | char a; 75 | int c; 76 | char b; 77 | }S; 78 | ``` 79 | 80 | 구성은 같지만, 순서가 다르다. 81 | 82 | 자료타입은 일치하지만, 선언된 순서에 따라 할당되는 메모리 공간이 아래와 같이 달라진다. 83 | 84 | 85 | 86 | 이 경우에는 총 12바이트가 필요하게 된다. 87 | 88 |
89 | 90 | ```c 91 | typedef struct student { 92 | char a; 93 | int c; 94 | double b; 95 | }S; 96 | ``` 97 | 98 | 두 규칙이 모두 적용되는 상황이다. b가 double로 8바이트이므로 기본 공간이 8바이트로 설정된다. 하지만 a와 c는 8바이트로 해결이 가능하기 때문에 16바이트로 해결이 가능하다. 99 | 100 | 101 | 102 |
103 | 104 |
105 | 106 | ##### [참고자료] 107 | 108 | [링크]() -------------------------------------------------------------------------------- /Language/[C] 동적할당.md: -------------------------------------------------------------------------------- 1 | ## [C] 동적할당 2 | 3 |
4 | 5 | ##### *동적할당이란?* 6 | 7 | > 프로그램 실행 중에 동적으로 메모리를 할당하는 것 8 | > 9 | > Heap 영역에 할당한다 10 | 11 |
12 | 13 | - `` 헤더 파일을 include 해야한다. 14 | 15 | - 함수(Function) 16 | 17 | - 메모리 할당 함수 : malloc 18 | 19 | - `void* malloc(size_t size)` 20 | 21 | - 메모리 할당은 size_t 크기만큼 할당해준다. 22 | 23 | - 메모리 할당 및 초기화 : calloc 24 | 25 | - `void* calloc(size_t nelem, sizeo_t elsize)` 26 | - 첫번째 인자는 배열요소 개수, 두번째 인자는 각 배열요소 사이즈 27 | - 할당된 메모리를 0으로 초기화 28 | 29 | - 메모리 추가 할당 : realloc 30 | 31 | - `void* realloc(void *ptr, size_t size)` 32 | - 이미 할당받은 메모리에 추가로 메모리 할당 (이전 메모리 주소 없어짐) 33 | 34 | - 메모리 해제 함수 : free 35 | 36 | - `void free(void* ptr)` 37 | - 할당된 메모리 해제 38 | 39 |
40 | 41 | #### 중요 42 | 43 | 할당한 메모리는 반드시 해제하자 (해제안하면 메모리 릭, 누수 발생) 44 | 45 |
46 | 47 | ```c 48 | #include 49 | #include 50 | 51 | int main(void) { 52 | int arr[4] = { 4, 3, 2, 1 }; 53 | int* pArr; 54 | 55 | // 동적할당 : int 타입의 사이즈 * 4만큼 메모리를 할당 56 | pArr = (int*)malloc(sizeof(int)*4); 57 | 58 | if(pArr == NULL) { // 할당할수 없는 경우 59 | printf("malloc error"); 60 | exit(1); 61 | } 62 | 63 | for(int i = 0; i < 4; ++i) { 64 | pArr[i] = arr[i]; 65 | } 66 | 67 | for(int i = 0; i < 4; ++i) { 68 | printf("%d \n", pArr[i]); 69 | } 70 | 71 | // 할당 메모리 해제 72 | free(pArr); 73 | 74 | return 0; 75 | } 76 | ``` 77 | 78 | - 동적할당 부분 : `pArr = (int*)malloc(sizeof(int)*4);` 79 | - `(int*)` : malloc의 반환형이 void*이므로 형변환 80 | - `sizeof(int)` : sizeof는 괄호 안 자료형 타입을 바이트로 연산해줌 81 | - `*4` : 4를 곱한 이유는, arr[4]가 가진 동일한 크기의 메모리를 할당하기 위해 82 | - `free[pArr]` : 다 사용하면 꼭 메모리 해제 83 | 84 |
85 | 86 |
87 | 88 | ##### [참고 자료] 89 | 90 | - [링크](https://blockdmask.tistory.com/290) 91 | 92 | -------------------------------------------------------------------------------- /Language/[Cpp] shallow copy vs deep copy.md: -------------------------------------------------------------------------------- 1 | # [Cpp] 얕은 복사 vs 깊은 복사 2 | 3 |
4 | 5 | > shallow copy와 deep copy가 어떻게 다른지 알아보자 6 | 7 |
8 | 9 | ### 얕은 복사(shallow copy) 10 | 11 | 한 객체의 모든 멤버 변수의 값을 다른 객체로 복사 12 | 13 |
14 | 15 | ### 깊은 복사(deep copy) 16 | 17 | 모든 멤버 변수의 값뿐만 아니라, 포인터 변수가 가리키는 모든 객체에 대해서도 복사 18 | 19 |
20 | 21 |
22 | 23 | ```cpp 24 | struct Test { 25 | char *ptr; 26 | }; 27 | 28 | void shallow_copy(Test &src, Test &dest) { 29 | dest.ptr = src.ptr; 30 | } 31 | 32 | void deep_copy(Test &src, Test &dest) { 33 | dest.ptr = (char*)malloc(strlen(src.ptr) + 1); 34 | strcpy(dest.ptr, src.ptr); 35 | } 36 | ``` 37 | 38 |
39 | 40 | `shallow_copy`를 사용하면, 객체 생성과 삭제에 관련된 많은 프로그래밍 오류가 프로그램 실행 시간에 발생할 수 있다. 41 | 42 | ``` 43 | 즉, 얕은 복사는 프로그래머가 스스로 무엇을 하는 지 44 | 잘 이해하고 있는 상황에서 주의하여 사용해야 한다 45 | ``` 46 | 47 | 대부분, 얕은 복사는 실제 데이터를 복제하지 않고서, 복잡한 자료구조에 관한 정보를 전달할 때 사용한다. 얕은 복사로 만들어진 객체를 삭제할 때는 조심해야 한다. 48 | 49 |
50 | 51 | 실제로 얕은 복사는 실무에서 거의 사용되지 않는다. 대부분 깊은 복사를 사용해야 하는데, 복사되는 자료구조의 크기가 작으면 더욱 깊은 복사가 필요하다. 52 | 53 |
54 | 55 |
56 | 57 | #### [참고 자료] 58 | 59 | - 코딩 인터뷰 완전분석 -------------------------------------------------------------------------------- /Language/[Java] Auto Boxing & Unboxing.md: -------------------------------------------------------------------------------- 1 | # [Java] 오토 박싱 & 오토 언박싱 2 | 3 |
4 | 5 | 자바에는 기본 타입과 Wrapper 클래스가 존재한다. 6 | 7 | - 기본 타입 : `int, long, float, double, boolean` 등 8 | - Wrapper 클래스 : `Integer, Long, Float, Double, Boolean ` 등 9 | 10 |
11 | 12 | 박싱과 언박싱에 대한 개념을 먼저 살펴보자 13 | 14 | > 박싱 : 기본 타입 데이터에 대응하는 Wrapper 클래스로 만드는 동작 15 | > 16 | > 언박싱 : Wrapper 클래스에서 기본 타입으로 변환 17 | 18 | ```JAVA 19 | // 박싱 20 | int i = 10; 21 | Integer num = new Integer(i); 22 | 23 | // 언박싱 24 | Integer num = new Integer(10); 25 | int i = num.intValue(); 26 | ``` 27 | 28 |
29 | 30 | 31 | 32 |
33 | 34 | #### 오토 박싱 & 오토 언박싱 35 | 36 | JDK 1.5부터는 자바 컴파일러가 박싱과 언박싱이 필요한 상황에 자동으로 처리를 해준다. 37 | 38 | ```JAVA 39 | // 오토 박싱 40 | int i = 10; 41 | Integer num = i; 42 | 43 | // 오토 언박싱 44 | Integer num = new Integer(10); 45 | int i = num; 46 | ``` 47 | 48 |
49 | 50 | ### 성능 51 | 52 | 편의성을 위해 오토 박싱과 언박싱이 제공되고 있지만, 내부적으로 추가 연산 작업이 거치게 된다. 53 | 54 | 따라서, 오토 박싱&언박싱이 일어나지 않도록 동일한 타입 연산이 이루어지도록 구현하자. 55 | 56 | #### 오토 박싱 연산 57 | 58 | ```java 59 | public static void main(String[] args) { 60 | long t = System.currentTimeMillis(); 61 | Long sum = 0L; 62 | for (long i = 0; i < 1000000; i++) { 63 | sum += i; 64 | } 65 | System.out.println("실행 시간: " + (System.currentTimeMillis() - t) + " ms"); 66 | } 67 | 68 | // 실행 시간 : 19 ms 69 | ``` 70 | 71 | #### 동일 타입 연산 72 | 73 | ```java 74 | public static void main(String[] args) { 75 | long t = System.currentTimeMillis(); 76 | long sum = 0L; 77 | for (long i = 0; i < 1000000; i++) { 78 | sum += i; 79 | } 80 | System.out.println("실행 시간: " + (System.currentTimeMillis() - t) + " ms") ; 81 | } 82 | 83 | // 실행 시간 : 4 ms 84 | ``` 85 | 86 |
87 | 88 | 100만건 기준으로 약 5배의 성능 차이가 난다. 따라서 서비스를 개발하면서 불필요한 오토 캐스팅이 일어나는 지 확인하는 습관을 가지자. 89 | 90 |
91 | 92 |
93 | 94 | #### [참고 사항] 95 | 96 | - [링크](http://tcpschool.com/java/java_api_wrapper) 97 | - [링크](https://sas-study.tistory.com/407) 98 | 99 | -------------------------------------------------------------------------------- /Language/[Java] Interned String in JAVA.md: -------------------------------------------------------------------------------- 1 | # Interned String in Java 2 | 자바(Java)의 문자열(String)은 불변(immutable)하다. 3 | String의 함수를 호출을 하면 해당 객체를 직접 수정하는 것이 아니라, 함수의 결과로 해당 객체가 아닌 다른 객체를 반환한다. 4 | 그러나 항상 그런 것은 아니다. 아래 예를 보자. 5 | ```java 6 | public void func() { 7 | String haribo1st = new String("HARIBO"); 8 | String copiedHaribo1st = haribo1st.toUpperCase(); 9 | 10 | System.out.println(haribo1st == copiedHaribo1st); 11 | } 12 | ``` 13 | `"HARIBO"`라는 문자열을 선언한 후, `toUpperCase()`를 호출하고 있다. 14 | 앞서 말대로 불변 객체이기 때문에 `toUpperCase()`를 호출하면 기존 객체와 다른 객체가 나와야 한다. 15 | 그러나 `==`으로 비교를 해보면 `true`로 서로 같은 값이다. 16 | 그 이유는 `toUpperCase()` 함수의 로직 때문이다. 해당 함수는 lower case의 문자가 발견되지 않으면 기존의 객체를 반환한다. 17 | 18 | 그렇다면 생성자(`new String("HARIBO")`)를 이용해서 문자열을 생성하면 `"HARIBO"`으로 선언한 객체와 같은 객체일까? 19 | 아니다. 생성자를 통해 선언하게 되면 같은 문자열을 가진 새로운 객체가 생성된다. 즉, 힙(heap)에 새로운 메모리를 할당하는 것이다. 20 | 21 | ```java 22 | public void func() { 23 | String haribo1st = new String("HARIBO"); 24 | String haribo3rd = "HARIBO"; 25 | 26 | System.out.println(haribo1st == haribo3rd); 27 | System.out.println(haribo1st.equals(haribo3rd)); 28 | } 29 | ``` 30 | 위의 예제를 보면 `==` 비교의 결과는 `false`이지만 `equals()`의 결과는 `true`이다. 31 | 두 개의 문자열은 같은 값을 가지지만 실제로는 다른 객체이다. 32 | 두 객체의 hash 값을 비교해보면 확실하게 알 수 있다. 33 | 34 | ```java 35 | public void func() { 36 | String haribo3rd = "HARIBO"; 37 | String haribo4th = String.valueOf("HARIBO"); 38 | 39 | System.out.println(haribo3rd == haribo4th); 40 | System.out.println(haribo3rd.equals(haribo4th)); 41 | } 42 | ``` 43 | 이번에는 리터럴(literal)로 선언한 객체와 `String.valueOf()`로 가져온 객체를 한번 살펴보자. 44 | `valueOf()`함수를 들어가보면 알겠지만, 주어진 매개 변수가 null인지 확인한 후 null이 아니면 매개 변수의 `toString()`을 호출한다. 45 | 여기서 `String.toString()`은 `this`를 반환한다. 즉, 두 구문 모두 `"HARIBO"`처럼 리터럴 선언이다. 46 | 그렇다면 리터럴로 선언한 객체는 왜 같은 객체일까? 47 | 48 | 바로 JVM에서 constant pool을 통해 문자열을 관리하고 있기 때문이다. 49 | 리터럴로 선언한 문자열이 constant pool에 있으면 해당 객체를 바로 가져온다. 50 | 만약 pool에 없다면 새로 객체를 생성한 후, pool에 등록하고 가져온다. 51 | 이러한 플로우를 거치기 때문에 `"HARIBO"`로 선언한 문자열은 같은 객체로 나오는 것이다. 52 | `String.intern()` 함수를 참고해보자. 53 | 54 | ### References 55 | - https://www.latera.kr/blog/2019-02-09-java-string-intern/ 56 | - https://blog.naver.com/adamdoha/222817943149 -------------------------------------------------------------------------------- /Language/[Java] Java 8 정리.md: -------------------------------------------------------------------------------- 1 | # [Java] Java 8 정리 2 | 3 |
4 | 5 | ``` 6 | Java 8은 가장 큰 변화가 있던 버전이다. 7 | 자바로 구현하기 힘들었던 병렬 프로세싱을 활용할 수 있게 된 버전이기 때문 8 | ``` 9 | 10 |
11 | 12 | 시대가 발전하면서 이제 PC에서 멀티 코어 이상은 대중화되었다. 이제 수많은 데이터를 효율적으로 처리하기 위해서 '병렬' 처리는 필수적이다. 13 | 14 | 자바 프로그래밍은 다른 언어에 비해 병렬 처리가 쉽지 않다. 물론, 스레드를 사용하면 놀고 있는 유휴 코어를 활용할 수 있다. (대표적으로 스레드 풀) 하지만 개발자가 관리하기 어렵고, 사용하면서 많은 에러가 발생할 수 있는 단점이 존재한다. 15 | 16 | 이를 해결하기 위해 8버전에서는 좀 더 개발자들이 병렬 처리를 쉽고 간편하게 할 수 있도록 기능들이 추가되었다. 17 | 18 |
19 | 20 | 크게 3가지 기능이 8버전에서 추가되었다. 21 | 22 | - Stream API 23 | - Method Reference & Lamda 24 | - Default Method 25 | 26 |
27 | 28 | Stream API는 병렬 연산을 지원하는 API다. 이제 기존에 병렬 처리를 위해 사용하던 `synchronized`를 사용하지 않아도 된다. synchronized는 에러를 유발할 가능성과 비용 측면에서 문제점이 많은 단점이 있었다. 29 | 30 | Stream API는 주어진 항목들을 연속으로 제공하는 기능이다. 파이프라인을 구축하여, 진행되는 순서는 정해져있지만 동시에 작업을 처리하는 것이 가능하다. 31 | 32 | 스트림 파이프라인이 작업을 처리할 때 여러 CPU 코어에 할당 작업을 진행한다. 이를 통해서 하나의 큰 항목을 처리할 때 효율적으로 작업할 수 있는 것이다. 즉, 스레드를 사용하지 않아도 병렬 처리를 간편히 할 수 있게 되었다. 33 | 34 |
35 | 36 | 또한, 메소드 레퍼런스와 람다를 자바에서도 활용할 수 있게 되면서, 동작 파라미터를 구현할 수 있게 되었다. 기존에도 익명 클래스로 구현은 가능했지만, 코드가 복잡해지고 재사용이 힘든 단점을 해결할 수 있게 되었다. 37 | 38 | 39 | 40 |
41 | 42 |
43 | 44 | #### [참고 자료] 45 | 46 | - [링크](http://friday.fun25.co.kr/blog/?p=266) -------------------------------------------------------------------------------- /Language/[Java] wait notify notifyAll.md: -------------------------------------------------------------------------------- 1 | #### Object 클래스 wait, notify, notifyAll 2 | 3 | ---- 4 | 5 | Java의 최상위 클래스 = Object 클래스 6 | 7 | Object Class 가 갖고 있는 메서드 8 | 9 | * toString() 10 | 11 | * hashCode() 12 | 13 | * wait() 14 | 15 | 갖고 있던 **고유 lock 해제, Thread를 잠들게 함** 16 | 17 | * notify() 18 | 19 | **잠들던 Thread** 중 임의의 **하나를 깨움**. 20 | 21 | * notifyAll() 22 | 23 | 잠들어 있던 Thread 를 **모두 깨움**. 24 | 25 | 26 | 27 | 28 | 29 | *wait, notify, notifyAll : 호출하는 스레드가 반드시 고유 락을 갖고 있어야 함.* 30 | 31 | => Synchronized 블록 내에서 실행되어야 함. 32 | 33 | => 그 블록 안에서 호출하는 경우 IllegalMonitorStateException 발생. 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Language/[Javascript] 데이터 타입.md: -------------------------------------------------------------------------------- 1 | 2 | # 데이터 타입 3 | 4 | 자바스크립트의 데이터 타입은 크게 Primitive type, Structural Type, Structural Root Primitive 로 나눌 수 있다. 5 | 6 | - Primitive type 7 | - undefined : typeof instance === 'undefined' 8 | - Boolean : typeof instance === 'boolean' 9 | - Number : typeof instance === 'number' 10 | - String : typeof instance === 'string' 11 | - BitInt : typeof instance === 'bigint' 12 | - Symbol : typeof instance === 'symbol' 13 | - Structural Types 14 | - Object : typeof instance === 'object' 15 | - Fuction : typeof instance === 'fuction' 16 | - Structural Root Primitive 17 | - null : typeof instance === 'obejct' 18 | 19 | 기본적인 것은 설명하지 않으며, 놓칠 수 있는 부분만 설명하겠다. 20 | 21 | ### Number Type 22 | 23 | ECMAScript Specification을 참조하면 number type은 double-precision 64-bit binary 형식을 따른다. 24 | 25 | 아래 예제를 보자 26 | 27 | ```jsx 28 | console.log(1 === 1.0); // true 29 | ``` 30 | 31 | 즉 number type은 모두 실수로 처리된다. 32 | 33 | ### BigInt Type 34 | 35 | BigInt type은 number type의 범위를 넘어가는 숫자를 안전하게 저장하고 실행할 수 있게 해준다. BitInt는 n을 붙여 할당할 수 있다. 36 | 37 | ```jsx 38 | const x = 2n ** 53n; 39 | 9007199254740992n 40 | ``` 41 | 42 | ### Symbol Type 43 | 44 | Symbol Type은 **unique**하고 **immutable** 하다. 이렇나 특성 때문에 주로 이름이 충돌할 위험이 없는 obejct의 유일한 property key를 만들기 위해서 사용된다. 45 | 46 | ```jsx 47 | var key = Symbol('key'); 48 | 49 | var obj = {}; 50 | 51 | obj[key] = 'test'; 52 | ``` 53 | 54 | ## 데이터 타입의 필요성 55 | 56 | ```jsx 57 | var score = 100; 58 | ``` 59 | 60 | 위 코드가 실행되면 자바스크립트 엔진은 아래와 같이 동작한다. 61 | 62 | 1. score는 특정 주소 addr1를 가르키며 그 값은 undefined 이다. 63 | 2. 자바스크립트 엔진은 100이 number type 인 것을 해석하여 addr1와는 다른 주소 addr2에 8바이트의 메모리 공간을 확보하고 값 100을 저장하며 score는 addr2를 가르킨다. (할당) 64 | 65 | 만약 값을 참조할려고 할 떄에도 한 번에 읽어야 할 메모리 공간의 크기(바이트 수)를 알아야 한다. 자바스크립트 엔진은 number type의 값이 할당 되어있는 것을 알기 때무네 8바이트 만큼 읽게 된다. 66 | 67 | 정리하면 데이터 타입이 필요한 이유는 다음과 같다. 68 | 69 | - 값을 저장할 때 확보해야 하는 메모리 공간의 크기를 결정하기 위해 70 | - 값을 참조할 때 한 번에 읽어 들여야 할 메모리 공간의 크기를 결정하기 위해 71 | - 메모리에서 읽어 들인 2진수를 어떻게 해석할지 결정하기 위해 -------------------------------------------------------------------------------- /Language/[Javasript] Object Prototype.md: -------------------------------------------------------------------------------- 1 | # Object Prototype 2 | Prototype은 JavaScript object가 다른 object에서 상속하는 매커니즘이다. 3 | 4 | ## A prototype-based language? 5 | JavaScript는 종종 prototype-based language로 설명된다. prototype-based language는 상속을 지원하고 object는 prototype object를 갖는다. prototype object는 method와 property를 상속하는 template object 같은 것이다. 6 | 7 | object의 prototype object 또한 prototype object를 가지고 있으며 이것을 **prototype chain** 이라고 부른다. 8 | 9 | JavaScript에서 연결은 object instance와 prototype(\__proto__ 속성 또는 constructor의 prototype 속성) 사이에 만들어진다 10 | 11 | ## Understanding prototype objects 12 | 아래 예제를 보자. 13 | ```js 14 | function Person(first, last, age, gender, interests) { 15 | 16 | // property and method definitions 17 | this.name = { 18 | 'first': first, 19 | 'last' : last 20 | }; 21 | this.age = age; 22 | this.gender = gender; 23 | //...see link in summary above for full definition 24 | } 25 | ``` 26 | 우리는 object instance를 아래와 같이 만들 수 있다. 27 | ```js 28 | let person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']); 29 | ``` 30 | 31 | person1에 있는 method를 부른다면 어떤일이 발생할 것인가? 32 | ```js 33 | person1.valueOf() 34 | ``` 35 | valueOf()를 호출하면 36 | - 브라우저는 person1 object가 valueOf() method를 가졌는지 확인한다. 즉, 생성자인 Person()에 정의되어 있는지 확인한다. 37 | - 그렇지 않다면 person1의 prototype object를 확인한다. prototype object에 method가 없다면 prototype object의 prototype object를 확인하며 prototype object가 null이 될 때까지 탐색한다. 38 | -------------------------------------------------------------------------------- /Language/[Python] 매크로 라이브러리.md: -------------------------------------------------------------------------------- 1 | # 파이썬 매크로 2 | 3 |
4 | 5 | ### 설치 6 | 7 | ``` 8 | pip install pyautogui 9 | 10 | import pyautogui as pag 11 | ``` 12 | 13 |
14 | 15 | ### 마우스 명령 16 | 17 | 마우스 커서 위치 좌표 추출 18 | 19 | ```python 20 | x, y = pag.position() 21 | print(x, y) 22 | 23 | pos = pag.position() 24 | print(pos) # Point(x=?, y=?) 25 | ``` 26 | 27 |
28 | 29 | 마우스 위치 이동 (좌측 상단 0,0 기준) 30 | 31 | ``` 32 | pag.moveTo(0,0) 33 | ``` 34 | 35 | 현재 마우스 커서 위치 기준 이동 36 | 37 | ```python 38 | pag.moveRel(1,0) # x방향으로 1픽셀만큼 움직임 39 | ``` 40 | 41 |
42 | 43 | 마우스 클릭 44 | 45 | ```python 46 | pag.click((100,100)) 47 | pag.click(x=100,y=100) # (100,100) 클릭 48 | 49 | pag.rightClick() # 우클릭 50 | pag.doubleClick() # 더블클릭 51 | ``` 52 | 53 |
54 | 55 | 마우스 드래그 56 | 57 | ```python 58 | pag.dragTo(x=100, y=100, duration=2) 59 | # 현재 커서 위치에서 좌표(100,100)까지 2초간 드래그하겠다 60 | ``` 61 | 62 | > duration 값이 없으면 드래그가 잘 안되는 경우도 있으므로 설정하기 63 | 64 |
65 | 66 | ### 키보드 명령 67 | 68 | 글자 타이핑 69 | 70 | ```python 71 | pag.typewrite("ABC", interval=1) 72 | # interval은 천천히 글자를 입력할때 사용하기 73 | ``` 74 | 75 |
76 | 77 | 글자 아닌 다른 키보드 누르기 78 | 79 | ```python 80 | pag.press('enter') # 엔터키 81 | ``` 82 | 83 | > press 키 네임 모음 : [링크](https://pyautogui.readthedocs.io/en/latest/keyboard.html) 84 | 85 |
86 | 87 | 보조키 누른 상태 유지 & 떼기 88 | 89 | ```python 90 | pag.keyDown('shift') # shift 누른 상태 유지 91 | pag.keyUp('shift') # 누르고 있는 shift 떼기 92 | ``` 93 | 94 |
95 | 96 | 많이 쓰는 명령어 함수 사용 97 | 98 | ```python 99 | pag.hotkey('ctrl', 'c') # ctrl+c 100 | ``` 101 | 102 |
103 | 104 |
105 | 106 | #### [참고 자료] 107 | 108 | - [링크](https://m.blog.naver.com/jsk6824/221765884364) -------------------------------------------------------------------------------- /Language/[c] C언어 컴파일 과정.md: -------------------------------------------------------------------------------- 1 | ### C언어 컴파일 과정 2 | 3 | --- 4 | 5 | gcc를 통해 C언어로 작성된 코드가 컴파일되는 과정을 알아보자 6 | 7 |
8 | 9 | 10 | 11 | 이러한 과정을 거치면서, 결과물은 컴퓨터가 이해할 수 있는 바이너리 파일로 만들어진다. 이 파일을 실행하면 주기억장치(RAM)로 적재되어 시스템에서 동작하게 되는 것이다. 12 | 13 |
14 | 15 | 1. #### 전처리 과정 16 | 17 | - 헤더파일 삽입 (#include 구문을 만나면 헤더파일을 찾아 그 내용을 순차적으로 삽입) 18 | - 매크로 치환 및 적용 (#define, #ifdef와 같은 전처리기 매크로 치환 및 처리) 19 | 20 |
21 | 22 | 2. #### 컴파일 과정 (전단부 - 중단부 - 후단부) 23 | 24 | - **전단부** (언어 종속적인 부분 처리 - 어휘, 구문, 의미 분석) 25 | - **중단부** (SSA 기반으로 최적화 수행 - 프로그램 수행 속도 향상으로 성능 높이기 위함) 26 | - **후단부** (RTS로 아키텍처 최적화 수행 - 더 효율적인 명령어로 대체해서 성능 높이기 위함) 27 | 28 |
29 | 30 | 3. #### 어셈블 과정 31 | 32 | > 컴파일이 끝나면 어셈블리 코드가 됨. 이 코드는 어셈블러에 의해 기계어가 된다. 33 | 34 | - 어셈블러로 생성되는 파일은 명령어와 데이터가 들어있는 ELF 바이너리 포맷 구조를 가짐 35 | (링커가 여러 바이너리 파일을 하나의 실행 파일로 효과적으로 묶기 위해 `명령어와 데이터 범위`를 일정한 규칙을 갖고 형식화 해놓음) 36 | 37 |
38 | 39 | 4. #### 링킹 과정 40 | 41 | > 오브젝트 파일들과 프로그램에서 사용된 C 라이브러리를 링크함 42 | > 43 | > 해당 링킹 과정을 거치면 실행파일이 드디어 만들어짐 44 | 45 |
46 | 47 | -------------------------------------------------------------------------------- /Language/[java] Casting(업캐스팅 & 다운캐스팅).md: -------------------------------------------------------------------------------- 1 | ## Casting(업캐스팅 & 다운캐스팅) 2 | 3 | #### 캐스팅이란? 4 | 5 | > 변수가 원하는 정보를 다 갖고 있는 것 6 | 7 | ```java 8 | int a = 0.1; // (1) 에러 발생 X 9 | int b = (int) true; // (2) 에러 발생 O, boolean은 int로 캐스트 불가 10 | ``` 11 | 12 | (1)은 0.1이 double형이지만, int로 될 정보 또한 가지고 있음 13 | 14 | (2)는 true는 int형이 될 정보를 가지고 있지 않음 15 | 16 |
17 | 18 | ##### 캐스팅이 필요한 이유는? 19 | 20 | 1. **다형성** : 오버라이딩된 함수를 분리해서 활용할 수 있다. 21 | 2. **상속** : 캐스팅을 통해 범용적인 프로그래밍이 가능하다. 22 | 23 |
24 | 25 | ##### 형변환의 종류 26 | 27 | 1. **묵시적 형변환** : 캐스팅이 자동으로 발생 (업캐스팅) 28 | 29 | ```java 30 | Parent p = new Child(); // (Parent) new Child()할 필요가 없음 31 | ``` 32 | 33 | > Parent를 상속받은 Child는 Parent의 속성을 포함하고 있기 때문 34 | 35 |
36 | 37 | 2. **명시적 형변환** : 캐스팅할 내용을 적어줘야 하는 경우 (다운캐스팅) 38 | 39 | ```java 40 | Parent p = new Child(); 41 | Child c = (Child) p; 42 | ``` 43 | 44 | > 다운캐스팅은 업캐스팅이 발생한 이후에 작용한다. 45 | 46 |
47 | 48 | ##### 예시 문제 49 | 50 | ```java 51 | class Parent { 52 | int age; 53 | 54 | Parent() {} 55 | 56 | Parent(int age) { 57 | this.age = age; 58 | } 59 | 60 | void printInfo() { 61 | System.out.println("Parent Call!!!!"); 62 | } 63 | } 64 | 65 | class Child extends Parent { 66 | String name; 67 | 68 | Child() {} 69 | 70 | Child(int age, String name) { 71 | super(age); 72 | this.name = name; 73 | } 74 | 75 | @Override 76 | void printInfo() { 77 | System.out.println("Child Call!!!!"); 78 | } 79 | 80 | } 81 | 82 | public class test { 83 | public static void main(String[] args) { 84 | Parent p = new Child(); 85 | 86 | p.printInfo(); // 문제1 : 출력 결과는? 87 | Child c = (Child) new Parent(); //문제2 : 에러 종류는? 88 | } 89 | } 90 | ``` 91 | 92 | 문제1 : `Child Call!!!!` 93 | 94 | > 자바에서는 오버라이딩된 함수를 동적 바인딩하기 때문에, Parent에 담겼어도 Child의 printInfo() 함수를 불러오게 된다. 95 | 96 | 문제2 : `Runtime Error` 97 | 98 | > 컴파일 과정에서는 데이터형의 일치만 따진다. 프로그래머가 따로 (Child)로 형변환을 해줬기 때문에 컴파일러는 문법이 맞다고 생각해서 넘어간다. 하지만 런타임 과정에서 Child 클래스에 Parent 클래스를 넣을 수 없다는 것을 알게 되고, 런타임 에러가 나오게 되는것! 99 | 100 | -------------------------------------------------------------------------------- /Language/[java] Java major feature changes.md: -------------------------------------------------------------------------------- 1 | > Java 버전별 변화 중 중요한 부분만 기록했습니다. 더 자세한건 참고의 링크를 봐주세요. 2 | 3 | ## Java 8 4 | 5 | 1. 함수형 프로그래밍 패러다임 적용 6 | 1. Lambda expression 7 | 2. Stream 8 | 3. Functional interface 9 | 4. Optional 10 | 2. interface 에서 default method 사용 가능 11 | 3. 새로운 Date and Time API 12 | 4. JVM 개선 13 | 1. JVM 에 의해 크기가 결정되던 Permanent Heap 삭제 14 | 2. OS 가 자동 조정하는 Native 메모리 영역인 Metaspace 추가 15 | 3. `Default GC` Serial GC -> Parallel GC (멀티 스레드 방식) 16 | 17 | ## Java 9 18 | 19 | 1. module 20 | 2. interface 에서 private method 사용 가능 21 | 3. Collection, Stream, Optional API 사용법 개선 22 | 1. ex) Immutable collection, Stream.ofNullable(), Optional.orElseGet() 23 | 4. `Default GC` Parallel GC -> G1GC (멀티 프로세서 환경에 적합) 24 | 25 | ## Java 10 26 | 27 | 1. var (지역 변수 타입 추론) 28 | 29 | ## Java 11 30 | 31 | 1. HTTP Client API 32 | 1. HTTP/2 지원 33 | 2. RestTemplate 의 상위 호환 34 | 2. String API 사용법 개선 35 | 3. OracleJDK 독점 기능이 OpenJDK 에 포함 36 | 37 | ## 참고 38 | 39 | - [Java Latest Versions and Features](https://howtodoinjava.com/java-version-wise-features-history/) 40 | - [JDK 8에서 Perm 영역은 왜 삭제됐을까](https://johngrib.github.io/wiki/java8-why-permgen-removed/) 41 | - [Java 11 String API Additions](https://www.baeldung.com/java-11-string-api) 42 | -------------------------------------------------------------------------------- /Language/[java] Record.md: -------------------------------------------------------------------------------- 1 | # [Java] Record 2 | 3 |
4 | 5 | 6 | 7 |
8 | 9 | ``` 10 | Java 14에서 프리뷰로 도입된 클래스 타입 11 | 순수히 데이터를 보유하기 위한 클래스 12 | ``` 13 | 14 |
15 | 16 | Java 14버전부터 도입되고 16부터 정식 스펙에 포함된 Record는 class처럼 타입으로 사용이 가능하다. 17 | 18 | 객체를 생성할 때 보통 아래와 같이 개발자가 만들어야한다. 19 | 20 |
21 | 22 | ```java 23 | public class Person { 24 | private final String name; 25 | private final int age; 26 | 27 | public Person(String name, int age) { 28 | this.name = name; 29 | this.age = age; 30 | } 31 | 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | public int getAge() { 37 | return age; 38 | } 39 | } 40 | ``` 41 | 42 | - 클래스 `Person` 을 만든다. 43 | - 필드 `name`, `age`를 생성한다. 44 | - 생성자를 만든다. 45 | - getter를 구현한다. 46 | 47 |
48 | 49 | 보통 `Entity`나 `DTO` 구현에 있어서 많이 사용하는 형식이다. 50 | 51 | 이를 Record 타입의 클래스로 만들면 상당히 단순해진다. 52 | 53 |
54 | 55 | ```java 56 | public record Person( 57 | String name, 58 | int age 59 | ) {} 60 | ``` 61 | 62 |
63 | 64 | 자동으로 필드를 `private final` 로 선언하여 만들어주고, `생성자`와 `getter`까지 암묵적으로 생성된다. 또한 `equals`, `hashCode`, `toString` 도 자동으로 생성된다고 하니 매우 편리하다. 65 | 66 | 대신 `getter` 메소드의 경우 구현시 `getXXX()`로 명칭을 짓지만, 자동으로 만들어주는 메소드는 `name()`, `age()`와 같이 필드명으로 생성된다. 67 | 68 |
69 | 70 |
71 | 72 | #### [참고 자료] 73 | 74 | - [링크](https://coding-start.tistory.com/355) -------------------------------------------------------------------------------- /Language/[java] String StringBuilder StringBuffer 차이.md: -------------------------------------------------------------------------------- 1 | ### String, StringBuffer, StringBuilder 2 | 3 | ---- 4 | 5 | | 분류 | String | StringBuffer | StringBuilder | 6 | | ------ | --------- | ------------------------------- | -------------------- | 7 | | 변경 | Immutable | Mutable | Mutable | 8 | | 동기화 | | Synchronized 가능 (Thread-safe) | Synchronized 불가능. | 9 | 10 | --- 11 | 12 | #### 1. String 특징 13 | 14 | * new 연산을 통해 생성된 인스턴스의 메모리 공간은 변하지 않음 (Immutable) 15 | * Garbage Collector로 제거되어야 함. 16 | * 문자열 연산시 새로 객체를 만드는 Overhead 발생 17 | * 객체가 불변하므로, Multithread에서 동기화를 신경 쓸 필요가 없음. (조회 연산에 매우 큰 장점) 18 | 19 | *String 클래스 : 문자열 연산이 적고, 조회가 많은 멀티쓰레드 환경에서 좋음* 20 | 21 |
22 | 23 | #### 2. StringBuffer, StringBuilder 특징 24 | 25 | - 공통점 26 | - new 연산으로 클래스를 한 번만 만듬 (Mutable) 27 | - 문자열 연산시 새로 객체를 만들지 않고, 크기를 변경시킴 28 | - StringBuffer와 StringBuilder 클래스의 메서드가 동일함. 29 | - 차이점 30 | - StringBuffer는 Thread-Safe함 / StringBuilder는 Thread-safe하지 않음 (불가능) 31 | 32 |
33 | 34 | *StringBuffer 클래스 : 문자열 연산이 많은 Multi-Thread 환경* 35 | 36 | *StringBuilder 클래스 : 문자열 연산이 많은 Single-Thread 또는 Thread 신경 안쓰는 환경* 37 | -------------------------------------------------------------------------------- /Language/[java] 자바 가상 머신(Java Virtual Machine).md: -------------------------------------------------------------------------------- 1 | ## 자바 가상 머신(Java Virtual Machine) 2 | 3 | 시스템 메모리를 관리하면서, 자바 기반 애플리케이션을 위해 이식 가능한 실행 환경을 제공함 4 | 5 |
6 | 7 | 8 | 9 |
10 | 11 | JVM은, 다른 프로그램을 실행시키는 것이 목적이다. 12 | 13 | 갖춘 기능으로는 크게 2가지로 말할 수 있다. 14 | 15 |
16 | 17 | 1. 자바 프로그램이 어느 기기나 운영체제 상에서도 실행될 수 있도록 하는 것 18 | 2. 프로그램 메모리를 관리하고 최적화하는 것 19 | 20 |
21 | 22 | ``` 23 | JVM은 코드를 실행하고, 해당 코드에 대해 런타임 환경을 제공하는 프로그램에 대한 사양임 24 | ``` 25 | 26 |
27 | 28 | 개발자들이 말하는 JVM은 보통 `어떤 기기상에서 실행되고 있는 프로세스, 특히 자바 앱에 대한 리소스를 대표하고 통제하는 서버`를 지칭한다. 29 | 30 | 자바 애플리케이션을 클래스 로더를 통해 읽어들이고, 자바 API와 함께 실행하는 역할. JAVA와 OS 사이에서 중개자 역할을 수행하여 OS에 구애받지 않고 재사용을 가능하게 해준다. 31 | 32 |
33 | 34 | #### JVM에서의 메모리 관리 35 | 36 | --- 37 | 38 | JVM 실행에 있어서 가장 일반적인 상호작용은, 힙과 스택의 메모리 사용을 확인하는 것 39 | 40 |
41 | 42 | ##### 실행 과정 43 | 44 | 1. 프로그램이 실행되면, JVM은 OS로부터 이 프로그램이 필요로하는 메모리를 할당받음. JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리함 45 | 2. 자바 컴파일러(JAVAC)가 자바 소스코드를 읽고, 자바 바이트코드(.class)로 변환시킴 46 | 3. 변경된 class 파일들을 클래스 로더를 통해 JVM 메모리 영역으로 로딩함 47 | 4. 로딩된 class파일들은 Execution engine을 통해 해석됨 48 | 5. 해석된 바이트 코드는 메모리 영역에 배치되어 실질적인 수행이 이루어짐. 이러한 실행 과정 속 JVM은 필요에 따라 스레드 동기화나 가비지 컬렉션 같은 메모리 관리 작업을 수행함 49 | 50 |
51 | 52 | 53 | 54 |
55 | 56 | ##### 자바 컴파일러 57 | 58 | 자바 소스코드(.java)를 바이트 코드(.class)로 변환시켜줌 59 | 60 |
61 | 62 | ##### 클래스 로더 63 | 64 | JVM은 런타임시에 처음으로 클래스를 참조할 때 해당 클래스를 로드하고 메모리 영역에 배치시킴. 이 동적 로드를 담당하는 부분이 바로 클래스 로더 65 | 66 |
67 | 68 | ##### Runtime Data Areas 69 | 70 | JVM이 운영체제 위에서 실행되면서 할당받는 메모리 영역임 71 | 72 | 총 5가지 영역으로 나누어짐 : PC 레지스터, JVM 스택, 네이티브 메서드 스택, 힙, 메서드 영역 73 | 74 | (이 중에 힙과 메서드 영역은 모든 스레드가 공유해서 사용함) 75 | 76 | **PC 레지스터** : 스레드가 어떤 명령어로 실행되어야 할지 기록하는 부분(JVM 명령의 주소를 가짐) 77 | 78 | **스택 Area** : 지역변수, 매개변수, 메서드 정보, 임시 데이터 등을 저장 79 | 80 | **네이티브 메서드 스택** : 실제 실행할 수 있는 기계어로 작성된 프로그램을 실행시키는 영역 81 | 82 | **힙** : 런타임에 동적으로 할당되는 데이터가 저장되는 영역. 객체나 배열 생성이 여기에 해당함 83 | 84 | (또한 힙에 할당된 데이터들은 가비지컬렉터의 대상이 됨. JVM 성능 이슈에서 가장 많이 언급되는 공간임) 85 | 86 | **메서드 영역** : JVM이 시작될 때 생성되고, JVM이 읽은 각각의 클래스와 인터페이스에 대한 런타임 상수 풀, 필드 및 메서드 코드, 정적 변수, 메서드의 바이트 코드 등을 보관함 87 | 88 |
89 | 90 |
91 | 92 | ##### 가비지 컬렉션(Garbage Collection) 93 | 94 | 자바 이전에는 프로그래머가 모든 프로그램 메모리를 관리했음 95 | 하지만, 자바에서는 `JVM`이 프로그램 메모리를 관리함! 96 | 97 | JVM은 가비지 컬렉션이라는 프로세스를 통해 메모리를 관리함. 가비지 컬렉션은 자바 프로그램에서 사용되지 않는 메모리를 지속적으로 찾아내서 제거하는 역할을 함. 98 | 99 | **실행순서** : 참조되지 않은 객체들을 탐색 후 삭제 → 삭제된 객체의 메모리 반환 → 힙 메모리 재사용 100 | 101 |
-------------------------------------------------------------------------------- /Language/[java] 자바 컴파일 과정.md: -------------------------------------------------------------------------------- 1 | ### 자바 컴파일과정 2 | 3 | --- 4 | 5 | #### 들어가기전 6 | 7 | > 자바는 OS에 독립적인 특징을 가지고 있습니다. 그게 가능한 이유는 JVM(Java Vitual Machine) 덕분인데요. 그렇다면 JVM(Java Vitual Machine)의 어떠한 기능 때문에, OS에 독립적으로 실행시킬 수 있는지 자바 컴파일 과정을 통해 알아보도록 하겠습니다. 8 | 9 | 10 | 11 | 12 | 13 | --- 14 | 15 | #### 자바 컴파일 순서 16 | 17 | 1. 개발자가 자바 소스코드(.java)를 작성합니다. 18 | 2. 자바 컴파일러(Java Compiler)가 자바 소스파일을 컴파일합니다. 이때 나오는 파일은 자바 바이트 코드(.class)파일로 아직 컴퓨터가 읽을 수 없는 자바 가상 머신이 이해할 수 있는 코드입니다. 바이트 코드의 각 명령어는 1바이트 크기의 Opcode와 추가 피연산자로 이루어져 있습니다. 19 | 3. 컴파일된 바이트 코드를 JVM의 클래스로더(Class Loader)에게 전달합니다. 20 | 4. 클래스 로더는 동적로딩(Dynamic Loading)을 통해 필요한 클래스들을 로딩 및 링크하여 런타임 데이터 영역(Runtime Data area), 즉 JVM의 메모리에 올립니다. 21 | - 클래스 로더 세부 동작 22 | 1. 로드 : 클래스 파일을 가져와서 JVM의 메모리에 로드합니다. 23 | 2. 검증 : 자바 언어 명세(Java Language Specification) 및 JVM 명세에 명시된 대로 구성되어 있는지 검사합니다. 24 | 3. 준비 : 클래스가 필요로 하는 메모리를 할당합니다. (필드, 메서드, 인터페이스 등등) 25 | 4. 분석 : 클래스의 상수 풀 내 모든 심볼릭 레퍼런스를 다이렉트 레퍼런스로 변경합니다. 26 | 5. 초기화 : 클래스 변수들을 적절한 값으로 초기화합니다. (static 필드) 27 | 5. 실행엔진(Execution Engine)은 JVM 메모리에 올라온 바이트 코드들을 명령어 단위로 하나씩 가져와서 실행합니다. 이때, 실행 엔진은 두가지 방식으로 변경합니다. 28 | 1. 인터프리터 : 바이트 코드 명령어를 하나씩 읽어서 해석하고 실행합니다. 하나하나의 실행은 빠르나, 전체적인 실행 속도가 느리다는 단점을 가집니다. 29 | 2. JIT 컴파일러(Just-In-Time Compiler) : 인터프리터의 단점을 보완하기 위해 도입된 방식으로 바이트 코드 전체를 컴파일하여 바이너리 코드로 변경하고 이후에는 해당 메서드를 더이상 인터프리팅 하지 않고, 바이너리 코드로 직접 실행하는 방식입니다. 하나씩 인터프리팅하여 실행하는 것이 아니라 바이트 코드 전체가 컴파일된 바이너리 코드를 실행하는 것이기 때문에 전체적인 실행속도는 인터프리팅 방식보다 빠릅니다. 30 | 31 | --- 32 | 33 | Reference (추가로 읽어보면 좋은 자료) 34 | 35 | [1] https://steady-snail.tistory.com/67 36 | 37 | [2] https://aljjabaegi.tistory.com/387 38 | 39 | -------------------------------------------------------------------------------- /Linux/Linux Basic Command.md: -------------------------------------------------------------------------------- 1 | ## 리눅스 기본 명령어 2 | 3 | > 실무에서 자주 사용하는 명령어들 4 | 5 |
6 | 7 | `shutdown`, `halt`, `init 0`, `poweroff` : 시스템 종료 8 | 9 | `reboot`, `init 6`, `shutdown -r now` : 시스템 재부팅 10 | 11 |
12 | 13 | `sudo` : 다른 사용자가 super user권한으로 실행 14 | 15 | `su` : 사용자의 권한을 root로 변경 16 | 17 | `pwd` : 현재 자신이 위치한 디렉토리 18 | 19 | `cd` : 디렉토리 이동 20 | 21 | `ls` : 현재 자신이 속해있는 폴더 내의 파일, 폴더 표시 22 | 23 | `mkdir` : 디렉토리 생성 24 | 25 | `rmdir` : 디렉토리 삭제 26 | 27 | `touch` : 파일 생성 (크기 0) 28 | 29 | `cp` : 파일 복사 (디렉토리 내부까지 복사 시, `cp - R`) 30 | 31 | `mv` : 파일 이동 32 | 33 | `rm` : 파일 삭제 (디렉토리 삭제 시에는 보통 `rm -R`을 많이 사용) 34 | 35 | `cat` : 파일의 내용을 화면에 출력 36 | 37 | `more` : 화면 단위로 보기 쉽게 내용 출력 38 | 39 | `less` : more보다 조금 더 보기 편함 40 | 41 | `find` : 특정한 파일을 찾는 명령어 42 | 43 | `grep` : 특정 패턴으로 파일을 찾는 명령어 44 | 45 | `>>` : 리다이렉션 (파일 끼워넣기 등) 46 | 47 | `file` : 파일 종류 확인 48 | 49 | `which` : 특정 명령어의 위치 찾음 50 | 51 | 52 |
53 | 54 | `ping` : 네트워크 상태 점검 및 도메인 IP 확인 55 | 56 | `ifconfig` : 리눅스 IP 확인 및 설정 57 | 58 | `netstat` : 네트워크의 상태 59 | 60 | `nbstat` : IP 충돌 시, 충돌된 컴퓨터를 찾기 위함 61 | 62 | `traceroute` : 알고 싶은 목적지까지 경로를 찾아줌 63 | 64 | `route` : 라우팅 테이블 구성 상태 65 | 66 | `clock` : 시간 조절 명령어 67 | 68 | `date` : 시간, 날짜 출력 및 시간과 날짜 변경 69 | 70 |
71 | 72 | `rpm` : rpm 패키지 설치, 삭제 및 관리 73 | 74 | `yum` : rpm보다 더 유용함 (다른 필요한 rpm 패키기지까지 알아서 다운로드) 75 | 76 | `free` : 시스템 메모리의 정보 출력 77 | 78 | `ps` : 현재 실행되고 있는 프로세스 목록 출력 79 | 80 | `pstree` : 트리 형식으로 출력 81 | 82 | `top` : 리눅스 시스템의 운용 상황을 실시간으로 모니터링 가능 83 | 84 | `kill` : 특정 프로세스에 특정 signal을 보냄 85 | 86 | `killall` : 특정 프로세스 모두 종료 87 | 88 | `killall5` : 모든 프로세스 종료 (사용X) 89 | 90 |
91 | 92 | `tar`, `gzip` 등 : 압축 파일 묶거나 품 93 | 94 | `chmod` : 파일 or 디렉토리 권한 수정 95 | 96 | `chown` : 파일 or 디렉토리 소유자, 소유 그룹 수정 97 | 98 | `chgrp` : 파일 or 디렉토리 소유 그룹 수정 99 | 100 | `umask` : 파일 생성시의 권한 값을 변경 101 | 102 | `at` : 정해진 시간에 하나의 작업만 수행 103 | 104 | `crontab` : 반복적인 작업을 수행 (디스크 최적화를 위한 반복적 로그 파일 삭제 등에 활용) 105 | 106 |
107 | 108 | `useradd` : 새로운 사용자 계정 생성 109 | 110 | `password` : 사용자 계정의 비밀번호 설정 111 | 112 | `userdel` : 사용자 계정 삭제 113 | 114 | `usermod` : 사용자 계정 수정 115 | 116 | `groupadd` : 그룹 생성 117 | 118 | `groupdel` : 그룹 삭제 119 | 120 | `groups` : 그룹 확인 121 | 122 | `newgrp` : 자신이 속한 그룹 변경 123 | 124 | `mesg` : 메시지 응답 가능 및 불가 설정 125 | 126 | `talk` : 로그인한 사용자끼리 대화 127 | 128 | `wall` : 시스템 로그인한 모든 사용자에게 메시지 전송 129 | 130 | `write` : 로그인한 사용자에게 메시지 전달 131 | 132 | `dd` : 블럭 단위로 파일을 복사하거나 변환 133 | 134 |
135 | 136 |
137 | 138 |
139 | 140 | ##### [참고 자료] 141 | 142 | - [링크](https://vaert.tistory.com/103) 143 | 144 | -------------------------------------------------------------------------------- /Linux/Permission.md: -------------------------------------------------------------------------------- 1 | ## 퍼미션(Permisson) 활용 2 | 3 |
4 | 5 | 리눅스의 모든 파일과 디렉토리는 퍼미션들의 집합으로 구성되어있다. 6 | 7 | 이러한 Permission은 시스템에 대한 읽기, 쓰기, 실행에 대한 접근 여부를 결정한다. (`ls -l`로 확인 가능) 8 | 9 | 퍼미션은, 다중 사용자 환경을 제공하는 리눅스에서는 가장 기초적인 보안 방법이다. 10 | 11 |
12 | 13 | 1. #### 접근 통제 기법 14 | 15 | - ##### DAC (Discretionary Access Control) 16 | 17 | 객체에 대한 접근을 사용자 개인 or 그룹의 식별자를 기반으로 제어하는 방법 18 | 19 | > 운영체제 (윈도우, 리눅스) 20 | 21 | - ##### MAC (Mandotory Access Control) 22 | 23 | 모든 접근 제어를 관리자가 설정한대로 제어되는 방법 24 | 25 | > 관리자에 의한 강제적 접근 제어 26 | 27 | - ##### RBAC (Role Based Access Control) 28 | 29 | 관리자가 사용자에게는 특정한 역할을 부여하고, 각 역할마다 권리와 권한을 설정 30 | 31 | > 역할 기반 접근 제어 32 | 33 |
34 | 35 | 2. #### 퍼미션 카테고리 36 | 37 | 38 | 39 | > r : 읽기 / w : 쓰기 / x : 실행 / - : 권한 없음 40 | 41 | ex) `-rwxrw-r--. 1 root root 2104 1월 20 06:30 passwd` 42 | 43 | - `-rwx` : 소유자 44 | - `rw-` : 관리 그룹 45 | - `r--.` : 나머지 46 | - `1` : 링크 수 47 | - `root` : 소유자 48 | - `root` : 관리 그룹 49 | - `2104` : 파일크기 50 | - `1월 20 06:30` : 마지막 변경 날짜/시간 51 | - `passwd` : 파일 이름 52 | 53 |
54 | 55 | 3. #### 퍼미션 모드 56 | 57 | ##### 1) 심볼릭 모드 58 | 59 | 60 | 61 | 62 | 63 | 명령어 : `chmod [권한] [파일 이름]` 64 | 65 | > 그룹(g)에게 실행 권한(x)를 더할 경우 66 | > 67 | > `chmod g+x` 68 | 69 |
70 | 71 | ##### 2) 8진수 모드 72 | 73 | chmod 숫자 표기법은, 0~7까지의 8진수 조합을 사용자(u), 그룹(g), 기타(o)에 맞춰 숫자로 표기하는 것이다. 74 | 75 | > r = 4 / w = 2 / x = 1 / - = 0 76 | 77 | 78 | 79 |
80 | 81 |
82 | 83 | ##### [참고 자료] 84 | 85 | - [링크](http://cocotp10.blogspot.com/2018/01/linux-centos7.html) 86 | 87 | -------------------------------------------------------------------------------- /Linux/Von Neumann Architecture.md: -------------------------------------------------------------------------------- 1 | ## 폰 노이만 구조 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 | ##### 단점 26 | 27 | 메모리와 CPU를 연결하는 버스는 하나이므로, 폰 노이만 구조는 순차적으로 정보를 처리하기 때문에 '고속 병렬처리'에는 부적합하다. 28 | 29 | > 이를 폰 노이만 병목현상이라고 함 30 | 31 |
32 | 33 | 폰 노이만 구조는 순차적 처리이기 때문에 CPU가 명령어를 읽음과 동시에 데이터를 읽지는 못하는 문제가 있는 것이다. 34 | 35 | 이를 해결하기 위해 대안으로 하버드 구조가 있다고 한다. -------------------------------------------------------------------------------- /New Technology/AI/README.md: -------------------------------------------------------------------------------- 1 | ### **AI/ML 용어 정리** 2 | 3 | --- 4 | 5 | - **머신러닝:** 인공 지능의 한 분야로, 컴퓨터가 학습할 수 있도록 하는 알고리즘과 기술을 개발하는 분야입니다. 6 | - **데이터 마이닝:** 정형화된 데이터를 중심으로 분석하고 이해하고 예측하는 분야입니다. 7 | - **지도학습 (Supervised learning):** 정답을 주고 학습시키는 머신러닝의 방법론. 대표적으로 regression과 classification이 있습니다. 8 | - **비지도학습 (Unsupervised learning):** 정답이 없는 데이터가 어떻게 구성되었는지를 알아내는 머신러닝의 학습 방법론. 지도 학습 혹은 강화 학습과는 달리 입력값에 대한 목표치가 주어지지 않습니다. 9 | - **강화학습 (Reinforcement Learning):** 설정된 환경속에 보상을 주며 학습하는 머신러닝의 학습 방법론입니다. 10 | - **Representation Learning:** 부분적인 특징을 찾는 것이 아닌 하나의 뉴럴 넷 모델로 전체의 특징을 학습하는 것을 의미합니다. 11 | - **선형 회귀 (Linear Regression):** 종속 변수 y와 한개 이상의 독립 변수 x와의 선형 상관 관계를 모델링하는 회귀분석 기법입니다. ([위키링크](https://ko.wikipedia.org/wiki/선형_회귀)) 12 | - **자연어처리 (NLP):** 인간의 언어 형상을 컴퓨터와 같은 기계를 이용해서 모사 할 수 있도록 연구하고 이를 구현하는 인공지능의 주요 분야 중 하나입니다. ([위키링크](https://ko.wikipedia.org/wiki/자연어_처리)) 13 | - **학습 데이터 (Training data):** 모델을 학습시킬 때 사용할 데이터입니다. 학습데이터로 학습 후 모델의 여러 파라미터들을 결정합니다. 14 | - **테스트 데이터 (Test data):** 실제 학습된 모델을 평가하는데 사용되는 데이터입니다. 15 | - **정밀도와 재현율 (precision / recall):** binary classification을 사용하는 분야에서, 정밀도는 모델이 추출한 내용 중 정답의 비율이고, 재현율은 정답 중 모델이 추출한 내용의 비율입니다.([위키링크](https://ko.wikipedia.org/wiki/정밀도와_재현율)) 16 | 17 | 빅데이터는 많은 양의 데이터를 분석하고, 이해하고, 예측하는 것. 이를 활용하는 다양한 방법론 중에 가장 많이 사용하고 있는 것이 '머신러닝'이다. 18 | 19 | 데이터 마이닝은 구조화된 데이터를 활용함. 머신러닝은 이와는 다르게 비구조화 데이터를 활용하는게 주목적 20 | 21 | 머신러닝은 AI의 일부분. 사람처럼 지능적인 컴퓨터를 만드는 방법 중의 하나. 데이터에 의존하고 통계적으로 분석해서 만드는 방법이 머신러닝이라고 정의할 수 있음 22 | 23 | 통계학들이 수십년간 만들어놓은 통계와 데이터들을 적용시킨다. 통계학보다 훨씬 데이터 양이 많고, 노이즈도 많을 때 머신러닝의 기법을 통해 한계를 극복해나감 24 | 25 | 26 | 27 | 머신러닝에서 다루는 기본적인 문제들 28 | 29 | - 지도 학습 30 | - 비지도 학습 31 | - 강화 학습 32 | -------------------------------------------------------------------------------- /New Technology/Big Data/DBSCAN 클러스터링 알고리즘.md: -------------------------------------------------------------------------------- 1 | ## DBSCAN 클러스터링 알고리즘 2 | 3 | > 여러 클러스터링 알고리즘 中 '밀도 방식'을 사용 4 | 5 | K-Means나 Hierarchical 클러스터링처럼 군집간의 거리를 이용해 클러스터링하는 방법이 아닌, 점이 몰려있는 **밀도가 높은 부분으로 클러스터링 하는 방식**이다. 6 | 7 | `반경과 점의 수`로 군집을 만든다. 8 | 9 |
10 | 11 | 12 | 13 |
14 | 15 | 반경 Epsilon과 최소 점의 수인 minpts를 정한다. 16 | 17 | 하나의 점에서 Epsilon 안에 존재하는 점의 수를 센다. 이때, 반경 안에 속한 점이 minpts로 정한 수 이상이면 해당 점은 'core point'라고 부른다. 18 | 19 | 20 | 21 | > 현재 점 P에서 4개 이상의 점이 속했기 때문에, P는 core point다. 22 | 23 |
24 | 25 | Core point에 속한 점들부터 또 Epsilon을 확인하여 체크한다. (DFS 활용) 26 | 27 | 이때 4개 미만의 점이 속하게 되면, 해당 점은 'border point'라고 부른다. 28 | 29 | 30 | 31 | > P2는 Epsilon 안에 3개의 점만 존재하므로 minpts = 4 미만이기 때문에 border point이다. 32 | 33 | 보통 이와 같은 border point는 군집화를 마쳤을 때 클러스터의 외곽에 해당한다. (해당 점에서는 확장되지 않게되기 때문) 34 | 35 |
36 | 37 | 마지막으로, 하나의 점에서 Epslion을 확인했을 때 어느 집군에도 속하지 않는 점들이 있을 것이다. 이러한 점들을 outlier라고 하고, 'noise point'에 해당한다. 38 | 39 | 40 | 41 | > P4는 반경 안에 속하는 점이 아무도 없으므로 noise point다. 42 | 43 | DBSCAN 알고리즘은 이와 같이 군집에 포함되지 않는 아웃라이어 검출에 효율적이다. 44 | 45 |
46 | 47 |
48 | 49 | 전체적으로 DBSCAN 알고리즘을 적용한 점들은 아래와 같이 구성된다. 50 | 51 | 52 | 53 |
54 | 55 | ##### 정리 56 | 57 | 초반에 지정한 Epsilon 반경 안에 minpts 이상의 점으로 구성된다면, 해당 점을 중심으로 군집이 형성되고, core point로 지정한다. core point가 서로 다른 core point 군집의 일부가 되면 서로 연결되어 하나의 군집이 형성된다. 58 | 59 | 이때 군집에는 속해있지만 core point가 아닌 점들을 border point라고 하며, 아무곳에도 속하지 않는 점은 noise point가 된다. 60 | 61 |
62 | 63 |
64 | 65 | #### DBSCAN 장점 66 | 67 | - 클러스터의 수를 미리 정하지 않아도 된다. 68 | 69 | > K-Means 알고리즘처럼 미리 점을 지정해놓고 군집화를 하지 않아도 된다. 70 | 71 | - 다양한 모양과 크기의 클러스터를 얻는 것이 가능하다. 72 | 73 | - 모양이 기하학적인 분포라도, 밀도 여부에 따라 군집도를 찾을 수 있다. 74 | 75 | - 아웃라이어 검출을 통해 필요하지 않은 noise 데이터를 검출하는 것이 가능하다. 76 | 77 |
78 | 79 | #### DBSCAN 단점 80 | 81 | - Epslion에 너무 민감하다. 82 | 83 | > 반경으로 설정한 값에 상당히 민감하게 작용된다. 따라서 DBSCAN 알고리즘을 사용하려면 적절한 Epsilon 값을 설정하는 것이 중요하다. 84 | 85 |
86 | 87 |
88 | 89 | ##### [참고 자료] 90 | 91 | [링크]() 92 | 93 | [링크]() -------------------------------------------------------------------------------- /New Technology/Big Data/데이터 분석.md: -------------------------------------------------------------------------------- 1 | DataFrame을 만들어 다루기 위한 설치 2 | 3 | ``` 4 | >>> pip install pandas 5 | >>> pip install numpy 6 | >>> pip install matplotlib 7 | ``` 8 | 9 | > pandas : DataFrame을 다루기 위해 사용 10 | > 11 | > numpy : 벡터형 데이터와 행렬을 다룸 12 | > 13 | > matplotlib : 데이터 시각화 14 | 15 |
16 | 17 | #### 데이터 분석 18 | 19 | 스칼라 : 하나의 값을 가진 변수 `a = 'hello'` 20 | 21 | 벡터 : 여러 값을 가진 변수 `b = ['hello', 'world']` 22 | 23 | > 데이터 분석은 주로 '벡터'를 다루고, DataFrame의 변수도 벡터 24 | 25 | 이런 '벡터'를 pandas에서는 Series라고 부르고, numpy에서는 ndarray라 부름 26 | 27 |
28 | 29 | ##### 파이썬에서 제공하는 벡터 다루는 함수들 30 | 31 | ``` 32 | >>> all([1, 1, 1]) #벡터 데이터 모두 True면 True 반환 33 | >>> any([1,0,0]) #한 개라도 True면 True 반환 34 | >>> max([1,2,3]) #가장 큰 값을 반환한다. 35 | >>> min([1,2,3]) #가장 작은 값을 반환한다. 36 | >>> list(range(10)) #0부터 10까지 순열을 만듬 37 | >>> list(range(3,6)) #3부터 5까지 순열을 만듬 38 | >>> list(range(1, 6, 2)) #1부터 6까지 2단위로 순열을 만듬 39 | ``` 40 | 41 |
42 | 43 |
44 | 45 | #### pandas 46 | 47 | ```python 48 | import pandas as pd #pandas import 49 | df = pd.read_csv("data.csv") #csv파일 불러오기 50 | ``` 51 | 52 | 53 | 54 |
55 | 56 | 다양한 함수를 활용해서 데이터를 관측할 수 있다. 57 | 58 | ```python 59 | df.head() #맨 앞 5개를 보여줌 60 | df.tail() #맨 뒤 5개를 보여줌 61 | df[0:2] #특정 관측치 슬라이싱 62 | df.columns #변수명 확인 63 | df.describe() #count, mean(평균), std(표준편차), min, max 64 | ``` 65 | 66 | 67 | 68 |
69 | 70 | ##### 특정 변수 기준 그룹 통계값 71 | 72 | ```python 73 | # column1 변수별로 column2 평균 값 구하기 74 | df.groupby(['column1'])['column2'].mean() 75 | ``` 76 | 77 |
78 | 79 | 변수만 따로 저장해서 Series로 자세히 보기 80 | 81 | ```python 82 | s = movies.movieId 83 | s.index = movies.title 84 | s 85 | ``` 86 | 87 | 88 | 89 | Series는 크게 index와 value로 나누어짐 (왼쪽:index, 오른쪽:value) 90 | 91 | 이를 통해 따로 불러오고, 연산하는 것도 가능해진다. 92 | 93 | ```python 94 | s['Toy Story (1995)'] #이 컬럼이 가진 movieId가 출력됨 95 | print(s*2) #movieId가 *2되어 출력 96 | ``` 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /New Technology/IT Issues/2020 ICT 이슈.md: -------------------------------------------------------------------------------- 1 | ## 2020 ICT 이슈 2 | 3 | > 2020 ICT 산업전망 컨퍼런스에서 선정된 이슈들 4 | 5 |
6 | 7 | - 5G 8 | - 보호무역주의 9 | - AI 10 | - 규제 11 | - 모빌리티 12 | - 신남방, 신북방 정책 13 | - 구독경제 14 | - 반도체 15 | - 4차 산업혁명 시대 노동의 변화 16 | - 친환경 ICT 17 | 18 |
19 | 20 | ##### 가장 큰 화두는 '5G' 21 | 22 | 5G 인프라가 본격적으로 구축, B2B 시장이 열리면서 가속화될 예정 23 | 24 |
25 | 26 | ##### 온디바이스 AI 27 | 28 | 클라우드 연결이 필요없는 하드웨어 기반 인공지능인 **온디바이스 AI** 대전이 본격화될 예정 29 | 30 | > 삼성전자는 앞서 NPU를 갖춘 모바일 AP인 '엑시노스9820'을 공개했음 31 | 32 |
-------------------------------------------------------------------------------- /New Technology/IT Issues/README.md: -------------------------------------------------------------------------------- 1 | # IT Issues 2 | 3 | 최근 IT 이슈 동향 정리 -------------------------------------------------------------------------------- /New Technology/IT Issues/[2019.08.07] 이메일 공격 증가로 보안업계 대응 비상.md: -------------------------------------------------------------------------------- 1 | ## 이주의 IT 이슈 (19.08.07) 2 | 3 | ### 이메일 공격 증가로 보안업계 대응 비상 4 | 5 | --- 6 | 7 | > 올해 악성메일 탐지 건수 약 342,800건 예상 (SK인포섹 발표) 8 | > 9 | > 전년보다 2배 이상, 4년전보다 5배 이상 증가함 10 | 11 | 랜섬웨어 공격의 90%이상이 이메일로 시작됨 (KISA 발표) 12 | 13 |
14 | 15 | 해커가 '사회공학기법'을 활용해 사용자가 속을 수 밖에 없는 제목과 내용으로 지능화되고 있음 16 | 17 | > 이메일 유형 : 견적서, 대금청구서, 계약서, 발주서, 경찰청 및 국세청 사칭 18 | > 19 | > 최근에는 여름 휴가철 맞아 전자항공권 확인증 위장 이메일도 유포되는 中 20 | 21 |
22 | 23 | #### 대응 상황 24 | 25 | - 안랩 : 이메일 위협 대응이 가능한 안랩MDS(지능형 위협 대응 솔루션) 신규 버전 발표 26 | 27 | > 이메일 헤더, 제목, 본문, 첨부파일로 필터링 설정 (파일 확장자 분석) 28 | 29 | ``` 30 | * 안랩 MDS 31 | 다양한 공격 유입 경로별로 최적화된 대응 방안을 제공하는 지능형 위협 대응 솔루션 32 | - 사이버 킬체인 기반으로 네트워크, 이메일, 엔드포인트와 같은 경로의 침입 단계부터 최초 감염, 2차감염, 잠복 위협까지 최적화 대응 제공 33 | ``` 34 | 35 | - 지란지교시큐리티 : 홈페이지에 최신 악성메일 트렌드 부분을 공지하여 예방 가이드 제시 36 | 37 | > 실제 악성 이메일 미리보기 기능, 첨부된 파일 유형과 정보, 바이러스 탐지 내역 등 38 | 39 | #### 예방책 40 | 41 | - 사용 중인 문서 작성 프로그램 최신 버전 업데이트 42 | - 오피스문서 매크로 기능 허용 X 43 | 44 | 45 | 46 | **엔드포인트** : 네트워크에 최종적으로 연결된 IT 장치를 의미 (스마트폰, 노트북 등) 47 | 48 | 해커들의 궁극적인 목표가 바로 '엔드포인트' 해킹 49 | 50 | 네트워크를 통한 공격이기 때문에, 각각 연결이 되는 공간마다 방화벽(Firewall)을 세워두는 것이 '엔드포인트 보안' -------------------------------------------------------------------------------- /New Technology/IT Issues/[2019.08.08] IT 수다 정리.md: -------------------------------------------------------------------------------- 1 | ## [모닝 스터디] IT 수다 정리(19.08.08) 2 | 3 | 1. ##### 쿠팡 서비스 오류 4 | 5 | > 지난 7월 24일 오전 7시부터 쿠팡 판매 상품 재고가 모두 0으로 표시되는 오류 발생 6 | 7 | 재고 데이터베이스에서 데이터를 불러오는 'Redis DB'에서 버그가 발생함 8 | 9 | ***Redis란?*** 10 | 11 | ``` 12 | 오픈소스 기반 데이터베이스 관리 시스템(DBMS), 데이터를 메모리로 불러와서 처리하는 메모리 기반 시스템이다. 13 | 속도가 빠르고 사용이 칸편해서 트위터, 인스타그램 등에 사용 되고 있음 14 | ``` 15 | 16 | 속도가 빠른 대신, 데이터가 많아지면 버그 발생 가능성도 증가. 처리 데이터가 많을 수록 더 많은 메모리를 요구해서 결국 용량 부족으로 장애가 발생한 것으로 보임 17 | 18 |
19 | 20 | 2. ##### GraphQL 21 | 22 | > facebook이 만든 쿼리 언어 : `A query language for your API` 23 | 24 | 기존의 웹앱에서 API를 구현할 때는, 통상적으로 `REST API` 사용함. 클라이언트 사이드에서 기능이 필요할 때마다 새로운 API를 만들어야하는 번거로움이 있었음 25 | 26 | → **클라이언트 측에서 쿼리를 만들어 서버로 보내면 편하지 않을까?**에서 탄생한 것이 GraphQL 27 | 28 | 특정 언어에 제한된 것이 아니기 때문에 Node, Ruby, PHP, Python 등에서 모두 사용이 가능함. 또한 HTTP 프로토콜 제한이 없어서 웹소켓에서 사용도 가능하고 모든 DB를 사용이 가능 29 | 30 |
31 | 32 | 3. ##### 현재 반도체 매출 세계 2위인 SK 하이닉스의 탄생은? 33 | 34 | > 1997년 외환 위기로 인해 LG반도체가 현대전자로 합병됨(인수 후 '현대반도체'로 변경) 35 | > 36 | > 2001년에 `현대전자 → 하이닉스 반도체`로 사명 변경, 메모리 사업부 제외한 나머지 사업부는 모두 독립자회사로 분사시킴. 이때 하이닉스는 현대그룹에서 분리가 되었음 37 | > 38 | > 2011년부터 하이닉스 인수에 많은 기업들이 관심을 보임 (현대 중공업, SK, STX) 39 | > 40 | > 결국 SK텔레콤이 3조4천억에 단독 입찰(SK텔레콤은 주파수 통신산업으로 매월 수천억씩 벌고 있었음)하면서 2012년 주주통회를 통해 SK그룹에 편입되어 `SK하이닉스`로 사명 변경 41 | 42 | SK그룹의 탄탄한 지원을 받음 + 경쟁 반도체 기업(엘피다) 파산으로 수익 증가, DRAM과 NAND의 호황기 시대를 맞아 2014년 이후 17조 이상의 연간매출 기록 中 43 | 44 | -------------------------------------------------------------------------------- /New Technology/IT Issues/[2019.08.20] Google, 크롬 브라우저에서 FTP 지원 중단 확정.md: -------------------------------------------------------------------------------- 1 | ## Google, 크롬 브라우저에서 FTP 지원 중단 확정 2 | 3 |
4 | 5 | 6 | 7 | 크롬 브라우저에서 보안상 위험 요소로 작용되는 FTP 지원을 중단하기로 결정함 8 | 9 | 8월 15일, 구글은 암호화된 연결을 통한 파일 전송에 대한 지원도 부족하고, 사용량도 적어서 아예 기능을 제거하기로 결정함 10 | 11 |
12 | 13 | ***FTP (파일 전송 프로토콜)이란?*** 14 | 15 | > TCP/IP 프로토콜을 가지고 서버와 클라이언트 사이에 파일 전송을 하기 위한 프로토콜 16 | 17 |
18 | 19 | 과거에는 인터넷을 통해 파일을 다운로드 할 때, 웹 브라우저로 FTP 서버에 접속하는 방식을 이용했음. 하지만 이제 네트워크가 발달하면서, 네트워크의 안정화를 위해서 FTP의 쓰임이 줄어들게 됨 20 | 21 |
22 | 23 | FTP는 데이터를 주고받을 시, 암호화하지 않기 때문에 보안 위험에 노출되는 위험성 존재함. 또한 사용량도 현저히 적기 때문에 구글 개발자들이 오랫동안 FTP를 제거하자고 요청해왔음 24 | 25 | 이런 FTP의 단점을 개선하기 위해 SFTP와 SSL 프로토콜을 사용하는 中 26 | 27 | 현재 크롬에서 남은 FTP 기능 : 디렉토리 목록 보여주기, 암호화되지 않은 연결을 통해 리소스 다운로드 28 | 29 | FTP 기능을 없애고, FTP를 지원하는 소프트웨어를 활용하는 방식으로 바꿀 예정. 크롬80버전부터 점차 비활성화하고 크롬82버전에 완전히 제거될 예정이라고 함 -------------------------------------------------------------------------------- /Seminar/2019 삼성전자 비전캠프.md: -------------------------------------------------------------------------------- 1 | ## [2019 삼성전자 비전캠프] 2 | 3 | #### 기업에 대해 새로 알게된 점 4 | 5 | ------ 6 | 7 | - 삼성전자 DS와 CE/IM은 완전히 다른 기업 8 | 9 | 그러므로, **반도체 공정을 돕는 데이터 분석**을 하고 싶다든지, **반도체 위에 SW를 올리겠다든지 하는 것**은 부적절 함. 10 | 11 | **박종찬 상무님 (무선사업부)** 12 | 13 | ------ 14 | 15 | - 설득의 3요소 (아리스토텔레스의 수사학) 16 | 17 | > 남을 설득하기 위해 필요한 3가지 18 | 19 | 1. logos : 논리와 증거 20 | 2. Pathos : 듣는 사람의 심리 상태 21 | 3. Ethos : 말하는 사람의 성품, 매력도, 카리스마, 진실성 (가장 중요) 22 | 23 | > 정리하면, 행동을 통해 나의 호감도와 진정성을 인지시키고, 신뢰의 다리를 구축 (Ethos) 24 | > 25 | > 나의 마음을 받아들일 마음 상태일 때 (Pathos) 26 | > 27 | > 논리적으로 설득을 진행 (Logos) 28 | 29 | - 개발자의 기쁨은 여러 사람이 나의 제품을 사용하는 데서 온다. 30 | 31 | => **삼성전자의 입사 동기** (motivation) 가 될 수 있음. 32 | 33 | - (상무님이 생각하는) 미래 프로그래밍에 필요한 3요소 34 | 35 | 1. 클라우드 36 | 37 | 2. 대용량 서버 38 | 39 | Battle-ground 게임은 인기가 많았음. 그러나, 서버 설계를 잘못하여, 유저수에 비례하여 비용이 증가함. 40 | 41 | 3. 데이터 42 | 43 | > 이 3가지는 반드시 잘하고 있어야 함. 그 외 모든 분야에서의 프로그래머는 사라질 수도 있다고 생각하심. 예를 들어, front-end 개발의 경우, AI 기술을 통해서 할 수 있음. 44 | 45 | - 신입 개발자의 자세 46 | - 초기에는 (5년) 다양한 분야에 대해서 전부 다뤄보아야 함. 47 | - 이후에는, 2가지 분야를 잘 할 수 있어야 함. 예) 백엔드 + 데이터 / 프론트엔드 + 백엔드 / 데이터 + ML 48 | - 패권 사회가 되고 있음 49 | - 미국 vs 중국, 한국 vs 일본 50 | 최근 상황을 보면, 우위에 서기 위해서 상대방을 괴롭힘 51 | **다른 IT 기업이 아닌 삼성전자에서 일하고 싶은 이유로 뽑을 수 있음**. 52 | - 한국이 잘할 수 있는 분야는 2가지 - IT / Contents -------------------------------------------------------------------------------- /Seminar/2019 삼성전자 오픈소스 컨퍼런스(SOSCON).md: -------------------------------------------------------------------------------- 1 | ## 2019 SOSCON 2 | 3 | > 삼성전자 오픈소스 컨퍼런스 4 | 5 | 2019.10.16~17 ( 삼성전자 R&D 캠퍼스 ) 6 | 7 |
8 | 9 | #### 삼성전자 오픈소스 추진 현황 10 | 11 | - 2002 : PDA 12 | - 2009 : Galaxy, Smart TV, Exynos 13 | - 2012 : Z Phone, Tizen TV, Gear, Refrigerator, Washer 14 | - 2018 : IoT Devices 15 | - 2019 ~ : 5G, AI, Robot 16 | 17 |
18 | 19 | #### 오픈소스 핵심 역할 20 | 21 | 1. ##### OPENESS 22 | 23 | 소스코드/프로젝트 공개 확대 ( [삼성 오픈소스 GitHub](https://github.com/samsung) ) 24 | 25 | 국내 주요 커뮤니티 협력 강화 26 | 27 | 2. ##### Collaboration 28 | 29 | 글로벌 오픈소스 리딩 30 | 31 | 국내 주요 SW 단체 협력 32 | 33 | 3. ##### Developemnt Culture 34 | 35 | 사내 개발 인프라 강화 36 | 37 | Inner Source 확대 38 | 39 |
40 | 41 | 오픈소스를 통해 미래 주요 기술을 확보 → 고객에게 더욱 새로운 가치와 경험을 제공 42 | 43 |
44 | 45 |
46 | 47 | #### 5G 48 | 49 | --- 50 | 51 | - 2G : HUMAN to HUMAN 52 | 53 | - 3G/4G : HUMAN to MACHINE 54 | 55 | - 5G : MACHINE to MACHINE 56 | 57 |
58 | 59 | 2G/3G/4G : Voice & Data 60 | 61 | 5G : Autonomous Driving, Smart City, Smart Factory, Drone, Immersive Media, Telecom Service 62 | 63 | -------------------------------------------------------------------------------- /Seminar/NCSOFT 2019 JOB Cafe.md: -------------------------------------------------------------------------------- 1 | ### 2019-10-02 NCSOFT JOB Cafe 2 | 3 | --- 4 | 5 | - Micro Service Architecture 사용 6 | - 사용하는 언어와 프레임워크는 다양 (C++ 기반 자사 제품도 사용) 7 | - NC Test 8 | - 일반적인 기업 인적성과 유사 9 | - 회사에 대한 문제도 나옴 (연혁) 10 | - 직무에 따른 문제도 나옴 11 | - ex) Thread, Network(TCP/IP), OSI 7계층, 브라우저 동작 방법 등 12 | 13 | - NCSOFT 소개 14 | 15 | 16 | -------------------------------------------------------------------------------- /Web/CSR & SSR.md: -------------------------------------------------------------------------------- 1 | ## CSR & SSR 2 | 3 |
4 | 5 | > CSR : Client Side Rendering 6 | > 7 | > SSR : Server Side Rendering 8 | 9 |
10 | 11 | CSR에는 모바일 시대에 들어서 SPA가 등장했다. 12 | 13 | ##### SPA(Single Page Applictaion) 14 | 15 | > 최초 한 번 페이지 전체를 로딩한 뒤, 데이터만 변경하여 사용할 수 있는 애플리케이션 16 | 17 | SPA는 기본적으로 페이지 로드가 없고, 모든 페이지가 단순히 Html5 History에 의해 렌더링된다. 18 | 19 |
20 | 21 | 기존의 전통적 방법인 SSR 방식에는 성능 문제가 있었다. 22 | 23 | 요즘 웹에서 제공되는 정보가 워낙 많다. 요청할 때마다 새로고침이 일어나면서 페이지를 로딩할 때마다 서버로부터 리소스를 전달받아 해석하고, 화면에 렌더링하는 방식인 SSR은 데이터가 많을 수록 성능문제가 발생했다. 24 | 25 | ``` 26 | 현재 주소에서 동일한 주소를 가리키는 버튼을 눌렀을 때, 27 | 설정페이지에서 필요한 데이터를 다시 가져올 수 없다. 28 | ``` 29 | 30 | 이는, 인터랙션이 많은 환경에서 비효율적이다. 렌더링을 서버쪽에서 진행하면 그만큼 서버 자원이 많이 사용되기 때문에 불필요한 트래픽이 낭비된다. 31 | 32 |
33 | 34 | CSR 방식은 사용자의 행동에 따라 필요한 부분만 다시 읽어온다. 따라서 서버 측에서 렌더링하여 전체 페이지를 다시 읽어들이는 것보다 빠른 인터렉션을 기대할 수 있다. 서버는 단지 JSON파일만 보내주고, HTML을 그리는 역할은 자바스크립트를 통해 클라이언트 측에서 수행하는 방식이다. 35 | 36 |
37 | 38 | 뷰 렌더링을 유저의 브라우저가 담당하고, 먼저 웹앱을 브라우저에게 로드한 다음 필요한 데이터만 전달받아 보여주는 CSR은 트래픽을 감소시키고, 사용자에게 더 나은 경험을 제공할 수 있도록 도와준다. 39 | 40 |
41 | 42 |
43 | 44 | #### CSR 장단점 45 | 46 | - ##### 장점 47 | 48 | - 트래픽 감소 49 | 50 | > 필요한 데이터만 받는다 51 | 52 | - 사용자 경험 53 | 54 | > 새로고침이 발생하지 않음. 사용자가 네이티브 앱과 같은 경험을 할 수 있음 55 | 56 | - ##### 단점 57 | 58 | - 검색 엔진 59 | 60 | > 크롬에서 리액트로 만든 웹앱 소스를 확인하면 내용이 비어있음. 이처럼 검색엔진 크롤러가 데이터 수집에 어려움이 있을 가능성 존재 61 | > 62 | > 구글 검색엔진은 자바스크립트 엔진이 내장되어있지만, 네이버나 다음 등 검색엔진은 크롤링에 어려움이 있어 SSR을 따로 구현해야하는 번거로움 존재 63 | 64 |
65 | 66 | #### SSR 장단점 67 | 68 | - ##### 장점 69 | 70 | - 검색엔진 최적화 71 | 72 | - 초기로딩 성능개선 73 | 74 | > 첫 렌더링된 HTML을 클라이언트에서 전달해주기 때문에 초기로딩속도를 많이 줄여줌 75 | 76 | - ##### 단점 77 | 78 | - 프로젝트 복잡도 79 | 80 | > 라우터 사용하다보면 복잡도가 높아질 수 있음 81 | 82 | - 성능 악화 가능성 83 | 84 |
85 | 86 |
87 | 88 | ##### [참고 자료] 89 | 90 | - [링크](https://velog.io/@zansol/%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0-%EC%84%9C%EB%B2%84%EC%82%AC%EC%9D%B4%EB%93%9C%EB%A0%8C%EB%8D%94%EB%A7%81SSR-%ED%81%B4%EB%9D%BC%EC%9D%B4%EC%96%B8%ED%8A%B8%EC%82%AC%EC%9D%B4%EB%93%9C%EB%A0%8C%EB%8D%94%EB%A7%81CSR) -------------------------------------------------------------------------------- /Web/Cookie & Session.md: -------------------------------------------------------------------------------- 1 | ## Cookie & Session 2 | 3 | 4 | 5 | | | Cookie | Session | 6 | | :------: | :--------------------------------------------------: | :--------------: | 7 | | 저장위치 | Client | Server | 8 | | 저장형식 | Text | Object | 9 | | 만료시점 | 쿠키 저장시 설정
(설정 없으면 브라우저 종료 시) | 정확한 시점 모름 | 10 | | 리소스 | 클라이언트의 리소스 | 서버의 리소스 | 11 | | 용량제한 | 한 도메인 당 20개, 한 쿠키당 4KB | 제한없음 | 12 | 13 | 14 | 15 | #### 저장 위치 16 | 17 | - 쿠키 : 클라이언트의 웹 브라우저가 지정하는 메모리 or 하드디스크 18 | - 세션 : 서버의 메모리에 저장 19 | 20 | 21 | 22 | #### 만료 시점 23 | 24 | - 쿠키 : 저장할 때 expires 속성을 정의해 무효화시키면 삭제될 날짜 정할 수 있음 25 | - 세션 : 클라이언트가 로그아웃하거나, 설정 시간동안 반응이 없으면 무효화 되기 때문에 정확한 시점 알 수 없음 26 | 27 | 28 | 29 | #### 리소스 30 | 31 | - 쿠키 : 클라이언트에 저장되고 클라이언트의 메모리를 사용하기 때문에 서버 자원 사용하지 않음 32 | - 세션 : 세션은 서버에 저장되고, 서버 메모리로 로딩 되기 때문에 세션이 생길 때마다 리소스를 차지함 33 | 34 | 35 | 36 | #### 용량 제한 37 | 38 | - 쿠키 : 클라이언트도 모르게 접속되는 사이트에 의하여 설정될 수 있기 때문에 쿠키로 인해 문제가 발생하는 걸 막고자 한 도메인당 20개, 하나의 쿠키 당 4KB로 제한해 둠 39 | - 세션 : 클라이언트가 접속하면 서버에 의해 생성되므로 개수나 용량 제한 없음 -------------------------------------------------------------------------------- /Web/HTTP Request Methods.md: -------------------------------------------------------------------------------- 1 | # HTTP Request Methods 2 | 3 |
4 | 5 | ``` 6 | 클라이언트가 웹서버에게 요청하는 목적 및 그 종류를 알리는 수단을 말한다. 7 | ``` 8 | 9 |
10 | 11 | 12 | 13 |
14 | 15 | 1. #### GET 16 | 17 | 리소스(데이터)를 받기 위함 18 | 19 | URL(URI) 형식으로 서버 측에 리소스를 요청한다. 20 | 21 |
22 | 23 | 2. #### HEAD 24 | 25 | 메세지 헤더 정보를 받기 위함 26 | 27 | GET과 유사하지만, HEAD는 실제 문서 요청이 아닌 문서에 대한 정보 요청이다. 즉, Response 메세지를 받았을 때, Body는 비어있고, Header 정보만 들어있다. 28 | 29 |
30 | 31 | 3. #### POST 32 | 33 | 내용 및 파일 전송을 하기 위함 34 | 35 | 클라이언트에서 서버로 어떤 정보를 제출하기 위해 사용한다. Request 데이터를 HTTP Body에 담아 웹 서버로 전송한다. 36 | 37 |
38 | 39 | 4. #### PUT 40 | 41 | 리소스(데이터)를 갱신하기 위함 42 | 43 | POST와 유사하나, 기존 데이터를 갱신할 때 사용한다. 44 | 45 |
46 | 47 | 5. #### DELETE 48 | 49 | 리소스(데이터)를 삭제하기 위함 50 | 51 | 웹 서버측에 요청한 리소스를 삭제할 때 사용한다. 52 | 53 | > 실제로 클라이언트에서 서버 자원을 삭제하도록 하진 않아 비활성화로 구성한다. 54 | 55 |
56 | 57 | 6. #### CONNECT 58 | 59 | 클라이언트와 서버 사이의 중간 경유를 위함 60 | 61 | 보통 Proxy를 통해 SSL 통신을 하고자할 때 사용한다. 62 | 63 |
64 | 65 | 7. #### OPTIONS 66 | 67 | 서버 측 제공 메소드에 대한 질의를 하기 위함 68 | 69 | 웹 서버 측에서 지원하고 있는 메소드가 무엇인지 알기 위해 사용한다. 70 | 71 |
72 | 73 | 8. #### TRACE 74 | 75 | Request 리소스가 수신되는 경로를 보기 위함 76 | 77 | 웹 서버로부터 받은 내용을 확인하기 위해 loop-back 테스트를 할 때 사용한다. 78 | 79 |
80 | 81 | 9. #### PATCH 82 | 83 | 리소스(데이터)의 일부분만 갱신하기 위함 84 | 85 | PUT과 유사하나, 모든 데이터를 갱신하는 것이 아닌 리소스의 일부분만 수정할 때 쓰인다. 86 | 87 |
88 | 89 |
90 | 91 |
92 | 93 | #### [참고자료] 94 | 95 | - [링크](https://www.quora.com/What-are-HTTP-methods-and-what-are-they-used-for) 96 | - [링크](http://www.ktword.co.kr/test/view/view.php?no=3791) 97 | 98 | -------------------------------------------------------------------------------- /Web/HTTP status code.md: -------------------------------------------------------------------------------- 1 | ## HTTP status code 2 | 3 | > 클라우드 환경에서 HTTP API를 통해 통신하는 것이 대부분임 4 | > 5 | > 이때, 응답 상태 코드를 통해 성공/실패 여부를 확인할 수 있으므로 API 문서를 작성할 때 꼭 알아야 할 것이 HTTP status code다 6 | 7 |
8 | 9 | - 10x : 정보 확인 10 | - 20x : 통신 성공 11 | - 30x : 리다이렉트 12 | - 40x : 클라이언트 오류 13 | - 50x : 서버 오류 14 | 15 |
16 | 17 | ##### 200번대 : 통신 성공 18 | 19 | | 상태코드 | 이름 | 의미 | 20 | | :------: | :---------: | :----------------------: | 21 | | 200 | OK | 요청 성공(GET) | 22 | | 201 | Create | 생성 성공(POST) | 23 | | 202 | Accepted | 요청 접수O, 리소스 처리X | 24 | | 204 | No Contents | 요청 성공O, 내용 없음 | 25 | 26 |
27 | 28 | ##### 300번대 : 리다이렉트 29 | | 상태코드 | 이름 | 의미 | 30 | | :------: | :--------------: | :---------------------------: | 31 | | 300 | Multiple Choice | 요청 URI에 여러 리소스가 존재 | 32 | | 301 | Move Permanently | 요청 URI가 새 위치로 옮겨감 | 33 | | 304 | Not Modified | 요청 URI의 내용이 변경X | 34 | 35 |
36 | 37 | ##### 400번대 : 클라이언트 오류 38 | 39 | | 상태코드 | 이름 | 의미 | 40 | | :------: | :----------------: | :-------------------------------: | 41 | | 400 | Bad Request | API에서 정의되지 않은 요청 들어옴 | 42 | | 401 | Unauthorized | 인증 오류 | 43 | | 403 | Forbidden | 권한 밖의 접근 시도 | 44 | | 404 | Not Found | 요청 URI에 대한 리소스 존재X | 45 | | 405 | Method Not Allowed | API에서 정의되지 않은 메소드 호출 | 46 | | 406 | Not Acceptable | 처리 불가 | 47 | | 408 | Request Timeout | 요청 대기 시간 초과 | 48 | | 409 | Conflict | 모순 | 49 | | 429 | Too Many Request | 요청 횟수 상한 초과 | 50 | 51 |
52 | 53 | ##### 500번대 : 서버 오류 54 | 55 | | 상태코드 | 이름 | 의미 | 56 | | :------: | :-------------------: | :------------------: | 57 | | 500 | Internal Server Error | 서버 내부 오류 | 58 | | 502 | Bad Gateway | 게이트웨이 오류 | 59 | | 503 | Service Unavailable | 서비스 이용 불가 | 60 | | 504 | Gateway Timeout | 게이트웨이 시간 초과 | -------------------------------------------------------------------------------- /Web/Logging Level.md: -------------------------------------------------------------------------------- 1 | ## Logging Level 2 | 3 |
4 | 5 | 보통 log4j 라이브러리를 활용한다. 6 | 7 | 크게 ERROR, WARN, INFO, DEBUG로 로그 레벨을 나누어 작성한다. 8 | 9 |
10 | 11 | - #### ERROR 12 | 13 | 에러 로그는, 프로그램 동작에 큰 문제가 발생했다는 것으로 즉시 문제를 조사해야 하는 것 14 | 15 | `DB를 사용할 수 없는 상태, 중요 에러가 나오는 상황` 16 | 17 |
18 | 19 | - #### WARN 20 | 21 | 주의해야 하지만, 프로세스는 계속 진행되는 상태. 하지만 WARN에서도 2가지의 부분에선 종료가 일어남 22 | 23 | - 명확한 문제 : 현재 데이터를 사용 불가, 캐시값 사용 등 24 | - 잠재적 문제 : 개발 모드로 프로그램 시작, 관리자 콘솔 비밀번호가 보호되지 않고 접속 등 25 | 26 |
27 | 28 | - #### INFO 29 | 30 | 중요한 비즈니스 프로세스가 시작될 때와 종료될 때를 알려주는 로그 31 | 32 | `~가 ~를 실행했음` 33 | 34 |
35 | 36 | - #### DEBUG 37 | 38 | 개발자가 기록할 가치가 있는 정보를 남기기 위해 사용하는 레벨 39 | 40 |
41 | 42 |
43 | 44 | ##### [참고사항] 45 | 46 | - [링크](https://jangiloh.tistory.com/18) 47 | 48 | -------------------------------------------------------------------------------- /Web/Nuxt.js.md: -------------------------------------------------------------------------------- 1 | # Nuxt.js 2 | 3 | 4 | 5 |
6 | 7 | > vue.js를 서버에서 렌더링할 수 있도록 도와주는 오픈소스 프레임워크 8 | 9 | 서버, 클라이언트 코드의 배포를 축약시켜 SPA(싱글페이지 앱)을 간편하게 만들어준다. 10 | 11 | Vue.js 프로젝트를 진행할 때, 서버 부분을 미리 구성하고 정적 페이지를 만들어내는 기능을 통해 UI 렌더링을 보다 신속하게 제공해주는 기능이 있다. 12 | 13 |
14 | 15 |
16 | 17 | ***들어가기에 앞서..*** 18 | 19 | - SSR(Server Side Rendering) : 서버 쪽에서 페이지 컨텐츠들이 렌더링된 상태로 응답해줌 20 | - CSR(Client Side Rendering) : 클라이언트(웹브라우저) 쪽에서 컨텐츠들을 렌더링하는 것 21 | - SPA(Single Page Application) : 하나의 페이지로 구성된 웹사이트. index.html안에 모든 웹페이지들이 javascript로 구현되어 있는 형태 22 | 23 | > SPA는 보안 이슈나 검색 엔진 최적화에 있어서 단점이 존재. 이를 극복하기 위해 처음 불러오는 화면은 SSR로, 그 이후부터는 CSR로 진행하는 방식이 효율적이다. 24 | 25 |
26 | 27 | ***Nuxt.js는 왜 사용하나?*** 28 | 29 | vue.js를 서버에서 렌더링하려면 설정해야할 것들이 한두개가 아니다ㅠ 30 | 31 | 보통 babel과 같은 webpack을 통해 자바스크립트를 빌드하고 컴파일하는 과정을 거치게 된다. Node.js에서는 직접 빌드, 컴파일을 하지 않으므로, 이런 것들을 분리하여 SSR(서버 사이드 렌더링)이 가능하도록 미리 세팅해두는 것이 Nuxt.js다. 32 | 33 | > Vue에서는 Nuxt를, React에서는 Next 프레임워크를 사용함 34 | 35 |
36 | 37 | Nuxt CLI를 통해 쉽게 프로젝트를 만들고 진행할 수 있음 38 | 39 | ``` 40 | $ vue init nuxt/starter 41 | ``` 42 | 43 | 기본적으로 `vue-router`나 `vuex`를 이용할 수 있게 디렉토리가 준비되어 있기 때문에 Vue.js로 개발을 해본 사람들은 편하게 활용이 가능하다. 44 | 45 |
46 | 47 | #### 장점 48 | 49 | --- 50 | 51 | - 일반적인 SPA 개발은, 검색 엔진에서 노출되지 않아 조회가 힘들다. 하지만 Nuxt를 이용하게 되면 서버사이드렌더링으로 화면을 보여주기 때문에, 검색엔진 봇이 화면들을 잘 긁어갈 수 있다. 따라서 **SPA로 개발하더라도 SEO(검색 엔진 최적화)를 걱정하지 않아도 된다.** 52 | 53 | > 일반적으로 많은 회사들은 검색엔진에 적절히 노출되는 것이 매우 중요함. 따라서 **검색 엔진 최적화**는 개발 시 반드시 고려해야 할 부분 54 | 55 | - SPA임에도 불구하고, Express가 서버로 뒤에서 돌고 있다. 이는 내가 원하는 API를 프로젝트에서 만들어서 사용할 수 있다는 뜻! 56 | 57 | 58 | 59 | #### 단점 60 | 61 | --- 62 | 63 | Nuxt를 사용할 때, 단순히 프론트/백엔드를 한 프로젝트에서 개발할 수 있지않을까로 접근하면 큰코 다칠 수 있다. 64 | 65 | ex) API 요청시 에러가 발생하면, 프론트엔드에게 오류 발생 상태를 전달해줘야 예외처리를 진행할텐데 Nuxt에서 Express 에러까지 먹어버리고 리디렉션시킴 66 | 67 | > API부분을 Nuxt로 활용하는 게 상당히 어렵다고함 68 | 69 | -------------------------------------------------------------------------------- /Web/OAuth.md: -------------------------------------------------------------------------------- 1 | ## OAuth 2 | 3 | > Open Authorization 4 | 5 | 인터넷 사용자들이 비밀번호를 제공하지 않고, 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수있는 개방형 표준 방법 6 | 7 |
8 | 9 | 이러한 매커니즘은 구글, 페이스북, 트위터 등이 사용하고 있으며 타사 애플리케이션 및 웹사이트의 계정에 대한 정보를 공유할 수 있도록 허용해준다. 10 | 11 |
12 | 13 |
14 | 15 | #### 사용 용어 16 | 17 | --- 18 | 19 | - **사용자** : 계정을 가지고 있는 개인 20 | - **소비자** : OAuth를 사용해 서비스 제공자에게 접근하는 웹사이트 or 애플리케이션 21 | - **서비스 제공자** : OAuth를 통해 접근을 지원하는 웹 애플리케이션 22 | - **소비자 비밀번호** : 서비스 제공자에서 소비자가 자신임을 인증하기 위한 키 23 | - **요청 토큰** : 소비자가 사용자에게 접근권한을 인증받기 위해 필요한 정보가 담겨있음 24 | - **접근 토큰** : 인증 후에 사용자가 서비스 제공자가 아닌 소비자를 통해 보호 자원에 접근하기 위한 키 값 25 | 26 |
27 | 28 | 토큰 종류로는 Access Token과 Refresh Token이 있다. 29 | 30 | Access Token은 만료시간이 있고 끝나면 다시 요청해야 한다. Refresh Token은 만료되면 아예 처음부터 진행해야 한다. 31 | 32 |
33 | 34 | #### 인증 과정 35 | 36 | --- 37 | 38 | > 소비자 <-> 서비스 제공자 39 | 40 | 1. 소비자가 서비스 제공자에게 요청토큰을 요청한다. 41 | 2. 서비스 제공자가 소비자에게 요청토큰을 발급해준다. 42 | 3. 소비자가 사용자를 서비스제공자로 이동시킨다. 여기서 사용자 인증이 수행된다. 43 | 4. 서비스 제공자가 사용자를 소비자로 이동시킨다. 44 | 5. 소비자가 접근토큰을 요청한다. 45 | 6. 서비스제공자가 접근토큰을 발급한다. 46 | 7. 발급된 접근토큰을 이용해서 소비자에서 사용자 정보에 접근한다. 47 | 48 |
49 | -------------------------------------------------------------------------------- /Web/PWA (Progressive Web App).md: -------------------------------------------------------------------------------- 1 | ### PWA (Progressive Web App) 2 | 3 | > 웹의 장점과 앱의 장점을 결합한 환경 4 | > 5 | > `앱 수준과 같은 사용자 경험을 웹에서 제공하는 것이 목적!` 6 | 7 |
8 | 9 | #### 특징 10 | 11 | 확장성이 좋고, 깊이 있는 앱같은 웹을 만드는 것을 지향한다. 12 | 13 | 웹 주소만 있다면, 누구나 접근하여 사용이 가능하고 스마트폰의 저장공간을 잡아 먹지 않음 14 | 15 | **서비스 작업자(Service Worker) API** : 웹앱의 중요한 부분을 캐싱하여 사용자가 다음에 열 때 빠르게 로딩할 수 있도록 도와줌 16 | 17 | → 네트워크 환경이 좋지 않아도 빠르게 구동되며, 사용자에게 푸시 알림을 보낼 수도 있음 18 | 19 |
20 | 21 | #### PWA 제공 기능 22 | 23 | - 프로그래시브 : 점진적 개선을 통해 작성돼서 어떤 브라우저든 상관없이 모든 사용자에게 적합 24 | - 반응형 : 데스크톱, 모바일, 테블릿 등 모든 폼 factor에 맞음 25 | - 연결 독립적 : 서비스 워커를 사용해 오프라인에서도 작동이 가능함 26 | - 안전 : HTTPS를 통해 제공이 되므로 스누핑이 차단되어 콘텐츠가 변조되지 않음 27 | - 검색 가능 : W3C 매니페스트 및 서비스 워커 등록 범위 덕분에 '앱'으로 식별되어 검색이 가능함 28 | - 재참여 가능 : 푸시 알림과 같은 기능을 통해 쉽게 재참여가 가능함 29 | -------------------------------------------------------------------------------- /Web/README.md: -------------------------------------------------------------------------------- 1 | ## Web 2 | 3 | - [브라우저 동작 방법](https://github.com/kim6394/tech-interview-for-developer/blob/master/Web/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%20%EB%8F%99%EC%9E%91%20%EB%B0%A9%EB%B2%95.md) 4 | - [쿠키(Cookie) & 세션(Session)](https://github.com/kim6394/tech-interview-for-developer/blob/master/Web/Cookie%20%26%20Session.md) 5 | - [웹 서버와 WAS의 차이점](https://github.com/kim6394/tech-interview-for-developer/blob/master/Web/Web%20Server%EC%99%80%20WAS%EC%9D%98%20%EC%B0%A8%EC%9D%B4.md) 6 | - [OAuth]() 7 | - [PWA(Progressive Web App)](https://github.com/kim6394/tech-interview-for-developer/blob/master/Web/PWA%20(Progressive%20Web%20App).md) 8 | - Vue.js 9 | - [Vue.js 라이프사이클](https://github.com/kim6394/tech-interview-for-developer/blob/master/Web/Vue.js%20%EB%9D%BC%EC%9D%B4%ED%94%84%EC%82%AC%EC%9D%B4%ED%81%B4%20%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0.md) 10 | - [Vue CLI + Spring Boot 연동하여 환경 구축하기](https://github.com/kim6394/tech-interview-for-developer/blob/master/Web/Vue%20CLI%20%2B%20Spring%20Boot%20%EC%97%B0%EB%8F%99%ED%95%98%EC%97%AC%20%ED%99%98%EA%B2%BD%20%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0.md) 11 | - [Vue.js + Firebase로 이메일 회원가입&로그인 구현하기](https://github.com/kim6394/tech-interview-for-developer/blob/master/Web/Vue.js%20%2B%20Firebase%EB%A1%9C%20%EC%9D%B4%EB%A9%94%EC%9D%BC%20%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85%EB%A1%9C%EA%B7%B8%EC%9D%B8%20%EA%B5%AC%ED%98%84.md) 12 | - [Vue.js + Firebase로 Facebook 로그인 연동하기](https://github.com/kim6394/tech-interview-for-developer/blob/master/Web/Vue.js%20%2B%20Firebase%EB%A1%9C%20%ED%8E%98%EC%9D%B4%EC%8A%A4%EB%B6%81(facebook)%20%EB%A1%9C%EA%B7%B8%EC%9D%B8%20%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0.md) 13 | - [Nuxt.js란]() 14 | - React 15 | - [React + Spring Boot 연동하여 환경 구축하기](https://github.com/kim6394/tech-interview-for-developer/blob/master/Web/React%20%26%20Spring%20Boot%20%EC%97%B0%EB%8F%99%ED%95%98%EC%97%AC%20%ED%99%98%EA%B2%BD%20%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0.md) 16 | 17 |
-------------------------------------------------------------------------------- /Web/REST API.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/Web/REST API.pptx -------------------------------------------------------------------------------- /Web/React/React Fragment.md: -------------------------------------------------------------------------------- 1 | # [React] Fragment 2 | 3 |
4 | 5 | ``` 6 | JSX 파일 규칙상 return 시 하나의 태그로 묶어야한다. 7 | 이런 상황에 Fragment를 사용하면 쉽게 그룹화가 가능하다. 8 | ``` 9 | 10 |
11 | 12 | 아래와 같이 Table 컴포넌트에서 Columns를 불렀다고 가정해보자 13 | 14 | ```JSX 15 | import { Component } from 'React' 16 | import Columns from '../Components' 17 | 18 | class Table extends Component { 19 | render() { 20 | return ( 21 | 22 | 23 | 24 | 25 |
26 | ); 27 | } 28 | } 29 | ``` 30 | 31 |
32 | 33 | Columns 컴포넌트에서는 ` ~~ `와 같은 element를 반환해야 유효한 테이블 생성이 가능할 것이다. 34 | 35 | ```jsx 36 | import { Component } from 'React' 37 | 38 | class Columns extends Component { 39 | render() { 40 | return ( 41 |
42 | Hello 43 | World 44 |
45 | ); 46 | } 47 | } 48 | ``` 49 | 50 | 여러 td 태그를 작성하기 위해 div 태그로 묶었다. (JSX 파일 규칙상 return 시 하나의 태그로 묶어야한다.) 51 | 52 | 이제 Table 컴포넌트에서 DOM 트리를 그렸을 때 어떻게 결과가 나오는지 확인해보자 53 | 54 |
55 | 56 | ```html 57 | 58 | 59 |
60 |
61 | 62 | 63 | 64 |
HelloWorld
65 | ``` 66 | 67 | Columns 컴포넌트에서 div 태그로 묶어서 Table 컴포넌트로 보냈기 때문에 문제가 발생한다. 따라서 JSX파일의 return문을 무조건 div 태그로 묶는 것이 바람직하지 않을 수 있다. 68 | 69 | 이때 사용할 수 있는 문법이 바로 `Fragment`다. 70 | 71 | ```jsx 72 | import { Component } from 'React' 73 | 74 | class Columns extends Component { 75 | render() { 76 | return ( 77 | 78 | Hello 79 | World 80 | 81 | ); 82 | } 83 | } 84 | ``` 85 | 86 | div 태그 대신에 Fragment로 감싸주면 문제가 해결된다. Fragment는 DOM트리에 추가되지 않기 때문에 정상적으로 Table을 생성할 수 있다. 87 | 88 |
89 | 90 | Fragment로 명시하지 않고, 빈 태그로도 가능하다. 91 | 92 | ```JSX 93 | import { Component } from 'React' 94 | 95 | class Columns extends Component { 96 | render() { 97 | return ( 98 | <> 99 | Hello 100 | World 101 | 102 | ); 103 | } 104 | } 105 | ``` 106 | 107 |
108 | 109 | 이 밖에도 부모, 자식과의 관계에서 flex, grid로 연결된 element가 있는 경우에는 div로 연결 시 레이아웃을 유지하는데 어려움을 겪을 수도 있다. 110 | 111 | 따라서 위와 같은 개발이 필요할 때는 Fragment를 적절한 상황에 사용하면 된다. 112 | 113 |
114 | 115 |
116 | 117 | #### [참고 사항] 118 | 119 | - [링크](https://velog.io/@dolarge/React-Fragment%EB%9E%80) 120 | -------------------------------------------------------------------------------- /Web/React/React Hook.md: -------------------------------------------------------------------------------- 1 | # React Hook 2 | 3 | > useState(), useEffect() 정의 4 | 5 | 6 | 7 |
8 | 9 | 리액트의 Component는 '클래스형'과 '함수형'으로 구성되어 있다. 10 | 11 | 기존의 클래스형 컴포넌트에서는 몇 가지 어려움이 존재한다. 12 | 13 | 1. 상태(State) 로직 재사용 어려움 14 | 2. 코드가 복잡해짐 15 | 3. 관련 없는 로직들이 함께 섞여 있어 이해가 힘듬 16 | 17 | 이와 같은 어려움을 해결하기 위해, 'Hook'이 도입되었다. (16.8 버전부터) 18 | 19 |
20 | 21 | ### Hook 22 | 23 | - 함수형 컴포넌트에서 State와 Lifecycle 기능을 연동해주는 함수 24 | - '클래스형'에서는 동작하지 않으며, '함수형'에서만 사용 가능 25 | 26 |
27 | 28 | #### useState 29 | 30 | 기본적인 Hook으로 상태관리를 해야할 때 사용하면 된다. 31 | 32 | 상태를 변경할 때는, `set`으로 준 이름의 함수를 호출한다. 33 | 34 | ```jsx 35 | const [posts, setPosts] = useState([]); // 비구조화 할당 문법 36 | ``` 37 | 38 | `useState([]);`와 같이 `( )` 안에 초기화를 설정해줄 수 있다. 현재 예제는 빈 배열을 만들어 둔 상황인 것이다. 39 | 40 |
41 | 42 | #### useEffect 43 | 44 | 컴포넌트가 렌더링 될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook 45 | 46 | > '클래스' 컴포넌트의 componentDidMount()와 componentDidUpdate()의 역할을 동시에 한다고 봐도 된다. 47 | 48 | ```jsx 49 | useEffect(() => { 50 | console.log("렌더링 완료"); 51 | console.log(posts); 52 | }); 53 | ``` 54 | 55 | posts가 변경돼 리렌더링이 되면, useEffect가 실행된다. 56 | 57 |
58 | 59 |
60 | 61 | #### [참고자료] 62 | 63 | - [링크](https://ko.reactjs.org/docs/hooks-intro.html) 64 | -------------------------------------------------------------------------------- /Web/Spring/JPA.md: -------------------------------------------------------------------------------- 1 | # JPA 2 | 3 | > Java Persistence API 4 | 5 |
6 | 7 | ``` 8 | 개발자가 직접 SQL을 작성하지 않고, JPA API를 활용해 DB를 저장하고 관리할 수 있다. 9 | ``` 10 | 11 |
12 | 13 | JPA는 오늘날 스프링에서 많이 활용되고 있지만, 스프링이 제공하는 API가 아닌 **자바가 제공하는 API다.** 14 | 15 | 자바 ORM 기술에 대한 표준 명세로, 자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스다. 16 | 17 |
18 | 19 | #### ORM(Object Relational Mapping) 20 | 21 | ORM 프레임워크는 자바 객체와 관계형 DB를 매핑한다. 즉, 객체가 DB 테이블이 되도록 만들어주는 것이다. ORM을 사용하면, SQL을 작성하지 않아도 직관적인 메소드로 데이터를 조작할 수 있다는 장점이 있다. ( 개발자에게 생산성을 향상시켜줄 수 있음 ) 22 | 23 | 종류로는 Hibernate, EclipseLink, DataNucleus 등이 있다. 24 | 25 |
26 | 27 | 28 | 29 | 스프링 부트에서는 `spring-boot-starter-data-jpa`로 패키지를 가져와 사용하며, 이는 Hibernate 프레임워크를 활용한다. 30 | 31 |
JPA는 애플리케이션과 JDBC 사이에서 동작하며, 개발자가 JPA를 활용했을 때 JDBC API를 통해 SQL을 호출하여 데이터베이스와 호출하는 전개가 이루어진다. 32 | 33 | 즉, 개발자는 JPA의 활용법만 익히면 DB 쿼리 구현없이 데이터베이스를 관리할 수 있다. 34 | 35 |
36 | 37 | ### JPA 특징 38 | 39 | 1. ##### 객체 중심 개발 가능 40 | 41 | SQL 중심 개발이 이루어진다면, CRUD 작업이 반복해서 이루어져야한다. 42 | 43 | 하나의 테이블을 생성해야할 때 이에 해당하는 CRUD를 전부 만들어야 하며, 추후에 컬럼이 생성되면 관련 SQL을 모두 수정해야 하는 번거로움이 있다. 또한 개발 과정에서 실수할 가능성도 높아진다. 44 | 45 |
46 | 47 | 2. ##### 생산성 증가 48 | 49 | SQL 쿼리를 직접 생성하지 않고, 만들어진 객체에 JPA 메소드를 활용해 데이터베이스를 다루기 때문에 개발자에게 매우 편리성을 제공해준다. 50 | 51 |
52 | 53 | 3. ##### 유지보수 용이 54 | 55 | 쿼리 수정이 필요할 때, 이를 담아야 할 DTO 필드도 모두 변경해야 하는 작업이 필요하지만 JPA에서는 엔티티 클래스 정보만 변경하면 되므로 유지보수에 용이하다. 56 | 57 | 4. ##### 성능 증가 58 | 59 | 사람이 직접 SQL을 짜는 것과 비교해서 JPA는 동일한 쿼리에 대한 캐시 기능을 지원해주기 때문에 비교적 높은 성능 효율을 경험할 수 있다. 60 | 61 |
62 | 63 | #### 제약사항 64 | 65 | JPA는 복잡한 쿼리보다는 실시간 쿼리에 최적화되어있다. 예를 들어 통계 처리와 같은 복잡한 작업이 필요한 경우에는 기존의 Mybatis와 같은 Mapper 방식이 더 효율적일 수 있다. 66 | 67 | > Spring에서는 JPA와 Mybatis를 같이 사용할 수 있기 때문에, 상황에 맞는 방식을 택하여 개발하면 된다. 68 | 69 |
70 | 71 |
72 | 73 | #### [참고 사항] 74 | 75 | - [링크](https://velog.io/@modsiw/JPAJava-Persistence-API%EC%9D%98-%EA%B0%9C%EB%85%90) 76 | - [링크](https://wedul.site/506) 77 | 78 | -------------------------------------------------------------------------------- /Web/Spring/Spring MVC.md: -------------------------------------------------------------------------------- 1 | # Spring MVC Framework 2 | 3 |
4 | 5 | ``` 6 | 스프링 MVC 프레임워크가 동작하는 원리를 이해하고 있어야 한다 7 | ``` 8 | 9 |
10 | 11 | 12 | 13 | 클라이언트가 서버에게 url을 통해 요청할 때 일어나는 스프링 프레임워크의 동작을 그림으로 표현한 것이다. 14 | 15 |
16 | 17 | ### MVC 진행 과정 18 | 19 | ---- 20 | 21 | - 클라이언트가 url을 요청하면, 웹 브라우저에서 스프링으로 request가 보내진다. 22 | - `Dispatcher Servlet`이 request를 받으면, `Handler Mapping`을 통해 해당 url을 담당하는 Controller를 탐색 후 찾아낸다. 23 | - 찾아낸 `Controller`로 request를 보내주고, 보내주기 위해 필요한 Model을 구성한다. 24 | - `Model`에서는 페이지 처리에 필요한 정보들을 Database에 접근하여 쿼리문을 통해 가져온다. 25 | - 데이터를 통해 얻은 Model 정보를 Controller에게 response 해주면, Controller는 이를 받아 Model을 완성시켜 Dispatcher Servlet에게 전달해준다. 26 | - Dispatcher Servlet은 `View Resolver`를 통해 request에 해당하는 view 파일을 탐색 후 받아낸다. 27 | - 받아낸 View 페이지 파일에 Model을 보낸 후 클라이언트에게 보낼 페이지를 완성시켜 받아낸다. 28 | - 완성된 View 파일을 클라이언트에 response하여 화면에 출력한다. 29 | 30 |
31 | 32 | ### 구성 요소 33 | 34 | --- 35 | 36 | #### Dispatcher Servlet 37 | 38 | 모든 request를 처리하는 중심 컨트롤러라고 생각하면 된다. 서블릿 컨테이너에서 http 프로토콜을 통해 들어오는 모든 request에 대해 제일 앞단에서 중앙집중식으로 처리해주는 핵심적인 역할을 한다. 39 | 40 | 기존에는 web.xml에 모두 등록해줘야 했지만, 디스패처 서블릿이 모든 request를 핸들링하면서 작업을 편리하게 할 수 있다. 41 | 42 |
43 | 44 | #### Handler Mapping 45 | 46 | 클라이언트의 request url을 어떤 컨트롤러가 처리해야 할 지 찾아서 Dispatcher Servlet에게 전달해주는 역할을 담당한다. 47 | 48 | > 컨트롤러 상에서 url을 매핑시키기 위해 `@RequestMapping`을 사용하는데, 핸들러가 이를 찾아주는 역할을 한다. 49 | 50 |
51 | 52 | #### Controller 53 | 54 | 실질적인 요청을 처리하는 곳이다. Dispatcher Servlet이 프론트 컨트롤러라면, 이 곳은 백엔드 컨트롤러라고 볼 수 있다. 55 | 56 | 모델의 처리 결과를 담아 Dispatcher Servlet에게 반환해준다. 57 | 58 |
59 | 60 | #### View Resolver 61 | 62 | 컨트롤러의 처리 결과를 만들 view를 결정해주는 역할을 담당한다. 다양한 종류가 있기 때문에 상황에 맞게 활용하면 된다. 63 | 64 |
65 | 66 |
67 | 68 | #### [참고사항] 69 | 70 | - [링크](https://velog.io/@miscaminos/Spring-MVC-framework) 71 | - [링크](https://velog.io/@miscaminos/Spring-MVC-framework) -------------------------------------------------------------------------------- /Web/Spring/[Spring Boot] SpringApplication.md: -------------------------------------------------------------------------------- 1 | ## [Spring Boot] SpringApplication 2 | 3 |
4 | 5 | 스프링 부트로 프로젝트를 실행할 때 Application 클래스를 만든다. 6 | 7 | 클래스명은 개발자가 프로젝트에 맞게 설정할 수 있지만, 큰 틀은 아래와 같다. 8 | 9 | ```java 10 | @SpringBootApplication 11 | public class Application { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(Application.class, args); 15 | } 16 | 17 | } 18 | ``` 19 | 20 |
21 | 22 | `@SpringBootApplication` 어노테이션을 통해 스프링 Bean을 읽어와 자동으로 생성해준다. 23 | 24 | 이 어노테이션이 있는 파일 위치부터 설정들을 읽어가므로, 반드시 프로젝트의 최상단에 만들어야 한다. 25 | 26 | `SpringApplication.run()`으로 해당 클래스를 run하면, 내장 WAS를 실행한다. 내장 WAS의 장점으로는 개발자가 따로 톰캣과 같은 외부 WAS를 설치 후 설정해두지 않아도 애플리케이션을 실행할 수 있다. 27 | 28 | 또한, 외장 WAS를 사용할 시 이 프로젝트를 실행시키기 위한 서버에서 모두 외장 WAS의 종류와 버전, 설정을 일치시켜야만 한다. 따라서 내장 WAS를 사용하면 이런 신경은 쓰지 않아도 되기 때문에 매우 편리하다. 29 | 30 | > 실제로 많은 회사들이 이런 장점을 살려 내장 WAS를 사용하고 있고, 전환하고 있다. 31 | 32 | -------------------------------------------------------------------------------- /Web/Spring/[Spring Data JPA] 더티 체킹 (Dirty Checking).md: -------------------------------------------------------------------------------- 1 | # [JPA] 더티 체킹 (Dirty Checking) 2 | 3 |
4 | 5 | 6 | ``` 7 | 트랜잭션 안에서 Entity의 변경이 일어났을 때 8 | 변경한 내용을 자동으로 DB에 반영하는 것 9 | ``` 10 | 11 |
12 | 13 | ORM 구현체 개발 시 더티 체킹이라는 말을 자주 볼 수 있다. 14 | 15 | 더티 체킹이 어떤 것을 뜻하는 지 간단히 살펴보자. 16 | 17 |
18 | 19 | JPA로 개발하는 경우 구현한 한 가지 기능을 예로 들어보자 20 | 21 | ##### ex) 주문 취소 기능 22 | 23 | ```java 24 | @Transactional 25 | public void cancelOrder(Long orderId) { 26 | //주문 엔티티 조회 27 | Order order = orderRepository.findOne(orderId); 28 | 29 | //주문 취소 30 | order.cancel(); 31 | } 32 | ``` 33 | 34 | `orderId`를 통해 주문을 취소하는 메소드다. 데이터베이스에 반영하기 위해선, `update`와 같은 쿼리가 있어야할 것 같은데 존재하지 않는다. 35 | 36 | 하지만, 실제로 이 메소드를 실행하면 데이터베이스에 update가 잘 이루어진다. 37 | 38 | - 트랜잭션 시작 39 | - `orderId`로 주문 Entity 조회 40 | - 해당 Entity 주문 취소 상태로 **Update** 41 | - 트랜잭션 커밋 42 | 43 | 이를 가능하게 하는 것이 바로 '더티 체킹(Dirty Checking)'이라고 보면 된다. 44 | 45 |
46 | 47 | 그냥 더티 체킹의 단어만 간단히 해석하면 `변경 감지`로 볼 수 있다. 좀 더 자세히 말하면, Entity에서 변경이 일어난 걸 감지한 뒤, 데이터베이스에 반영시켜준다는 의미다. (변경은 최초 조회 상태가 기준이다) 48 | 49 | > Dirty : 상태의 변화가 생김 50 | > 51 | > Checking : 검사 52 | 53 | JPA에서는 트랜잭션이 끝나는 시점에 변화가 있던 모든 엔티티의 객체를 데이터베이스로 알아서 반영을 시켜준다. 즉, 트랜잭션의 마지막 시점에서 다른 점을 발견했을 때 데이터베이스로 update 쿼리를 날려주는 것이다. 54 | 55 | - JPA에서 Entity를 조회 56 | - 조회된 상태의 Entity에 대한 스냅샷 생성 57 | - 트랜잭션 커밋 후 해당 스냅샷과 현재 Entity 상태의 다른 점을 체크 58 | - 다른 점들을 update 쿼리로 데이터베이스에 전달 59 | 60 |
61 | 62 | 이때 더티 체킹을 검사하는 대상은 `영속성 컨텍스트`가 관리하는 Entity로만 대상으로 한다. 63 | 64 | 준영속, 비영속 Entity는 값을 변경할 지라도 데이터베이스에 반영시키지 않는다. 65 | 66 |
67 | 68 | 기본적으로 더티 체킹을 실행하면, SQL에서는 변경된 엔티티의 모든 내용을 update 쿼리로 만들어 전달하는데, 이때 필드가 많아지면 전체 필드를 update하는게 비효율적일 수도 있다. 69 | 70 | 이때는 `@DynamicUpdate`를 해당 Entity에 선언하여 변경 필드만 반영시키도록 만들어줄 수 있다. 71 | 72 | ```java 73 | @Getter 74 | @NoArgsConstructor 75 | @Entity 76 | @DynamicUpdate 77 | public class Order { 78 | 79 | @Id 80 | @GeneratedValue(strategy = GenerationType.IDENTITY) 81 | private Long id; 82 | private String product; 83 | ``` 84 | 85 |
86 | 87 |
88 | 89 | #### [참고 자료] 90 | 91 | - [링크](https://velog.io/@jiny/JPA-%EB%8D%94%ED%8B%B0-%EC%B2%B4%ED%82%B9Dirty-Checking-%EC%9D%B4%EB%9E%80) 92 | - [링크](https://jojoldu.tistory.com/415) 93 | -------------------------------------------------------------------------------- /Web/Spring/[Spring] Bean Scope.md: -------------------------------------------------------------------------------- 1 | # [Spring] Bean Scope 2 | 3 |
4 | 5 | ![image](https://user-images.githubusercontent.com/34904741/139436386-d6af0eba-0fb2-4776-a01d-58ea459d73f7.png) 6 | 7 |
8 | 9 | ``` 10 | Bean의 사용 범위를 말하는 Bean Scope의 종류에 대해 알아보자 11 | ``` 12 | 13 |
14 | 15 | Bean은 스프링에서 사용하는 POJO 기반 객체다. 16 | 17 | 상황과 필요에 따라 Bean을 사용할 때 하나만 만들어야 할 수도 있고, 여러개가 필요할 때도 있고, 어떤 한 시점에서만 사용해야할 때가 있을 수 있다. 18 | 19 | 이를 위해 Scope를 설정해서 Bean의 사용 범위를 개발자가 설정할 수 있다. 20 | 21 |
22 | 23 | 우선 따로 설정을 해주지 않으면, Spring에서 Bean은 `Singleton`으로 생성된다. 싱글톤 패턴처럼 특정 타입의 Bean을 딱 하나만 만들고 모두 공유해서 사용하기 위함이다. 보통은 Bean을 이렇게 하나만 만들어 사용하는 경우가 대부분이지만, 요구사항이나 구현에 따라 아닐 수도 있을 것이다. 24 | 25 | 따라서 Bean Scope는 싱글톤 말고도 여러가지를 지원해준다. 26 | 27 |
28 | 29 | ### Scope 종류 30 | 31 | - #### singleton 32 | 33 | 해당 Bean에 대해 IoC 컨테이너에서 단 하나의 객체로만 존재한다. 34 | 35 | - #### prototype 36 | 37 | 해당 Bean에 대해 다수의 객체가 존재할 수 있다. 38 | 39 | - #### request 40 | 41 | 해당 Bean에 대해 하나의 HTTP Request의 라이프사이클에서 단 하나의 객체로만 존재한다. 42 | 43 | - #### session 44 | 45 | 해당 Bean에 대해 하나의 HTTP Session의 라이프사이클에서 단 하나의 객체로만 존재한다. 46 | 47 | - #### global session 48 | 49 | 해당 Bean에 대해 하나의 Global HTTP Session의 라이프사이클에서 단 하나의 객체로만 존재한다. 50 | 51 | > request, session, global session은 MVC 웹 어플리케이션에서만 사용함 52 | 53 |
54 | 55 | Scope들은 Bean으로 등록하는 클래스에 어노테이션으로 설정해줄 수 있다. 56 | 57 | ```java 58 | import org.springframework.context.annotation.Scope; 59 | import org.springframework.stereotype.Service; 60 | 61 | @Scope("prototype") 62 | @Component 63 | public class UserController { 64 | } 65 | ``` 66 | 67 |
68 | 69 |
70 | 71 | #### [참고 자료] 72 | 73 | - [링크](https://gmlwjd9405.github.io/2018/11/10/spring-beans.html) -------------------------------------------------------------------------------- /Web/UI와 UX.md: -------------------------------------------------------------------------------- 1 | ## UI와 UX 2 | 3 |
4 | 5 | 많이 들어봤지만, 차이를 말하라고 하면 멈칫한다. 면접에서도 웹을 했다고 하면 나올 수 있는 질문. 6 | 7 |
8 | 9 | ### UI 10 | 11 | > User Interface 12 | 13 | 사용자가 앱을 사용할 때 마주하는 디자인, 레이아웃, 기술적인 부분이다. 14 | 15 | 디자인의 구성 요소인 폰트, 색깔, 줄간격 등 상세한 요소가 포함되고, 기술적 부분은 반응형이나 애니메이션효과 등이 포함된다. 16 | 17 | 따라서 UI는 사용자가 사용할 때 큰 불편함이 없어야하며, 만족도를 높여야 한다. 18 | 19 |
20 | 21 |
22 | 23 | ### UX 24 | 25 | > User eXperience 26 | 27 | 앱을 주로 사용하는 사용자들의 경험을 분석하여 더 편하고 효율적인 방향으로 프로세스가 진행될 수 있도록 만드는 것이다. 28 | 29 | (터치 화면, 사용자의 선택 flow 등) 30 | 31 | UX는 통계자료, 데이터를 기반으로 앱을 사용하는 유저들의 특성을 분석하여 상황과 시점에 맞도록 변화시킬 수 있어야 한다. 32 | 33 |
34 | 35 | UI를 포장물에 비유한다면, UX는 그 안의 내용물이라고 볼 수 있다. 36 | 37 | > 포장(UI)에 신경을 쓰는 것도 중요하고, 이를 사용할 사람을 분석해 알맞은 내용물(UX)로 채워서 제공해야한다. 38 | 39 | -------------------------------------------------------------------------------- /Web/Vue.js와 React의 차이.md: -------------------------------------------------------------------------------- 1 | ## Vue.js와 React의 차이 2 | 3 | 4 | 5 |
6 | 7 | ##### 개발 CLI 8 | 9 | - Vue.js : vue-cli 10 | - React : create-react-app 11 | 12 | ##### CSS 파일 존재 유무 13 | 14 | - Vue.js : 없음. style이 실제 컴포넌트 파일 안에서 정의됨 15 | - React : 파일이 존재. 해당 파일을 통해 style 적용 16 | 17 | ##### 데이터 변이 18 | 19 | - Vue.js : 반드시 데이터 객체를 생성한 이후 data를 업데이트 할 수 있음 20 | - React : state 객체를 만들고, 업데이트에 조금 더 작업이 필요 21 | 22 | ``` 23 | name: kim 값을 lee로 바꾸려면 24 | Vue.js : this.name = 'lee' 25 | React : this.setState({name:'lee'}) 26 | ``` 27 | 28 | Vue에서는 data를 업데이트할 때마다 setState를 알아서 결합해분다. 29 | 30 |
31 | 32 |
33 | 34 | 35 | 36 | #### [참고 사항] 37 | 38 | - [링크]( [https://medium.com/@erwinousy/%EB%82%9C-react%EC%99%80-vue%EC%97%90%EC%84%9C-%EC%99%84%EC%A0%84%ED%9E%88-%EA%B0%99%EC%9D%80-%EC%95%B1%EC%9D%84-%EB%A7%8C%EB%93%A4%EC%97%88%EB%8B%A4-%EC%9D%B4%EA%B2%83%EC%9D%80-%EA%B7%B8-%EC%B0%A8%EC%9D%B4%EC%A0%90%EC%9D%B4%EB%8B%A4-5cffcbfe287f](https://medium.com/@erwinousy/난-react와-vue에서-완전히-같은-앱을-만들었다-이것은-그-차이점이다-5cffcbfe287f) ) 39 | - [링크](https://kr.vuejs.org/v2/guide/comparison.html) 40 | 41 | -------------------------------------------------------------------------------- /Web/[Web] REST API.md: -------------------------------------------------------------------------------- 1 | ### REST API 2 | 3 | ---- 4 | 5 | REST : 웹 (HTTP) 의 장점을 활용한 아키텍쳐 6 | 7 | #### 1. REST (REpresentational State Transfer) 기본 8 | 9 | * REST의 요소 10 | 11 | * Method 12 | 13 | | Method | 의미 | Idempotent | 14 | | ------ | ------ | ---------- | 15 | | POST | Create | No | 16 | | GET | Select | Yes | 17 | | PUT | Update | Yes | 18 | | DELETE | Delete | Yes | 19 | 20 | > Idempotent : 한 번 수행하냐, 여러 번 수행했을 때 결과가 같나? 21 | 22 |
23 | 24 | * Resource 25 | 26 | * http://myweb/users와 같은 URI 27 | * 모든 것을 Resource (명사)로 표현하고, 세부 Resource에는 id를 붙임 28 | 29 |
30 | 31 | * Message 32 | 33 | * 메시지 포맷이 존재 34 | 35 | : JSON, XML 과 같은 형태가 있음 (최근에는 JSON 을 씀) 36 | 37 | ```text 38 | HTTP POST, http://myweb/users/ 39 | { 40 | "users" : { 41 | "name" : "terry" 42 | } 43 | } 44 | ``` 45 | 46 |
47 | 48 | * REST 특징 49 | 50 | * Uniform Interface 51 | 52 | * HTTP 표준만 맞는다면, 어떤 기술도 가능한 Interface 스타일 53 | 54 | 예) REST API 정의를 HTTP + JSON로 하였다면, C, Java, Python, IOS 플랫폼 등 특정 언어나 기술에 종속 받지 않고, 모든 플랫폼에 사용이 가능한 Loosely Coupling 구조 55 | 56 | * 포함 57 | * Self-Descriptive Messages 58 | 59 | * API 메시지만 보고, API를 이해할 수 있는 구조 (Resource, Method를 이용해 무슨 행위를 하는지 직관적으로 이해할 수 있음) 60 | 61 | * HATEOAS(Hypermedia As The Engine Of Application State) 62 | 63 | * Application의 상태(State)는 Hyperlink를 통해 전이되어야 함. 64 | * 서버는 현재 이용 가능한 다른 작업에 대한 하이퍼링크를 포함하여 응답해야 함. 65 | 66 | * Resource Identification In Requests 67 | 68 | * Resource Manipulation Through Representations 69 | 70 | * Statelessness 71 | 72 | * 즉, HTTP Session과 같은 컨텍스트 저장소에 **상태 정보 저장 안함** 73 | * **Request만 Message로 처리**하면 되고, 컨텍스트 정보를 신경쓰지 않아도 되므로, **구현이 단순해짐**. 74 | 75 | * 따라서, REST API 실행중 실패가 발생한 경우, Transaction 복구를 위해 기존의 상태를 저장할 필요가 있다. (POST Method 제외) 76 | 77 | * Resource 지향 아키텍쳐 (ROA : Resource Oriented Architecture) 78 | 79 | * Resource 기반의 복수형 명사 형태의 정의를 권장. 80 | 81 | * Client-Server Architecture 82 | 83 | * Cache Ability 84 | 85 | * Layered System 86 | 87 | * Code On Demand(Optional) 88 | -------------------------------------------------------------------------------- /Web/네이티브 앱 & 웹 앱 & 하이브리드 앱.md: -------------------------------------------------------------------------------- 1 | ## 네이티브 앱 & 웹 앱 & 하이브리드 앱 2 | 3 |
4 | 5 | #### 네이티브 앱 (Native App) 6 | 7 | 8 | 9 | 흔히 우리가 자주 사용하는 어플리케이션을 의미한다. 10 | 11 | 모바일 기기에 최적화된 언어로 개발된 앱으로 안드로이드 SDK를 이용한 Java 언어나 iOS 기반 SDK를 이용한 Swift 언어로 만드는 앱이 네이티브 앱에 속한다. 12 | 13 |
14 | 15 | ##### 장점 16 | 17 | - 성능이 웹앱, 하이브리드 앱에 비해 가장 높음 18 | - 네이티브 API를 호출하여 사용함으로 플랫폼과 밀착되어있음 19 | - Java나 Swift에 익숙한 사용자면 쉽게 접근 가능함 20 | 21 | ##### 단점 22 | 23 | - 플랫폼에 한정적 24 | - 언어에 제약적 25 | 26 |
27 | 28 |
29 | 30 | #### 모바일 웹 앱 (Mobile Wep App) 31 | 32 | 33 | 34 | 모바일웹 + 네이티브 앱을 결합한 형태 35 | 36 | 모바일 웹의 특징을 가지면서도, 네이티브 앱의 장점을 지녔다. 따라서 기존의 모바일 웹보다는 모바일에 최적화 된 앱이라고 말할 수 있다. 37 | 38 | 웹앱은 SPA를 활용해 속도가 빠르다는 장점이 있다. 39 | 40 | > 쉽게 말해, PC용 홈페이지를 모바일 스크린 크기에 맞춰 줄여 놓은 것이라고 생각하면 편함 41 | 42 |
43 | 44 | ##### 장점 45 | 46 | - 웹 사이트를 보는 것이므로 따로 설치할 필요X 47 | - 모든 기기와 브라우저에서 접근 가능 48 | - 별도 설치 및 승인 과정이 필요치 않아 유지보수에 용이 49 | 50 | ##### 단점 51 | 52 | - 플랫폼 API 사용 불가능. 오로지 브라우저 API만 사용가능 53 | - 친화적 터치 앱을 개발하기 약간 번거로움 54 | - 네이티브, 하이브리드 앱보다 실행 까다로움 (브라우저 열거 검색해서 들어가야함) 55 | 56 |
57 | 58 |
59 | 60 | #### 하이브리드 앱 (Hybrid App) 61 | 62 | 63 | 64 | > 네이티브 + 웹앱 65 | 66 | 네이티브 웹에, 웹 view를 띄워 웹앱을 실행시킨다. 양쪽의 API를 모두 사용할 수 있는 것이 가장 큰 장점 67 | 68 |
69 | 70 | ##### 장점 71 | 72 | - 네이티브 API, 브라우저 API를 모두 활용한 다양한 개발 가능 73 | - 웹 개발 기술로 앱 개발 가능 74 | - 한번의 개발로 다수 플랫폼에서 사용 가능 75 | 76 | ##### 단점 77 | 78 | - 네이티브 기능 접근 위해 개발 지식 필요 79 | - UI 프레임도구 사용안하면 개발자가 직접 UI 제작 80 | 81 |
82 | 83 |
84 | 85 | #### 요약 86 | 87 | 88 | 89 |
90 | 91 |
92 | 93 |
94 | 95 | ##### [참고 자료] 96 | 97 | - [링크](https://m.blog.naver.com/acornedu/221012420292) 98 | 99 | -------------------------------------------------------------------------------- /resources/CPU 스케줄링.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/CPU 스케줄링.PNG -------------------------------------------------------------------------------- /resources/CPU점유.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/CPU점유.PNG -------------------------------------------------------------------------------- /resources/Main Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/Main Image.png -------------------------------------------------------------------------------- /resources/authentication.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/authentication.JPG -------------------------------------------------------------------------------- /resources/composite_pattern_1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/composite_pattern_1.PNG -------------------------------------------------------------------------------- /resources/composite_pattern_2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/composite_pattern_2.PNG -------------------------------------------------------------------------------- /resources/composite_pattern_3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/composite_pattern_3.PNG -------------------------------------------------------------------------------- /resources/login.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/login.JPG -------------------------------------------------------------------------------- /resources/ncsoft.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/ncsoft.jpg -------------------------------------------------------------------------------- /resources/roadmap.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/roadmap.PNG -------------------------------------------------------------------------------- /resources/run 화면.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/run 화면.JPG -------------------------------------------------------------------------------- /resources/signup.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/signup.JPG -------------------------------------------------------------------------------- /resources/vue init.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/vue init.JPG -------------------------------------------------------------------------------- /resources/로그인 성공.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/로그인 성공.JPG -------------------------------------------------------------------------------- /resources/비밀번호 불일치시.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/비밀번호 불일치시.JPG -------------------------------------------------------------------------------- /resources/사용자확인.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/사용자확인.JPG -------------------------------------------------------------------------------- /resources/웹앱 추가.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/웹앱 추가.JPG -------------------------------------------------------------------------------- /resources/파이어베이스 프로젝트 추가.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/파이어베이스 프로젝트 추가.JPG -------------------------------------------------------------------------------- /resources/파이어베이스 프로젝트 추가2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/파이어베이스 프로젝트 추가2.JPG -------------------------------------------------------------------------------- /resources/활성화.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/활성화.JPG -------------------------------------------------------------------------------- /resources/회원가입성공.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangKyu/tech-interview-for-developer/b478de0481da8227913c647afb004c5d39c0718e/resources/회원가입성공.JPG --------------------------------------------------------------------------------