블로그
전체 92025. 03. 23.
0
[인프런 워밍업 클럽 3기] CS - 3주차 발자국
스터디 회고 무사히 3주차 스터디를 마쳤다.마치고 나서 든 생각은 혼자서 공부했다면 절대 이 시점에 마무리하지 못했을 것이라는 점이다.아마 혼자 했다면 계속 차일 피일 미뤘을 것이다...억지로라도 따로 시간을 내게 해준 것 만으로도 나에겐 충분히 의미가 깊은 스터디였다. 이번 스터디를 하는 내내 만족스러운 강의였다.어느덧 벌써 3주일이 지났는데, 1주차 회고에서 말했듯이 시작할 때 비전공자를 위한 수업이 아닌가 하는 걱정이 있었다.열심히 공부한 것은 아니지만 그래도 한번씩 다 본 내용들이라는 생각과, 심지어 옆에서 따로 전공책으로 CS를 공부하는 친구들도 있었기에 계속 고민이 됐다. 완주를 한 지금 나는, 이해하기 어려웠던것을 그림으로 차근차근 핵심만 짚어주는 강의와 함께 전반적으로 CS 지식을 한번 훑어봤지만따로 CS를 공부했던 친구는, 스터디를 시작하지 않았을 나의 모습처럼 아직 반도 끝내지 못했다.물론 이 강의로 자료구조와 운영체제를 완전히 섭렵했다고 생각하진 않는다. 하지만 전반적인 내용을 쉽게, 이해해서, 한번 훑어봤다는 점에서 아주 만족한다.친구에게도 추천해봤지만 CS 공부에 정답은 없는 만큼 그 친구만의 길이 있으리라 생각한다. 만약 어느 전공자가 이 강의, 또는 스터디를 듣길 고민한다면 정말 추천해주고싶다. 물론 비전공자 또한 말할것도 없다. 크게 빠지는 내용 없이 정말 교수님보다 잘가르친다고 생각한다.
2025. 03. 23.
0
[인프런 워밍업 클럽_3기 CS] 3주차 운영체제 미션
메모리의 종류는 어떤것들이 있나요? 각 메모리의 특징도 함께 적어주세요. 레지스터 - 휘발성 메모리로, cpu 계산할 때 메인메모리에 있는 값을 레지스터로 가져온 후 계산한다. 가장 속도가 빠르고 용량이 작다. 캐시 - 휘발성 메모리로, 메인메모리에 있는 값을 레지스터로 옮기려면 시간이 오래걸리기에 필요할것같은 데이터를 저장한다.단계에 따라 가장 속도가 빠른 L1캐시를 보고, 없다면 L2 캐시 확인, 또 없으면 메인 메모리에서 값을 가져온다. RAM - 휘발성으로, 실제 운영체제와 프로세스들이 올라가는 공간이다. 저장공간 대비 비싸기 때문에 데이터를 저장하기보단 실행중인프로그램만 올린다. HDD,SSD - 비휘발성 메모리로, 앞서 말한 메모리보다 상대적으로 느리다. 하지만 저장할 수 있는 용량이 크고 저장공간 대비 상대적으로 값이 싸다. 사용자 프로세스가 메모리의 운영체제 영역에 침범하지 못하도록 만든 레지스터는 어떤 레지스터일까요? base register 메모리 할당 방식에서 가변 분할 방식과 고정 분할 방식의 장단점은 뭔가요? 가변 분할 방식은 원하는 논리영역만큼 할당하여 필요한 만큼만 메모리 영역을 사용할 수 있다. 이를 통해 다른 프로세스와 세그먼트를 공유하기 편하고, 각 영역에 댛나 메모리 접근 보호도 편하다.하지만 사용 후 회수할 때 외부단편화가 일어나서 메모리 낭비가 심하다. 고정 분할 방식은 메모리 영역을 미리 고정된 크기로 나누기 때문에 오버헤드가 적다.하지만 작은 프로세스도 큰 영역에 할당되기 때문에 내부단편화가 발생한다. CPU 사용률을 올리기 위해 멀티프로그래밍을 올렸지만 스왑이 더 많이 이루어져 CPU 사용률이 0%에 가까워 지는 것을 뭐라고 할까요? 스레싱 HDD나 SSD는 컴퓨터를 실행시키는데 꼭 필요한 걸까요? 단지 데이터를 저장하는 장치일 뿐이기 때문에 실행에 꼭 필요하다고 생각하지 않는다.그 외의 메모리 안에 운영체제, 실행시킬 파일의 데이터가 모두 올라간다면 문제되지 않는다. 하지만 HDD나 SSD를 제외한 저장장치는 휘발성 메모리이기 때문에, 운영체제를 저장해둘 비휘발성 메모리가 필요하다. 파일을 삭제해도 포렌식으로 파일을 복구할 수 있는 이유가 무엇일까요? 특정 파일을 삭제해도 파일 시스템은 파일의 모든 정보를 지우는 것이 아니라, 파일 테이블의 헤더만 삭제하고 free block list에 추가하기때문에 사용자 입장에선 사라진것처럼 보이지만사용했던 블록의 데이터는 그대로 남아있기 때문에 복구할 수 있다.
2025. 03. 23.
0
[인프런 워밍업 클럽_3기 CS] 3주차 자료구조 미션
지금까지 배운 5개의 정렬 알고리즘의 장단점과 시간 복잡도를 적어주세요. 버블 정렬은 바로 옆에 숫자와 비교해서 자리를 바꾸는 알고리즘으로, 한번 끝까지 진행하면 가장 큰 숫자는 자기 위치를 찾아서 가장 끝에 정렬된다. 이해와 구현이 간단하지만 O(n^2)의 시간복잡도를 가져서 성능이 별로 안좋다. 선택 정렬은 배열의 정렬되지 않은 영역의 첫 번째 원소를 시작으로 마지막 원소까지 비교하여 가장 작은 값을 첫 번째 원소로 가져온다.역시 이해와 구현이 간단하지만 O(n^2)의 시간복잡도를 가져서 성능이 별로 안좋다. 삽입 정렬은 배열을 정렬,비정렬 영역으로 나눠서 정렬한다. 정렬되지 않은 영역에서 데이터를 꺼내고, 정렬된 영역 내의 적절한 위치에 삽입하여 정렬한다.마찬가지로 구현이 쉽지만, O(n^2)의 시간복잡도를 가져서 성능이 별로 안좋다. 병합 정렬은 분할정복의 방식을 따라서, 큰 문제를 작은 문제로 쪼개서 하나씩 해결한다.쉽게 병렬화되어 처리할 수 있고, O(n log n)의 시간복잡도를 얻기 때문에 다른 정렬에 비해 이득을 볼 수 있다.하지만 높은 메모리 사용량이 필요하고 분석하기가 어렵다. 퀵 정렬도 분할정복 방식을 따른다. 정렬 전에 하나의 원소를 피벗으로 설정하여 피벗보다 크고 작은 값을 기준으로 left, right index 영역으로 구분한다. 즉, 한 번 진행이 될 때 마다 피벗이 정렬되고, 왼쪽 오른쪽 영역을 재귀호출하여 모든 영역을 정렬한다.O(n log n)의 시간복잡도로 병합 정렬과 같아보이지만, 퀵정렬이 더 적은 비교랑 메모리 공간을 차지하기 때문에 퀵 정렬이 더 좋은 알고리즘으로 평가된다. 하지만 피벗을 어떤 것으로 지정하냐에 따라 왼쪽 오른쪽 영역이 한쪽으로 치우칠 수 있기 때문에 최악의 상황으로 O(n^2)이 될 수도 있다. 메모리가 부족한 시스템에서 어떤 문제를 해결하는데 재귀로 쉽게 구현이 가능할 것 같습니다. 여러분이라면 메모이제이션과 타뷸레이션 중 어떤 걸 이용하실 건가요? 이유를 함께 적어주세요. 우리가 해결해야 하는 것은 메모리가 부족한 상황을 해결해야 하는 것이므로 타뷸레이션을 사용할 것이다.재귀로 쉽게 구현이 가능하다는 판단이 있어도 메모이제이션을 사용한다면 여러 재귀호출로 인해 오히려 메모리를 더 많이 사용하게 될 것이기 때문이다.
2025. 03. 16.
0
[인프런 워밍업 클럽 3기] CS - 2주차 발자국
재귀에 대해 설명해주셨는데, 콜스택을 기반으로 설명해주셔서 머리속에 특히 더 쉽게 받아들인것 같다.학교에서 하노이의 탑 슈도 코드를 처음 봤을 때 저기에서 왜 저쪽 인자를 대입하는 것인지 머리속에 도저히 상상이 안갔었다.대충 재귀 개념만 인지하고 그냥 넘어갔었는데 그림과 화살표, 이 코드가 어느 부분으로 더 작게 쪼개서 구현할 수 있는지 알 수 있어서 이 부분이 제일 이번주에 의미가 있었다고 생각한다. 정렬 알고리즘의 기초인 버블, 선택 정렬 설명도 오랜만에 다시 보니까 쉽게 환기되어 좋았다. 세마포어와 모니터 설명을 위한 그림이 귀여웠다. 책에는 공유자원을 이용하면 안되니까 대기큐에 프로세스를 둔다, 구현해봐라 등등 뜬구름 잡는 글들 한가득이었는데 설명 진짜 대단하다고 느꼈다. 학교에서는 솔직히 운영체제 과목 거의 던져놓고 방치했었는데, 이 강의 덕분에 웬만한 개념들을 확실히 이해할 수 있다는 생각이 든다. cs 기반이 정말 부족하다고 생각했었는데 스스로도 채워지고 있음을 느낀다.
2025. 03. 16.
0
[인프런 워밍업 클럽_3기 CS] 2주차 자료구조와 알고리즘 미션
재귀함수에서 기저조건을 만들지 않거나 잘못 설정했을 때 어떤 문제가 발생할 수 있나요?계속 콜스택에 함수가 쌓이다가 스택 오버플로우가 발생한다. 0부터 입력 n까지 홀수의 합을 더하는 재귀 함수를 만들어보세요.int sumOdd(n){ // 재귀 로직 if(n == 1) return 1; return n + sumOdd(n-1); } std::cout 다음 코드는 매개변수로 주어진 파일 경로(.는 현재 디렉토리)에 있는 하위 모든 파일과 디렉토리를 출력하는 코드입니다. 다음 코드를 재귀 함수를 이용하는 코드로 변경해보세요.const fs = require("fs"); // 파일을 이용하는 모듈 const path = require("path"); // 폴더와 파일의 경로를 지정해주는 모듈 function traverseDirectory1(directory){ const stack = [directory]; // 순회해야 할 디렉토리를 저장할 스택 while (stack.length > 0) { // 스택이 빌 때까지 반복 const currentDir = stack.pop(); // 현재 디렉토리 const files = fs.readdirSync(currentDir); // 인자로 주어진 경로의 디렉토리에 있는 파일or디렉토리들 for (const file of files) { // 현재 디렉토리의 모든 파일or디렉토리 순회 const filePath = path.join(currentDir, file); //directory와 file을 하나의 경로로 합쳐줌 const fileStatus= fs.statSync(filePath); // 파일정보 얻기 if (fileStatus.isDirectory()) { // 해당 파일이 디렉토리라면 console.log('디렉토리:', filePath); stack.push(filePath); } else { // 해당 파일이 파일이라면 console.log('파일:', filePath); } } } } traverseDirectory1("."); // 현재 경로의 모든 하위 경로의 파일, 디렉토리 출력 기저조건 : 더 남아있는 directory가 없을때반복 : 인자로 주어진 경로의 디렉토리에 있는 파일or디렉토리들 순회 모르겠습니다
2025. 03. 16.
0
[인프런 워밍업 클럽_3기 CS] 2주차 운영체제 미션
FIFO 스케줄링의 장단점이 뭔가요?구현이 쉽고 직관적이지만, 타임 슬라이스가 큰 프로세스 차례가 되면 그 다음 프로세스가 언제 실행될지 장담할 수 없고 평균 대기시간이 커진다. SJF를 사용하기 어러운 이유가 뭔가요?짧은 프로세스를 먼저 실행하고자 하는 스케줄링인데, 어떤 프로세스가 짧을지 예측이 안되서 사용이 어렵다.또한 FIFO의 단점을 그대로 갖고 있다. RR 스케줄링에서 타임 슬라이스가 아주 작으면 어떤 문제가 발생할까요?컨텍스트 스위칭으로 인한 오버헤드가 너무 커져서 프로세스 처리량보다 많아진다. 운영체제가 MLFQ에서 CPU Bound Process와 I/O Bound Process를 어떻게 구분할까요?프로세스가 실행 중 스스로 cpu를 반납하면 cpu 사용이 적다는 뜻이니 i/o로 구분하고 타임 슬라이스를 오버하는 프로세스는 cpu bound로 구분한다. 공유자원이란무엇인가요?여러 개의 프로세스가 공유해서 사용하는 자원 교착상태에 빠질 수 있는 조건은 어떤 것들을 충족해야할까요?상호배제, 비선점, 점유와 대기, 원형 대기