블로그

하얀종이개발자

인프런 워밍업 클럽 2기 - CS 전공지식 스터디 3주차 마지막 발자국

운영체제 3주차 학습 요약 가상메모리컴퓨터의 물리적 메모리의 크기를 확장하기 위해 사용되는 기술운영체제가 각 프로세스마다 독립적인 메모리공간을 할당할 수 있게 해줌이때문에 프로그래머는 프로그램이 메모리 어디에 위치하는지 신경쓰지 않고, 0부터 시작된다고 생각하고 프로그래밍 함동적주소변환 (DAT)메모리관리자가 가상메모리의 논리주소를 물리주소로 변환하는 것을 말함세그멘테이션 분할 방식에서 논리 주소를 물리주소로 변환메모리관리자는 CPU에서 받은 논리주소를 세그멘테이션 테이블을 이용하여 물리주소를 찾음페이징 분할 방식에서 논리 주소를 물리주소로 변환메모리관리자는 CPU에서 받은 논리주소를 페이지 테이블을 이용하여 물리주소를 찾음페이지드 세그멘테이션 분할 방식에서 논리 주소를 물리주소로 변환세그멘테이션 테이블의 속성값으로 페이지 테이블의 인덱스를 추가할 수 있게하여 세그멘테이션, 페이지 테이블을 모두 이용해서 물리주소를 찾음가상메모리는 세그멘테이션으로 분할되어 있고, 물리메모리는 페이징으로 분할되어 있어 각 분할방식의 장점을 취할 수 있게 함메모리 접근권한세그멘테이션 테이블에 메모리의 특정번지에 권한을 부여하는 속성을 추가하여, 메모리 접근시 권한을 검사할 수 있음디멘드 페이징 정책조만간 필요할 것 같은 데이터를 메모리에 가져오고 쓰이지 않을 것 같은 데이터는 스왑영역으로 보내는 정책필요한 데이터를 언제 메모리로 가져올지를 결정하는 것페이지 테이블 엔트리접근비트, 변경비트, 유효비트, 권한비트 (프레임번호만 있는게 아님)페이지 폴트프로세스가 가상메모리에 접근요청했을때 물리메모리에 데이터가 없을때 발생하는 인터럽트페이지 폴트가 발생하면 보조저장장치의 스왑영역에 접근하여 스왑영역에 있는 데이터를 메모리에 올리는 작업을 함페이지 교체정책스왑영역에서 데이터를 찾아 메모리에 올리려고 했는데, 이미 메모리가 가득찼을때 조회할 데이터를 메모리에 추가하기위해 데이터를 남기거나 스왑영역으로 보내는 정책무작위, FIFO, Optimum, LRU, Clock Algorithm, Enhanced Clock Algorithm스레싱과 워킹셋스레싱제한된 물리 메모리에 프로그램을 많이 올려 스왑 영역에 데이터가 많이 저장되고 Page Fault가 자주 발생하게 되면 CPU 사용률이 떨어짐. 스케줄러에 의해 운영체제는 CPU 사용률을 올리기 위해 더 많은 프로세스를 메모리에 올리게 되고 이를 반복하게 되면 CPU 사용률이 0에 가깝게 떨어지는데 이를 스레싱이라고 함워킹셋현재 메모리에 올라온 페이지는 다시 사용할 확률이 높기에 하나의 세트로 묶어서 메모리에 올리는데 이를 워킹셋이라고 함입출력장치주변장치(I/O 디바이스, 저장장치)들은 메인보드에 있는 버스로 연결되어 있음각 하드웨어에 맞게 외부 인터페이스가 존재캐릭터 디바이스, 블록디바이스 입출력 제어기는 두 개의 채널, 시스템 버스와 입출력 버스로 구분파일과 파일시스템운영체제가 파일을 관리하기 위한 파일 관리자파일을 관리하는 하드디스크나 Flash Memory(SSD)는 블록 디바이스, 파일 시스템은 전송 단위는 블록이지만, 사용자는 바이트 단위로 파일에 접근이 가능해야 함, 파일 관리자가 이를 중간에서 관리파일의 종류순차파일구조, 직접파일구조, 인덱스파일구조디렉토리관련있는 파일을 모아둘 수 있도록 하는 장치알고리즘 & 자료구조 3주차 학습 요약 삽입 정렬 (Insertion Sort)정렬되지 않은 영역에서 데이터를 하나씩 꺼내서 정렬된 영역 내 적절한 위치에 "삽입"해서 정렬하는 알고리즘삽입하려는 데이터를 정렬된 영역의 원소를 역순으로 순회하면서 비교O(n²)장점 : 작은 데이터나 거의 정렬된 데이터에 대해 매우 효율적단점 : 속도가 느려서 대규모 데이터에 비효율적 병합 정렬 (Merge Sort)정렬하려고 하는 배열을 잘게 쪼갠다음, 순서에 맞게 재배열하는 알고리즘 (재귀)O(n log n) 장점 : 속도가 빠르며 대규모 데이터에서도 일정한 성능을 보임 단점 : 추가 메모리 공간이 필요하며, 메모리 효율이 떨어질 수 있음퀵 정렬 (Quick Sort)배열의 숫자중 하나를 피벗으로 설정하고, 피벗의 왼쪽에는 작은값, 피벗의 오른쪽에는 큰값을 정렬하는 알고리즘분할시 왼쪽과 오른쪽의 포인트가 교차하면 피벗과 오른쪽 포인트의 값과 교환하여 피벗값을 정렬해나감평균 O(n log n), 최악 O(n²) 장점 : 평균적으로 매우 빠르고, 메모리 사용이 적음 단점 : 피벗 선택에 따라 성능이 달라지며, 최악의 경우 속도가 느려질 수 있음 (그러나 최악이 되는 경우는 거의 없음)동적프로그래밍메모이제이션계산 결과를 따로 기억해서 여러 번 중복 계산하지 않도록 하는 기법하향식 계산 방식으로 활용타뷸레이션계산에 필요한 모든 값을 전부 계산 후 테이블에 저장하는 기법상향식 계산 방식으로 활용 회고스터디의 마지막 주차가 되었네요. 나름 정리도 하고 CS전공지식 스터디 내부에서 다른분들이랑 모여 발표 스터디도 하면서 열심히 학습하면서 많이 배운시간이 었던거 같아요. 특히나 알고리즘을 직접 구현해보면서 각 알고리즘의 장.단점을 외우지 않아도 조금만 생각해보면 장.단점을 도출할 수 있게 되어서 좋았어요.스터디 발표 & 정리 자료 캡쳐빠르게 끝나 아쉬움반 후련함반이 있지만, 계속 복습하고 부족한 부분 채워나가면서 열심히 해나가겠습니다.많이 배웠습니다. 즐거웠어요.

백엔드CS전공지식그림으로쉽게배우는자료구조와알고리즘그림으로쉽게배우는운영체제인프런워밍업클럽2기감자

하얀종이개발자

인프런 워밍업 클럽 2기 - CS 전공지식 스터디 특별미션

특별미션 특별 미션) 실수로 워밍업 클럽 출석을 빼먹었는데 우연히 데이터를 수정할 수 있는 권한이 주어졌습니다. 러너분의 이름(name)과 출석수(count)가 저장된 배열에서 여러분(나)의 데이터를 퀵정렬을 이용해 오름차순 정렬하고 가장 첫 번째 데이터인 여러분의 출석수를 변경하도록 코드를 작성해주세요. (퀵정렬 구현 부분도 변경) import java.util.Arrays; public class QuickSort { public static void main(String[] args) { User[] arr = { new User("홍길동", 5), new User("임꺽정", 4), new User("이순신", 3), new User("나", 1), new User("짱구", 5) }; System.out.println("===== 정렬 전 ====="); System.out.println(Arrays.toString(arr)); // 퀵정렬 실행 quickSort(arr, 0, arr.length - 1); // 첫 번째 나의 데이터의 출석수 변경 arr[0].count = 5; System.out.println("===== 정렬 후 ====="); System.out.println(Arrays.toString(arr)); } // 퀵정렬 함수 static void quickSort(User[] arr, int left, int right) { // 기저조건 if (left >= right) { return; } int pivotIndex = divide(arr, left, right); quickSort(arr, left, pivotIndex - 1); quickSort(arr, pivotIndex + 1, right); } // 배열을 나누고 피벗의 위치를 반환하는 함수 static int divide(User[] arr, int left, int right) { int pivot = arr[left].count; // 피벗은 첫 번째 원소의 count 값 int leftStartIndex = left + 1; int rightStartIndex = right; while (leftStartIndex <= rightStartIndex) { // 피벗보다 큰 값을 찾을 때까지 왼쪽에서 오른쪽으로 이동 while (leftStartIndex <= right && arr[leftStartIndex].count <= pivot) { leftStartIndex++; } // 피벗보다 작은 값을 찾을 때까지 오른쪽에서 왼쪽으로 이동 while (rightStartIndex >= left + 1 && arr[rightStartIndex].count >= pivot) { rightStartIndex--; } // 인덱스가 교차하지 않았으면 값 교환 if (leftStartIndex < rightStartIndex) { swap(arr, leftStartIndex, rightStartIndex); } } // 피벗과 rightStartIndex 교환 swap(arr, left, rightStartIndex); return rightStartIndex; } // 두 원소의 값을 교환하는 함수 static void swap(User[] arr, int index1, int index2) { User temp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = temp; } } class User { String name; int count; User(String name, int count) { this.name = name; this.count = count; } @Override public String toString() { return "{name: '" + name + "', count: " + count + "}"; } }  문제를 해결하기 위한 퀵정렬을 수행하고 나의 출석수를 변경하는 코드를 Java로 작성했습니다.count 기준으로 정렬하고, 정렬된 배열의 첫 번째 데이터인 나의 출석수를 5로 변경하는 로직입니다.개인 일정때문에 첫번째 OT를 빠졌었는데, 구제될 수 있는 기회가 생겼네요.감사합니다.!!

백엔드인프런워밍업클럽2기CS전공지식특별미션

하얀종이개발자

인프런 워밍업 클럽 2기 - CS전공지식 스터디 미션 03 입니다.

CS전공지식 미션 2운영체제메모리의 종류는 어떤것들이 있나요? 각 메모리의 특징도 함께 적어주세요.레지스터CPU 내부에 있는 가장 빠른 메모리로 CPU가 계산하기위해 데이터를 임시로 저장CPU가 직접 접근할 수 있으며, 64bit 32bit CPU라는 말도 CPU의 연산단위이면서 레지스터의 크기를 나타냄캐시L1, L2, L3 캐시등이 있으면 CPU와 메모리 사이의 속도차이를 줄이기 위해 임시로 데이터를 저장하는 공간메인 메모리일반적으로 RAM을 의미하며 포노이만 구조의 CPU가 연산하기위해 프로세스를 올리는 공간전원이 꺼지면 데이터도 사라지는 휘발성 메모리임보조저장장치SSD, HDD 등으로 데이터를 영구적으로 저장할 수 있음, 메모리보다 속도가 느림전원이 꺼져도 데이터가 남아있는 비휘발성 메모리임 사용자 프로세스가 메모리의 운영체제 영역에 침범하지 못하도록 만든 레지스터는 어떤 레지스터일까요?경계레지스터 : CPU내부에 존재해서 맨 앞에 저장하고 있는 운영체제 영역의 최대 범위를 기록하고 있어, 침범하지 못하게 함, 만약 경계 레지스터의 값을 넘긴 프로세스가 있으면 해당 프로세스를 종료시킴메모리 할당 방식에서 가변 분할 방식과 고정 분할 방식의 장단점은 뭔가요?가변분할방식은 프로세스의 크기에 맞춰 메모리를 분할하는 방식으로 프로세스의 영역별로 메모리를 분할 할 수 있어, 메모리 접근권한이나 메모리 공유를 할 수 있음, 그러나 외부단편화가 발생하여 메모리낭비가 생길 수 있음 고정분할방식은 고정된 크기로 메모리를 분할 하는 방식으로 가변분할방식의 외부단편화를 제거할 수 있음, 그러나 고정된 크기에 프로세스를 나눠서 할당하기 때문에 내부 단편화가 발생할 수 있고, 프로세스 영역별로 나눌수 없어 메모리 접근권한이나 공유하는데 어려움이 있음CPU 사용률을 올리기 위해 멀티프로그래밍을 올렸지만 스왑이 더 많이 이루어져 CPU 사용률이 0%에 가까워 지는 것을 뭐라고 할까요?스레싱많은 프로그램을 메모리에 올리면 스왑이 빈번하게 일어날 수 있음이때 CPU가 실제 작업을 처리하지 못하고 스왑 작업에만 몰두하게 되어 CPU를 사용하지 못하는 현상을 말함HDD나 SSD는 컴퓨터를 실행시키는데 꼭 필요한 걸까요?꼭 필요하지는 않음컴퓨터가 실행되기 위해서는 RAM이 필요하지만, HDD나 SSD는 데이터의 영구적 저장을 위한 보조 장치임만약 시스템이 네트워크 기반 부팅을 사용하거나 RAM 디스크를 활용하는 경우, HDD나 SSD 없이도 컴퓨터를 실행할 수 있음. 다만 RAM은 전원이 꺼지면 데이터가 모두 사라지기 때문에 일반적으로는 운영체제를 포함한 데이터를 저장하기 위해 HDD나 SSD가 필요파일을 삭제해도 포렌식으로 파일을 복구할 수 있는 이유가 무엇일까요?파일을 삭제하더라도 실제로 데이터는 즉시 삭제되지 않고, 파일 시스템에서 해당 파일의 참조만 제거됨실제 데이터는 디스크에 그대로 남아 있기 때문에 포렌식 도구를 이용해 복구할 수 있음.완전한 삭제를 위해서는 데이터를 덮어쓰는 과정을 거쳐야 함자료구조와 알고리즘지금까지 배운 5개의 정렬 알고리즘의 장단점과 시간 복잡도를 적어주세요.버블 정렬 (Bubble Sort)O(n²)장점 : 단순한 구조로 이해 & 구현이 쉬움, 거의 정렬된 배열에서는 빠르게 종료될 수 있음단점 : 속도가 느리고, 다른 효율적인 정렬 알고리즘에 비해 많이 사용되지 않음선택 정렬 (Selection Sort)O(n²)장점 : 메모리 사용이 적고, 단순한 구조로 이해 & 구현이 쉬움단점 : 속도가 느리고, 다른 효율적인 정렬 알고리즘에 비해 많이 사용되지 않음삽입 정렬 (Insertion Sort)O(n²)장점 : 작은 데이터나 거의 정렬된 데이터에 대해 매우 효율적단점 : 속도가 느려서 대규모 데이터에 비효율적병합 정렬 (Merge Sort)O(n log n)장점 : 속도가 빠르며 대규모 데이터에서도 일정한 성능을 보임단점 : 추가 메모리 공간이 필요하며, 메모리 효율이 떨어질 수 있음퀵 정렬 (Quick Sort)평균 O(n log n), 최악 O(n²)장점 : 평균적으로 매우 빠르고, 메모리 사용이 적음단점 : 피벗 선택에 따라 성능이 달라지며, 최악의 경우 속도가 느려질 수 있음 (그러나 최악이 되는 경우는 거의 없음)메모리가 부족한 시스템에서 어떤 문제를 해결하는데 재귀로 쉽게 구현이 가능할 것 같습니다. 여러분이라면 메모이제이션과 타뷸레이션 중 어떤 걸 이용하실 건가요? 이유를 함께 적어주세요.메모이제이션(Memoization)재귀를 사용하면서 이미 계산된 값을 기억하고 활용하는 방식으로, 필요할 때 계산된 값을 바로 반환해서 사용재귀 구조를 그대로 유지하면서도 중복 계산을 피할 수 있음타뷸레이션(Tabulation)문제를 하위 문제부터 점진적으로 해결하는 방식으로, 반복문을 사용해 값을 채워나가는 방식메모리 부족한 상황이라면 타뷸레이션을 사용할 것 같습니다.타뷸레이션은 스택 오버플로우 위험이 없고, 재귀 호출에 따른 추가적인 메모리 오버헤드가 발생하지 않기 때문에 메모리를 더 효율적으로 사용할 수 있습니다. 

백엔드CS전공지식그림으로쉽게배우는자료구조와알고리즘그림으로쉽게배우는운영체제인프런워밍업클럽2기감자

빠타박스

[인프런 워밍업클럽 2기] CS전공지식_발자국_3주차 (Final)

1. 개요이름: 인프런 워밍업 클럽 2기 - CS 전공지식 빠타박스 [신충식]기간: 2024.10.14 - 2024.10.182. 목표 및 성과설정한 목표: 가벼운 학습 CS 지식 습득 및 중요한 부분에 대한 습득달성한 성과: 마무리 지점에 여러가지 중요한 내용이 운영체제를 통해 습득하게 되었다. 3. 잘된 점 (Keep)성공적인 요소:4. 개선할 점 (Problem)문제점 : 이번 과정이 끝나더라도 한번더 복습해야 한다. (정리하지 못한 부분도 존재한다)   5. 다음 단계 (Try)향후 계획: 정보처리기사 실기 시험이 끝나고 해당 내용을 복습하고자 한다. 무제한 강의 특성상 좋다. 휴.. 인생실기 시험 끝나면 심화도 봐서 코딩테스트 문제를 풀기에 적합할 수 있도록 되어야 겠지..그리고 아직 적지 못한 C++코드를 분석할 예정이다.  6. 기타 의견일주일 동안 학습하며3주차 과정은 조금 힘든 과정이다 지금 이걸 작성하고 내일 모래면 정처기 실기시험이 있다.최선을 다하자... 이 실기가 끝나면 꼭 1트만에 합격해서 끝내고 알고리즘 자료구조를 학습하고 면접 내용을 정리하며,프로젝트를 진행하면서 게임 출시까지도 보고 앞으로 나아가자...3주차 미션에 대해휴.. 3주차 미션은 좀 더 운영체제 같은 것 들을 중요시 했고 간단하면서도 어려웠다.이 이유는 내가 정처기에 빠져있고, 현재로써 제대로된 집중을 하지 못했기 때문이다.즐거웠다. 이 과정을 지나면서 하지만. 스터디 클럽이라기 보다. 자기주도 학습 유도 와 보상심리를 이용한 나아감이였다. 꼭 완주 하고 싶다. 하지만 배워야한다. 라는 느낌? 그래도 이 과정이 있어서 정말 다행이다. 저렴하게 강의 시청을 할 수 있었다는 점과. 이 과정의 커리큘럼대로 시간표대로 진행함에 있어서 어려움을 좀 덜 느꼈던거 같다. 다양한 사람들의 학습 방법에 대해 한번 눈여겨 보기도 한다.  요즘 젊은이들은 어떻게 공부하는가... 흠... 나에게 적용할 부분이 무엇인가. 미션을 좀 이렇게 해볼걸...이번 풀이는 좀 구글링 한 부분도 있었다. 아무래도 제대로된 이해를 하기 힘든 부분이 있었다. 이번 학습에 대해서 아직 제대로 정리도 못한 상황이다. 실기가 끝나면 바로 적용해야지  빠타박스노션 https://gibeonsoftwork.notion.site/2-CS-10e530ec4ad680ff802cf36606049182?pvs=4 소감내 군대시절 우연히~들었던 믿지 못할 한마디~게임 개발 할 수 있다는 매혹적인 얘기내게 꿈을 심어주었어~ 말도 안돼 고갤 저어도~내안에 나 나를보고 속삭여~코테 공부하는 자는 CS 필수라고~용기를 내 넌 할 수 있어!쉼 없이 흘러가는 3주~ (정처기는 6주째)이대로 !!! 유튜브 볼순 없잖아~~!!!인프런과 도전하는거야!!!인프런 감자 손을잡고!정처기 CS 모두의 꿈을 모아서!!!!!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~ 감자의 거센 속도~!!! javascript!~~!!!!빠타 앞길 막아서도 결코 두렵지 않아(chatgpt~~!)끝없이 펼쳐진 수많은 코드들~~~밝은 미래 위한 거야~~~~ 인프런!~ 

알고리즘 · 자료구조cs-미션-발자국cs-발자국인프런워밍업클럽2기워밍업CS지식자료구조알고리즘감자타이틀곡

하얀종이개발자

인프런 워밍업 클럽 2기 - CS 전공지식 스터디 2주차 발자국

운영체제 2주차 학습 요약 CPU 스케쥴링 알고리즘SJF (Shortest Job First)짧은 작업 시간을 가진 프로세스에 먼저 CPU를 할당하는 방식버스트 타임이 긴 프로세스는 계속 실행되지 않을 수 있고, 어떤 프로세스가 얼마나 실행될지 예측이 어려움RR (Round Robin)시간을 균등하게 분배하여 각 프로세스에 순차적으로 CPU를 할당하는 방식컨텍스트 스위칭으로 인해 처리량이 늘어남MLFQ (Multi Level Feedback Queue)프로세스의 우선순위를 동적으로 조절하여 CPU를 효율적으로 할당하는 방식오늘날 운영체제에서 가장 일반적으로 사용됨프로세스 동기화여러 프로세스가 공유 자원에 동시에 접근할 때 순서를 정하여 데이터의 일관성을 유지하는 것프로세스간 통신의 종류한 컴퓨터 내에서 프로세스간 통신하는 방법 : 파일 or 파이프를 이용한 프로세스 내에서 쓰레드간 통신하는 방법 : 데이터 or 힙영역을 이용네트워크를 이용하여 통신하는 방법 : 소켓통신, RPC공유자원과 임계영역공유자원은 프로세스 혹은 스레드간 통신할 때 공동으로 이용하는 변수나 파일 같은 것들공유자원은 여러 프로세스가 공유하고 있기 때문에 각 프로세스의 접근 순서에따라 결과가 달라질 수 있음임계영역은 프로세스 혹은 스레드가 동시에 사용하면 안되는 영역 (접근 순서등의 이유로 결과가 달라지는 영역)경쟁조건은 공유자원을 서로 사용하기 위해 경쟁하는 것임계구역 문제를 해결하기 위한 조건상호배체임계영역엔 하나의 프로세스만 접근해야 함한정대기기다리는 프로세스는 언제가는 임계영역에 접근 할 수 있어야함진행의 융통성한 프로세스가 다른 프로세스의 일을 방해해서는 안됨세마포어 & 모니터뮤텍스는 공유자원을 lock()과 unlock()을 이용하여 프로세스의 접근을 제어하는 메커니즘여러 프로세스의 접근을 관리할 수 있으면 세마포어 (뮤텍스는 동기화 대상이 오직 하나임)세마포어는 잘못된 사용으로 임계영역을 보호받지 못할 수 있음 (세마포어를 사용하지 않고 임계구역에 들어간 경우)이를 해결한 방식이 모니터모니터는 공유자원을 숨기고 접근에 대한 인터페이스만 제공하여 공유자원에 안전하게 접근하게 하는 메커니즘운영체제가 처리하는게 아니라 프로그래밍 언어차원에서 지원하는 방법임교착상태 (데드락)두개 이상의 프로세스들이 서로가 가진 자원을 기다리다 아무도 작업을 진행하지 못하는 상태데드락 필요조건상호배제비선점점유대기원형대기은행원 알고리즘총 자원의 양과 현재 할당한 자원의 양을 기준으로 안정 또는 불안정 상태로 나누고, 교착상태가 발생하지 않는 수준이 되도록 자원을 할당하는 알고리즘검출 & 회복교착상태는 어떻게 검출하지?가벼운 교착상태 검출 (타이머)일정시간마다 작업을 조작하고 교착상태가 발생하면 체크포인트로 롤백무거운 교착상태 검출 (순환구조)교착상태를 일으킨 프로세스를 강제 종료시키고 다시 실행 시킬때 체크포인트로 롤백오버헤드가 발생하지만 억울하게 종료되는 프로세스는 발생하지않음메모리레지스터 (32bit 또는 64bit)캐시CPU와 메인메모리 속도 차이 때문에 미리 데이터를 저장하는 임시공간메인메모리 (RAM)프로세스를 로드, 휘발성보조기억장치 (SSD, HDD)디스크 저장, 비휘발성물리 주소 - 물리적인 메모리 주소논리 주소 - 사용자 관점에서 본 상대적 주소, 사용자는 논리 주소를 통해 물리 주소로 접근메모리 할당방식가변분할방식메모리에 연속해서 프로세스를 할당단점으로 외부 단편화가 발생할 수 있음고정분할방식메모리를 정해진 크기로 나누어 프로세스를 할당단점으로 내부 단편화가 발생할 수 있음버디시스템메모리를 2의 제곱 수로 분할하여 할당하는 방식가변분할방식과 고정분할방식을 합친 방법 알고리즘 & 자료구조 2주차 학습 요약 재귀 & 재귀적으로 생각하기재귀는 자기 자신을 다시 호출하는 함수를 말함어떤 문제를 해결하기 위해 문제의 부분 문제를 같은방식으로 해결하는 과정하향식 풀이에서 활용됨 (하위 문제를 기반으로 해결)하노이탑 구현하기세개의 기둥과 서로 다른 크기의 원반들이 있을때 가장 큰 원반이 아래에 있고 위로 갈수록 작은 원반으로 이루어져있음하나의 기둥에 있는 원반들을 다른 기둥으로 옮겨야 함기둥 A에 있는 원반을 기둥 C로 옮기기 (하향식 접근으로 풀이)  처음 시작 그림으로 쉽게 배우는 자료구조와 알고리즘 (기본편) 캡쳐  모두 옮김그림으로 쉽게 배우는 자료구조와 알고리즘 (기본편) 캡쳐자바코드public class HanoiTop { void hanoi(int count, String from, String to, String temp){ if(count == 0) return; hanoi(count - 1, from, temp, to); System.out.printf("원반 %d를 %s에서 %s로 이동\n", count, from, to); hanoi(count - 1, temp, to, from); } public static void main(String[] args) { HanoiTop hanoiTop = new HanoiTop(); hanoiTop.hanoi(3, "A", "C", "B"); } } 버블정렬앞에 있는 숫자와 옆에 있는 숫자를 비교해서 자리를 바꾸는 알고리즘자바코드public class BubbleSort { void bubbleSort(int[] arr) { // 사이클 - 자리교체는 (배열의 갯수 - 1) 번 수행함 for (int i = 0; i < arr.length - 1; i++) { // 횟수 - 정렬이 된 원소의 이전 원소보다 하나 이전의 원소까지 순회 // 시작점이 (arr.length-i-1)번 임 for (int j = 0; j < (arr.length - i - 1); j++) { // 앞의 데이터가 뒤에 데이터보다 더 크다면? if (arr[j] > arr[j + 1]) { // 데이터 자리변경 int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } public static void main(String[] args) { int[] arr = {2, 3, 1, 4}; // 정렬 전 - arr = [2, 3, 1, 4] System.out.println("정렬 전 - arr = " + Arrays.toString(arr)); BubbleSort bubbleSort = new BubbleSort(); bubbleSort.bubbleSort(arr); // 정렬 후 - arr = [1, 2, 3, 4] System.out.println("정렬 후 - arr = " + Arrays.toString(arr)); } } 선택정렬정렬되지 않은 배열의 첫번째 원소를 시작으로 마지막 원소까지 탐색하여 가장 작은 값을 정렬되지 않은 첫번째 배열로 가져오는 알고리즘자바코드public class SelectionSort { void selectionSort(int[] arr) { // 1 사이클의 순회는(배열의 갯수 - 1) 번 수행됨 for (int i = 0; i < arr.length - 1; i++) { int minValueIndex = i; // 가장 작은 값을 탐색하기위해 순회 for (int j = i + 1; j < arr.length; j++) { if (arr[j] < arr[minValueIndex]) { // 작은값 저장 minValueIndex = j; } } // 자리 변경 int temp = arr[i]; arr[i] = arr[minValueIndex]; arr[minValueIndex] = temp; } } public static void main(String[] args) { int[] arr = {4, 2, 1, 3}; // 정렬 전 - arr = [4, 2, 1, 3] System.out.println("정렬 전 - arr = " + Arrays.toString(arr)); SelectionSort selectionSort = new SelectionSort(); selectionSort.selectionSort(arr); // 정렬 후 - arr = [1, 2, 3, 4] System.out.println("정렬 후 - arr = " + Arrays.toString(arr)); } }  회고2주차 스터디를 진행하면서 정해진 진도도 학습하면서, 스터디안에 발표스터디에 참여해서 복습도 하는 과정이었어요. 적어보였던 운영체제의 내용이 생각보다 많아서 정리하는데 은근 시간이 오래 걸리더라구요. 그래도 스터디안의 발표 스터디에 참여하여 정리내용을 발표하고 다른 스터디원들의 발표내용도 듣고 헷갈리는 부분도 토론해서 도움이 많이 되었던 한 주 였던것 같습니다.스터디 발표 정리 자료 캡쳐그리고 이번 알고리즘 강의에서는 항상 어렵게 느꼈던 재귀에 대해 조금은 이해한게 너무 좋았습니다.어떤 문제를 해결하기 위해 문제의 부분 문제를 같은 방식으로 분해하여 해결한다.!! 재귀함수 내에서 자기 자신을 호출할 때 이 함수가 벌써 구현이 되어있다고 가정하고 재귀함수를 구현한다.!! 많이 연습해봐야겠지만 그래도 재귀적으로 생각하는 방법을 느낄 수 있었던 것 같습니다.마지막 1주가 남았는데, 끝까지 열심히 해서 끝까지 완주해야겠네요. 화이팅

백엔드인프런워밍업클럽2기CS전공지식2주차발자국감자

하얀종이개발자

인프런 워밍업 클럽 2기 - CS전공지식 스터디 미션 02 입니다.

CS전공지식 미션 2운영체제FIFO 스케줄링의 장단점이 뭔가요?FIFO (First In First Out) 스케쥴링은 말그대로 먼저 들어온 프로세스가 먼저 CPU를 할당 받는 방식을 말합니다.장점은 단순하게 들어온 순서대로 처리하기 때문에 이해와 구현이 쉽고, 프로세스가 작업이 완료될때까지 지속적으로 실행되기 때문에 CPU의 사용률을 높다는 것에 있습니다.단점으로는 진행되고 있는 프로세스가 완전히 끝나야만 다음 프로세스에 CPU를 할당할 수 있기 때문에, 만약 작업시간이 긴 프로세스가 먼저 실행되고 작업시간이 작은 프로세스가 다음에 실행된다고 한다면, 작은 프로세스는 계속 기다리는 상황이 생길 수 있습니다. 또한 도중에 I/O작업이 발생하면 CPU작업이 필요없는데도 I/O작업이 끝날때까지 CPU가 대기하는 비효율도 발생하게 됩니다.SJF를 사용하기 여러운 이유가 뭔가요?  SJF(Shortest Job First)는 짧은 작업시간을 가진 프로세스에 먼저 CPU를 할당하는 방식입니다. 그러나, 이론적으로는 FIFO보다 빠르지만 사용하기 어려운 이유가 있습니다.첫번째는 짧은 작업시간을 가진 프로세스를 선별해야 하는데 실제 어떤 프로세스가 얼마나 실행될지 예측이 어렵다는 점 입니다. 운영체제는 작업의 소요 시간을 사전에 예측하기 힘들며, 이를 정확히 판단하는 것은 거의 불가능합니다.두번째는 작업시간이긴 프로세스의 우선순위가 계속 뒤로 밀리면서 실행되지 못하고, 기아(starvation) 상태에 빠질 가능성이 있습니다. 이러한 문제들로 인해 SJF는 현실적으로 사용될 수 없습니다.RR 스케줄링에서 타임 슬라이스가 아주 작으면 어떤 문제가 발생할까요?RR(Round Robin)는 FIFO 스케쥴링의 단점을 해결하기위해 시간을 균등하게 분배하여 각 프로세스나 작업에 순차적으로 CPU를 할당하는 방식을 말합니다.타임슬라이스가 아주 작으면 타임슬라이스 마다 CPU가 할당되는 프로세스가 변경되는 만큼 컨텍스트 스위칭이 발생하기 때문에 처리량이 늘어날 수 있는 문제가 있습니다. 만약 프로세스의 처리량보다 컨텍스트 스위칭의 처리량이 커진다면 배보다 배꼽이 더 큰 상황이 될 수 있습니다.운영체제가 MLFQ에서 CPU Bound Process와 I/O Bound Process를 어떻게 구분할까요?MLFQ (Multi Level Feedback Queue)는 프로세스의 우선순위를 동적으로 조절하여 CPU를 효율적으로 할당하는 방식을 말합니다. MLFQ는 CPU Bound Process는 타임슬라이스를 크게 주고 I/O Bound Process는 타임슬라이스를 적게 주는 방식으로 동작하는데, 프로세스가 동작하면서 주어진 타임슬라이스를 모두 사용하고 운영체제에 의해 CPU를 빼앗기면 CPU Bound Process로 간주하여 우선순위를 낮춰 다음 실행될 때 더 큰 타임슬라이스를 부여하도록 하고, I/O작업이 발생하여 스스로 CPU를 반납하면 I/O Bound Process로 간주하여 우선순위를 높여 작은 타임슬라이스가 주어지도록 합니다.공유자원이란무엇인가요?공유자원은 여러 프로세스나 스레드가 동시에 접근할 수 있는 자원을 말합니다. 예를 들어, 파일, 프린터, 메모리 등이 있습니다. 공유자원은 여러 프로세스 혹은 스레드가 공유하고 있기 때문에 각 프로세스의 접근 순서에 따라 결과가 달라질수 있어 조심해야 합니다. (동기화 문제)교착상태에 빠질 수 있는 조건은 어떤 것들을 충족해야할까요?교착상태 (데드락)은 두개 이상의 프로세스들이 서로가 가진 자원을 기다리다 아무도 작업을 진행하지 못하는 상태를 말합니다. 교착상태에 빠질 수 있는 조건은 4가지인데 모두 충족해야 교착상태에 빠질 수 있습니다.상호 배제 : 어떤 프로세스가 한 리소스를 점유했다면 그 리소스는 다른 프로세스에게 공유되면 안됨비선점 : 프로세스 A가 리소스를 점유하고 있으면 다른 프로세스가 리소소를 빼앗을 수 없음점유대기 : 어떤 프로세스가 리소스 A를 가지고 있는 상태에서 리소스 B를 원하는 상황원형대기 : 점유와 대기를 하는 프로세스의 관계가 원형을 이루고 있음 자료구조와 알고리즘재귀함수에서 기저조건을 만들지 않거나 잘못 설정했을 때 어떤 문제가 발생할 수 있나요?재귀함수는 자기 자신을 다시 호출하는 함수를 말하는데, 문제를 반복적으로 더 작은 문제로 분해하여 해결하는데 사용됩니다. 이때 계속 자기 자신을 호출하므로 어느순간에는 호출을 멈춰야 하는데, 기저조건이 이 역할을 하게 됩니다.만약 기저조건을 만들지 않거나 잘못설정하면, 함수가 계속해서 자신을 호출하여, 스택오버 플로우가 발생하여 프로그램이 비정상적으로 종료 될 수 있습니다.2.0부터 입력 n까지 홀수의 합을 더하는 재귀 함수를 만들어보세요.자바스크립트 코드function sumOdd(n){ // 기저조건 : n이 0보다 작으면 0을 반환 if (n <= 0) return 0; // 홀수일 때는 n을 더하고, 짝수일 때는 n-1을 재귀호출 if(n % 2 !== 0) { return n + sumOdd(n - 2); } else { return sunOdd(n - 1); } } console.log(sumOdd(10)) // 25자바 코드개인적으로 자바를 사용하고 있어서 자바코드로도 작성해봤습니다.public class SumOddNumbers { // 0부터 n까지 홀수의 합을 구하는 재귀 함수 public static int sumOdd(int n) { // 기저 조건: n이 0 이하일 때 0을 반환 if (n <= 0) { return 0; } // n이 홀수인 경우 n을 더하고, 짝수인 경우 n-1로 재귀 호출 if (n % 2 != 0) { return n + sumOdd(n - 2); // n이 홀수일 때 } else { return sumOdd(n - 1); // n이 짝수일 때 다음 홀수로 } } public static void main(String[] args) { int n = 10; int result = sumOdd(n); System.out.println("0부터 " + n + "까지 홀수의 합: " + result); // 출력: 25 } }

백엔드인프런워밍업클럽2기cs전공지식스터디미션2주차감자

빠타박스

[인프런 워밍업클럽 2기] CS전공지식_발자국_2주차

1. 개요이름: 인프런 워밍업 클럽 2기 - CS 전공지식 빠타박스 [신충식]기간: 2024.10.07 - 2024.10.112. 목표 및 성과설정한 목표: 가볍게 학습하며 정보처리기사 실기 대비달성한 성과: 운영체제와 알고리즘에 대한 중요한 부분을 쉽게 이해할 수 있는 계기가 되었다. 3. 잘된 점 (Keep)성공적인 요소: 적은 요소들을 기록했지만. 많은 것을 배울 수 있었다.  4. 개선할 점 (Problem)문제점 : 여전히 정보처리기사 실기와 함께 학습을 하고 있다는 점이다. 그래서 조금 깊게 들여다 보고 싶은데 그러지 못하고 있다. 개선이 필요한 프로세스 : 기록을 최소화 하게 되었지만. 아직도 쉽지 않다.   5. 다음 단계 (Try)향후 계획: 3주차는 마지막 기간이다. 그러나 정보처리기사 실기가 껴있는 관계로 역시 가볍게 볼 예정이다. 그러나 향후 다시 봐야하기 때문에, 조금이라도 정리하면서 기록하고자 한다.   다음 3주차에서 시도할 사항:기록은 가볍게,구현 부분 가볍게 C++과 비교하기 (다른 사람의 코드)수료식? 역할 및 책임:정처기 실기를 1트만에 합격해야 하는 의무가 있다..; 내년 까지 또 기다릴 순 없다..6. 기타 의견일주일 동안 학습하며2주차는 정말 중요한 부분들이 많이 나왔다. 운영체제의 스케줄링과 관련된 내용인, FIFO(이건 원래 FCFS로알고 있다.), SJF, RR, MLF MLQ등 중요한 내용들이였고, 그중 세마포어와 데드락과 관련된 내용이 정말 인상깊고 중요한 내용이였음을 알 수 있다. (게임회사 면접에서도 종종 물어보는 면접내용이기도 해서 와닿았다)자료구조 알고리즘에서는 기본적으로 3주차 마지막의 섹션 범위를 맞추기 위해 1주차에 비해 빠듯하지 않았다. 가볍게 볼 수 있었다. 또 알고리즘의 기본인 정렬에 대해 버블과 선택정렬은 이해하기 쉬웠다.조금 이상한건 섹션 6을 갑자기 뛰어넘어서.. 음..... 종종 뭔가 뛰어넘어간게 있었다.2주차 미션에 대해2주차 미션도 간단했다. 구현 부분에서 순간 착각해서 다시 쓰게되었었지만. 이 미션도 다시한번더 볼 필요가 있다고 생각이든다. 미션을 좀 이렇게 해볼걸...조금 아쉽게 미션을 풀이를 했다. 확실히 배우고 가고 싶지만. 어찌되었든 강사님께서는 가볍게 훑고 다음에 다시 보라는 식으로 말씀하시는 것 같다.  일단 정보처리기사실기가 끝나면 다시한번더 점검해보자.   

알고리즘 · 자료구조cs-발자국cs-미션-발자국인프런워밍업클럽2기자료구조알고리즘

하얀종이개발자

인프런 워밍업 클럽 2기 - CS 전공지식 스터디 1주차 발자국

운영체제 1주차 학습 요약 운영체제운영체제는 컴퓨터를 유연하게 동작시키기 위해 필요하다.운영체제가 하는일프로세스를 관리 (여러 프로그램을 동작시킴)메모리를 관리 (프로그램은 메모리에 올라감)하드웨어 관리 (사용자의 하드웨어에 대한 직접 접근을 막음)파일 시스템 관리 (하드디스크에 많은 파일들을 효율적으로 저장&관리)운영체제의 구조커널 - 프로세스와 메모리, 저장장치를 관리하는 핵심적인 기능을 담당인터페이스 - 사용자가 시스템과 상호작용을 도와주는 외부 인터페이스시스템 콜 - 커널은 사용자 애플리케이션과 커널이 소통할때 사용되는 내부 인터페이스 (커널을 보호)드라이버 - 하드웨어와 커널간의 인터페이스폰노이만 구조CPU와 메모리를 분리하고 프로그램을 메모리에 올려서 실행하는 구조인터럽트인터럽트는 폴링 방식의 단점을 해결하기위해 CPU가 현재 진행중인 작업을 일시중단하고 외부에서 발생한 이벤트를 처리하기위해 서비스루틴을 실행하는 매커니즘프로세스프로그램이 메모리에 올라가서 CPU 할당의 대상이 되는 능동적인 존재프로세스의 구조코드영역(실제 코드), 데이터영역(전역변수, 정적변수), 스택영역(지역변수, 함수), 힙영역 (객체 등, 런타임시 동적인 메모리를 할당할 수 있는 공간)컴파일 과정test.c -> 전처리기 -> test.i -> 컴파일러 -> test.s(어셈블리어) -> 어셈블러 -> test.o(기계어) -> 링커(라이브러리 연결) -> test.exe프로세스 컨트롤 블록 (PCB)운영체제는 여러개의 프로세스를 관리하고 공평하게 CPU를 할당하기 위해 프로세스 정보를 담은 PCB를 만들고 저장함식별자, 프로세스 상태, 프로그램카운터, 레지스터 정보등을 저장프로세스 상태생성, 준비, 실행, 대기, 완료컨텍스트 스위칭프로세스를 실행하는 중에 다른 프로세스를 실행하기 위해 실행중인 프로세스를 저장하고 다른 프로세스의 상태값으로 교체하는 작업쓰레드한 프로세스 내에서 동시에 각자 실행될 수 있는 작업 흐름의 단위기본적으로 프로세스 1개에는 1개의 쓰레드가 존재쓰레드끼리는 스택영역을 제외한 다른 영역은 공유해서 사용, 프로세스에 할당된 Virtual Memory로 공간이 제약됨공유하는 영역을 통해 메모리 낭비를 줄이고 쓰레드끼리 소통할때 비용이 적게 들지만, 안정성이 떨어짐CPU 스케쥴링운영체제는 CPU를 여러 프로세스에 할당/해제 하는 것을 CPU 스케쥴링이라고 함다중 큐준비, 대기 상태의 프로세스는 다중 큐 자료구조에서 관리다중큐에는 정확하게는 프로세스의 정보를 가진 PCB가 저장CPU 스케쥴링 알고리즘FIFO (First In First Out)스케쥴링 큐에 들어온 순서대로 CPU를 할당 받는 방식한 프로세스가 완전히 끝나야 다음 프로세스가 시작되고, I/O작업시 I/O작업이 끝날때까지 CPU가 대기하는 단점이 있음프로세스의 BURST TIME에 따라 성능차이가 심하게 나기 때문에 잘 쓰이지 않고, 일괄처리 시스템에서 쓰임  알고리즘 & 자료구조 1주차 학습 요약 알고리즘어떤문제를 해결하기 위한 구체적이고 확실한 방법자료구조데이터를 효율적으로 저장하고 사용할 수 있도록 정리하는 방법상황에 맞는 적절한 자료구조를 선택하고 이에 맞는 적절한 알고리즘을 적용할 수 있어야 한다.시간복잡도더 좋은 알고리즘이란 무엇일까? 메모리를 더 적게 사용하는 것? 속도가 빠른 것?입력값이 달라지더라도 동일하게 알고리즘의 속도를 표현하는 방법이 시간복잡도입력값에 따른 변화의 추이를 나타내는 방법중에 최악의 경우를 기준으로 표기하는 빅 오 표기법이 가장 많이 사용됨배열동일한 데이터 타입의 요소들을 연속된 메모리 공간에 저장하는 자료구조읽기, 쓰기와 같은 참조에는 O(1)의 성능을 가짐그러나 데이터 삽입, 삭제에서는 데이터 복사, 이동등이 일어나 비효율적임또한, 고정된 크기로 배열을 생성해야함연결리스트배열의 단점은 연속된 메모리공간이 필요하다는 것과 초기 배열의 크기를 모르면 메모리가 낭비될 수 있다는 점임연결리스트에 데이터를 추가한다면 빈 메모리 공간에 데이터를 생성하고 연결만 해주면 됨연결리스트는 요소 접근시 첫번째 노드부터 이동하면서 찾아야함, O(N)배열 VS 연결리스트배열은 메모리 크기가 고정이고, 연속된 주소에 할당되는 단점, 그러나 인덱스 접근으로 인해 참조는 매우 빠름 연결리스트는 초기 크기를 알 필요없이 데이터를 생성하고 연결만 해주면 됨대신 인덱스 접근이 느림 (첫번째 노드부터 이동하면서 찾아야 함)스택먼저 들어간 데이터가 가장 마지막에 나가는 First In Last Out의 자료구조큐먼저 들어간 데이터가 가장 먼저 나오는 First In First Out의 가료구조덱데이터 삽입과 제거를 앞과 뒤 모두에서 자유롭게 사용할 수 있는 자료구조덱을 이용하면 스택과 큐 모두 구현 가능해시테이블해시 함수에 의해 생성된 해시값을 인덱스로 사용하여, key, value 쌍으로 저장됨해시충돌서로 다른 입력값이 동일한 해시값을 갖는 상황체이닝충돌이 발생한 경우, 동일한 해시값을 갖는 여러개의 항목을 연결리스트로 저장 (실제로는 레드블랙트리) 해시테이블의 장.단점장점 : 빠른 데이터 읽기, 삽입, 삭제 - O(1)의 성능단점 : 메모리를 많이 차지함 (좋은 해시함수는 필수)셋데이터의 중복을 허용하지 않는 자료구조 (순서를 보장하지 않고 중복을 허용하지 않음) 회고1주일동안 CS 전공지식 스터디를 하면서 부족한 것을 채우면서 많이 공부하게 된 것 같아요. 다른사람들이 어떻게 공부하고 있는지, 그리고 미션을 통해 가장 중요하게 알고 넘어가야 하는 부분들을 집어주셔서 확실히 개념이 잡히는 것 같아요.스터디를 진행하면서 전공자임에도 스스로 알고 있다라고 생각했던 것들이, 생각보다 잘 모르고 있구나 라는 반성을 많이 하게 된 것 같습니다. 스터디와 강의로 통해서 개념을 다시 정리할 수 있게되어 너무 좋았어요. 특히, 운영체제 부분 프로세스의 상태 전환 하는 부분에서 많이 배운 것 같네요.개발을 할 때 필요한 기본 지식들, 알고리즘 그리고 자료구조들은 평생 사용하는 것들인데 스터디를 통해 많은 것들을 얻는 것 같아요. 이제 2주 남았는데요. 짧다면 짧은 기간이지만 함께 달려서 완주했으면 좋겠습니다.  

백엔드인프런워밍업클럽2기cs발자국

빠타박스

[인프런 워밍업클럽 2기] CS전공지식_Mission01

운영체제while(true){ wait(1); // 1초 멈춤 bool isActivated = checkSkillActivated(); // 체크 }위 코드는 1초 마다 플레이어가 스킬을 사용했는지 체크하는 코드입니다. 이 방식은 폴링방식입니다.1초마다 체크하기 때문에 성능에 좋지 않습니다. 이를 해결하기 위한 방식으로 어떤 걸 이용해야 할까요? 이런 풀링 방식의 경우 계속 매초마다 확인을 하니까 효율이 좋지 못하다.이전에 서버에게 클라이언트에서 로그인 인증 됬는지 처리하기 위해 계속 해서 switch 문에 들락날락 처리 되도록 한적이 있는데. 확실히 삑나간적이 있었다.이럴때 필요한게 인터럽트 인데 일종의 대기상태 라고 생각하면 될 것 같다.CPU는 다른 작업을 실행시키거나 하여 잠시 대기시키고 해당 작업이 완료되는 시점에 신호를 받아 완료 시킨다. 언리얼엔진에서도 비슷하게 조건을 주어 매초마다 주는 Tick 발생을 제어하는 것들이 있는데.상태머신에서도 볼 수 있는 현상이다.조건을 주어 다른 것이 실행되게 하고 입력값이 들어오면 그때서야 실행하는 것이다. 인터럽트도 일정 입력이 들어올 때까지 작동하지 않고 들어오면 인터럽트에 의해 다른 업무를 시키고 그 업무로 들어가게 한다. 해결방법인터럽트 핸들러 : 특정이벤트가 발생했을 때 인터럽트가 발생하도록 처리 CPU는 대기상태에서 벗어나서 해당 이벤트를 즉시 실행상태 플러그 : 인터럽트 핸들러에서 상태 플래그를 설정하고 loop에서 이 플래그를 체크하여 작업을 수행하도록 volatile bool skillActivated = false; void interruptHandler() { skillActivated = true; // 인터럽트 발생시 플래그 } while(1) { if (skillActivated) { skillActivated = false; // 플래그 초기화 } // 다른 작업 수행 }우선 순위 관리를 통해 중요한 이벤트 부터 처리타이머 사용 : 주기적인 작업시 타이머 설정해서 일정 시간마다 인터럽트 처리다용도 입출력(GPIO)핀의 변화를 감지해서 인터럽트 발생등등 2. 프로그램과 프로세스가 어떻게 다른가요?프로그램 명령문의 집합체일종의 실행파일같이 .exe 형태로 이루어짐컴퓨터의 관점에서 저장장치만 사용하는 수동적 존재 프로세스실행중인 프로그램저장장치에서 프로그램이 메모리에 올라간 것메모리도 사용하고 운영체제 CPU 스케줄링에 따라 CPU도 사용됨, 능동적인 존재이다. 3. 멀티프로그래밍과 멀티프로세싱이 어떻게 다른가요?멀티 프로그래밍메모리에 여러개의 프로세스가 올라온 것 멀티 프로세싱CPU가 여러개의 프로세스를 처리하는 것  -> 오늘날 멀티프로세싱 프로그래밍이 전부다 쓰인다.메모리에는 여러개의 프로세스가 올라오는 멀티프로그래밍, 시분할 처리로 CPU가 각각의 프로세스를 짧은 시간동안 교대로 실행하는 멀티프로세싱이 있다. (동시에 실행된다는 개념이 아니다) 4. 운영체제는 프로세스를 관리하기 위해서 어떤 것을 사용하나요?운영체제는 프로세스가 만들어지면 해당 프로세스의 정보를 가지고 있는 PCB를 만든다. 이것은 연결리스트 자료구조 마냥 저장되어있는데. 프로세스가 종료되면 해당 리스트에서 프로세스의 PCB를 제거합니다. 그러면서 연결리스트의 구조는 그대로 유지 합니다. PCB의 구조는포인터프로세스 상태프로세스 ID프로그램 카운터레지스터 정보메모리관련정보CPU스케줄링 정보 등 PCB내부에서 여러개의 동작이 실행되어 운영체제에 의해 관리됩니다.  5. 컨텍스트 스위칭이란 뭔가요? 프로세스를 실행하는 중에 다른 프로세스를 실행하기 위해 실행 중인 프로세스를 저장하고 다른 프로세스의 상태값으로 교체는 작업을 - 컨텍스트 스위칭 이라고 한다. 컨텍스트 스위칭은 PCB의 내용이 변경된다.실행중인 프로세스의 작업내용을 PCB에 저장하고 실행될 기존 프로세스의 PCB의 내용대로 CPU가 다시 셋팅 된다.  컨텍스트 스위칭이 발생시 PCB의 변경 값 프로세스 상태프로그램 카운터 : 다음 실행할 명령어 주소레지스터 값 & 메모리관련 정보 : 각종 레지스터의 값 정보 발생 이유 CPU 점유시간이 다 되거나 입출력 요청이 있거나다른 종류의 인터럽트가 있을 때 발생할 때  자료구조와 알고리즘1. 여러분은 교실의 학생 정보를 저장하고 열람할 수 있는 관리 프로그램을 개발하려고 합니다.이 때 여러분이라면 학생의 정보를 저장하기 위한 자료구조를 어떤 걸 선택하실 건가요? 이유를 함께 적어주세요.학생 정보를 저장하기 위해 구조체와 벡터를 결합해 사용할 수 있을 것 같다. 구조체는 학생 정보를 표현하고, 벡터는 여러 학생 정보를 동적으로 저장할 수 있다. C++에서는 이러한 것이 STL에 컨테이너로 되어 사용가능하다.사용이유구조체 사용 : 학생 정보를 하나의 단위로 묶어 관리하기 위해 구조체를 사용학생의 이름나이학생ID등의 속성을 쉽게 다룰 수 있다. 벡터 사용 : 벡터는 동적 배열로, 학생 수가 변동 될 수 있는 상황에 유용하다. 학생을 추가하거나 삭제할 때 유연하게 대처가능 하다. #include <iostream> #include <iomanip> #include <string> #include <vector> using namespace std; struct Student { // 기본적으로 구조체는 기본적으로 public string name; int age; string studentId; // 구조체 변수 초기화 Student(string n, int a, string id) : name(n), age(a), studentId(id) {} }; class StudentManager { public: void AddStudent(const string& name, int age, const string& studentId) { vStudents.emplace_back(name, age, studentId); // 객체내 인자만받아 함수 내에서 객체 생성해 삽입 - emplace_back 생성자 한번만 호출 } /*width() 또는 iomanip/ setw()로 정리*/ void DisplayStudents() const { for (const auto& student : vStudents) { cout << "| " << "Name: " << student.name << " |" << setw(6) << "Age: " << student.age << " |" << setw(13) << "Student ID: " << student.studentId << " |" << endl; } } private: // 공개가 필요없는 vector<Student> vStudents; }; int main() { StudentManager manager; manager.AddStudent("홍길동", 20, "20230001"); manager.AddStudent("인프런", 21, "20230002"); manager.AddStudent("감자 ", 25, "20230003"); cout << "학생정보: " << endl; manager.DisplayStudents(); return 0; } 2. 여러분은 고객의 주문을 받는 프로그램을 개발하려고 합니다. 주문은 들어온 순서대로 처리됩니다. 이 때 여러분이라면 어떤 자료구조를 선택하실 건가요? 이유를 함께 적어주세요.큐(Queue)자료구조를 사용해서 FIFO방식으로 데이터를 처리하므로 주문이 들어온 순서대로 처리할 수 있습니다. STL에 queue를 사용할 수 있습니다.사용이유FIFO : 선입선출 방식, 주문이 들어온 순서대로 처리할 수 있어서 주문관리에 적합합니다. 고객 대기 시간을 최소화할 수 있습니다. (단. 끼어들기 금지)간편한 관리 : C++STL 제공하기에 복잡한 구현없이 간편하게 큐를 관리 확장성 : 새로운 주문 추가또는 기존 주문을 처리하는 과정이 명확해서 확장및 유지보수 용이 /*여러분은 고객의 주문을 받는 프로그램을 개발하려고 합니다. 주문은 들어온 순서대로 처리됩니다. 이 때 여러분이라면 어떤 자료구조를 선택하실 건가요? 이유를 함께 적어주세요. */ #include<iostream> #include<queue> #include<string> using namespace std; typedef struct Order { string customerName; // 고객이름 string item; // 주문한 물건 int quantity; // 주문 수량 int price; // 주문 가격 int Sum; // 주문 총 가격 // 각 변수 초기화 Order(string name, string itm, int qty, int pri, int sum) : customerName(name), item(itm), quantity(qty), price(pri), Sum(sum) {} } Orderinfo; class OrderManager { public: void AddOrder(const string& name, const string& item, int quantity, int price, int Sum) { Sum = (price * quantity); orders.emplace(name, item, quantity, price, Sum); // 새로운 주문 객체를 큐에 추가 } void ProcessOrder() // 주문 처리 { // 큐에 주문이 있는가? if (!orders.empty()) { Order currentOrder = orders.front(); // 현재 처리할 주문을 큐의 앞에서 가져온다. orders.pop(); // 주문을 큐에서 제거 // 처리 중인 주문 정보 출력 cout << "Processing order for |"; cout << currentOrder.customerName << ": " << currentOrder.item << ": " << currentOrder.quantity << " | " << currentOrder.price << " | " << currentOrder.Sum << " | " << endl; } else { cout << "No orders to process. " << endl; // 주문이 없을 때 } } // 큐에 주문이 있는지 확인 bool bfHasOrders() const { return !orders.empty(); // 큐가 비어있지 않으면 true반환 } private: // 주문을 저장할 큐 queue<Order> orders; }; int main() { OrderManager manager; // 주문 추가 manager.AddOrder("김감자", "토마토", 2, 3000, NULL); manager.AddOrder("인프런", "바나나", 1, 2000, NULL); while (manager.bfHasOrders()) { manager.ProcessOrder(); // 주문처리 } return 0; }

cs-미션인프런워밍업클럽2기빠타박스인프런cs자료구조알고리즘운영체제

유진

인프런 워밍업 클럽 BE 2기 - 클린코드 / 테스트코드 발자국 4주차

강의 출처 Practical Testing: 실용적인 테스트 가이드 학습 내용레이어드 아키텍쳐(Layered Architecture)와 테스트 - 노션 정리Test DoubleDummy - 아무것도 하지 않는 깡통 객체.Fake - 단순한 형태로 동일한 기능은 수행하나, 프로덕션 초기에는 부족한 객체.Stub - 테스트에서 요청한 것에 대해 미리 준비한 결과를 제공하는 객체. 그 외에는 응답하지 않는다.Spy - stub이면서 호출된 내용을 기록하여 보여줄 수 있는 객체. 일부는 실제 객체처럼 동작하고 일부만 stubbing 할 수 있다.Mock - 행위에 대한 기대를 명세하고, 그에 따라 동작하도록 만들어진 객체.Stub / Mock 의 차이? -> Stub은 상태 검증 / Mock은 행위 검증@Mock, @Spy, @MockBean, @SpyBean, @InjectMocks - 노션 정리BDDMockito - Mockito를 BDD 스타일로 wrap해서 사용.// given Mockito.when(mailSendClient.sendEmail(anyString(), anyString(), anyString(), anyString())) .thenReturn(true); // BDDMockito given BDDMockito.given(mailSendClient.sendEmail(anyString(), anyString(), anyString(), anyString())) .willReturn(true);Classicist VS. Mockist진짜 객체로 테스트를 하고 필요한 경우에만 mocking해서 테스트를 하자. (Classicist)외부 시스템의 경우 mocking 처리해서 테스트.하나의 테스트는 하나의 주제만을 가져야 한다. 논리구조(if문, for문..) 같은 경우는 지양하는 것이 좋다. 만약 케이스 확장이 필요하다면 @ParameterizedTest 사용. 테스트 환경의 독립성 보장 - given절에서는 값 넣어줄 때 생성자, builder 사용.테스트 간 독립성 보장 - 두 가지 이상의 테스트가 하나의 자원을 공유할 때 주의해야 한다. 공유 자원(인스턴스)의 여러 시나리오를 테스트 하고 싶을 경우? -> @DynamicTest 사용.Test Fixture각각의 테스트에서 given이 중복되는 경우 @BeforeEach 에 작성할 경우 주의 해야 할 점 -> 각 테스트 입장에서 알지 못해도 테스트 내용을 이해하는데 문제가 없는지 / 수정해도 모든 테스트에 영향을 주지 않는지 고려해야 한다.data.sql 사용 지양. -> 무엇을 테스트하고 있는지 파악하기 어려울 수 있다.테스트 클래스마다 builder를 만들어서 각자 필요한 파라미터만 사용한다. (builder class를 만들어서 한 곳에서 관리하는 것이 오히려 복잡도를 늘어나게 한다.)Test Fixture 클렌징deleteAll()mapping된 테이블을 조회 후 delete 한다. 연관된 테이블을 모두 조회한 후 삭제하기 때문에 시간과 비용이 들 수 있다.테이블의 삭제 순서를 고려해야 될 수 있다.deleteAllInBatch()테이블의 삭제 순서를 고려해야 한다.여러 조건들(외래키 조건..)에 따라 삭제가 되지 않을 수 있다.테스트 환경 통합하기ServiceTest, RepositoryTest@ActiveProfiles("test") @SpringBootTest public abstract class IntegrationTestSupport { @MockBean protected MailSendClient mailSendClient; }ControllerTest@WebMvcTest(controllers = { OrderController.class, ProductController.class }) public abstract class ControllerTestSupport { @Autowired protected MockMvc mockMvc; @Autowired protected ObjectMapper objectMapper; @MockBean protected OrderService orderService; @MockBean protected ProductService productService; }private 메서드의 테스트는 하지 말아야 한다. 꼭 해야 된다면 따로 객체를 분리해서 테스트를 할 수 있다.테스트에서만 필요한 메서드는 만들어도 되지만, 보수적으로 접근해야 한다. 미션미션 1 - Layered Architecture 구조의 레이어별 특징과 테스트 작성법 -> 노션 정리미션 2 - @Mock, @Spy, @MockBean, @SpyBean, @InjectMocks 차이점 / @BeforeEach 배치 -> 노션 정리회고인프런 워밍업 클럽 BE 2기 4주차라니 시간이 어떻게 흘러간지 모르겠다. 이번 주는 특히나 내가 평소 궁금했던 것들에 대한 강의여서 더 집중해서 들었던 것 같다. 바로 프로젝트에 적용 해볼 만 한 내용이 많아서 만족스러웠다. 워밍업 클럽 진도를 따라가는게 쉽지는 않았지만 지나고 보니 포기하지 않고 어떻게든 하려고 노력 했던 것이 많은 도움이 된 것 같다.

백엔드인프런워밍업클럽2기테스트

예진안

인프런 워밍업 클럽2 cs <day11>

운영체제가상메모리 | 세그먼트, 페이징RAM | 가변분할, 고정분할(세그먼트,페이징이랑 가변분할이랑 고정분할이랑 갑자기 뭔차이지? 라는 생각이 들어서 이전 수업 듣고 까먹지 않게 적어놨다)(가상메모리 ram 차이가아니고 그냥 가변분할은 어떤 종류다~ 말하는거같기도하고)가상메모리 개요컴퓨터마다 메모리의 크기가 달라, 작업할 프로세스크기 > 메모리 일 경우 -> 실행불가문제 해결 방법 : 가상메모리를 사용. 메모리 관리자가 프로세스크기와 할당할 번지를 신경쓰지 않도록 0x0 번지부터 할당한다고여기게 한다.메모리 관리자 덕분에 프로세스와 메모리는 직접적으로 부딪힐 일이 없다.? 가상메모리 안에 메모리 관리자가 들어있나여? 사진이 안에 들어가있네 가상메모리 관리자라고 해야되나가상메모리 크기는 이론적으로는 무한, cpu 비트 수 + 메모리 크기에 정해진다.프로세스 처리 양 > 메모리 크기 일때처리하지 못한 프로세스를 하드디스크에 있는 스왕엽역으로 이동처리가 필요할 때 물리 메모리로 가져와서 실행 시킨다.- 32bit = 4GB => 메모리 크기도 4GB- 메모리 크기가 4GB 일 때, 프로세스 4GB *5 개 작업해야한다. => 디스크의 스왑영역으로 이동동적 주소변환 (DAT) : 메모리 관리자는 물리메모리와 스왑여역까지 합쳐 프로세스가 사용하는 가상주소를 물리주소로 변환실제 0x0 번지 물리주소에는 운영체제 영역 -> 프로세스들은 사용 x가상메모리 시스템에서는 나머지영역을 가변분할 방식, 고정분할 방식으로 나뉜다.-가변분할 (세그먼테이션) / 고정분할방식 (페이징) / 페이지드 세그먼트 (혼용)메모리 관리자는 가상주소 - 물리주소 => 1대1 매핑 테이블로 관리세그멘테이션 (배치 정책)세그멘테이션 -> 프로세스를 함수, 모듈 등으로 세그먼트를 구성한다.사용자 입장 : 세그먼트들(함수 + 모듈 ..)은 서로 인접하지 않는다.프로세스 입장 : 영역들이 서로 인접해 있다.논리주소논리주소는 사용자, 프로세스 CPU 사용논리주소 -> 물리주소 변환은 메모리관리자가 담당메모리 관리자는 세그멘테이션 테이블을 가지고 물리 메모리 주소를 계산한다.논리주소 -> 물리주소 변환 과정cpu에서 논리주소 전달 -> 메모리 관리자가 몇번 세그먼트인지 알아낸다-> 메모리 관리자 내에 있는 Segment Table Base Register 를 이용해서 물리 메모리 내에 있는 세그멘테이션을 찾는다.(여기서 STBR 와 세그멘테이션 테이블은 다르다. STBR에서 세그멘테이션을 찾고 찾은 걸로 세그먼트번호 참조)-> 세그먼트 번호를 인덱스로 Base Address, BoundAddress를 찾는다.(운영체제는 컨텍스트 스위칭이 일어날 때마다 STBR의 내용을 해당 프로세스의 값으로 바꿔줘야한다.)-> Bound Address는 메모리의 크기를 나타낸다.메모리 관리자는 cpu에서 받은 논리주소와 Bound Address의 크기를 비교한다.-> 논리주소 < Bound Address 일 경우, 논리주소 + Base Address = 물리주소 구하기.논리주소 > Bound Address 일 경우, 메모리를 침범했다고 생각하고 에러를 내보낸다.세그먼트 3번이 0x750번지로 접근cpu의 요청을 받은 메모리 관리자, STBR 을 이용해서 물리 메모리 내에 있는 세그멘테이션을 찾는다.-> 세그먼트 번호를 인덱스로 세그멘테이션 테이블을 참조한다. 3번 세그먼트, BA 500-> 논리주소 > Bound Address 이므로 에러를 발생시킨다. 세그멘테이션 장점 :메모리를 가변적으로 분할할 수 있다.코드영역,데이터영역,힙,스택 모두 모듈로 처리가능 => 각 영역의 공유와 접근보호가 쉽다.세그멘테이션 단점 :외부단편화 발생페이징(배치정책)고정분할 방식 사용메모리 할당 시 정해진 크기로 페이지를 나눈다. =>관리하기 쉬움, 외부단편화 발생하지 않음논리주소공간에서는 페이지, 물리주소 공간에서는 프레임이라고 부른다.페이징 주소변환페이지 넘버 (인덱스 ) = 논리주소 / 페이지크기오프셋 = 논리주소 % 페이지크기메모리관리자는 페이지테이블을 가진다.CPU 32bit , 논리주소공간 4GB 물리주소 공간 2GB (논리 > 물리 크기를 설정함으로써 스왑영역을 사용하는 걸로 가정)논리주소공간을 16MB 256페이지로 나눈다.물리주소 공간(2GB) -> 16MB * 128 로 나눈다CPU가 논리주소를 메모리 관리자에게 넘긴다.-> 메모리관리자 안에 있는 PageTableBaseRegister를 이용해서 페이지 물리 메모리에 있는 페이지 테이블을 찾는다.-> 페이지 번호는 인덱스로, 프레임 번호를 알아낸다.-> 오프셋을 이용해 물리주소로 변환한다.ex 1번 인덱스의 프레임 번호는 1번. 프레임번호 + 오프셋 = 물리주소 => 1477217(페이지 테이블에 프레임 = Invalid 일경우 스왑영역에 저장된 부분임)(PTBR은 운영체제가 컨텍스트 스위칭할 때 마다 해당 프로세스의 것으로 업데이트해준다)세그멘테이션 vs 페이징세그멘테이션 : 프소세스마다 크기가 달라서 bound Address가 필요하다.페이징 : 모든 페이지가 크기가 동일해서 Bound Address가 필요하지 않다.페이징의 내부단편화세그멘테이션 : 논리적인 영역별로 세그먼트를 나눈다.페이징 : 논리적인 영역별로 나누기보다 정해진 크기로 나눈다. 특정 영역만 공유하거나 권한 부여가 어렵다.페이지 테이블의 크기를 얼만큼씩 나눌지가 제일 중요하다,프로세스 많아질수록, 페이지테이블 늘어난다. => 프로세스가 실제로 사용할 수있는 메모리영역🔽페이지 테이블도 물리 메모리의 운영체제 영역에 저장되어 있다.-> 페이지 테이블이 크면 사용자 영역이 부족해진다STBR로 세그멘테이션을 찾는다고 했는데 그럼 세그멘테이션이 겁나 많아서 세그멘티에션 테이블도 많다는 건가? 위와 같은 맥락인 것 같다.페이지드 세그멘테이션(배치정책)세그멘테이션 + 페이징 장점 취합세그먼트로 나눠 관리해서 다른 프로세스와 공유, 권한 부여가 쉽다.오버헤드가 적고 페이지 크기를 정해 나눠서 할당 시킨다.메모리 접근 권한 : 메모리 특정번지에 부여된 권한읽기(READ), 쓰기(Write), 실행(EXECUTE)프로세스는 영역마다 접근권한이 있다.CODE영역 : 프로그램 그자체. 수정되면 안됨. 읽기 실행권한DATA 영역 : 일반변수, 전역변수, 상수로 선언한 변수가 저장. 읽기권한 쓰기권한은 없거나 있다.HEAP,STACK영역 : 읽기 쓰기 권한메모리 접근 권한 검사 : 논리주소에서 물리주소로 변환할 때마다 실시된다.권한비트를 추가해서 검사를 한다.권한이 없는 메모리가 접근 시 에러를 발생시킨다.페이지드 세그멘테이션 : 세그멘테이션 테이블 + 페이지 테이블 사용권한비트 , Bass Addres(페이지넘버), Bound Address(페이지개수) 로 변환 시킨다.cpu에서 논리주소를 메모리 관리자에게 넘긴다.-> 세그먼트를 찾는 방식으로 세그먼트를 찾는다.-> 권한비트로 세그먼트 권한을 위반하는지 검사한다.(권한 위반 시 프로세스 종료)-> 페이지 넘버 = 인덱스. 페이지 넘버에서 인덱스를 참조해서 프레임을 알아낸다.페이지드 세그먼트 단점 : 세그멘테이션테이블과 페이지 테이블을 참조할 때 총 메모리 접근이 두 번이다.=> 현재 운영체제는 페이지드 세그먼트와 페이징 기능을 적절히 섞어 작업한다. 알고리즘삽입 정렬정렬된 영역 맨 끝 원소와 정렬되지 않은 영역 첫 원소와 크기를 비교하여 정렬하고정렬되지 않은 영역에서 비교하는 원소A > 정렬된 영역 원소B 경우 => 정렬된 영역 원소 다음 원소와 비교해당원소 자리에 정렬된 영역 원소B 복사정렬되지 않은 영역에서 비교하는 원소A < 정렬된 영역 원소B 경우 => 정렬된 영역 원소 이전 원소에 A 삽입function InsertionSort (arr) { for(let i =1; i< arr.length; ++i){ //정렬되지 않은 배열. 첫번째원소는 정렬되었다고 가정 let insertingData = arr[i]; for(let j =i-1; j>=0;--j){ //정렬된 배열 if(arr[j] > insertingData ){ arr[j+1] =arr[j]; }else{ break;// for문탈출 } } arr[j+1] = insertingData; } }오늘의 질문메모리 관리자는 어디에 위치해있나? cpu안? 혹은 메모리마다 가지고 있나?cpu 와 메모리 관리자는 따로 존재한다.CPU가 메모리에 접근하는 것을 관리하는 컴퓨터 하드웨어 부품 이라고 한다.테이블은 메모리에 할당되어있다고 하지만 그럼 STBR이랑 PTBR은 메모리 관리자 안에 있는데 어캐그럼? 험~ 

알고리즘 · 자료구조운영체제알고리즘인프런워밍업클럽2기

유진

인프런 워밍업 클럽 BE 2기 - 클린코드 / 테스트코드 발자국 3주차

강의 출처 Practical Testing: 실용적인 테스트 가이드 학습 내용단위 테스트JUnit5AssertJ(assertThat(actual).isEqualTo(expected)..)테스트 케이스 세분화 하기해피 케이스 (항상 통과하는 테스트)예외 케이스 -> 경계값 테스트 (범위, 구간, 날짜 등)테스트 하기 어려운 영역은 구분하고 분리해야 한다. (테스트 내부에 있는 값을 파라미터, 상수로 분리)현재 날짜/시간, 랜덤한 값, 전역변수/함수, 사용자 입력 등 표준 출력, 메시지 발송, db에 기록하기 등TDD : Test Driven Development프로덕션 코드보다 테스트 코드를 먼저 작성하여 테스트가 구현 과정을 주도하도록 하는 방법론실패하는 테스트 작성(RED) -> 테스트를 통과하는 최소한의 코딩(GREEN) -> 구현 코드 리팩토링(REFACTOR)TDD의 핵심가치 - 피드백DisplayName문장 : A이면 B이다. / A이면 B가 아니고 C이다.테스트 행위에 대한 결과까지 기술도메인 용어를 사용하여 추상화 된 내용 담기테스트의 현상을 중점으로 기술 X특정 시간 이전에 주문을 생성하면 실패한다.(X)영업 시간 이전에는 주문을 생성할 수 없다.(O)BDD : Behavior Driven DevelopmentTDD에서 파생된 개발 방법Given : 시나리오 진행에 필요한 모든 준비 과정(객체, 값, 상태 등)When : 시나리오 행동 진행Then : 시나리오 진행에 대한 결과 명시, 검증 미션Readable Code 강의의 지뢰찾기 프로젝트로 단위 테스트 작성하는 미션. CellSnapshotTest(셀의 상태 - 빈 셀, 지뢰 셀, 숫자 셀, 열지 않은 셀), CellPositionTest(Cellposition 생성 - 해피 케이스, 0 미만의 인덱스 Cellposition 생성 불가 - 경계값 테스트), GameBoardTest(지뢰 셀을 오픈하면 게임상태 Lose로 변경), ConsoleInputHandlerTest(사용자가 1을 입력하면 셀 오픈). 총 3개의 테스트 클래스와 8개의 테스트를 작성했다. GameBoardTest와 ConsoleInputHandlerTest는 테스트에 실패 했는데, GameBoardTest의 경우는 검증하고자 하는 메소드에서 값을 제대로 불러오지 못하여 실패했다. ConsoleInputHandlerTest는 Scanner를 테스트 해야 했는데 NoSuchElementException이 발생해 테스트에 실패했다.  회고평소에 테스트에 대한 고민이 많았었는데, 강사님의 라이브 코딩으로 테스트 하는 법을 배울 수 있어서 좋았다. 무엇을, 어떻게 테스트 해야 하는지는 아직 어려움이 있어서 꾸준한 노력이 필요할 것 같다. 다음 주에는 강의 완강을 목표로 끝까지 최선을 다해야겠다.

백엔드백엔드인프런워밍업클럽2기

Yoo Seung Hwan

[인프런 워밍업 클럽 2기 백엔드 프로젝트 과정] 3주차 발자국

I. 3주차 학습 내용  1일차 - 포트폴리오 사이트 화면 개발부트스트랩  템플릿 수정2일차 - 어드민 공통 기능 개발0) 오류의 종류자바 계열에서 오류는 크게 Error와 Exception으로 나뉜다Error는 애플리케이션에서 대응할 수 없는 오류로 - Stack OverFlow Error와 같이 개발자가 해결할 수 없는 오류이다.Exception은 애플리케이션에서 대응할 수 없는 오류로 - RuntimeException 과 같이 개발자가 대응하는 코드를 작성할 수 있는 오류이다.  1) 예외 처리 RuntimeException : 실행시점에 발생하는 예외 처리를 위한 클래스예외는 다양한 경우가 있을 수 있다. 하지만 모든 예외에 대응할 수 없으므로 그 외의 오류에 대응하는 코드를 작성해주어야 한다. Exception을 통해 예외를 정의해주고 Advice의 @ExceptionHandler를 통해 예외에 대한 처리를 지정해준다 2)DTO2-1 공통 Api 응답 포맷Api 응답의 공통 포맷 작성companion object: 클래스의 메서드를 각 클래스의 인스턴스 없이 호출할 수 있게 해줌 수정, 삭제, 저장 성공시에 대한 포맷을 작성해줌 2-2 폼 DTO공통 폼 요소 정의사용자 입력폼을 정의 포맷, 강의에서는 타입별로 text, date, select로 나눔 나는 개인 프로젝트에 date는 필요 없어서 text, checkbox, select 타입 포맷을 지정함 3) Interceptor요청과 응답 사이에서 특정 작업을 수행하는 역할interceptorConfiguration을 통해 admin 하위에 경로가 adminInterceptor에 영향을 받게 함addIPathPatterns - 특정 경로를 인터셉터 처리에서 포함excludePathPatterns - 특정 경로를 인터셉터 처리에서 제외 3일차 - 데이터 조회, 삽입 수정, 삭제 기능 개발  II. 3주차 미션 - 조회 API 개발하기3주차 미션강의 계획대로 진행하다 보니 과제가 조회 api 개발이 presentation을 통해 Json 포맷으로 웹 페이지의 결과를 띄우는건줄 알았는데 아니였나 보다 이번주 마지막 강의를 들어보니 조회 api는 따로 있었다. 망했다일단 Json을 통해 presentation 페이지에 띄우는건 어려운점이 크게 없었다. 사용자 정보를 저장하는 엔티티 이름을 User로 지정해서 SQL 예약어와 겹쳐서 User로 지정된 변수명과 연결된 클래스를 전부 UserInfo로 바꿔야 하는 문제 외에는 없었다. 조회 api 개발은 아직 진행 중이다. 연결된 엔티티가 정보 전체를 받아오는 문제, 리포지토리를 통해서 조회를 다시해야 하는 문제가 있어 엔티티, 리포지토리 코드를 전체적으로 수정하고 있다. 선택된 책 엔티티가 유저 엔티티 자체를 인자로 받다 보니 api를 개발할때 넘겨줄 인자가 없어 조회 코드를 작성하지 못해 userid만을 참조하도록 하고 selecbook repository에 getbyuserId를 추가하는 작업을 추가하는 중이다. 3주차에서 완주를 결국 실패하게 됬지만 모든 과정을 꾸준히 지속해 나갈 생각이다.     III. 3주차 회고3주차 미션은 지금까지의 미션 중에서는 가장 어려웠다. 지금까지는 전체적인 아키텍쳐 구조를 잘 몰라도 어느정도 따라할 수 있었는데 테스트 코드가 까지 통과해야 하는 코드를 작성해야하다 보니 기존에 잘못 쓴 코드들을 다 들어내고 작업해야 하는 경우도 있었다. 처음 하는 작업이다 보니 설계단계에서부터 실수가 많이 보여 시간을 많이 들이고 있는 중이다. 그래도 이 부분을 잘 정리해서 다음부터는 좀 더 삽질을 덜 하게 되도록 노력하겠다. 경험 덕분에 클린 코드에 대한 새로운 관점이 생겼고 아키텍쳐에 대해 자세히 공부해야 겠다는 생각이 들었다. 코드 설계단계의 중요성도 새로 깨닫게 되었다.지금은 그저 미션을 위해서 끄적여 놓은 코드에 불과하지만 추후 과정이 끝나고 여유가 생겼을 때 코드를 좀 더 다듬고 이번 경험을 토대로 프로젝트 전체를 재설계하여 좀 더 완성도 높은 프로젝트로 완성하고 싶은 욕심이 생겼다.

백엔드인프런워밍업클럽2기백엔드

Yoo Seung Hwan

[인프런 워밍업 클럽 2기 백엔드 프로젝트 과정] 2주차 발자국

I. 2주차 학습 내용 1일차 - 데이터를 다루는 리포지토리 개발하기1) 데이터베이스 초기화테스트 데이터를 초기화 했음 @Component - 스프링에 빈으로 만들 클래스를 알려주는 것설명을 들으때마다 이런 기술들을 통해 스프링의 위대함을 잘 알려주는 것 같다. 스프링이 없었다면 개발을 위해 직접 인스턴스를 생성하고 관리해야 했을텐데 복잡한 서비스에서는 스프링이 필수라는 것을 잘 느낄 수 있는 것 같다. @Profile - 특정 value일 때만 빈으로 생성@PostConstruct - 빈 생성 직후 postConstruc 과정시에 실행 되도록 해줌 1일차 과정 중에는 프로젝트에 사용할 테스트 데이터들을 정의 하고 필요한 곳에 초기화 하였음코틀린 문법에 익숙하지 않아 혼자서 생각하면서 작성하지는 못했으나 파이썬이나 JS, Java 등 프로그래밍 언어에 어느 정도 익숙한 사람이라면 추측 가능한 코드들이 많아서 어렵지 않았습니다. 코틀린 문법에 익숙해지기 위해 코틀린의 리스트 생성등 기초 문법을 찾아 보는 등 다른 공부에 시간을 많이 할애 할 수 있는 시간이였습니다. 2일차 - 리포지토리 테스트 하고 성능 개선하기들어보기만 했던 대망의 테스트 코드 작성@DataJpaTest - Jpa 관련 테스트 어노테이션@TestInstance - 테스트 인스턴스를 관리 강의에서는 인스턴스의 라이프 사이클을 클래스 단위로 정의해주는 역할을 했음assert - 개발 및 디버깅을 전제로 사용하는것, 비즈니스 로직과 검증 로직은 구분할 수 있음 코드나 개념적으로 어려운 부분은 없었음. 테스트 코드를 작성하면서 해야할 생각에 대해 배운게 더 많았다. 데이터가 어떻게 서로 전달되고 결과는 어떻게 나와야할지 클래스를 추상화 하듯이 생각하면서 오류를 잘 발견할 수 있게끔 그러면서도 테스트 코드의 가독성은 높게 작성하는 것이 좋은 테스트 코드라는 생각이 들었다.  개발자 관련된 소식을 접하다 보면 테스트 코드에 대해서 많이 들어보게 됩니다. 저는 아직 제가 테스트 코드 같이 딥한 내용을 배우기보다는 기초에 더 투자할 때라 생각하여 한번도 테스트 코드 작성과 관련해서 고민 해본적도 작성해본적도 없었습니다. 하지만 테스트 코드에 대해서 배우고 나니 생각보다 어려운 개념이 아니였고 기초 단계의 공부와 코드 작성에 많은 도움을 주었습니다. 오류의 탐색 범위를 줄이는데 도움을 주었고. 완성될 프로젝트의 작동 과정에 대해 코드적으로 고민해 보니 다른 코드들이 어떻게 작성되어야 할지 간접적으로 생각해보게 되었습니다. 이는 나중에 제가 개인 프로젝트를 할때 큰 도움이 될것 같았습니다. 항상 어려운 개념이라고 느껴졌던 테스트 코드에 대해서 선입견을 깨는 좋은 경험이였습니다.  3일차 - 데이터를 조회하고 변환하는 서비스 개발 II. 2주차 미션 - REST API 설계하기왜 백엔드가 상상력이 풍부한 사람들이 해야 하는가에 대해 깨달았던 시간 어떤 유튜브 동영상에서 백엔드 개발자는 상상력이 많은 사람들이 해야하는가에 대해 관한 이야기를 하는걸 봤었다.백엔드 개발자는 상상력이 풍부한 사람이여야 한다.당시에는 이해하지 못했지만 미션을 해결하면서 어느 정도 깨달음을 얻은 것 같다. 이번 미션은 REST API 설계였다. 대학교에서 과제를 하면서 카카오 REST API를 활용한적 있는 나한테는 그리 어려운 과제가 아닐거라고 생각했었다. 하지만 API를 사용하는것과 설계하는 것은 달랐다. API를 설계하면서 나는 내가 작성했던 ERD를 다시 보았다. 그때 당시에는 꽤 괜찮은 설계라고 생각했었는데 api를 통해 데이터가 오가는걸 생각하니 잘못된 부분이 보여 몇 군데를 수정했다. 연결관계에는 문제가 없었지만 데이터를 주고 받는데 불필요한 외래키와 중복키가 있어서 제거 하였다. 이번 과제를 하면서 가장 고민했던 부분은 API 설계 툴이였다. 그냥 표로 간단하게 정리해서 설계를 하려 했었는데 다른 분들이 올리신 API 설계를 보니 특정 툴을 이용해서 올린게 너무 멋있어 보였다. 그래서 PostMan, Swagger, GitBook 등을 찾게 되었다. 하지만 안타깝게도 개인적인 사정으로 바쁜 나머지 툴들을 이용해서 과제를 올리지는 못했다. PostMan과 GitBook이 내 마음에 들어서 추후 워밍업 클럽 과정이 끝나면 해당 툴들에대해 공부하는 시간을 가져야겠다.   III. 2주차 회고2주차는 개인적으로 바쁜 시간이였습니다. 개인적인 일들로 많이 바쁜 시간이었고 집에오면 몸이 지쳐서 강의를 제때도 못듣고 대충 듣고 넘어가기도 했던 것 같습니다. 평소라면 그냥 넘어갔다가 기억을 다 잊은 상태에서 다시 강의를 들으러 왔었겠지만 워밍업 클럽을 신청하게 된 다짐과 동기, 그리고 앞으로 해야 할 과제들을 생각하면서 시간 날 때마다 강의를 다시 들어 빠르게 내용을 습득하고 제 것으로 만들 수 있었던 것 같습니다. 시작한지 얼마 안 지난것 같은데 벌써 10월의 절반이 갔고 워밍업 클럽의 진도도 50%가 넘어가고 있는데 저 같이 꾸준하지가 못한 사람들은 마음을 다시 다잡을 때인것 같습니다. 앞으로도 계속 정진하여 완주 하는 것을 목표로 달려보겠습니다.

백엔드인프런워밍업클럽2기

유진

인프런 워밍업 클럽 BE 2기 - 클린코드 / 테스트코드 발자국 2주차

강의 출처 Readable Code: 읽기 좋은 코드를 작성하는 사고법 학습 내용코드 다듬기주석 적절히 사용하기자주 변하는 정보는 지양관련 정책이나 코드가 변경될 경우 주석도 업데이트변수와 메서드의 나열 순서변수는 사용하는 순서대로 나열메서드의 경우 객체의 입장에서 고려공개 메서드를 상단에 배치공개 메서드끼리도 기준을 가지고 배치(상태변경 > 판별 >= 조회 메서드)비공개 메서드는 공개 메서드에서 언급된 순서대로 배치패키지 나누기문맥으로써 정보를 제공할 수 있음패키지를 쪼개지 않으면 관리가 어려움(너무 잘게 쪼개는 것도 관리가 어렵다)대규모 패키지 변경은 팀원과 합의 후기능 유지보수IDE의 도움받기코드품질 : sonarlint 포맷규칙 : .editorconfig 리팩토링메서드 추출로 추상화 레벨 맞추기중복 제거, 메서드 추출Optionalsetter 사용 x, 무분별한 getter사용 대신 객체에 메세지 보내기객체의 책임과 응집도IO 통합일급컬렉션 Order 객체 추출추상화 관점의 차이구현에 초점을 맞춘 추상화 / 도메인 개념에 초점을 맞춘 추상화미션사용자가 이용권을 선택하고 선택한 이용권에 따라서 가격을 계산하는 프로그램을 리팩토링하는 미션이었다. 추상화 레벨에 맞지 않는 부분이 있다면 메서드 추출 등으로 추상화 레벨을 맞춰주고, 객체지향 패러다임에 맞게 객체들이 상호 협력하고 있는지, SRP, DIP, 일급 컬렉션 등의 포인트로 리팩토링을 해주면 되었다.회고미션을 진행하는 동안 가장 큰 어려움은 전체 코드의 맥락을 파악하는 것이었다. 그러다보니 변수, 메서드명 변경, 메서드 추출 등의 소심한 리팩토링 위주로 미션을 진행했다. 수강했던 강의들의 복습의 필요성을 절실히 느낄 수 있었다. 지난 강의들을 바탕으로 읽기 좋은 코드란 무엇인지 끈임없이 고민하는 자세를 가져야겠다.

백엔드인프런워밍업클럽2기백엔드

예진안

인프런 워밍업 클럽2 cs <day8>

운영체제데드락 = 교착상태프로세스들 중 작업이 끝나기를 기다리다가 아무것도 못하는 프로세스가 이렇지도 저러지도 못하는 상황 => 공유자원이 원인식사하는 철학자식탁에 세 명의 철학자가 있고 세 개의 포크가 존재한다.밥을 먹을 땐 두 개의 포크를 사용해서 먹어야된다.포크 = 공유자원 , 철학자 = 프로세스교착상태 => 철학자 두 명이상이 밥을 같이 먹게 될 때 포크가 부족한 상황교착상태의 필요조건상호배제 : 프로세스가 리소스를 점유했을 때 점유한 리소스가 다른 프로세스와 같이 사용될 때비선점 : 프로세스a가 작업 중인데 프로세스 b가 와서 강제로 선점점유과 대기 : 프로세스가 리소스를 하나 점유하고 있고 또다른 리소스를 원하고(대기하고) 있는 상태원형대기 : 점유와 대기 형태가 원을 만들어 무한히 대기 중인 모습데드락 해결교착상태를 회피 : 교착상태가 일어날 정도로 프로세스에게 자원을 많이 할당해주지 않는다.안정상태 ------------- 불안정상태 --교착상태에 빠질확률 🔼--->은행원 알고리즘은행이 돈을 빌려줄 때 사업자의 자금상태를 확인하고(안정상태)여러 사업자에게 돈을 빌려주고 다른 사업자가 돈을 갚았을 때 그 돈으로 다른 사람에게 돈을 빌려주는 방식은행이 교착상태일 때 - 가진 돈은 100이지만 50, 50씩 빌려주었고 A는 20을 더 빌려주면 50까지 갚겠노라 한다 그래서 B에게 가서 50을 갚으라고 하고 그돈으로 A에게 돈을 빌려주려 했지만 갚지 못했다.-> 은행은 가진돈이 없다. 교착상태은행의 안정상태 : 기업가들이 여윳돈과 대출을 했을 때 빌릴 수 있는 능력이 있는지 확인한다. https://www.inflearn.com/users/17036/@%EA%B0%90%EC%9E%90 감자님 강의 중위에 상태 중 p1이 자원을 4만큼 요구한다. -> 사용가능한 자원은 2이므로 거절된다. p2에서는 자원을 2만큼 요구한다 -> 자원을 할당 시켜주고 4+2해서 6을 돌려받아 >>> 프로세스 p1과 p2의 나머지 자원을 할당시켜준다.불안정상태: 사용가능한 자원은 1개지만 프로세스들이 요구하고자 하는 자원이 훨씬 많을 경우 교착상태를 예방하기엔 어렵고 교착상태가 일어났을 때의 해결방법이 뭐가 있을까교착상태를 구분하기 -> 가벼운 교착상태 무거운 교착상태가벼운 교착 상태 : 프로세스가 일정시간 안에 작업을 진행하지 않음 -> 교착상태로 간주 해결 : 일정 시점마다 체크포인트에 저장을 하도록 하고 이전 체크포인트로 롤백하여 복구무거운 교착 상태 : 자원할당 그래프 이용 자원할당 그래프가 아래와 같이 순환구조 -> 교착상태 해결 : 교착상태가 일어난 프로세스 P2를 강제 종료시켜서 원형대기를 풀어버린다. 다시 실행 시킬 때 체크포인트로 롤백시킨다.이렇게 자원할당 그래프를 유지하고 검사 => 오버헤드가벼운 교첵상태에 비해 문제의 프로세스만 강제종료하면 되기때문에 효율적일지도?알고리즘재귀 -하노이탑이게 왜 재귀문과 연관이 있나...하향식 방식 계산을 한다. 원반 3을 움직이기 위해서는 원반1,2 전처리를 해야하게 때문function ha(count, from, to,temp){ if(count==0) return ; //기저함수 ha(count-1,from,temp,to); console.log(`원반 ${count}를 ${from} 에서 ${to}로 이동`); ha(count-1, temp,to,from); } ha(3,"A","B","C"); //원반갯수count,원반들이 처음에 꽃혀있는 기둥 from, //원반들이 최종적으로 꽂힐 기둥to, // 원반들이 이동을 위해 일시적으로 사용할 기둥temp //원반3이 기둥c로 이동하기위해서는 (하위문제) 원반 1,2,가 기둥 B로 위치해야함

알고리즘 · 자료구조알고리즘운영체제인프런워밍업클럽2기

도호

[인프런워밍업클럽2기] 1주차 발자국

본 회고는 인프런 박우빈 지식공유자님의 Readable Code: 읽기 좋은 코드를 작성하는 사고법 강의를 듣고 작성된 내용입니다.총평 예상했던 것 보다 하루에 들어야하는 강의 분량이 많아서 힘들었다. 하지만 실무를 하면서 고민했던 부분들이 조금이나마 해결이 된 것에 보람을 느꼈다.그리고 영어 공부를 할 필요성을 느꼈다. Readable하기 위해서 중요한 것은 네이밍이라고 생각한다. 아무리 열심히 추상화를 하고 결합도를 낮춰도 변수와 메서드 이름이 의도를 담지 못한다면 의미가 없는 것 이라고 생각한다.이 생각을 한 이유는 강의를 보면서 지식 공유자님의 네이밍에 무릎을 탁 쳤기 때문이다. 나였다면 어떻게 했을까를 생각해보니 너무 초라했다. KPT 회고 Keep강의를 들으면서 나에게 필요했던, 내가 고민 했던 부분들을 위주로 정리해 나갔다.코드를 따라가면서 나라면 어떻게 수정 했을 지 고민하고 비교해보았다.Problem미션을 위한 정도까지만 강의를 듣고 DAY 5의 분량을 수강하지 못하였다. 한번 미루니 분량이 걷잡을 수 없이 늘어나버렸다. Try강의를 미리 들어놔야겠다.학습 내용 요약 읽기 좋은, 가독성이 좋은 코드를 짜야하는 이유는 무엇일까? 나는 코드를 읽을 때 생각없이 읽혀야한다고 생각한다. 문제 해결을 위해서 혹은 기능 수정을 위해서 기존 코드를 읽을 때 코드를 잘못 이해하게 된다면 잘 동작하던 부분에도 문제가 생길 수 있다. 그리고 우리의 개발 기간이 배로 늘어날 것이다. 어찌되었던 개발자는 회사의 제품을 잘 만들어서 그로 인해 회사에 수익을 가져다줘야하는 역할을 맡고 있기 때문이다. 개발 기간이 줄어들면 그만큼 투입되는 인건비가 줄어드는 것 일 테니까 말이다. 읽기 좋은 코드를 짜기 위해서는 아래 항목들에 신경을 써야한다.네이밍추상화Depth 그리고 공백 즉 비즈니스가 담고있는 내용을 쉽게 읽히게 해야한다.객체 지향 코드가 무조건 가독성이 좋고 어느 상황에서든 적용되어야하는 패러다임은 아니다. 상황에 따라서 절차 지향 코드가 더 적절할 때도 있을테니까.그렇지만 알고서 안쓰는거랑 모르고 안쓰는 것, 잘못알고 잘못 쓰는 것은 다르다. 강의에서는 객체 지향 패러다임에 대해서 여러 세션을 할당해서 설명하고 있다.흔히들 객체지향에서 이야기하는 SOLID, 캡추상다 같은 특징들은 구글 검색만 해도 나오니까 넘어가도록 하겠다.미션 회고이번 주차의 미션은 실생활의 행동을 추상화, 코드를 리팩토링하고 SOLID를 정의하기 였다.정의와 추상화는 어렵지 않았지만 코드 리팩토링은 약간의 고민이 필요했다.이유는 유효성 검증을 ealry return할 때, Order의 사용자가 유효한지를 Order가 검사하는 것이 맞을까? 라는 고민을 했었다.나의 결론은 Order도 User의 정보를 갖고있기 때문에 Order 레벨에서 User에 대한 검사정도는 필요하다고 판단했다. User가 null일 수도 있으니까 말이다.다음 미션은 리팩토링해보기인데 정말 기대된다. 아자아자

인프런워밍업클럽2기readablecode박우빈

유진

인프런 워밍업 클럽 BE 2기 - 클린코드 / 테스트코드 발자국 1주차

강의 출처 Readable Code: 읽기 좋은 코드를 작성하는 사고법 학습 내용읽기 좋은 코드를 작성하기 위해서는 추상화가 필요하다.추상화의 방법변수와 메서드의 이름에서 무엇을 하는지 알 수 있어야 한다.메서드 시그니처(메서드명, 파라미터), 반환타입추상화 레벨을 동등하게 해주어야 한다.상수 추출early return중첩 분기문, 중첩 반복문 줄이기부정어구를 대체 할 수 있는지예외처리(개발자가 의도한 예외와 예상치 못한 예외의 처리)NullPointException, Optional객체지향SOLID미션추상과 구체의 예시 : 카페에서 커피를 주문하는 것을 단계별로 구체화했다.코드 리팩토링 : 메서드명 변경, 메서드 추출, early return, 부정어구 대체 등을 하여 코드를 리팩토링 했다.SOLID 나만의 언어로 정리 회고클린코드에 대해 어떻게 접근해야 할 지 알 수 있어서 좋았다. 막연하게 어렵다고 생각했던 것들을 코드 리팩토링을 통해 공부할 수 있어서 좋았다. 그런데 생각보다 강의를 듣는게 빠듯했다. 강의만 듣는 것이 아니라 직접 코드로 적용해 보려고 하니까 강의 시간의 두 배는 더 소요되는 것 같다. 게다가 2번째 미션은 시간 안에 제출하지 못했기 때문에 다음 주부터는 시간 분배를 잘해야겠다.  

백엔드인프런워밍업클럽2기백엔드

도호

[인프런워밍업클럽2기] DAY 4 미션

코드 리팩토링요구사항 사용자가 생성한 '주문'이 유효한지 확인해야한다.주문 항목은 1개 이상이어야한다.주문 전체 가격은 1원 이상이어야 한다.주문한 사용자 정보는 필수 정보이다.Order는 주문 객체이고, 필요하다면 Order에 추가 메서드를 만들 수 있다.필요하다면 메서드를 추출할 수 있다.public boolean validate(Order order) { if (order.isEmpty()) { log.info("주문 항목이 없습니다."); return false; } if (order.isInvalidPrice()) { log.info("올바르지 않은 총 가격입니다."); return false; } if (order.isInvalidUser()) { log.info("사용자 정보가 없습니다."); return false; } return true; }SOLIDSingle Responsibility Principle (단일 책임 원칙)하나의 모듈은 하나에 대한 책임만을 가져야한다.클래스 내부 private 메서드가 많거나 단위테스트가 애매한 경우에는 책임을 분리하는 것을 고려할 수 있다. Open-Close Principle (개방-폐쇄 원칙)확장에 열려있고 수정엔 닫혀있어야한다.새로운 기능을 추가할 때 기존 기능에 영향 없이 추가할 수 있어야한다. 즉 서로간의 의존 관계를 최소화해야한다.이 원칙은 B기능을 추가하였는데 A기능 테스트가 깨짐으로써도 확인할 수 있다.Liskov Substitution Principle (리스코프 치환 원칙)부모 클래스의 역할을 자식이 대체할 수 있어야한다.List 인터페이스의 구현체를 LinkedList에서 ArrayList로 변경하더라도 결과가 동일해야한다.Interface Segregation Principle (인터페이스 분리 원칙)하나의 인터페이스가 많은 책임을 가지고 있다면 인터페이스를 분리해야한다.Dependency Inversion Principle (의존관계 역전 원칙)구현체를 직접 사용하는 것 보다 추상화 된 것을 바라보는 것이 확장에 용이하다.List를 사용하는 것이 ArrayList를 사용하는 것 보다 확장에 유리하다.

백엔드인프런워밍업클럽2기

채널톡 아이콘