블로그

예진안

인프런 워밍업 클럽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기

Taeho

인프런 워밍업 클럽 - CS Day 9

Algorithm참고 : https://visualgo.net/en/sortingBubble Sort인접한 두 원소를 비교하여 두 원소의 위치를 교환한다.과정배열을 처음부터 끝까지 순회하며 인접한 두 원소를 비교한다.왼쪽 원소가 오른쪽 원소보다 크면 두 원소를 교환한다.이 과정을 배열이 정렬될 때까지 반복한다.시간 복잡도O(n^2)장점이해와 구현이 간단한다.단점성능이 좋지 않다.Selection Sort배열에서 최솟값을 찾아 맨 앞으로 이동시킨다.과정정렬되지 않은 부분에서 최솟값을 찾는다.찾은 최솟값을 정렬되지 않은 부분의 첫 번째 원소와 교환한다.정렬된 부분을 한 칸 늘리고, 정렬되지 않은 부분에서 위 과정을 반복한다.시간 복잡도O(n^2)장점이해와 구현이 간단하다.단점성능이 좋지 않다.OSProgramming LanguageCompile Language개발자가 코드를 작성하고 컴파일을 수행하여 0과 1로된 기계어로 실행파일을 만든다.→ 기계어로 되어 있어 실행 속도가 인터프리터 언어에 비해 빠르다.컴파일 과정에서 개발자의 문법오류를 체크한다.ex) C, C++, C#Interpreter Language개발자가 작성한 코드를 미리 기계어로 만들어 놓지 않고 실행시 코드를 한줄씩 해석해 실행하는 언어→ 미리 검사를 하지 않기 때문에 실행할 때 오류가 발생할 수 있고, 컴파일 언어보다 느리다.ex) Javascript, Python, Ruby프로세스의 영역코드 영역실행해야 할 코드가 들어간다.데이터 영역전역 변수나 배열이 들어가는 영역스택 / 힙프로세스가 실행될 때 할당되는 메모리스택 : 지역변수와 함수 관련 값들이 저장힙 : 실행 중에 메모리 공간을 할당할 수 있는 유동적인 공간Compile 언어가 Process가 되는 방법개발자가 코드 작성전처리 단계 실행개발자가 작성한 코드를 확인하고 전처리 구문을 처리한다.C에서는 #이라는 키워드로 선언된다.ex) #include<stdio.h>, #define MY_NUMBER 100코드에 있는 모든 주석은 삭제된다.결과물로 .i 파일이 생성된다.전처리기에서 나온 결과파일을 컴파일러가 처리한다.컴파일러는 .i 파일을 기계어에 가까운 어셈블리어로 변환시킨다.결과물로 .s 파일이 생성된다.어셈블러 작업이 수행된다.오브젝트 파일.o로 변환된다.오브젝트 파일은 0과 1로 구성되어 있다.코드영역과 데이터 영역이 나뉘어져 있다.링커 작업이 수행된다.모든 오브젝트 파일을 하나의 코드 영역과 데이터 영역으로 묶어준다.실제로 실행될 주소를 매핑시켜준다.결과물로 .exe 파일이 생성된다.사용자가 .exe파일을 실행시키면 OS가 프로세스를 생성한다.OS는 파일에 있는 코드 영역과 데이터 영역을 가져와 프로세스의 코드 영역과 데이터 영역에 넣어주고, 빈 상태의 스택과 힙을 할당한다.PCB를 만들어 프로세스를 관리가 가능하게 한다.PC(프로그램 카운터)에 다음 실행할 명령어의 주소를 생성한 프로세스의 코드영역의 첫번째 주소로 설정한다.→ OS의 CPU 스케줄링에 따라서 프로세스가 실행되다가 작업을 마친다.메모리 종류레지스터가장 빠른 기억장소, CPU 내에 존재한다.휘발성 메모리CPU를 나타내는 값에서 32bit, 64bit를 의미하는 것이 레지스터의 크기이다.CPU는 계산을 수행할 때 메인 메모리에 있는 값을 레지스터로 가져와서 계산한다.계산 결과는 메인 메모리에 저장한다.캐시휘발성 메모리속도가 매우 빠른 레지스터와 레지스터에 비해 상대적으로 느린 메인 메모리 사이의 속도 간극을 메우기 위해 필요한 데이터를 미리 가져와 저장하는 저장소성능의 이유로 여러 개가 존재한다.L1, L2, L3→ 숫자가 커질 수록 느린 캐시CPU가 값을 요청해 레지스터로 값을 옮겨야 한다면 빠른 캐시를 순차적으로 확인하고, 캐시에 데이터가 없으면 메인 메모리를 조회한다.ex) L1 → L2 → L3 → 메인 메모리보조 저장장치(HDD, SSD)비휘발성 메모리메인 메모리실제 운영체제와 다른 프로세스들이 올라가는 공간휘발성 메모리데이터를 저장하기 보다는 실행중인 프로그램만 저장한다.OS는 메모리를 관리하기 위해서 1Byte 크기로 구역을 나누고 숫자(주소)를 매긴다.32bit CPU, 64bit CPU32bit CPU레지스터, ALU, Data Bus : 32bit메모리 : 2^32 = 4GB64bit CPU레지스터, ALU, Data Bus : 64bit메모리 : 2^64 = 16384PiB64bit CPU가 32bit CPU 보다 한번에 처리할 수 있는 양이 많기 때문에 속도가 더 빠르다.물리 주소 & 논리 주소물리 주소 공간 : 0x0부터 시작하는 주소 공간논리 주소 : 사용자 관점에서 바라 본 주소 공간사용자는 물리 주소를 몰라도 논리 주소로 물리 주소에 접근할 수 있다.OS를 위한 공간은 따로 확보한다.경계 레지스터H/W적으로 OS 공간과 사용자 공간을 나누는 레지스터CPU 내에 존재하는 레지스터메모리 관리자가 사용자 프로세스가 경계 레지스터의 값을 벗어났다면 검사하고, 벗어났다면 해당 프로세스를 종료시킨다.절대 주소 & 상대 주소개발자가 프로그램이 실행될 주소를 신경쓰지 않고 개발할 수 있는 이유→ 컴파일러가 컴파일을 할 때 메모리 0번지에서 실행한다고 가정하기 때문절대 주소 : 메모리 관리자가 바라본 프로세스가 올라간 물리 주소상대 주소 : 사용자가 바라보는 논리 주소재배치 레지스터프로그램의 시작 주소가 저장되어 있다.사용자가 요청한 논리 주소의 데이터를 물리 주소로 치환해준다.사용자가 메모리에 접근할 때마다 논리 주소를 물리 주소로 치환해준다.메모리 할당 방식메모리 오버레이메모리보다 용량이 큰 프로그램을 실행시키는 방법큰 프로그램을 메모리에 올릴 수 있을 정도로 분할하여 일부만 실행하고, 실행되지 않은 프로그램은 HDD의 스왑 영역에 저장하는 방식Swap스왑영역에 있는 데이터 일부를 메모리로 가져오고 메모리에 있는 데이터를 스왑영역으로 옮기는 것가변 분할 방식(= Segmentation, 세그멘테이션)프로세스의 크기에 따라 메모리를 나누는 방식하나의 프로세스가 메모리에 연속된 공간에 할당된다.→ 연속 메모리 할당이라고 한다.장점메모리에 연속된 공간에 할당된다.→ 내부 단편화가 없다.단점외부 단편화가 발생한다.고정 분할 방식(= Paging, 페이징)프로세스의 크기와는 상관없이 정해진 크기로 나누는 방식하나의 프로세스가 메모리에 분산되어 할단된다.→ 비연속 메모리 할당이라고 한다.장점구현이 간단하고 오버헤드가 적다.단점작은 프로세스도 큰 영역에 할당되어 내부 단편화가 발생한다.내부 단편화프로세스에 필요한 메모리보다 더 큰 고정 크기의 메모리 블록이 할당될 때 발생한다.할당된 메모리와 실제 사용된 메모리 사이의 차이로 인해 메모리 공간이 낭비된다.고정 크기 분할 방식에서 주로 발생한다.해결 방법은 딱히 없고, 분할되는 크기를 조절하여 내부 단편화를 최소화한다.외부 단편화메모리 할당과 해제를 반복하면서 작은 빈 공간들이 메모리 곳곳에 흩어져 생기는 현상전체 가용 메모리는 충분하지만, 연속된 큰 블록을 할당할 수 없는 상황을 만든다.가변 분할 방식에서 주로 발생한다.조각모음외부 단편화가 발생한 공간을 합쳐주는 작업현재 메모리에서 실행되고 있는 프로세스들의 작업을 일시 주징하고, 메모리 공간을 이동시켜야 한다.→ 오버헤드가 발생한다.버디 시스템가변 분할 방식 + 고정 분할 방식오늘날의 OS가 채택한 메모리 할당 방식2의 제곱으로 메모리를 분할하여 할당하는 방식→ 근접한 메모리 공간을 합치기 쉽다.→ 조각 모음보다 훨씬 간단하다.장점가변 분할 방식처럼 프로세스 크기에 따라 할당되는 메모리 크기가 달라지고, 외부 단편화를 방지하기 위해 메모리 공간을 확보하는 것이 간단하다.내부 단편화가 발생할 수 있지만 고정 분할 방식에 비해 많은 공간이 낭비되지는 않는다.

알고리즘 · 자료구조워밍업클럽CS전공지식DAY9

김예지

[인프런 워밍업 스터디 클럽 2기 FE] 2주차 과제 - 예산 계산기

예산 계산기 만들기GitHub : 08-budget-calculato 기능 목록분류 / 지출 내역 / 비용 데이터를 받아 리스트 생성하기추가 / 수정 / 삭제 이벤트 → toasts 메세지 1초 띄우기총 비용 계산하기전체 삭제 기능 구현하기폴더구조📁src ├── App.js ├── App.css ├── 📁components │ ├── ExpenseForm.js │ ├── ExpenseList.js │ └── ExpenseLists.js데이터 구조 정하기expense: 항목, details: 지출 내역, amount: 비용,1. ExpenseForm : 데이터 전달데이터를 입력하고 제출을 누르면 App.js에 있는 handleSubmit 함수로 데이터 전달. handleSubmit 함수에서는 const updatedData = [...prev, newExpenseData]; 스프레드 연산자를 사용해 배열에 새 항목을 추가한다.React에서는 상태(state)를 직접 수정하지 않고 새로운 값을 반환하는 방식으로 상태를 업데이트해야 한다. 불변성을 유지하는 것이 중요한 이유는 React가 상태가 변할 때 렌더링을 다시 수행하는데, 상태가 변경된 것을 인식하기 위해서는 참조가 완전히 새로운 값으로 바뀌어야 하기 때문.강의에서 불변성에 대한 설명을 듣고 바로 기능을 만드니까 더 잘 기억에 남는다.2. toasts 메세지 조건부 렌더링하기const showMessageWithColor = (status) => { let color; let message; if (status === 'add') { message = '아이템이 생성되었습니다.'; color = '#f0faf6'; } else if (status === 'edit') { message = '아이템이 수정되었습니다.'; color = '#f0faf6'; } else if (status === 'delete') { message = '아이템이 삭제되었습니다.'; color = '#fee'; } setMessage(message); setMessageColor(color); setShowMessage(true); // 1초 후에 메시지 숨기기 setTimeout(() => { setShowMessage(false); }, 1000); };showMessage: 메시지를 표시할지 여부를 결정합니다. true 표시, false 숨김 처리message: 사용자에게 표시할 메시지 텍스트messageColor: 메시지의 배경색을 설정status 매개변수를 통해 메시지의 종류( 'add', 'edit', 'delete')를 구분한다.{showMessage && ( <div className='w-full px-2 py-2 text-sm rounded-lg' style={{ backgroundColor: messageColor }} > {message} </div> )}showMessage가 true일 때만 메시지 박스가 렌더링style 속성을 사용하여 messageColor를 배경색으로 설정3. 총 지출 비용 계산const calculateTotalAmount = (data) => { return data.reduce((acc, item) => acc + item.amount, 0); };수정 버튼을 누르고 input을 수정할 때마다 값이 반영되어서 저장 버튼을 누르면 총 지출 비용을 계산하도록 함수로 따로 만들었다. 최종 값은 toLocaleString() 사용해 쉼표가 포함된 형식으로 바꿔준다.4. 항목 전체 삭제ExpenseList에 있는 전체 치우기 버튼을 눌러주면 기존 배열에 들어있던 데이터를 지우고 calculateTotalAmount() 에도 값을 전달해 0으로 초기화 시켜준다.강의에서 들었던 To-Do 앱과 그렇게 큰 기능 차이가 나지 않았기 때문에 어렵지는 않았다. 강의 내용을 복기하면서 비슷한 흐름으로 만들었다. 리액트의 불변성을 지키고 최적화를 잘 고려해야겠다.

워밍업클럽

Taeho

인프런 워밍업 클럽 - CS Day 8

Algorithm하노이의 탑하향식 계산 방식의 좋은 예시→ 재귀함수의 좋은 예시제약 조건한 번에 하나의 원반을 움직일 수 있다.가장 위에 있는 원반만 옮길 수 있다.아래에 작은 원반이 올 수 없다.OS교착상태여러 프로세스가 서로 다른 프로세스의 작업이 끝나길 기다리다가 아무 작업도 수행되지 않는 상태발생 원인상호 배제 : 공유 자원은 한 번에 하나의 프로세스만 사용할 수 있다.비선점 : 다른 프로세스가 사용 중인 자원을 강제로 빼앗을 수 없다.점유와 대기 : 프로세스가 이미 자원을 보유한 상태에서 다른 자원을 요청하며 대기한다.원형 대기 : 점유와 대기를 하는 프로세스들의 관계가 원형이다.하나라도 충족하지 않으면 교착상태가 발생하지 않는다.→ 교착 상태를 예방하는 것을 구현하기는 매우 어려워서 교착 상태를 해결하는 방향으로 발전됐다.해결방법교착상태 회피프로세스들에게 자원을 할당할 대 어느 정도 자원을 할당해야 교착상태가 발생하는지 파악해서 교착상태가 발생하지 않는 수준의 자원을 할당한다.전체 자원의 수와 할당된 자원의 수를 기준으로 안정상태와 불안정 상태로 나뉜다.OS는 안정상태를 유지하려 한다.안전 상태: 모든 프로세스가 요구한 최대 자원을 할당받아 실행을 완료할 수 있는 상태불안정상태에 있더라도 무조건 교착상태에 들어가는 것이 아니라 교착상태에 빠질 확률이 높아지는 것이다.은행원 알고리즘작동 원리프로세스가 자원을 요청할 때, 그 요청이 시스템을 안전 상태로 유지할 수 있는지 확인한다.안전 상태를 유지할 수 있는 요청만 수락하고, 불안정한 상태를 초래할 수 있는 요청은 거절한다.주요 개념최대 요구량(Max Need): 프로세스가 실행을 완료하기 위해 필요한 최대 자원 양할당량(Allocation): 현재 프로세스에 할당된 자원 양필요량(Need): 최대 요구량에서 현재 할당량을 뺀 값가용량(= 시스템 총 자원, Available): 시스템에서 현재 사용 가능한 자원 양단점비용이 비싸고 비효율적이다.교착상태 검출가벼운 교착 상태 검출타이머를 이용하는 방식프로세스가 일정시간 동안 작업을 진행하지 않는다면 교착상태가 발생했다고 간주하고 교착상태를 해결한다.교착상태 해결 방법일정 시점마다 체크포인트를 만들어 작업을 저장하고 타임아웃으로 교착상태가 발생했다면 마지막으로 저장했던 체크포인트로 롤백한다.무거운 교착 상태 검출자원 할당 그래프를 이용하는 방식OS가 자원 할당 그래프를 유지하고 검사해야 하기 때문에 오버헤드가 발생한다.But. 가벼운 교착 상태 검출에서 발생할 수 있는 억울하게 종료되는 프로세스가 발생하지 않는다.OS에서 프로세스가 어떤 작업을 사용하는지 지켜보고 교착상태가 발생했다면 해결한다.

알고리즘 · 자료구조워밍업클럽CS전공지식DAY8

예진안

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

운영체제프로세스간 통신프로세스간의 통신 종류 : 한 컴퓨터 안에 프로세스들 간의 통신다른 컴퓨터 안에 있는 프로세스들 간의 통신한 컴퓨터 안에 프로세스들 간의 통신 방법파일 사용: 하나의 파일을 이용하여 통신하려는 프로세스끼리 읽고 쓰기파이프 사용 : 운영체제가 만든 파이프를 통해 데이터를 읽고 쓰기쓰레드 사용 : 한 프로세스 안에서 여러 쓰레드 간 통신 방법데이터 영역에 있는 전역변수나 힙 영역을 이용하면 통신이 가능하다.네트워크 사용 : 운영체제가 제공하는 소켓, RPC(원격프로 시저 호출)를 이용RPC(Remote Procedure call) - 다른 컴퓨터를 호출 공유자원과 임계구역공유자원 : 통신하면서 공동으로 이용하는 변수나 파일들공유자원은 프로세스 접근 순서에 따라 결과가 달라진다.컨텍스트 스위칭으로 인해서 시분할된다 -> 어떤 프로세스가 먼저 실행될지 예측하기 어렵다.-> 동기화 문제 : 연산 결과가 예측이 어려워 이 과정에서 생기는 문제들.임계구역 (Critical Section) : 여러 프로세스가 동시에 사용하면 안되는 영역.경쟁조건 (Race Condition) : 공유 자원을 서로 사용하기 위해 경쟁하는 것.임계구역에 대한 해결을 위해서 상호배제 매커니즘 필요상호배제 : 둘 이상의 프로세스가 동시에 임계 영역(CS : Critical Section)에 진입하는 것을 방지하기 위해 사용되는 알고리즘상호배제의 요구사항 임계영역엔 동시에 하나의 프로세스만 접근 가능여러 요청에도 하나의 프로세스만 접근 허용한다.임계구역에 들어간 프로세스는 빠르게 나와야한다.(다른 프로세스가 오래 기다리기 때문) 세마포어 https://baebalja.tistory.com/340세마 포어란? 공유자원이 하나 이상일 때 처리하는 동기화 방법현재 공유 자원에 접근할 수 있는 프로세스/스레드(resource)의 수예시 프린터를 사용하려는 다른 컴퓨터 두 대프린터기 : 공유자원컴퓨터 : 프로세스들, 경쟁조건해소 방법 : 프린터실을 만들어 오직 한 컴퓨터만 프린터를 사용할 수 있게 만든다.열쇠관리자 : 운영체제열쇠 : 세마포어프로세스에서 동기화 대상이 여러 개가 될 수있기 때문에 세마포어는 여러 개가 존재할 수있다.wait()함수와 signal()함수를 이용 위 함수에 들어갈 인자 값은 동기화하고있는 프로세스의 개수wait() : 열쇠를 요청해서 열쇠를 받고 문을 잠그는 함수. 다른 함수는 실행되지 않고 멈춘다.signal() : 열쇠 관리자(OS)에게 열쇠 반납 함수. 다음 함수가 실행된다.단점 : 두 개의 함수는 순서를 지키지 않고 호출해서 세마포어를 사용하지 못할 수가 있다. 모니터세마포어를 보완한 상호배제 알고리즘프로그래밍 언어 차원에서 지원하는 방법으로 자바에서 주로 모니터한다.synchronized 가 붙은 함수 : 동시에 여러 프로세스가 실행 시킬 수 없다.ex) synchronized 가 붙은 increase()함수 사용 시 synchronized 가 붙은 decrease()함수도 사용할 수없다.->synchronized 가 붙은 함수가 사용된다면 다른 synchronized 함수도 사용불가.wait(), signal()함수를 임계영역에 감싸지 않아도 된다. 알고리즘재귀적으로 생각하기(재귀적 사고 skrr)for문 vs 재귀함수 => for문이 더 효율적, 재귀함수는 어떨때 효율적일까?하향식 계산에 유리한 재귀함수하향식 계산 : 하위 문제의 결과를 기반으로 현재 문제를 계산한다 (재귀함수)return number * factorial(number -1);상향식 계산 : 일반적으로 실행되는 계산(for문) 재귀함수를 상향식으로 계산한다고 성능이 좋아지진 않아서 굳이 재귀문을 상향식 계산하지 않는다.function factorial(number){ if( number ==1 || number ==0) return 1;//기저 조건 return number * factorial(number-1);// 현재문제 * 하위 문제 } 부족하다고 생각되는 부분은 블로그에 찾아가서 읽어봤다. 이 열정이 얼마나 갈지 모르겠네 

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

김예지

[인프런 워밍업 스터디 클럽 2기 FE] 2주차 과제 - 타이핑 테스트

 타이핑 테스트 앱 만들기GitHub : 07-typing-test 개요타이핑 테스트 기능 구현주어진 시간 내에 문장을 타이핑하고 입력 속도(WPM, CPM)와 정확도를 측정 필요한 기능타이핑된 값결과 팝업 보여주기 구현하기초반에 필요하다고 생각되는 부분들을 셋팅한다.typingInput.addEventListener('input', () => { const spans = printText.querySelectorAll('span'); const userInput = typingInput.value; // 사용자가 입력한 값 userInputArray = userInput.split(''); totalTypedCharacters = userInput.length; // 입력된 문자 수 // 두 배열을 비교하여 클래스 추가 for (let i = 0; i < currentTypingText.length; i++) { if (userInputArray[i] === currentTypingText[i]) { // 맞으면 'complete' 클래스 추가 spans[i].classList.add('complete'); spans[i].classList.remove('error'); } else if (userInputArray[i] !== undefined) { // 'error' 클래스 추가 spans[i]?.classList.remove('complete'); spans[i].classList.add('error'); } else { // 입력이 지워진 경우 spans[i]?.classList.remove('complete'); spans[i]?.classList.remove('error'); } } // 오류 계산 calculateErrors(); });처음에는 input 값을 실시간으로 받고 현재 타이핑 해야 하는 문장과 비교를 했었는데 생각과 달리 정확한 비교가 어려웠다. 그래서 현재 타이핑 해야 하는 글자와 사용자가 입력한 글자를 모두 배열의 요소로 저장하고 비교하는 방법으로 바꾸고 span 요소에 class를 추가해 complete / error 를 표시했다.// 오류 수 계산 function calculateErrors() { // 현재 문장의 오류 수 currentSentenceErrors = 0; // 현재 문장에서의 오류 수를 계산 for (let i = 0; i < currentTypingText.length; i++) { if ( userInputArray[i] !== currentTypingText[i] && userInputArray[i] !== undefined ) { currentSentenceErrors++; } } // 전체 오류 수 업데이트 (이전 오류 수에 현재 문장 오류 추가) const totalErrorCount = totalErrors + currentSentenceErrors; errorsElement.textContent = totalErrorCount; // 정확도 계산 calculateAccuracy(totalErrorCount); }원래는 오류 수 계산을 typingInput.addEventListener()의 for문에서 같이 처리했었는데, 다음 문장으로 넘어갈 때 오류 개수가 이상하게 업데이트 되는 바람에 함수로 분리하고 문장 별로 오류 수를 저장하고 업데이트하는 방식으로 변경했다. 오류 개수와 정확도는 화면에 실시간으로 반영되는 값이라 정확도 함수에 오류 수를 넘겨서 같이 업데이트 했는데 지금 보니까 그냥 같은 함수에서 처리해도 됐을 것 같다는 생각이 든다.function loadNextSentence() { // 현재 문장의 오류를 전체 오류에 누적 totalErrors += currentSentenceErrors; // 새로운 문장 현재 문장 오류 초기화 currentSentenceErrors = 0; currentSentenceIndex++; const nextSentence = TYPINGS[currentSentenceIndex]; renderTextWithSpans(nextSentence); typingInput.value = ''; userInputArray = []; typingInput.setAttribute('maxlength', currentTypingText.length); } // 엔터를 눌렀을 때 다음 문장 로드 typingInput.addEventListener('keydown', (_event) => { if (_event.key === 'Enter') { // 기본 엔터 입력 방지 _event.preventDefault(); if (userInputArray.length === currentTypingText.length) { if (currentSentenceIndex < TYPINGS.length - 1) { // 엔터를 눌렀을 때 다음 문장 로드 loadNextSentence(); } else { // 마지막 문장일 때 결과 팝업 표시 showTypingResult(); } } } });다음 문장으로 넘어가는 함수에서는 textarea에 maxlength값을 넣어 타이핑해야 하는 글자 수 이상으로 타이핑하지 못하게 했다. enter을 눌렀을 때 다음 문장으로 바뀌는 방법으로 했더니 다음 문장으로 넘어갔을 때 textarea에 enter가 입력되면서 줄바꿈 처리가 되어서 _event.preventDefault(); 로 줄바꿈이 되지 않게 했다.function startTimer() { timerInterval = setInterval(() => { if (currentTime > 0) { currentTime--; timeElement.textContent = currentTime; } else { clearInterval(timerInterval); typingInput.disabled = true; showTypingResult(); } }, 1000); }마지막 문장까지 입력하고 enter을 누르면 결과 팝업이 뜨지만 처음 설정해둔 시간이 다 됐을 때도 결과 팝업이 뜬다.function initializeTypingTest() { calculateTotalCharacters(); const firstSentence = TYPINGS[0]; renderTextWithSpans(firstSentence); typingInput.setAttribute('maxlength', currentTypingText.length); errorsElement.textContent = INITIAL_ERRORS; timeElement.textContent = INITIAL_TIME; accuracyElement.textContent = INITIAL_ACCURACY; typingInput.value = ''; }초기 값들도 상수로 선언해서 화면을 초기화 하는 함수에서 사용했다.이번에는 과제를 하기 전에 자바스크립트 명명 규칙을 지켜서 해보기로 했다. 자바스크립트 미션 중에서 제일 오래 걸렸던 미션이다. 처음 구현했을 때 생각했던대로 작동하지 않아서 어떻게 만들어야할지 고민이 많았다. 계속 수정해가며 기능을 완성시키기는 했는데 이게 맞는지.. 어려웠다.

워밍업클럽

Taeho

인프런 워밍업 클럽 - CS Day 7

Algorithm재귀 사용하는 패턴단순 반복문반복문으로 구현했을 때보다 이점이 되는 부분이 없음Call Stack에 공간을 많이 차지해 성능이 반복문보다 좋지 않다.하향식 계산하향식 계산 : 하위문제의 결과를 기반으로 현재 문제를 계산하는 방식재귀가 반복문보다 성능이 좋은 경우큰 문제를 해결하기 위해 작은 재귀 함수를 호출한다.재귀를 사용해서만 구현이 가능하다.상향식 계산 : 하위 문제를 모아서 현재 문제를 계산하는 방식반복문으로 구현한 것보다 성능이 좋지 않음반복문이나 재귀를 사용해서 구현할 수 있다.OSProcess간 통신하나의 컴퓨터 내에서 프로세스간 통신하는 방법Pipe운영체제가 생성한 파이프를 이용해 데이터를 읽고 쓰는 방법File통신을 하려는 프로세스들이 하나의 파일을 이용해 읽고 쓰는 방법Thread를 이용한 통신하나의 프로세스 내에서 쓰레드간 통신하는 방법쓰레드는 코드, 데이터, 힙 영역을 공유한다.(스택 영역만 별도로 갖는다.)데이터 영역의 전역 변수나 힙 영역을 이용하여 통신할 수 있다.NetworkOS가 제공하는 Socket 통신RPC(Remote Procedure Call)다른 컴퓨터의 함수를 호출하는 방법공유자원과 임계구역공유자원 : 프로세스간 통신을 할 때 공용으로 이용하는 변수나 파일여러 프로세스가 공유하기 때문에 각 프로세스의 접근 순서에 따라서 결과가 달라질 수 있다.컨텍스트 스위칭으로 시분할 처리를 하기 때문에 프로세스간의 실행 순서를 예측하기 어렵다.⇒ 동기화 문제가 발생할 수 있다.임계규역 : 여러 프로세스가 동시에 사용하면 안되는 영역상호배제 메커니즘을 통해 해결할 수 있다.경쟁조건 : 공유자원을 사용하기 위해 서로 경쟁하는 것상호배제 요구사항임계영역엔 동시에 하나의 프로세스만 접근한다.여러 요청에도 하나의 프로세스의 접근만 허용한다.임계구역에 들어간 프로세스는 빠르게 나와야한다.Semaphore상호배제 메커니즘의 한 종류Semaphore :  정수 값을 가지는 변수로, 공유 자원에 접근할 수 있는 프로세스/스레드의 수를 나타낸다.세마포어를 갖고 있는 프로세스가 실행되고 세마포어를 반납한다.기본 연산wait(S): 세마포어 값을 감소시킨다.값이 0이면 프로세스/스레드를 대기 상태로 만든다.signal(S): 세마포어 값을 증가시킵니다.대기 중인 프로세스/스레드가 있다면 깨운다.종류이진 세마포어: 0과 1 두 가지 값만 갖는다.(뮤텍스와 유사하게 사용한다.)카운팅 세마포어: 0 이상의 정수 값을 갖는다.(여러 자원을 관리할 때 사용된다.)장단점장점: 여러 프로세스/스레드 간의 복잡한 동기화 문제를 해결할 수 있다.단점잘못 사용하면 교착 상태나 기아 상태를 유발할 수 있다.ex) 세마포어를 획득하는 함수와 세마포어를 반납하는 함수의 위치 잘못 사용Mutex(MUTual EXclusion)뮤텍스는 이진 세마포어의 특수한 경우여러 스레드가 공유 자원에 동시에 접근하는 것을 방지하는 기술기본 연산Lock: 스레드가 임계 영역에 진입할 권한을 획득Unlock: 임계 영역 사용을 마치고 다른 스레드가 진입할 수 있게 한다.뮤텍스와의 차이세마포어는 여러 프로세스/스레드의 접근을 허용할 수 있지만, 뮤텍스는 하나의 프로세스/스레드만 접근을 허용한다.Monitor세마포어의 단점을 보완한 상호배제 메커니즘OS가 처리하는 것이 아니라 프로그래밍 언어단에서 지원하는 기능ex) Java : synchronized 키워드한 번에 하나의 프로세스/스레드만 실행할 수 있다.

알고리즘 · 자료구조워밍업클럽CS전공지식DAY7

인프런 워밍업 클럽 스터디 2기 백엔드 - 1주차 회고록

항상 코드를 짜며 고민을 한다내 코드는 객체지향 적인가? 내 코드는 다른 사람이 와도 이해하기 쉬울까?(TMI: 갑자기 위 질문을 나한테 던져보다, 어떤 Youtube 강의 중에 '넌 전혀 restful 하지 않아' 라는 강연이 떠올랐다..) 이 부분에 대한 대답으로는 간단하게 시니어 개발자들에게 코드 리뷰 를 받게 되면 점진적으로 좋은 코드가될 수 있을 것 같다. 하지만 현재 혼자 공부하고 있는 입장으로서, 누군가 한테 내 코드 리뷰를 받을 수가 없어,혼자 클린 코드에 대한 고민을 하며 코드를 작성하고는 한다. 그래서 위 워밍업 클럽을 신청하게 되었고, 겸사 겸사 테스트 코드 학습도 하게 될 것이라더 많은 지식을 얻게 될 생각에 벌써 머리가 아프지만, 기분이 좋다. 1주차Readble - Code 에 Section1 ~ Section5 까지 의 강의를 들었다.클린코드 관련 키워드 및 클린 코드 방법을 공부하기 위한 강의라 생각했지만내용이 너무너무 알찻다. OOP 및 SOLID 원칙 등 너무 좋은 내용에 대한 인사이트를 얻게 되었고,강의자 님을 전달력이 너무 좋아, 귀에 쏙쏙 들어왔기에 2배로 효율적이라고 생각한다. 위 섹션들을 들으면서 공통적으로 느끼는 건사고 하는 방법에 정말 많은 도움이 되는 것 같다. 한가지 사고방식에 사로잡히는게 아닌, 여러 방향으로 유연한 사고를 할 수 있게 도와준다. 프로그래밍 머리는 제로인 내가 들었을 때 한번에 50% 이상 이해가 된 강의는 처음이다. 특히 요일 별로 섹션을 나눠 듣고, 꼭 실천해야한다는 의무감 및 책임감도 있고강의 내용을 더욱 더 깊게 이해하기 위한 미션들을 수행하면서 한층 더 성장한 듯한 느낌을 받았고다른 개발자들의 글들을 보며 동기부여 및 다양한 인사이트 를 얻게 되어 감사하다. 강의수강 요약강의에서 제일 기억에 남는 부분은섹션3 파트이다. 사람은 생각을 하고 살아야한다.생각도 아무런 생각이 아닌, 논리와 사고의 흐름을 가지고 있어야 한다고 생각한다. 위 내용을 프로그래밍에 빗대어 설명을 해주셨고 내용들이 귀에 쏙쏙 박혀서 너무 좋은 섹션이였다.'뇌 메모리 적게쓰기' 에 대한 해답을 찾기 위해 노력을 해보는 계기가 되었다.  미션미션은 총 2개를 진행하였고, 아직 까지 크게 어려운 내용은 있지 않았다.왜냐? 추상적인 내용을 바탕으로 내 생각을 표현하는 미션이 였고누가 틀렸네, 맞았네 의 그런 미션이 아니었기 때문이다 하나 코드 문제가 있긴했는데, 간단한 리팩토링에 대한 미션이라강의를 잘 듣고 생각나는 키워드를 바탕으로 미션을 해결할 수 있었다.사실 해결이라는 단어가 좀 모호하긴 한대, 내 기준에서는 그래도 나름 객체지향 적으로 리팩토링을 해보았다..   모든 정리 내용은 Github 에 기록을 해두었습니다.

백엔드OOPJava

예진안

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

DAY 6 과제운영체제 -섹션 3유닛 5,6,7 SJF,RR, MLFQ알고리즘 - 섹션 3 유닛 1 재귀 알고리즘재귀함수란 자기 자신을 호출하는 함수콜스택에 자리를 많이 차지하여 메모리효율에 떨어진다.콜스택 : 프로세스에서 코드,데이터, 힙,스택 으로 메모리 영역이 있다. 그 중 하나콜스택은 함수가 First In Last Out으로 처음 들어가는 함수가 나중에 나온다.재귀함수가 호출될 때마다 콜스택에 계속 쌓이는데 거기서 메모리 효율이 떨어진다.그럼에도 불구하고 사용하는 이유팩토리얼을 표현하기 편리하다.팩토리얼 : 1부터 n까지 모두 곱하여 표현하는 것 (표기 5!)5! =5*4*3*2*1 function facto(num){ if(num == 1 || num == 0){ return 1; }else{ return num * fac(num-1); //5 * fac(4)= 5 * 4 * fac(3).... } }운영체제SJFShort Job FirstFIFO 의 단점을 보안해보려고 만든 알고리즘이지만brustTime(대기시간)이 너무 긴 프로세스에게는 계속 밀려나서 불리한 알고리즘프로세스의 실행시간을 예측하기도 어렵기 때문에->실패해버린 알고리즘 ㅜㅜ RRRound Robin실행시간이 다끝날 때까지 기다리는 FIFO 과 SJF 단점을 보안해서타임 슬라이스를 부여해서 일정 시간이 지나면 프로세스가 cpu 할당하는 것을 끊고맨 뒤로 보내버리는 알고리즘RR 대기시간 = FIFO 대기시간 -> RR은 비효율적인 방식!RR은 컨텍스트 스위칭에 시간을 더 많이 사용하기 때문RR은 타임슬라이스의 크기에 따라 효율이 달라진다.타임 슬라이스⬇, 컨텍스트 스위칭⬆ -> 배보다 배꼽이 더 커진다.타임 슬라이스 ⬆, 사용자가 여러 프로세스를 같이 사용할 때 버벅임을 느낄 수있다.하지만 실제 타임슬라이스는 1ms으로 설정되어 있다~ MLFQMulti Level Feedback QueueRR 업그레이드 버전타임 슬라이스의 크기에 따라 달라지는 알고리즘 이다.CPU Bound Process :cpu 사용률과 처리량을 제일 중요 시 여긴다.I/O Bound Process : 입출력 장치 사용률과 처리량을 제일 중요 시 여긴다. 타임 슬라이스 크기 차이에 따라 i/o 사용률이 확연히 다른 걸 볼 수있지만,오른쪽 p1은 컨텍스트 스와칭⬆, 오버헤드도 ⬆p1과 같이 실행시간이 긴 애들은 오버헤드와 같은 불공평을 견뎌야한다...->MLFQ를 사용해서 불공평을 없애보자!cpu 바운드프로세스와 입출력 바운드 프로세스 각각 다른 타임 슬라이스를 부여한다.->구분해야된다.구분하는 방법!cpu 바운드 프로세스 일 경우 cpu 사용하는 프로세스가 타임슬라이스 크기를 오버해 cpu 스케줄러에 의해 강제로 cpu를 빼앗기는 상황이 생긴다.반대로 입출력 바운드 프로세스는 스스로 cpu를 반납하려는 상황이 생긴다.(cpu 사용률 적음)이 방법을 토대로 우선순위와 타임슬라이스에 따른 큐를 준비한다.👇1. 프로세스가 우선순위 1큐에 들어간다.2. 타임슬라이스 크기를 오버해 강제로 CPU를 뺏긴다-> 우선순위 2 큐로 우선순위가 낮은 큐로 이동=> 우선순위에 밀릴수록 타임 슬라이스크기가 커지고 CPU를 효율적으로 사용할 수 있는 환경이 된다.다른 알고리즘은 되게 친근했는데 MLFQ는 들을 때 예? 하면서 한 번씩 다시들었다.사실 공부했던 건데 큐와 큐사이를 이동할 수 있는 알고리즘임~ 하고 외워버리기만하고 이렇게 자세하게 보지 않았던 것 같다.

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

ppusda

인프런 워밍업 클럽 2기 - 백엔드 프로젝트(Kotlin, Spring) / 1주차 발자국

⭐ 1주 동안 배운 내용을 정리하고 회고하는 시간을 가져보자. 복습한다고 생각하고 간단하게 요약하며 정리해보자. ╰(°▽°)╯1일차 - 웹 기본 개념 이해하기웹 서비스의 구성 요소클라이언트 [요청하는 주체] ↔ 서버 [응답하는 주체] ↔ 데이터베이스 [데이터 집합]클라이언트는 요청하는 주체이며, 사용자 혹은 고객이라고도 표현한다.서버는 응답하는 주체이며, 요청받은 결과를 클라이언트 측으로 응답한다.데이터베이스는 데이터의 집합이며 이를 관리하는 DBMS를 일반적으로 DB라고 부른다. 브라우저에 주소를 입력하면 벌어지는 일클라이언트가 브라우저에 https://www.google.com 을 입력하면 어떻게 될까?클라이언트가 보낸 주소를 DNS 서버에서 IP로 변환하여 알려준다.클라이언트는 해당 IP 주소로 서버에 요청을 하며, 서버는 요청 데이터를 처리한다.처리 완료된 응답 데이터를 다시 클라이언트 측에 전달한다. DNS? (Domain Name System)DNS는 사용자가 흔히 보는 www.google.com과 같은 도메인 이름을 IP로 변환하는 시스템이다.DNS 서버는 이러한 변환 역할을 대신 수행해주는 서버이며, KT, SKT, LG, Google 등이 이러한 서버를 제공한다. 웹 프레임워크Framework, 프레임워크?프레임워크는 공통적으로 요구되는 기능들을 보다 편리하게 만들 수 있도록 해주는 뼈대, 구조이다.제어의 주도권을 프레임워크가 가지고 있으며, 틀 안에서 주어진 것을 활용해야한다. Library, 라이브러리?라이브러리는 활용 가능한 도구들의 집합으로 제어의 주도권을 사용자가 가지고 있으며 정해진 틀 없이 사용자가 원하는 것을 만들 수 있다. Spring FrameworkMVC 패턴 (Model-View-Controller)소프트웨어 아키텍쳐 디자인 패턴으로 Model, View, Controller로 각 역할을 분담하여 결합도를 낮추고 유지보수를 용이하게 할 수 있다.Model - 데이터 처리View - 보여지는 화면 처리Controller - 클라이언트 요청 처리 레이어드 아키텍처 (Controller-Service-Repository)가장 대중적인 소프트웨어 아키텍처로 Controller, Service, Repository로 구분하여 사용한다.Controller - 클라이언트 요청 처리Service - 비즈니스 로직 (핵심 로직) 처리Repository - 데이터베이스 접근 처리 Spring Bean과 의존성 주입Spring Bean은 스프링에서 관리되는 객체를 뜻한다.이는 스프링 컨테이너가 직접 관리하기에 제어의 역전(Inversion of Control; IOC)라고 부르며 스프링에서 의존성을 주입해주어 객체를 사용할 수 있다.생성자 주입, 수정자 주입, 필드 주입의 방법이 있지만, 런타임 시 수정자를 통해 의존성이 바뀌거나 의존하는 Bean을 누락했을 시 컴파일 단에서 오류를 잡아낼 수 있기 때문에 생성자 주입을 추천한다.생성자 주입@Service class PresentationService (private val presentationRepository: PresentationRepository) { ... } 수정자 주입private lateinit var presentationRepository: PresentationRepository @Autowired fun setPresentationRepository(presentationRepository: PresentationRepository) { this.presentationRepository = presentationRepository } 필드 주입@Autowired private lateinit var presentationRepository: PresentationRepository HTTP와 REST APIHTTP (Hyper Text Transfer Protocol) 는 서버와 클라이언트 간 어떻게 데이터를 교환할지를 정해놓은 통신 규약이다.HTTP 요청 메서드GET - 읽기 작업을 처리할 때 사용됨POST - 쓰기 작업(생성)을 처리할 때 사용됨PUT (전체 수정) / PATCH (부분 수정) - 쓰기 작업(업데이트)를 처리할 때 사용 됨DELETE - 삭제 작업을 처리할 때 사용 됨HTTP 상태 코드2xx : 정상 처리3xx : 리다이렉션 - 페이지 이동이 이루어져야 함4xx : Bad Request - 클라이언트 측 요청 오류5xx : Internal Server Error - 서버 측 오류REST API클라이언트와 서버 간 인터넷을 통해 정보를 안전하게 교환하기 위해 사용하는 규칙이다.RESTful 하게 API를 작성하려면 URL만으로 어떤 자원에 대해 어떻게 처리할 건지 파악할 수 있어야 한다.POST /members ⇒ O, Post는 생성을 처리할 때 사용 / member 생성하기 위한 요청임을 알 수 있다.POST /createNewMember ⇒ X, RESTful 하지 않음 2일차 - 데이터베이스 기본 개념데이터베이스1일차에 소개했던 것 처럼 데이터의 집합이다.이를 관리하는 툴을 DBMS (Database Management System)이라고 부른다. RDBMS, 관계형 데이터베이스행과 열로 이루어진 표의 형태로 저장되는 데이터베이스하나의 행은 데이터, 열은 각 데이터의 특징이라고 할 수 있으며 이것들이 모여 하나의 테이블(표)이 된다.각 테이블을 조인하여 정보 간의 관계나 링크를 설정할 수 있는 기능이 있으며, 이를 통해 여러 데이터 간의 관계를 설정할 수 있기에 관계형 데이터베이스라고 부른다.⇒ Oracle, MySQL, PostgreSQL 등이 이에 해당된다. NoSQL, 비관계형 데이터베이스관계형 데이터베이스를 제외한 모든 종류의 데이터베이스를 비관계형 데이터베이스로 분류한다.⇒ MongoDB, Redis 등이 이에 해당된다. JPAJPA (Java Persistence API)는 자바 진영 ORM 기술의 표준이다.ORM (Object Relational Mapping)은 객체 관계를 매핑해주는 기술로 객체지향 프로그래밍의 객체와 데이터베이스를 매핑해주는 역할을 한다.장점특정 DB에 대한 의존성을 줄일 수 있음쿼리를 직접 작성하지 않아도 됨데이터에 객체지향적인 관점에서 접근이 가능함단점ORM 만으로는 한계가 있기에, 복잡한 쿼리의 경우 네이티브 쿼리를 작성해야 함JPA에 대한 충분한 학습이 이루어진 후 사용해야 함. 영속성 컨텍스트JPA에서 Entity를 관리하는 저장공간이다.애플리케이션과 데이터베이스 사이에서 Entity를 보관하는 가상 데이터베이스 역할을 한다.아래에선 이 영속성 컨텍스트의 3가지의 특징을 소개하려고 한다.1차 캐시영속성 컨텍스트 내부의 캐시를 1차 캐시라고 부른다.조회한 결과를 캐시 공간에서 먼저 찾아보고 쿼리를 수행 할지 결정한다.더티 체킹영속성 컨텍스트 내에서 Entity의 변화가 감지됬을 경우 이를 데이터베이스에 자동으로 적용하는 기능을 더티 체킹 또는 변경 감지라고 부른다.최초로 데이터를 조회할 때의 스냅샷을 보관해두고 이를 트랜잭션 종료 시점과 비교하여 변경된 내용을 적용하는 것이다.쓰기 지연쓰기 작업을 즉시 수행하지 않고, 영속성 컨텍스트 내에 모아두었다가 트랜잭션이 종료될 때 한 번에 수행한다. 트랜잭션트랜잭션은 데이터베이스에 적용할 여러 작업을 하나로 묶어주는 논리적 단위이다.커밋, Commit : 트랜잭션으로 묶인 모든 작업을 데이터베이스에 영구히 반영하는 작업롤백, Rollback : 트랜잭션으로 묶인 모든 작업을 원상복구 하는 작업 3일차 ~ 5일차 (실습)이번 실습 내용에서는 기존에 알고 있던 내용은 제외하고 실습을 진행하면서 알게 된 Kotlin 문법에 대해서 조금 정리해볼까 한다.@Entity class Achievement( // 여기가 생성자 title: String, description: String, achievedDate: LocalDate?, // null 허용 (=일 수도 있다.) / 반대로 !!는 null이 아니다를 표현함 host: String, isActive: Boolean ) : BaseEntity() { // BaseEntity 상속 // 생략 var isActive: Boolean = isActive } 위는 실습 중에 작성한 Entity의 일부이다.Java와는 다르게 Class명 옆에서 생성자를 정의할 수 있고, 변수명: 타입 과 같은 구조를 가지고 있다.타 클래스 상속을 위해서 : BaseEntity()와 같이 사용한 부분을 볼 수 있다.변수를 선언할 때는 var 또는 val을 쓴다.var ⇒ 읽기/쓰기가 가능한 일반 변수val ⇒ 읽기만 가능한 final 변수 nullable을 표현할 수 있다.? ⇒ null 일 수도 있다fun getEndYearMonth(): String { if (endYear == null || endMonth == null) { return "Present" } return "${endYear}.${endMonth}" } 이어서 함수 부분이다.Java와는 다르게 메서드를 정의할 때 fun을 통해 선언하며, String을 반환할 때 프론트에서 사용하던 것 처럼 ${} 사이에 변수를 넣어 처리를 할 수 있었다. 번외 - 서브 미션 과제워밍업 클럽 2기 - 백엔드(Kotlin, Spring) 과정에서는 서브 미션을 수행하도록 과제가 주어진다.현재 기획한 내용은 음악 플레이리스트를 만들 수 있는 미니 프로젝트를 기획하고 테이블 설계까지 완료 하였다.https://github.com/ppusda/MML 단순하게 요즘 듣는 음악 리스트를 공유하기 위한 프로젝트로 기획하게 되었으며, 설계한 테이블은 아래와 같다.User 별로 플레이리스트를 생성하여 음악 목록을 만들 수 있게 해두었고, 목록을 관리하기 위해 각 테이블을 분리하였다.미션 내용이 단순히 CRUD 까지 밖에 없어서 임의로 데이터를 추가하거나, 향후 시간이 난다면 실제 데이터를 불러와서 이용할 수 있게 해볼까 한다. 총 회고오랜만에 기초부터 복습하는 느낌이 들어 면접 준비한다는 느낌으로 중요한 내용만 추려서 정리해보았다.아직 1주차라서 많은 내용을 다뤄보지는 못한 것 같고, 앞으로 실습 면에서 Kotlin 문법을 기억 속에서 되찾으며 여러모로 부족한 부분을 찾아가며 배워보면서 즐겨 볼 생각이다.  모두 화이팅! (o゚v゚)ノ

백엔드워밍업클럽백엔드2기Kotlin

코딩박사 잇잇쌤(IT Eat)

인공지능 머신러닝/딥러닝 , Rust 강사 코딩박사 잇잇쌤입니다!

안녕하세요 ~코딩박사 잇잇쌤입니다!14년차 개발 프리랜서 강사 이고, IT 용어부터 간단명료하게 쉽게 진입 장벽을낮춰드리는 매직을 부리겠습니다!( 아 잇잇쌤은 IT를 Eat 냠냠 하는 과정을 표현했습니다!! )제가 IT업계에 들어온 계기는...19살때, 해커학원? (그때는 코딩강의가 없고 오프라인 학원이 다 해커학원이었다는.. 당시... C언어가 재밌었던 이유가 포인터때문에 ..나홀로 여자혼자 배운다..라는 자부심도 있었던 것 같음) C언어를 배운 것을 시작으로, 대학교때 안드로이드 1 개발 을 시작으로, 외국계 테스팅 을 위해서 인턴쉽도 경험도 쌓고, 그 이후, 2012년도에 중견 IT업계 System Integration 회사에 입사해서 밤샘도 많이 했으며, System Management 를 다년간 경험하면서 느낀 험난했던 과정 속 나도 모르게 노하우를 쌓아왔습니다. (좋코딩에서, 웹드라마 주인공이 과거의 딱 저라는...)이후 대기업에서 IT관련 강의, 지식을 공유 흥미를 느껴,프리랜서로 나와, IT 관련 수업도 진행하면서 내가 그동안 배웠던 언어들 JAVA, Javascript, ABAP,C, Database 등을 정리하면서 코로나의 블루를 타파하고자 미니 프로젝트등을 진행 했었고,파이썬 등, 알고리즘, AI 머신러닝 , 딥러닝 기술 등을 숨고를 통해 나눈 경험이 있습니다.안티에이징을 위해서 마치 백신 주입하듯이 , 신기술을 배워야 살아 남는게 이 업계의 특성인데, 가장 쉽게 배우는 방법을 터득하면서 여러분들과 소통하고 싶어 졌습니다 !~!!이후, 코로나가 끝나고 운 좋게, 강의를 촬영해커스 HRD 에서 "Rust 기초부터 실무까지 과정"https://www.hackershrd.com/lecture_240216.php?mode=lecView_240216&pcate=cate&scate=002&product_key=01::nref%3E0%3EB007%3EM056&p_id=0000000000&s_id=Y24M062602메가스터디아카데미 "인공지능 기초" 과정https://megastudyacademy.co.kr/camp/lecture/801멋사넥스트 (멋쟁이사자처럼) "AI를 활용한 파이낸셜 모델링(PF) 과정"https://www.likelion-next.com/classes/215041한빛앤 과 다수 협업하면서 VOD강의를 출시하기도 하였습니다!!이제는 인프런에서 여러분들과 만날 수 있게 되어 영광입니다.저는 5시간 동안 카메라 앞에 서서 여러분들께 설명하는데 너무 즐거워서 지치지 않습니다.저의 강의에 대한 지치지 않고 포기하지 않는 열정!열정!열정!으로당신이 허락한 시간 안에 모든걸 쏟아 붇겠다라는 마음 가짐으로 항상 임해오고 있습니다.나중에 기회되면 라이브 강의에서 만나면!반갑게 알아봐 주시면 너무!너무!너무! 반가울 것 같습니다 !인공지능이 도대체 뭐길래 배우는 거지? 🔎비전공자 분들, 향후에 미래에 어떤 언어들이 유망한지, 현업이신데 엑셀 로만 데이터를 분석하고 계신 분들, 개발자 10년이상되셔서 좀 변화가 필요하신 분들은 PM님 C레벨 이사님들! 모두 모두 이 강의를 주목해주세요.저도 14년차 개발자로, 일해오면서 안티에이징 (똑같은 업무에 질려 노화되는 현상) 을 위해서 많은 노력을 해왔어요.그중에 가장 특효약이 바로 인공지능 기초과정 (머신러닝,딥러닝,신언어1개 배우기) 였어요!제가 그동안 Java나 C++,자료구조 많이 가르쳐봤는데!Rust나 AI 과정을 준비하면서 너무 신세계인거에요!이렇게 운영체제 모르고 코딩했구나... 이렇게 효율적인 메모리 언어를 그동안 몰랐구나,CTO가 결정한 솔루션이 사용하라는 대로 그 언어만 계속 사용해 왔구나! 밤샘으로 후회스럽더라구요!하면서, 앞으로는 다양한 좋은 언어들 배워 봐야 겠다 라는 욕심이 생겼어요!그래서 다양한 강의를 만들면서 가르치고 알려주고 상대방과 소통하면서 이해가 된다고 개발 커리어를 위해서다양한 과정들을 도움이 되었다고 할 때, 너무 행복함을 느꼈답니다!여러분들의 로드맵 참여는 저에게 큰 힘이 됩니다!!!많은 관심 주시면 저도 다양한 강의가 준비되어있으니까 앞으로 인프런에 강의도 기회되면 올릴거고 다양하게 만날 수 있게 노력하겠습니다~숨고 후기보기 ! : https://soomgo.com/profile/users/1949734?from=portfolio뭐 어쨌든 결론은 !!! 저의 로드맵에 참여해주세요~ 😍😍▼▼▼▼▼▼▼▼▼https://inf.run/9Vjfz

딥러닝 · 머신러닝

서상연

인프런 워밍업 클럽스터디 2기 FE - 1주차 발자국

강의변수선언방법: var, let, constvar: 중복선언 및 재할당이 가능하다. 예전부터 사용함let: 중복선언은 할수 없고 재할당만 가능하다. 주로 일반 변수 선언 시 사용한다.const: 중복선언 및 재할당을 할 수 없다. 주로 상수 선언 시 사용한다. 유효범위(scope)var: 함수레벨(function-level scope)let, const: 블럭레벨(block-level scope)let, const는 블록안에서만 접근할 수 있음 hoistingvar: 선언되기 전 변수를 먼저 호출하면 undefined로 초기화 되어 표시되고 함수의 경우에는 위로 끌어올려 정상적으로 실행됨let, const: 값이 선언되기 전 호출하면 초기화 오류를 발생, 함수도 실행되지 않음. 초기화 전까지 TDZ(Temporal Dead Zone)이라하여 일시적인 비활성 상태임타입원시타입: Boolean, String, Number, null, undefined, Symbol => Call Stack에 값이 저장참조타입: Function, Object, Array, Class => Heap메모리에 저장자바스크립트 동적 타입이다. thismethod: 해당 객체를 가리킨다.함수: window 객체를 가리킨다.constructor 함수: 빈 객체를 가리킨다.Event LoopClosure다른 함수 내부에 정의된 함수를 리턴하여 외부 함수가 실행된 후에도 외부 함수 내 변수나 함수에 액세스 할 수 있다.구조분해할당배열이나 객체의 속성을 해체하여 개별 변수에 담을 수 있게 하는 Javascript 표현식전개연산자 특정 객체나 배열의 값을 다른 객체, 배열로 복제하거나 옮길 때 사용.

프론트엔드FE인프런워밍업클럽2기

김예지

[인프런 워밍업 스터디 클럽 2기 FE] 2주차 과제 - 비밀번호 생성 앱

 비밀번호 생성 앱 만들기GitHub : 06-password-generation 개요조건에 따른 비밀번호 생성 기능 구현Generator, Design Pattern 을 사용해보기 필요한 기능조건에 따른 비밀번호 생성생성된 비밀번호 복사 기능 구현하기//문자 범위 const charSets = { numbers: '0123456789', small: 'abcdefghijklmnopqrstuvwxyz', capital: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', symbols: '@!#$&%', }; //사용자 체크박스 설정 function getOptions() { return { numbers: document.getElementById("numbers").checked, small: document.getElementById("small").checked, capital: document.getElementById("capital").checked, symbols: document.getElementById("symbols").checked, }; }createButton.addEventListener("click", () => { const length = parseInt(inputLength.value, 10); const options = getOptions(); /*비밀번호 생성 최소 조건 생략 */ //Generator 사용할 때 const generatedPassword = generatePassword(length, options); //Factory Pattern 사용할 때 const generator = PasswordFactory.createPasswordGenerator(options); const generatedPassword = generator.generate(length); passwordElement.textContent = generatedPassword; }); 사용자가 선택한 비밀번호 길이와 옵션을 전달받아 비밀번호를 생성한다. 위의 설정들과 shufflePassword(password) 비밀번호 셔플 함수, copyToClipboard(text) 생성된 비밀번호 복사 함수는 같고 비밀번호 생성 과정만 다르다. Generator 사용function generatePassword(length, options) { const generator = passwordGenerator(options); let password = ""; // 선택된 옵션 배열 추가 const selectedSets = []; if (options.numbers) selectedSets.push(charSets.numbers); if (options.small) selectedSets.push(charSets.small); if (options.capital) selectedSets.push(charSets.capital); if (options.symbols) selectedSets.push(charSets.symbols); // 각 문자 집합에서 하나씩 선택하여 추가 selectedSets.forEach((set) => { password += set.charAt(Math.floor(Math.random() * set.length)); console.log(password); }); // 나머지 자리에 대해 랜덤 문자 추가 for (let i = password.length; i < length; i++) { password += generator.next().value; } // 비밀번호를 섞어서 반환 return shufflePassword(password); } generatePassword(length, options)함수는 비밀번호를 생성하고 길이를 관리합니다.사용자 설정 옵션 반영:사용자가 선택한 옵션 값에 따라 selectedSets 배열을 만듭니다. 이 배열은 선택된 문자 집합(숫자, 소문자, 대문자, 기호)을 포함합니다. 최소 하나의 문자 포함:selectedSets 배열을 반복하여 각 문자 집합에서 최소한 하나의 문자를 포함시킵니다. 이는 비밀번호가 선택된 옵션을 만족하도록 보장합니다.남은 길이의 랜덤 문자 추가:나머지 비밀번호 길이에 대해서는 passwordGenerator를 사용하여 랜덤 문자를 생성합니다.비밀번호 반환: 최종적으로 생성된 비밀번호는 지정된 길이와 사용자 옵션을 반영하여 반환됩니다. function* passwordGenerator(options) { const selectedSets = []; if (options.numbers) selectedSets.push(charSets.numbers); if (options.small) selectedSets.push(charSets.small); if (options.capital) selectedSets.push(charSets.capital); if (options.symbols) selectedSets.push(charSets.symbols); while (true) { const randomSet = selectedSets[Math.floor(Math.random() * selectedSets.length)]; yield randomSet.charAt(Math.floor(Math.random() * randomSet.length)); } } passwordGenerator(options) 함수는 비밀번호를 생성합니다.무한 루프: while (true)를 사용하여 passwordGenerator()가 호출될 때 무한 루프를 실행합니다. 이 루프는 무작위 문자를 계속 생성하는 역할을 합니다.무작위 문자 집합 선택: 선택된 옵션 배열을 파라미터로 받아 randomSet에서 무작위로 하나의 문자 집합을 선택합니다. Math.random()을 사용하여 0과 1 사이의 무작위 소수를 생성한 후, 이를 selectedSets.length와 곱하여 배열의 인덱스를 얻습니다. Math.floor()를 사용하여 소수를 정수로 변환함으로써 유효한 인덱스 범위 내에서 선택이 이루어지도록 합니다.무작위 문자 선택: 위에서 선택된 문자 집합(randomSet)에서 문자를 선택합니다.예를 들어, 선택된 randomSet이 '0123456789'일 때, Math.random()이 0.65를 반환하면 0.65 * 10 (randomSet.length) = 6.5 → Math.floor()에 의해 6이 되고charAt(index) 메서드를 사용하여 문자열에서 지정된 인덱스에 있는 문자를 반환합니다. 랜덤 문자 생성 반복: 이 과정을 호출될 때마다 반복합니다.  Factory Pattern 사용// 비밀번호 생성기 클래스 class PasswordGenerator { constructor(options) { this.options = options; this.selectedSets = []; if (options.numbers) this.selectedSets.push(charSets.numbers); if (options.small) this.selectedSets.push(charSets.small); if (options.capital) this.selectedSets.push(charSets.capital); if (options.symbols) this.selectedSets.push(charSets.symbols); } // 비밀번호 생성 generate(length) { let password = ""; this.selectedSets.forEach((set) => { password += set.charAt(Math.floor(Math.random() * set.length)); }); while (password.length < length) { const randomSet = this.selectedSets[Math.floor(Math.random() * this.selectedSets.length)]; password += randomSet.charAt(Math.floor(Math.random() * randomSet.length)); } return shufflePassword(password); } } class PasswordFactory { static createPasswordGenerator(options) { return new PasswordGenerator(options); } }PasswordFactory.createPasswordGenerator(options) 를 호출하여 PasswordGenerator 인스턴스를 생성한 후, 인스턴스의 generate(length) 메서드를 통해 비밀번호를 생성한다.  배운 걸 사용해보고자 Generator 함수와 클래스를 썼다.   

워밍업클럽

[Readable Code: 읽기 좋은 코드를 작성하는 사고법 회고 1주차

출처 : Readable Code: 읽기 좋은 코드를 작성하는 사고법 / 박우빈 1. 회고저자께서 회고 방식에 대한 아티클을 소개해주셨고 KPT로 진행 후 주차별로 다른 회고 방식을 적용해보려고 합니다. Keep(만족했고 지속할 부분)단순히 따라치는 수준에 그치더라도 직접 코드 작성 미션 전 수강 내용 훑어보고 진행하기 Problem(부정적 또는 아쉬웠던 부분)강의 수강 전에 목표 달성 실패목표 : 코드 분석 및 수강 전 리팩토링한 코드와 수강 후 리팩토링된 코드 비교실제 : 코드 분석은 했으나 리팩토링까지는 진행하지 못함 Trying(Problem 해결 방식으로 다음에 시도해볼 점)목표 설정 후 시간제한 두기시간제한 없이 루즈하게 진행하여 목표 달성도 실패했고, 결과물도 만족스럽지 못함 2. 학습 내용 요약추상(섹션1~2)이름짓기단복수에 의미 부여줄임말 사용하지 않기도메인 언어 사용(유행어, 은어, 방언 금지)좋은 코드 보고 습득필드 이름은 추상화하지 않음메서드명은 내부 처리 내용을 추상화  메서드 선언부메서드 선언부 : 반환타입 + 메서드명 + 파라미터메서드 시그니처 : 메서드명 + 파라미터반환타입에 대한 고민 : 반환할만한 값이 있는지? boolean이라면 true/false가 무엇을 의미할지?파라미터가 날짜 형태라면 String 형태보다는 LocalDate가 적절해보임전치사 잘 활용하기메서드 내에서 동일한 추상화 레벨로 묶여야함매직넘버 / 매직스트링 : 상수로 추출되지 않은 숫자나 문자 -> 리팩토링할 때 실제 의미가 같은 데이터만 변경했는지 확인 필요 논리, 사고의 흐름Early Returnif(){}else if(){}else{}구조 보다는 개별 if문과 return 사용(if의 조건을 else 까지 기억하기 어려움) 사고의 depth 줄이기중첩 분기문 / 중첩 반복문코드 분석이 어렵다면 depth 1로 줄이는 것 고려, 그러나 모든 것을 메서드로 추출하면 오히려 가독성이 떨어질 수 있음사용할 변수는 가깝게 선언하기공백 라인을 대하는 자세비슷한 역할단위로 끊어주기 부정어를 대하는 자세!isLeft=> isRight, isNotLeft ( 부정 연산자 !의 가독성이 떨어짐) 해피 케이스와 예외 처리예외 발생 가능성 낮추기 - 외부와의 접점의도한 예외와 예상치 못한 예외 구분return null 자제,Optional 사용 고려(단, Optional은 비싼 객체이므로 꼭 필요한 경우에만 사용)Optional을 파라미터로 받는 것은 안티패턴(Optional이 가진 데이터 null, optional null)Optional 해소 - isPresent().orElseGet(), orElseThrow(), ifPresent(), ifPresentOrElse() 사용++ orElse(), orElseGet(), orElseThrow() 차이 숙지 객체 지향 패러다임(섹션4)객체지향 설계객체와 외부 세계는 공개 메서드로 소통함책임 분리1개의 관심사로 명확하게 책임 정의setter 사용 자제객체에서 데이터를 꺼내어(getter) 분기처리하는 것이 아니라 공개 메서드에 필요한 정보를 입력하고 true/false 확인필드 수는 적을 수록 좋음 (totalPrice 같은 것은 성능상 이유가 아니라면 필요할 때마다 계산하여 반환  SOLIDSRP하나의 클래스는 하나의 변경 이유(책임)만 가져야 한다OCP확장에는 열려있고 수정에는 닫혀있다 -> 기존 코드 변경 없이 시스템 기능 확장LSP부모 클래스가 자식 클래스를 완전히 대체할 수 있어야한다.자식 클래스끼리 호환되지 않는 기능은 부모 클래스에서 제외ISP사용하지 않는 인터페이스에 의존하면 안됨(3개 중 2개는 쓰는데 1개는 사용하지 않는 경우 인터페이스를 분리해야함)DIP의존성의 순방향 : 고수준 모듈이 저수준 모듈 참조의존성의 역방향 : 고수준(고추상), 저수준(저추상) 모듈 모두 추상화에 의존구현체에 의존하는 것이 아니라 구현체의 추상(인터페이스)에 의존++ 참고DIP(Dependency Inversion Principle)DI(Dependency Injection) - "3" 제 3자가 의존성 주입IoC(Inversion of Control) 객체지향 적용하기(섹션5)상속과 조합상속보다는 조합상속은 결합도가 높음인터페이스 활용부모의 필드를 직접 참조하지 않는 것이 좋음Value Object도메인의 특정 개념을 추상화하여 표현한 객체불변성(final), 동등성(equals(), hashCode() 등, 내부 값이 같으면 같은 객체 취급), 유효성 검증(객체 생성 시점) 등 보장 필요++ VS EntityEntity단일 필드 식별자식별자만 같으면 다른 필드 값이 달라도 동등한 객체 취급VO전체 필드가 식별자모든 필드가 같아야 동등한 객체취급일급 컬렉션일급시민(ex 함수)변수로 할당 가능파라미터로 전달 가능함수의 결과로 반환 가능일급 컬렉션컬렉션만을 유일하게 필드로 가지는 객체컬렉션을 객체와 동등한 레벨로 다루기 위함단 하나의 컬렉션 필드만 가짐가공 로직 및 테스트 작성 가능반환할 때는 getter로 객체 주소를 반환하는 것이 아니라 새로운 컬렉션을 반환해야함 Enum의 특성과 활용상수와 상수 관련 로직 집합도메인 개념과 기능 명시 가능변경이 잦은 개념은 DB로 관리 다형성 활용하기OCP조건을 만족하는가?만족하면 행위 수행 숨겨져 있는 도메인 개념 도출하기도메인 지식은 발견하는 것객체지향은 현실을 흉내내는 것현실에서 인지하기 어려운 개념도 도출해서 사용할 때가 있음설계할 때는 최대한 미래를 예측해서 진행하고 틀렸을 때 언제든 돌아올 수 있도록 코드를 만들어야함   

백엔드

gusn9719

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

 인프런 워밍업 클럽 프론트엔드 2기의 1주차 발자국을 남기려고 한다. 이렇게 발자국이라는 회고의 개념을 이제까지 작성을 해본 적이 없다.여기서부터가 문제였다. 나태하고 수동적으로 살아왔던 나를 반성하게 된다. 이 워밍업 클럽을 계기로 이런 회고록 작성에 익숙해지는 것부터가 나에게는 한 발자국을 내딛는 경험이 될 것이고 이것을 바탕으로 능동적인 학습을 하고자 한다.처음으로 작성해보는 회고이기 때문에 형식이나 글의 흐름은 좋지 못할 것 같지만 처음으로 시도했다는 거에 의의를 두고 계속해서 성장해 나가는 발자국의 작성이 이번 워밍업 클럽의 가장 큰 목표이다. 일단 이번 1주차는 개인적으로 신청하고 해야할 일이 있어서 강의를 많이 듣지도 못했고, 과제도 다 완수하지 못했다.Day2 자바스크립트 기초 Section 2~4 일단 올해 초에 kdt 부트캠프를 시작해서 8월에 수료를 했기에 기본적인 프론트엔드의 개념은 대충은 알고있다.하지만 아무나 수강할 수 있었던 이름 없는 부트캠프였기에 부족한 게 많았다.물론 내가 더 노력했으면 이 시간들을 더 값지게 보낼 수 있었겠지만 처음 말했듯이 수동적인 삶을 살아 왔기에 주위에서 이 정도만 하는데 내가 굳이 더 무언가를 해야하나? 라는 핑계로 열심히 살지 않았던 거 같다.사설은 여기까지하고 부족한 게 많았던 부트캠프를 보내와서 대충은 알고 있던 개념들을 이번에 다시 한번 리마인드 한다는 느낌으로 꼼꼼히 열심히 들었던 거 같다. 개념을 다시 상기 시키는 것은 좋았지만, 이 부분들은 솔직히 완전한 이해라고 해야 할까? 외우는 것은 힘들 것 같다.그냥 생각 안 날 때마다 구글링을 하고 챗gpt에게 물어보는 게 좋을 것 같았다. 이 부분에 너무 오랜 시간을 쏟을 시간이 없을 거 같았다. 기초가 중요하다고 생각하지만 시간이 없다... 다음 번에 다시 또 복습을 하는 시간을 가지겠다... 꼭! 2일차의 미션은 음식 메뉴 앱이었다.gitHub 주소: https://github.com/gusn9719/inflearn_week1/tree/main/day2일단 완성은 했지만 솔직히 맘에 들지는 않는다. 나름 react 부트캠프를 수료한지 2달 밖에 지나지 않았는데 2달 사이에 또 너무 나태했었나 보다. 이런 간단한 앱을 만드는 것도 힘들었고 프론트엔드를 지망하는데 너무 css가 조잡해 보였다.이런 화면으로 완성을 했다.코드는 이런 식으로 작성을 했다. 이렇게 작성을 하고 더 나은 방법은 없을까 하고 내 코드를 챗gpt에게 보여준 다음에 개선을 부탁했다.gpt는 카테고리를 event로 가져왔고 filter 메소드를 이용해서 카테고리를 처리했다. 사실 내가 보기에는 거기 같지만, 무언가 가독성이 더 좋아진 걸 느낄 수 있었다. 나도 이런 코드 작성을 지향하기로 마음 먹고 2일차는 여기서 끝을 맞치겠다.Day3 자바스크립트 중급(1) Section 5 (1 ~ 8)3일차의 교육은 자바스크립트 this ~ Map, Filter, Reduce 까지었다.일단 this는 예전에 교육을 받을 때 화살표 함수에서 와 일반 함수에서 작동 방식이 달라서 이게 왜 이런 건지 이해가 안 가서 많이 알아봤던 기억이 났다. 결국 그때 알아 낸 건 화살표 함수가 더 늦게 정의 돼서 그랬다~ 대충 이렇게 알게 된 기억이 있다.그리고 bind, call, apply는 사실 아직도 정확히 모르겠다. 지금이야 강의를 들은 지 얼마 되지 않아 이렇게 작동합니다~ 라고 말을 할 수 있는 거지.... 이거를 내가 과연 한 달 뒤에도 기억을 할까 싶지만 내가 생각하는 코딩이란 모든 걸 완벽히 이해하려고 하면 박사 과정까지 해야지 나처럼 비 전공자가 기초 개념을 완벽히 이해하려고 하는 것은 다람쥐 쳇바퀴 도는 거라 생각을 해서 다시 상기 시키는 것에 만족을 하고 끝임 없이 모를 때 마다 검색을 해보고 다시 읽어보고 하다 보면 내껄로 만들지 않을까? 라는 생각을 하며 넘어 갔다.일단 중요한 개념은 this를 윈도우 객체가 아닌 전달 받은 인수를 사용할 수 있게 해주는 건데 거기서 내가 생각을 한 게 수동으로 this를 설정해서 외부 데이터를 사용하는 게 아니라면 화살표 함수를 사용해서 this를 어느정도 자동화 해서 사용하자~~~ 이런 느낌으로 기억을 하고 넘어가기로 생각했다.다음으로 Event Loop 는 예전에 처음 배울 때 신기해서 열심히 들은 기억이 있었기에 이걸 다시 들을 때 또 재밌었다. 그냥 이 프로그래밍이라는 게 작동하는 방식이라 재밌는 거 같다.내가 대충 이해한 개념을 적으면 자바스크립트는 단일 스레드로 한 번에 많은 일을 처리 할 수 없는 동기 언어여서 비동기 함수들은 일단 콜 스택에 들어가자 마자 외부 api로 넘긴다(ex web API) 그리고 외부 api에서 콜백 함수를 처리하고 task queue에 넘기고 이벤트 루프라는 친구가 콜스택이 언제 비지?~~하면서 계속 감시하다가 콜스텍이 비게 되면 task queue에 있는 값을 콜스택에 넘기고 그 로직이 실행되고 끝나는 형식으로 알고 있다. 요약하면:자바스크립트는 단일 스레드로 동작하며, 한 번에 하나의 작업만 콜 스택에서 처리할 수 있다.비동기 함수는 실행되면 Web API로 보내지고, 완료되면 Task Queue에 콜백 함수가 추가된다.이벤트 루프(Event Loop)는 콜 스택이 비었는지를 확인하면서 비면 Task Queue에서 콜백 함수를 콜 스택에 넣고 실행한다.내가 재밌게 들었던 개념을 다시 들어서 좋았다.클로저 개념은 조금 어려웠지만 데이터를 보호하는데 최적화 되어 있구나를 느꼈다. 변수의 스코프를 명확히 정의하고, 의도하지 않은 외부 접근을 차단하는 데 유용하겠구나~~~ 같은 느낌이다. 계속해서 구조분해 할당이다. 너무 글이 쓸데없이 길어지는 거 같아 핵심만 정리하고 넘어가겠다.기억할 핵심은배열과 객체의 값을 쉽게 추출해 변수로 할당할 수 있는 편리한 문법.장점은 간결하고 가독성이 좋다, 기본값 설정이 가능하다.주의할 점은 변수 이름 일치와 중첩된 구조, 그리고 변수 재선언입니다.나머지 내가 정리 안 한 개념들은 간단하거나 사용법이 정확히 기억이 안 나면 그때 그때 다시 검색을 해봐야 할 것 같은 개념들이다. 3일차의 정리가 너무 의식의 흐름대로 작성을 했지만... 다음 주의 나는 이런 점을 개선해서 작성하기로 맘 먹고 넘어가도록 하겠다... 3일차의 미션은 가위바위보 앱이었다.github 주소 : https://github.com/gusn9719/inflearn_week1/tree/main/day3이것도 어찌저찌 구현은 했다.진짜 이걸 작성하면서 class나 id의 작성과 네이밍이 너무 일관되지 않고 지저분했지만 이것 또한 내가 해결 해야 할 숙제로 생각했다.구현한 화면의 일부다.처음 과제의 예시를 보고 컴퓨터가 어떤 것을 냈을지 알려주면 좋을 것 같았고 한 판마다 보여주는 결과를 조금만 더 가시성 있게 승리하면 초록, 비기면 검정, 지면 빨강. 이 정도만 개선을 해서 만들어 봐야겠다 생각을 했고 구현을 했다.여기서 구조분해 할당을 적용하고 내심 뿌듯했다. 초반에 일단 구현을 하고 봐야지 하고 대충 지은 변수에다가 엄청난 양의 글자들을 적다보니 너무 코드가 길고 사람이 읽기에 가독성이 구리다는 걸 느끼고 배웠던 구조분해 할당을 적용했다.또 하나 재밌었던 것은 컴퓨터의 승리를 구현하는 if문이었다. 사실 이건 경우의 수가 그렇게 크지 않아 일일히 비교를 하는 것도 나쁘지 않았지만, 그렇게 작성을 처음에 해보고 뭔가 더 좋은 방법이 없을까 싶어서 gpt에게 이걸 더 간단하게 구현할 수 있지 않냐고 물어봤고 이러한 방법을 제시해 줬다. 순환적인 구조를 수학적으로 처리한 로직이었고, 사실 나는 이런 개념이 있다는 게 진짜 너무 신기했다. 이걸 이용하면 나중에 이미지의 무한 슬라이드도 쉽게 구현할 수 있다고 생각했다. 이렇게 작성을 하면 이미지 무한 슬라이드를 구현할 수 있다. 이건 진짜 꼭 기억하고 싶은 방법이다.이번 과제는 부족한 것들 투성이었지만 이런 개념들을 알게 된 거에 만족을 하고 내가 조금 더 나아질 일만 남았다는 긍정적인 생각을 하며 3일차를 끝내기로 하겠다.Day4 자바스크립트 중급(2) Section 5 (9 ~ 17)4일차에는 내가 제대로 몰랐던 개념들과 신기한 것을 몇 개 알게 되었다.일단 IIFE, Intersection Observer, Curry function 이렇게 3개는 나중에도 충분히 많이 사용할 것 같은 개념들이었다. 이런 유용한 것들을 나는 왜 처음 볼까? 라는 생각을 하며 강의를 재밌게 들었다. 1. IIFE (Immediately Invoked Function Expression)정의: IIFE는 즉시 실행 함수 표현식으로, 선언과 동시에 실행되는 함수입니다. 함수가 실행되면 내부에 정의된 변수들이 외부에 노출되지 않기 때문에 변수의 스코프를 보호할 수 있습니다.형식:(function() { // 내부에서만 사용되는 코드 })(); 주요 목적:전역 스코프 오염 방지: 변수가 전역 스코프에 영향을 주지 않도록 독립적인 스코프를 만들기 위해 사용.즉시 실행이 필요한 초기화 작업 등을 수행할 때 유용.2. Intersection Observer정의: Intersection Observer는 DOM 요소가 뷰포트(화면)에 진입하거나 나가는 것을 비동기적으로 감지할 수 있는 API입니다.사용 방법:const observer = new IntersectionObserver(callback); observer.observe(targetElement); // 타겟 요소 감시 시작 주요 목적:무한 스크롤: 사용자가 페이지를 아래로 스크롤할 때 요소가 화면에 나타나면 새로운 콘텐츠를 로드하는 기능.Lazy Loading: 이미지나 비디오 같은 무거운 리소스를 사용자가 실제로 볼 때 로드해서 성능 최적화.애니메이션 트리거: 특정 요소가 화면에 들어올 때 애니메이션을 실행할 때 유용.3. Curry Function (커링 함수)정의: 커링 함수는 여러 개의 인자를 받는 함수를 하나의 인자를 받는 여러 함수로 변환하는 기법입니다. 즉, 함수가 일부 인자만 받으면 그 인자를 기억한 채로 새로운 함수를 반환하고, 나머지 인자를 나중에 받을 수 있습니다.형식:function add(a) { return function(b) { return a + b; }; } const addFive = add(5); console.log(addFive(3)); // 8 주요 목적:코드 재사용성 증가: 함수의 인자를 부분적으로 적용해서 새로운 함수를 만들 수 있어 코드가 더 유연해집니다.함수 조합: 함수들을 작은 단위로 나눠 재사용하거나, 부분 적용을 통해 더 큰 로직을 쉽게 구성할 수 있음.정리IIFE: 선언 즉시 실행되는 함수로, 전역 스코프를 오염시키지 않고 데이터를 보호.Intersection Observer: DOM 요소가 화면에 나타나거나 사라질 때 트리거되며, 성능 최적화와 인터랙션에 유용.Curry Function: 인자를 나눠서 받는 함수로, 코드 재사용성 및 함수 조합을 쉽게 만들어 줌.일단 오늘 시간이 부족해 gpt의 도움을 받아 핵심만 정리했다.이 부분은 나중에 따로 더 정리를 해보겠다. 아무튼 이렇게 4일 차까지의 개념을 정리했다.이번주는 시간 배분을 잘못해서 여기까지만 진행을 했다. 미션 또한 다음주에 완성시키도록 하겠다. 처음 작성하는 회고록이라 너무 의식의 흐름대로 작성을 해서 가독성이 떨어지고, 맞춤법이나 이런 것도 아마 많이 틀렸을 것 같다.첫 술에 배가 부를 순 없다 생각을 하며 약간의 위안을 해보지만 다음번 발자국에서는 훨씬 더 시간을 투자해서 깔끔한 회고록을 작성해보겠다.일다 이번 회고를 작성하며 느꼈던 아쉬운 점을 정리함으로서 이번 회고를 끝내겠다. 1주차의 교육과정을 끝까지 다 완수하지 못한 것이 가장 아쉽다.회고를 남김에 있어 너무 의식의 흐름으로 적어 가독성이 굉장히 떨어지는 것 같다.강의를 들으면서 인상 깊었던 점을 메모장에 바로 작성해 두자.일단 회고록을 너무 갑작스럽게 작성하려 했던 것이 가장 큰 문제였다.강의를 듣다가 모르거나 중요한 개념들은 바로바로 메모를 남겨 다음번 회고 작성을 조금 더 용이하게 하자!

프론트엔드자바스크립트

이호준

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

강의 수강1주차에는 섹션 6. OOP까지 강의를 공부 했다공부 방식은 JS 기초적인 부분은 알고 있었기 때문에, 강의 자료를 통해 공부를 먼저 했고, 몰랐던 부분이나 헷갈리는 부분이 있을 경우 동영상 강의를 활용하였다주어진 진도를 다 진행하지 못한게 아쉬웠고 2주차에는 밀린 부분까지 따라가는 것을 목표로 잡기로 했다미션미션은 3번 퀴즈 앱까지 작성 완료 했고 4번 책 리스트 앱을 작성중 이다음식 메뉴 앱(https://github.com/hojun-lee99/inflearn-warmingup-fe/tree/main/quiz01)음식 메뉴 대신 좋아하던 슈퍼 히어로 리스트로 만들어 보았다버튼 클릭 이벤트에서 버튼의 value를 가져와 div의 클래스의 값과 동일하지 않을 경우 hidden 클래스를 이용해 정보를 숨기는 방식으로 작성 하였다가위 바위 보 앱(https://github.com/hojun-lee99/inflearn-warmingup-fe/tree/main/quiz02)Math.random() 메서드를 이용해 가위바위보를 계산 하였다최종 결과 계산은 삼항 연산자를 중첩으로 사용하여 결과를 출력해 보았다js 코다가 너무 길어서 다시하기 기능부분을 따로 분리해 보았는데 js는 파일을 분리하더라도 전역변수를 공유한다는 사실도 추가로 알게 되었다퀴즈 앱(https://github.com/hojun-lee99/inflearn-warmingup-fe/tree/main/quiz03) 문제를 3개 html로 작성해두고 다음 버튼을 누르면 현재 문제 태그에 hidden 클래스를 추가해 숨기고 다음 문제는 제거하여 나타나게 하는 방식으로 구현을 했다정답을 체크하기 위해 js파일에 배열로 추가해 두었는데 더 좋은 방법이 없을지 추가적으로 찾아봐야 할 것 같다이번주 회고미션을 진행하면서 js를 통한 기능 구현은 오히려 할만 했지만 css를 이용해 생각하면 화면을 구현하는 부분에서 많은 애를 먹으면서 시간을 많이 잡아 먹게 되었다react 파트를 진행하게 되면 러닝 커브가 더 높아질 것으로 예상 되는데 늦기 전에 수업진도를 빨리 따라가고 포기 하지 않고 3주차까지 열심히 달려나가기를 다짐하며 1주차 회고 작성을 마친다

프론트엔드

sdsd988

[워밍업 클럽 스터디 2기 백엔드(클린코드, 테스트코드)] 1주차 발자국

1주차 강의섹션 1. 추상과 구체섹션 2. 논리, 사고의 흐름 | 객체 지향 패러다임섹션 3. 객체 지향 패러다임 (SOLID)요약 : 좋은 코드(클린코드)를 작성하기 위한 도구와 사용 방법을 학습 강의 내용추상과 구체 (클린코드의 목적과 도구)논리, 사고의 흐름  우리는 코드를 읽는 시간이 더 많다.따라서, 코드는 쉽게 읽히고 이해되어야 한다.이를 위해, 우리는 추상, 구체 를 이해하고 분리해야 한다.메서드 작성, 파라미터 선언, 반환값 고민, 매직 스트링 등 좋은 코드 작성을 위한 고민과 도구를 학습조기 리턴, 공백 라인, 부정어 등 이해하기 쉬운 코드 작성을 위해 조심해야 하는 부분 학습 한번쯤 들어보거나, 읽어본 이야기다. 그렇지만, 현업에서 개발하면서 시간을 핑계로, 선배들이 좋게 보지 않는다는 이유로 실무 개발과 공부한 내용을 분리해서 개발해왔다. 그렇기에, 실제 코드를 바탕으로 고민하고 코드를 작성해보는 경험이 좋았다. 개발자는 고민하고, 코드를 직접 작성해봐야 뭐가 된다는 것을 새삼 느낄 수 있었다. 객체 지향 패러다임단일 책임 원칙객체의 변경 기준은 책임이다.책임이 단일하지 않다면, 변경의 기준도 단일하지 않다.이로 인해 객체의 코드 변경의 원칙이 무너진다. 코드를 읽고, 객체를 사용해야 하는 입장에서 어려움을 겪게 된다.개방 / 폐쇄 원칙책임이 과중히 부과되어서는 안된다.즉 객체는 자신의 책임에 대해서는 기능을 확장할 수 있지만, 자신이 아닌 책임에 대해서는 영향을 받으면 안된다.현재의 책임이 구체인지 추상인지 고민하고, 구체라면 추상화와 다형성을 활용해서 원칙을 지킬 수 있다.리스코프 치환 원칙 사용하는 입장에서 부모 클래스와 자식 클래스의 차이를 알지 못해야 한다.즉 슈퍼 클래스는 불필요한 기능을 상속해서는 안된다. 객체의 상속 사용시 주의해야 할 것 같다.인터페이스 분리 원칙책임을 명확하게 갖는 것은, 인터페이스도 예외가 아니다.인터페이스는 추상화, 다형성의 중요한 도구인 동시에 책임을 갖는다.의존성 역전 원칙기능은 변하고, 요구사항은 추가된다.그렇기에 고수준 모듈은 구체(저수준 모둘)를 참조하는 것이 아니라 추상에 의존해야 한다.새로운 요구 사항이 추가되고, 기능이 변경된다고 하더라도 추상에 의존한다면 코드의 변경 범위를 최소화 할 수 있다  미션 : 배운 내용을 바탕으로 고민해보기미션1. 추상과 구체 사례 예시 제출미션2. 과제 코드 리팩토링 제출미션은 강의를 학습한 내용을 적용해보는 방향으로 접근했다.특히, 고민 해보는 것을 중요하게 생각했다.과거에도 강의를 보고 학습하면서, 직접 고민해보는 시간이 부족했다고 생각했다. public class Delivery { private Order order; public boolean validateOrder(Order order) { if (validateItemSize(order)) { log.info("주문 항목이 없습니다."); return false; } if (validateTotalPrice(order)) { log.info("올바르지 않은 총 가격입니다."); return false; } if (DoesNotHaveCustomerInfo(order)) { log.info("사용자 정보가 없습니다."); return false; } return true; } private boolean validateTotalPrice(Order order) { return order.getTotalPrice() <= 0; } private boolean validateItemSize(Order order) { return order.doesNotHaveItems(); } private boolean DoesNotHaveCustomerInfo(Order order) { return order.doesNotHaveCustomInfo(); } } 1주차 회고 계획한 것 보다 강의와 미션에 시간을 할애하지 못했다.과제를 제출하고, 다른 참여생분들이 작성한 미션을 보면서 반성하고 자극되었다.특히 아쉬운 점은, 과제를 pdf, github 등을 통해 더 깔끔하게 제출할 수 있었는데 하지 못한점이 아쉽다.좋았던 점은, 워밍업 클럽이라는 곳에 소속감이 생겨서 주어진 기간내에 강의를 완강했다는 것. 혼자 수강했다면 이 정도 진로를 나갈 수 없었을 것이라고 생각한다.가장 좋았던 것은 미션이었다. 강의에서도 가장 좋은 점이 직접 리팩토링을 하는 시간이 많다는 것.워밍업 클럽에서도 미션이 가장 좋았다. 직접 무언가를 하는 경험이 지금의 내게 가장 맞다고 생각되었다.

백엔드백엔드클린코드ReadableCode읽기좋은코드를작성하는사고법

rhrud0412

[인프런 워밍업 클럽 Figma 2기] 프로덕트 디자인 1주차 발자국

인프런 워밍업 클럽 2기 1주차컨포넌트 사용에 있어서 미숙한 부분이 있어 러너로 참가하게 됨.스터디 커리큘럼에 따라 들으면서 최대한 페이스 조절하여 하루에 주어진 테스크 완수를 목표로 함. 처음은 열정적으로!! 열심히 하겠다는 마음가짐을 가지고 시작 1주차 학습 내용디자인 토큰과 베리어블의 개념배리어블 등록 : 색상, 간격, 타이포그래피, 그림자, 투명도, 그리드아이콘 컴포넌트화 : union, flatten selection, multiple component입력 컴포넌트 만들어보기 : 버튼, 체크박스, 라디오 버튼, 스위치 버튼잘한 점강의를 들으면서 미션수행하는 과정이 느린 진행 속도에도 불구하고 성실하게 강의를 따라감.대부분의 과제를 제시간에 충실히 따라 완료함.아쉬운 점아이콘 컴포넌트 과정에서 union, flatten selection 둘다 적용해야하는데 일부분만 적용해서다시 수정함.강의를 들으면서 그대로 따라서 미션을 수행하다 보니 주어진 테스크는 완료했지만, 개인적으로 완벽하게 숙지했는가에 대한 의문이 들어 복습의 필요성을 느낌.   다음주 목표커리큘럼을 따라서 꾸준하게 강의 수강하기강의를 마냥 따라가면서 미션 수행하는 것이 아니라 이해하면서 하기+복습하기  

UX/UIfigma디자인시스템boldUX워밍업클럽프로덕트디자인

마블

워밍업 클럽 2기 BE 1주차 발자국

1주차 배운 내용 요약클린코드의 중요성 알아가기가독성 -> 글이 잘 읽히는 것이 중요하다. 나 뿐만 아닌 다름 사람이 코드를 읽었을 때 얼마나 잘 이해할 수 있을까?회사에서 일을 할 때 코드를 읽는 것이 대부분유지보수성 -> 추상이란? 추상에 대해서 생각해보기추상이란 무엇일까?구체화 된 어떤 것들을 중에서 중요한 것만 추출하여 파악하는 것.어떤 일면만을 추상화하고, 다른 측면은 버린다.컴퓨터 측면에서 추상화8 byte -> 1bit, 4bit -> int 자료형추상화 레벨 - 고수준 언어, 저수준 언어고수준 언어는 레벨이 높다저수준은 언어는 레벨이 낮다.적절한 추상화는 복잡한 데이터와 로직을 단순화 한다.잘못된 추상화는 Side-effect를 야기시킨다. 그러기 때문에 추상화를 잘 알고 사용해야 한다.이름을 잘 지어야 한다.이름짓기단수 복수 구분하기 이름 줄이지 않기은어/방언 사용하지 않기좋은 코드를 보고 습득하기메서드와 추상화메서드 내부는 구체화된 내용메서드의 시그니쳐(반환타입, 메서드명, 파라미터)는 추상화된 레벨메서드 내부의 추상화 레벨을 잘 확인한다. -> 더 구체화 된 레벨이 있을 경우 메서드로 추출하여 레벨을 맞춘다.메서드명, 반환 값, 파라미터를 잘 확인한다.구체화 된 내용들을 적절하게 담기 이름void 대신 충분히 반환할 만한 값이 있는지 고민하기파라미터 타임, 개수, 순서를 통해 의미를 전달할 수 있다.매직 넘버, 매직 스트링의미를 갖고 있으나, 상수로 추출되지 않는 숫자와 문자열 등 -> 상수 추출로 이름을 짓고 의미를 부여한다가독성, 유지보수성 증가논리 사고의 흐름Early Returnreturn 문을 사용하여 else 사용을 줄인다. 사고의 depth 줄이기1. 중첩 if, for중첩된 반복문 또는 조건문을 없앨 수 있도록 구체화된 내용을 메서드로 추출하는 등 추상화하여 중첩을 줄인다.무조건 1depth로 만드는 게 아닌, 추상화를 통한 사고 과정의 depth임을 알아야 한다.2. 사용할 변수는 가깝게 선언변수는 사용하는 곳과 가깝지 않으면 잊어버린다.3. 공백 라인도 의미를 가진다.4. 부정어 줄이기부정어는 생각을 한번 더 거치게 한다.반대를 뜻하는 이름으로 바꾸기메서드 이름에 부정어 넣기5. 해피케이스와 예외 처리예외 발생 가능성 낮추기검증이 필요한 부분은 외부 데이터가 대부분이다사용자 입력, 객체 생성자, 외부 서버의 요청 등의도한 예외와 의도하지 않은 예외를 구분한다.사용자 예외와, 개발자 확인 예외NullPointerException 방지return null 사용 자제Optional 사용 고민Optional은 비싼 객체임으로 사용할 때 고민해야 한다.파라미터로 사용하는 객체는 아니다.Optional로 받은 반환 값은 빨리 해소한다. Optional을 해소하는 방법분기문을 만드는 isPresent()-get() 대신 풍부한 API 사용orElseGet, orelseThrow, ifPresent, ifPresentOrElseorElse(), orElseGet(), orElseThrow()의 차이 숙지orElse() : 항상 실행, 확정된 값일 때 사용orElseGet() : null인 겨우 실행, 값을 제공하는 동작(supplier) 정의orElseThrow() : null인 경우 에러 객체 throw 객체 지향객체 설계비공개 필드 (데이터), 비공개 로직(코드)공개 메서드 선언부를 통해 외부 세계와 소통 → 각 메서드의 기능은 객체의 책임을 드러내는 창구객체의 책임이 나뉨에 따라 객체 간 협력이 발생 주의점1개의 관심사로 명확하게 책임이 정의되었는지 확인 생성자, 정적 팩토리 메서드에서 유효성 검증이 가능하다. setter 사용 자제 getter 사용 자제 필드의 수는 적을수록 좋다.도메인 지식은 만드는 것이 아니라 발견하는 것이다.  상속과 조합상속보다 조합을 사용하자상속은 부모와 자식의 결합도를 높인다.상속을 통한 코드의 중복 제거가 주는 이점보다, 중복이 생기더라도 유연한 구조 설계가 주는 이점이 더 크다.Value Object도메인의 어떤 개념을 추상화하여 표현한 값 객체값으로취급하기 위해서, 불변성, 동등성, 유효성 검증 등을 보장해야 한다. 불변성 : final 필드, setter 금지동등성 : 서로 다른 인스턴스여도 내부의 값이 같으면 같은 값 객체로 취급한다. equals() & hashCode() 재정의가 필요유효성 검증 : 객체가 생성되는 시점에 값에 대한 유효성을 보장일급 컬렉션 - 일급 함수다른 요소에게 사용 가능한 모든 연산을 지원하는 요소변수, 파라미터, 함수 리턴 값으로 사용컬렉션만 유일하게 필드로 갖는 객체  getter 생성시 새로운 컬렉션으로 반환해야 한다.EnumEnum은 상수의 집합이며, 상수와 관련된 로직을 담을 수 있는 공간이다.특정 도메인 개념에 대해 그 종류와 기능을 명시적으로 표현해줄 수 있다.다형성 활용하기if문 줄이기어떤 조건을 만족하면, 그 조건에 해당하는 행위를 수행한다.변하는 것 → 조건, 행위변하지 않는 것 → 조건을 만족하는 가?, 행위를 수행한다.DAY2 미션 - 추상과 구체아기에게 우유를 따르라고 했을 때 아기는 제대로 우유를 따르지 못한다는 그런 내용이 생각이 떠올랐던 미션이었다. 컴퓨터적 사고에 대한 내용인데 아기는 우유를 따르라고 했을 때컵을 가져와라우유를 가져와라우유팩 뚜껑을 열어라우유팩을 들어라우유를 컵에 따라라이런 구체화 된 내용을 말하지 않으면 할 수 없다는 내용이다. 이렇듯 컴퓨터적 사고는 모듈을 개발할 때 모든 논리 과정을 생각하지 않으면 만들 수 없다. 그런데 우리의 뇌는 이런 모든 구체화 된 내용을 기억할 수 없기 때문에 추상화하지 않으면 기억하기 힘들다.일상 생활에서 자연스럽게 사용하고 있었지만, 이것을 다시 개발에 적용하는 것이 쉽진 않은 것 같다. 미션은 최근에 일어났던 일로 하긴 했지만 일을 할 때 코드가 하나도 추상화되어있지 않아 읽기 힘들고 기억하기가 힘들었는데 이번에 강의를 들으면서 배웠던 내용으로 추상화하려고 노력하니 많이 발전된 모습을 보일 수 있어서 좋았다. DAY4 미션 - SOLID 정의자바와 스프링을 하면서 너무 많이 들었던 내용이었다. 또한 면접을 볼 때도 엄청 외우고 다녔었는데 다시 보니 리마인드 되고 미션을 하면서 다시 내가 재 정의를 하려니 쉽지 않았지만 새롭게 배울 수 있었다. 학습은 타인에게 설명할 수 있는 단계 까지이다. 나도 이렇게 항상 생각하고 학습해왔기 때문에 이번에도 내가 타인에게 설명하는 것을 생각하며 SOLID를 다시 정의했다.1주차 회고최근에 책을 읽는 독서법을 바꾸려고 노력하고 있다. 전에는 빨리 읽으려고 노력했던 반면 요새는 책 내용 중 인상 깊었던 것들은 실천하려고 노력한다. 그렇지 않으면 읽었던 내용들을 다 잊어버린다. 그 좋은 내용들을 잊기 싫었다. 강의 내용도 그랬다. 사실 읽었던 책에 나온 내용들이긴 하지만 책은 이해하기 쉽지 않았다. 그런데 강의는 그것을 잘 이해할 수 있도록 강사님이 잘 설명해 주시기도 했고, 직접 해볼 수 있는 실습이 있어서 강의 내용을 이해하기 더 수월했다. 이론도 중요하지만 이론을 적용할 실습이 동반되지 않으면 말짱 도루묵이다. 그런면에서 얻을 수 있는 것이 많아서 좋았다.그리고 책에서 배웠던 내용을 리마인드 한다고 생각하면서 이번 1주차를 보냈다. 강의 내용도 좋고 중간 중간 미션과 회고를 쓰게 하는 것도 좋았다. 시간이 지남에 따라 해이해지는 정신을 잘 잡아주는 커리큘럼 구성이 좋았다.마지막으로 하나 반성을 하자면, 시간 투자를 많이 못했다. 강의를 듣고 공부하는 데에 시간을 많이 못쓰고.. 강의가 밀리기도 했다. 다행이 휴일이 많아서 따라왔지만, 다음 주부터는 이렇게 하다간 힘들 거라는 생각이 들었다. 시간을 많이 투자하고 관련된 책들도 다시 읽고, 미션도 열심히 수행해야겠다고 반성했다.  

백엔드발자국워밍업클럽2기1주차

채널톡 아이콘