블로그

승현

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

이번주 학습 내용DTO 사용하는 이유JPA를 이용해서 Entity를 조회 후 바로 클라이언트에 전달하는 것은 좋지 않다.왜 좋지 않을까?클라이언트에 불필요한 정보 포함Entity에는 테이블의 정보를 모두 가지고 있기 때문에 클라이언트 화면에 필요한 정보보다 더 많은 정보를 넘겨주게 되면 클라이언트에서도 해당 화면에 필요한 정보가 명확하게 무엇인지 어려워 유지보수 및 트래픽 부분에서도 이슈가 있을 수 있다.보안성Entity에 있는 정보를 모두 클라이언트에게 전달하게 되면, 노출되면 안되는 개인정보가 네트워크 트래픽상에 노출될 수 있어 보안 부분에서 이슈가 발생할 수 있다. Open-Session-In-View (OSIV) 문제스프링 JPA에서 영속성 컨텍스트에서 Entity 조회시 Controller까지 해당 Entity를 전달하게 되면 해당 영속성 컨텍스트의 트랜잭션이 종료되지 않기 때문에 개발자가 의도하지 않은 데이터의 변경이 발생할 수 있음. 그러면 비즈니스에 크리티컬한 부분이 되기에 open-session-iv-view 옵션을 false로 설정하고 서비스 단에서 DTO로 변환하여 전달하는 것이 좋다. 레포지토리 성능 개선스프링 JPA를 이용한 조회의 문제점 (N+1)단일 테이블 조회시에는 이슈가 없으나 연관된 Entity를 조회시에는 의도하지 않게 N+1의 쿼리를 실행하게 되는데, 데이터 개수가 적을때는 이슈가 없을 수 있으나 개수가 많아질 수록 N의 값이 커지기 때문에 성능 이슈가 발생할 수 있다. 어떻게 해결할 수 있을까?JPQL의 fetch join 사용 @Batchsize(size) 어노테이션 활용Lazy 로딩시 IN절로 조회되는 데이터의 사이즈를 지정할 수 있다.테스트 코드실무에서 테스트코드는 매우 중요하다.내가 변경한 곳은 1개의 라인일지라도 해당 라인의 영향도는 알 수 없기 때문이다. ( 프로젝트 규모에 따라 다르지만 ㅎㅎ )기존의 비즈니스 로직도 동일하게 동작하면서 내가 변경한 기능도 정확하게 동작하는지 확인하기 위해서는 배포하고 직접 화면을 확인하는 방법도 있지만 테스트 코드를 작성하면 코드 레벨에서 기능을 체크할 수 있다.테스트 코드 작성방법given - when - then테스트 코드 관련 어노테이션@DataJpaTest : 레포지토리 테스트Mockito 사용 : 단위 테스트에 사용@SpringbootTest 사용SpringbootTest는 스프링 컨테이너가 실행되어서 동작되므로 많은 테스트 코드 진행시 Mockito보다 속도가 느릴 수 있다.이번주 미션 진행[미션3] API 설계하기이번 미션은 API 설계였는데 Restful하게 설계하려니 고민되는 부분이 있었고, 무엇보다 문서 작성이 힘들었다.Github에서 관리하면 이력관리가 될 것 같아서 Github wiki에 정리하였는데 마크다운으로 작성하려니 직관적이지 않고, 반복되는 패턴들인데도 복사/붙여넣기 하는 과정이 있어 불필요하게 작성되는 느낌을 받았다.추후에는 Spring docs로 코드레벨에서 API 명세를 관리할 수 있게 개선 해야할 것 같다.회고멘토님께서 이번주 중간 점검 미팅때 QnA를 진솔하게 해주셔서 감사했다.JPA의 성능이슈에 대해서 고민하다가 이렇게 JPQL을 써야한다면 JPA만으로는 실무의 모든 쿼리를 대체할 수는 없을 것 같다. Mybatis + JPA의 구조를 택하는 이유도 네이티브 쿼리의 니즈가 있어서 아닐까 싶다.요즘 회사에서 MSA 프로젝트 유지보수를 맡게되어서 코드 분석을 빡세게 하고 있고, 퇴근 후에는 운동, 플러터 스터디도 같이 진행하고 있어서 주변에서 일정을 들으면 놀라긴 하는데, 새로운 것을 배우는 재미가 있어서 그런지 아직까지는 버티면서 할만 한 것 같다.

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

[인프런 워밍업 클럽 3기] PM/PO 2주차 발자국

학습 내용-고객 리서치를 하는 이유는 더 나은 의사결정을 하기 위해서임.-의사결정을 위한 리서치 설계1) '해야 할 의사결정' 정의하기2) '알아야 하는데 모르는 것' 정의하기3) 적합한 리서치 방법 계획하기4) 리서치 수행 계획 구체화하기 -심층 인터뷰의 용도1) 고객의 문제 확인 등2) 다양한 상황에 활용(기회 발견, 가설 확인, 문제나 니즈 확인)-심층 인터뷰의 한계1) 기억에 의존하여 얘기하므로 오랜 시간이 지날수록 틀린 이야기를 할 가능성 높음2) 솔직하게 이야기하지 않을 가능성 있음-인터뷰 인원10명에서 시작하여 의사결정에 필요한 충분한 지식을 획득했다고 판단되면 인터뷰 마치기-인터뷰 설계1) 사업 질문-> 리서치 질문-> 인터뷰 질문 순으로 만들기2) 구체적인 상황, 경험, 행동 질문3) 멘탈모델 파악하기-인터뷰 가이드 만들기 -사용성 테스트 하는 방법1) 성공적인 프로덕트의 조건: Valuable, Usable, Feasible, Viable2) 유저가 사용, 이해, 기능을 발견할 수 있는지 확인-사용성 테스트 시기1) 새로운 제품이나 기능을 만들 때, 앱 리디자인, 기존 기능 개선 시2) 엔지니어들이 작업하기 전-사용성 테스트 인원5명 정도면 충분, 여러 유저 그룹이 있는 경우 더 많은 인원 필요-사용성 테스트 방법1) 태스크와 질문을 섞기2) 오프라인, 원격, Unmoderated Test 등이 가능3) 녹화 -PM의 데이터 활용1) 현황 파악하기2) 패턴 찾아보기3) 미래 예측하기-크게 볼 때 아래와 같음1) 지표를 이용해 우리 사업의 현황을 한눈에 파악하기2) 데이터를 깊이 들여다 봐서 인사이트 찾기3) 실행하기 전에 타당성을 미리 평가하고, 우선순위를 세우기4) 실행한 후, 결과를 정량적으로 측정하고 평가하기5) 상관관계 찾아내기 -PM의 데이터 역량 쌓기1) 데이터 축적 관련 역량: 어떤 데이터를 축적할 것인지 정의하고, 그 데이터를 어떤 형태, 어떤 이름으로 축적할지 정의하기2) 데이터 활용 역량: 어떤 의사결정이 필요한지 정의, 의사결정을 잘하기 위해 어떤 데이터가 필요한지 정의, 데이터를 어떤 형태로 기록하면 좋을지 나중에 분석하는 상황을 상상-> 지표 이해하기, 데이터 분석 역량, 툴 사용 역량 회고PM으로서 고객과 데이터에 대해 어떻게 전문성을 쌓아야 하는지 배울 수 있는 한 주였다. 고객 리서치를 하는 목적은 의사결정을 하기 위함이므로 이 부분을 유념해서 전체 고객 리서치를 진행해야 함을 알게 되었다. 사업 질문-> 리서치 질문-> 인터뷰 질문 순으로 설계하는 부분이 인상적이었는데 단계별로 질문을 만들기 위해서는 많은 연습이 필요할 것 같다는 생각이 들었다. PM으로서 데이터 활용하는 것이 중요하다는 것은 많이 이야기를 들어왔는데 구체적으로 어떤 부분에서, 어떻게 활용할 수 있을지 알게 되어 좋았다. SQL의 중요성을 다시 한 번 깨달았고, PM의 역할이 데이터를 정의하는 것에서부터 시작한다는 것이 신기했다.

기획 · PM· POPMPO프로젝트매니저김민우

히히

[인프런 워밍업 클럽 3기] CS - 2주차 미션

[인프런 워밍업 클럽 3기 - CS 전공지식 스터디]의 2주차 미션 내용을 작성한 글입니다. 운영체제Q1. FIFO 스케줄링의 장단점이 뭔가요?A1. 장점: 구현이 매우 쉽고 단순하다.단점: 평균 대기 시간이 길어질 수 있다. Q2. SJF를 사용하기 여러운 이유가 뭔가요?A2.CPU 실행 시간을 미리 알기 어렵다. 가장 짧은 작업부터 처리하면 효율적이지만만, 실제 OS가 각 프로세스의 CPU 사용 시간을 정확히 알 수 없다. Q3. RR 스케줄링에서 타임 슬라이스가 아주 작으면 어떤 문제가 발생할까요?A3.아주 작은 타임 슬라이스로 인해, 프로세스가 실행되다가 Context Switching이 발생한다. 효율이 떨어지고 시스템 성능이 저하될 수 있다. Q4. 운영체제가 MLFQ에서 CPU Bound Process와 I/O Bound Process를 어떻게 구분할까요?A4.MLFQ에서는 타임 슬라이스 전부 소진하면 더 낮은 우선순위 큐로 내려간다.I/O Bound 프로세스는 CPU를 짧게 쓰고 자주 I/O를 수행하기 때문에, 상대적으로 높은 우선순위를 부여받고, CPU Bound 프로세스는 계속 CPU를 사용하려 하기 때문에, 낮은 우선순위로 내려간다. Q5. 공유자원이란무엇인가요?A5.여러 프로세스가 동시에 사용하거나, 사용하고 싶어 하는 자원 Q6. 교착상태에 빠질 수 있는 조건은 어떤 것들을 충족해야할까요?A6. 상호 배제, 점유 대기, 비선점, 환형 대기 자료구조와 알고리즘Q1. 재귀함수에서 기저조건을 만들지 않거나 잘못 설정했을 때 어떤 문제가 발생할 수 있나요?A1.무한 재귀가 일어나고, 결국 스택 오버플로가 발생하여 프로그램이 중단될 수 있다. Q2. 0부터 입력 n까지 홀수의 합을 더하는 재귀 함수를 만들어보세요.A2.function sumOdd(n){ if (n < 1) { return 0; } if (n % 2 !== 0) { return n + sumOdd(n - 1); } else { return sumOdd(n - 1); }} console.log(sumOdd(10)) // 25 Q3. 다음 코드는 매개변수로 주어진 파일 경로(.는 현재 디렉토리)에 있는 하위 모든 파일과 디렉토리를 출력하는 코드입니다.다음 코드를 재귀 함수를 이용하는 코드로 변경해보세요.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("."); // 현재 경로의 모든 하위 경로의 파일, 디렉토리 출력A4.function traverseDirectoryRecursive(directory) { const files = fs.readdirSync(directory); for (const file of files) { const filePath = path.join(directory, file); const fileStatus = fs.statSync(filePath); if (fileStatus.isDirectory()) { console.log("디렉토리:", filePath); traverseDirectoryRecursive(filePath); } else { console.log("파일:", filePath); } } }  

웹 개발인프런워밍업클럽인프런워밍업클럽3기CS

[워밍업 BE 프로젝트 3기] 2주차 발자국

 학습 2주차는 섹션 3 뒷부분부터 섹션 4까지 진행합니다. 모르는 부분 위주로 기록하며 학습했습니다. 데이터베이스 초기화하기스프링 건설 작업 이후 수행되는 데이터 초기화 기능 작성 리포지토리 개발 / 테스트 / 성능 개선 @DataJpaTest에는 @Transactional이 있어 메서드 하나마다 트랜잭션이 적용되며 종료 시 롤백됨@TestInstance를 적용하여 인스턴스의 라이프사이클 변경 가능for (i in 1..n) {} 같은 문법도 알게 됨N+1 문제 해결을 위해 JPQL로 직접 쿼리 지정default_batch_fetch_size 를 지정하여 페치 사이즈 지정 가능 컨트롤러 클래스 생성@RestController는 지정한 응답을 그대로 반환@Controller는 /resources/templates 하위의 html 파일을 반환 DTO 개발DTO 생성할 때 필터링을 수행함 -> 데이터 조회 쿼리에서 조건을 추가할 순 있지만, JPA 원칙상 지양해야 함 Presentation Layer 개발 / 테스트여러 서비스에서 레포지터리를 주입받다보면 관리가 복잡해짐 -> 필요한 레포지터리를 한번에 래핑해서 사용함 (퍼사드패턴)@Transactional(readOnly=true) → JPA에서 스냅샷 뜨고 비교하는 작업 생략테스트 시 모킹 인스턴스 주입 방식@InjectMocks -> 강의에서는 서비스 주입에 사용. @Mock으로 생성된 객체를 주입하여 실제 객체를 생성함@Mock -> 강의에서는 레포지터리 주입에 사용. 단순히 가짜 객체를 만듦lateinit -> 초기화를 늦춤@AutoConfigureMockMvc → 자동으로 MockMvc 관련 설정 추가  Thymeleaf 부트스트랩 템플릿 추가: 파일을 수정하여 사용할 부분 코드만 정리<div th:replace="~{presentation/fragments/fragment-navigation :: navigation}"></div> -> 해당 파일에서 아이디가 navigation인 컴포넌트를 찾아 로드 인터셉터 개발: HandlerInterceptor의 메서드를 오버라이딩preHandle: 컨트롤러까지 요청이 가기 전에 동작postHandle: 컨트롤러가 응답을 리턴한 이후에 동작 - 예외 시 동작 XafterCompletion: '' - 예외 시 동작 O  미션 1주차에 이어서 2주차 미션도 2가지입니다.Rest API 설계조회 API 만들기 API 문서는 사용해본 도구가 많이 없어서, Postman에서 제공하는 Documentation을 이용했습니다. 다 하고 뭐가 부족하다 싶었는데 응답을 설정하지 않았더라고요. 제출을 먼저 해버렸지만 Mock Server 같이 응답 폼을 미리 명시할 수 있는 방법을 더 찾아봐야겠습니다. 여기까지는 대부분 설계한 산출물을 제출하는 작업이었습니다. 하지만 바로 API를 하나 만들게 되면서 그동안 강의에서 배운 모든 작업이 필요했습니다.application.yml 설정레포지터리, 서비스, 컨트롤러 구현더미데이터 추가 클래스 구현 단순히 과제를 제출하는데 의의를 두었다면 조회 기능만 간단하게 구현했을 것 같습니다.하지만 저는 이번 워밍업을 하면서 그 전에 해보지 않았던 걸 해보며 한 단계 나아가는 경험을 하고 싶었습니다.그래서 강의에서 나왔던 더미데이터 추가, 테스트 코드 작성도 완료하여 제출하려고 합니다. 테스트 코드를 작성하면서 겪은 문제가 크게 2가지 있었습니다. (상세한 내용은 리드미에 작성할 예정입니다.)먼저 레포지터리를 추가할 수 없다는 문제를 맞았는데, 해결하며 문제와 관련해서 스프링에서 엔티티를 찾는 원리, 컴포넌트 스캔, ApplicationContext 등에 대해 찾아보게 되었습니다.두 번째로는 테이블을 생성하는 DDL이 자동으로 실행되면서 생긴 에러입니다. 생각보다 간단한 문제였고 테이블 이름을 지을 때 신중해야겠다고 느꼈습니다. 🥲 확실히 직접 해보면서 강의에서는 마주하지 않은 문제들을 해결해보니 더욱 흥미가 생겼고, 시간 가는 줄 모르게 작업한 것 같습니다.이제 절반 조금 넘게 달렸는데, 힘내서 꼭 완주하겠습니다. !! 

제갈진우

[인프런 워밍업 클럽 스터디 3기] PM 워밍업클럽 2주차 미션

고객 조사 계획: 비게임 산업 확장을 위한 고객 인사이트 조사 1. 조사 주제 설정목적비게임 산업(이커머스, 핀테크 등)에서 씽킹엔진(Thinking Engine)의 도입 가능성을 검토하고, 해당 산업에서 고객들이 겪는 데이터 분석 관련 문제를 심층적으로 이해하여 최적의 솔루션을 제안하는 것. 핵심 질문비게임 산업에서 데이터 분석이 중요한 이유는 무엇인가?현재 기업들이 사용하는 데이터 분석 도구의 한계점은 무엇인가?씽킹엔진이 해결할 수 있는 주요 Pain Point는 무엇인가? 2. 조사 대상 선정주요 타겟이커머스/핀테크 기업의 데이터 분석가, PM(Product Manager)BI(Business Intelligence) 및 데이터 엔지니어비즈니스 의사결정자(마케팅, 운영 담당자 등) 선정 기준월간 활성 사용자(MAU) 100만 이상 기업데이터 분석 도구(Amplitude, Mixpanel, Google Analytics 등)를 이미 사용 중이나 불만을 느끼는 고객데이터 기반 의사결정을 중요하게 여기는 기업 3. 조사 방법조사 방식1:1 심층 인터뷰주요 고객의 Pain Point를 깊이 이해하기 위한 정성적 접근.설문조사다양한 고객군을 대상으로 정량 데이터를 확보하여 주요 문제를 파악.사용성 테스트씽킹엔진 데모를 활용하여 실사용 피드백과 UX 개선점을 도출. 진행 프로세스1차 인터뷰: 15명의 주요 고객과 1:1 심층 인터뷰 진행 (온라인 또는 오프라인).설문조사: 100명을 대상으로 주요 Pain Point를 정량적으로 분석 (온라인 설문 도구 활용).사용성 테스트: 5명을 대상으로 씽킹엔진 데모를 제공하고 실사용 피드백 확보. 4. 인터뷰 질문 설계(1) 배경 질문현재 어떤 산업(이커머스, 핀테크 등)에서 일하고 계신가요?업무에서 데이터 분석이 얼마나 중요한 역할을 하나요? (2) 현재 사용 중인 데이터 분석 도구 및 한계3. 현재 사용 중인 데이터 분석 도구는 무엇인가요? (Amplitude, Mixpanel, Google Analytics 등)4. 기존 도구에서 불편함을 느끼는 점이 있나요?5. 특정 데이터를 분석할 때 가장 어려운 점은 무엇인가요?(3) 씽킹엔진의 활용 가능성6. 실시간 데이터 분석 기능이 필요하다고 생각하시나요?7. 현재 데이터 분석에서 가장 보완하고 싶은 기능은 무엇인가요?8. 데이터 분석 도구를 변경하거나 추가 도입하는 데 가장 중요한 요소는 무엇인가요? (비용, 학습 곡선, 기능 등)(4) 마무리 질문9. 데이터 분석 과정에서 가장 개선하고 싶은 점은 무엇인가요?10. 씽킹엔진 같은 새로운 분석 도구를 테스트해볼 의향이 있으신가요? 5. 기대 결과 및 활용 방안 산업별 Pain Point 분석이커머스, 핀테크 등 주요 산업군별 데이터 분석의 문제점과 요구사항을 정리하여 통찰력을 확보.고객 니즈 기반 제품 개선인터뷰와 설문조사 결과를 바탕으로 씽킹엔진의 기능 추가 및 개선 방향 설정.마케팅 전략 최적화도출된 Pain Point를 활용하여 비게임 산업 타겟 마케팅 메시지와 전략을 수립.시장 확장 가능성 검증비게임 산업에서 씽킹엔진의 도입 가능성과 시장 진입 전략에 대한 구체적인 데이터를 기반으로 의사결정. 인터뷰 질문지조사 목적: 비게임 산업에서 씽킹엔진의 도입 가능성과 고객의 Pain Point를 파악하기 위한 질문지.1. 배경 질문귀하의 회사는 어떤 산업(이커머스, 핀테크 등)에 속해 있나요?귀하의 업무에서 데이터 분석은 얼마나 중요한 역할을 하나요?데이터 분석 결과가 귀하의 의사결정에 얼마나 영향을 미칩니까?2. 현재 사용 중인 데이터 분석 도구 및 한계현재 사용 중인 데이터 분석 도구는 무엇인가요?해당 도구들에서 불편하거나 부족하다고 느끼는 점은 무엇인가요?데이터를 분석할 때 가장 자주 겪는 어려움은 무엇인가요?3. 씽킹엔진의 활용 가능성 및 니즈실시간 데이터 분석 기능이 필요하다고 생각하시나요?데이터 분석 도구에서 가장 보완되었으면 하는 기능은 무엇인가요?새로운 데이터 분석 도구를 도입할 때 가장 중요하게 고려하는 요소는 무엇인가요?4. 마무리 질문데이터 분석 과정에서 가장 개선하고 싶은 점은 무엇인가요?씽킹엔진 같은 새로운 분석 도구를 테스트해볼 의향이 있으신가요?추가로 하고 싶으신 말씀이나 의견이 있으신가요? 

기획 · PM· PO씽킹데이터워밍업클럽인프런PMPO

제갈진우

[인프런 워밍업 클럽 스터디 3기] PM 워밍업클럽 2주차 회고

학습 내용 요약이번 주차 강의에서는 PM이 고객과 데이터를 어떻게 다뤄야 하는지에 대해 배웠다. 고객과 직접 인터뷰하고 사용성을 테스트하는 것이 중요하며, 데이터를 통해 문제를 파악하고 해결책을 찾는 것이 핵심이었다. 단순히 지표 하나에 의존하지 않고, 여러 데이터를 종합적으로 분석하는 역량이 필요함을 다시금 깨달았다. 나의 회고데이터 분석가로서 PM 역할을 이해하고 학습하는 과정에서 가장 와닿았던 부분은 고객에 대한 전문가가 되는 것과 데이터를 통해 문제를 정의하고 해결하는 것이었다.현재 비게임 산업 확장을 고민하며 고객을 탐색하고 있는 상황에서, 강의에서 배운 고객 인터뷰와 사용성 테스트 방법론은 실무에서 바로 활용할 수 있는 인사이트를 제공했다. 특히, 고객 인터뷰를 할 때 열린 질문을 활용하고, 특정한 선택지로 유도하지 않는 것이 중요하다는 점이 인상적이었다. 실제로 고객과 대화를 하다 보면 원하는 방향으로 답변을 유도하고 싶은 유혹이 있는데, 이번 학습을 통해 그런 실수를 줄일 수 있을 것 같다. 미션 회고이번 미션은 고객 인터뷰 설계였는데, 실무에서도 고객사 인터뷰를 진행하고 있는 만큼 흥미롭게 접근할 수 있었다. 조사 주제를 설정하고, 인터뷰 대상을 정하며, 질문을 설계하는 과정에서 강의에서 배운 프레임워크를 적용해볼 수 있었다. 특히, 사업 질문 → 리서치 질문 → 인터뷰 질문으로 이어지는 논리적인 구조를 유지하는 것이 유용했다. 앞으로 실제 인터뷰를 진행할 때도 이런 방식을 적용해 볼 계획이다. 앞으로의 계획이번 학습을 통해 PM이 고객과 데이터를 어떻게 활용해야 하는지 더 깊이 이해하게 되었다. 현재 고민 중인 비게임 산업 확장과 신규 고객 확보 전략에도 이 개념들을 적용할 예정이다.고객 인터뷰를 활용하여 비게임 산업의 주요 니즈 파악데이터 네이밍 및 이벤트 정의 방식 개선 PM과 데이터 분석의 경계에서 균형을 찾고, 보다 효과적인 문제 해결 방안을 도출하는 것이 앞으로의 목표다. 이번 학습을 통해 그 방향성을 더 명확히 잡을 수 있었다.

기획 · PM· PO워밍업클럽회고2주차발자국PMPO인터뷰고객분석

zhzhdk257

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

해당 블로그의 발자국은 정보근님의 입문자를 위한 Spring Boot with Kotlin - 나만의 포트폴리오 사이트 만들기 강의 기반으로 작성하였습니다. 2주차 강의 내용 요약 Spring Data JPA Repositories스프링에서 제공하는 Spring Data JPA를 사용하면 인터페이스 상속만으로 기본적인 CRUD 기능 사용 가능 테스트 - 어노테이션@DataJpaTest : JPA 관련 테스트를 위한 설정 제공. 특히 JPA 엔티티, 리포지토리, 데이터베이스 컴포넌트를 테스트하기에 적합. 테스트 실행 시, 내장 데이터베이스를 설정하고 @Entity 및 @Repository 어노테이션이 부여된 클래스들을 검색하여 테스트 환경 설정.@TestInstance : 테스트 인스턴스의 라이프사이클 지정. 기본적으로 JUnit5는 각 @Test 메소드마다 새로운 테스트 인스턴스를 생성하지만 본 프로젝트에서는 @BeforeAll을 사용하여 모든 테스트 메소드에 공통적으로 적용될 작업을 한 번만 수행할 것이기 때문에 라이프사이클을 클래스 단위로 지정.@BeforeAll : 테스트 클래스 내의 모든 @Test 메소드 실행 전에 한 번 실행.@Autowired : 필드 주입 방식으로 의존성을 주입할 때 사용.@DisplayName : 테스트 클래스나 메소드의 이름 정의. 테스트 결과에서 각 메소드를 쉽고 빠르게 인지하기 위해 사용. FetchType엔티티에서 연관관계 매핑 시 설정 가능한 FetchType은 Eager와 Lazy가 있다. Lazy를 적용한다면 사용하지 않을 자식 데이터의 조회를 방지할 수 있다. 연관관계에 따라 기본값이 다르기 때문에 항상 fetch=FetchType.LAZY로 명시해주는 것이 좋다. Fetch JoinJPA에 의존하지 않고 직접 JPQL 쿼리를 보낸다. Join을 활용해 한번에 부모와 자식 데이터를 조회할 수 있다. 하지만 OneToMany, 또는 ManyToMany 관계의 자식 엔티티가 여러 개일 경우, 하나만 조인할 수 있다는 한계가 있다. Batch Fetch SizeIN 절을 사용해 여러 건의 데이터 한번에 조회. 1+N의 쿼리가 1+(N/batch_fetch_size) 정도의 수준으로 줄어든다. 하지만 DBMS에 따라 IN 절의 파라미터 개수 제한이 있기도 하고, 한 번에 많은 데이터를 불러오는 것은 애플리케이션이나 데이터베이스에 부담을 줄 수 있기 때문에 적절한 개수 설정이 필요. 클래스 생성 - 어노테이션@Controller : 컴포넌트 스캔의 대상이 되어 빈으로 등록. 컨트롤러 레이어에 해당함을 명시. SSR(서버 사이드 렌더링) 방식으로 웹 개발할 때 사용. 스프링 내부적으로 return된 문자열과 같은 이름을 갖는 html 파일을 찾아 클라이언트에게 응답. 파일의 경로나 확장자는 별도 옵션으로 지정가능@RestController : 컴포넌트 스캔의 대상이 되어 빈으로 등록. 컨트롤러 레이어에 해당함을 명시. CSR(클라이언트 사이드 렌더링) 방식으로 웹 개발을 하거나, 데이터의 처리만을 담당하는 API를 개발할 때 사용. return 값은 HTTP 응답 메시지의 Body에 들어간다. String 외의 리턴 타입을 정하면 HTTP 헤더 값 등 설정에 따라 JSON 등으로 변환하여 Body에 넣는다.@RequestMapping : HTTP 요청을 정의하는 역할. 클래스와 메소드에 붙일 수 있다. 이 때 클래스에 붙이면, 정의한 경로가 클래스 내부의 모든 메소드에 공통적으로 붙게 된다. PresentationApiController.test()는 “/api/test”의 경로를 가질 것이고, PresentationViewController.test()는 “/test”의 경로를 갖게 된다.@GetMapping : HTTP 프로토콜은 여러 메소드를 갖고 있는데 대표적으로 GET, POST, PUT, DELETE가 있다. @GetMapping 어노테이션은 @RequestMapping(method =[RequestMethod.GET])와 같다. “/api/test” 경로로 GET 요청을 했을 때 PortfolioApiController.test()가 호출. 만약 같은 경로로 POST 요청을 할 경우는 HTTP 상태 코드 중 405 Method Not Allowed 응답을 준다. controller 패키지레이어드 아키텍처에서 컨트롤러란 사용자의 요청이 진입하는 Entry Point 의미. 요청을 받아서 실질적으로 처리하는 역할을 하는 서비스 레이어로 넘겨주고, 서비스 레이어에서 처리한 결과를 응답하는 역할. 클라이언트와의 인터페이스만을 담당하기 때문에, 처리 로직 변경없이 API 명세만을 바꿀 경우 서비스는 그대로 두고 컨트롤러만 새로 만들면 클라이언트와의 인터페이스를 변경할 수 있다. 서비스 개발 - 어노테이션@Transactional : 트랜잭션을 간편하게 열고 닫을 수 있게 해준다.rollbackFor: 어떤 예외가 발생했을 때 롤백할지 정의readOnly: 읽기 전용 트랜잭션으로 설정. JPA를 사용할 경우 더티체킹 등을 수행하지 않게 해준다.isolation: 트랜잭션 고립 수준 정의 서비스 테스트 - 어노테이션@ExtendWith : JUnit 5에서 테스트 확장을 지원하는 어노테이션@InjectMocks : Mockito에서 테스트 대상이 되는 클래스에 인스턴스 주입@Mock : Mockito에서 Mock 객체를 생성할 때 사용 컨트롤러 테스트 - 어노테이션@SpringBootTest : Spring Boot 애플리케이션을 테스트하는 데 사용. 실제 애플리케이션과 유사한 환경을 구성해 테스트 실행 가능@AutoConfigureMockMVC : Spring MVC를 모의로 테스트하는 데 사용. MockMVC 객체가 자동으로 구성되어 컨트롤러를 모의로 테스트할 수 있다. 내부적으로 Spring Boot Test의 일부로 제공되며, MockMVC를 구성하고 테스트 환경을 적절하게 설정.+) Interceptor : 컨트롤러보다 앞단에서 동작하여 여러 컨트롤러의 요청을 공통적으로 처리하는 기능 회고개인적으로 바쁜 한주여서 강의를 듣는 것조차 좀 벅찼던 것 같다. 그렇지만 어쨌든 다 듣기는 했다!! 발자국을 쓰면서 다시 한번 개념을 정리하는 시간을 가질 수 있었다.그리고 역시 테스트 부분이 늘 어렵다. 강의를 들으며 클론코딩만 해보았는데 미션을 통해 스스로 테스트 코드를 짜는 연습을 반복해봐야 할 것 같다. 미션미션 3 ) REST API 설계하기미션2에서 완성한 사용자, 도서, 독서기록, 리뷰 테이블 별로 REST API를 설계해보았는데 솔직히 잘한건지 모르겠다. 간단한 CRUD를 설계하면 되는거라 크게 어렵지는 않았는데 직접 api를 개발해보아야 감이 잡힐 것 같다. 다음 미션도 곧바로 해봐야겠다.

백엔드인프런워밍업클럽

[인프런 워밍업 클럽 스터디 3기] CS - 2주차 발자국

2주차 학습 내용 정리 운영체제프로세스 동기화프로세스는 독립적으로 실행되기도 하지만, 다른 프로세스와 데이터를 주고받으며 통신하는 경우도 있다. 프로세스 간 통신은 여러 방식으로 이루어질 수 있다.프로세스 간 통신 방법한 컴퓨터 내에서의 통신파일을 이용한 방법: 여러 프로세스가 하나의 파일을 읽고 쓰며 통신파이프를 이용한 방법: 운영체제가 생성한 파이프를 통해 데이터 교환쓰레드를 이용한 방법: 한 프로세스 내 쓰레드들은 코드, 데이터, 힙 영역을 공유하므로 전역변수나 힙을 통해 통신 가능네트워크를 이용한 통신소켓 통신: 운영체제가 제공하는 소켓을 이용한 통신RPC(원격 프로시저 호출): 다른 컴퓨터에 있는 함수를 호출하는 방식공유자원과 동기화 문제프로세스 간 통신 시 공동으로 이용하는 변수나 파일을 공유자원이라고 한다. 여러 프로세스가 공유자원에 접근할 때 각 프로세스의 접근 순서에 따라 결과가 달라질 수 있다.컨텍스트 스위칭으로 인한 시분할 처리 때문에 어떤 프로세스가 먼저 실행될지 예측하기 어렵고, 이로 인해 연산 결과를 예측하기 힘든 동기화 문제가 발생한다.임계구역과 상호배제임계구역(Critical Section): 여러 프로세스가 동시에 사용하면 안 되는 영역상호배제(Mutual Exclusion) 메커니즘의 요구사항:임계영역에는 동시에 하나의 프로세스만 접근해야 함여러 요청이 있어도 하나의 프로세스만 접근 허용임계구역에 들어간 프로세스는 빠르게 나와야 함동기화 해결 방법세마포어(Semaphore)상호배제 메커니즘의 한 종류정수형 변수로 구현됨공유 자원의 개수에 따라 초기값 설정wait() 함수로 시작하고 signal() 함수로 종료단점: wait()와 signal() 함수를 잘못 사용할 경우 문제 발생모니터(Monitor)세마포어의 단점을 해결한 상호배제 메커니즘프로그래밍 언어 차원에서 지원하는 방법자바의 synchronized 키워드가 대표적 예시데드락(교착상태)데드락은 여러 프로세스가 서로 다른 프로세스의 작업이 끝나기를 기다리다가 아무도 작업을 진행하지 못하는 상태를 말한다.교착상태의 필요조건교착상태가 발생하기 위해서는 다음 4가지 조건이 모두 충족되어야 한다.상호배제: 한 프로세스가 자원을 점유하면 다른 프로세스와 공유할 수 없음비선점: 프로세스가 자원을 빼앗길 수 없음점유와 대기: 프로세스가 자원을 가진 상태에서 다른 자원을 기다림원형 대기: 점유와 대기 관계가 원형을 이룸데드락 해결 방법교착상태 회피(Deadlock avoidance)자원 할당 시 교착상태가 발생하지 않는 수준의 자원만 할당안정 상태(Safe state)와 불안정 상태(Unsafe state)로 구분은행원 알고리즘: 전체 자원과 프로세스의 최대요구자원을 고려해 자원 할당교착상태 검출 및 해결가벼운 교착상태 검출: 타이머를 이용일정 시간 동안 프로세스가 작업을 진행하지 않으면 교착상태로 간주체크포인트로 롤백하여 해결무거운 교착상태 검출: 자원 할당 그래프 이용프로세스들 간 자원 점유와 대기 관계를 그래프로 표현순환구조가 생기면 교착상태로 판단교착상태를 일으킨 프로세스를 강제종료하고 체크포인트로 롤백프로그래밍 언어와 프로세스프로그래밍 언어 유형컴파일 언어개발자가 작성한 코드를 컴파일 과정을 거쳐 기계어로 변환컴파일 과정에서 문법 오류 검사실행 속도가 빠름C, C++, C# 등이 해당인터프리터 언어코드를 한 줄씩 해석해 실행실행 시 오류가 발생할 수 있음컴파일 언어보다 속도가 느림JavaScript, Python, Ruby 등이 해당코드 실행 방식컴파일 방식전체 코드를 기계어로 변환 후 실행실행 전 타입/문법 검사로 안정성 확보빠른 실행 속도 (C, C++, Java 등)처리 과정: 코드 → 전처리기 → 컴파일러 → 어셈블러 → 링커 → 실행파일인터프리터 방식코드를 실행 시점에 한 줄씩 해석별도의 컴파일 과정 없음실행 속도는 상대적으로 느림 (JavaScript, Python, Ruby 등)프로세스의 메모리 구조프로세스는 네 가지 메모리 영역으로 구성된다.코드 영역: 실행할 코드가 저장된 영역데이터 영역: 전역변수나 배열이 저장되는 영역스택 영역: 지역변수, 함수 매개변수, 함수의 리턴 주소 등이 저장힙 영역: 동적 메모리 할당이 이루어지는 영역프로그램 실행 과정사용자가 프로그램 실행 → 운영체제가 프로세스 생성exe 파일의 코드와 데이터 영역을 프로세스의 해당 영역에 로드빈 스택과 힙 영역 할당PCB(Process Control Block) 생성하여 관리프로그램 카운터를 코드 영역의 첫 주소로 설정CPU 스케줄링에 따라 프로세스 실행메모리메모리의 종류와 특징레지스터가장 빠른 기억장소로 CPU 내에 존재휘발성 메모리CPU 비트(32비트/64비트)를 결정계산 시 메인메모리 값을 레지스터로 가져와 처리캐시레지스터와 메인메모리 사이의 중간 매개체필요할 것 같은 데이터를 미리 가져와 저장여러 레벨로 구성(L1, L2, L3)메인메모리(RAM)운영체제와 실행 중인 프로그램이 올라가는 공간휘발성 메모리HDD/SSD보다 빠르지만 비싸서 실행 중인 프로그램만 저장보조저장장치(HDD, SSD)비휘발성 메모리가격이 저렴하고 용량이 큼데이터 영구 저장에 적합메모리 주소물리 주소: 실제 메모리의 위치(하드웨어 관점)논리 주소: 사용자 관점에서의 주소절대 주소: 메모리 관리자가 바라본 실제 프로그램 위치상대 주소: 컴파일러가 0번지로 가정한 주소메모리 관리 방식유니프로그래밍 환경메모리 오버레이: 큰 프로그램을 작게 나눠 일부만 실행멀티프로그래밍 환경가변 분할 방식프로세스 크기에 따라 메모리 할당장점: 내부 단편화가 없음단점: 외부 단편화 발생고정 분할 방식정해진 크기로 메모리 분할장점: 구현이 간단하고 오버헤드가 적음단점: 내부 단편화 발생버디 시스템2의 승수로 메모리 분할장점: 가변/고정 분할 방식의 단점 최소화외부 단편화 방지에 용이하며, 내부 단편화도 최소화자료구조와 알고리즘재귀(Recursion)재귀는 어떠한 것을 정의할 때 자기 자신을 참조하는 방식이다. 재귀 함수는 자기 자신을 호출하는 함수로, 반드시 탈출조건(기저조건)이 있어야 한다.재귀 함수의 특징콜스택에 함수 호출이 쌓임(FILO 구조)탈출조건이 없으면 스택 오버플로우 발생구현 시 자기 자신이 이미 구현되어 있다고 가정하면 쉽게 작성 가능재귀적 사고 패턴단순 반복 실행: 성능은 for문보다 떨어짐하위 문제 결과 기반 계산: 팩토리얼 같은 문제에 적합하향식 계산: 재귀를 통해 큰 문제를 작은 문제로 분할하여 해결상향식 계산: for문이나 재귀로 작은 문제부터 해결하여 큰 문제 해결하노이 탑재귀 함수의 대표적인 예시로, 하향식 계산의 좋은 사례입니다.세 개의 기둥과 크기가 다른 원반들로 구성규칙: 한 번에 하나의 원반만 이동, 작은 원반 위에 큰 원반이 올 수 없음하위 문제로 분할하여 해결정렬 알고리즘버블 정렬(Bubble Sort)가장 간단한 정렬 알고리즘 중 하나로, 인접한 두 요소를 비교하여 정렬한다.특징구현이 매우 간단함성능은 O(n²)으로 좋지 않음매 반복마다 가장 큰 요소가 마지막으로 이동선택 정렬(Selection Sort)정렬되지 않은 영역에서 최솟값(또는 최댓값)을 찾아 정렬된 영역의 끝에 배치하는 알고리즘이다.특징구현이 간단함성능은 O(n²)으로 좋지 않음정렬된 영역과 정렬되지 않은 영역으로 구분하여 처리두 정렬 알고리즘 모두 이해와 구현은 쉽지만, 대용량 데이터나 성능이 중요한 경우에는 더 효율적인 정렬 알고리즘을 사용하는 것이 좋다. 벌써 2주차가 지나갔다. 이번주에 강의를 몰아듣게 되어 학습 후에 머리속에 정리가 되지 않았는데 발자국을 작성하며 학습정리에 도움이 된거 같다. 남은 기간은 미리 강의를 듣고 미리 잘 정리해두도록 해야겠다.  참고 출처https://www.inflearn.com/course/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B8%B0%EB%B3%B8https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C

구탱

인프런 워밍업 클럽 스터디 3기 - CS 전공지식 (운영체제, 자료구조, 알고리즘) 미션

운영체제 2주차 과제 FIFO 스케줄링의 장단점이 뭔가요?-> 장점은 구현이 쉽다는 것이고 단점은 앞에 긴작업이 있으면 뒤에서 오래 기다려야 합니다.SJF를 사용하기 여러운 이유가 뭔가요?-> 실행시간을 예측하기가 어렵고 계산의 정확도가 떨어지기 때문입니다.RR 스케줄링에서 타임 슬라이스가 아주 작으면 어떤 문제가 발생할까요?-> 오버헤드가 커져서 프로세스가 실행되는 것보다 전환되는 시간이 더 오래걸릴 수 있습니다.운영체제가 MLFQ에서 CPU Bound Process와 I/O Bound Process를 어떻게 구분할까요?-> CPU Bound Process는 낮은 우선순위의 큐로 이동되고, I/O Bound 프로세스는 실행을 일찍하고 높은 우선순위를 유지합니다.공유자원이란무엇인가요?-> 여러 프로세스들이 모두 사용할 수 있는 자원이고 경쟁이 발생할 수 있습니다.교착상태에 빠질 수 있는 조건은 어떤 것들을 충족해야할까요?-> 상호배제와 비선점, 점유와 대기, 원형대기가 필요조건이다. 알고리즘 2주차 과제 재귀함수에서 기저조건을 만들지 않거나 잘못 설정했을 때 어떤 문제가 발생할 수 있나요?-> 기저조건이 없거나 설정이 잘못되면 재귀가 무한으로 반복됩니다. 또한 함수가 종료되지 않고 계속 호출되어서 오버플로우가 발생하며 프로그램이 정상적으로 작동되지 않는 문제가 발생합니다.0부터 입력 n까지 홀수의 합을 더하는 재귀 함수를 만들어보세요.function sumOdd(n) { // 재귀 로직 if(n<=0) return 0; return (n%2 !==0 ? n : 0) + sumOdd(n-1); } console.log(sumOdd(10));다음 코드는 매개변수로 주어진 파일 경로(.는 현재 디렉토리)에 있는 하위 모든 파일과 디렉토리를 출력하는 코드입니다. 다음 코드를 재귀 함수를 이용하는 코드로 변경해보세요.const fs = require("fs"); // 파일을 이용하는 모듈 const path = require("path"); // 폴더와 파일의 경로를 지정해주는 모듈 function traverseDirectory1(directory) { const files = fs.readdirSync(directory); // 디렉토리의 파일 목록 불러오기 for (const file of files) { const filePath = path.join(directory, file); const fileStatus = fs.statSync(filePath); if (fileStatus.isDirectory()) { console.log('디렉토리:', filePath); traverseDirectory(filePath); // 디렉토리인 경우에는 재귀 호출 } else { console.log('파일:', filePath); } } } traverseDirectory1("."); 

이진희

[인프런 워밍업 스터디 클럽 3기 FE] 2주차 발자국

강의 수강따라하며 배우는 자바스크립트 A-Zhttps://www.inflearn.com/course/따라하는-리액트 일주일 동안 학습했던 내용자바스크립트의 심볼, 제너레이터, 이터레이터, 디자인패턴에 대한 강의를 들었다.리액트의 함수형, 클래스형 컴포넌트에 대한 강의를 들었고아직 리액트로 투두 앱을 만드는 중이다..! 회고자소서를 써야해서 시간을 많이 투자 못했지만, 포기하기 않고 강의를 지속해서 수강하고 있는 모습에 스스로를 칭찬하고 싶다!!!리액트 강의를 들으며 스위프트랑 비슷한 부분이 있어서 보다 쉽게 이해됐던 것 같다.프론트 공부를 하기 전에 여기저기서 들어왔던 용어들에 대한 개념을 잡아서 뿌듯했다.이번주는 할 일이 많아 과제를 하지 못했지만, 다음주에는 더 시간을 투자해서 과제로 더 공부할 계획이다!다시보려고 기록해둔 강의를 한 번 더 들어야겠다..!  강의 수강하면서 에러 해결했던 부분도 같이 남긴다.에러1. tailwind 설치 오류npx tailwindcss init 에러참고https://www.inflearn.com/community/questions/1521720/npx-tailwindcss-init-가-안되네요?srsltid=AfmBOoo0xfLbGznadNCzcvvkOub_g89qM3Pkk-EcselgEG1h4qrZrZSM해결 명령어 (터미널 입력)npm install -D tailwindcss@3 postcss autoprefixernpx tailwindcss init 에러2. 리액트 실행 오류에러 일부 발췌opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error', 'error:0308010C:digital envelope routines::unsupported' ], 참고 블로그https://velog.io/@rcg0529/ErrorReact실행오류-error03000086digital-envelope-routinesinitialization-error해결 명령어 (터미널 입력)export NODE_OPTIONS=--openssl-legacy-provider

프론트엔드

yeajinny

[워밍업 클럽 CS 3기] 2주차 발자국

운영체제프로세스 간 통신→ 한 컴퓨터내에서 파일과 파이프를 이용해서 통신, 쓰레드 통신, 네트워크 통신(소켓, RPC)→ 공유 자원이란 프로세스가 같이 이용하는 파일, 변수→ 공유 자원으로 인해 동기화 문제 발생 공유자원과 임계구역→ 임계구역 : 여러 프로세스가 동시에 사용할 수 없는 구역→ 경쟁조건 : 공유자원을 사용하기 위한 프로세스간 경쟁→ 임계구역 문제 해결을 위한 상호배제 매커니즘 상호배제 메커니즘 → 한번에 한 프로세스만 임계영역에 접근 가능, 대신 프로세스는 빠르게 나와야함.→ 컨텍스트 스위칭: 운영체제가 현재 작업을 멈추고 다른 작업으로 전환 세마포어(상호배제 매커니즘)→ 임계구역에 접근할 수 있는 권한 (여러개 존재 가능)→ 장점: 동기화 문제 해결→ 단점: 세마포어를 요청 또는 반납 하는 순서가 핵심, 모니터로 해결 가능모니터(프로그래밍 언어로 해결)→ 예시: JAVA에서 synchronized가 붙어있으면 동시에 여러 프로세스에서 실행시킬 수 없음→ 이런식으로 컨트롤하는 것이 모니터 데드락→ 프로세스들이 서로 작업 끝내길 기다리다가 아무도 작업을 하지 못하는 상태→ 발생이유: 공유 자원 데드락 예시: 식사하는 철학자→ 포크3개 철학자 3개 (포크가 2개 있어야 식사 가능) 교착 상태의 필요조건→ 상호 배제 : 한 프로세스가 리소스를 점유했다면 그 리소스는 공유되어선 X (포크)→ 비선점: A가 점유한다면 B는 뺏을 수 없다→ 점유와 대기: 프로세스가 A를 갖고 B를 대기해야…→ 원형 대기: 점유, 대기하는 관계가 원형 데드락 해결→ 교착 상태 회피: 교착 상태가 발생하지 않는 수준의 자원 할당→ 최대한 안정상태로 갈수있게, 불안정 상태는 교착 상황이 발생할 확률이 높음 은행원 알고리즘→ 여윳돈과 대출 금액을 보고 안정상황인지 확인하고 돈을 빌려줌 알고리즘 구현→ 운영체제는 시스템의 총 자원을 알아야함→ 프로세스는 최대 요구 자원을 운영체제에게 알려줘야함→ 은행원 알고리즘은 비효율적이고 비용이 많이 든다교착상태는 허용, 그러나 해결할 수 있도록 검출 방법→ 가벼운 교착 상태 검출 (프로세스가 작업을 진행하지 않는다면 교착)→ 무거운 교착 상태 검출 (프로세스가 그래프로 어떤 자원 사용하는지 살펴보고 교착 상태 파악) 컴파일과 프로세스→ 컴파일 언어→ 개발자가 코드 작성, 컴파일 되고 실행파일을 만듦→ 컴파일하면서 오류 검사, 기계어로 실행 파일을 만들기 때문에 속도가 빠름 (C, C++, C#) →인터프리터 언어→ 실행시 코드를 한줄씩 실행해봄(JS, Ruby, Python)→ 프로세스 내에는 코드, 데이터,힙(동적 메모리 할당), 스택(지역변수, 매개변수, 함수 리턴주소) 전처리기 (전처리 구문 처리, #include, #define, 주석 제거)컴파일러 (기계어에 가까운 어셈블리어로 만든다)어셈블러(오브젝트 파일로 변환시킴, 0과1로 구성)링커(오브젝트 파일을 실행 파일로)실행 파일( 완벽한 상태의 코드 영역, 데이터 영역 구성) 메모리레지스터→ 가장 빠름, CPU내에 존재→ 컴퓨터 꺼지면 날아가서 휘발성 메모리(34bit, 64bit)→ CPU는 계산 할때 메인 메모리에 있는 값을 레지스터로 가져와 계산하고 다시 메인메모리에 저장 램(메인메모리)→ 레지스터와 메인 메모리 사이에 캐시→ 운영체제, 프로세스가 올라가는 공간 (휘발성) 보조저장장치→ 가격이 저렴해서 오래 저장 가능 (전원 공급 필요 없음, 비휘발성) 캐시→ 메인메모리에서 필요한 데이터는 미리 가져와 캐시에 저장→ 단계 별로 L1, L2,… 없으면 메인 메모리를 살펴봄 메인 메모리→ 운영체제는 메모리 관리를 위해 1바이트 크기로 구역을 나누고 주소 매김→ 32bit는 버스의 크기도 32 bit, 2에 32승으로 메모리도 4GB  물리 주소 공간→ 메모리를 컴퓨터에 연결했을때 0x0번지부터 시작하는 주소 공간논리 주소 공간→ 사용자 관점에서 바라본 공간 경계 레지스터메모리 관리자가 프로세스가 경계 레지스터를 벗어났는지 검사하고 벗어났다면 프로세스 종료 절대 주소(물리 주소 공간), 상대 주소(논리 주소 공간)→ 컴파일러는 0x0번지라고 생각(상대 주소), 실제 주소는 0x4000번지(메모리 관리자가 보는 절대 주소) 메모리 할당 방식→ 메모리 오버레이란 프로세스를 잘라 당장 필요한 부분만 메모리에 올리고 나머지는 하드디스크에 가변 분할 방식(연속 메모리 할당, 세그멘테이션)→ 프로세스의 크기에 따라 메모리를 나눔 고정 분할 방식(비연속 메모리 할당)→ 프로세스 크기 상관없이 메모리를 나눔오늘날에는 둘을 혼합하고 있음 버디 시스템(2의 승수로 메모리를 할당)-> 메모리 공간 확보가 간단-> 내부 단편화가 발생, 많이 낭비되지는 않음 자료구조와 알고리즘재귀→ 어떤 것을 정의할 때 자기 자신을 참조하는 것 콜스택→ 메모리 공간이 가득차서 자동 종료→ 함수가 호출되면서 올라가는 메모리 영역 (스택)→ FILO→ 재귀 함수가 for문보다 메모리를 더 많이 씀→ 문제를 더 쉽게 해결하려고 씀 (예: 팩토리얼)재귀함수는 탈출 조건(기저 조건) 필수특정 조건이 나오면 알아서 종료가 되어야 함 재귀의 패턴→ 단순 반복 실행을 재귀로 (성능은 좋지 않음)→ 하위 문제의 결과를 기반으로 현재 문제를 계산(팩토리얼)→ for문은 상향식 계산, 재귀는 하향식 계산(하위 문제의 결과를 기반으로 현재 문제를 계산)→ 상향식은 for문과 재귀 둘다 구현 가능, 하향식은 오로지 재귀로만하노이탑→ 하향식 문제의 예시→ 원반 2,1을 기둥B로 옮기는 것이 하위 문제→ 원반 1을 기둥c로 옮기는 것이 마지막 하위 문제 버블 정렬→ 앞에 있는 숫자와 옆에 있는 숫자를 비교해서 자리를 바꿈→ BIG-O는 O(N2) 선택 정렬→ 첫번째부터 마지막까지 비교 후 가장 작은 값을 첫번째로→ 정렬된 영역, 정렬되지 않은 영역으로 구분해서 정렬→ BIG-O는 O(N2)→ 버블 선택 모두 직관적이고 이해하기 쉬우나 성능이 나쁨칭찬할 점: 예습을 좀 했습니다. 확실히 강의 내용이 머리에 더 잘 들어오는 것 같아요.보완할 점: 재귀의 기저조건 찾는걸 잘 못하는 것 같아요. 재귀 원리는 이해가 되는데 기저 조건을 1인지 0인지 if문 2개로 해야할지..이런게 자꾸 어려워서 더 공부해야 할 것 같습니다.다음 주 목표: 백준에서 재귀랑 정렬문제 각각 10개 이상씩 풀고 오전에는 예습, 저녁에는 강의 듣는 것이 목표입니다.

CS워밍업클럽

김보민

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

인프런 워밍업 클럽 본격적으로 실습에 들어가게 되는 주였다.또 온라인 라이브도 있었다. ✅ 강의2주차 강의부터는 본격적으로 프로젝트를 구현하는 내용이었다.repository를 개발하고 테스트 코드도 작성해보며 성능 개선까지 해보았다.서비스와 컨트롤러도 개발하여 API를 만들고 직접 확인해보았다. 또한 테스트 코드도 작성하였다.Thymeleaf를 활용해 화면단의 템플릿을 부트스트랩을 통해 가져오고 수정하여 프로젝트에 맞게 구현하였다.컨트롤러의 앞단에서 동작하는 인터셉터를 구현하였다. ✅ 미션2주차 미션은 미션3, 4 두가지 였다.(마감기준보다는 시작기준으로..ㅎㅎ)[미션3] REST API 설계하기[미션4] 조회 REST API 만들기[미션3]은 내가 미니 프로젝트로 하기로 결정한 플레이리스트 공유 프로젝트에서 사용될 간단한 CRUD를 예상하고 API를 설계해서 제출했다.고민 포인트가 하나 있었다면, 플레이리스트 생성할 때 필연적으로 음원 목록들의 id가 배열로 들어갈 것이기 때문에 음원 목록 조회까지 잊지 말아야했다는 점이다. 또 사용자 본인만의 플레이리스트를 조회하고 싶은 니즈가 있을 것이고, 전체의 모든 플레이리스트를 보고 싶은 니즈가 있을 것 같아서 조회 API를 두 개 둬봤다. 문서는 Postman documentation을 활용해 제출했다. ㅎㅎ [미션4]는 발자국을 작성하는 지금 시점에서 아직 다 마치지는 못했다. 플레이리스트 조회의 경우 강의에서처럼 데이터베이스 초기화 코드를 통해 임의로 넣어서 테스트 해볼 수 있겠지만, 뭔가 직접 CRUD를 완성한 뒤 조회하고 싶었다. 그래서 이번 조회 API 과제에서는 음원 목록을 조회하는 API를 먼저 다루는 것으로 결정했다. 여기서 음원 목록을 어떻게 다룰것이냐라는 고민도 있었는데, 음원은 어딘가의 오픈 API로 끌어오거나 크롤링으로 가져오면 베스트일 것 같았다. 하지만 이번에는 그렇게까지는 하지 않고 간단하게 xml 파일에 음원 목록을 몇개 정리해서 데이터베이스 초기화 코드에서 읽고 넣어주는 것으로 결정했다. xml 파일은 gpt의 도움을 받았다 ㅎㅎ 간단하게 jackson-dataformat-xml을 사용해서 다음과 같이 코드를 작성했다.  // track 초기화 - xml 파일로 데이터 추가 val xmlMapper = XmlMapper() val inputStream = javaClass.getResourceAsStream("/track-data.xml") ?: throw IllegalStateException("track-data.xml not found") val tracks = xmlMapper.readValue<List<Track>>(inputStream) trackRepository.saveAll(tracks)    스프링 애플리케이션 실행 후 결과를 확인해보면 다음과 같이 데이터가 잘 등록된 것을 확인할 수 있었다. 마지막으로 음원 목록 조회 API 코드까지 완성 후 포스트맨으로 테스트한 결과이다. 이제 남은 건 테스트 코드 작성이다...! 빨리 마무리하고 미션 제출해야겠다....🏃‍♂ 🍀 마무리확실히 강의를 들으면서 프로젝트를 따라가는 것과, 내가 생각하는 프로젝트에 적용해보는 것은 확연히 달랐다. 강의를 들으면서 할 때는 술술 넘어가던 부분이 혼자 프로젝트에 적용해보려고 하니 또 기억이 안나고, 잘 안되기도 했다..! 그래서 이 워밍업 클럽을 통해 강의 + 나만의 프로젝트를 해볼 수 있어서 참 좋고 얻어가는게 많을 것 같다. 다음주도 화이팅!!  

이지민

인프런 워밍업 클럽 CS 3기 2주차 미션 (운영체제)

운영체제FIFO 스케줄링의 장단점이 뭔가요?장점: - 먼저 온 프로세스가 먼저 CPU를 사용하는 First In First Out의 구조를 가지기 때문에 단순하고 직관적입니다.단점: - 현재 실행 중인 프로세스가 완전히 끝나야 다음 프로세스가 실행되기 때문에 먼저 도착한 실행시간이 긴 프로세스가 완료될 때까지 기다려야 하는 Convoy effect(호위 효과)가 일어날 수 있습니다.- FIFO 스케줄링은 비선점의 특징을 가지기 때문에 실행 중인 프로세스가 CPU를 스스로 포기하지 않는 한 강제로 CPU를 뺏을 수 없습니다.- 만약 CPU를 사용하는 프로세스가 I/O 작업을 진행하고 있다면 CPU는 쉬고 있는 상태가 되기 때문에 CPU 사용률이 좋지 않습니다.SJF를 사용하기 여러운 이유가 뭔가요?- 프로세스의 종료시간을 예측하는 것은 거의 불가능하기 때문입니다.- Burst Time이 긴 프로세스는 실행 순위가 계속 뒤로 밀려 아주 오랫동안 실행되지 않을 수 있습니다. RR 스케줄링에서 타임 슬라이스가 아주 작으면 어떤 문제가 발생할까요?- 타임 슬라이스를 너무 작게 설정하면 컨텍스트 스위칭이 너무 자주 일어나게 되어 오버헤드가 커지게 됩니다. 운영체제가 MLFQ에서 CPU Bound Process와 I/O Bound Process를 어떻게 구분할까요?- CPU를 사용하는 프로세스가 타임 슬라이스 전에 CPU를 스스로 반납한다면 운영체제는 이 프로세스의 CPU 사용량이 적으므로 I/O Bound Process일 가능성이 높다고 판단합니다.- 반대로 CPU를 사용하는 프로세스가 타임 슬라이스를 오버하여 CPU 스케줄러에 의해 강제로 CPU를 뺏긴다면 운영체제는 이 프로세스의 CPU 사용량이 높으므로 CPU Bound Process일 가능성이 높다고 판단합니다. 공유자원이란무엇인가요?- 프로세스/쓰레드 간 통신을 할 때 여러 프로세스/쓰레드가 공동으로 이용하는 자원(메모리, 변수, 파일, 데이터 등…)을 ‘공유자원’이라고 합니다. 교착상태에 빠질 수 있는 조건은 어떤 것들을 충족해야할까요?- 교착상태의 필요조건으로는 4가지가 있습니다.- 상호 배제어떤 프로세스/쓰레드가 한 리소스를 점유했다면 그 리소스를 사용하는 동안 다른 프로세스에게 공유되면 안됨식사하는 철학자에서 포크가 리소스에 해당합니다.- 비선점프로세스/쓰레드 A가 리소스를 점유하고 있는데 프로세스/쓰레드 B가 그 리소스를 빼앗을 수 없어야 함식사하는 철학자에서 철학자 A가 들고 있는 포크를 철학자 B가 뺏을 수 없는 상황에 해당합니다.- 점유와 대기어떤 프로세스/쓰레드가 리소스를 가지고 있는 상태에서 추가적인 리소스를 원하지만 추가 리소스를 사용할 수 없어 대기하는 상태식사하는 철학자에서 오른쪽 포크를 손에 쥔 채로 왼쪽 포크를 기다리는 상태를 의미합니다.- 원형 대기점유와 대기를 하는 프로세스/쓰레들의 관계가 원형(순환 구조)을 이루며, 각 프로세스가 다음 프로세스가 보유한 리소스를 기다리는 상황.식사하는 철학자에서 서로가 서로의 포크를 원하는 원형(순환 구조)를 이루는 상황에 해당합니다.

[워밍업 클럽 3기 BE code] 2주차

테스트가 필요한 이유사람이 애플리케이션을 실행하면서 잘 작동되는지 확인하는 작업은 놓칠 수도 있고, 시간이 오래 걸려 비효율적이다.테스트 코드 작성의 이점빠른 피드백: 코드 수정 후 바로 검증 가능자동화: 반복적인 수동 테스트가 불필요안정성: 코드 변경이 발생해도 기존 기능이 정상 동작하는지 보장디버깅 용이: 문제 발생 시 원인 파악이 쉬움단위 테스트작은 코드 단위를 독립적으로 검증하는 테스트 → 검증 속도가 빠르고 안정적이다.관련 라이브러리JUnit5: 단위 테스트를 위한 테스트 프레임워크AssertJ: 테스트 코드 작성을 원활하게 돕는 라이브러리수동 테스트 vs 자동화된 테스트 비교수동 테스트 사람이 직접 성공/실패를 판단실수 가능성 높음반복이 어려움시간이 오래 걸림자동화된 테스트 시스템이 자동으로 판단 실수 가능성 낮음반복이 쉬움소요 시간이 짧음 자동화된 테스트를 활용하면 수동 테스트의 한계를 극복할 수 있다.자동화 테스트를 작성하면 테스트 결과만 확인하면 되므로 빠르고 정확하다.테스트 케이스 세분화하기해피 케이스(정상 동작)*만 작성하지 않고 예외 케이스(예상하지 못한 상황)도 함께 테스트해야 한다.TDD (Test Driven Development)프로덕션 코드보다 테스트 코드를 먼저 작성하여, 테스트가 구현 과정을 주도하도록 하는 개발 방법론빠른 피드백을 통해 코드 품질을 높이고, 유연한 설계를 가능하게 함TDD의 장점내 코드의 피드백을 빠르게 받을 수 있음리팩토링이 쉬워짐 → 테스트가 있으므로 기존 기능이 정상 동작하는지 보장됨테스트 가능한 코드 설계 → 단일 책임 원칙(SRP)에 맞게 코드 구조를 고민하게 됨디버깅 시간 단축 → 기능 개발 중 발생하는 문제를 사전에 방지할 수 있음기능 구현 방식 비교방식 장점 단점 선 기능 구현, 후 테스트 작성 장점 : 구현이 직관적이고 빠르게 가능 단점 : 테스트 누락 가능성, 특정 케이스만 검증, 잘못된 구현 발견 지연   선 테스트 작성, 후 기능 구현 (TDD) 장점 : 테스트가 어려운 영역을 미리 발견하여 설계를 개선할 수 있음 단점 : 초기 개발 속도가 다소 느릴 수 있음TDD의 핵심 원칙: Red → Green → Refactor1⃣ Red (실패하는 테스트 작성)테스트 코드를 먼저 작성하고 실행 → 아직 기능이 없으므로 테스트가 실패해야 한다.2⃣ Green (기능 구현하여 테스트 통과)테스트가 통과하도록 최소한의 기능을 구현한다.3⃣ Refactor (리팩토링)중복 제거, 코드 개선을 통해 더 나은 구조로 변경한다.리팩토링 후에도 테스트가 통과하는지 확인한다.테스트는 [문서]다테스트 코드는 해당 기능의 동작을 설명하는 문서 역할을 한다.@DisplayName을 활용하여 테스트 목적을 명확히 하자.@DisplayName("회원 가입 시 이메일이 중복되면 예외가 발생한다") @Test void 회원가입_이메일중복_예외발생() { // Given // When // Then }생각 정리테스트의 중요성에 대해서는 인지하고 있었지만 테스트 코드 작성이 항상 귀찮고 어렵게 느껴졌었다. 하지만 테스트 코드를 작성하고 결과를 확인하는 과정 자체가 더 나은 프로덕션 코드를 만드는 과정이 될 수 있다는 것을 깨달았다. 특히 TDD의 경우에는 기능이 없는데 테스트 코드를 먼저 작성하는게 이해가 안 됐었는데 테스트를 통과하는 최소한의 기능을 먼저 만들고 점진적으로 더 나은 코드 작성 및 설계를 할 수 있도록 유도하는 과정이라는 것을 알게 되었다. 강의https://www.inflearn.com/course/practical-testing-%EC%8B%A4%EC%9A%A9%EC%A0%81%EC%9D%B8-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B0%80%EC%9D%B4%EB%93%9C/dashboard

언니복이

백엔드 코틀린 개발하기 2주차 모르는 개념 정리

Domain 개발하기데이터 초기화@Component // 스프링 빈으로 등록어떤 클래스를 빈으로 등록할지 알려주는 어노테이션📌 @Component란?@Component는 Spring Framework에서 빈(Bean)으로 등록하기 위한 기본적인 애너테이션입니다.즉, Spring이 해당 클래스를 자동으로 스프링 컨테이너(IOC 컨테이너)에 등록하도록 해줍니다.🚀 @Component 사용 방법@Component class MyService { fun doSomething() { println("MyService is working!") } } @Component를 사용하면 MyService 클래스가 Spring Bean으로 등록됨.다른 곳에서 @Autowired 또는 생성자 주입을 통해 사용할 수 있음.@Service class SomeClass(private val myService: MyService) { fun execute() { myService.doSomething() } } SomeClass에서 MyService를 자동으로 주입받아 사용 가능  🎯 @Component vs 기타 빈 애너테이션Spring에서는 @Component 외에도 특정한 목적에 맞는 다른 애너테이션들이 있습니다.애너테이션 설명 @Component 가장 기본적인 빈 등록 애너테이션 @Service 비즈니스 로직을 처리하는 클래스에 사용 @Repository 데이터베이스 작업(DAO, Repository)에 사용 @Controller Spring MVC 컨트롤러(웹 요청 처리)에 사용💡 실제 동작은 동일하지만, 역할에 맞게 애너테이션을 사용하는 것이 가독성과 유지보수성을 높이는 데 도움이 됩니다.📌 @Component를 어디서 쓰면 좋을까?✅ 사용하면 좋은 경우특정한 역할이 없는 일반적인 Bean을 만들 때 (Utility Class, Helper, Config)다른 서비스, 레포지토리와는 다르게 특별한 역할이 없는 경우❌ 다른 애너테이션을 쓰는 것이 좋은 경우비즈니스 로직을 처리하는 경우 → @Service데이터 액세스 관련 클래스 → @Repository웹 요청을 처리하는 컨트롤러 → @Controller🔥 결론@Component는 Spring Bean을 등록하는 가장 기본적인 애너테이션.역할이 명확한 경우 @Service, @Repository, @Controller를 사용하는 것이 더 가독성이 좋음.주로 일반적인 유틸리티 클래스나 특정한 계층에 속하지 않는 클래스에서 사용됨. 🚀📌 @PostConstruct란?@PostConstruct는 Spring에서 빈(Bean)이 생성된 후 자동으로 실행되는 메서드를 지정하는 애너테이션입니다.즉, 스프링 컨테이너가 해당 빈을 생성하고 의존성 주입(DI)이 완료된 후 한 번 실행되는 초기화 메서드를 정의할 때 사용된다.🚀 @PostConstruct 기본 사용 예시@Component class MyService { @PostConstruct fun initializeData() { println("MyService 초기화 중...") // 초기 데이터 설정 로직 } } ✅ 실행 흐름:MyService가 스프링 컨테이너에 의해 빈(Bean)으로 생성됨.의존성 주입(DI)이 완료됨.@PostConstruct가 붙은 initializeData() 메서드가 자동 실행됨.💡 @PostConstruct의 주요 특징Spring Bean이 생성된 후, 단 한 번만 실행됨.의존성 주입이 완료된 후 실행되므로, 다른 빈을 사용할 수 있음.애플리케이션이 실행될 때 한 번만 초기화해야 하는 작업에 적합.🎯 @PostConstruct가 유용한 경우사용 예시 설명 초기 데이터 설정 DB에서 기본 데이터를 불러오거나, 캐시를 로딩할 때 외부 API 연동 애플리케이션 시작 시 특정 API와 통신해야 할 때 리소스 초기화 특정 설정 파일을 읽거나, 초기 환경을 세팅할 때📌 데이터 초기화 예시@Service class DataService(private val repository: MyRepository) { @PostConstruct fun initializeDatabase() { if (repository.count() == 0L) { repository.saveAll(listOf(MyEntity("데이터1"), MyEntity("데이터2"))) println("초기 데이터 삽입 완료") } } } ✅ 데이터베이스에 초기 데이터를 넣어야 할 때 유용함.⚠ 주의할 점❌ 비동기 작업 (@Async)과 함께 사용하면 안 됨@PostConstruct는 빈 초기화 이후 즉시 실행되므로 비동기 메서드와 충돌 가능.대안: ApplicationRunner 또는 CommandLineRunner를 활용.@Bean fun initRunner() = ApplicationRunner { println("애플리케이션 실행 후 초기화 코드 실행") } 🔥 결론@PostConstruct는 Spring Bean이 생성된 후 단 한 번 실행되는 초기화 메서드.초기 데이터 설정, API 호출, 설정값 초기화 등에 유용.비동기 작업과 함께 사용하면 예상치 못한 문제가 발생할 수 있음.→ 이럴 때는 ApplicationRunner를 고려하는 것이 좋음. 🚀📌 achievementRepository.saveAll(achievements) 데이터가 없는데도 되는 이유Spring Data JPA의 saveAll() 메서드는 비어있는 리스트(List<T>)를 전달해도 오류 없이 실행되도록 설계되어 있다.즉, achievements 리스트가 비어있다면 아무런 데이터도 저장되지 않고, 그냥 정상적으로 메서드가 종료된다.🚀 saveAll() 동작 방식achievementRepository.saveAll(emptyList()) // 데이터가 없어도 실행됨 ✔ 내부적으로 실행되는 로직비어있는 리스트(emptyList<T>())가 들어오면, 아무 동작 없이 바로 반환.데이터가 있으면 각각의 엔티티를 save() 메서드를 이용해 Batch Insert 또는 개별 저장 수행.트랜잭션이 있으면 한 번에 처리되고, 없으면 개별 실행됨.🎯 saveAll()이 실행될 때 두 가지 경우1⃣ 데이터가 있을 때val achievements = listOf( Achievement(name = "Level 1", score = 10), Achievement(name = "Level 2", score = 20) ) achievementRepository.saveAll(achievements) // DB에 저장됨 saveAll()은 리스트에 있는 엔티티들을 한꺼번에 저장함.2⃣ 데이터가 없을 때val emptyList = emptyList<Achievement>() achievementRepository.saveAll(emptyList) // 아무 일도 일어나지 않음 saveAll()은 빈 리스트가 들어오면 아무런 작업도 하지 않고 그냥 종료됨.SQL 쿼리가 실행되지 않으며, 오류도 발생하지 않음.🔥 결론✅ saveAll(emptyList())는 아무런 데이터도 저장하지 않고 그냥 종료되도록 설계됨.✅ 데이터가 없을 경우에도 오류 없이 정상 동작함.✅ Spring Data JPA는 이런 경우를 고려하여 예외를 던지지 않음.📌 즉, 데이터가 없어도 saveAll()이 실행되지만, 실제로 DB에는 아무런 변경이 일어나지 않는 것! 🚀 Kotlin에서 fun의 의미Kotlin에서 fun 키워드는 함수를 정의할 때 사용되는 키워드Java의 public List<Skill> findAllByIsActive(boolean isActive)와 같은 역할을 한다.🚀 fun findAllByIsActive(isActive: Boolean): List<Skill>// select * from skill where is_active = :isActive fun findAllByIsActive(isActive: Boolean): List<Skill> ✅ 설명findAllByIsActive(isActive: Boolean):isActive 값이 true 또는 false인 데이터를 조회하는 메서드.SQL 변환: SELECT * FROM skill WHERE is_active = :isActive반환 타입: List<Skill> → 여러 개의 Skill 객체 리스트를 반환.🔹 사용 예시val activeSkills: List<Skill> = skillRepository.findAllByIsActive(true) println(activeSkills) // 활성화된 스킬 목록 출력 🚀 fun findByNameIgnoreCaseAndType(name: String, type: SkillType): Optional<Skill>// select * from skill where lower(name) = lower(:name) and type = :type fun findByNameIgnoreCaseAndType(name: String, type: SkillType): Optional<Skill> ✅ 설명findByNameIgnoreCaseAndType(name: String, type: SkillType):이름(name) 대소문자 구분 없이 검색하고,타입(type)이 일치하는 데이터를 조회.SQL 변환: SELECT * FROM skill WHERE lower(name) = lower(:name) AND type = :type반환 타입: Optional<Skill> → 조회된 값이 있을 수도 있고, 없을 수도 있음.🔹 사용 예시val skill: Optional<Skill> = skillRepository.findByNameIgnoreCaseAndType("java", SkillType.PROGRAMMING) if (skill.isPresent) { println("Skill found: ${skill.get()}") } else { println("Skill not found") } 🔥 결론Kotlin에서 fun은 함수 선언 키워드.findAllByIsActive(isActive: Boolean): 활성화된(is_active) 데이터를 리스트로 반환.findByNameIgnoreCaseAndType(name, type): 대소문자 구분 없이 특정 이름과 타입을 가진 데이터를 조회.Spring Data JPA는 메서드 이름을 기반으로 자동으로 SQL을 생성하여 실행함. 🚀 회고사실 왕복 3시간 거리 회사를 다니고 지금 커피챗, 친구들 만나기, 스터디 2개까지 해서 솔직히 버거워서 밀렸음 그래도 일단 과제를 내고자 하는 의지로 내는 중...

인프런 워밍업 클럽 스터디 3기 - CS <2주 발자국>

프로세스 동기화프로세스 간 통신(IPC: Inter-Process Communication)프로세스는 독립적인 실행 단위이기 때문에 기본적으로 타 프로세스의 메모리 영역에 접근할 수 없다. 서로 다른 프로세스들이 데이터를 교환하고 협력할 수 있도록 도와주는 메커니즘이다.통신의 분류는 크게 3가지로 분류될 수 있다.같은 컴퓨터 내 프로세스 간 통신같은 프로세스 내 스레드 간 통신네트워크를 이용한 원격 프로세스 간 통신같은 컴퓨터 내 프로세스 간 통신파일파일은 프로세스 들이 하나의 파일을 이용해 데이터를 쓰고 읽어서 데이터를 전달하는 방식이다.파이프파이프는 운영체제가 생성한 특별한 메모리 구조로 한 쪽 프로세스는 쓰고 다른 쪽 프로세스는 읽는 단방향 통신이다.익명 파이프(anonymous pipe) : 부모-자식 처럼 관련된 프로세스 간 통신명명 파이프(named pipe) : 이름이 있는 파일형태로 관련이 없는 프로세스 간 통신메시지 큐운영체제가 관리하는 큐 형태의 자료구조로 메시지 단위로 데이터를 주고 받는 형식이다. 비동기 통신이 가능하고 메시지 단위여서 데이터 구조화에 용이하다.공유 메모리여러 프로세스가 동시에 접근 가능한 메모리 영역을 운영체제가 할당하여 공유 메모리 영역을 통해 읽고 쓸 수 있다. 단 동기화 문제로 인해 세마포어, 뮤택스 등의 관리가 필요하다.시그널특정 이벤트(kill 혹은 ctrl+c)를 발생을 알리는 비동기 통신 메커니즘. 데이터 전달 보다는 프로세스 제어에 사용된다.스레드 간 통신스레드는 프로세스 내의 존재하는 실행 단위로 같은 프로세스내의 스레드들은 기본적으로 코드, 데이터, 힙 영역을 공유한다.이때 전역 변수, 힙 영역을 통해 데이터를 쉽게 주고 받는다.공유 자원에 대한 동시 접근 시 동기화가 매우 중요하여 동기화 도구들을 활용한다.뮤텍스(Mutex) : 한 번에 하나의 스레드만 공유 자원 접근할 수 있게 한다.조건 변수(Condition Variable) : 특정 조건이 충족될 때까지 스레드를 대기 상태로 두었다가 조건이 충족되면 통지하는 방식세마포어(Semaphore) : 0이상의 정수 값을 가지고 있고 0이되면 다른 스레드의 접근을 막는 방식. 프로세스가 자원을 얻을 때 wait(P 연산)으로 세마 포어 값을 감소시키고 signal(V 연산)으로 자원을 반환할 때 세마포어 값을 증가시킨다.wait(S): S -= 1 if (S < 0): 현재 스레드를 대기 큐에 넣고 대기 상태로 전환 signal(S): S += 1 if (S <= 0) 대기 큐에서 한 개의 스레드를 깨워 실행 준비 상태로 전환네트워크를 통한 원격 프로세스 간 통신소켓(Socket)네트워크 프로토콜(TCP/IP, UDP)를 활용하여 서로 다른 컴퓨터의 프로세스가 데이터를 주고 받을 수 있도록 하는 추상화된 인터페이스네트워크를 통해 통신 가능하며 표준화된 인터페이스라는 장점이 있지만, 데이터의 직렬화/역직렬화의 문제와 네트워크 프로그래밍의 복잡성이 존재한다.RPC(Remote Process Call)다른 컴퓨터에 있는 프로세스 함수를 로컬 함수 처럼 호출할 수 있도록 해주는 기술.내부적으로 소켓 통신 등을 사용하고 호출 과정, 파라미터 전달, 결과 반환을 추상화하여 원격 함수 호출을 구현할 수 있다.분산 시스템 개발에 용이하지만 성능 오버헤드 문제와 호출 실패 시 처리가 복잡하다.공유자원과 임계구역공유자원(Shared Resource)여러 프로세스(또는 스레드)들이 함께 사용하는 자원(메모리, 파일, 변수)를 의미한다.동시에 여러 프로세스가 공유하기 때문에 접근 순서에 따라 결과가 달라질 수 있다.컨텍스트 스위칭등으로 인해 결과를 예측하기 어려운 상황이 발생하며 이를 동기화 문제 (Synchronization Problem)이라고 한다.임계구역(Critical Section)공유 자원에 접근할 때 반드시 보호해야 하는 코드 영역여러 프로세스가 동시에 임계구역에 접근하면 의도치 않은 결과가 발생하게 된다.접근 순서와 타이밍 문제로 발생하는 경쟁적 상태를 경쟁 조건(Race Condition)이라고 한다.임계 구역 문제 해결을 위한 조건상호 배제(Mutual Exclusion)한 번에 단 하나의 프로세스만 임계구역에 접근 가능진행(Progress)임계구역을 사용하지 않는 프로세스가 다른 프로세스의 접근을 방해하지 않아야 한다.유한 대기(Bounded Waiting)어떤 프로세스든 일정한 시간 내에 반드시 임계 구역에 진입할 수 있어야 한다.프로세스의 기아 상태(Starvation)를 피하고 프로세스의 공평한 자원 할당이 필요하다.임계구역 문제 해결 방법세마포어운영체제 차원에서 제공하는 동기화 도구로 공유자원의 접근 권한을 관리하는 정수형 변수이다.세마포어의 값은 일반적으로 자원의 개수를 의미하며 보통 이진(0,1) 세마포어를 사용하여 임계 구역을 보호한다.공유 자원에 접근하려는 프로세스를 대기 큐에 넣고 운영체제가 대기 큐에 있는 프로세스에게 세마포어를 통해 접근 권한을 제어한다.두 가지 기본 연산을 통해 관리한다.wait() : 자원이 없으면 프로세스는 자원이 확보될 때까지 대기 상태로 들어간다.signal( ) : 자원을 사용한 후 다시 자원을 반납하여 대기중인 프로세스에게 공유자원을 사용하게 한다.int s = 1; wait(s) // 임계 구역 사용 signal(s) 단 signal()과 wait()의 호출 순서가 잘못되면 세마포어 값이 혼동되어 데이터 손상이나 교착상태(deadlock)를 유발할 수 있다.뮤텍스(Mutex)세마포어의 특수한 형태로 오직 한 프로세스만 임계구역 접근을 허용하는 이진 세마포어(binary semaphore)이다.C언어에서 POSIX 스레드 API를 사용하면 pthread_mutex_lock()과 pthread_mutex_unlock()으로 표현된다.모니터운영체제가 아니라 프로그래밍 언어 수준에서 제공하는 동기화 메커니즘이다.모니터는 공유 데이터와 이를 조작하는 프로시저(메서드)를 하나의 객체로 묶은 형태로 제공한다.프로그래머는 직접 wait(), signal()을 호출할 필요 없이 언어에서 자동으로 동기화 관리를 한다.public class SharedCounter {    private int count = 0; ​    public synchronized void increment() {        count++;   } ​    public synchronized int getCount() {        return count;   } }자바에서는 synchronized 키워드를 통해 동기화 코드를 작성하게 된다.synchronized 메서드를 호출하는 동안에는 다른 synchronized 메서드가 접근 불가능 핟록 배타적 접근이 보장된다.

자료구조 알고리즘 2주차

재귀 (Recursion)재귀 구현함수가 자기 자신을 호출하는 방식기본적으로 종료 조건(Base case) 과 반복 호출(Recursive case) 로 구성됨const myFunc = (number) => { if (number > 10) return; console.log(number); myFunc(number + 1); }; myFunc(1); 종료가 없는데 자동으로 실행이 종료된 이유?종료 조건이 없거나 충족되지 않으면 무한 반복콜스택(Call Stack)이 계속 쌓여서 메모리 한계를 넘으면 스택 오버플로우(Stack Overflow) 발생 후 프로그램 강제 종료됨콜스택의 개념함수 호출 정보를 저장하는 메모리 구조 (LIFO)재귀 호출이 일어날 때마다 스택에 함수 상태(매개변수, 지역변수 등) 가 쌓임호출이 끝나면 스택에서 빠져나가며 이전 상태로 돌아감재귀를 사용하는 이유문제를 더 작은 하위 문제로 나눠서 풀기 좋을 때 유리예시 : 팩토리얼, 피보나치 수열, 트리 탐색, 하노이탑 등반복문보다 코드가 간결하고 직관적일 수 있음재귀적으로 생각하기재귀의 여러 가지 패턴 분석하기단순 반복 구현반복문(for/while)으로 충분한데 재귀를 쓰면 비효율적 (콜스택 부담)하위 문제 결과를 기반으로 현재 문제 계산예시: 팩토리얼(n!) = n * (n-1)!하향식(Top-down): 큰 문제에서 시작 → 하위 문제를 해결하며 내려감상향식(Bottom-up): 작은 문제부터 차례로 풀어서 큰 문제를 해결 (재귀보다는 반복문과 DP에 주로 사용)어떤 종류의 재귀 함수인지 구분하기단순 재귀: 하위 문제를 그대로 호출 (ex. 팩토리얼)const power = (x, n) => { if (n === 0) return 1; return power(x, n - 1) * x; }; console.log(power(2, 5)); const strLength = (arr) => { if (arr[0] === undefined) return 0; return strLength(arr.slice(0, -1)) + 1; }; let str = "abcde"; let len = strLength(str); console.log(len); const factorial = (num) => { if (num === 1 || num === 0) return 1; return num * factorial(num - 1); }; console.log(factorial(5));다중 재귀: 여러 번 호출하는 경우 (ex. 피보나치) 트리 재귀: 트리 구조 탐색 (ex. DFS)꼬리 재귀: 마지막에 자기 자신 호출 → 반복문으로 최적화 가능재귀의 위력을 느낄 수 있는 문제하노이탑 트리 탐색 (DFS)백트래킹 (경로 탐색, 조합, 순열 문제)재귀를 쉽게 사용할 수 있는 방법종료 조건을 명확히 설계스택 오버플로우 방지 위해 입력값 제한 또는 반복문 전환 고려메모이제이션(Memoization) 으로 중복 계산 제거하노이탑가장 대표적인 재귀 문제원판을 한 개씩 이동시키는 재귀적 패턴이동 순서가 명확하고, 규칙에 따라 분할 정복 가능최소 이동 횟수: 2ⁿ - 1// 원반의 갯수, 시작 기둥(from), 이동할 기둥(to), 임시로 사용할 수 있는 기동(temp) const hanoi = (count, from, to, temp) => { if (count === 0) return; hanoi(count - 1, from, temp, to); console.log(`원반 ${count}를 ${from}에서 ${to}로 이동`); hanoi(count - 1, temp, to, from); }; hanoi(3, "A", "C", "B"); 버블 정렬 (Bubble Sort)핵심 개념인접한 두 값을 비교하고 교환하며 정렬매번 가장 큰 값을 뒤로 밀어내는 방식 → 버블처럼 부상하는 느낌for문 두 개가 중첩됨외부 루프: 전체 패스 반복 (n-1회)내부 루프: 인접 요소 비교 및 교환 (n-i-1회)시간 복잡도O(n²)등차수열의 합: (n-1) + (n-2) + … + 1 = n(n-1)/2데이터가 많아지면 급격히 느려짐const bubbleSort = (arr) => { for (let i = 0; i < arr.length - 1; i++) { for (let j = 0; j < arr.length - i - 1; j++) { if (arr[j] > arr[j + 1]) { let temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } }; 선택 정렬 (Selection Sort)핵심 개념최솟값을 찾아서 맨 앞과 교환하는 방식한 번 선택한 요소는 다시 고려하지 않음 → 안정성은 없음성능for문 두 개가 중첩외부 루프: 정렬 범위 축소내부 루프: 최솟값 탐색시간 복잡도 O(n²) → 버블 정렬과 비슷한 비효율성const selectronSort = (arr)=>{ for(let i = 0 ; i < arr.length - 1 ; i++){ let minValueIndex = i; for(let j = i + 1 ; j < arr.length; j++){ minValueIndex = j; } let temp = arr[i]; arr[i] = arr[minValueIndex]; arr[minValueIndex] = temp; } } 회고..배운 내용 & 내 생각재귀재귀는 단순히 "함수가 자기 자신을 호출하는 것"이라고만 알고 있었는데,이번에 콜스택과 메모리 구조를 이해하고 나니까 재귀 호출이 어떻게 돌아가는지 시각화가 됐다.특히 종료 조건(Base case)이 왜 중요한지 체감했다.종료 조건을 제대로 못 걸면 콜스택이 무한히 쌓이다가 스택 오버플로우가 발생한다는 걸 코드로 실험해보며 확인했다.팩토리얼이나 피보나치 같이 작은 문제로 쪼개서 풀어가는 방식은 하향식(Top-down),반복문이나 동적 계획법으로 밑에서부터 쌓아가는 건 상향식(Bottom-up)이라는 개념이 머릿속에 좀 더 명확해졌다.정렬 알고리즘버블 정렬과 선택 정렬은 사실 비슷한 느낌인데, 다시 보면 비효율적인 방식이라는 걸 알게 됐다.특히 시간 복잡도 O(n²)를 등차수열의 합으로 직접 계산해보니 훨씬 더 와닿았다.그럼에도 불구하고 이런 정렬부터 배우는 이유는, 기초적인 반복과 비교 구조를 이해하기 위해서라는 생각이 들었다.어려웠던 점과 해결 방법재귀에서 하향식과 상향식 사고가 헷갈렸는데,직접 코드를 그려보고 함수 호출 순서와 콜스택 흐름을 손으로 써보니까 감이 잡혔다.또, 하노이탑 문제를 풀면서 "문제를 나누고, 나눈 문제를 어떻게 다시 합칠지"를 생각하는 패턴이 중요한 걸 느꼈다.적용과 앞으로의 계획재귀적인 사고를 백트래킹 문제에 적용해보고 싶다.예를 들어 DFS 기반 조합, 순열, 경로 탐색 문제를 풀어보면서 패턴을 익힐 예정이다.정렬 알고리즘은 이제 퀵 정렬, 병합 정렬 같은 효율적인 방식으로 넘어가야겠다.또한, 재귀는 단순한 반복의 다른 표현이 아니라, 문제를 쪼개서 푸는 사고법이다.이걸 익히면 알고리즘 문제에서 트리 구조나 백트래킹을 자연스럽게 생각할 수 있다.

운영체제 2주차

프로세스 간 통신(IPC)서로 다른 프로세스가 데이터를 주고받기 위한 기법. 각 방법마다 동기화 방식, 속도, 구현 난이도에서 차이가 있다.방법특징장점단점파이프 (Pipe)한 방향 통신 (익명 파이프), 부모-자식 간 사용간단하고 구현 쉬움양방향 어렵고 제한적임메시지 큐메시지 형태로 데이터 전송, 큐를 통해 비동기 처리비동기 지원, 독립적 통신커널 리소스 필요, 크기 제한공유 메모리메모리 공간을 공유, 가장 빠른 통신 방식속도 빠름동기화(락) 필수, 복잡함소켓네트워크 기반 통신, 원격 프로세스와 통신 가능네트워크를 통한 유연한 통신프로토콜 관리 복잡, 느림[프로세스 A] --| 파이프 |--> [프로세스 B] [프로세스 A] --| 메시지 큐 |--> [프로세스 B] [프로세스 A] | | 공유 메모리 (Shared Memory) | [프로세스 B] [프로세스 A] <-- TCP/UDP 소켓 --> [프로세스 B]공유 자원과 임계 구역공유 자원은 여러 프로세스나 스레드가 접근하는 데이터나 자원이다. 임계 구역은 그 자원에 접근하는 코드 영역으로, 동시에 접근하면 문제 발생 가능성이 있다.용어설명공유 자원여러 프로세스나 스레드가 동시에 접근하는 자원 (예: 파일, 메모리)임계 구역공유 자원에 접근하는 코드 블록으로, 동시에 접근하면 데이터 일관성 문제가 생김동기화 도구임계 구역을 보호하기 위해 사용 (락, 세마포어, 모니터 등)세마포어동기화 객체로, 카운터 값을 통해 자원 접근을 제어한다. 임계 구역에 여러 프로세스가 접근하지 못하게 조정하며, 두 가지 연산으로 관리한다.wait() (P 연산): 세마포어 값을 감소. 값이 0보다 작으면 대기signal() (V 연산): 세마포어 값을 증가. 대기 중인 프로세스가 있으면 깨움종류설명카운팅 세마포어자원의 개수를 관리. 값이 0 이상일 때만 접근 허용이진 세마포어0 또는 1 값을 가짐. 뮤텍스와 유사하게 동작 // wait() 연산 (P) wait(S): while S <= 0: wait S = S - 1 // signal() 연산 (V) signal(S): S = S + 1모니터공유 자원과 그 자원을 사용하는 메서드를 하나의 단위로 캡슐화하고 동기화를 자동으로 처리하는 구조이다. 특정 언어나 플랫폼에서 구현 방식이 다르다.언어/플랫폼구현 방법설명Javasynchronized 키워드 사용메서드나 블록 단위로 동기화 처리C#lock 키워드, Monitor 클래스Monitor.Enter/Exit 또는 lock 문법 사용.NETC# 동일 + Task, async/await병렬 처리와 비동기 지원을 강화 데드락(교착 상태)서로 자원을 점유하고 대기하는 상황이 꼬여서 아무도 작업을 진행하지 못하는 상태.[P1] ----(점유중)---> [R1] ^ | | | | (대기중) | | [P4] <----(점유중)---- [R4]  데드락 발생 조건 (4가지 필요조건)조건설명상호 배제자원을 한 번에 하나의 프로세스만 점유 가능비선점자원을 강제로 빼앗을 수 없음점유와 대기자원을 점유한 채로 다른 자원을 기다리는 상태순환 대기프로세스들이 원형으로 자원을 점유하고 대기하는 구조데드락 해결 방법방법설명장점단점예방데드락 발생 조건 중 하나를 제거하여 사전에 차단단순하고 명확함시스템 자원 활용도 낮음회피자원 할당 시 안전 상태인지 판단 후 할당 (은행원 알고리즘)교착상태 회피 가능복잡하고 오버헤드 큼검출 및 복구교착 상태 발생 후 감지 및 해결 (롤백, 강제 종료 등)유연성 있음오버헤드, 데이터 손실 가능성회피 전략 - 은행원 알고리즘안정 상태(Safe): 자원 요청이 들어와도 교착 상태가 발생하지 않는 상태불안정 상태(Unsafe): 교착 상태가 발생할 가능성이 있는 상태지만, 아직 교착 상태는 아님검출 방법방식설명특징가벼운 검출 (타임아웃)일정 시간 동안 작업이 없으면 교착 상태로 간주하고 복구 시도간단하지만 오탐 가능성 있음무거운 검출 (자원 할당 그래프)자원/프로세스 관계를 그래프로 그려 순환 존재 여부 탐지정확하나 지속적 검사로 인한 오버헤드 발생컴파일과 프로세스언어 구분구분설명언어 예시컴파일 언어소스 코드를 기계어로 변환 후 실행 파일 생성C, C++, C#, Go인터프리터 언어소스 코드를 실행할 때 한 줄씩 해석하여 실행Python, JavaScript, Ruby컴파일 과정 (C 기준)복사편집test.c → 전처리기 → test.i test.i → 컴파일러 → test.s test.s → 어셈블러 → test.o test.o → 링커 → test.exe 실행 파일이 프로세스로링커가 생성한 실행 파일은 OS에 의해 메모리에 적재되고, 프로세스로 생성되어 실행된다.메모리 종류메모리 유형설명특징레지스터CPU 내부, 가장 빠른 속도CPU 연산용, 소량캐시 메모리CPU와 메인 메모리 사이에 위치L1(가장 빠름) ~ L3 존재메인 메모리(RAM)실행 중인 프로그램과 데이터를 저장휘발성, 속도 중간보조 저장장치HDD, SSD 등비휘발성, 대용량 저장비트 수에 따른 주소 공간32비트: 2³² → 4GB 주소 공간 한계64비트: 2⁶⁴ → 이론상 수십 기가바이트 이상의 메모리 접근 가능메모리와 주소주소 구분설명물리 주소실제 메모리 주소, 하드웨어가 직접 접근논리 주소사용자 프로세스가 접근하는 가상의 주소경계 레지스터커널과 사용자 공간을 구분하며, 보호 기능 수행메모리 할당 방식방식설명장점단점가변 분할(세그멘테이션)프로세스 크기에 맞게 메모리 공간 할당공간 효율적외부 단편화 발생고정 분할(페이징)일정 크기 페이지 단위로 메모리 할당관리 간단, 단편화 적음내부 단편화 가능성버디 시스템2의 거듭제곱으로 메모리 블록을 분할 및 병합분할/병합 유연함일부 메모리 낭비 가능버디 시스템 예시메모리 전체 크기: 2048바이트요청 크기: 500바이트2048 → 1024 → 512바이트로 분할 후 500바이트 할당나머지 12바이트만 낭비, 효율적 공간 사용 가능  회고..배운 점IPC 방식의 차이점과 적절한 사용처를 구분할 수 있게 되었다.세마포어와 모니터의 개념적 차이와 구현 방식을 언어별로 정리했다.메모리 할당 방식에서 외부 단편화, 내부 단편화 개념이 헷갈렸는데 확실히 정리했다.아쉬운 점은행원 알고리즘은 개념적으로만 접근했고, 실제 코드 구현이나 응용 사례가 부족했다. IPC도 실습 위주로 보완이 필요하다.더 해보고 싶은 것세마포어, 모니터를 직접 구현 해본 코드 검색해보기데드락 검출을 위한 자원 할당 그래프를 찾아보기 

인프런 워밍업 클럽 스터디 3기 - CS 2주차 알고리즘 미션

재귀함수에서 기저조건을 만들지 않거나 잘못 설정했을 때 어떤 문제가 발생할 수 있나요?스택 오버플로우가 발생하여 콜 스택이 가득 찰때까지 재귀 함수가 실행된다. 0부터 입력 n까지 홀수의 합을 더하는 재귀 함수를 만들어보세요.function sumOdd(n) { if (n < 0) {return 0;} if (n <= 1) { return n; } if (n % 2 == 1) { return n + sumOdd(n - 1) } else { return sumOdd(n-1); } } 다음 코드는 매개변수로 주어진 파일 경로(.는 현재 디렉토리)에 있는 하위 모든 파일과 디렉토리를 출력하는 코드입니다. 다음 코드를 재귀 함수를 이용하는 코드로 변경해보세요.const fs = require("fs"); // 파일을 이용하는 모듈 const path = require("path"); // 폴더와 파일의 경로를 지정해주는 모듈 function traverseDirectory1(directory){ const files = fs.readdirSync(directory); // 현재 디렉토리 파일 목록 for (const file of files) { const filePath = path.join(directory, file); // 파일과 경로 합치기 const fileStatus= fs.statSync(filePath); // 파일 정보 if (fileStatus.isDirectory()) { // 해당 파일이 디렉토리라면 traverseDirectory1(filePath); // 들어가서 재귀 호출 } else { // 해당 파일이 파일이라면 console.log('파일:', filePath); // 파일 경로 출력 } } } traverseDirectory1("."); // 현재 경로의 모든 하위 경로의 파일, 디렉토리 출력 

(2주차) 자료구조 알고리즘 미션

재귀함수에서 기저조건을 만들지 않거나 잘못 설정했을 때 어떤 문제가 발생할 수 있나요?재귀가 끝나지 않으므로 스택 오버플로가 발생한다 함수가 호출될 때마다 콜 스택(call stack)에 쌓이는데, 끝없이 호출되면 모든 메모리를 사용하게 된다 0부터 입력 n까지 홀수의 합을 더하는 재귀 함수를 만들어보세요.const sumOdd = (n) => { // 기저 조건: n이 0보다 작으면 0을 반환하고 끝낸다 if (n <= 0) { return 0; } // 현재 숫자가 홀수면 더하고, 짝수면 그냥 넘긴다 if (n % 2 !== 0) { return n + sumOdd(n - 1); } else { return sumOdd(n - 1); } } console.log(sumOdd(10)); // 25다음 코드는 매개변수로 주어진 파일 경로(.는 현재 디렉토리)에 있는 하위 모든 파일과 디렉토리를 출력하는 코드입니다. 다음 코드를 재귀 함수를 이용하는 코드로 변경해보세요.const fs = require("fs"); const path = require("path"); const traverseDirectoryRecursive = (directory) => { const files = fs.readdirSync(directory); // 디렉토리 안의 파일/폴더 목록 가져온다 for (const file of files) { const filePath = path.join(directory, file); // 경로를 합친다 const fileStatus = fs.statSync(filePath); // 파일/디렉토리 상태 확인 if (fileStatus.isDirectory()) { console.log('Directory : ', filePath); // 재귀 호출: 하위 디렉토리를 다시 순회 traverseDirectoryRecursive(filePath); } else { console.log('File : ', filePath); } } } traverseDirectoryRecursive("."); // 현재 경로부터 시작

인프런 워밍업 클럽 스터디 3기 - CS 2주차 운영체제 미션

FIFO 스케줄링의 장단점이 뭔가요?장점 : 먼저 도착하는 프로세스가 먼저 실행되는 알고리즘으로 직관적이며 컨텍스트 스위칭이 발생하지 않아 오버헤드가 적다.단점 : 평균 대기 시간이 길어질 확률이 매우 높다. 우선순위가 적용되지 않는다. SJF를 사용하기 여러운 이유가 뭔가요?항상 짧게 걸리는 프로세스가 먼저 실행되기 때문에 오래 걸리는 프로세스는 무한정으로 기다릴 가능성이 높고 정확한 실행 시간을 알기는 어렵다. RR 스케줄링에서 타임 슬라이스가 아주 작으면 어떤 문제가 발생할까요?타임 슬라이스가 매우 작으면 컨텍스트 스위칭이 증가하여 오버헤드가 커지고 성능이 저하된다. 운영체제가 MLFQ에서 CPU Bound Process와 I/O Bound Process를 어떻게 구분할까요? I/O Bound Process는 CPU 사용량이 짧아 스스로 CPU를 반납할 가능성이 높고 CPU Bound Process는 타임 슬라이스를 모두 사용하여 강제로 CPU를 빼앗길 수 있다.따라서 타임 슬라이스의 사용에 따라 구분할 수 있다. 공유자원이란무엇인가요?여러 프로세스가 공유하여 사용하는 자원. 동시에 사용할 수 있기 때문에 임계구역과 접근을 운영체제에서 제어해야 한다. 교착상태에 빠질 수 있는 조건은 어떤 것들을 충족해야할까요?상호 배제 : 한 번에 하나의 프로세스만 공유자원을 사용할 수 있다.비선점 : 한 프로세스가 공유자원을 점유하고 있을 때 다른 프로세스는 강제로 빼앗을 수 없다. 스스로 반납을 기다려야 한다.점유와 대기 : 할당된 자원을 유지한 상태에서 추가 자원을 요청하여 대기하는 상황. 원형 대기 : 원의 형태로 자원을 서로 기다리는 상황. 즉 모든 프로세스가 영원히 자원을 획득할 수 없다.(철학자의 식사시간) 

채널톡 아이콘