블로그

[인프런워밍업스터디_BE_2기] 1주차 발자국!

Readable Code: 읽기 좋은 코드를 작성하는 사고법 수강 후 작성한 글입니다. 1주차 정리1주차에는 추상 섹션에서 추상과 구체에 대한 개념 정리, 이름짓기 등 간단한 부분을 배웠다. 이중에서 한 클래스 또는 메서드 내에서 추상화 레벨을 맞추는 부분은 기존에 생각하지 못하던 부분이라 해당 섹션의 내용 중 가장 인상 깊었다.다음 섹션3 논리, 사고의 흐름에서는 사고의 depth를 줄이는 부분이 기억에 남았다. 기존에 중첩된 for문이나 if문 등을 보면 강박적으로 이를 해소하고자 했던 것 같은데, 눈에 보이는 depth가 아니라 사고 과정을 줄이는 것이 중요하다는 것을 듣고 실무에서 이 부분을 놓치지 않도록 계속 신경 써야겠다는 생각이 들었다.섹션 4에서는 객체를 설계할 때 생각할 것과 SOLID에 대해 배웠다. 1주차 내용중 가장 와닿았던 내용이 있었는데, 그것은 'getter은 굉장히 폭력적'이라는 것이다. 객체 지향에 대해 공부하면서 이를 실무에 적용했을 때 'A.getAA().getAAA()..'와 같이 연속된 getter를 사용하여 비교하거나하는 등 뭔가 가독성이 떨어진다는 느낌을 받을 때가 많았다. 그런데 이렇게 무작정 getter를 쓰기보다는 다른 방법을 생각해보고 적용해보면서 이렇게 해결할 수도 있구나! 하면서 클래스를 만들면 습관적으로 getter를 만들던 내 자신을 돌아보게 되었다.섹션 5에서는 본격적으로 객체 지향을 적용한 다양한 리팩터링을 진행하였는데, 평소 존재는 알고 있었지만 활용하지 못했던 일급컬렉션과 같은 개념을 잘 알 수 있게 되었고, ValuObject나 Enum 처럼 사용하고 있었음에도 충분히 활용하지 못한 부분이 있다는 것을 알 수 있어 굉장히 유익했다. 1주차 과제 정리1주차 Day2 과제"추상과 구체" 강의를 듣고, 생각나는 추상과 구체의 예시가 있다면 한번 3~5문장 정도로 적어봅시다. 일상 생활, 자연 현상, 혹은 알고 있는 개발 지식 등 어느 것이든 상관 없습니다. 추상에서 구체로, 또는 구체에서 추상으로 방향은 상관 없으나, 어떤 것이 추상이고 어떤 것이 구체 레벨인지 잘 드러나게 작성해 보아요 :) ex) 우리가 상대방에게 소리를 내어 말을 하고 듣는 과정을 구체 레벨에서 표현한다면? - 폐에서 나온 공기가 성대를 통과한다. - 이는 나의 입술을 통해 외부로 방출되고, 상대방과 나 사이에 있는 공기를 진동시킨다. - 공기를 통해 전달된 진동은 고막, 달팽이관 등을 거쳐 청각세포, 청신경을 통해 뇌로 전달된다.추상: 총을 쏜다. 구체: 약실에 탄약을 넣는다.총의 방아쇠를 당긴다.공이치기가 공이를 때린다.뇌관이 폭발하며 탄약 내 화약을 연소시킨다.화약이 연소되며 발생한 가스가 탄환을 밀어낸다. 1주차 Day4 과제아래 코드와 설명을 보고, [섹션 3. 논리, 사고의 흐름]에서 이야기하는 내용을 중심으로 읽기 좋은 코드로 리팩토링해 봅시다.public boolean validateOrder(Order order) { if (order.getItems().size() == 0) { log.info("주문 항목이 없습니다."); return false; } else { if (order.getTotalPrice() > 0) { if (!order.hasCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } else { return true; } } else if (!(order.getTotalPrice() > 0)) { log.info("올바르지 않은 총 가격입니다."); return false; } } return true; }  https://github.com/HyeongSeop-Kim/readable-code/tree/main/src/main/java/cleancode/day4/tobe SOLID에 대하여 자기만의 언어로 정리해 봅시다.  저는 SOLID 원칙을 파인만 기법을 적용해서 초등학생에게 설명할 수 있도록 최대한 간단한 비유를 들어서 정리해봤습니다.  단일 책임 원칙 (Single Responsibility Principle) -> 프로그램에서 하나의 클래스나 함수는 한 가지 책임을 져야해. -> 장난감을 정리할 때 각자 한 가지 역할만 맡는 거야. 한 사람은 로봇 장난감을 모으고, 또 다른 사람은 자동차 장난감을 정리해. 그러면 일이 더 깔끔하고 빠르게 끝날 수 있겠지?  개방-폐쇄 원칙 (Open-Closed Principle) -> 프로그램은 쉽게 확장할 수 있어야 하지만, 기존 코드를 고치지 않아도 새 기능을 추가할 수 있어야해. -> 게임을 만들 때, 새로운 사냥터를 추가하고 싶어. 그런데 게임 자체를 다시 만들 필요가 있을까? 그냥 새로운 사냥터를 추가할 수 있게 하면 만들면 돼.  리스코프 치환 원칙 (Liskov Substitution Principle) -> 부모 클래스를 사용하는 곳에 자식 클래스를 넣어도 문제없이 작동해야 해. -> 청소기는 로봇 청소기도 있고, 일반 청소기도 있고, 작은 손청소기도 있잖아? 어떤 청소기를 사용하더라도 청소기라면 다 청소를 해줄 수 있어.  인터페이스 분리 원칙 (Interface Segregation Principle) -> 하나의 큰 인터페이스를 여러 개로 나눠서 필요한 것만 사용할 수 있게 하는 거야. -> 학교에서 준비물을 챙길 때, 매번 모든 준비물을 챙겨두는 것보다 미술 시간이 있는 날에는 미술 도구만 챙기고, 체육 시간이 있는 날에는 체육복만 챙기는 게 더 가볍고 좋겠지? 의존성 역전 원칙 (Dependency Inversion Principle) -> 프로그램에서 높은 수준의 클래스가 낮은 수준의 세부 사항에 의존하지 않게 해야 해. -> 핸드폰 충전기가 핸드폰마다 전부 다르면 너무 불편하겠지? 한 가지 충전기로 모든 핸드폰을 충전하게 하면 핸드폰을 바꾸더라도 기존에 사용하던 충전기를 사용할 수 있겠지? 1주차를 마치며이번 인프런 워밍업 스터디 2기의 소식을 들었을 때 기존에 듣고 있었던 테스트 코드에 대한 강의와 더불어 관심을 가지고 있던 Readable Code에 대한 내용이 있어 신청을 하고 싶었다. 하지만 현재 실무에서 맡고 있는 프로젝트 일정이 빠듯해서 계속 고민을 하게 되었는데, 이번 기회를 놓치면 다음에는 기회가 없을 수도 있을 것 같고, 0기에서의 좋은 기억도 있어 신청을하였다. 아쉬웠던 점역시 업무가 바쁘다보니 퇴근 이후 강의를 듣는 것도 빠듯했다. 그래서 과제를 기한에 맞춰 제출하긴 하였지만 시간이 부족하다보니 깊은 고민을 해보지 못한 것이 가장 아쉬웠던 것 같다. 칭찬할 점시간이 없는 와중에도 일정표에 따라 진도를 맞춰간 것은 칭찬할 점이라고 생각한다. 보완할 점주말을 조금 더 활용하여 시간이 부족한 부분을 채워야할 것 같다.

백엔드

홍정훈

[인프런 워밍업 클럽 2기 클린코드&테스트코드] 1주차 발자국

출처 : Readable Code: 읽기 좋은 코드를 작성하는 사고법 - 박우빈1. 학습 내용 요약이름 짓기추상적 사고를 기반으로 함단수와 복수를 구분이름 줄이지 않기은어/방언 사용하지 않기좋은 코드를 보고 습득하기 메서드 이름메서드 구현에 대한 부분을 추상화해서 중요한 내용을 가지고 있어야 함파라미터와 연결지어 더 풍부한 의미를 전달 할 수 있음 파라미터타입, 개수, 순서를 통해 의미 전달 반환타입메서드 시그니처에 납득이 가는, 적절한 타입의 반환 값void 대신 충분히 반환할 만한 값이 있는지반환 값이 있다면 테스트에 용이 추상화 레벨하나의 세계 안에서는 추상화 레벨이 동등해야 함읽는 사람으로 하여금 자연스럽게 읽히도록 함 Early return일찍 리턴 할 수 있는 경우에는 빠르게 리턴하자! Depth 줄이기무조건 1 depth로 만들어라 → X추상화를 통한 사고 과정의 depth를 줄이는 것이 중요 사용한 변수는 가깝게 선언하기 공백라인복잡한 로직의 의미 단위를 나누어 보여줌으로써 읽는 사람에게 추가적인 정보 전달 부정어! 를 통하여 조건을 뒤집을 경우 사고 과정이 두 번 일어나게 됨한 번에 이해할 수 있게 메서드명 자체에 부정어구를 녹이는 방법을 사용부정어구를 쓰지 않아도 되는 상황인지도 체크 예외 처리예외가 발생할 가능성 낮추기사용자에게 보여줄 예외 vs 개발자가 보고 처리해야 할 예외  새로운 객체를 만들 때 주의할 점1개의 관심사로 명확하게 책임이 정의되었는지생성자, 정적 팩토리 메서드에서 유효성 검증이 가능setter 사용 자제데이터는 불변이 최고만약 변경해야하는 경우 set~ 보다는 update~와 같이 의도를 드러내는 네이밍 이용getter 사용도 자제반드시 필요한 순간에만 생성객체에게 공손하게 물어보자!필드의 수는 적을수록 좋음불필요한 데이터가 많을 수록 복잡도와 대응할 변화가 증가상속보다는 조합을 사용하자상속은 수정이 어렵다 → 부모와 자식의 결합도가 높음조합과 인터페이스를 활용하는 것이 유연한 구조상속을 통한 코드의 중복 제거가 주는 이점보다, 중복이 생기더라도 유연한 구조 설계가 주는 이점이 더 큼 Value Object도메인의 어떤 개념을 추상화하여 표현한 값 객체값으로 취급 받기 위해선 불변성, 동등성, 유효성 검증 등을 보장해야 함 VO vs EntityEntity는 식별자가 존재, 식별자가 아닌 필드의 값이 달라도, 식별자가 같으면 동등한 객체로 취급VO는 식별자 없이, 내부이 모든 값이 다 같아야 동등한 객체로 취급  일급 컬렉션필드가 반드시 하나!컬렉션을 추상화하며 의미를 담을 수 있고, 가공 로직의 보금자리가 생김getter로 컬렉션을 반환할 일이 생긴다면, 외부 조작을 피하기 위해 꼭 새로운 컬렉션으로 만들어서 반환  Enum상수의 집합, 상수와 관련된 로직을 담을 수 있는 공간특정 도메인 개념에 대해 종류와 개념을 명시적으로 표현 가능  2. 미션 회고미션 1. 추상과 구체의 예시를 적어보는 과제였다. 나는 '호흡'이라는 추상 개념을 구체화 해보기로 했다. 우리 몸이 구체적으로 어떻게 호흡이라는 과정이 일어나는 지 서술해보았다. 미션을 통해 추상화 레벨에 대해 생각해보고, 추상화가 얼마나 중요한지 느끼게 되는 계기가 되었다.미션2. 섹션 3에서 배운 내용을 기반으로 읽기 좋은 코드로 리팩토링하는 과제였다. 강의 이전에 문제 코드를 미리 봤었는데, 강의를 보고 문제 코드를 다시 보니 처음에 캐치하지 못했던 개선점들이 보이는 게 신기했다. 문제는 문제점을 우선 파악하고, 개선 방안을 생각해본 뒤, 코드로 직접 수정하며 해결하였다.미션 풀이 과정은 노션에 따로 정리하였다 https://www.notion.so/Day-4-1145cf1d569e80139747c0781f448f433. KPTKeep코드를 보고 이번에는 어떤 방식으로 리팩토링을 해야 할지 고민하면서 강의를 들었다Problem강의가 조금 밀리니 미션을 해결하는 과정에서 고민할 시간을 많이 가지지 못했다.Try강의를 마감일자에 맞추어서 급하게 듣는 것이 아닌 조금 여유를 가지고 듣는 것이 좋겠다.다른 분들이 제출한 코드들을 내 코드와 비교하는 시간을 가져야겠다.4. 느낀점 이번 주는 잘못 들이고 있던 습관들을 고칠 수 있었다. 부정어, 줄임말 등 정말 많은 곳에서 실수를 하고 있었다. 예를 들어, 무언가 객체를 만들면 거의 조건 반사적으로 @Getter, @Setter를 적곤 했다. 이전에 Setter는 조심해서 사용해야 한다는 글을 본 적이 있어서 이제는 잘 사용하지 않지만 Getter는 거리낌 없이 사용했다. 강의를 보고 나니 Getter도 정말 최후에 생성해야하고, 객체에서 Getter로 변수를 꺼내다 쓰는 것이 아닌 요청하는 습관이 바람직 하다는 것을 알게 되었다. 돌아보면 당장 눈앞에 보이는 코드 짜기에 급급했지, 후대에 다른 개발자가 내 코드를 볼 것이라고 생각하고 코드를 짰던 기억은 정말 손에 꼽았던 것 같다. 이번 워밍업 클럽을 통해 Readable한 코드에 대해 항상 고민하는 개발자가 되었으면 좋겠다.

프로그래밍 언어

HYERIN JO

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

Liked, 스터디에 참여하며 좋았던 점은?JavaScript에 대해서 복습하는 시간을 가질 수 있었다.미션을 수행하면서 JavaScript 라이브러리, 프레임워크를 사용하지 않고 tailwindCSS를 적용하는 법을 배울 수 있어서 좋았다. 배운걸 실제로 적용해봐야지 머릿 속에 각인되고 더 잘 이해가 되는 거 같다.Learned, 스터디에서 배운 점은?강의에서 배운 점?호이스팅JavaScript에서 호이스팅은 코드가 실행되기 전에 변수 및 함수 선언(이름)이 로컬 범위(유효 범위)의 맨 위로 들어올려지거나 끌어올려지는 경우를 설명합니다.DOM, Document Object Model돔은 메모리에 웹 페이지 문서 구조를 트리 구조로 표현해서 웹 브라우저가 HTML 페이지를 인식하게 해줍니다.웹 페이지를 이루는 요소들을 자바스크립트가 이용할 수 있게끔 브라우저가 트리구조로 만든 객체 모델을 의미합니다.CRP, Critical Rendering PathDOM tree 생성: 렌더 엔진이 문서를 읽어들여서 그것들을 파싱하고 어떤 내용을 페이지에 렌더링할지 경정Render tree 생성: 브라우저가 DOM과 CSSOM을 결합하는 곳이며, 이 프로세스는 화면에 보이는 모든 콘텐츠와 스타일 정보를 모두 포함하는 최종 렌더링 트리를 출력함. 화면에 표시되는 모든 노드의 콘텐츠 및 스타일 정보를 포함함.Layout(reflow): 브라우저가 페이지에 표시되는 각 요소의 크기와 위치를 계산하는 단계Paint: 실제 화면에 그리기Event Bubbling이벤트 버블링이란 깊게 중첩된 이벤트가 발생했을 때, 이벤트가 위로 (bubble up) 전달 되는 것을 의미합니다.Event Capturing이벤트 캡처링이란 이벤트 버블링과 다르게 제일 상단에 있는 요소에서 아래로 이벤트가 내려오는 것을 말합니다.Event Delegation이벤트 위임은 하위 요소의 이벤트를 상위 요소에 위임하는 것입니다.this 키워드메소드에서 this를 사용할 경우? 해당 객체를 가리킨다.const artist = { name: 'Minnie', sing() { console.log('sing this', this); // {name: 'Minnie', sing: f sing()} } } 함수에서 this를 사용할 경우? window 객체를 가리킨다.function eatHamburger() { console.log(this); // window 객체 } constructor 함수에서 this 사용할 경우? 빈 객체를 가리킨다.function Artist(name) { this.name = name; console.log(this); // {} } const minnie = new Artist('Minnie'); 콜백함수에서 this를 사용할 경우? (콜백함수가 일반함수일 경우) window 객체를 가리킨다.const artist = { name: 'Minnie', nums: [1, 2, 3], print() { this.nums.forEach(function(num){ console.log(`name: ${this.name}, num: ${num}`); // name: undefined, num: 1 }); } }; 화살표 함수에서 this를 사용할 경우? 상위 스코프의 this를 가리킨다. Lexical this라고 부른다.const artist = { name: 'Minnie', nums: [1, 2, 3], print() { this.nums.forEach((num) => { console.log(this); // {name: 'Minnie', nums: Array(3)} }); } }; Event Loop이벤트 루프는 Call Stack(호출 스택)과 Callback Queue(콜백 큐)를 계속해서 확인하며, Call Stack이 비어 있을 때 콜백 큐에 대기 중인 콜백 함수들을 FIFO(First In, First Out) 방식으로 Call Stack에 넣어 비동기 코드를 실행합니다. 이는 비동기 함수들이 완료된 후에도 Call Stack에 있는 동기 코드가 모두 처리될 때까지 대기하다가 실행되는 구조를 따릅니다.클로저다른 함수 내부에 정의된 함수가 있는 경우 외부 함수가 실행을 완료하고 해당 변수가 해당 함수 외부에서 더 이상 액세스할 수 없는 경우에도 해당 내부 함수는 외부 함수의 변수 및 범위에 액세스할 수 있습니다.미션을 하면서 배운 점?미션 1. 음식 메뉴 앱github repository: https://github.com/hyer0705/inflearn-warmingup-club-2/tree/main/javascript/food-menu-app메뉴 데이터는 아래와 같은 구조로 정의합니다:{ category: 'breakfast' | 'lunch' | 'shakes' | 'dinner', food: string, cost: number, desc: string, img: string } 각 메뉴는 menus 변수에 배열 형태로 저장됩니다.사용자가 음식 카테고리를 선택하면, Array.prototype.filter() 메서드를 사용해 menus에서 선택한 카테고리에 맞는 음식들을 필터링합니다.필터링된 음식 데이터를 기반으로, document.createElement(), element.innerHTML, element.innerText 등의 DOM API를 사용해 화면에 표시합니다.미션 2. 가위 바위 보 앱github repository: https://github.com/hyer0705/inflearn-warmingup-club-2/tree/main/javascript/rock-paper-scissors-appplayData 변수에 총 플레이 횟수, 플레이어 승리 횟수, 컴퓨터 승리 횟수를 저장합니다.const playData = { totalPlayCnt: 10, playerWin: 0, computerWin: 0 } 사용자가 가위, 바위, 보 버튼을 클릭하면, 컴퓨터는 Math.random() 메서드를 사용해 랜덤으로 가위, 바위, 보 중 하나를 선택합니다.버튼 클릭 시 플레이 횟수가 줄어들며, 결과는 playData에 저장됩니다.버튼 클릭시 해당 라운드의 결과를 DOM 조작 API를 사용하여 화면에 표현해줍니다.10회 라운드가 끝나면 게임이 종료되고, 최종 결과가 화면에 표시됩니다."다시 시작" 버튼을 클릭하면 playData가 초기화되어 게임을 다시 시작할 수 있습니다.Lacked, 스터디에 참여하면서 부족했던 점은?개인적인 사정으로 1주차 진도표의 절반만 진행했다.Longed For, 앞으로 개선하고 싶은 점은?다음주에는 커리큘럼에 따라갈 수 있도록 열심히 강의를 듣고 미션을 수행해야지! 그러기 위해 빨간날과 주말을 적극적으로 활용해야 겠다.참고자료강의 출처: 따라하며 배우는 자바스크립트 A-Z, John AhnEvent Bubbling Image: https://www.freecodecamp.org/news/event-bubbling-in-javascript/?source=post_page-----4209bf40575c--------------------------------Event Capturing Image: https://www.javascripttutorial.net/javascript-dom/javascript-events/Event Delegation Image: https://dmitripavlutin.com/javascript-event-delEvent Loop Image: https://medium.com/@burak.bburuk/what-is-the-event-loop-in-javascript-and-why-is-it-essential-to-understand-b11af520a28b

프론트엔드워밍업클럽발자국1주차인프런워밍업클럽워밍업클럽스터디2기프론트엔드

[인프런 워밍업 스터디 클럽 2기 백엔드] 1주차

해당 글은 인프런 박우빈 강사님의 「Readable Code: 읽기 좋은 코드를 작성하는 사고법」을 바탕으로 작성하였습니다.그 외 글에 등장하는 모든 이미지는 직접 그린 이미지입니다. 동기와 스터디 목표인프런 워밍업 클럽 0기 우수 러너로 운 좋게 선정된 후, 반년 이상이 훌쩍 지났다. 다시금 기강이 해이해지고 할 일을 미뤄간다고 (이 반년 간 대시보드가 0기를 진행할 때보다 많이 휑해진 걸 보면 마음이 쓰리다...) 생각할 무렵 2기 소식이 들려왔다. 내가 신청한 코스는 박우빈 님의 코스! 사실 우빈 님의 명성도 잘 모른 채 '테스트 코드'라는 달콤한 단어와 커리큘럼만 보고 바로 신청서를 제출해버렸다. 추후 스터디를 같이 진행하는 러너 분께서 우빈 님의 명성을 알려주셔서 놀란 기억이 있다. 나는 작년, 학원에서 5개월 정도의 부트캠프로 코딩을 처음 배웠기 때문에, 기초적인 문법만 알지 자바 컨벤션이나 리팩토링 같은 건 수박 겉 핥기 정도로 밖에 알지 못했다. 이번 기회로 우빈 님의 사고법과 노하우를 10퍼센트라도 챙겨가는 것이 이번 스터디의 소박하지만 원대한 목표라고 할 수 있겠다. 1주차 요약해당 블로그 글에는 강의에 등장하는 예시 코드는 작성하지 않고, 이론적인 부분만 요약해 작성합니다. 예시 코드는 우빈 님의 git repository에서 다운 받을 수 있습니다.❗git repository 받기❗이 부분은, 내용이 있는 것은 아니지만 개인적으로 당부하고 싶은 부분이 있다. 아직 해당 강의를 들어본 적이 없는 분이라면, 강의에서 제공해주는 파일을 받고 꼭! 로직을 천천히 읽으며 흐름을 정확히 이해하고 강의를 시작했으면 좋겠다. 이를 제대로 파악해보지 않고 처음부터 들이받았다가 바로 다음 섹션부터 후회해버렸다... 😂😂 프로그램이란?프로그램 = 설치하는 것 = 데이터와 코드의 집합체위 개념을 유념하며 추상화에 대해 깊이 알아가자. 추상과 구체추상 ⇔사물을 정확히 이해하기 위해 사물이 지닌 여러 측면 가운데 특정 면 만을 가려내어 포착위 추상의 정의에서 가장 중요한 단어는 '가려낸다.'라고 우빈 님께서는 짚어주셨다. 가려낸다는 것은 일부를 생략하고 버리는 것이며, 이는 정보를 함축하고 제거한다는 것과 같다. 추상화 레벨추상화 레벨이란 추상과 구체 사이 존재하는 레벨들이다.추상화 레벨이라는 단어만 보면 굉장히 어렵게 느껴지지만, 간단하게 생각해보자. 바로 윗 문단에서 우리는 추상을 사물의 특정 정보를 함축, 제거한다고 이해했다. 그렇다면 이 정보들을 함축, 제거하지 않은 것을 뭐라고 할까? 바로 '구체'이다. 구체의 사전적 정의는 '사물이 직접 경험하거나 지각할 수 있도록 일정한 형태와 성질을 갖춤.' 이다. 우리가 이해한 추상이란 개념에 맞춰 생각한다면 구체의 정의에서 중요한 부분은 '지각할 수 있는' 이겠지만 확 와 닿지는 않는다. 그래서 간단하게 도식화해보았다. 예시를 한 번 들어보자. 친구에게 '저녁 식사로 라면을 끓여 먹었어.'라고 한 문장으로 끝내버릴 수 있는 간단한 문장을 극단적으로 늘려보자. '물 550 ml를 냄비에 담고 가스레인지 위에 올려 불을 점화했어. 물이 끓으면 스프와 면을 넣어 3~4분을 기다리고, 완성 후 불을 소화했어. 면을 젓가락으로 집어 입에 넣고, 저작 운동을 통해 섭취하고 소화했어.' 이렇게 말한다면 대화의 흐름이 엉망일 것이다. 이 보다 더더욱 길게 말한다면 친구가 대체 무슨 말을 하고자 하는 것인지 파악조차 어려울 것이다.여기서 우리가 일상적으로 대화하듯이 말하는 '저녁 식사로 라면을 끓여 먹었어.' 라는 한 문장이 추상, 뒤의 호흡이 긴 문장을 구체라고 생각할 수 있다. 예시를 들어보면 전혀 어려운 개념이 아니라는 것을 알 수 있다. 컴퓨터 과학과 추상그렇다면 이제 한 가지 의문이 든다. '그래서 추상의 정의를 왜 이렇게 자세히 이해하려고 하는거야?' 답은 간단하다. 컴퓨터는 인간의 언어를 알지 못하고 1과 0으로만 소통할 수 있다는 것은 모두가 알 것이다. 하지만 우리는 영어로 코드를 작성하고 있다. 이 의미는 우리가 쓰고 있는 고수준 언어는 기계어를 사람이 알기 쉽도록 추상화한 것이다. 하드웨어와 운영체제 사이도, 운영체제와 애플리케이션 사이에서도 마찬가지이다. 컴퓨터 과학이란 겹겹이 쌓인 추상화의 모음인 것이다. 누구나 코딩을 처음 접할 때, 메서드, 클래스 개념도 자세히 알지 못해 main 메서드에 줄줄이 로직을 다 때려넣어 본 적이 있을 것이다. 이렇게 되면 눈이 굉장히 피로해지고 로직 파악도 되지 않는다는 것도 알고 있다. 이런 것들을 적절히 추상화해 복잡한 데이터와 로직은 단순화하는 것이 이 강의의 핵심 목표인 것이다. 잘못된 추상화복잡한 로직들 중 일부를 똑 떼서 메서드로 추출하고, 클래스로 다 만들고 이름도 내가 읽기 좋게 바꿔버리자! 하고 무턱대고 리팩토링한다면 이게 좋은 리팩토링 방식일까?⇒ 그렇지 않다! 잘못된 추상화는 구체화 과정에서 유추가 안 된다! 친구가 이런 말을 했다고 해보자.친구들끼리 있을 때는 모두가 아~ 하고 단어의 의미를 유추하고 대화를 이어나갈 수 있을 것이다. 하지만 저 말을 가족들끼리 있을 때 한다면? 혹은 직장 상사와 있을 때 한다면? 사람마다 성향 차이가 있겠지만 아마 대부분은 대화의 흐름이 끊길 것이다. 듣는 이를 고려하지 못한 어휘 선택이라고 할 수 있다. 즉, 우리는 단어의 선택 조차도 대화하는 집단이 어디냐에 따라 적절히 선택하고는 한다. 이를 코드에 적용하자면 우리가 담당하는 도메인 영역에 따라 추상화 기준이 다를 수도 있다. 가장 중요한 것은 문맥을 파악해야 한다는 것이다. 이름 짓기이름 짓기는 추상화의 중요한 첫걸음이다.끝에 -(e)s를 붙여 데이터가 단수인지 복수인지 구분하기이름 줄이지 않기가독성 vs 효율성 에서 가독성을 택하는 게 좋다.단, 관용어 처럼 이용하는 것이 있으니 내가 속한 집단에 잘 맞춰가야 한다.은어/방언 사용하지 않기현재 팀원들이 다같이 아는 단어여도, 신입이 왔을 때를 고려해야 한다.도메인 용어 사용하기상점을 store라고 할지, shop이라 할지 우선적으로 논의해야 한다.좋은 코드를 보고 습득하기비슷한 상황에서 자주 사용하는 단어, 개념을 습득한다.poop, candidate, threshold 등... 메서드와 추상화한 메서드에는 하나의 기능만!메서드의 이름으로 구체적 내용을 추상화추상화된 구체를 유추 가능한 적절한 의미가 담기는 이름파라미터랑 연결지어 더 풍부한 의미 전달 가능(ex: ~~From (파라미터))항상 동사로 시작해야 한다는 강박은 불필요! ★메서드 선언부★반환 타입 메서드명 (파라미터) {구현부} 에서 메서드 명과 파라미터를 합쳐 메서드 시그니쳐라고 한다.하나의 세계(=메서드) 안에서는 추상화 레벨이 동등해야 한다. 파라미터파라미터의 타입, 개수, 순서를 통한 의미 전달★파라미터는 외부 세계와 소통하는 창요리 레시피의 재료 같은 의미 반환 타입메서드 시그니쳐에 납득 가는 적절한 타입의 반환 값 돌려주기void 대신 충분히 반환할 값이 있는지 고민하기반환 값이 있어야 테스트가 용이하다. 매직 넘버, 매직 스트링의미는 갖고 있으나, 상수로 추출되지 않은 숫자, 문자열 등을 의미매직 넘버, 매직 스트링을 상수로 추출해 이름을 짓고 의미 부여가독성과 유지 보수성↑ Early return일찍 리턴할 수 있는 것은 빠르게 리턴!if 문의 else를 지양한다.if 문단을 메서드로 추출 후, 조건을 충족 시 바로 return 시키는 방식 사고의 depth 줄이기중첩 분기문, 중첩 반복문 줄이기각각의 반복문을 메서드로 쪼갠다!무조건 depth를 1로 만들자는 의미 X!2중 중첩이 더 도움이 된다고 판단 시 메서드 분리는 금물.사용할 변수는 가깝게 선언하기i = 10; ... 무언가의 복잡한 로직 ... j = i + 10; // 이렇게 되면 i의 값이 기억이 안 난다!메서드 리팩토링 시 컴파일 에러 주의!리팩토링할 메서드를 복제해 리팩토링 완료 후 원 메서드를 지우는 방식으로 진행 권장 공백 라인 대하기공백도 의미를 갖는다! 의미가 달라진다고 생각하는 부분들에 공백 라인을 준다! 부정어를 대하는 자세부정어구를 사용하지 않아도 되는 상황인지 체크부정의 의미를 다른 단어가 있는지 고민하기! 같은 부정 연산자는 가독성이 떨어지니 지양해피 케이스와 예외 처리사람은 해피 케이스에 몰두하게 되기 때문에 예외 가능성을 최대한 낮춰야 한다.검증이 필요한 부분은 주로 외부 세계와의 접점사용자 입력, 객체 생성, 외부 서버 요청 등...의도한 예외와 예상치 못한 예외를 구분하기사용자에게 보여줄 예외 vs 개발자가 처리해야 하는 예외 null을 대하는 자세자바에서는 null 처리가 중요하다. NullPointException의 지옥...NullPoint를 최대한 방지하도록 경각심 갖기메서드 설계 시 return null을 자제이것이 불가능하면 Optional 사용을 고려단, Optional은 꼭 필요할 때만 사용할 것Optional을 파라미터로 받지 않도록 하기. 분기 케이스가 3개나 되어 버린다.Optional 반환 시 빠르게 해소한다.★ orElseGet(), orElseThrow(), ifPresent(), ifPresentOfElse() 등을 사용하자★ 객체와 추상화 레벨객체의 비공개 필드와 비공개 로직은 공개 메서드 선언부로 외부와 소통 ⇒ 객체의 책임은 공개 메서드로 드러난다.책임에 따라 분리된 각 객체들이 상호작용 하며 협력한다.외부에서는 구체적 구현을 알 수 없고 몰라도 된다! 객체 생성 시 주의점1개의 관심사가 명확하게 정의되었는가? 외부와 어떤 소통을 해야하는가?생성자, 정적 팩토리 메서드에서 유효성 검증 가능도메인 특화 검증 로직이 들어갈 수 있음setter 사용 자제!데이터는 불변이어야 사이드 이펙트가 없다!객체 내부에서 외부의 개입 없이 자체 변경 및 가공을 하도록 하자변경이 불가피하다면 update~ 같은 의미있는 네이밍을 하자.getter 사용 자제!getter도 꼭 필요할 때만 사용한다!getter는 폭력적인 메서드라 외부에서 getter를 호출하는 것은 강도를 불러오는 것과 다름이 없다!객체에 메세지를 보내기!필드 수는 적을 수록 좋다불필요 데이터가 많을수록 복잡도가 높아진다.중복 데이터 필드는 최대한 줄이고, 파생 데이터 필드는 메서드로 풀어본다.단, 미리 가공하는 것이 성능에 이점이 있다면 필드로 쓰자. SOLIDSRP(Single Responsibility) / 단일 책임 원칙 - 한 객체가 책임 1, 책임 2를 모두 갖고 있다면, SRP를 위반 - 하나의 클래스는 단 한 가지의 변경 이유(= 책임) 만을 가져야 한다. - 객체가 가진 공개 메서드, 필드, 상수 등은 해당 객체의 단일 책임에 의해서만 변경 되는가? - 관심사의 분리 - 높은 응집도(클래스나 모듈 내 요소들이 긴밀하게 작용), 낮은 결합도(=의존성 / 한 객체가 변경되었을 때 다른 객체가 변화되는가) - 클래스와 객체 레벨에서 강조되는 원칙 - 책임을 갖는다의 의미? 지금 객체의 책임은? ← 책임이란 판단이 어려움!- 책임을 볼 줄 아는 눈이 필요 OCP(Open-Closed)- 확장에는 열려 있고 수정에는 닫혀 있기- 기존 코드 변경 없이, 시스템 기능 확장해야 한다.- 추상화와 다형성을 활용 LSP(Liskov Substitution)- 상속 구조에서, 부모 클래스의 인스턴스를 자식 클래스의 인스턴스로 치환 가능해야 한다.- 자식 클래스는 부모 클래스의 책임을 준수하고 부모 클래스의 행동을 변경하면 안 된다!- LSP 위반 시 상속 클래스 사용 시 오동작, 예상 밖 예외 발생 ISP(Interface Segregation)- 클라이언트는 자신이 사용하지 않는 인터페이스에 의존하면 안 된다.- 인터페이스 잘게 쪼개기!- ISP 위반 시 불필요한 의존성으로 인해 결합도가 높아진다.- 인터페이스에 A,B 기능이 존재하고, 구현체 1은 A,B를 모두 사용하고 구현체 2가 A만 사용한다면, 인터페이스를 A, B로 쪼개야 한다. DIP(Dependency Inversion)- 상위 수준의 모듈은 하위 수준의 모듈에 의존하면 안 된다.- 둘 모두 추상화에 의존(=의존성의 역방향)해야 한다.- 고수준 모듈이 저수준 모듈을 참조하는 것을 의존성의 순방향이라고 한다.- 저수준 모듈 변경 시에도 고수준 모듈에 영향이 가면 안된다.- 카페(고수준)에서 커피(저수준)를 판다(sell 함수)라는 행위를 한다고 가정- 카페에서 다른 음료를 판매하고 싶다면?- 음료라는 인터페이스를 둬야 한다! 상속과 조합상속보다는 조합!상속은 수정이 어렵다.부모 자식 간의 결합도가 높다...조합과 인터페이스를 잘 활용하는 것이 관건!상속으로 중복 코드 제거 하기 <<< 중복이 생겨도 유연한 구조중복 제거로 극한의 효율을 얻고자 하는 것은 옛 이야기이다. value object도메인의 개념을 추상화하여 표현하는 값 객체불변, 동등, 유효성 검증 보장이 필수불변성: final 필드 사용하기, setter 금지하기동등성: 서로 다른 인스턴스여도 내부 값이 같으면 같은 객체지폐의 일련번호가 달라도 같은 값으로 보는 것과 같은 개념이다!유효성 검증: 객체가 생성되는 시점에 대한 유효성 보장 VO? Entity?Entity는 식별자가 존재!식별자 외의 필드 값이 달라도 식별자가 같으면 동등한 객체이다.VO는 식별자가 없고, 내부 필드의 모든 값이 다 같아야 동등한 객체이다. 일급 컬렉션일급 시민다른 요소에게 사용 가능한 모든 연산을 지원하는 요소변수 할당 가능파라미터 전달 가능함수 결과 반환 가능일급 컬렉션컬렉션을 포장하면서 컬렉션만을 유일하게 필드로 가지는 객체컬렉션을 다른 객체와 동등 레벨로 다룰 수 있다.의미 부여와 가공 로직의 보금자리가 생긴다!getter로 컬렉션을 반환해야 한다면 외부 조작을 피하기 위해 새 컬렉션을 만들어 반환해야 한다.ex) getter로 리스트를 가져와 add() 등의 함수로 조작 위험성 존재 Enum의 특성과 활용상수의 집합상수와 관련된 로직을 담는 공간! → 상태와 행위를 한 곳에서 관리 가능한 객체특정 도메인 개념에 대해 종류와 기능을 명시적 표현 가능단, 변경이 잦은 개념은 Enum 보단 DB 관리가 나을 수도 있다. + αorElse() vs orElseGet() vs orElseThrow()의 차이orElseThrow는 값이 있으면 쓰고 없으면 예외.orElse()는 괄호 안이 항상 실행되는 값이다. 확정된 값일 때만 사용한다. (호출할 필요가 없어도(null이어도...) 항상 실행) orElseGet()은 null인 경우 실행된다. 값을 제공하는 동작을 정의한다. (null인 경우에만 괄호 안 동작이 실행)- orElseGet()은 Supplier를 통해 람다식 형태로 매개변수를 전달한다. 이는 자바의 람다식 동작 방식으로 인해, 즉시 실행하지 않고 호출할 때만 실행한다. 이를 통해 orElse와 다르게 지연 평가가 가능안티 패턴강의에서 지나가듯 말씀하신 내용으로, e.printStackTrace()는 대표적 안티 패턴!나머지 대표 안티 패턴은 God Object, God Class, 매직 넘버, 매직 스트링, 싱글톤 남용 등이 존재자바의 람다식 동작 방식추가 학습 필요 미션미션은 총 2개가 있었고, 각 풀이는 노션 포스트 링크를 첨부한다.미션 1미션 2

백엔드백엔드워밍업클럽

[워밍업 클럽 2기 BE 클린코드&테스트] - Readable Code 발자국 1주차

강의 정리Section 1쓰기 좋은 코드 << 읽기 좋은 코드코드를 잘 짠다? 읽기가 좋다~도메인 : 해결하고자 하는 문제 영역도메인 지식 : 도메인을 이해하고 해결하는데 필요한 지식Section 2클린 코드의 본질은 : 가독성프로그램 : 데이터 + 코드추상과 구체추상화의 대표적인 행위 : 이름 짓기적절한 추상화는 코드를 이해하기 쉽게 + 구체를 쉽게 유추적절한 추상화는 도메인의 문맥 안에서 중요한 정보는 가려내어 남긴다이름 짓기단순하지만 고도의 추상화 행위! 굉장히 중요하다!!1. 단수, 복수 표현하기2. 이름 줄이지 않기줄임말 : 가독성이 나빠진다관용적으로 사용하는 줄임말 정도는 사용해도 괜찮다Ex) column -> col, latitude -> lat, longitude -> lon3. 은어/방언 사용하지 않기일부만 이해하는 용어 금지X (새로운 팀원을 위하여)도메인 용어 사용하기도메인 : 해결하고자 하는 문제 영역4. 좋은 코드를 보고 습득하기좋은 프레임워크, 라이브러리들의 좋은 설계나 코드를 보고 학습하자!메서드와 추상화잘 쓰여진 코드라면, 한 메서드의 주제(기능)는 반드시 하나!메서드의 이름으로 구체적인 내용을 추상화⭐ 메서드 선언부반환타입 + 메서드 시그니처 = 메서드 선언부메서드 시그니처 : 메서드명 + 파라미터메서드 시그니처라는 용어는 오버로딩 때문에 따로 정리된 용어라고 한다메서드명기능을 유추할 수 있는 적잘한 이름 (파라미터와 연결지어 풍부하게 유추!)파라미터타입, 개수, 순서를 통해 의미 전달!!외부와 소통하는 창 (필요한 정보를 의미한다!)반환타입메서드 시그니처에 적절한 반환값 -> 테스트에 좋을 수 있다실습Tip파라미터와 연결지어 풍부하게 유추//cellInputCol로부터 Col을 변환할꺼야 int selectedColIndex = convertColFrom(cellInputCol);매직넘버, 매직 스트링아직 상수로 추출되지 않은 값이름을 짓고 의미를 부여 -> 가독성, 유지보수성 향상Section 3논리, 사고의 흐름!범주화를 통한 최소한의 정보로 나타내어 추상화, 가독성을 향상시키자!Early returnif 문을 메서드로 분리!if문에 return을 사용 -> 이전 정보를 신경 쓰지 않아도 된다!Early return을 통해 else의 사용을 지양depth 줄이기중첩 분기문, 중첩 반복문(실제 동작을 줄이는 것 X, 코드를 분리하는 것 O)무조건 1depth? 아니다!이해하기 편하다면 나누지 말자 -> 가독성을 기준으로 분리하자실습Tip컴파일 에러를 줄이기 위해서 메서드를 복사해서 리팩토링한다!공백 라인을 통해 의미 단위를 나누자!부정어추가로 사고를 뒤짚어야 하므로 불편할 수 있다왼쪽이 아니다오른쪽이다로 변경! (부정어 없이 다른 표현으로 작성한다면 👍)또는, 메서드명에 부정의미를 담아서 작성하자해피 케이스와 예외처리예외 발생 가능성 낮추기검증이 필요한 부분은 외부의 데이터 (사용자 데이터는 믿으면 안된다!)의도한 예외, 예상하지 못한 예외 구분하기NULLNullPointException 방지return null 자제Optional코스트가 크다Optional을 파라미터로 받지 않도록 한다케이스가 3개나 된다Optional이 null인지 아닌지 + Optional이 null인지반환타입에만 사용한다null일 가능성이 있다는 것을 알려줄 때 사용하고Optpional을 반환받았다면 빠르게 해소한다Optional 해소하는 방법orElseGet(), orElseThrow(), ifPresent(), ifPresentOrElse()orElse() -> 항상 실행orElseGet() -> null인 경우 실행 public T orElse(T other) { return value != null ? value : other; } public T orElseGet(Supplier<? extends T> supplier) { return value != null ? value : supplier.get(); } public T orElseThrow() { if (value == null) { throw new NoSuchElementException("No value present"); } return value; }Section 4 객체 지향 패러다임객체 : 추상화된 데이터 + 코드협력과 책임관심사의 분리 : 높은 응집도, 낮은 결합도객체 설계하기1개의 관심사로 명확하게 책임이 정의되었는지!생성자, 정적 팩토리 메서드에서 유효성 검증 가능 (도메인 특화 검증 로직)setter 사용 자제why?객체 내부에서 외부의 개입 없이 자체적인 변경/가공만약 외부데이터로 변경해야한다면? update~로 네이밍을 하자getter 도 추천 X필드의 수는 적을수록 좋다필드를 가공해서 계산할 수 있다면 메서드를 통해 제공하도록 하자!성능판단SOLID1. SRP : Single Responsibility Principle단일 책임 원칙하나의 클래스는 단 한가지의 변경 이유(책임)만을 가져야 한다.객체가 가진 공개 메서드, 필드, 상수 등은 단일 책임에 의해서만 변경되는가?관심사의 분리높은 응집도, 낮은 결합도 (의존성 낮다)2. OCP : Open - Closed Principle개방 - 폐쇄 원칙확장에는 열려 있고, 수정에는 닫혀있다기존 코드의 변경 없이, 시스템의 기능을 확장할 수 있다추상화와 다형성을 활용해서 OCP를 지킬 수 있다3. LSP : Liskov Substiution Principle리스코프 치한 원칙상속 구조에서, 부모 클래스의 인스턴스를 자식 클래스의 인스턴스로 치환할 수 있어야 한다.LSP 를 위반하면, 상속 클래스를 사용할 때 오동작, 예상 밖의 예외가 발생하거나, 이를 방지하기 위한 불피요한 타입 체크가 동반될 수 있다.Ex. 엑셀을 밟으면 자동차는 앞으로 나가야한다4. ISP : Interface Segregation Principle인터페이스 분리 원칙클라이언트는 자신이 사용하지 않는 인터페이스에 의존하면 안된다인터페이스를 기능 단위로 쪼개자!!ISP를 위반하면, 불필요한 의존성으로 인해 결합도가 높아진다5. DIP : Dependency Inversion Principle ⭐의존성 역전 원칙상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 된다. 둘 모두 추상화에 의존해야 한다.의존성의 순방향 : 고수준 모듈이 저수준 모듈을 참조하는 것의존성의 역방향 : 고수준, 저수준 모듈이 모두 추상화에 의존하는 것학습할 도서 목록 정리함께 자라기』(김창준, 인사이트, 2018)『Clean Code(클린 코드)』(로버트 C. 마틴, 인사이트, 2013)『클린 아키텍처: 소프트웨어 구조와 설계의 원칙』(로버트 C. 마틴, 인사이트, 2019)『최고의 프롬프트 엔지니어링 강의』(김진중, 리코멘드, 2024)YouTube @ShuOmi_Official 'Zettelkasten Note-Taking Method: Simply Explained'

백엔드

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

 운영체제 cCopy codewhile(true){ wait(1); // 1초 대기 bool isActivated = checkSkillActivated(); // 스킬 사용 여부 확인 } 위 코드는 1초마다 플레이어의 스킬 사용 여부를 확인하는 폴링 방식입니다. 하지만 1초마다 상태를 확인하므로 성능 저하를 초래할 수 있습니다. 이 문제를 개선하기 위해 어떤 방법을 사용할 수 있을까요?인터럽트 방식CPU는 I/O 장치 관리자에게 명령을 전달하고 나서 다른 작업을 계속 수행합니다. I/O가 완료되면 장치 관리자가 CPU에 신호를 보내고, CPU는 이 신호를 받아 인터럽트 서비스 루틴(ISR)을 실행하여 해당 작업을 처리합니다. 이렇게 하면 CPU가 주기적으로 상태를 확인하지 않아도 되므로 성능이 향상됩니다. 프로그램과 프로세스의 차이는 무엇인가요?프로그램: 하드디스크와 같은 저장 장치에 저장된 명령어들의 집합프로세스: 메모리에 적재되어 실행 중인 프로그램 멀티프로그래밍과 멀티프로세싱의 차이는 무엇인가요?멀티프로그래밍: 메모리에 여러 개의 프로세스가 올라와 있는 것멀티프로세싱: 여러 개의 프로세스를 CPU가 처리하는 것 운영체제는 프로세스를 관리하기 위해 무엇을 사용하나요?프로세스 제어 블록(PCB)를 사용합니다. 컨텍스트 스위칭이란 무엇인가요?컨텍스트 스위칭은 실행 중인 프로세스의 상태를 기억 및 저장하고, 다른 프로세스로 교체하여 실행하는 작업입니다 (PCB 활용) 자료구조와 알고리즘여러분은 교실의 학생 정보를 저장하고 조회할 수 있는 관리 프로그램을 개발하려고 합니다. 이때 학생 정보를 저장하기 위한 자료구조로 무엇을 선택하시겠습니까? 이유를 함께 적어주세요.배열 구조를 선택하겠습니다.학생 정보는 학기 초 입학 시에 주로 작성되고, 후에는 주로 조회만을 수행하는 경우가 많기에 조회 시 O(1)의 시간 복잡도를 가진 배열이 적합합니다. 여러분은 고객의 주문을 받는 프로그램을 개발하려고 합니다. 주문은 들어온 순서대로 처리됩니다. 이때 어떤 자료구조를 선택하시겠습니까? 이유를 함께 적어주세요.큐 자료구조큐의 FIFO 구조를 감안했을 때 주문이 들어온 순서대로 주문 처리가 가능한 점에 착안하여 큐를 선택하는 것이 적합하다고 생각합니다.

인프런 워밍업 클럽 스터디 2기 - CS 1주차 미션

운영체제 위 코드는 1초 마다 플레이어가 스킬을 사용했는 지 체크하는 코드입니다. 이 방식은 폴링방식입니다. 1초마다 체크하기 때문에 성능이 좋지 않습니다. 이를 해결하기 위한 방식으로 어떤 걸 이용해야 할까요?while(true){ wait(1); // 1초 멈춤 bool isActivated = checkSkillActivated(); // 체크 } 인터럽트 방식이벤트 형식 -> 입출력이 완료되면 CPU에게 신호를 보냄 -> 신호를 받은 CPU는 ISR을 실행시켜 작업을 완료함폴링 방식은 CPU가 입출력 관리자에게 주기적으로 확인함 -> 비효율적 프로그램과 프로세스가 어떻게 다른가요?  프로그램은 명령문의 집합체프로세스는 프로그램이 실행될 때 메모리 위에 올라간 것 -> 즉 실행 중인 프로그램(메모리와 CPU를 사용 중임)운영체제는 프로세스를 관리하기 위해서 어떤 것을 사용하나요? PCB  프로그램이 실행되고 프로세스가 만들어질 때 PCB가 함께 생성 PCB에는 해당 프로세스의 정보를 가지고 있는 자료구조(포인터, 프로세스 상태 등등)컨텍스트 스위칭이란 뭔가요?  프로세스를 실행하는 도중 다른 프로세스를 실행하기 위한 작업 다른 프로세스를 실행하기 위해 실행중인 프로세스A의 작업 내용을 PCB(A)에 저장이후 실행할 프로세스의 작업 내용이 담긴 PCB(B)를 토대로 CPU가 세팅됨자료구조 여러분은 교실의 학생 정보를 저장하고 열람할 수 있는 관리 프로그램을 개발하려고 합니다.이 때 여러분이라면 학생의 정보를 저장하기 위한 자료구조를 어떤 걸 선택하실 건가요?이유를 함께 적어주세요.    배열교실의 학생 정보 -> 크기가 정해져있음학생 정보를 저장하고 열람 -> 참조한다. 인덱스로 빠르게 접근이 가능하기 때문에 배열을 사용한다(O(1)의 성능을 가지고 있음)   여러분은 고객의 주문을 받는 프로그램을 개발하려고 합니다.주문은 들어온 순서대로 처리됩니다.이 때 여러분이라면 어떤 자료구조를 선택하실 건가요? 이유를 함께 적어주세요.  큐들어온 순서대로 처리 -> 선입선출

미션프로세싱배열연결리스트

ronnie

백엔드 클린코드, 테스트코드 회고 1주차

해당 회고는 'Readable Code : 읽기 좋은 코드를 작성하는 사고법' 강의에 대한 회고입니다.시작팀프로젝트를 진행하면서 완성도 있는 코드를 짜고 싶다는 생각과 함께 여기저기서 들었던 코드 잘 짜는 방법에 대한 정리가 필요했습니다. 이런 모호한 생각들을 정리해보았고 결론적으로 이 강의를 듣게 되었습니다.제가 이 강의를 찾은 이유는 다음 3가지 이유에서였는데요,지금까지 프로젝트를 진행하면서 기능구현을 위한 개발은 했지만 같이 개발하는 팀원들을 위한 개발은 하지 못한 것 같다팀원들과 코드 컨벤션을 정하면서 서로 알고 있는 리소스 자체가 적어 방향성을 잡기 힘들었다팀원들에게서 괜찮았던 구현방식을 배우면서 나도 나만의 좋은 코드짜는법을 익혀 주변 사람들에게 공유하고 싶은 마음읽기 좋은 코드라는 의미를 작은 수준에서부터 자연스럽게 확장시켜가는 강의라고 느껴져 작은 부분에서부터 빠른 적용을 하고 싶은 저에게 좋은 선택이었다고 생각합니다. 배운 것들1주차에서 학습한 것은 추상에 관한 것들과 코드를 읽을 때의 생각을 배우고 이들을 기반한 객체 지향을 학습했습니다.읽기 좋은 코드를 쓰기에 앞서 시작을 추상으로 한 것이 좋았습니다. 구체적인 코드 작성법을 배우기 전 모든 것의 기반은 적절한 추상화라는 것을 느꼈습니다.다음은 코드를 읽을 때 어떤 사고가 이루어지는지와 이를 기반한 코드적 습관(?)을 배웠습니다. 뭔가 코드를 짤 때하는 행동들에 생명력을 주는 듯한 느낌이었습니다. 배운 것은 다음과 같습니다. 추상추상은 중요한 정보를 가려내고 덜 중요한 정보는 버리는 것반대로 추상에서 구체적인 것을 유연하게 찾을 수 있어야 한다!다음과 같은 이유로 추상에서 구체로 돌아가지 못할 수 있다..추상화 과정에서 중요한 정보를 부각시키지 못함해석자가 동일하게 공유하는 컨텍스트가 없음잘못된 추상화는 후폭풍이 매우 심하기 때문에 잘 고려해서 해야 한다. 이름 짓기이름 짓기는 추상화의 대표적인 예라고 할 수 있다.중요한 점은 표현하고자 하는 구체에서 중요한 개념만 추출해서 드러내고 우리 도메인 컨텍스트 안에서 이해되어야 한다는 것이다.다음과 같은 tip이 있다.단수와 복수를 비교하기만약 리스트나 컬렉션 타입이라면 복수형태로 표현해서 이해를 도울 수 있다이름 줄이지 않기줄임말은 얻는 것보다 잃는 것이 많다(가독성 > 효율성?)관용어처럼 사용되는 것 제외 (col, lat, lon, cnt는 비추천)줄임말이 이해되는 것은 컨텍스트 때문인 것을 늘 상기은어/방언 사용하지 않기농담, 일부 팀원만 아는 용어 금지도메인 용어 사용하기 (도메인 용어 사전을 먼저 구축해야 할 수도, 방대하거나 필요하다면)좋은 코드를 보고 습득하기비슷한 상황에서 자주 사용되는 단어나 개념 습득하기pool(한정된 자원을 가지는 것), candidate(후보), threshold(문지방, 한계점, 임계값) 등 메서드 추상화잘 짜여진 메서드는 메서드 안에 주제(하는 일)가 하나만 존재한다.메서드명을 생각해보면 메서드명은 내부의 구체적인 동작을 유추할 수 있어야 한다. 반대로 생각해보면 하나의 메서드명이 나오기 힘든 로직을 가진다면 2개 이상의 동작이 있을 확률이 크다. 메서드명, 파라미터, 반환타입은 추상화된 구체를 쉽게 유추할 수 있거나 실행할 때 필요한 변수들을 쉽게 캐치할 수 있도록 하는 것이 좋다. 반환 타입은 필요한 의미를 충분히 가지도록 하고 void 대신 반환할만 한 값이 있는지 고민해보자.  추상화 레벨메서드 안과 밖은 서로 추상화 레벨이 다르다.밖은 상대적으로 추상화 레벨이 높고 안은 낮다고 할 수 있다. 메서드 안팎은 서로 파라미터와 반환타입으로 교류한다.하나의 메서드 안에서 추상화 레벨을 맞춰주기 위해 구체적인 레벨의 것이 있는지 확인하고 있다면 메서드화하는 등의 방법으로 바꿔주면 좋다. 매직 넘버, 매직 스트링상수로 추출하는 것은 이름을 주어 추상화하는 것이라고 볼 수 있다.특정한 의미를 가지는 (보드의 가로, 세로 길이 등) 숫자나 문자열같은 경우에 상수로 추출해준다면 가독성과 유지보수성이 올라간다.또한 중요한 숫자나 문자를 강조하면서 읽는 사람이 더 주의깊게 볼 수 있도록 해준다.  사고의 depth 줄이기사고 과정의 depth를 줄이기 위한 메서드 추출을 고려하자.사용할 변수는 가깝게 선언하는 것이 좋다. 공백 라인, 부정어, 예외처리의미 단위로 적절하게 공백 라인을 사용하는 것이 좋다.연산자로 부정하기 보다는 메서드명으로 구성하는 것이 더 나을지 고민하자.해피 케이스 외의 예외들이 생길 부분을 고려하고 의도한 예외(사용자에게 보여줄 예외)와 그렇지 않은 예외(개발자가 보고 처리해야 할 예외)를 구분하자. Nullnull반환은 웬만하면 하지 않는다. Optional도 처리할 분기가 3개나 되기 때문에 꼭 필요한지 생각해본다.stream API를 적용하자. orElse(), orElseGet(), orElseThrow()의 차이를 알고 적절하게 사용하자.  마무리 회고어렴풋이 아는 것들을 확실하게 체득할 수 있었던 한 주였습니다.새롭게 기록되는 학습들을 보니까 기분이 좋습니다. 이번주에는 불규칙하게 들었지만 다음주에는 정해진 시간에 정해진 양만큼 들어야겠습니다. 다음주도 화이팅! 

웹 개발백엔드클린코드테스트코드워밍업클럽

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

Keep (유지할 점)편안한 학습 환경: 강의가 부담 없이 진행되어 사고를 확장할 수 있는 좋은 기회가 되었다.사고 중심의 접근: 각 섹션에서 개념을 깊이 있게 생각하고 적용할 수 있도록 돕는 내용이 많았다. 특히, 추상화와 Early return 기법을 통해 코드 가독성을 높이는 방법을 배운 점이 유익했다.다양한 관점 공유: 워밍업 클럽을 통해 다양한 사람들의 문제 해결 방식과 의견을 공유할 수 있는 점이 큰 장점이었다.Problem (문제점)체화의 어려움: 배운 내용을 실제로 체화하는 것이 어렵고, 마치 자주 사용하지 않는 단축키처럼 필요할 때만 떠오르게 되는 문제가 있었다. 예를 들어, SOLID 원칙을 실천하기 위한 방법이 즉각적으로 떠오르지 않을 수 있었다.정보의 과부하: 각 섹션에서 다룬 내용이 많아, 모든 개념을 동시에 소화하기에 다소 벅찼다. 특히, 객체 지향 패러다임과 상속, 조합의 복잡성을 이해하는 데 어려움이 있었다.Try (시도해볼 점)지속적인 연습: 배운 개념들을 간단한 프로젝트나 기능을 통해 의도적으로 연습하고 체화하는 시간을 가져야겠다. 예를 들어, 일급 컬렉션과 Enum을 활용한 작은 프로젝트를 진행해보겠다.개념 요약 정리: 각 섹션의 핵심 개념을 요약하여 개인 노트를 만들어, 자주 복습할 수 있도록 하겠다. 특히 객체의 책임과 역할에 대한 부분을 명확히 정리할 예정이다. 미션 2. 코드 리팩토링기존 코드기존의 validateOrder 메서드는 여러 조건을 중첩된 if 문으로 처리하여 가독성이 떨어지고, 확장성이 낮았습니다.public boolean validateOrder(Order order) { if (order.getItems().size() == 0) { log.info("주문 항목이 없습니다."); return false; } else { if (order.getTotalPrice() > 0) { if (!order.hasCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } else { return true; } } else if (!(order.getTotalPrice() > 0)) { log.info("올바르지 않은 총 가격입니다."); return false; } } return true; } 리팩토링한 코드리팩토링 후, 각 검증 로직을 별도의 클래스로 분리하여 Single Responsibility Principle을 적용했습니다. 이를 통해 가독성과 유지 보수성을 향상시켰습니다.public class Order { public boolean hasItems() { return this.getItems().size() != 0; } } public interface OrderValidator { boolean validate(Order order); } public class ItemValidator implements OrderValidator { @Override public boolean validate(Order order) { if (order.hasItems()) { return true; } log.info("주문 항목이 없습니다."); return false; } } public class PriceValidator implements OrderValidator { @Override public boolean validate(Order order) { if (order.getTotalPrice() > 0) { return true; } log.info("올바르지 않은 총 가격입니다."); return false; } } public class CustomerInfoValidator implements OrderValidator { @Override public boolean validate(Order order) { if (order.hasCustomerInfo()) { return true; } log.info("사용자 정보가 없습니다."); return false; } } public class OrderValidation { private final List<OrderValidator> validators; public OrderValidation(List<OrderValidator> validators) { this.validators = validators; } public boolean validateOrder(Order order) { for (OrderValidator validator : validators) { if (!validator.validate(order)) { return false; } } return true; } } 이 리팩토링을 통해 각 검증 로직이 명확하게 분리되어, 새로운 검증 규칙을 추가하기 쉽고, 코드의 가독성을 높일 수 있었습니다. 각 클래스가 단일 책임을 가지므로 유지 보수성도 향상되었습니다.

안지수

[워밍업 클럽] BE 클린코드&테스트 1주차 발자국

강의: Readable-Code: 읽기 좋은 코드를 작성하는 사고법 학습 내용추상 읽기 좋은 코드를 작성하기 위해서는 결국 도메인을 잘 이해하고 그 안에서 약속된 추상화를 해야 한다.논리, 사고의 흐름코드 읽는 사람의 뇌 메모리를 적게 쓰게 하기 위해서,else if 분기 보다 return문을 사용해서 사고의 depth를 줄이고공백 라인을 사용해서 로직의 흐름을 잘 따라갈 수 있게 만들자.!과 같은 부정연산자를 사용하기 보다 메서드에 부정의 의미를 담아서 읽는 사람이 뇌 메모리를 덜 쓰게 하자.해피 케이스 뿐만 아니라 예외 처리 주의 할 것.객체 지향 패러다임객체란 결국 추상화된 데이터와 코드의 모음관심사의 분리로 객체는 책임을 갖게 되고, 각 객체는 공개 메서드 선언부를 통해 다른 객체와 협력하게 된다.SOLID객체 지향 적용하기상속 보다는 조합 사용VO, 일급 컬렉션, ENUM을 통한 객체 지향 미션리팩토링 미션 시 고려한 점사고의 depth 줄이기 -> early return 사용기존 코드의 3중 if문을 3개의 if문으로 early return하는 구조로 리팩토링추상화 레벨 맞추기 -> 구체적인 로직을 메서드로 추상화객체의 getter를 호출하지 않고 추상화된 메서드 사용 회고Keep 진도표의 일정대로 강의 수강 & 미션 제출Problem 주어진 미션에 대해서 오래 고민하지 못한 점이 아쉽다.Try 미션에 좀 더 시간을 투자해서 강의 내용을 제대로 소화하고 미션에 충분히 적용할 수 있도록 해야겠다.

백엔드

spacebar

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

1주차 학습내용 추상잘 쓰여진 코드라면, 한 메서드의 주제는 반드시 하나다.생략할 정보와 의미를 부여하고 드러낼 정보를 구분하는 것이 중요하다. 추상화는 코드의 양보다 의미가 중요하다. 추상화 레벨이 갑자기 달라지면 코드를 읽는 입장에서 이해하는 데 어려움이 있기 때문에 어떤 의미를 담을 때 주변에 비해 너무 구체적인 의미를 담지 않는지에 대해 생각해야 한다. 논리,사고의 흐름 Early return 사고의 depth 줄이기 부정의 의미를 담는 다른 단어가 존재하는지 확인, 부정어구로 메서드명 구성 ('!'는 가독성이 떨어짐) 예외처리 -> 항상 NullpointException을 방지하는 방향으로 경각심을 갖고 코드 작성 메서드 설계시 return null을 자제하기!  객체 지향 패러다임 새로운 객체를 만들 때 1개의 관심사로 명확하게 책임이 정의되었는지 확인하기 setter 사용 자제하기, getter도 처음에는 사용 자제하고 반드시 필요한 경우에 추가 필드의 수는 적을수록 좋다. 객체 지향 적용하기 상속은 결합도가 높아 수정이 어려우니 조합과 인터페이스라는 유연한 구조를 사용하자. Value Object (VO) : 도메인의 어떤 개념을 추상화하여 표현한 값 객체 Entity와 VO의 차이는 식별자의 유무 (VO는 식별자가 없음)getter로 컬렉션을 반환해야 한다면 새로운 컬렉션으로 만들어 반환(외부의 조작 피하기 위해)   1주차 미션 [DAY2 미션]추상과 구체의 예시로 "집에서 아이스 라떼 만들기"의 과정을 설명했다. 일상 속의 예시를 생각하는 과정에서 추상과 구체라는 개념을 더 이해할 수 있었다.[DAY4 미션]예시 코드를 리팩토링 하는 과정에서 시간적 여유가 부족해 꼼꼼히 보지 못해 아쉬운 부분이 있다. (다시 리팩토링 해 볼 예정) SOLID에 대해 알고는 있지만 막상 설명하려고 하면 잘 나오지 않았는데 이번 기회에 나만의 언어로 적어보면서 더 정리할 수 있었다.회고가볍게 생각했는데 생각보다 매일 일정한 분량의 강의를 듣는다는 것이 쉽지 않았다. 그리고 막연히 '클린코드'는 좀 더 기술적인 역량이 갖춰진 상태에서 접해야 하는 부분이라고 생각했는데 강의를 듣다보니 내가 짜고 있는 코드에도 충분히 적용할만한 내용들이 많았다. 그리고 강의를 들으면서 객체지향에 대한 개념과 추상과 구체에 대한 내용을 코드 리팩토링에 어떤 식으로 적용할 수 있는지에 대해 생각해 볼 수 있었다.

성우

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

자바스크립트는 처음이지만... 이번 주 동안 배웠던 내용들을 가볍게 정리했다var, let, constvar : 중복 선언, 재할당 가능let : 중복 선언 불가, 재할당 가능const : 중복 선언과 재할당 둘 다 불가함 (재할당이 필요없다면 const를 사용하자 Window 객체브라우저에 의해 자동으로 생성(브라우저의 창을 나타냄) <- 브라우저의 객체브라우저 창에 대한 정보 찾기, 제어 가능var로 변수, 함수를 선언시 window 객체의 프로퍼티가 됨 DOMHTML 문서를 프로그래밍적으로 조작할 수 있는 객체 기반 구조각 HTML 요소는 트리 구조로 이루어진 노드로 표현Document 객체와 메서드를 이용해서 웹페이지의 상태와 모든 HTML 태그에 접근 가능 Event버튼을 클릭했을때 액션이 일어나게 하려면 -> EventListener이벤트 리스너를 호출하기 위해서는 이벤트 리스너를 객체나 요소에 등록해야함이벤트 종류UI, 키보드, 마우스, 포커스, 폼 등이벤트 버블링 : 이벤트가 발생했을시 이벤트가 상위 요소 핸들러에 전달 됨이벤트 캡처링 : 버블링과 반대로 상단 요소에서 아래로 이벤트가 내려옴이벤트 딜리게이션 : 하위 요소의 이벤트를 상위 요소에 위임Closure함수가 정의된 환경을 기억하고, 그 환경에 접근할 수 있는 함수(함수가 실행된 이후에도 외부 함수의 변수를 기억하는 기능), 데이터 은닉, 상태 유지 등에 사용순수 함수동일한 입력값에 대해 항상 동일한 결과를 반환하고, 외부 상태에 의존하지 않으며, 부작용이 없는 함수IFEE정의와 동시에 사용되는 함수, 변수를 전역으로 선언하는 것을 피하기 위해서 사용됨 (내부 안으로도 다른 변수들이 접근하는 것을 막을 수도 있음)비동기JS는 싱글 스레드 언어이지만 비동기 작업이 가능Callback: 작업이 완료되면 호출할 함수 전달Promise: 비동기 작업의 성공 또는 실패를 나타내는 객체async/await: Promise를 처리하기 위한 더 간단한 문법ES6ES(JS의 표준 사양을 정의하는 스크립트 언어. JS는 ES 표준을 구현한 언어)ES6는 ES의 6번째 버전이며 2015년에 발표(가장 중요한 버전)미션 1https://github.com/Sungw0o/JS-React/tree/main/frontend/mission/chap1  미션 2https://github.com/Sungw0o/JS-React/tree/main/frontend/mission/chap2 미션 3https://github.com/Sungw0o/JS-React/tree/main/frontend/mission/chap3  회고JS는 아예 진짜 처음이라 배우는데 너무 익숙하지 않아 고생했다다음주에 JS 강의 1회독을 빨리 마무리하고 이해가 되지 않았던 부분부터 차근차근 복습해야겠다 

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

dmstjd0214

[인프런 워밍업 스터디 클럽 2기_BE] 1주차 회고록 정리

오랜만에 인프런 워밍업 클럽을 진행했다.기존에 한 번 들었던 강의들이지만 너무 알차고 맛있는 강의였기 때문에 다시 듣는 마음에 설레였다.이번 주차에서는 가장 중요하다고 생각한 것들이 있는데추상과 구체논리, 사고의 흐름객체 지향 패러다임SOLID객체 지향 적용하기이 흐름이었는데, 정말로 강의를 보면서 느낀 것은생각하는 방법에 대해 알려주기 → 생각을 직접 해보기 → 생각한 것에 대한 구현을 진행하기라는 순서로 이루어져 있다는 것을 깨달았다.추상화를 잘하는 것은 핵심을 파악하는 것이며, 분석하는 능력을 키울 수 있다고 생각했다!첫 주차 과제를 진행하며, 추상과 구체를 작성하는 방법을 배웠고 실생활에서 구체화를 하는 작업을 해보았다.이름이랑 메서드명, 심지어 띄어쓰기를 하는 것조차 추상화의 과정이라는 점이 너무 신기했다.추상화 레벨이라는 내용도 있었는데, 상당히 많은 도움이 된 것 같았다. 코드를 읽으면서 "이건 구체화된 내용이지 않을까? 가독성이 좋은가?"라는 생각을 끊임없이 이어갔다.내가 부족했던 부분은 핵심을 파악하고 간추리는 생각이었는데, 생각하는 방법을 기르는 연습을 한 것이 너무 좋았다. 구현은 어떻게든 할 수 있지만, 어떤 방식으로 설계할지는 나의 몫이라고 생각했다!생각한 후에는 그에 맞는 객체를 설계해야 하는데,설계 과정에서 주의해야 할 점이 머릿속에 박혔다. "무례한 행동"이라는 말이 머릿속에 박혀 토이 프로젝트나 개발을 진행하면서 getter나 setter를 사용하려고 할 때 많이 떠올랐다.객체를 설계할 때 높은 응집도와 낮은 결합도가 핵심이었다. 용어를 알고 개발하는 것과 모르고 하는 것의 차이가 크다는 것을 알았다.응집도: 하나의 클래스가 기능에 집중하기 위한 모든 정보와 역할 결합도: 모듈 간의 상호 의존성을 나타내는 개념객체의 결합도와 응집도에 대한 이해하기 쉬운 정리점진적인 리팩토링 방법도 배우고 정말 꿀팁만 얻은 느낌이다.도메인 지식은 생각하는 것이 아닌 발견하는 것이다. 도메인 주도 개발을 공부할 때, 도메인 지식을 어떻게든 생각해서 개발을 진행했는데, 하다 보면 도메인이 발견되고 그에 맞게 개발을 하며 점진적인 리팩토링을 하는 궁극적인 개발 방법을 배운 것 같다.SOLID 원칙에 대해 이론적으로만 공부했었는데, 직접 코드를 작성하며 배우니까 확 와닿았다.단일 책임 원칙 (SRP): 하나의 클래스는 단 한 가지의 변경 이유만을 가져야 한다.개방-폐쇄 원칙 (OCP): 확장에는 열려있고, 수정에는 닫혀 있어야 한다.리스코프 치환 원칙 (LSP): 상속 구조에서 부모 클래스의 인스턴스를 자식 클래스의 인스턴스로 치환할 수 있어야 한다.인터페이스 분리 원칙 (ISP): 클라이언트는 자신이 사용하지 않는 인터페이스에 의존하면 안 된다.의존성 역전 원칙 (DIP): 상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 된다.전체적으로는 이전에 배운 책임과 역할에 대해 이론적으로 가장 많이 정리된 느낌이었다. 그중에서 SRP와 DIP가 가장 와닿았으며, 책임과 역할별로 클래스를 나누고 추상화된 인터페이스를 참조하여 사용하는 것을 직접 코드로 작성하며 배웠다. 기존에 작성했던 코드에 대해 많은 반성을 하게 되었다. 책임이 없는 나쁜 코드였던 것 같다.섹션 5에서 직접 객체 지향을 코드에 적용해 보았다.각 내용을 정리해보면,Entity는 식별자를 통해 고유성을 가지며, 시간에 따라 상태가 변할 수 있지만, VO는 불변성을 가지며 모든 속성이 동일하면 같은 객체로 간주된다.일급 컬렉션은 컬렉션을 감싸는 클래스로, 컬렉션을 포함한 비즈니스 로직과 불변성을 보장하여 관리하는 객체이다.Enum은 상수의 집합이며, 상수와 관련된 로직을 담을 수 있는 공간이다.다형성 활용하기 부분에서는 전략 패턴과 함께 적용해서 회사에서도 코드 작성을 더 깔끔하게 해 보았다. 아직 일급 컬렉션에 대해서는 확실히 와닿지는 않아서 추후에 공부하면서 "아, 이런 개념이 있었구나"라고 언젠가 깨달을 것 같다.2주차 과제는 주어진 메서드에 대해 객체를 설계하고 적용해 보는 내용이었다. 섹션을 보고 큰 키워드를 떠올리며 개선을 했는데, 딱딱 맞아떨어지면서 "아, 이렇게 다음에 큰 규모의 코드가 있을 때 바꾸면 되겠구나"라고 어느 정도 감을 잡았던 것 같다.관련 코드: GitHub 링크아직 객체 지향에 대해 공부를 많이 하지는 않았고 익숙하지는 않지만, 조금씩이라도 이런 식으로 하면 좋겠다는 생각을 한 것 자체로 성공이라고 생각한다. 2주차를 진행하면서 더 확 와닿을 수 있기를 기대하며 계속 공부를 이어가야겠다.

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

너무 짧았던 일주일이었습니다.리더블 코드를 수강하면서 원래는 2개의 강의이기도 하고 나름 solid에 관심이 있었기에 강의 소요 시간이 짧을 줄 알았는데 코드를 직접 만들어보는 것이 오래걸리더라고요.쉽지 않았습니다.진짜 처음부터 알려주십니다. 초반에는 쉬웠습니다. 공백이나 !를 어떻게 사용하는 것이 좋은지, 이름 짓는 기준 등 섹션3까지는 쉬웠는데 섹션 4부터 조금씩 어려워지더라고요.특히 solid가 강의 시간도 길고 어려웠는데 solid를 적용하면서 솔직히 "지금 코드에서는 비효율적인 것 같다"라는 느낌을 받았지만, 유익한 개념으로 하나씩 예시를 들어서 설명해주는 것이 쉽게 이해되었습니다. (그것과 별개로 개념을 코드로 만드는 것은 진짜 힘들더라고요.)"왜 클린 코드를 추구해야 되는가?"부터 "추상화란 무엇이며, 어디서부터 출발하는건가?"를 지나 "객체 지향 적용하기" 때 VO가 뭔지도 몰랐던 저에게 좋은 경험이 되었습니다.솔직히 DTO, VO, DAO 등을 헷갈려서 블로그를 매번 찾아보지만 확실하게 개념이 확립되지 않았지만 VO를 제대로 배울 수 있어서 좋았습니다. 강의 자체에 소요 되는 시간이 너무 많기에 앞으로는 시간을 줄이기 위해서 이론듣고 저 혼자 실습해본 뒤에 강의 실습을 따로 듣는 방법으로 진행해보려 합니다.다음 주에는 선행학습을 할 수 있을 정도로 빨라졌으면 좋겠습니다. 첫 번째 미션의 정답이 없는 문제라서 최대한 다양한 방법으로 표현하는 것을 답으로 제출하려고 했습니다.하지만 후손들 입장에서는 알아보기 힘들 것 같아서 통일성 있게 코드를 수정했습니다.그리고 미션을 주시는데 간략하게 말하자면 강의에서 배운 내용을 나만의 언어로 바꾸는 연습하면서 다른 사람들이 어떻게 생각하는지 같이 공유할 수 있다는 것이 좋은 것 같아요. 코드를 따라치는데 게임을 실행 중에 열었을 때 근처 빈 곳은 열려야 하는데 열리지 않아서 고생했네요...파라미터랑 사용하는 값이랑 달라서 생긴 오류였는데 그걸 계속 못 찾아서 하나씩 비교해서 봤네요...

백엔드백엔드readable_code

cosmos

[워밍업 클럽 스터디 2기 - BE 클린코드&테스트] 1주차 발자국

1주차 동안 학습했던 내용 정리하나의 클래스와 거대한 main 메서드에 작성된 지뢰찾기 게임을 강의를 수강하면서 읽기 좋은 코드로 수정하는 과정을 단계적으로 학습했다.두 번째 섹션에서는 추상이라는 주제로 시작하여 구체와 추상에 대한 정의를 배우고, 추상화하는 과정에서 다음과 같은 방법을 학습했다.의미를 적절하게 전달하는 메서드, 변수명 짓기메서드 선언부에 꼭 필요하고, 적절한 파라미터 전달하기하나의 메서드 안에서 추상화 레벨을 동일하게 맞추기일정한 의미를 가지는 숫자나 문자열을 상수로 추출하기세 번째 섹션에서는 코드를 읽는 과정에서 코드 내용을 기억하기 위해 뇌의 메모리를 사용한다는 사실에 대해서 인지할 수 있었고, 이 메모리 사용량을 줄일 수 있는 다음과 같은 방법을 학습했다.Early return으로 리턴해야 될 값을 바로 바로 반환하기코드 중간 중간 의미가 나뉘는 부분에 공백 라인을 삽입하기부정 연산자를 사용을 지양하고, 메서드 이름으로 부정의 의미 전달하기사용자가 서비스를 이용할 때 성공적인 시나리오대로 이용할 것이라는 생각을 버리고, 적절한 예외를 이용해 적절하지 않은 사용에 대해서도 방어적인 코드 작성하기1주차 미션에 대한 회고Keep첫 번째 미션을 기한 안에 제출했다.두 번째 미션은 기한 안에 제출하지 못했지만, 1주차가 끝나기 전에 제출했다.Problem1주차 미션은 크게 어려운 점이 없었다.TRY함께 스터디를 진행하는 다른 개발자분이 제출한 풀이법과 내 풀이법을 비교하면서 부족한 부분을 추가적으로 학습하자.1주차 학습에 대한 회고Keep워밍업 클럽 스터디 2기에 참여했다.스터디를 통해 평소 학습하고 싶었던 내용에 대해서 학습할 수 있는 기회를 잡았다.Problem두 번째 미션을 기한안에 제출하지 못했다.강의를 수강하는 동안 집중력일 잃고 자주 핸드폰을 확인했다.TRY미션 제출 기한을 꼭 지키자.미션, 발자국을 마감 시각에 맞춰 제출하는 것이 아닌 여유를 갖고 미리 미리 진행해서 제출 마감 전날에 제출한다.미션, 발자국 마감일에는 제출했던 내용을 다시 곱씹으며 부족한 부분이 없는지 체크한다.강의를 수강하는 동안에는 핸드폰을 확인하지 않는다.학습 시간과 휴식 시간을 적절하게 안배해서 강의 내용을 최대한 많이 흡수하려고 노력하자.

백엔드백엔드읽기좋은코드발자국스터디

Dayoming

인프런 워밍업 클럽 백엔드 스터디 2기 | 1주차 발자국🐾

 박우빈 님의 Readable Code: 읽기 좋은 코드를 작성하는 사고법 을 듣고 작성한 게시글입니다.  강의 수강 내용 요약강의에서 사용되는 용어들🔑도메인(domain)- 해결하고자 하는 문제 영역- ex) 결제 도메인, 주문 도메인, 상품 도메인...🔑 도메인 지식- 도메인을 이해하고 해결하는 데 필요한 지식부끄러운 이야기지만 도메인(domain) 이라는 이야기를 많이 들어보긴 했어도 도메인의 정의에 대해서는 따로 생각해보지 않았던 것 같다. 강의에 시작하기 앞서 사용되는 용어들에 대해 정리해 보면서 프로그래밍은 문제(=도메인)를 해결하기 위한 도구라는 생각을 다시 한 번 상기한 상태로 본 강의를 수강할 수 있었다. 추상 (抽象)사물을 정확하게 이해하기 위해서 사물이 지니고 있는 여러 가지 측면 가운데서 특정한 측면만을 가려내어 포착하는 것, 어떤 일면만을 추상하는 것은 다른 측면을 버린다는 것과 같다.'깨끗한 코드를 쓰는 것'은 많은 개발자들의 로망이자 지켜야 할 규칙으로 자리잡고 있다. 그렇지만 우리에게 중요한 건 단순히 규칙을 지키는 것이 아니다. 개발자는 프로그램을 만드는 순간 순간 최적의 선택을 해야 하기 때문에 '왜 그런 규칙이 생겨났는가' 가 중요하다. 어떤 경우에는 규칙을 깨야 하는 경우도 존재한다. 그 편이 소프트웨어와 소프트웨어를 사용하는 사람들에게 더 좋다고 판단된다면!지식 공유자님이 말씀하시는 클린 코드가 중요한 이유는 가독성이다. 글이 잘 읽힌다는 것은 이해가 잘 된다는 뜻이고, 유지보수 하기가 수월해지므로 우리의 시간과 자원을 절약하게 해준다. 클린 코드라 지칭하는 수많은 원칙이나 조언은 이를 위해서라고 한다. 레거시 코드를 읽을 미래의 나나 다른 개발자가 코드를 빠르게 이해할 수 있는 코드를 짜두면 장기적으로 더 나은 생산성을 보이게 된다.이런 가독성을 위해서 중요하게 여겨지는 개념이 추상(抽象)이다. 무언가를 추상화한다는 것이 어렵게 다가오겠지만, 우리 뇌는 일상적으로 이 일을 수행하고 있다. 예를 들면 '차를 마신다'는 것도 다음과 같은 행위의 추상이다.1. 물을 끓인다. 2. 끓인 물을 컵에 붓는다. 3. 끓인 물이 들어있는 컵에 티백을 넣는다. 4. 찻물을 2~3분 정도 우린 후 마신다.컴퓨터 과학에서의 대표적인 예는 자료형(Type)이다. 1byte는 8bit를 묶은 것이고, char은 1byte로 문자 1개를 의미한다. 즉, 데이터(=bit) 덩어리를 어떻게 읽을 것인지에 대한 추상이다. 이렇게 적절한 추상화는 복잡한 데이터와 복잡한 로직을 단순화하여 이해하기 쉽도록 돕는다.적절한 추상화는 구체를 유추할 수 있게 한다. 누군가 '차를 마셨다' 라고 하면 물을 끓여 찻잎을 우리는 모습을 쉽게 상상할 수 있다. 그러나 잘못된 추상화가 야기하는 사이드 이펙트 또한 크다. 추상으로부터 구체를 유추하지 못한다면 잘못된 추상화이다. 이런 경우가 발생하는 이유는 다음과 같다.추상화 과정에서 중요한 정보를 부각시키지 못했다.해석자가 동일하게 공유하는 문맥이 없다.예를 들어 우리 집에서는 '밥 먹기' 를 '냠냠이 먹기' 라고 한다고 가정하자.회사 동료에게 '저는 어제 8시에 냠냠이 먹었어요.' 라고 한다면..아마도 갑자기 왜 귀여운 척을 하지? 라고 생각하지 않을까?이런 상황을 방지하기 위해서는 중요한 정보만 남도록 잘 덜어내어 추상화 하고, 적절한 이름을 짓는 것이 필요하다.어떻게 보면 '냠냠' 이라는 건 '먹는다' 는 구체를 떠올릴 수 있게 해주니, 아주 틀린 추상은 아닐지도 모르겠다. 이상한 사람 취급을 받을 수는 있겠지만 메서드와 추상화 레벨이름을 짓는 것과 더불어 인상깊었던 부분은 메서드와 추상화 레벨에 관한 부분이었다.'메서드명 뿐만 아니라 메서드 선언부 전체가 유기적으로 관여해서 의미를 전달한다' 는 것! 프로그램을 짤 때 메서드명은 최대한 메서드의 행동이 잘 드러나도록 작성하려고 하는 편인데, 파라미터나 반환타입까지 고려해야 한다는 생각은 해본 적이 없었다.회고를 하면서, 최근 넷플릭스에서 본 흑백요리사가 떠올랐다.출처: 넷플릭스안성재 셰프는 '요리를 만든 사람의 의도가 전해지는 것' 을 가장 중시한다. 요리에 쓸모없는 데코레이션을 올리는 것 보다 각 음식의 재료들이 자신의 역할을 다하길 바란다. 프로그램을 짜는 것도 다르지 않다는 생각이 들었다. 파라미터, 반환타입, 메서드명이라는 재료를 가지고, 누구나 이 메서드가 의도한 바를 명확히 알 수 있도록 하는 것. 모든 메서드를 이런 마음가짐으로 설계한다면 프로그래머계의 미슐랭 3스타를 받을 수 있지 않을까? 논리, 사고의 흐름뇌 메모리를 적게 쓰는 방법에 대해 알게 되어 좋았다.전에 클린 코드나 객체지향 생활체조 원칙에 대해 읽으면서 크게 와닿지 않았는데 직접 코드를 읽어보고, 고쳐보고, 고친 코드를 읽어보는 과정을 반복하니 이해할 수 있었다. if ~ else if ~ else문으로 코드를 짜는 게 본인 입장에서는 확실히 직관적이고 편하지만.. 겪어야 할 고통을 미래로 미뤄두는 것 뿐이다. 심지어 그 고통은 복리로 돌아온다. return 할수 있는 부분은 빨리 return 하고, 메서드로 쪼갤 수 있는 부분은 쪼개자! 물론 어떤 것이 효율적일지에 대한 적절한 판단이 필요하다.예외에 관한 부분도 좋았다. 프로그램을 짜다 보면 대부분 '대충 이렇게 잘 흘러가겠지?' 라고(해피케이스) 생각하게 되기 쉽다. 그러나 우리는 항상 방심하지 말고 예외가 발생하는 상황을 염두에 두어야 한다. 그냥 처음부터 '아마 생각한대로 흘러가진 않겠지만 이렇게 되긴 해야 돼..' 라고 생각하는 게 나을지도 모르겠다. 의도한 예외와 의도하지 않은 예외를 잘 구분해서 예상치 못한 상황이 발생하더라도 대참사만은 막을 수 있도록 안전한 프로그램을 설계하는 연습을 해야겠다. 객체 지향 패러다임과 SOLIDSOLID.. 정보처리기사 공부 했던 때가 주마등처럼 스쳐지나갔다. 뭔지도 모르고 달달 외웠었는데..코드를 직접 수정하며 각각 원칙을 적용해보는게 재미있었다. 다만 따라하면서 만약 내가 프로그램을 설계한다면 이 원칙들을 다 지키도록 설계할 수 있을까? 하는 생각이 들었다. 조금만 프로그램 규모가 커져도 지금보다 훨씬 복잡해질 것 같다😥 확실히 읽기에 편한 만큼 쓰는 사람이 고생해야 한다.. 그만큼 더 많이 복습하고, 더 많은 코드들을 봐야겠다고 다짐했다. 미션 수행 요약DAY2 - 추상과 구체의 예시 들기추상과 구체의 예시를 생각하는 것은 그리 어렵지 않았다. 그렇지만 '일상 생활에서 이렇게 많은 추상화가 이루어지고 있었구나' 하는 생각이 들어 신기했다. 추상이라는게 되게.. 어려운 말이라고 생각했는데 그냥 필요한 부분만 뽑아내는 것이라는게 체감됐다.책을 읽는 행위를 구체화 한다면? 1. 책을 손에 쥐거나 디지털 장치에서 페이지를 연다. 2. 눈으로 글자를 추적한다. 3. 글자를 인식하는 즉시 문장과 단어들이 뇌에서 의미로 변환된다. 4. 글 속의 아이디어와 자신의 가치관을 비교하고 의미를 추측해 자신의 해석을 만들어 낸다.다른 분이 하신 과제도 간간히 구경했는데, 특히 기억에 남는 과제가 있었다. 추상: 아침엔 네 다리로 걷고, 점심엔 두 다리로 걷고, 저녁엔 세 다리로 걷는다. 구체: 인간 ... 진짜 생각지도 못했다. 이런 수수께끼들도 사실 추상이었다👏🏻👏🏻 DAY4 - 코드 리팩토링, SOLID 요약🛠 리팩토링 전public boolean validateOrder(Order order) { if (order.getItems().size() == 0) { log.info("주문 항목이 없습니다."); return false; } else { if (order.getTotalPrice() > 0) { if (!order.hasCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } else { return true; } } else if (!(order.getTotalPrice() > 0)) { log.info("올바르지 않은 총 가격입니다."); return false; } } return true; }🛠 리팩토링 후public class ValidateException extends IllegalArgumentException { public ValidateException(String message) { super(message); } }public boolean validateOrder(Order order) { if (order.getItems().size() == 0) { throw new ValidateException("주문 항목이 없습니다."); } if (order.getTotalPrice() < 0) { throw new ValidateException("올바르지 않은 총 가격입니다."); } if (order.hasNotCustomerInfo()) { throw new ValidateException("사용자 정보가 없습니다."); } return true; }지금까지 배운 내용을 토대로 리팩토링을 진행했는데 너무너무 재밌었다. 이게 천직인가 싶을 정도로.. 예전에 현업에 있을 때도 그랬는데 구현보다 레거시 코드 뜯어 고치는게 더 재밌는거 정상이죠?확실히 강의를 들으며 공부하는 것과 실제로 배운 걸 적용해보는건 다르다. 앞으로 더 많이 뜯고, 읽고, 쓰면서 욕도 먹어보고 해야겠다. 갈길이 멀다.KPTKeep: 앞으로 지속하고 싶은 부분회고회고를 작성하면서 기록했던 부분을 다시 돌아보니 당시에 들었던 강의 내용이 생생하게 기억나서 좋았다. 사실 개발 외적으로도 주간 회고, 월간 회고, 이런 저런 회고 방법을 시도했었지만 딱히 와닿지 않았다. 그런데 이번에 1주차 발자국을 작성하면서 공부했던 내용을 돌아보게 되고 내가 알게된 것들과 몰랐던 것들에 대한 경계선이 뚜렷해지는 느낌을 받았다. 우빈 님 추천으로 KPT 방식도 알게 되고.. 4주차 회고를 진행할 땐 회고의 달인이 된 내 모습까지 기대해보며👶🏻커뮤니티 활동낯을 많이 가리는 나지만.. 나름 열심히 커뮤니티 활동에 참여하려고 노력하고 있다. 뭔가 아는 척 하는 것 같아 보일까 보내고 난 직후에도 삭제할까 말까, 괜히 보냈나 백 번 고민했다😥 그래도 인프런 워밍업 클럽이 제공하는 가장 큰 혜택이 이 커뮤니티 아닐까 싶다. 실제로 다른 분들이 이야기 하는 걸 구경하기만 해도 지식이 느는 기분이다. 직접 참여할 때는 두말 할 것 없이 성장한다. 위 대화만 해도 JVM과 스레드에 대해 다시 한 번 정리해볼 수 있는 시간이었다. 늘 커뮤니티에 상주하고 계신 몇몇 분들 덕분에 자극도 많이 받는다👍🏻Problem: 아쉬웠던 점기록나는 강의를 들으면서 거의 모든 내용을 기록해둔다. 당시에 생각나는 것, 듣고 있는 내용... 쓰다보면 사실 회의감이 들 때도 있다. 시간이 거의 두 세배는 넘게 걸리니 비효율적이지 않은가? 하는 생각이 들고 있었다. 시간이 오래 걸리니 강의를 틀기까지 꽤 큰 결심이 필요한데 필기 방식을 바꿔야하나 고민 중이다.일정이번에 진도표에 적힌 진도를 모두 따라가지 못했다. 다음 주에는 이번 주에 밀린 진도까지 꼭 학습해야겠다.Try: Problem을 해결하기 위해 시도해볼 점인프런의 강의 노트 기능을 이용해보는건 어떨까?일정은.. 그냥 열심히 하는 수밖에 없다. 이번엔 꼭 주말 전까지 2주차 진도를 끝내 놓을 것🔥🔥🔥

백엔드클린코드백엔드워밍업클럽JAVA

표수진

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

회사를 다니면서도 기본적인 내용만 대충 알고 '퇴근하면 피그마 공부해야지..' 했었는데 퇴사하고나서야 시간이 생겨 이렇게 피그마 공부를 제대로 시작하게 됐다. 혼자 공부하다보면 다른 일때문에 강의를 듣는 게 우선순위에서 밀리는 경우가 종종 있었는데 인프런 워밍업 클럽과 함께 정해진 시간표에 따라 미션을 수행하다보니 강제적인 요소가 있어서 아직 1주차지만 더 열심히 강의를 들으려고 했던 것 같다.그리고 재직중에도 스타일 가이드는 여러번 작성해봤던 적이 있었지만 실제로 디자인 시스템까지 구축해본 경험은 없어서 실무에서는 디자인 시스템을 어떻게 개발하고 어떻게 활용하는지 제대로 알고 싶어서 볼드님의 강의를 듣게 되었는데 기초적인 개념부터 꼼꼼하게 알려주셔서 이번 기회에 피그마 배리어블에 대해 깊게 이해하고 역량을 키워 프로덕트 디자이너로서 원하는 회사로 이직까지 할 수 있었으면 좋겠다. 1주차 강의 내용 요약디자인 토큰과 배리어블, 디자인 시스템에 대한 기본적인 개념 및 구조 알아보기배리어블은 디자인 토큰을 만들기 위한 요소이고, 디자인 토큰은 디자인 시스템의 기본 구성 요소일관성 있는 경험을 제공하기 위해 제작,관리하기도 훨씬 용이한 특징이 있음 디자인시스템 : 재사용 가능한 컴포넌트, 패턴, 가이드디자인시스템은 '큰 목표를 가지되, 작은 성공을 이뤄나가면서 공감대를 형성하며 만들어가야한다'색상, 간격, 타이포그래피, 아이콘, 그림자 효과 등 배리어블 및 스타일로 등록하기배리어블은 오직 하나의 변수만 저장(참조 가능), 스타일은 하나 또는 다수의 변수 저장배리어블은 Raw value - Primitive - Theme - Semantic - Component로 계층을 가지고 있음입력(Input) 컴포넌트 만들기 : 버튼, 체크박스, 라디오버튼, 스위치 버튼컴포넌트와 인스턴스, 프로퍼티에 대한 기본 개념 공부 스스로 칭찬하고 싶은 점스터디 진행 일정에 맞춰서 한주동안 온라인 강의를 열심히 듣고 미션을 수행했다.피그마 공부에 대해 하루 루틴을 만들 수 있었던 좋은 기회가 된 것 같다.모르는 개념을 이해하기 위해 여러번 강의를 들어보면서 조금은 감을 잡으려고 노력했던 것 같다.아쉬웠던 점, 보완하고 싶은 점(다음주 목표)조금 더 일찍 공부를 제대로 시작했으면 어땠을까 하는 아쉬움이 크게 남았지만 1달동안 열심히 해서 꼭 피그마 배리어블을 마스터 할 수 있었으면 좋겠다.이번주는 휴일이 중간에 있었어서 매일 매일 같은 시간대에 공부를 하지는 못했다. 다음주부터는 오전 시간을 활용해서 강의를 듣도록 노력해야겠다.피그마를 제대로 배우는 게 처음이다보니 아직 어려운 부분이 많아서 강의 내용에 따라가기 급급했는데 다음주부터는 왜 이렇게 만드는지에 대해 조금 더 고민해보는 시간을 가져봐야겠다. 

UX/UIUXUI피그마피그마배리어블프로덕트디자인figma볼드UX

syhan7516

[워밍업 클럽 2기 BE - 클린코드 & 테스트] 1주차 발자국

읽기 좋은 코드가 중요한 이유쓰기보다 읽기에서 더 많은 시간을 소비시간과 자원을 아끼려면 읽기 수월한 것이 중요 추상과 구체 (이름, 메서드)추상화는 중요한 핵심 개념을 남겨서 표현한 것추상으로 구체화된 내용을 예측 가능해야 잘된 것이름의 다양한 방법으로 표현 가능                    하나의 문단에는 하나의 주제로 접근메서드의 구성으로 예측 가능하도록 하기 상수날 것의 상수 또한 예측 가능한 표현을 사용하자 뇌 메모리 적게 쓰기뇌가 힘들면 읽기 좋은 코드가 아니다Early return,사고의 depth 줄이기,공백 라인과부정어의 고민 예외 처리예외 처리를 통해 견고한 SW 개발 가능외부 접점에서 주로 발생 의도에 따라 예외 구분Null 대한 고민 필요 추상의 객체 지향객체 간의 협력과 책임 관점으로 생각관심사의 분리를 통해 부여 객체 지향의 특성에 맞게 객체 설계 및 접근 (캡슐화, 추상화, 상속, 다형성) SOLID객체 지향 설계를 더 이해하기 쉽고, 유연성과 유지 보수하기 쉽게 도와주는 원칙들SRP - 하나의 클래스는 하나의 책임 담당OCP - 확장에는 열려있고, 수정에는 닫혀있기LSP - 부모는 자식으로 대체 가능하도록 하기ISP - 사용하지 않는 인터페이스 의존하지 않기DIP - 상위 모듈은 하위 모듈의 구현에 의존하면 안되며, 상위 모듈에서 정의한 추상 타입에 의존하자  객체 지향 적용하기상속보다 조합을 사용VO,일급 컬렉션,Enum,다형성 활용완벽한 설계는 없으며, 당시 최선을 다하기 미션 해결 과정 요약SOLID 정리의 경우 필요한 이유를 중점으로 저의 언어로 표현하였습니다.그 과정에서 예시를 검색하며, 적용 전과 적용 후를 비교해 저의 것으로 만드는데 많은 도움이 되었습니다.읽기 좋은 코드를 만드는 과제에서는 어떻게 하면 쉽게 읽을 수 있을지 고민하였습니다.그 과정에서 수정하고, 다시 읽어보는 식으로 쉽게 읽힐 때까지 반복하여 배움을 적용하는데 큰 도움이 되었습니다. 1주차 회고강의 내용을 시간이 날 때마다 복습하여 이론적으로는 모두 흡수하여 뿌듯합니다.자바 개념이 부족하여 새롭게 배운 내용을 찾아보느라 강의 코드 작성을 많이 못해 아쉽습니다.이론 뿐만 아니라 강의 코드 작성 연습을 통해 다른 면에서도 더 잘 습득할 수 있도록 목표로 하겠습니다. 강의 출처 : Readable Code: 읽기 좋은 코드를 작성하는 사고법

정지훈

인프런 워밍업 클럽(클린코드, 테스트) - 1주차 발자국

[Readable Code: 읽기 좋은 코드] 발자국 박우빈님의 읽기 좋은 코드강의를 수강했고, 마침 워밍업 클럽 스터디가 열려서 참여하게 되었다.수강했던 내용을 한번 더 복습하면서 체화시켜보고, 놓쳤던 부분들을 복습하기 위해서였다.목표했던 봐와 같이 한번 더 들으면서 학습하니까 전에 놓쳤었던 부분들이 보였고, 실습과 함께하니까 코드를 보는 실력이 향상됨을 느꼈다. 1주차의 핵심 내용은 아래와 같았다추상사고의 흐름객체지향 패러다임  머리속에서 이해하고 있던 내용을 직접 실습해보며 진행했다. 기존에 개인적으로 학습하던 자바프로그래밍 학습 저장소에, 직접 배운 내용을 적용해보면서 진행하였다.강의에 나오는 예제를 보면서 실습하면, 나도 모르게 나의 사고가 아닌 배운 내용을 외워서 하는 실습이 될 것이라고 생각했기 때문이었고, 실제로 직접 고민하는 시간을 많이 가질 수 있어서 좋았다. 과제는 1주차에 2회 진행하였다.[Day2 과제]주소창에 www.google.com 을 입력했을 때 화면이 출력되기까지의 과정을 구체레벨로 표현하면?위의 문장으로 내 과제를 제출했다.기본적인 네트워크 동작이지만 내부적으로 많은 구체적인 작업들이 이루어져있기 때문에 추상에 잘 어울리는 예시였다고 생각한다.또한 저 문장을 살펴보면서 한번 더 네트워크에서 이루어지는 동작에 대해 깊게 생각해보고 학습해볼 수 있었다. [Day4 과재]https://github.com/Jeongjjuna/inflearn-warming-up-club/blob/main/src/main/java/day4/Main.java위와 같이 과제를 제출하였고, 중점적으로 생각한 내용은 아래와 같다.if-else의 복잡성을 최대한 단순화하고, 가능하면 빠르게 리턴하자.메서드명을 의미있게 작성하자.상수를 분리하자.Order 객체에세 메세지를 던져서 내부에게 물어보는 방식으로 구현하자.주된 과제의 목적인 사고의 흐름을 막지않고 최대한 물 흐르게 코드를 읽기 쉽게 작성하는 것이 목적이었다고 생각한다.그 과정에서 내가 아는 지식들, 그리고 강의에서 들었던 여러 내용들을 적용하려 노력했다. 마무리마지막으로 과제를 진행하고 실습하는거에만 몰두하지 말고, 함께 공부하는 학습원들의 학습 블로그를 많이 찾아보고 싶다고 생각이 들었다.중간중간 다른분들의 과제를 보며 이렇게도 할 수 있구나 하는 생각이 많이 들었었고, 이번주는 많은 분들의 코드를 보지는 못했지만, 많이 찾아볼 수 록 좋은 경험, 좋은 인사이트를 얻을 수 있을 것 같다. 다음주는 2주차로 읽기 좋은 코드 마지막인데, 그동안 봐왔던 강의내용을 모두 적용해보려고 노력해봐야겠다. 화이팅!

백엔드백엔드워밍업클럽발자국

유진

Node.js 개발자의 코-프링 적응기(1) | 인프런 워밍업 클럽 2기 - 백엔드

인프런 워밍업 클럽 2기입문자를 위한 Spring Boot with Kotlin(https://inf.run/bXQQQ) 강의를 듣고 작성하였습니다. 소개📌 Node.js (NestJS)를 주로 사용하는 2년차 백엔드 개발자입니다.📌 스타트업을 다니던 중 회사가 폐업하여 다시 취업 준비를 하고 있습니다.📌 스프링을 시작한 이유는 크게 2가지입니다.1. 프레임워크의 제한을 받지 않는 백엔드 개발자가 되고 싶습니다. 2. 대한민국에서 개발자로 큰 회사로 가려면 Node.js는 약간 한계가 있다고 느꼈습니다.📌 적당히 게으르고 적당히 노력하는 평범한 사람이지만 최선을 다해 완주하겠습니다.NestJS 가 약간 스프링의 구조를 따라한?? 느낌이라서 비슷한 부분이 아주 많습니다.. 강의 내용을 전부 요약하기보단 생각에 남았던 부분만 정리했습니다.웹 프레임워크웹 프레임워크는 개발을 하면서 공통되고 반복되는 작업들에 대해 좀 더 편리하게 사용할 수 있게 만들어주는 도구입니다.지금 제가 사용하는 NestJS 같은 경우에도 Node.js 를 이용한 웹 서버 개발을 편하게 만들어주는 웹 프레임워크라고 할 수 있습니다. 마찬가지로 Java나 Kotlin을 이용해 웹 서버를 개발하는 경우 Spring 이나 Spring Boot 라는 프레임 워크를 사용합니다.SpringMVC 패턴을 사용합니다.레이어드 아키텍쳐를 사용합니다.  레이어드 아키텍쳐소스코드의 역할과 관심사에 따라 계층으로 분리한 아키텍처 입니다.출처 | https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch01.html여기서 Persistence layer 를 Data Access layer라고 하기도 합니다.controller(presentation) -> service(business) -> repository(Persistence/data access) 컨트롤러는 말 그대로 컨트롤러로서의 역할서비스는 레포지토리로부터 DB에 대한 메서드를 가져와서 사용리포지토리는 DB를 조작하는 매서드를 정의 NestJS 에서도 일반적으로 이런 계층형 아키텍처를 사용하였고, 컨트롤러에 서비스 로직이 어디까지 보여지는지에 대한 논의를 했던 것이 기억에 납니다. 이런 세세한 컨벤션은 아마 개발자마다 기준이 다를 수 밖에 없는 것 같습니다.의존성 주입(DI)https://docs.spring.io/spring-framework/reference/core/beans/introduction.htmlhttps://docs.nestjs.com/fundamentals/custom-providers#di-fundamentals의존성 주입은 한 객체가 사용하는 다른 객체를 직접 만들지 않고, 외부에서 주입받아 사용하는 방식으로, 제어 역전(IoC)기술 중 하나입니다.제어 역전(IoC)은 개발자가 컨트롤해야하는 부분을 프레임워크에 위임하여, 개발자가 신경써줄 부분을 줄여주는 기술입니다. (로 저는 이해하고 있습니다.) 출처 | https://project-eclise.fandom.com/wiki/Spring_Bean_(Alpha) 스프링에서는 Bean 이라는 것을 통해서 프레임워크에 권한을 위임할 대상을 지정합니다.bean은 Spring IoC 컨테이너에서 관리하는 객체입니다. IoC 컨테이너가 Bean 을 생성할 때 종속성을 주입합니다. 의존성 주입 방식은 생성자, 수정자, 필드 방식 3가지가 있습니다만 생성자만 사용하면 된다는 친구의 말을 들었던 기억이 납니다..(ㅎㅎ..)NestJS에서는 default(provider), request, transient 이렇게 세가지 스코프로 DI를 지원하는데, 마찬가지로 여기도 provider 방식만 사용했었습니다.이유는 둘 다 provider 방식이 안전하기 때문이라고 요약할 수 있겠습니다.JPA자바 ORM 기술의 표준 인터페이스입니다. ORM은 객체-관계 매핑으로 관계형 데이터베이스를 객체와 매핑해주는 기술을 말합니다.ORM은 만능인가? 에 대해 생각해보는 아티클https://yceffort.kr/2021/07/dont-use-nodjs-orm저수준: 순수JDBC, 중간수준: Querydsl, 고수준 JPA 로 대체해서 생각하면 됩니다 영속성 컨텍스트개인적인 이해에 도움이 되었지만 차마 똑같이 설명할 엄두는 안나는 아티클https://msolo021015.medium.com/jpa-persistence-context-deep-dive-2f36f9bd6214DB 작업이 실제로 DB에 반영되기 전에 모여있는 장소입니다. 트랜잭션이 시작되면 영속성 컨텍스트에 의해 조회/수정될 엔티티를 보관하고 관리합니다.(1차캐시) 캐시되기 때문에 성능에 도움이 됩니다(더티체킹) 스냅샷을 이용해 데이터 일관성을 향상시킵니다.(쓰기지연) 영속성 컨택스트 내에 모아놨다가 트랜잭션 종료될 때 한번에 수행합니다. (개인공부1) JVM이란JVM (Java Virtual Machine)은 Java 애플리케이션을 실행하기 위한 가상 머신입니다.Java와 Kotlin 같은 언어는 소스 코드를 작성한 후, 컴파일되면 바이트코드(bytecode)라는 중간 언어로 변환됩니다. 이 바이트코드는 운영 체제에 종속되지 않고, 다양한 플랫폼에서 실행될 수 있습니다. 운영 체제에 종속되지 않고, 다양한 플랫폼에서 실행되는 이 특징을 WORA(Write Once, Run Anywhere)라고 합니다. (개인공부2) Kotlin과 TypeScript의 차이출처 | https://itnext.io/typescript-or-kotlin-for-a-backend-268191b56525typescriptJavaScript에 정적 타입 시스템을 추가한 언어JavaScript로 컴파일되어 브라우저와 서버(Node.js)에서 실행됩니다.정적 타입이지만 any 사용 가능OOP, FP, 일급객체, 람다식 지원비동기: Promise, async/await kotlinJava 의 대안으로 나온 언어JVM을 통해 바이트코드로 컴파일되며, Java와 상호 운용이 가능합니다.엄격한 정적 타입 시스템OOP, FP, 고차함수, 람다식 지원, 함수형 프로그래밍 더 좋다 함비동기: Coroutines, suspend (개인공부3) Spring과 Spring Boot의 차이출처 | https://codestates.com/blog/content/스프링-스프링부트스프링엔터프라이즈 애플리케이션 개발을 위한 프레임워크외부 서버 필요XML 등을 이용해 환경 설정 작업 필요한땀한땀 짜야 해서 복잡도가 높다스프링부트스프링 프레임워크를 더 편하게 쓰기 위한 프레임워크 (프레임워크의 프레임워크)내장 서버 제공(Tomcat, Jetty)application.properties나 application.yml 을 사용하여 간단하게 환경 설정 가능Spring Initializr와 같은 프로젝트 시작 도구많은 설정 자동화되어 있음 미니프로젝트https://github.com/yujiniii/toy-box/tree/main/sky-kongkong 여기서 업데이트됩니다!마무리JVM과 spring 생태계가 생각보다 깊어서, 차곡차곡 개념을 추가해야할 거 같습니다. 스레드 관련해서도 정리하고 싶었는데 결국 못했네요 ᵕ_ᵕ̥̥코드 작업에서는 NestJS 와 비교되는 부분(데코레이터-어노테이션, 인터셉터 등) 을 위주로 작성하고, 프로젝트도 얼른얼른 작업 해야할 거 같습니다..다음 주차는 면접준비랑 겹쳐서 걱정이지만.... ( っ °、。)っ 그래두 화이티이잉...!!

백엔드

채널톡 아이콘