블로그

[0일차] 인프런 워밍업 클럽 0기 백엔드 - 시작!!

어? 강의가 되게 재밌어 보이네?오랜 기간 취업 준비를 하는 도중 프로젝트 없이 공부만 하다보니 개발이 재미 없어지기 시작하였습니다.물론 오랜 취업 준비 기간으로 힘든 것도 있지만 내가 직접 만드는 서비스가 없다보니 흥미가 떨어진 것 같다고 생각하였습니다. 그렇게 어떤 프로젝트를 할까, 개인으로 할까? 팀으로 할까? 많은 고민을 하던 중 '자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지!' 라는 강의를 알게 되었습니다.강의 목차를 보니 웹 개발에 필요한 기술부터 네트워크, AWS 등 정말 백엔드로서 필요한 지식을 한 강의에서 제공해주는 것에 매력을 느꼈습니다. 하지만 돈 없는 취준생은 듣고 싶지만 부담이 되었습니다.😭 이건 꼭 해야해..!그렇게 며칠을 고민하던 중 지식 공유자께서 직접 참여를 하고, 다양한 사람들과 의견을 주고 받을 수 있는 스터디가 열린다는 것을 알게 되었습니다. 거기에 대상 강의가 바로..! 제가 구매할지 말아야할지 고민하던 '자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지!' 였습니다.저는 개발 실력도 중요하지만 네트워킹에 참여하는 것도 중요하다고 생각하였는데 이 기회는 두마리의 토끼를 동시에 잡을 수 있는 매력적인 이벤트였습니다. 강의를 사야할지 말아야할지 고민하던 저는 주저 없이 스터디를 신청하게 되었고, 강의도 바로 구매하였습니다.😁 그렇게 시작한 OT(0일차)16일 금요일 스터디의 시작을 알리는 OT를 하였습니다. 지식공유자이신 최태현님께서 대략적인 스터디 일정을 알려주셨고, 자바의 역사에 대해 알려주셨습니다. 스터디 일정을 보니 정말 타이트하고 힘들 것 같지만 저는 시간 많은 취준생 아니..백수이기 때문에 열심히 스터디 일정에 맞춰서 달려보겠습니다. 이번 기회로 참여하신 다른 러너분들과 많은 이야기와 정보를 주고 받고 싶습니다. 오랜 취업준비를 하였지만 그런 것 치고는 큰 실력향상이 있진 않았던 것 같아 이번 기회에 제대로 마음 잡고 공부해보려고 합니다..! 화이팅..! (급 종료)

백엔드백엔드인프런워밍업클럽스터디0기

학생

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

발자국이번주 강의 범위는 따라하며 배우는 자바스크립트 A-Z(섹션 1~8) 까지였다.워낙에 기록을 안하는 성격이라 어떤 식으로 해야 할지 감이 안잡히지만 이제부터라도 습관을 들이는 편이 좋겠다.강의 요약이번주 강의에는 정말 많은 내용이 담겨 있었지만,이전에 혼자 책으로 공부할 때 한 번 보고 이해가 되지 않았던 부분,중요하다고 생각하는 부분,혹은 아예 처음 듣는 내용을 위주로 요약해보았다.그 목록은 아래와 같다.호이스팅HTML DOM this자바스크립트 비동기 처리 과정IIFECurryingOOP비동기Iterator & Generator자바스크립트 디자인 패턴요약을 한다고 하긴 했는데 요약이 아니라 공부노트같긴 하다. 다음 회고때는 중요한 내용 두 개 정도로 줄일까 한다.호이스팅(hoisting)변수 선언이 스코프 내의 가장 위로 끌어올려지는 것.var, let, const 모두 호이스팅된다. 그런데 방식이 다르다.var의 호이스팅console.log(a) var a = 1출력 결과: undefinedwhy? var의 경우 선언(a = undefined) -> 할당(a = 1) 됨.let, const의 호이스팅console.log(a) let a = 1결과: 에러 뜸.why? let, const의 경우 선언 -> TDZ -> 할당(a = 1) 됨.따라서 변수 선언이 스코프의 맨 위로 올라간다 해도 출력 불가. TDZ에 걸림. HTML DOMDOM(Document Object Model): 웹 페이지를 이루는 요소들을 tree구조로 만든 객체 모델.웹 페이지 빌드 과정(CRP: Critical Rendering Path)html을 DOM으로, CSS를 CSSOM으로 만든다.DOM과 CSSOM을 결합(Render Tree 생성)Layout(페이지에 표시되는 각 요소의 크기 및 위치 계산)Paint(실제 화면에 그리기)Render Tree 생성, Layout, Paint단계는 비용이 많이 든다.이 비용을 줄이기 위해 React에서는 가상 DOM을 사용해 성능을 높임. DOM Event event의 3단계 흐름: Capturing -> Target -> Bubblingevent Capturing: 이벤트가 위에서 아래로 전달되는 것event Bubbling: 가장 깊게 중첩된 요소에 이벤트가 발생했을 때 이벤트가 위로 전달되는 것event.stopPropagation(): 중첩 중지.Event Delegation(이벤트 위임)하위 요소의 이벤트를 상위 요소에 위임하는 것.하위 요소의 이벤트를 상위에서 제어. this메소드에서 this는 해당 객체를 참조.함수에서 this는 window 객체를 참조.constructor에서 this는 빈 객체를 참조.여기서 함수와 메소드의 차이가 헷갈려 알아보니, 다음과 같았다.메소드는 함수의 일종이며, 객체의 속성이 함수인 것을 메소드라고 한다.참고: https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Functionslexical this: 화살표함수(ES6)에서 this는 항상 상위스코프의 this를 가리키게 된다.bins, call, apply함수에서 this를 쓸 때 window객체 말고 다른 객체를 참조하도록 하는 방법들call: function.call(객체, 인수1, 인수2, ...)apply: function.apply(객체, [인수1, 인수2, ...])bind: const bindFunc = function.bind(객체); bindFunc(인수) // 이 때 호출. 자바스크립트의 비동기 처리 과정event loop자바스크립트는 동기 언어. 따라서 비동기를 사용하려면 브라우저 등의 도움을 받아야 한다.브라우저 내부: 자바스크립트 엔진 + Web APIs + Callback Queue + Event Loop자바스크립트 엔진: 메모리 힙 + Call Stack메모리 힙: 변수 저장 창고Call Stack: 함수 호출 시 함수가 쌓이는 곳setTimeout과 같은 비동기 기능을 처리하는 과정 (브라우저가 처리해줌)Call Stack에 setTimeout 쌓임Web APIs에게로 setTimeout이 이동 후 setTimeout의 지정한 시간만큼 대기Callback Queue에 함수가 보내지고 대기Event Loop는 Call Stack이 비면 Callback Queue에서 먼저 온 순서대로 Call Stack에 넣어줌  IIFE(즉시 호출 함수 표현식)정의가 되자마자 즉시 실행되는 자바스크립트 함수. 주된 목적: 변수 전역 선언 회피, 다른 변수의 내부 접근 막기( // 소괄호 1: 전역선언 막고 변수접근 막기 function() {} )() // 소괄호 2: 즉시 실행 함수 생성함수 이름이 없으려면이 함수를 할당받을 변수를 지정해야 함이 함수를 즉시호출해야함(IIFE) Currying커링: f(a,b,c) => f(a)(b)(c)로 변환하는 기술. 다른 언어에도 존재함.// 매개변수가 몇개든 함수를 currying해주는 함수 function curry(func) { return function curried(...args) { if(args.length >= func.length) { return func.apply(this, args); } else { return function (...args2) { return curried.apply(this, args.concat(args2)); } } } } OOP(객체 지향 프로그래밍)특징자료 추상화(Abstraction): 필요한 정보만 표현 -> 간결상속(Inheritance): 새 클래스가 기존 클래스의 기능 가져와 사용 -> 효율다형성(Polymorphism): Overriding(재정의) 사용. 인스턴스에 따라 같은 동작에 다른 결과물.코드 재사용 가능한 이점캡슐화(Encapsulation): 클래스 안에 묶어 보호 및 쉬운 관리상속부모 클래스를 자식 클래스에서 확장.extends 키워드 사용.super(): 자식 클래스에서 부모 클래스의 생성자나 메소드 호출할 때 사용. 비동기병렬로 작업. 순서를 기다리지 않음.비동기 요청이 여러개이고 한 요청이 다른 요청의 결과에 의존할때callback함수(es5): 특정 함수에 매개변수로 전달된 함수.promise(es6): 비동기처리 결과 성공, 실패 각각 resolve, reject. .then()으로 체이닝Promise.then(resolve값).catch(reject값).finally(성공실패무관)async/await(es7): 비동기식 코드를 동기식처럼 보이게 작성.async로 함수를 감싸고 그 안에서 await를 이용해 각 요청을 대기시킴동기식 코드에서 쓰는 try catch구문을 사용 가능 Iterator & Generatoriteratornext()를 호출해서 value, done 두 개의 속성을 가지는 객체를 반환하는 객체.[Symbol.iterator]()를 이용하면 반복가능한값을 반복기로 생성 가능.generatorGenerator Function은 사용자의 요구에 따라 다른 시간 간격으로 여러 값을 반환 가능.yield: 제너레이터함수의 실행을 일시적으로 정지시킴.function* 함수이름()제너레이터: 제너레이터 함수의 반환.제너레이터.next()로 사용.generator도 value, done 속성이 담긴 객체를 반환.자바스크립트 디자인 패턴디자인 패턴: 공식화된 프로그램/시스템 디자인 문제해결 모범 사례.장점최고의 솔루션: 검증됨.재사용성: 여러문제에 적용가능.풍부한 표현력향상된 의사 소통필요없는 코드 리팩토링: 검증됨코드베이스 크기 감소: 공간 보존Singleton Pattern:인스턴스를 하나의 객체로 제한.Factory Pattern: 특수함수인 팩토리함수를 사용해 비슷한 객체 많이 만들수있음.=> 비슷한 객체를 반복적으로 생성하야 하는 경우 사용. Mediator Pattern(중재자 패턴): 객체 그룹에 대한 중앙 권한 제공.Observer Pattern: observer를 이용해 객체를 관찰.Module Pattern: 더 작은 것으로 분할.export를 이용. 미션 해결 과정(과제 총합본은 따로 작성하고 있다.) https://www.inflearn.com/blogs/6758미션1 음식 메뉴 앱포인트: 각 카테고리의 버튼을 누를 때마다 메뉴들을 보여주는 공간을 비우고 해당 카테고리의 메뉴를 채움스타일: 우선은 아는 것이 별로 없고 주어진 것부터 제대로 공부하고 싶어서 과제 예시와 최대한 비슷하게 만들었다. 추가: 미디어 쿼리를 이용해 개발자 도구가 켜진 상태의 화면크기부터는 화면에 메뉴를 1열로 표시시간 많이 든 부분: CSS, 이미지 처리(선정 및 다운로드, 크기조정) 아직 HTML/CSS 공부가 많이 필요하다는 것을 깨달았다.  사진은 pixabay의 무료 이미지를 이용했으나, 다른 분의 글을 보고 음식 메뉴에 API를 이용하는 좋은 방법이 있다는 것을 깨달았다. 그런 훌륭한 문물이 있다는 것을 이제야 상기하다니! 직접 음식 메뉴를 선정하고 설명을 지어내는 것에 신경을 쓰느라 음식 API를 이용한다는 생각을 하지 못했다. 앞으로 다루어야 할 이미지가 많아질 경우 API를 사용하자.  미션2-가위바위보 앱포인트: Math.random을 이용해 컴퓨터의 가위바위보를 구현. 판마다 게임보드에 스코어 표시스타일: background에 그라데이션 효과를 적용함. 승부 결과마다 다른 색의 글귀를 표시 시간 많이 든 부분:만들 때 헷갈렸던 부분은 재도전 버튼을 눌렀을 때 기존에 써있던 플레이어와 컴퓨터의 점수를 삭제하고 새로 표시하는 부분이었다. 결국 재도전 버튼에 붙인 retry함수에서, gameDisplay에서 생성한 class를 querySelector로 찾아가 내용물을 비우고 classList에서 class 이름을 삭제하고 각 점수를 scoreboard에서 removeChild로 지웠다. 이는 gameDisplay가 실행되면 다시 생성된다. 미션3-퀴즈 앱포인트: 버튼을 누를 때마다 next버튼 생성 및 옵션 버튼 비활성화스타일: CSS의 grid 이용해 옵션 버튼 배치. position시간 많이 든 부분: CSS. 미션4-책 리스트 나열 앱포인트: 입력 후 제출 버튼을 누르면 input value를 미리 생성해둔 ul 내부에 li형태로 추가. 경고문은 setTimeout을 이용해 3초 뒤 사라지게 함스타일: 책이 추가/삭제되거나, 입력란을 빈칸으로 두고 제출했을 때의 경고문에 따라 색 다르게 표시얘는 다음주에 CSS를 공부해서 정렬을 보기 좋게 만들어줄 것이다.(거의 기능만 구현된 못생긴 화면)조만간 수정할 부분CSS 추가알림때문에 화면이 아래로 밀리는 문제 고치기 미션5-GithubFinder 앱포인트: Github API를 사용해 데이터 가져오기스타일: 우선 단순하게(아직 미해결. API 사용법 공부 후에 완성 예정)이친구는 fetch와 RESTful API 사용하는 법을 공부해야 하기 때문에 아직 해결하지 못했다. 다음 회고 때 해결 과정이 들어갈 것이다.미션6-비밀번호 생성 앱포인트: 선택된 체크박스의 값을 넣어 length란에 입력한 숫자값을 길이로 하는 문자열을 랜덤생성해야 한다.5~70의 숫자 조건에 length가 해당하지 않으면 alert를 실행시켰다.아무런 체크박스를 선택하지 않았을 경우도 alert를 실행시켰다.생성한 비밀번호를 복사하는 copy 버튼을 눌렀을 때 클립보드에 복사하는 코드navigator.clipboard .writeText(password.value) .then(() => { alert("successfully copied"); }) .catch(() => { alert("something went wrong"); });원래는 execCommand를 썼는데 deprecated되었다고 한다.then부분은, alert를 넣을 경우 then을 쓰지 않으면 복사가 되지 않아서 stack overflow사이트에서 가져온 코드이다. https://stackoverflow.com/questions/69438702/why-does-navigator-clipboard-writetext-not-copy-text-to-clipboard-if-it-is-pro문자열, 숫자, 특수문자를 랜덤으로 섞어 조합하는 것은 까다로웠지만 Math.random과 배열을 이용해 구현했다.체크박스 중 체크된 것의 value를, 생성 버튼을 클릭할때마다 배열에 넣고, 체크가 안되어있으면 배열에서 삭제하는 코드는 거의 줄글처럼 조건이 많이 작성되었다. 굉장한 하드코딩이 되었다...회고작년 말에 진로를 FE개발쪽으로 정하고 독학을 시작하였다.FE부트캠프는 참여한 적이 없었고, 따라서 미션 하나하나가 도장깨기를 하는 느낌이었다.예상대로 매일 미션 한개씩 하는데에는 시간이 꽤 걸렸다. 그리고 부족한 점을 많이 깨달았다.CSS, API 이용, 클린코드 작성 등 여러 방면에서의 지식 및 구현 경험 부족 미션을 할 때 일단 돌아가게 만들고 머리로 정리는 하지 않는 느낌  뒤로 갈수록 시간 부족 다음주 목표CSS 공부하기REST API 공부하고 미션 마저 해결하기다음주 회고 강의 요약 부분 분량 줄이기

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

박지원

[인프런 워밍업 클럽 스터디] Day 4 미션

1. 아래 코드와 설명을 보고, [섹션 3. 논리, 사고의 흐름]에서 이야기하는 내용을 중심으로 읽기 좋은 코드로 리팩토링해 봅시다.public boolean validateOrder(Order order) { if (order.checkItemsNone()) { log.info("주문 항목이 없습니다."); return false; } if (order.getTotalPrice() <= 0) { log.info("올바르지 않은 총 가격입니다."); return false; } if (order.hasNotCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } return true; } 2. SOLID에 대하여 자기만의 언어로 정리해 봅시다.SOLID객체지향 설계를 더 이해하기 쉽고 유연한 형태로, 유지 보수를 쉽게 만드는 데 도움을 주는 원칙 SRP: Single Responsibility Principal 단일 책임 원칙하나의 클래스가 하나의 책임만 갖도록 설계함객체의 공개 메서드, 필드, 상수 등이 객체의 단일 책임에 의해서만 변경되어야 한다. 상수: 동일한 퍼블릭 상수를 두 가지 객체가 사용하는 경우를 고려한다.관심사의 분리와도 일맥상통높은 응집도(클래스, 모듈 등이 긴밀하게 연결되어 있는 정도), 낮은 결합도(협력 관계의 2개 이상 객체에서, 한 객체가 변경될 때 다른 객체가 영향 받는 정도/ 의존성의 최소화라고도 함)*책임의 경계선을 인식하기 위해서는 계속해서 질문을 던져 보는 경험적 측면이 필요. OCP: Open-Closed Principle 개방-폐쇄 원칙새로운 요구 사항의 추가와 같은 변동 사항 발생 시, 기존 코드 변경 없이 시스템의 기능을 확장한다.추상화와 다형성을 통해 지킬 수 있다.*난이도 조절 기능이 추가된다면> (1) 숫자 변경되었을 때 그 숫자에 맞춰 게임이 정상 진행되도록 한다 (2) 난이도 조절에 대한 요구사항에 대응한다의 순서로 기능을 추가해 나간다. LSP: Liskov Substitution Principle 리스코프 치환 원칙상속 구조에서 부모 클래스 인스턴스를 자식 클래스 인스턴스로 치환할 수 있어야 한다.일반적으로부모 클래스보다 자식 클래스의 기능이 더 많다. 이때 부모 클래스가 기능하는 것을 자식 클래스가 해도 동일하게 동작해야 한다는 것.LSP를 위반하면 상속 클래스 사용 시 예외가 발생하거나, 불필요한 타입 체크가 필요할 수 있다. ISP: Interface Segregation Principle 인터페이스 분리 원칙클라이언트는 자신이 사용하지 않는 인터페이스에 의존해서는 안된다. 즉 인터페이스를 기능 단위로 잘게 나눠야 한다.ISP를 위반하면 결합도가 높아지고, 특정 기능 변경이 여러 클래스에 영향을 미칠 수 있다.  DIP: Dependency Inversion Principle 의존성 역전 원칙상위 수준 모듈이 하위 수준 모듈에 직접 의존하지 않고, 두 개 모두 추상화에 의존해야 한다.상위 수준 모듈: 추상화 레벨이 높은 쪽하위 수준 모듈: 구체에 가까운 쪽 *의존성: 하나의 모듈이 다른 하나 모듈을 알고 있거나 직접 사용하는 모든 것들의존성의 순방향: 고수준 모듈이 저수준 모듈을 참조하는 것의존성의 역방향: (고수준 모듈) 기능을 추상화해서 추상화된 스펙을 만족하는 것을 이용해 요구사항을 해결할 수 있는 것. (저수준 모듈) 인터페이스를 구현한 구현체가 얼마든지 바뀔 수 있는 것.즉, 추상화를 가운데 두고 의존하도록 하는 것 *DIP, DI, IoCDIP(Dependency Inversion Principle): 고수준 모듈과 저수준 모듈은 직접적 의존이 아닌 추상화에 의존해야 한다.DI(Dependency Injection): 필요한 의존성을 외부에서 주입받는다. "3"의 숫자를 기억할 것. 객체 a, b가 있는 상황에서 a가 b를 필요로 할 때 직접 생성자를 통해 주입 받는 것이 아닌, 제3자가 둘 사이의 의존성을 맺어준다. 스프링에서는 스프링 컨텍스트(**IoC 컨테이너)가 한다.IoC(Inversion of Control): 프로그램 제어 주도권이 개발자가 아닌 프레임워크에 있다.**IoC 컨테이너: 객체의 생명주기를 관리하고 의존성 주입까지 해 준다.

인프런워밍업클럽스터디

김체토

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

4주 차 - 학습했던 내용 요약피드백 컴포넌트와 네비게이션인 토스트, 스켈레통, 프로그레스바, 모달, 네비게이션, 페이지네이션, 헤더, 캐러셀 등의 컴포넌트를 만들었습니다.베리어블을 통해 다크 모드, 멀티 브랜드, 다언어 케이스에 적용할 수 있도록 설정하고 실습했습니다.Shop, Learn, OTT의 예시 페이지를 만들었습니다.라이브에서는 여러 브랜드의 디자인 시스템을 둘러보고 도큐먼트 요소들을 분석해 보고 chatGPT를 이용하여 디자인 시스템을 만들어보는 시간을 가졌습니다.  4주 차 - 회고4주간의 스터디를 통해 두 번째 완강을 빠른 시간에 할 수 있었습니다.개인 일정으로 1주 차에 학습을 많이 하지 못했습니다. 그래서 남은 3주 동안 미션을 한다고 마지막 날까지 부랴부랴 했는데 정말 시간이 정신없이 빠르게 지나간 것 같습니다.또 최근 AI를 활용한 프로덕트 디자인에 관한 콘텐츠가 많이 보였는데 디자인 시스템 설계에 chatGPT를 활용하여 실습을 해보니 색다른 경험이었습니다.  인프런 워밍업 클럽 스터디 - 후기볼드님께서 QnA도 열심히 해주시고 라이브 강의도 정말 하나라도 더 알려주시려고 꼼꼼히 준비하셔서 배우는 입장에서 너무 감사하고 자극도 많이 되었습니다!함께 스터디하는 수강생들도 열심히 해주어 저도 더 열심히 참여한 것 같아요 :)처음 볼드님 강의를 들었을 때는 처음 듣는 부분이 많아 50~60% 정도 이해가 되었는데, 이번 스터디를 통해 더 깊게 익히는 계기가 되었습니다.강의에서 볼드님도 수정에 대하여 여러 번 말씀하셨지만, 정말 디자인 시스템은 어떻게 더 효율적인 시스템이 될지 끝없이 고민하고 수정해 나가는 과정인 것 같습니다.스터디는 끝났지만 배웠던 것을 바탕으로 실무에서 베리어블 모드를 잘 사용하는 디자이너가 될 수 있도록 노력해 보겠습니다!  

UX/UI인프런워밍업클럽스터디figmauiux

김체토

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

3주 차 - 학습했던 내용 요약인풋 컴포넌트인 버튼, 체크박스, 라디오, 스위치, 라벨, 컨트롤 그룹, 텍스트 필드, 텍스트 상자, 셀렉트를 만들었습니다.디스플레이 컴포넌트인 아바타, 아코디언, 뱃지, 툴팁, 디바이더, 칩, 스테이터스 칩, 카드 폼, 테이블 요소들을 만들었습니다.제작한 컴포넌트의 대비를 체크하여 접근성에 부합하는지 체크해 주었습니다.라이브로 타이포그래피 베리어블에 대하여 공부했습니다.  3주 차 - 회고만들어진 컴포넌트를 볼 때는 금방 만들 수 있을 것 같았는데 실제로 하나씩 따라 만들어보니 시간이 생각보다 많이 걸립니다. 이번 주에 내비게이션 컴포넌트까지 만드는 게 목표였는데 디스플레이까지밖에 하지 못했습니다.테이블은 각 잡고 만들면 상당히 복잡해질 것 같네요.특히 만들어진 컴포넌트를 활용하여 또 다른 컴포넌트를 만들 때는 고려해야 할 점들도 많아지는데, 어떻게 더 효율적으로 프로퍼티를 구성하면 될지 고민을 거듭하면서 더 좋은 컴포넌트를 디자인할 수 있게 되는 것 같습니다.타이포그래피 베리어블도 많이 복잡하다고 느껴졌는데 볼드님 라이브를 듣고 쉽게 이해할 수 있었습니다. type face, font, font family도 잘 구분할 수 있게 되었습니다 :)타이포그래피 베리어블은 복잡하지만 잘 적용해 본다면 반응형 작업 시 타이포까지 대응할 수 있어 엄청 좋을 것 같습니다!  4주 차 - 다짐 및 계획다음 주에는 나머지 컴포넌트들을 만들고 예시 페이지들까지 완성하여 커리큘럼을 완주해 보도록 하겠습니다!!  

UX/UI인프런워밍업클럽스터디figmauiux

박지원

[인프런 워밍업 클럽 스터디] BE 1기 세번째 발자국

섹션 5. 책 요구사항 구현하기 JPA에서 연관관계를 매핑하기연관관계의 주인: "상대 테이블을 가리키는 테이블"Table을 바라보았을 때 누가 관계의 주도권을 가지고 있는지를 의미함.JPA에도 알려주는 법: 연관관계의 주인이 아닌 객체에서 @OneToMany와 같은 연관관계 어노테이션에 mappedBy 옵션을 표시한다.연관관계 주인의 효과: 연관관계의 주인을 기준으로 테이블이 연결된다.예를 들어, 연관관계의 주인인 person 은 setAddress 를 통해 테이블을 이어주지만, address로 같은 메서드를 실행하면 제대로 테이블이 연결되지 않는다.person.setAddress(address); // 정상 실행 address.setPerson(person);연관관계의 주인을 통해 객체를 이어줘도, 반대쪽도 이어지는 것은 아니므로 하나의 setter 안에서 객체끼리 완전히 연결시켜 주어야 한다.연관관계의 주인인 person 은 setAddress 내에서 address의 Person도 설정해 준다.public void setAddress(Address address) { this.address = address; this.address.setPerson(this); }연관관계를 나타내는 어노테이션 @OneToMany와 @ManyToOne: N : 1 관계@OneToOne: 1 : 1 관계@ManyToMany: N : M 관계 (*N : M 연관관계의 구조는 복잡하고, 테이블도 직관적으로 매핑되지 않기 때문에 사용하지 않는 게 좋음) JPA 연관관계의 다양한 옵션 mappedBy 옵션: 연관관계의 주인이 아닌 객체가 주인에게 매여 있음을 표시한다.@JoinColumn: 연관관계의 주인에게 활용할 수 있는 어노테이션. 연관관계의 주인이 가지고 있는 다른 테이블을 가리키는 필드의 이름이나 null 여부, 유일성 여부, 업데이트 가능 여부 등을 정해줄 수 있다.cascade 옵션: 한 객체가 저장되거나 삭제될 때, 연결되어 있는 객체도 함께 저장되거나 삭제되는 기능orphanRemoval 옵션: 연관관계가 끊어진 데이터를 자동으로 제거해 준다.fetch 옵션: 객체의지연 로딩 여부를 설정한다. 꼭 필요할 때 가져오는 LAZY 옵션(기본 옵션), 처음 데이터를 로딩할 때 바로 가져오는 EAGER 옵션이 있다.지연 로딩: 영속성 컨텍스트의 특징. 필요한 순간에 연결되어 있는 객체를 가져온다.연관관계를 사용하면?도메인 계층에서 두 클래스가 직접 협업할 수 있으므로 Service 계층의 코드가 더 간결해진다.하지만 연관관계를 너무 지나치게 사용하면 시스템 파악이 어려워지고 한 곳에서의 수정이 다른 곳까지 영향을 줄 수도 있으므로 여러 부분을 고민하며 연관관계 사용 여부를 결정해야 한다.섹션 6. 생애 최초 배포 준비하기 배포란 무엇인가 필요한 프로그램(ex. spring, MySql..)이 설치된 전용 컴퓨터에 코드를 옮기고 실행하는 과정profile 설정하기똑같은 서버 코드를 local profile에서는 H2 DB로, dev profile에서는 MySQL DB를 사용하도록 설정할 수 있다.application.yml의 설정 값도 함께 변경해 주어야 함.   git과 githubgit: 코드를 쉽게 관리할 수 있도록 해주는 버전 관리 프로그램github: git으로 관리되는 프로젝트의 코드가 저장되는 저장소코드를 github 저장소에 저장하는 과정git add .: 모든 코드를 담는다.git commit -m "메시지": 파일들을 포장하고 적고 싶은 문장을 적는다.git push: 송장을 붙인 파일들을 github에 보낸다.EC2: Elastic Compute Cloud의 약자로, 탄력적으로 원격 컴퓨터를 사용할 수 있다는 의미.섹션 7. 생애 최초 배포하기리눅스 명령어mikdir 폴더이름 - 폴더를 만든다ls - 현재 위치에서 폴더나 파일을 확인한다ls -l - 폴더의 자세한 정보를 확인한다 접근권한 명령어가 표시된다. 이를 변경하는 명령어가 chmod다. cd 폴더이름 - 폴더 안에 들어간다.cd .. - 현재 위치에서 상위 폴더로 간다.pwd - 현재 위치를 확인한다. rmdir 폴더이름 - 비어있는 디렉토리를 제거할 수 있도록 한다.foreground와 backgroundforeground: 우리가 보고 있는 프로그램background: 우리가 보고 있지 않은데 실행 중인 프로그램EC2 접속을 종료해도 서버가 동작하게 하려면 서버가 background에서 동작할 수 있도록 명령어를 추가해야 한다.jar 파일 실행 명령어의 앞뒤로 nohup [명령어] &를 붙여준다.ex. nohup java -jar build/libs/library-app-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev &rm nohup.out - nohup.out 파일을 제거한다.nohup.out 파일을 확인하는 방법리눅스 편집기 vim을 활용: vi nohup.out 입력접속한 터미널에서 확인: cat nohup.out or tail -f nohup.outbackground로 동작하고 있는 서버 종료하기리눅스 작업 관리자 명령어 ps aux를 사용해 실행 프로그램 목록을 볼 수 있다. (*java 관련 프로그램만 보고 싶다면 ps aux | grep java)프로그램마다 고유한 번호가 있으므로 kill -9 번호를 입력하면 서버 프로그램이 종료된다.섹션 8. Spring Boot의 이모저모 Spring Boot와 관련된 여러가지 사항build.gradle:gradle을 이용해 프로젝트를 빌드하고 의존성을 관리하기 위해 작성한 파일Spring과 Spring Boot Spring Boot는 Spring에서 제공하는 편리한 기능을 사용하기 위해 필요한 설정을 Java의 어노테이션 기반으로 가능하게 하고, 기본적인 설정들은 모두 자동으로 해준다.Spring Boot의 starter로 의존성 관리가 쉬워졌고, starter 추가만으로 원하는 기술을 쉽게 도입할 수 있게 되었다. application.yml과 application.properties:스프링 설정에 활용된다. YAML 방법이 가독성이 좋다.lombok : getter나 생성자, setter, equals, toString 등을 자동으로 만들어준다.어노테이션 @Getter, @NoArgsConstructor, @RequiredArgsConstructor(final이 붙어 있어 필수로 값 필요한 변수들을 가지고 있는 생성자를 만든다), @Setter, @EqualsAndHashCode, @ToString 등이 있다.<3주차 학습 내용 회고>완성한 서버를 배포해 보는 경험을 처음 경험해 본 일주일이었다. 강의에서 제공된 완벽한 코드를 실행시킨 것 뿐이지만, 지금까지 했던 코드의 터미널 실행과는 또 다른 느낌의 기쁨을 느낄 수 있었다. 깃 허브는 사실 아직도 잘 모르겠지만, 첫 시작을 했으니 다음에 사용할 때는 조금 더 여유롭게 사용할 수 있을 것 같다.연관관계를 따져보는 내용은 디비 수업에서 배웠던 것의 연장선에 있는 듯한데, 비슷하면서도 개념이 완전히 같지는 않아서 실제로 개발할 때 공부가 더 필요할 부분인 듯하다.본 강의 내용은 이번 주로 드디어 끝이 났다. 아직 남은 부분이 있긴 하지만, 이렇게 빠듯한 일정으로 강의를 다 수강해 본 게 얼마 만 인지 모르겠다. 남은 내용들도 잘 챙겨가서 다음 단계 공부에 잘 활용해 보고 싶다.  <미션>과제6API 3단 분리, Repository 분리하기API 분리는 전에 해두었던 것을 좀 더 간결하고 가독성 좋게 만드는 방식으로 만들었다.Repository의 경우 원래 만든 Repository의 볼륨이 상대적으로 컸기에 잘못 분리하면 에러 파티가 날 수도 있겠다 싶어서 살짝 부담스러웠지만 그래도 잘 분리할 수 있었다.과제7기존 코드를 JPA를 통해 동작하도록 변경하기왠지 모르겠지만 굉장히 오래 걸렸다. 첫 몇 시간은 아예 과제 주제를 착각해서 허송세월을 보내기도 했다. 차근차근 강의록을 다시 읽어보면서 내용을 과제에 적용하려고 했다.기존 코드는 쿼리를 직접 작성해야 했기에 문자열 " "안에 작성한다는 것이 매우 부담스러웠는데, 훨씬 간편해졌다. 다른 분들의 코드도 몇 개 참고했는데 JPA에서 제공하는 기능으로 쿼리를 원하는 대로 작성해서 데이터를 뽑아낸 경우도 있었다. 그런데 복잡해 보이기도 하고 나는 강의에서 다뤄진 내용으로 해보고 싶어서 기본 메소드를 사용했다. 나중에 필요할 때가 분명 있을 테니 그 때 활용해 보기로 했다.앞선 과제를 계속해서 더 간결하고 편리하게 사용할 수 있는 쪽으로 개선하는 과제가 많았는데, 이 과제들이 아니었다면 난 곧장 JPA만을 이용해 코드를 짰을 것이다.(아마도) 차근차근 순서대로 같은 기능을 하는 다른 코드들을 시간을 들여 작성해 보는 시간들이 매우 소중하다는 걸 느낀 과제였다.

인프런워밍업클럽스터디

박지원

[인프런 워밍업 클럽 스터디] BE 1기 두번째 발자국

섹션 3. 역할의 분리와 스프링 컨테이너스프링 컨테이너와 스프링 빈@RestController: 강의 중에 다루는 Controller 클래스를 스프링 빈으로 등록한다.스프링 빈: 스프링 컨테이너 안에 들어간 것. 클래스에 대한 다양한 정보 저장&인스턴스화가 이루어진다. 이때 필요한 의존성이 자동으로 설정되어 JdbcTemplate를 통한 인스턴스화가 가능하다.@Repository: Repository를 스프링 빈으로 등록한다.@Service: Service를 스프링 빈으로 등록한다.스프링 컨테이너의 필요성만약 필요에 따라 Repository를 구분하여 작성하게 된다면, Service 계층에서 어떤 Repository를 사용할지 수정해 주어야 한다. 큰 규모의 프로젝트에서는 담당하는 Repository를 변경하는 것이 번거롭기 때문에 Service 계층의 코드를 바꾸지 않고 Repository만을 변경할 방법을 고안해야 한다.이것에 대한 해결책이 스프링 컨테이너인 것.제어의 역전(IoC, Inversion of Control): 컨테이너가 필요한 Repository를 선택하고, Service를 만들어 주는 것.의존성 주입(Dependency Injection): Service를 만들 때 Repository 중 하나를 선택해 넣어주는 과정@Primary: 우선권 제어. 이 어노테이션이 붙은 Repository를 선택한다.스프링 빈을 다루는 법 스프링 빈으로 등록하기 @Service와 @Repository: 개발자가 만든 클래스를 스프링 빈으로 등록할 때 사용@Configuration와 @Bean: 외부 라이브러리나 프레임워크에 만들어져 있는 클래스를 스프링 빈으로 등록할 때 사용@Configuration : 클래스에 붙이는 어노테이션. @Bean을 사용할 때 함께 사용. @Bean : 메소드에 붙이는 어노테이션. 메소드에서 반환되는 객체를 스프링 빈에 등록.@Component: 컨트롤러, 서비스, 리포지토리 외의 추가적인 클래스를 스프링 빈으로 등록할 때 사용. 주어진 클래스를 컴포넌트로 간주한다. 스프링 서버가 사용될 때 자동으로 감지된다. 스프링 빈을 주입받기 생성자 이용하기: 가장 간단, 권장되는 방법ex. JdbcTemplate jdbcTemplatepublic UserRepository(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; }setter 사용하기: final 키워드 제거, 메소드에 @Autowired 붙이기필드에 직접 주입: 필드 위에 바로 @Autowired를 적어준다. @Qualifier: @Primary 어노테이션이 없는 상황에서 주입받는 쪽이 특정 스프링 빈을 선택함.@Primary와 @Qualifier를 모두 사용하고 있다면?: @Qualifier를 사용한다.섹션 4. 생애 최초 JPA 사용하기1-1. 문자열 SQL을 직접 사용하는 것의 한계문자열 작성에 실수가 있을 수 있고, 이를 인지하는 시점이 느림: 런타임 오류로 이어질 수 있다.특정 DB에 종속적: 특정 DB를 사용하다가 다른 종류의 DB로 바꿔야한다면 번거롭다.많은 반복작업: 많은 수의 쿼리를 작성해야 하고, SELECT 쿼리 시에는 필드 매핑이 번거롭다.DB의 테이블과 객체의 패러다임이 다르다: DB는 절차지향적이라면, 객체는 객체지향적.    1-2. 문자열 SQL의 한계에 대한 해결책JPA(Java Persistence API): 객체와 관계형 데이터베이스의 테이블을 짝지어 데이터를 영구적으로 저장할 수 있도록 정해진 Java 진영의 규칙(interface)Hibernate: JPA는 API이기 때문에 규칙일 뿐이고, 이 규칙대로 코드를 작성한 가장 유명한 프레임워크Spring Data JPA: SQL을 작성하지 않아도 쿼리가 나갈 수 있도록 자동으로 처리해준다. Spring Data JPA를 이용해 데이터를 생성, 조회, 수정, 삭제하기스프링은 JpaRepository<Entity, ID>를 구현 받는 Repository에 대해 자동으로 SimpleJpaRepository 기능을 사용할 수 있게 해 준다. SimpleJpaRepository에 있는 대표적인 메소드는 다음과 같다.save: 주어지는 객체를 저장하거나 업데이트findAll: 주어진 객체가 매핑된 테이블의 모든 데이터 가져오기findById: id를 기준으로 특정한 1개의 데이터 가져오기복잡한 JPA 코드를 직접 사용하는 게 아니라, 추상화된 기능으로써 사용하게 된다.Spring Data JPA를 이용해 다양한 쿼리 작성하기ex. 유저 삭제하기: 이름을 이용해 유저 존재 여부 확인/ 유저가 존재한다면 delete 쿼리 날리기UserRepository 인터페이스User: 이름을 기준으로 유저 데이터 조회해서 유저 객체 반환. 유저가 없다면 null이 반환됨findByName: 함수 이름만 작성하면, 알아서 select * from user where name = ?라는 SQL이 조립된다.find: 1개의 데이터를 가져옴.By: 뒤에 붙는 필드 이름으로 SELECT 쿼리의 WHERE 문이 작성된다 public interface UserRepository extends JpaRepository<User, Long> { User findByName(String name); }UserRepository: 기본적으로 들어있는 delete 메소드를 사용한다.public void deleteUser(String name) { User user = userRepository.findByName(name); if (user == null) { throw new IllegalArgumentException(); } userRepository.delete(user); }Spring Data JPA의 추가적인 쿼리 작성법By 앞find: 반환 타입은 객체 or Optional<타입>findAll: 쿼리의 결과물이 N개인 경우 사용 반환 타입은 List<타입> 이다.exists: 쿼리 결과가 존재하는지를 확인. 반환 타입은 boolean이다.count: SQL의 결과 개수를 센다. 반환 타입은 long이다.By 뒤: 필드 이름이 들어가고, 이들을 And나 Or로 조합할 수 있다. 동등 조건(=) 외 다양한 조건 활용도 가능함.findAllByNameOrAge 라 작성하게 되면, select * from user name = ? or age = ? 라는 쿼리가 나간다. 트랜잭션의 필요성과 스프링에서 트랜잭션을 제어하는 방법트랜잭션: 여러 SQL을 사용해야 할 때 한 번에 성공시키거나, 하나라도 실패하면 모두 실패시키는 기능commit: 트랜잭션 시작 후 사용된 SQL을 성공적으로 반영한다rollback: 트랜잭션 시작 후 사용된 SQL을 모두 취소한다.스프링에서 트랜잭션을 제어하는 방법: 대상 메소드에 @Transactional 어노테이션을 붙여준다.@Transactional 어노테이션데이터의 변경이 없고, 조회 기능만 있을 때는 @Transactional(readOnly = true)로 설정할 수도 있다.Unchecked Exception에 대해서만 롤백이 일어난다. (IOException과 같은 Checked Exception에 대해서는 일어나지 않음)영속성 컨텍스트: 테이블과 매핑된 Entity 객체를 관리/보관하는 역할 수행 스프링의 경우, 트랜잭션을 사용하면 영속성 컨텍스트가 생겨 나고, 트랜잭션이 종료되면 영속성 컨텍스트가 종료된다.영속성 컨텍스트의 특징변경 감지 (Dirty Check): Entity는 명시적으로 save 해주지 않아도 알아서 변경을 감지하여 저장한다.쓰기 지연: 트랜잭션이 commit 되는 시점에 SQL을 모아서 한 번만 날린다.1차 캐싱: ID를 기준으로 Entity를 기억한다. 섹션 5. 책 요구사항 구현하기책 생성, 대출, 반납 API를 온전히 개발하며 지금까지 다루었던 모든 개념을 실습해 본 다.책 생성, 대출, 반납 API 개발하기 책 생성 API:book 테이블을 설계하고, Book 객체를 만들고, Repository, Service, Controller, DTO를 만든다. book 테이블 명세:create table book( id bigint auto_increment, name varchar(255), primary key (id) );책 대출 API: 어떤 유저가 어떤 책을 반납했는지 확인할 수 있는 user_loan_history 테이블을 추가로 만들고, 책이 대출되었는지 확인 후 대출되지 않아야 대출할 수 있다.user_loan_history 테이블 명세:create table user_loan_history ( id bigint auto_increment, user_id bigint, book_name varchar(255), /* 유저가 빌린 책을 대출 중인지, 반납 완료했는지 확인하는 필드이다. 이 필드에 0이 들어가 있으면 대출 중인 것이고, 1이 들어가 있으면 반납한 것이다. tinyint는 객체와 매핑되면 true인 경우 1이, false인 경우 0이 저장된다. */ is_return tinyint(1), primary key (id) )user_loan_history 테이블에 대응되는 객체 loanhistory 패키지와 Repository를 만든다.서비스 계층: 책 이름으로 책을 가져오고, 책이 없는 경우를 확인해 예외처리한다. Book 객체를 확인하고 대출 기록을 확인한다. 대출되지 않았다면 유저 객체를 가져오고 대출 기록을 저장한다.책 반납 API대출 기능에서 사용하는 HTTP Body 스펙이 유저 이름과 책 이름으로 동일하지만, 새로운 DTO를 만들어 주는 것이 추후 side-effect의 발생을 줄인다.유저 이름을 찾아 유저 객체를 받아오고 유저 아이디와 책 이름으로 대출 기록 객체를 받는다. 해당 책의 is_return 값을 '1'로 바꾼다.<2주차 학습 내용 회고>API 개발을 계속해서 더 객체지향적으로 발전시키는 법을 배웠다. 아직도 SQL을 API에 가져와 쓰는 것이 익숙하지는 않지만, 이번주 학습 내용에 포함된 JPA를 자유롭게 다룰 수 있으면 훨씬 보기 쉽고 안정적인 서버를 개발할 수 있을 것 같다.특히 책 대출 기능 개발 부분이 어려웠는데, exists 메소드를 작성할 때 exist로 오타를 내서 스프링 서버가 동작하지 않아 아찔했던 기억이 있다. 여러 개의 클래스, 패키지 등을 다루는 만큼 더 꼼꼼하게 작성하도록 주의를 기울여야겠다.이번주는 평일에 이런저런 일들이 많아 제시간에 강의를 듣지 못한 날이 있다. 다음주가 마지막인만큼 하루에 들어야 할 강의는 꼭 그 날 해결할 수 있도록 할 것이다.  <미션>과제4과일 가게 운영을 표현하는 API를 만들기3단 분리를 해서 만들었는데, 알고 보니 과제6이 관련된 과제였어서 조금 후회되었다. 그래도 작성한 코드가 완벽하게 분리된 것은 아니어서 다음 과제에서는 더 다듬어진 코드로 만들 예정이다.SQL문을 통해서는 테이블에서 필요한 값을 뽑아내는 것이지, SQL문을 통해 모든 것이 더 계산된 결과를 받는 것이 아니다. 필요한 계산은 Repository 내에서 일어나도록 코드를 작성한다.  과제5클린 코드로 리팩토링하기강의 중에서도 클린 코드에 대한 언급이 간략하게 있지만, 직접 구글링으로 클린 코드에 대해 자세히 정리한 글을 읽으며 다시 한번 복습했다. 주어진 과제 코드를 리팩토링하면서 앞서 읽은 클린 코드에 대한 지식을 적용해 보려고 노력했다. (변수명, 클래스명, 함수명 짓기와 함수의 역할 분리)과제 코드는 간단한 동작을 하는 것이기 때문에 클래스와 메인 함수를 같은 java 파일 내에서 작성했지만, 규모가 더 큰 프로젝트라면 지금 하고 있는 도서 관리 어플리케이션처럼 많은 패키지와 클래스로 나눠서 작성하여 더 클린하게 코드를 작성하도록 유의해야 한다.클린 코드에 대한 것은 어렴풋이 알고 있었던 것이지만 의식해서 '클린 코드로 만들어보자'고 작성한 것은 이번 과제가 처음이라 새로운 경험이었다. 앞으로도 클린 코드 작성 원칙을 잊지 않도록 유념해야겠다.  프로그래밍 과제가 많아 힘들었지만, 해결했을 때의 뿌듯함은 역시 프로그래밍 과제만 한 것이 없는 것 같다. 남은 과제들도 모두 잘 수행해 보겠다.

인프런워밍업클럽스터디

shihy

[인프런 워밍업 클럽 스터디 1기] BE 두 번째 발자국

안녕하세요, 오늘은 어떻게 이번 주 회고록을 남길까 하다가 일기+반성+다짐 느낌으로 가보려고 합니다. 우선, 저번 주에 일이 마감해야 하는 일이 몰려, 권장 진도를 모두 따라가지는 못했던 관계로, 이번 주에는 저번 주에 해야 됐던 강의를 듣고 과제를 진행했습니다. 백엔드 강의를 이전에도 듣긴 했지만, 아직 자바 문법과 코드 작성에 익숙하지 않은 터라 20분 강의를 1시간 동안 들으며 노션에 강사님 말씀과 코드를 정리해가며(물론 인텔리제이에서 실습도 했고요ㅎㅎ) 공부했답니다. 이번에 공부하면서 막혔던 부분은 크게 두 파트였는데요, 다른 분들이 보시면 왜 저기서...? 라고 생각하시겠지만, 아무것도 모르는 저에게는 꽤나 큰 일이었습니다. 첫 번째는 MySQL 연동 과정이었는데요, 분명히 (그날 기준) 어제도 되었던 연동이 갑자기 안 되는 일이 생겼습니다. User에 root, password에는 1234로 했는데 안 된다고 하더라고요... 그래서 패스워드도 안 넣어보고, 데이터베이스를 새로 추가하기도 하고, 정말 이것저것 했는데 안 되길래 그만 데이터베이스에 있는 모든 파일을 지워버리는 큰 실수를 하게 된 것입니다... 하하... 모든 파일을 지우니 당시에는 마음이 편해지고 이제 완전히 새로운 마음으로 데이터베이스를 만들어야지!라고 하며 만들었는데 이번에는 새로운 오류가 뜨더라고요..? 그래서 오류를 인터넷에 복붙해서 검색했더니 제가 그만 루트 파일(모든 권한이 있는 엄청나게 중요한 파일)을 함께 지웠더라고요... 하하... 그래서 root를 처음에는 복구하려고 여러 시도를 했는데, run configuration에 vm editor에 새로운 파일을 추가했는데 변화가 없었고, 인텔리제이 컨솔창에서 무언가를 하려고 해도 뭘 해야할지 모르겠고, MySQL CLI에 들어가서 뭘 쳐보려고 해도 비번만 입력해도 화면이 다운되었습니다. 그러다가 cmd에서 MySQL에 접근할 수 있다는 것이 떠올라 어떻게 해서 접근해서 블로그에 나와있던 대로 MySQL에서 root를 재생성하는 코드를 쳤는데요, 이번에는 그런 명령어가 없다고 떴습니다. 하하... 그래서 그런 명령어를 치려면 고급 시스템 변수 - Path에 MySQL bin 파일을 추가해야 한다고 하길래 거기에 파일 추가까지 했는데요, 뭐 놀랍지도 않겠지만 cmd에서 그런 명령어는 없다고 뜨며 완전 힘이 빠져가고 있었습니다... 그 뒤에는 계속 인터넷에 관련 블로그를 찾아봤는데요, 어떤 분도 이렇게 생고생하시다가 결국은 MySQL 관련 폴더를 완전히 지우고 재설치하셨다고 하더라고요... 저도 처음에는 파일을 완전히 지우는 거에 좀 트라우마(과거에 파이썬 버전 여러 개 잘못 설치해서 폴더 지우는 데 엄청 고생한 경험 유)가 있어서 망설였지만, 이 방법 외에는 그 어떤 방법도 떠오르지 않아 결국은 모두 지우고 재설치했습니다^-^결론은 MySQL에서 root 파일은 절대 절대 절대 지우는 게 아니라는 것을 배웠고, 앞으로는 삭제->재설치가 아니라 스스로 복구해보는 경험도 해보고 싶다는 생각을 했습니다. 물론 아무런 문제도 발생하지 않는 게 최고긴 하지만요ㅎㅎ 두 번째는 아직 진행 중인데요, 앞에서 말씀 드렸듯 전 백엔드 극극 입문자입니다. 그래서 Controller, Service, Repository, Domain, DTO가 각자 하는 일은 알겠는데, 그 사이의 연결, 생성자 만드는 이유, 람다 문법 등 아직 모르는 것들이 엄청나게 많아서 (강의 내용 중) 3단 분리까지 완성한 이후 정리한 모든 코드들을 한 페이지씩 만들어서 코드를 다시 읽어보며 분석할 예정입니다... 저는 아직 강의를 들으며 따라하고 있기는 하지만 난도가 조금씩 올라가고 관계가 복잡해질수록 어떻게 공부해야 제 머릿속에 다 남고, 이걸 어떻게 바로 응용해가며 쓸 수 있을지 고민에 있는데요, 우선 밀린 진도부터 따라잡고 나서 차차 생각해봐야 할 것 같습니다... 다음 주에는 부지런히 공부해서 권장 진도도 맞추고, 백엔드 공부를 어떻게 하면 효율적으로, 효과적으로 제 것으로 만들 수 있을지 연구해서 돌아오겠습니다!안녕~

백엔드인프런워밍업클럽스터디

김체토

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

2주 차 - 학습했던 내용 요약 디자인 시스템과 피그마 배리어블, 디자인 토큰 등에 관한 이론을 공부했습니다.배리어블 계층과 이름을 어떻게 정하는지에 대하여 익혔습니다.color, spacing, radius 등 foundation 스타일과 배리어블 등록을 했습니다. ✔ 디자인 시스템이란재사용 가능한 컴포넌트, 패턴 그리고 가이드 ✔ 디자인 시스템의 6가지 구성1. 디자인 원칙 : 디자인 시스템이 왜 필요한가 (비전, 미션, 가치 설정)2. 스타일 가이드 : 브랜드를 나타내는 스타일 가이드EX) 로고, 칼라, 레이아웃/그리드, 간격, 아이콘, 모션, 일러스트레이션, 사진, 디자인 토큰, 타이포그래피, 톤 오브 보이스3. 컴포넌트 라이브러리 : 재사용이 가능한 UI 기본 요소 (코드 포함)EX) 버튼, 인풋 필드, 체크 박스, 라디오 등4. 패턴 라이브러리 : 자주 반복 사용되는 디자인 템플릿EX) 로그인 폼, 탐색 메뉴, 컨텐츠 카드 배치5. 문서화 : 가이드라인, 컴포넌트, 패턴, 스타일 가이드 등을 문서화 한 자료6. 시스템 관리/운영 : 디자인 시스템을 효과적으로 관리하고 유지하기 위한 프로세스와 규칙EX) 업데이트, 학습 자료, 등 (=가버넌스) ✔ 디자인 시스템이 있으면 좋은 점디자인 일관성 유지, 브랜드 강화, 효율적인 개발, 시간 단축, 팀 간 협업 강화, 빠른 온보딩, 유지 보수 용이, 높은 품질의 경험 ✔ 배리어블 계층Component (=component)Alias (=semantic)Global (=primitive)Raw value  2주 차 - 회고이론을 복습하고 Foundation 만드는데 시간이 많이 걸려 컴포넌트를 아직 만들어보지 못했어요 😭조금 더 부지런히 작업을 해보겠습니다..!  3주 차 - 다짐 및 계획파운데이션 설정과 문서화를 빨리 끝내고 다음주에는 컴포넌트들을 모두 만들겠습니다.  

UX/UI인프런워밍업클럽스터디figmauiux

Edun

[1번과제] 인프런 워밍업 클럽 스터디 FE 1기 과제제출

<과제명 : 음식메뉴 앱 만들기>언어 : JavaScript, HTML, CSSIDE : Visual Studio CodeConcept : BurgerKing Menu Appgithub : https://github.com/hyojin-park24/inflearn-warmingUp-club-fe/tree/main/inflearn-js-1<느낀점>1) JavaScript 문법과 CSS 문법을 모르면 막막한 망망대해로 빠져 버린다. . .2) 이번 과제 하나로 많은 문법과 JS 응용을 해볼 수 있었다 가령, 아래 코드와 같은 것들이랄까// == 와 ===의 차이 console.log(true ==1); // true console.log(true == '1'); // true console.log(true === '1') // false // 여러가지 class 선언시 css selector (class selector, id selector)가 space 마다 차이가 있my음 // 단일 class <nav> class = "navigation";</nav> const navigation = document.querySelector('.navigation'); // 다중 클래스 <nav> class = "navigation my-navi1 my-navi2";</nav> const navigation = document.querySelector('.navigation.my-navi1'); //같은 요소로 인식 const navigation = document.querySelector('.navigation .my-navi1'); //하위 요소로 인식 const navigation = document.querySelector('.navigation>.my-navi1'); //자식 요소로 인식3) 기본 문법도 익힐 수 있었다map함수: map()함수로 호출한 배열 값을 반환해줌 (변환 가능)for/forEach와 차이점 : 값 반환 및 변환 기능Node복사 : clonNodeElement.children : 요소 노드만 (할당가능)const [imgElement, textContainer] = content.children; //content자식에 imgElement와 textContainer가 있음을 기대. const [titleElement, priceElement, descptionElement] = textContainer.children; //txtContainer에 titleElement와 priceElement와 descriptionElement가 있음을 기대.const [imgElement, textContainer] = content.children; const [titleElement, priceElement, descptionElement] = textContainer.children; 요소의 HTML 태크 값을 읽어오는 innerHTML/ 요소의 Text값만 읽어오는 innerText화살표 함수Element.addEventListener(: e.target.id) 4) JS 스승인 뀨님 다시한번 감사합니다, , , 핫투.실행 화면

프론트엔드JavaScriptHTMLCSS인프런워밍업클럽스터디

홍승찬

[인프런 워밍업 클럽 스터디 BE 1기] 첫 번째 발자국

참가계기국비학원에서 기초를 다졌지만 이제까지 MyBatis만을 사용한 프로젝트를 진행했었다. 때문에 요즘 기업에서 많이 요구하는 JPA를 공부해야겠다는 생각으로 강의를 결제했지만, 혼자서 게시판을 만들어보는 개인프로젝트를 진행하면서 차일피일 미뤘었다.그런데 마침 인프런 워밍업 클럽 스터디가 시작한다는 것을 알게 되었고, 개인 프로젝트도 어느 정도 기능 구현이 완료된 상태였기에 JPA 기초를 공부하면서 기존 프로젝트를 JPA로 마이그레이션 하는 것이 좋은 경험이 될 것 같아서 워밍업 클럽 스터디에 참여하게 됐다.배운 것1주차는 IDE설치부터 기초적인 개념을 다시 공부하는 시간을 가졌다.1 .인텔리제이와 MySql이제까지 이클립스와 오라클을 사용했지만 강의에서는 인텔리제이와 mySql을 사용해서 두 개를 써보고 있다. 그런데 확실히 인텔리제이가 이클립스 보다 더 안정적으로 느껴져서 앞으로는 인텔리제이를 쭉 사용할거 같다.(사실 SSD 교체해서 이클립스 설치는 귀찮았다.)DB는 오라클 GUI를 사용했었는데, MySql CLI를 사용하려니 살짝 어려운 감이 있었다. 다만 아직 테이블을 설정하고 만들 일이 많이 없기 때문에 크게 힘들지는 않았다. 나중에 개인프로젝트 할 때는 MySql워크벤치? 사용해서 만들 것 같다.2. API알고 있는 내용들을 복습하고 잊고 있었던 부분들을 상기시킬 수 있는 좋은 기회였다.3. 리팩토링국비교육에서는 Controller, Service, Repository를 나눠야 하는 이유를 알려주지 않고 3개가 각자 어떤 책임과 역할이 있는지 알려주지 않았었다. 그래서 국비에서 만든 프로젝트를 보면 컨트롤러에서 많은 역할을 수행하고 서비스단에서는 리포지토리로 넘겨주는 역할 밖에 없었다. 다행히 친구의 피드백으로 인해 왜 3개가 나뉘어야하고, 각자의 책임이 뭔지 알게 됐었는데, 강의에서 그런 부분을 하나하나 짚고 넘어가면서 혼자 공부했던 내용들을 다시 짚고 넘어갈 수 있었다.느낀점위에서 말했던 것처럼 국비교육은 생략해서 혼자 공부하면서 알게 됐던 내용들이 멘토님의 강의에 찰떡 같은 비유와 함께 있는 것을 보면서 국비교육 말고 혼자서 강의로 공부했다면 더 많이 배웠을까 라는 생각이 들었다.개인사유로 인해 금요일에 있었던 백엔드 1차 중간점검에 참여하지 못해서 너무 아쉬웠다. 다음에 있는 중간점검은 꼭 참여해서 멘토님의 이야기를 들으면서 식견을 넓혀야겠다.   

인프런워밍업클럽스터디1기워밍업클럽스터디백엔드

박지원

[인프런 워밍업 클럽 스터디] BE 1기 첫번째 발자국

Section 1. 생애 최초 API 만들기1. 스프링 부트 프로젝트를 설정해 시작하고 실행하는 방법만들어져 있는 스프링 프로젝트를 다운로드 받아 IntelliJ를 통해 여는 경우: INntelliJ 실행 후 첫 화면의 Open을 통해 가져온다.메인 함수가 있는 클래스 옆에 있는 초록색 세모 버튼을 눌러 Run을 선택하면 실행된다.아무것도 없는 상태에서 새로 스프링 프로젝트를 시작하는 경우: https://start.spring.io/에 접속해 요소를 각각 설정해 준다.Project: 빌드 툴을 고르는 항목Language: 서버 개발 시 사용할 언어Spring Boot: 스프링 부트의 버전. 옆에 알파벳이 붙지 않은, 가장 최신 버전을 고르는 게 좋다.Project Metadata: 프로젝트에 사용될 다양한 이름을 설정하는 항목. Java의 버전은 11이 가장 많이 사용된다.Dependencies: 프로젝트에서 사용하는 라이브러리(*미리 만들어져 있는 기능을 가져다 사용하는 것)이나 프레임워크(*프로그래밍 개발 시 미리 만들어져 있는 구조에 코드를 가져다 끼워 넣는 것)위와 같은 설정을 마치고 Generate를 통해 프로젝트를 만들면 압축 파일이 다운로드 되고, 그 후의 과정은 '만들어져 있는 스프링 프로젝트를 다운로드 받아 IntelliJ를 통해 여는 경우'와 동일하다. 2. 서버 개발에 필요한 다양한 개념서버: 어떠한 기능을 제공하는 프로그램. 그 프로그램을 실행시키고 있는 컴퓨터네트워크: 인터넷을 통해 데이터를 주고 받게 하는 시스템HTTP: 웹을 통한 컴퓨터 간의 통신에 대한 표준화된 방식HTTP 요청: HTTP Method(GET, POST)와 Path(/portion)이 핵심이며, 요청에서 데이터를 전달하기 위한 방법은 쿼리와 바디이다. HTTP 응답: 상태 코드 API: 클라이언트와 서버는 HTTP를 주고 받으며 기능을 동작하고, 이때 정해진 규칙이다. 3. 스프링 부트를 이용한 GET API / POST API 개발API Specification(명세): API를 개발하기 전에 API의 HTTP method, HTTP path, 쿼리와 바디, API의 반환 결과를 결정해야 한다.GET API쿼리로 들어오는 값의 개수가 많아진다면? 즉 @RequestParam이 많아지면 코드가 길어지고, 실수의 여지가 생기므로 쿼리를 받는 Class를 만든다. DTO(Data Transfer Object) 객체: '쿼리'를 서버 안 Controller로 전달하는 역할POST API쿼리를 사용하지 않고 바디(Body)를 사용한다.Json: 바디에 데이터를 담아주는 방식 { "name": "최태현", "age": 99 }POST API의 경우에는 Body를 통해 데이터가 들어오기 때문에 @ReqestBody를 꼭 사용해주어야 한다.HTPP Body는 @ReqestBody를 통해 DTO에 매핑되고, Controller로 들어가 최종 결과를 반환한다.유저 생성 & 조회 API 개발유저 조회 시 필요한 JSON으로 결과 반환하기: Controller에서 그냥 객체를 반환하면, JSON으로 응답이 간다. 이때 객체에는 getter가 있어야 한다. Section 2. 생애 Database 조작하기디스크와 메모리의 차이, Database의 필요성 컴퓨터의 핵심 부품 세 가지: CPY는 연산담당, DISK는 장기기록, RAM(메모리)는 단기기억의 역할을 수행한다.서버를 실행시켜 API를 동작시키는 과정스프링부트 서버가 DISK에 파일로 존재한다. 서버를 실행하면 DISK의 코드 정보가 RAM으로 복사된다. API가 실행되면 연산이 수행되고, CPU와 RAM을 왔다 갔다 한다. (ex) POST API를 통해 생긴 유저 정보는 RAM에 쓰여 있다. 서버가 종료되면 RAM에 있는 모든 정보가 사라지므로 재시작하면 유저 정보가 없는 것. DISK에 정보를 저장하기 위해 DB를 사용하는 것. MySQL Database를 SQL과 함께 조작하기DDL(Data Definition Language): 데이터를 정의하는 SQLDBcreate database [데이터베이스 이름]; show databases; drop database [데이터베이스 이름]; use [데이터베이스 이름];테이블create table [테이블 이름] ( [필드1 이름] [타입] [부가조건], [필드 2 이름] [타입] [부가조건], ... primary key ([필드 이름]) ); show tables; drop table [테이블 이름];DML(Data Manipulation Language): 데이터를 조작하기 위한 SQLCRUDCreate(생성): 데이터를 넣는다Retrieve or Read(읽기): 조회한다Update(업데이트): 수정한다Delete(제거): 삭제한다# 데이터 넣기 INSERT INTO [테이블 이름] (필드1이름, 필드2이름, ...) VALUES (값1, 값2, ...) # 데이터 조회하기 SELECT * FROM [테이블 이름] WHERE [조건]; # 데이터 업데이트하기 UPDATE [테이블 이름] SET 필드1이름=값1, 필드2이름=값2, ... WHERE [조건]; # 데이터 삭제하기 DELETE FROM [테이블 이름] WHERE [조건]; 스프링 서버를 이용해 Database에 접근하고 데이터를 저장, 조회, 업데이트, 삭제하기스프링 서버와 DB 연결: application.yml 파일을 생성해 스프링 서버와 연결할 DB 정보를 설정한다.DB를 통해 데이터를 저장, 조회하기POST API를 DB를 이용하게 변경하기 (Controller)jdbcTemplate을 이용해 MySQL에 SQL을 보낸다."INSERT INTO user(name, age) VALUES(?, ?)"; 와 같이 값이 들어가야 하는 부분에는 ?를 사용한다.jdbcTemplate.update(sql, request.getName(), request.getAge());jdbcTemplate.update는 INSERT, UPDATE, DELETE 쿼리에 사용 가능첫 파라미터는 sql, ?를 대신할 값을 차례로 넣어줌GET API를 DB를 이용하게 변경하기 (Controller)jdbcTemplate.query(sql, RowMapper 구현 익명클래스): query를 사용하면 SELECT 쿼리를 날릴 수 있다.@Override 함수: ResultSet 객체에는 결과가 담겨있고, 이 객체에 getType("필드이름") 을 사용해서 실제 값을 가져온다.람다를 이용해 더 간결한 코드 작성도 가능하다.UPDATE API, DELETE API 예외 처리: 대상이 없으면 IllegalArgumentException과 같은 표준 예외를 throw해야한다.기본적인 코드 구조: 유저(대상)이 있는지 id나 name을 통해 확인한다→ 유저 데이터가 있다면 비어 있지 않은 리스트를 받아오고, 유저 데이터가 없다면 비어있는 리스트가 반환된다.→ if문으로 검사해서 유저가 존재하지 않으면 IllegalArgumentException을 던진다.  Section 3. 역할의 분리와 스프링 컨테이너좋은 코드(Clean Code)의 중요성코드를 작성하는 시간보다 읽는 시간이 훨씬 많다는 점을 고려해야 한다. 팀으로 협업하는 환경에서는 다른 사람이 작성한 코드를 읽어야 할 때도 있고, 내가 오래 전에 작성한 코드를 읽을 때도 있다. 코드를 읽어야만 맥락을 이해하고 기존 코드를 수정하거나 새로운 코드를 추가할 수 있다.클린코드를 읽으면 쉽게 코드를 읽고 이해할 수 있기에 중요한 것.기존의 Controller 코드에서는 한 개의 API가 너무 많은 역할을 수행하고 있다.API의 진입 지점으로써 HTTP Body를 객체로 변환현재 유저가 있는지, 없는지 등을 확인하고 예외 처리SQL을 사용해 실제 DB와의 통신 담당기존 Controller에서 하고 있는 역할을 분리하기(리팩토링)UserService 클래스: 현재 유저가 있는지 없는지 등을 확인하고 예외 처리하는 역할을 부여한다.UserRepository 클래스: DB에 SQL을 날리는 역할, 저장장치와의 접근을 담당한다.Layered Architecture: 각 클래스가 각자의 역할을 가지고 겹겹이 쌓인 것 UserRepository 클래스 자체가 JdbcTemplate를 갖도록 해서 파라미터를 통해 매번 넘겨주지 않아도 되게 한다.   <1주차 학습 내용 회고>진도표에 따라 강의 수강이 이루어지고 있다는 점은 스스로에게 수고했다고 말하고 싶다. 사실 1일차 과제부터 제시간에 제출하지 못했기에 (아직도..) 해결하는 대로 velog와 발자국도 수정할 예정이다.DB는 전공 수업에서 다뤘던 이후로 오랜만에 해 본 건데 API와 연결하는 부분이 아직 손에 익지 않아서 연습을 더 해봐야겠다.Java의 경우도 학교 수업에서 배웠던 거랑 다르게 조금 더 응용된 걸 많이 사용하고 있어서 새롭게 느껴진다.    <미션>과제12주차 발자국 작성 전까지 추가 예정 과제2GET API와 POST API를 직접 작성해 보는 실습LocalDate.parse를 이용해서 String을 DayOfWeek로 변환했다. LocalDate가 제공하는 메소드를 이용해 요일을 출력했다.리스트의 합을 구하는 것에 시간이 많이 소요되었는데, Controller에서 Request 클래스에서 return 받은 리스트 객체를 이용해 합을 구할 수 있었다.강의를 보며 그대로 따라하는 것보다 직접 해보려니 더 어렵게 느껴졌던 과제였다. 그래도 직접 적용해 보면서 이해도가 올라가고 있음이 느껴졌다.과제3익명 클래스, 람다 모두 프로그램/코드를 간결하게 한다. 특히 람다는 기존의 메서드 선언에 꼭 필요한 부분이 아닌 것은 생략할 수 있어서 클린하게만 코드를 작성한다면 추후에도 이용하기 좋은 방법 같았다.이외에도 코드의 가독성을 높일 수 있는 여러가지 방법을 공부했는데, 지금까지는 왠지 복잡하고 오히려 에러가 나면 디버깅 하는 것이 귀찮아 잘 쓰지 않았던 것들이었다. 앞으로는 열린 마음으로 스트림 API, 함수형 인터페이스 같은 것들을 사용해 보며 익숙해져야겠다.평소라면 강의 수강을 하면서도 더 알아보거나 공부할 생각을 안 했을텐데, 미션이라는 의무가 부여되었기에 조금 더 능동적으로 공부할 수 있던 일주일이었다. 미션 수행이 조금씩 밀리고 있는데 다음 주는 놓치는 미션 없이 모두 성공해 보겠다.

인프런워밍업클럽스터디

김희제

[인프런 워밍업 클럽_0기 BE] 두번째 발자국 남기기

강의 수강 요약6일차 Layered Architecture 만들기Spring Container 클래스 저장소로 들어간 클래스를 Spring Bean 이라고 한다. @Bean과 @Configuration을 사용해 객체를 스프링 빈에 등록할 수 있다.@Component를 사용해 클래스를 SpringBean에 등록할 수 있다.생성자를 통한 주입방식을 사용하는 것이 가장 권장된다. 7일차 JPAJPA가 인터페이스면 Hibernate가 구현체이다.@Transactional영속성 컨텍스트와 기능: 트렌젝션이 시작될 때 영속성 컨텍스트가 생겨나고, 데이터베이스 객체를 보다 잘 사용할 수 있게 해준다. 기능 : 변경감지, 쓰기지연, 1차캐싱, 지연로딩8일차 ~연관관계 구현관계의 주인은 1:N중 N이다.다수가 One의 id를 가지고 있으므로, Many가 주인이다.  간단한 회고엔티티를 작성하는 것이 너무 헷갈린다. 7일차까지는 단순히 따라가기만 하면 됐었는데, 미니프로젝트 과제가 시작되고, 나름 코드를 잘 짜려고 노력하다보니 toEntity와 같은 다양한 키워드들이 눈에 밟혀서 오래걸리는 것 같다..적용은 안했지만.. 미니 프로젝트를 중심으로 남은 강의를 잘 수강해보겠습니다! 미션 해결 과정여섯번째 과제: Layered Architecture 만들기링크 : https://github.com/heisje/Inflearn-warmup-club-study-0/blob/main/assignment/LayeredArchitecture.md부트캠프에서 프로젝트를 만들때 협업을 위해 관심사를 분리하던 것에 이름이 있단 것을 알고 놀랐다. JPA와 JDBC를 인터페이스로 통합하여 스프링빈 자동주입을 사용해서 구성해보았다.일곱번째 과제: 과일가게API작성하기쿼리를 JPA로 변경하는 것이 쉽지 않았다. @Query어노테이션을 사용하면, 내 기준으로 복잡해 보이는 메소드명을 줄이고 이해하기 좋은 쿼리로 작성할 수 있어 자주 애용할 것같다. 링크: https://github.com/heisje/Inflearn-warmup-club-study-0/blob/main/assignment/jpaFruitAPIs.md  

백엔드백엔드인프런워밍업클럽스터디

채널톡 아이콘