블로그

홍승찬

[인프런 워밍업 클럽 스터디 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기워밍업클럽스터디백엔드

코파

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

목차스터디 참가 계기와 소감 과제 내용앞으로의 방향1. 스터디 참가 계기와 소감 "'HTML, CSS, JS'로 나만의 웹사이트를 만들어 보아요!"라는 유혹적인 문구에 현혹되어 작년 말 웹 개발에 입문하게 되었다. 그리고 작년 크리스마스부터 개강한 모 KDT 국비교육 프론트엔드 부트캠프에 참가하게 되었고, 몇 주 전 수료를 하게 되었다. 4개월이 채 되지 않는 짧은 교육 기간에도 불구하고, 프론트엔드 개발자에게 필수적인 지식은 얼추 쌓을 수 있었다.  하지만 교육과정에서 진행된 두 개의 프로젝트에서 모두 백엔드를 담당하게 되면서 정작 프론트엔드 프로젝트가 하나도 없는 상태로 취업시장에 덩그러니 놓여지게 되었다. 백엔드 프로젝트 리팩토링이나 이력서 작성 등을 고민하며 시간을 낭비하고 있던 와중, 마침 인프런에서 진행하는 스터디를 발견하였다. 이 스터디에 참가하기 위해서는 무려 6만 6천원이라는 비용을 지불해야 했다. 강의 자체보다는 돈을 내고 스터디에 참여한다는 강제성이 큰 자극이 되어 꾸준한 학습을 진행하는 데 도움이 될 것이라고 판단하였다(강의가 수강료에 비해 좋지 않다는 의미가 절대 아니다). 실제로 기한이 주어지는 과제를 통해 평소라면 시작조차 하지 않았을 것들을 구현해보았다. 과제를 수행하면서 문제 정의와 해결 능력을 키울 수 있었다. 또한, 다른 참가자들이 꾸준히 참여하는 모습을 보는 것만으로도 자극을 받는다. 개발초보 취준생인 나부터 회사다니면서 공부하는 경력자분들, 그리고 공부하는 대학생분들까지 모두가 열심히 노력하는 모습을 보며 동기부여에 큰 도움이 되었다. 남은 기간 동안 목표 달성에 힘써야겠다.2. 과제 내용 1) 음식 메뉴https://www.inflearn.com/blogs/7678과제 설명 : 단골 카페인 쉬즈베이글의 메뉴를 만들어보았다. 카테고리별로 나누는 기능(필터링)을 구현하는 것이 핵심이었다.힘들었던 점 : 여태껏 쉬다가 오랜만에 바닐라 자바스크립트를 사용하려고 하니 그 자체가 버거웠다. 특히 자바스크립트로 HTML 요소들을 동적으로 생성하는 부분에서 많은 시간을 소모하였다.소감 : HTML 요소를 동적으로 생성하는 코드를 많이 작성하였다. 이게 효율적인지 의문이 들어서 시간날 때 연구를 해볼 것이다. 2) 가위바위보 게임https://www.inflearn.com/blogs/7768과제 설명 : 가위, 바위, 보 중 하나를 내면 게임이 진행된다. 각 회차별 남은 횟수 및 점수, 마지막 승부 결과와 리셋 버튼까지 구현해보았다.힘들었던 점 : 게임 로직은 단순하여도 여러 요소들을 화면에 렌더링하는 코드를 작성하는 것이 익숙하지 않아서 오래 걸렸다. 단순히 자바스크립트로 가위바위보 게임을 작성하라고 하면 쉬울텐데, 화면에 있는 여러 가지 요소들을 고려해야한다는 점에서 프론트엔드 개발이 쉽지 않다고 느낀다.소감 : Math.random을 활용하여 랜덤 생성하는 것이 어려워서 좀 연습을 해야할 것 같다. 3) 퀴즈(개발 진행중으로 링크 업로드하지 않음 ^^ ><)과제 설명 : 퀴즈 앱은 욕심을 많이 부려서 추가한 기능이 많기 때문에 아직 100% 완성하지는 못하였다. 현재 OX퀴즈에 있었던 큰 이슈를 해결한 상황이다.힘들었던 점 : 과제 중 이것이 가장 어려웠다. 일단 데이터를 불러와서 렌더링해야하는 점부터 어려웠고, 30문제의 데이터 중 10개를 뽑는 로직부터 작성하기 힘들었다. 다음 단계로 넘어갈 때 문제, 정답, 해설을 모두 업데이트 해야하는데, 오류가 매우 많아서 어떤 오류가 있었는지 기억이 잘 나지도 않는다.소감 : 처음부터 로직을 분리하여 추상화된 코드를 작성하고 싶은데 마음 같지 않다. 4) 책 목록https://www.inflearn.com/blogs/7759과제 설명 : 다른 이름의 투두리스트이다. 과제에는 삭제하는 것만 나온 것 같은데, 제대로 된 투두리스트를 만들어본 적이 없어서 수정, 삭제, 추가 기능 (임시저장, CSV 파일 변환, 전체 초기화)도 구현해 보았다.힘들었던 점 : html에서 <table>태그를 처음 다루어보아서 낯설었고, CSV 파일 변환 기능 구현할 때 이슈가 많아서 별도로 정리해두었다.소감 : 일단 CRUD부터 정확하고 빠르게 구현한 후, 추가기능을 고도화하는 방향으로 진행해아 할 것 같다. 리액트도 CRUD부터 빠르고 정확하게 만드는 연습을 해야겠다. 5) 비밀번호 생성https://www.inflearn.com/blogs/7745과제 설명 : 최대 네 가지 조건을 만족하는 비밀번호를 생성하는 어플을 만드는 것이었다. 힘들었던 점 : 기본 아이디어는 네 가지 조건에 해당하는 문자열을 각각 변수에 담아두고, 해당 조건을 체크하면 문자열들을 합친 후 랜덤으로 인덱스를 생성하여 추출하는 방식으로 하였다. 그런데 이러한 경우 체크된 조건에 해당하는 문자가 하나도 없을 수 있기 때문에, 체크된 조건의 문자열은 무조건 무작위로 1개를 뽑은 후에 진행하는 로직으로 변경하였다. 이 부분이 어려웠다.소감 : 배열과 관련된 고차함수를 잘 다루는 것이 중요한 것 같다. 아직 많이 부족해서 꾸준히 공부하려고 한다. 전체 소감변수 선언시 const, let과 scope의 중요성을 명확하게 깨달았다. 이 부분과 관련해서 오류가 많이 났었다. 함수를 작성하더라도 반환값을 리턴하는 것을 간과하거나, 클래스를 생성할 때 constructor가 초기 실행 시점에 작동한다는 점 등 세부사항에 대한 고려가 필요함을 알게 되었다.코드를 작성하면서 로직을 분리하는 것이 얼마나 중요한지를 실감하게 되었다. 코드에 반복되는 패턴이 보인다면 이를 상위 수준으로 추상화하여 정리하는 것이 필요하다. 말은 쉽지만, 내 수준에서는 징그럽게 어렵다.GitHub Finder, 타이핑 테스트, 퀴즈 앱은 화요일까지 완성하려고 한다.3. 앞으로의 방향 1) 수료를 위한 필수적인 목표 바닐라 JS 과제 3개 (완료)리액트 과제 3개발자국 3회 작성 (매주 일요일) : - 발자국에 수업 내용도 정리하기 - 이번주는 수업 내용 정리를 못해서 다음주부터 진행할 예정그룹스터디 2회 참여 및 공부 내용 발표 2) 추가 목표 코드 리팩토링: 기능 개선 및 추가, CSS 적용 (특히 라이브러리 활용), 로직 분리 등을 통한 코드 개선배포 및 정리: 효울적인 코드 고민해보기 

웹 개발워밍업클럽FE발자국1주차

lar

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

1. 1주차 학습한 강의 내용 1일차(1강~5강)1. 새로운 프로젝트 시작하기Spring Initializr 사용하기https://start.spring.io/새로운 프로젝트를 시작할 때 사용하면 된다.의존성 : 프로젝트에서 사용하는 라이브러리와 프레임워크를 의미한다.라이브러리 : 프로그래밍을 개발할 때 미리 만들어져 있는 기능들을 가져와서 사용하는 것을 의미한다.프레임워크 : 프로그래밍을 개발할 때 미리 만들어져 있는 구조에 코드를 가져와서 넣는 것을 의미한다.2. @SpringBootApplication과 서버@SpringBootApplicationpackage com.group.libraryapp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class LibraryAppApplication { public static void main(String[] args) { SpringApplication.run(LibraryAppApplication.class, args); } }@SpringBootApplication : 어노테이션, 스프링 부트를 자동으로 설정이 가능하다.Class : 메인 메소드로 구성된다.SpringApplication.run(LibraryAppApplication.class, args) : 실제 스프링 부트 애플리케이션을 시작한다는 의미를 가진 코드이다.서버(Server)란?기능을 제공하는 것을 의미한다.어떠한 기능을 제공하는 프로그램을 의미한다.그 프로그램을 실행시키고 있는 컴퓨터를 의미한다.3. 네트워크란 무엇인가?IP : 컴퓨터의 주소를 의미한다.Domain Name(도메인 네임) : 외우기 어려운 IP 대신 외우기 쉬운 이름으로 변환한 것을 의미한다.DNS : IP 244.66.51.9 = 도메인 네임 spring.com, 이러한 체계를 의미한다.port(포트) : 사용하는 프로그램 데이터를 받는다.4. HTTP와 API란 무엇인가?HTTP란?인터넷에서 데이터를 주고 받을 때 하는 표준, 약속을 의미한다.예) 운송장 표준 - 요청하는 행위, 받는 사람, 항목(자원), 세부조건행위와 자원은 운송장을 보내기 전에 약속을 해야 한다.HTTP 요청GET 요청GET /portion?color=red&count=2 Host: spring.com:3000 //의미 - 내놓아라 파란집 둘째, 포션 빨간색 2개 GET(HTTP Method) : 요청을 받는 컴퓨터에게 요청하는 행위(데이터 요청)/portion(Path) : 받을 항목(자원)? : 구분기호color=red : 자원의 세부조건(Query)& : 구분기호count=2 : 자원의 세부조건(Query)Host: spring.com:3000 : HTTP 요청을 받는 컴퓨터와 프로그램 정보POST 요청POST/oak/leather Host: spring.com:3000 오크가죽정보 //창고에 넣어라 빨간집, 오크가죽 POST : 요청을 받는 컴퓨터에게 요청하는 행위(데이터 저장)/oak/leather : HTTP 요청을 받는 컴퓨터에게 원하는 자원Host: spring.com:3000 : 어떤 컴퓨터에 어떤 데이터를 받을지 정보오크가죽정보 : 실제 저장할 오크 가죽 정보(데이터, Body)데이터를 보내는 2가지의 방법쿼리 : GET에서 사용한다.바디 : POST에서 사용한다.다양한 HTTP MethodGET : 데이터 요청, 쿼리 사용POST : 데이터 저장, 바디 사용PUT : 데이터 수정, 바디 사용DELETE : 데이터 삭제, 쿼리 사용API(Application Programming Inteface)란?정해진 약속을 통해 특정 기능을 수행하는 것을 의미한다.HTTP 응답정보 처리해서 응답 보내기(200 OK) -> 200 OK : 정보가 잘 저장되었다는 의미이다.저장이라는 기능을 수행한다.💡 요청에 대한 응답을 제공한 컴퓨터는 서버(Server)를 의미한다.💡요청한 컴퓨터는 클라이언트(Client)를 의미한다.상대 코드응답에 들어가는 숫자를 의미하며, 매우 다양하다.어떠한 상태인지 알려주는 코드이다.상대 코드의 종류200 OK : 요청이 성공했다는 의미이다.300 Moved Permanently : 다른 곳으로 옮겨가라는 의미이다.404 NotFound : 요청한 내용을 찾을 수 없다라는 의미이다.500 Internal Server Error : 내부에 문제가 발생했다는 의미이다.5. GET API 개발하고 테스트 하기덧셈 APIHTTP Method -> GETHTTP Path -> /add쿼리(key와 value) -> int number1 / int number2API의 반환 결과 -> 숫자 - 두 숫자의 덧셈 결과GET API 개발 데이터의 흐름Postman에서 ?number1=100&number2=200(쿼리) 스프링 부트에서 보내면 값을 보고 객체로 만들어둔 Calculator, Add, Request에다가 값을 넣는다.그 객체를 Controller, API의 진입지점에 보내준다.정보를 전달하는 역할의 객체 : DTO(Data Transfer Object)Postman에서 send를 하면, HTTP 요청 -> 스프링 부트 서버로 도착 -> API 진입지점을 거쳐 /Add 통과 후 DTO request 함수를 실행한다.return -> 응답 생성 -> Postman에게 전달 -> Postman에서 결과를 보여준다. 2일차(6강~9강)1. POST API 개발 및 테스트하기POST API에서 데이터 받을 경우HTTP Body 사용한다.JSON으로 데이터를 받는다.사용되는 문법 -> JSONJSON이란?객체 표기법을 의미하며, 무언가를 표현하기 위한 형식이다.JSON 문법{}중괄호를 사용한다.{}중괄호 안에 "key":value로 표기한다.속성은 ,로 구분한다.추가적으로 다른 JSON 문법을 작성할 수 있다.{ "name":"김철수", "age":50 } 곱셈 APIHTTP Method -> POSTHTTP Path -> /multiplyHTTP Body(JSON) -> {"number1":숫자,"number2":숫자}API의 반환 결과 -> 숫자(곱셈 결과)POST API 개발 데이터 흐름데이터를 전달해주는 객체인 DTO 생성POST API 개발Body 사용 시 @RequestBody 어노테이션을 사용한다.JSON을 CalculatorMultiplyRequest 객체로 전환해준다. 2. 유저 생성 API 개발 및 테스트하기도서 관리 애플리케이션의 요구사항사용자도서관 사용자 등록(이름 필수, 나이 선택)도서관 사용자 목록 확인도서관 사용자 이름 수정도서관 사용자 삭제책도서관 책 등록 및 삭제도서관 사용자 책 대여다른 사람이 대여 시 대여 불가능도서관 사용자 책 반납도서관 사용자 등록하기유저 생성 API 조건HTTP Method : POSTHTTP Path : /userHTTP Body (JSON)JSON { "name": String (null 불가능), "age":Integer } 결과 반환 X(HTTP 상태 200 OK이면 충분하다.)유저 생성 API 개발 데이터 흐름Body를 객체로 표현할 DTO 생성유저를 저장하기 위한 객체 생성유저 생성 API 개발POST user 호출 -> 함수 실행 -> Body에 이름과 나이가 들어오면 객체로 매핑한다.새로운 유저를 만들 때 사용되는 Requset -> 생성된 유저 객체가 List에 저장 -> 함수가 예외없이 완료되면 응답코드 200 OK로 반환한다.3. 유저 조회 API 개발 및 테스트하기유저 조회 API 조건HTTP Method : GETHTTP Path : /user쿼리 : 없음결과 반환 (JSON)JSON { "name": String (null 불가능), "age":Integer } 유저 조회 API 개발 데이터 흐름데이터를 담아 줄 DTO 생성유저 조회 API 개발User List 생성 -> List에 들어있는 유저들이 1개씩 돌면서 UserResponse 형태로 반환한다.결과 리스트에 추가 -> responses로 반환한다. 3일차(10강~13강)1. 컴퓨터의 핵심 부품 이해하기서버 유저 정보가 왜 남아있지 않는지 이해하기 위해 알아보자.CPU : 연산RAM : 임시 기억장치DISK : 장기 기억장치2. Database와 MYSQLDatabase란?데이터를 구조화시켜 저장하는 것을 의미한다.RDB (Relational Database) - MySQL : 데이터를 표처럼 구조회 시켜 저장하는 것을 의미한다.SQL(Structured Query Language) : 표처럼 구조화된 데이터를 조회하는 언어이다.3. MySQL에서 Table 생성하기데이터베이스 생성create database [데이터베이스 이름]; 데이터베이스 목록 확인show databases; 데이터베이스 삭제drop database [데이터베이스 이름]; 데이터베이스 안으로 들어가기use [데이터베이스 이름]; 테이블 목록 확인show tables; 테이블 생성create table [테이블 이름] ( [필드1 이름] [타입] [부가조건], [필드1 이름] [타입] [부가조건], ... primary key([필드 이름]) ); 테이블 생성 예시create table fruit ( id bigint auto_increment, name varchar(20), price int, stocked_date date, primary key (id) ); auto_increment : 데이터가 없어도 1부터 1개씩 증가하며, 자동 기록된다.primary key : 유일한 키를 의미하며, id라는 필드를 지정한다.테이블 삭제drop table [테이블 이름]; => 해당 SQL를 DDL(Data Definition Language)이라고 정의한다.MYSQL 타입의 종류정수 타입tinyint : 1바이트int : 4바이트bigint : 8바이트실수 타입double : 8바이트 정수decimal(A, B) : 소수점을 B개 갖고 있는 전체 A자릿수 실수문자열 타입char() : ()글자가 들어갈 수 있는 문자열varchar() : 최대 ()글자가 들어갈 수 있는 문자열날짜, 시간 타입date : 날짜, yyyy-MM-ddtime : 시간, HH:mm:ssdatetime : 날짜와 시간을 합친 타입, yyyy-MM-dd HH:mm:ss4. Table 데이터 조작하기생성, 조회, 수정, 삭제 방법(CRUD)생성 : Create읽기 : Read수정 : Update삭제 : Delete데이터 삽입insert into [테이블 이름](필드1 이름, 필드2 이름) values (값1, 값2, ...) 데이터 삽입 예시insert into fruit (name, price, stocked_date) values ('사과', 1000, '2023-01-01'); ()안의 필드와 값의 순서가 중요하기 때문에 순서대로 작성해야 한다.id는 지정하지 않아도 auto_increment가 자동으로 생성해준다.데이터 조회select * from [테이블 이름]; select * from [테이블 이름] where [조건]; 데이터 조회 예시select name, price from fruit; select * from fruit where name = '사과' and price <= 2000; 테이블명 대신 필드 이름도 가능하며, 여러개를 넣을 수도 있다.조건을 넣어서 조회도 가능하다. (and, or, =,>=,<=, !=, between, in, not 등이 있다.)데이터 수정update [테이블 이름] set 필드1이름=값, 필드2이름=값, ... where [조건]; 데이터 수정 예시update fruit set price = 1500 where name = '사과'; 조건을 붙이지 않으면 모든 데이터가 업데이트 되기 때문에 주의 해야 한다.데이터 삭제delete from [테이블 이름] where [조건]; 데이터 삭제 예시delete from fruit where name = '사과'; 조건을 붙이지 않으면 모든 데이터가 삭제 되기 때문에 주의 해야 한다.=> 해당 SQL를 DML(Data Manipulation Language)이라고 정의한다.5. Spring에서 Database 사용하기Database 설정 파일 추가application.yml 파일 생성spring: datasource: url: "jdbc:mysql://localhost/library" username: "root" password: "" driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://Host/접근DB명username: MySQL에 접근하기 위한 계정명password: MySQL에 접근하기 위한 비밀번호driver-class-name: DB에 접근 시 사용할 프로그램 4일차(14강~16강)1. 사용자 수정 API, 삭제 API 개발 및 테스트하기사용자 수정 API 조건HTTP Method : PUTHTTP Path : /userHTTP Body (JSON){ "id": Long, "name": String } 결과 반환 X (HTTP 상태 200 OK이면 충분하다.)사용자 삭제 API 조건HTTP Method : DELETEHTTP Path : /userQuery 사용문자열 name (삭제되어야 하는 사용자 이름)결과 반환 X (HTTP 상태 200 OK이면 충분하다.)사용자 수정 및 삭제 API 개발사용자를 수정하기 위한 DTO 추가사용자 수정/삭제 API 개발사용자 수정 API, 삭제 API 예외처리 하기존재하지 않는 사용자를 수정하거나 삭제하려고 해도 응답코드 200 OK가 나온다.> 예외처리해야 한다.데이터 존재 여부를 확인하고 예외처리 하기사용자 수정/삭제 API 예외처리 개발id를 기준으로 사용자가 존재하는지 확인하기 위해 SELECT 쿼리 작성한다.SQL을 DB에 전송해서 데이터가 있는지 확인한다.SELECT SQL의 결과가 있으면 0 반환, ? 값 id를 삽입한다.0은 최종적으로 List로 반환한다. 사용자가 존재하지 않을 경우 예외처리한다.사용자가 존재하지 않을 경우예외처리한 결과, 내부에 문제가 있다는 오류가 발생했다. 5일차(17강~18강)1. 좋은 코드(Clean Code)가 왜 중요한가?코드는 요구사항을 표현하는 언어이다. 좋은 코드는 코드만 보고도 의미를 파악을 할 수 있다.안 좋은 코드가 쌓이면, 시간이 지날수록 생산성이 낮아진다.Clean Code함수는 최대한 작게 만들고, 1가지 일만 수행하는 것이 좋다.클래스는 작아야 하며, 하나의 책임만을 가져야 한다.2. Controller, Service, Repository 분리하기Controller의 함수 1개가 하고 있던 역할API의 진입 지점으로서 HTTP Body를 객체로 변환한다 -> Controller현재 유저가 있는지 없는지 등을 확인하고 예외처리를 해준다. -> ServiceSQL을 사용해 실제 DB와의 통신을 담당한다. -> Repository역할 분리 구조Controller : API와 HTTP 관련 역할 담당Service : 분기 처리 및 로직 담당Repository : DB와의 접근을 담당각 역할을 분리하여 수행하는 계층으로 이루어진 구조를 계층화 아키텍쳐(Layered Architecture)라고 한다.JdbcTemplate 변수를 선언하고 생성자를 통해 UserRepository를 인스턴스화하는 시점에 JdbcTemplate을 넣어주도록 변경한다.2. 미션첫 번째 과제(1일차)나만의 어노테이션을 만들 수 있었다는 걸 알게 되었고, 어떠한 상황에서 정해진 어노테이션만 사용했었는데, 만드는 방법을 알게 되어 좋았다.두 번째 과제(2일차)3번째 문제에서 배열로 처리했는데, 배열보다는 리스트로 하는 게 더 좋다는 피드백 댓글을 보고 리스트로 적용해서 구현해보고, 다른 방법들도 알게 되어 좋았다.세 번째 과제(3일차)람다식에 대해 깊게 공부한 적은 없었는데, 이번 과제를 하면서 람다식에 대한 도입 배경, 방법 등을 알게 되어 좋았다.3. 회고일주일이 정말 금방 지나간 느낌이다. 과제를 하면서 스스로 고민해보고 구현하면서 성장할 수 있는 시간을 갖게 되어 좋았다. 다른 일도 겹치면서 아직 4,5일차 과제를 완료하지 못했지만 기간 안에 제출하도록 노력해야겠다. 헷갈리는 부분들을 복습하면서 다음주엔 더 분발해야겠다!

백엔드발자국회고워밍업1주차

Edun

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

1주차 회고록 작성.<강의>- 따라하며 배우는 자바스크립트 A-Z (Section0~1)<과제>- 음식 메뉴 App 만들기 [버거킹 메뉴 앱]: Javascript의 html 속성을 통해 각 노드의 요소마다 Button별로 Filtering된 Data를 넣어주기.<느낀점>1) 내게는 너무 낯선 Javascript2) 자유분방-예측불가-코드리뷰가 막막한 녀석. . .3) 어떻게든 돌아가도록 프로그램을 만들기 위해 탄생한 JavaScript라니. . .4) 이 녀석을 재밌게 만들어준 동료들(뀨님,꼉님, 쏘님) 사랑합니다 핫투.[JavaScript 기초]Console 객체IDE 설치VS codeWebStormVS code - Live Server 설치웹 프로젝트를 미리 볼 수 있도록 로컬 서버를 호스팅하는 확장 프로그램script.js - console.log크롬 개발도구(F12) Console 창에 출력됨개발시 어떠한 식으로 진행되는지 Console로 출력해서 알아보면 용이함어디서, 어떻게 에러가 났는지 출력을 할때 log사용함console.log('Hello,World'); console.log('1243'); console.log(true); var greeting = 'hello!'; console.log(greeting); console.log({a: "a", b: "b"}); console.table({a: "a", b: "b"}); console.error('Error!'); console.warn('Warning!!'); console.time('Hello'); console.time(1); console.time(2); console.time(3); console.time(4); console.time(5); console.time(6); console.time(7); console.timeEnd('Hello'); 변수 선언 : var, let, const자바스크립트 코드 작성브라우저 - 개발도구에서 바로 사용 가능IDE - VSCode 활용변수 선언 방식 / 참조범위 / 호이스팅호이스팅 : 인터프리터 언어 특성상, 호이스팅이 제공됨 (변수 끌어올려서 사용하는 것)| 변수 | 중복 | 재할당 | 유효한 참조 범위 (Scope) | 호이스팅 (변수 끌어올림) | | --- | --- | --- | --- | --- | | var | O | O | 함수 레벨 | 선언 : undefined 자동 할당 (초기화 전) 할당 : 값 할당 | | let(ES6) | X | O | 블록 레벨 | 선언 : undefined 할당 X (TDZ : Temporal Dead Zone) | | const(ES6) | X | X | 블록 레벨 | 선언 : undefined 할당 X (TDZ : Temporal Dead Zone) |// var type : 선언 및 할당 여러번 가능 (자유도 높음) // : 유지보수 하기 힘듦. var A = 1; console.log(A); var greeting = 'hello'; console.log(greeting); var greeting = 'hi'; console.log(greeting); greeting = 'how are you?'; console.log(greeting); // let type : 중복선언 X, 할당 가능 let ttt = 'hi, halo'; console.log(ttt); //let ttt 'haha'; // error. ttt = 'papapapa'; console.log(ttt); // const type : 중복 && 할당 X // : constant (상수) 약자 const damn = 'yess'; console.log(damn); //const damn = 'ttt'; //error. //damn = 'yesfds'; //console.log(damn); //error. //------------- 02. Scope //------------- 01) var 함수 레벨 스코프 function func() { if(true) { var a = 'a'; console.log(a); } console.log(a); } func(); //------------- 02) let,const 블록 레벨 스코프 function func2() { if(true) { let a = 'a_let'; console.log(a); } } func2(); //------------- 03. 호이스팅 //------------- 01) var 호이스팅 : undefined //------------- 02) let, const 호이스팅 : error. console.log(seelping); var seelping = '자고싶다'; // undefined let seelping = '자고싶다'; //error. //------------- 03) 함수 호이스팅 : 정상출력. func3(); function func3() { console.log('hosting test'); } 자바스크립트 타입원시타입 : Boolean, String, Numeric, Null, undefined, Symbol불변성에 저장됨고정 크기로 Call Stack에 저장됨실제 데이터가 변수에 할당됨참조타입 : Object, Array, Class, Functions실제 데이터는 Heep에 저장됨데이터 크기가 정해지지 않고 주소값이 Call Stack에 저장됨자바스크립트 = 동적 타입느슨한 타입동적 언어변수는 타입과 연결되지 않음모든 타입의 값으로 할당(및 재할당) 가능string → boolean → numeric 가능한 것//------------------------ 원시 타입 // 문자열 String const name = 'Edun'; // Number const age = 38; // Boolean const hasJob = true; // null const car = null; // undefined let anything; // Symbol const sym = Symbol(); //------------------------ 참조 타입 // Array 배열 : 객체의 하나의 형태 const hobbies = ['wailing', 'books']; // Object 객체 const addr = { province : '부산광역시', city : '남구' } console.log(typeof hobbies); console.log(Array.isArray(hobbies)); 자바스크립트 타입변환자바스크립트 함수 사용 변환let val; // Nuber to String val = String(111); val = String(8 + 4); // Boolean to String val = String(false); // Date to String val = String(new Date()); // Array to String val = String([1,2,3,4,5]); // toString() val = (5).toString(); // String to number val = Number('1'); val = Number(true); val = Number(false); val = Number(null); val = Number([1,2,3]); // NaN = Not a Number val = parseInt('111.40'); val = parseFloat('111.40'); console.log(val); console.log(typeof val); console.log(val.length); 자바스크립트 자체에 의해 자동 변환const val1 = 2; const val2 = String(3); const sum = val1 + val2; console.log(sum); // string으로 자동변환. console.log(typeof sum); 자바스크립트 연산 및 Math Objectconst num1 = 20; const num2 = 10; let val; // 산수 연산 val = num1 + num2; val = num1 * num2; val = num1 - num2; val = num1 / num2; val = num1 % num2; // 나머지 연산자 // Math Object //--------------------------------- 속성 val = Math.E; // 속성 val = Math.PI; // 속성 //--------------------------------- 메서드 val = Math.round(2.4); // 가까운 정수로 리턴 val = Math.ceil(2.4); // 무조건 올림 val = Math.floor(2.8); // 무조건 내림 val = Math.abs(-2); // 절댓값 val = Math.min(2,3,4,5,6,7,8,-1); val = Math.max(2,3,4,5,6,7,8,-1); val = Math.random(); // 0~1 사이에서 return. // 1~20 사이 랜덤 숫자 val = Math.floor(Math.random() * 20 + 1); //+1 필수. console.log(val); Template LiteralsTemlate Literals : javascript에서 backtick() 문자를 사용하여 문자열을 표현한 템플릿쉬운 줄바꿈‘\n’ → 실제 Enter 적용문자열 내부에 표현식을 포함할 수 있음‘+{a+b}+’ → 보간법 ${a+b}백틱(backtick) ⇒ ‘ ` '로 사용Loopsfor 코드 블록을 여러 번 반복 for/in 객체의 속성을 따라 반복 while 지정된 조건이 true 인 동안 코드 블록을 반복 do/while while 루프의 변형 조건이 true인지 검사하기 전에, 코드 블록 한 번 실행 후 조건이 true인 동안 루프 반복for vs forEachfor forEach 원래 사용되었던 접근 방식 배열 요소를 반복하는 새로운 접근 방식 breack 사용 가능 breack 사용 불가능 빠름 for보다 느림 비동기 await 작동 비동기 await 작동 애매함// for문 for(let i=0; i < 10; i++){ if(i === 3){ console.log('It is 3'); continue; } if(i === 5){ console.log('5 Stop the loop.'); break; } console.log('Number ' + i); } // for/in 문 const user = { name: 'Edun', province: '부산광역시', city: '남구' } for(let x in user){ console.log(`${x} : ${user[x]}`); } // while 문 let i = 0; while(i < 10){ console.log('Numer ' + i); i++; } // do/while 문 let i = 0; do { console.log('Number ' + i); i++; } while(i < 10); //배열을 Loop로 이용해서 컨트롤 해주기 const locations = ['서울', '부산', '경기도', '대구']; for(let i = 0; i < locations.length; i++){ console.log(locations[i]); } locations.forEach(function (location, index, array){ console.log(`${index} : ${location}`); console.log(array); }); // console.log(locations);   

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

희희

[인프런 워밍업 클럽 스터디 1기] BE 1주차 회고

첫번째 발자국 인프런 워밍업 클럽 스터디에 참여하여 일주일을 보낸 후 쓰는 첫번째 회고록. Section 1 - 생애 최초 API 만들기JVM자바 가상 머신의 약자os 별로 존재한다.바이너리 코드들을 읽고 검증한다.JRE자바 실행 환경의 약자JRE = JVM + 자바 프로그램 실행에 필요한 라이브러리 파일 등JVM의 실행 환경을 구현JDK자바 개발 도구의 약자JDK = JRE + 개발을 위한 도구(통합 개발 도구)컴파일러, 디버그 도구 등이 포함되어 있다.여러 버전이 있고, 각 버전별로 새로운 기능이 추가되거나 기존 기능이 사라진다.여러 종류가 있고, 기능 자체는 동일하나 성능과 비용에 약간의 차이가 있을 수 있다. 빌드 : 소스코드 파일을 컴퓨터에서 실행할 수 있는 독립 SW 가공물(Artifact, 독립적인 하나의 파일)로 변환시키는 과정실행 : 작성한 코드를 컴파일을 거쳐 작동시켜보는 것(독립 SW 가공물이 나올수도 있고, 나오지 않을 수도 있음)빌드 과정 자동화와 외부 라이브러리 관리를 위해 빌드 툴이 사용되며, 자주 사용되는 자바 빌드툴에는 maven, gradle이 있다. 어노테이션자동으로 설정/기능을 동작하게 하는 것@ + (어노테이션으로 만들어둔) 클래스 이름 서버 : 어떤 기능을 제공하는 프로그램. 또는 그 프로그램을 실행시키고 있는 컴퓨터클라이언트 : 서버에 어떤 기능을 요청하는 프로그램. 또는 그 프로그램을 실행시키고 있는 컴퓨터HTTP : 컴퓨터가 네트워크를 통해 다른 컴퓨터와 데이터를 주고받을 때 사용되는 통신 규약(중 하나)HTTP Method : HTTP 요청을 받는 컴퓨터에게 요청하는 행위(GET, POST, PUT, DELETE 등)요청을 받는 컴퓨터(IP 주소 / 도메인)와 프로그램(port) 정보Path : HTTP 요청을 받는 컴퓨터에게 원하는 자원Query : 자원의 세부 조건(조건이 여러개면 &로 구분)Body(JSON) : 저장할 자원의 정보JSON : 객체 표기법. 중괄호 안에 "key": value로 표기하며, 속성 각각은 ,로 구분한다. 요청에 대한 HTTP 응답200 OK (요청이 잘 처리됨)300 Moved Permanently (다른 곳으로 옮겨가라)404 NotFound (요청한 것을 찾을 수 없음)500 Internal Server Error (우리 내부에 문제가 생김)응답에는 추가 정보(바디)를 담을 수도 있음 API 정해진 약속을 하여 특정 기능을 수행하는 것클라이언트와 서버는 HTTP를 주고 받으며 기능을 동작하는데 이때 정해진 규칙API의 구성 요소(명세)HTTP MethodHTTP PathQuery(key와 value)API의 반환 결과 @RestController: 주어진 클래스를 Controller(API의 입구)로 등록한다 -> 현재 클래스를 API의 진입 지점으로 만들어줌@GetMapping("/add"): 아래 함수를 HTTP Method가 GET이고 HTTP Path가 /add인 API로 지정한다.@RequestParam: 주어지는 쿼리를 함수 파라미터에 넣는다 -> 같은 이름을 가진 쿼리의 값이 함수의 argument로 들어온다@RequestBody: HTTP Body 안에 담긴 JSON을 DTO 객체로 변환 (DTO : 정보를 전달하는 역할의 객체) Section 2 - Database 조작하기Database의 필요성: API를 통해 생성된 정보는 단기 기억장치인 RAM에 기록되는데, RAM에 기록된 정보는 서버가 종료되면 사라지기 때문에 DISK에 장기 저장하기 위해 DB를 사용한다. Database : 데이터를 구조화해서 저장하는 것RDB(Relational DB) - MySQL : 데이터를 표처럼 구조화해서 저장하는 DBSQL(Structured Query Language) : 표처럼 구조화된 데이터를 조회,저장 등 조작하는 언어-> MySQL을 사용 DDL(Data Definition Language) : 데이터를 정의하는 언어데이터베이스 만들기 : create database [데이터베이스 이름];데이터베이스 목록 보기 : show databases;데이터베이스 지우기 : drop database [데이터베이스 이름];데이터베이스 안으로 들어가기 : use [데이터베이스 이름];(특정 데이터베이스 안으로 들어간 후)테이블 목록 보기 : show tables;테이블 만들기 :create table [테이블 이름] ([필드1 이름] [타입] [부가조건],[필드2 이름] [타입] [부가조건],...primary key ([필드이름]));테이블 제거하기 : drop table [테이블 이름];DML(Data Manipulation Language) : 데이터를 조작하는 언어데이터를 넣는다 = 생성, create데이터를 조회한다 = 조회(읽기), retrieve of read데이터를 수정한다 = 업데이트, update데이터를 삭제한다 = 제거, delete-> CRUD데이터 넣기INSERT INTO [테이블 이름] (필드1이름, 필드2이름, ...)VALUDES(값1, 값2, ...)필드 이름과 값의 순서가 맞아야 한다명령어는 소문자로 써도 상관 없다auto_increment로 지정된 필드값은 지정해주지 않아도 자동으로 설정된다데이터 조회하기SELECT * FROM [테이블 이름];* 대신 필드 이름을 넣을 수 있다. 여러 개 넣는 것도 가능하다.SELECT * FROM [테이블 이름] WHERE [조건];where을 이용해 필터(조건)을 걸 수 있다.AND 또는 OR을 이용해 조건을 이어 붙일 수 있다.조건에는 =, <= 외에도 !=, <, >, >=, between, in, not in 등이 있다.BETWEEN [범위의 시작값] AND [범위의 끝값] : 양끝값을 포함한 범위 내의 값들만 가져온다.IN(조건1, 조건2) : 여러 조건을 한 번에 표시할 때 사용NOT IN() : 괄호 안 조건들에 포함되지 않는 데이터만 조회할 때 사용데이터 업데이트하기UPDATE [테이블 이름] SET 필드1이름=값, 필드2이름=값, ...WHERE [조건];where 절을 사용해 [조건]을 붙이지 않으면, 모든 데이터가 변경(업데이트)되니 주의해야 함데이터 삭제하기DELETE FROM [테이블 이름] WHERE [조건];[조건]을 붙이지 않으면 모든 데이터가 삭제되니 주의할 것!Spring에서 Database 사용하기사람이 아닌 스프링 서버가 MySQL 서버에 접근하게 하는 것application.yml 만들고 설정spring: datasource: url: "jdbc:mysql://localhost/library" username: "root" password: "5502" driver-class-name: com.mysql.cj.jdbc.DriverAPI 변경jdbcTemplate을 이용해 SQL을 날릴 수 있다. SQL을 만들어 문자열 변수로 저장한다. 이때 값이 들어가는 부분에 ?를 사용하면, 값을 유동적으로 넣을 수 있다.jdbcTemplate.update()는 INSERT, UPDATE, DELETE 쿼리에 사용할 수 있다(데이터에 변경을 주는 쿼리). 첫 파라미터로는 sql을 받고, ?를 데신할 값을 차례로 넣으면 된다.jdbcTemplate.query(sql, RowMapper 구현 익명클래스) : mapRow라는 함수를 override하고, override한 MapRow 안에서 sql의 실행 결과가 나오면 그 결과들의 데이터를 가져와 UserResponse(dto)로 바꿔준다. Section 3 - 역할의 분리와 스프링 컨테이너클린 코드가 중요한 이유 코드 : 요구사항을 표현하는 언어-> 개발자는 요구사항을 구현하기 위해 코드를 읽고 작성한다.-> 코드를 읽는 것은 필수적이고 피할 수 없으므로, 코드만 보고도 의미를 명확하게 파악할 수 있도록 코드를 작성해야 한다. 클린 코드함수는 최대한 작게 만들고 한 가지 일만 수행하는 것이 좋다.클래스는 작아야 하며 하나의 책임만을 가져야 한다.Controller의 함수 1개를 역할에 따라 분리API의 진입 지점으로써 HTTP Body를 객체로 변환하고 있다. -> Controller의 역할로 남겨둠현재 유저가 있는지, 없는지 등을 확인하고 예외 처리를 해준다. -> Service의 역할로 분리SQL을 통해 실제 DB와의 통신을 담당한다. -> Repository의 역할로 분리 3가지 역할로 구분된 구조controller : API와 HTTP 역할 담당service : 분기 처리, 로직 담당repository : DB와의 접근 담당* controller는 service를 사용하고, service는 repostory를 사용함** DTO는 계층 간의 정보를 전달하는 역할(여러 계층을 왔다갔다 함)-> 이런 구조를 Layered Architecture라고 한다!  회고인프런 워밍업 클럽 스터디에 참여한지 벌써 일주일이 지났다. 이번주에 다른 일들이 많이 겹쳐 내 생각보다 더 힘들었지만, 혼자서 공부하는 것보다 이점이 훨씬 많았다. 진도표에 매일 공부할 분량이 체계적으로 정해져 있어 내가 별도로 학습 계획을 짜지 않아도 계획적으로 공부할 수 있었다. 여러명이 함께 강의를 수강하는 스터디 방식이라 강의 듣는 것을 미루지 않고 진도표에 맞춰 학습할 동기부여가 되었다. 추가적으로 주어지는 과제를 통해 배운 내용에 대해 스스로 학습하고 정리할 수 있는 것도 좋았다. 강의 내용도 매우 흥미로웠다. 자바와 스프링에 대한 기초 지식부터, 백엔드 개발에 필요한 서버 관련 내용까지 차근차근 정리할 수 있었다. 또한 API 설계 및 개발 과정을 실습으로 진행하며 각 기능이 어떻게 동작하고 구현되는지 직접 코딩을 하며 익혔다. 다른 일들이 겹쳐 과제를 놓치기도 하고 실습 중 자바에 대한 이해가 부족하다는 것을 느껴 조금 아쉬운 1주차였지만, 2주차부터는 좀 더 많은 시간을 투자하고 자바에 대한 학습도 병행하며 더 충실한 일주일을 보낼 수 있도록 노력할 것이다.

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

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

 인프런 워밍업 클럽 1기 스터디 첫 주가 마무리 되었다. 학습 요약 및 회고, 미션 진행 과정과 회고, 첫 주를 마무리한 소감 및 앞으로의 각오 순으로 간략하게나마 첫 발자국을 작성한다. 첫 주의 학습 요약 및 회고진도표를 충실히 따랐다면 18강까지 학습이 완료 되어야 했지만 지난 한 주간 사정이 여의찮아 진도가 꽤 뒤쳐졌다. 발자국 작성 시점에서 수강 완료한 9강까지만 작성하겠다. 2주차에는 최대한 시간을 내어 진도율을 따라잡고자 한다. 섹션 0강의 소개와 준비본격적인 시작에 앞서 강의를 위해 준비하는 단계를 가졌다. Java와 인텔리제이, git은 설치되어 있었지만 PostMan이라는 api 테스트 툴을 처음 접해보았는데 다음 섹션에서 언급하겠지만 상당히 유용하고 편리하다. DBMS 역시 오라클만 사용해 보았기 때문에 영상을 따라 MySQL을 설치했다. 영상으로 명료하게 안내해 주셨기 때문에 프로그램 설치와 프로젝트 환경 설정에 어려움이 없었다. '프로젝트를 시작하는 첫 번째 방법' 영상에서는 올려주신 파일을 통해 Gradle 프로젝트를 불러왔는데, 내가 경험했던 첫 프로젝트가 떠올랐다. 국비학원에서 연식 있으신 강사님에게 배우며 프로젝트를 진행했는데, 스프링부트가 아닌 스프링으로 프로젝트를 해 보라는 말씀을 곧이곧대로 듣고 당시 maven으로 팀원과 손수 하나하나 환경 설정을 했다. 각자의 로컬환경에서 프로젝트를 통일하는데도 어려움이 꽤 있었다. 빌드 속도도 빠르고 복잡한 pom.xml로부터 해방시켜 주는 Gradle... 앞으로는 Gradle 쓸 일만 있었으면 싶은 바람이 있지만 두 빌드툴을 다 사용해 보는 경험은 나름대로 유의미할 거라고 생각해 본다. 섹션1생애 최초 API 만들기2-4강에서 서버 요청, 네트워크, HTTP와 API의 기초적인 개념을 학습하였다. 비유를 활용한 강사님의 설명이 굉장히 이해하기 쉽고 재미있었다. 대략 알고 있는 내용도 많았으나 복잡한 용어로 곧장 설명하고자 하면 머리에서 정리되지 않았던 것이 비유적으로, 또 원인 중심적으로 접근하니 훨씬 쉽고 간단명료하게 와닿는다. 특히 [집 주소]는 [ip] , 이를 알기 쉽게 [파란집]으로 대체한 것이 [도메인] 처럼 실생활적 단어에 일대일로 대응하여 용어를 설명하는 방식이 빠른 이해에 효과적이었다.HTTP Method도 이미 배우고 프로젝트로 구현해본 개념이지만 이 강의를 들으며 이제야 내가 무엇을 하고 있었는지가 확실해진 기분이 든다. 한 편으로는 내 머릿속이 이리도 엉망진창이었구나 싶다. 내가 무엇을 하는지 알고 행하는 것과 모르고 행하는 것은 정말 다르다. 아무래도 다 알기 전에 실천하고 행하는 것이 개발 공부의 미덕으로 여겨지고는 하는데, 나 자신은 개인적으로 선이해가 수행되지 않으면 실행하는 과정을 굉장히 힘겨워하는 타입이다. 지난 프로젝트 경험은 일단 하나하나 부딪히는 방식이었기에 여전히 머릿속에서 정리되지 않은 개념이 많다. 이번 강의 스터디가 모르고 행했던 것들을 다시 한 번 이해하는데 많이 도움되고 있고, 앞으로도 그럴 것이 기대된다. 차 주의 학습 목표이번 주 학습 시간이 적었던 것이 아쉽고, 다음 주부터는 진도표에 맞출 수 있도록 이른 시일 내에 진도율을 높이는 것을 목표로 더 적극적으로 수강할 것이다.  미션 과정 및 회고1일차 미션 - @Annotation어노테이션을 사용하고 있었지만 어노테이션의 의미에 대해 따로 디깅해 본 적은 없었기에 확실한 개념 이해에 도움을 주는 미션이었다. 구글링을 통해 여러 블로그를 찾아보고 책도 들춰보고 GPT에도 물어본 결과를 취합하여 질문에 따른 답을 작성했다. 내가 사용해 본 것들 외에도 컴파일 시에 검사를 하게하는 등 많은 기능을 하는 다양한 어노테이션들과, 커스텀 어노테이션을 정의하는 방법에 대해 새롭게 알게 되었다.https://dev-de.tistory.com/76 2일차 미션 - api 만들기2일차 미션으로는 GET, POST API를 만드는 세 가지 문제를 해결하였다. 어떤 방법이 더 나을지 나름대로 고민하였으나 완전히 만족스럽지는 않다. 또한 PostMan의 편의성에 감탄했다. 기초가 부족한 편이기에 아무것도 없었다면 List로 JSON을 받는다는 생각을 못 했을 텐데 문제에 Hint가 있는 것이 도움 되었다. 강사님의 피드백에 따라 date를 String으로 받지 않고 LocalDate를 바로 사용하는 방식으로 수정할 것이다.https://dev-de.tistory.com/77 3일차 미션 - 람다식에 대해람다식에 대해서는 이전에 타인의 코딩테스트 답변을 보고 공부 필요성을 느껴 간단히 알아본 적이 있었기에 그때 작성한 블로그 글을 보고 질문에 답변했다. 그러나 미션과 함께 제시된 [키워드]에 맞추어 디깅하다보니 람다식과 관련하여 여전히 잘 모르고 있던 내용들이 쏟아졌고 훨씬 깊이 있게 공부할 수 있었다.https://dev-de.tistory.com/78  소감 및 각오아직 많이 진행하지 않았지만 벌써 이번 인프런 워밍업 클럽 1기 스터디와 <자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]> 강의를 통해 새롭게 알고 배운 것이 많다. 지식적인 면 외에도 처음 인프런 워밍업 클럽 신청 시에 적어서 제출했던 '이번 스터디를 통해 기대하는 바'가 이루어지고 있다. 일상 유지를 어려워하며 취준을 위한 노력이 멈췄던 내게 정말로 다시 발을 내딛는 계기가 되어준다. 끝까지 강의와 미션 수행을 잘 따라가며 이 작은 레이스를 탈 없이 완주하고, 많은 것을 얻어가고 싶다.  

백엔드인프런워밍업클럽

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

01_네트워크와 API☾ Network데이터를 주고 받는 것(=택배)☾ IP각 컴퓨터의 고유 주소(=집 주소)256를 넘지 않는 4개의 숫자로 이루어짐ex. 대한시 민국구 서울동☾ Domain NameIP는 외우기 어려우니까 외우기 쉽게 별칭을 달아준 것ex. 빨간집☾ port number컴퓨터에서 돌아가는 여러 프로그램 중 한 프로그램을 특정하는 것ex. 홍길동☾ HTTP컴퓨터 간의 데이터를 주고 받는 표준(=운송장)ex. 내놓아라 파란집 둘째, 빨간포션 2개HTTP 요청GET /portion?color=red&count=2 Host: spring.com:3000 HTTP method(GET) : HTTP 요청을 받는 컴퓨터에게 요구하는 행위(데이터를 달라)path(/portion) : HTTP 요청을 받는 컴퓨터에게 원하는 자원Query(?color=red&count=2) : 자원을 요구할 때 필요한 조건Host : HTTP 요청을 받는 컴퓨터와 프로그램 정보POST /oak/leather Host: spring.com:3000 오크가죽정보 HTTP method(POST) : HTTP 요청을 받는 컴퓨터에게 요구하는 행위(데이터 저장해라)path(/oak/leather) : HTTP 요청을 받는 컴퓨터에게 원하는 자원Body(오크가죽정보) : 실제 저장할 정보Host : HTTP 요청을 받는 컴퓨터와 프로그램 정보정보를 보내는 2가지 방법Query : GET, DELETE에서 사용body : POST, PUT에서 사용HTTP 응답HTTP/1.1 200 OK Content-Type: application/json { "name":"A", "age":null } <aside> 💡 첫째줄 - 상태코드 여러줄 - 헤더 (한 줄 띄기) 여러줄 - 바디</aside>상태코드200 OK : 정상적으로 수행300 Moved Permanently : 다른 곳으로 옮겨가라404 Not Found : 요청을 찾을 수 없다500 Internal Server Error : 내부에 문제가 생김☾ API(Application Programming Interface)정해진 약속을 하여 특정 기능을 수행하는 것<aside> 💡 첫째줄 - Method path Query여러줄 - 헤더(여러 줄 가능)(한 줄 띄기)여러줄 - 바디(여러 줄 가능)</aside>☾ URL(Uniform Resource Locator)<http://spring.com:3000/portion?color=red&count=2> 주소창http : 사용하고 있는 프로토콜spring.com:3000 : 도메인 이름. 포트, 도메인 이름은 IP로 대체 가능portion : pathcolor=red&count=2 : 쿼리. 추가 정보02_GET APIQuery를 사용하여 데이터 요청☾ 덧셈 API 명세서HTTP Method HTTP Path Query(key, value) API의 반환 결과 GET /add int number1, int number2 int - 두 숫자의 덧셈 결과☾ @RequestParamcontroller/calculator/CalculatorControllerpackage com.group.libraryapp.controller.calculator; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; // @RestController : 주어진 클래스를 Controller(API의 진입 지점)으로 만들어 준다. API를 개발하려고 하는 클래스에 작성. 이 어노테이션이 있어야 클래스 안에 함수를 만들고 API 호출됐을 때 이 함수로 연결 @RestController public class CalculatorController { // @GetMapping("/add") : GET /add. 아래 함수를 HTTP Method가 GET이고 HTTP path가 /add인 API로 지정한다. @GetMapping("/add") public int addTwoNumbers(@RequestParam int number1, @RequestParam int number2) { // @RequestParam : Query를 통해서 넘어온 데이터를 함수 파라미터에 넣을 때 사용 return number1 + number2; } } @RequestParam 문제점 : Query가 늘어나면 함수의 파라미터도 길어짐☾ DTO해결책 : 객체를 받아서 사용dto/calculator/request/CalculatorAddRequestpackage com.group.libraryapp.dto.calculator.request; public class CalculatorAddRequest { private final int number1; private final int number2; public CalculatorAddRequest(int number1, int number2) { this.number1 = number1; this.number2 = number2; } public int getNumber1() { return number1; } public int getNumber2() { return number2; } } controller/calculator/CalculatorControllerpackage com.group.libraryapp.controller.calculator; import com.group.libraryapp.dto.calculator.request.CalculatorAddRequest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; // @RestController : 주어진 클래스를 Controller(API의 진입 지점)으로 만들어 준다. API를 개발하려고 하는 클래스에 작성. 이 어노테이션이 있어야 클래스 안에 함수를 만들고 API 호출됐을 때 이 함수로 연결 @RestController public class CalculatorController { // @GetMapping("/add") : GET /add. 아래 함수를 HTTP Method가 GET이고 HTTP path가 /add인 API로 지정한다. @GetMapping("/add") public int addTwoNumbers(CalculatorAddRequest request) { // API 호출될 때 주어진 Query가 이 객체에 있는 값에 들어가게 됨 return request.getNumber1() + request.getNumber2(); } }  DTO(Data Transfer Object) : 정보를 전달하는 역할의 객체03_POST APIHTTP body를 사용하여 데이터 받음JSON(JavaScript Object Notation)객체 표기법HTTP body에서 사용됨{ "key": value } ☾ 곱셈 API 명세서HTTP Method HTTP Path HTTP Body API의 반환 결과 POST /multiply { “number1”:숫자, “number2”:숫자 } 숫자(곱셈 결과)☾ 코드로 구현dto/calculator/request/CalculatorMultiplyRequestpackage com.group.libraryapp.dto.calculator.request; public class CalculatorMultiplyRequest { private int number1; private int number2; public int getNumber1() { return number1; } public int getNumber2() { return number2; } } controller/calculator/CalculatorControllerpackage com.group.libraryapp.controller.calculator; import com.group.libraryapp.dto.calculator.request.CalculatorAddRequest; import com.group.libraryapp.dto.calculator.request.CalculatorMultiplyRequest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; // @RestController : 주어진 클래스를 Controller(API의 진입 지점)으로 만들어 준다. API를 개발하려고 하는 클래스에 작성. 이 어노테이션이 있어야 클래스 안에 함수를 만들고 API 호출됐을 때 이 함수로 연결 @RestController public class CalculatorController { @PostMapping("/multiply") // POST /multiply public int multiplyTwoNumbers(@RequestBody CalculatorMultiplyRequest request) { // @RequestBody : POST API에서 HTTP body 안에 담긴 json을 DTO 객체로 변환시킬 수 있음. DTO 객체 앞에 작성. return request.getNumber1() *request.getNumber2(); } }  04_유저 생성 API☾ 도서관 사용자 등록 API 명세서HTTP Method HTTP Path HTTP Body(JSON) 결과 반환 POST /user { “name”: String(null 불가능), “age”: Integer } x (HTTP 상태코드 200 OK면 충분)☾ POST API 구현dto/user/request/UserCreateRequestpackage com.group.libraryapp.dto.user.request; public class UserCreateRequest { private String name; private Integer age; public String getName() { return name; } public Integer getAge() { return age; } } domain/user/Userpackage com.group.libraryapp.domain.user; // saveUser API가 사용돼서 유저가 저장되면 이 객체를 만들어서 실제 리스트에 저장 public class User { private String name; private Integer age; public User(String name, Integer age) { // API 통해서 들어온 name 값이 null이거나 비어있을 경우 예외 던짐 if (name == null || name.isBlank()) { throw new IllegalArgumentException(String.format("잘못된 name이 들어왔습니다.", name)); } this.name = name; this.age = age; } } controller/user/UserControllerpackage com.group.libraryapp.controller.user; import com.group.libraryapp.domain.user.User; import com.group.libraryapp.dto.user.request.UserCreateRequest; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; @RestController public class UserController { // Instance 생성 private final List<User> users = new ArrayList<>(); @PostMapping("/user") // 1. POST /user가 실행되면 public void saveUser(@RequestBody UserCreateRequest request) { // 2. 함수 실행. json 형식으로 HTTP Body에 name과 age가 들어오면 DTO로 값이 매핑 users.add(new User(request.getName(), request.getAge())); // 3. 유저 생성. 만들어진 유저 객체는 Users 리스트에 저장된다. } // 4. 200 OK 반환 } 05_유저 조회 API☾ 유저 조회 API 명세서HTTP Method HTTP Path Query 결과 반환 GET /user 없음 { “id”: Long, “name”: String(null 불가능), “age”: Integer }Id : 유저 별로 겹치지 않는 유일한 번호(Primary Key). 여기서는 저장할 때 List에 담겨 있는 유저의 순서를 id로 지정Controller에서 getter가 있는 객체를 반환하면 JSON이 된다.package com.group.libraryapp.domain.user; public class Fruit { private String name; private int price; public Fruit(String name, int price) { this.name = name; this.price = price; } public String getName() { return name; } public int getPrice() { return price; } } package com.group.libraryapp.controller.user; import com.group.libraryapp.domain.user.Fruit; import com.group.libraryapp.domain.user.User; import com.group.libraryapp.dto.user.request.UserCreateRequest; import com.group.libraryapp.dto.user.response.UserResponse; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; @RestController public class UserController { @GetMapping("/fruit") public Fruit fruit() { return new Fruit("바나나", 2000); } }  JSON 형식으로 반환☾ GET API 구현domain/user/Userpackage com.group.libraryapp.domain.user; // saveUser API가 사용돼서 유저가 저장되면 이 객체를 만들어서 실제 리스트에 저장 public class User { private String name; private Integer age; public User(String name, Integer age) { // API 통해서 들어온 name 값이 null이거나 비어있을 경우 예외 던짐 if (name == null || name.isBlank()) { throw new IllegalArgumentException(String.format("잘못된 name이 들어왔습니다.", name)); } this.name = name; this.age = age; } public String getName() { return name; } public Integer getAge() { return age; } } dto/user/response/UserResponsepackage com.group.libraryapp.dto.user.response; import com.group.libraryapp.domain.user.User; public class UserResponse { private long id; private String name; private Integer age; public UserResponse(long id, User user) { this.id = id; this.name = user.getName(); this.age = user.getAge(); } public long getId() { return id; } public String getName() { return name; } public Integer getAge() { return age; } } controller/user/UserControllerpackage com.group.libraryapp.controller.user; import com.group.libraryapp.domain.user.Fruit; import com.group.libraryapp.domain.user.User; import com.group.libraryapp.dto.user.request.UserCreateRequest; import com.group.libraryapp.dto.user.response.UserResponse; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; @RestController public class UserController { // Instance 생성 private final List<User> users = new ArrayList<>(); @PostMapping("/user") // 1. POST /user가 실행되면 public void saveUser(@RequestBody UserCreateRequest request) { // 2. 함수 실행. json 형식으로 HTTP Body에 name과 age가 들어오면 DTO로 값이 매핑 users.add(new User(request.getName(), request.getAge())); // 3. 유저 생성. 만들어진 유저 객체는 Users 리스트에 저장된다. } // 4. 200 OK 반환 @GetMapping("/user") public List<UserResponse> getUsers() { // UserResponse 반환 List<UserResponse> responses = new ArrayList<>(); // 빈 UserResponse 리스트 생성 for (int i = 0; i < users.size(); i++) { responses.add(new UserResponse(i + 1, users.get(i))); // 우리가 갖고 있는 List<User> users를 userResponse로 변환 } return responses; } } 현재 API의 문제점서버 재시작하면 데이터 사라짐유저 정보가 메모리에서만 유지되고 있기 때문  일주일 간의 학습 내용에 대한 간단한 회고를 작성해 주세요.API 제작을 어느 정도 알고 있다고 생각했는데 직접 해보니 아직 부족하다는 생각이 들었다. 복습 시간을 더 가져야겠다고 생각했다. 초반부에는 내용 정리를 꾸준히 하다가 점차 미루게 됐다. 주말에 남은 내용을 정리하고 다음주부터는 다시 일정에 맞게 내용 정리를 해야겠다.  미션을 해결하는 과정을 요약해 주세요.강의에서 작성한 코드와 주석을 읽으면서 내용을 복습하고, 이를 바탕으로 미션을 해결했다.다른 사람이 작성한 코드도 함께 읽어보며 미션을 했다.  미션 해결에 대한 간단한 회고를 작성해 주세요.API 만드는 미션이 생각보다 쉽지 않았다. 우선 제출은 했지만 추후에 수정할 필요가 있을 것 같다.

장종원

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

인프런 워밍업 클럽 1기 첫번째 발자국을 찍으며..이 스터디를 시작하게 된 동기는 직접 찾은 것은 아니고 친구의 추천으로 시작하게 되었다.공부를 해보지 않았던 분야는 아니지만, 성격상 동기부여 될 것이 있으면 좀 더 공부를 열심히 할 수 있을 것 같다는 생각이 들었던 것 같다. 그리고 마침 오래되어 까먹기도 많이 한 것 같아 다시 한 번 상기하면 좋을 것 같았다.이번 스터디로 공부에 대한 마음을 다시 한 번 잡고, 계획적으로 공부하는 습관을 기르기에 좋을 것 같다는 생각에 열심히 해보려 첫번째 발자국을 남긴다.섹션 1. 생애 최초 API 만들기어노테이션마법같은 일(설정 등)을 자동으로 해줌@SpringBootApplication : 스프링을 실행시킬 때 필요한 다양한 설정들을 자동으로 해줌서버컴퓨터가 특정 기능을 수행해준다.그래서 컴퓨터 자체를 서버라고도 함서버에 요청을 할 땐 인터넷(네트워크)으로 하게 됨네트워크현실세계에는 컴퓨터별 고유 주소(ip)가 존재인터넷을 통해 데이터를 주고 받음port : 특정 port를 사용하는 프로그램은 반드시 하나Domain name : ip주소는 외우기 어려우니 ‘이름’을 쓰는것 ⇒ 이러한 체계를 DNS(Domain Name System)이라함HTTP(TyperText Transfer Protocol)데이터를 주고 받는 표준. protocol : 표준/약속 GET : HTTP Method, 요청을 받는 컴퓨터에게 데이터를 달라고하는 것POST : 요청을 받는 컴퓨터에게 요청하는 행위, 원하는 자원을 적어줌. 실제 저장할 정보가 포함됨, 행위와 자원은 HTTP 요청 전 약속되어있어야함HTTP 요청을 받는 컴퓨터와 프로그램 정보 Http Method + path + Query(GET) OR Body(POST)PUT : 데이터를 수정하라(Body) / DELETE : 데이터 삭제하라(Query)HTTP 요청 문법(첫줄) 메소드 패스 쿼리 + HTTP 버전(다음 줄) 헤더(여러줄 가능)(한줄띄고 그다음 줄) 바디(여러줄 가능)HTTP 응답정상 처리되었다면 200 OK(상태코드)를 보낸쪽에 보냄응답에는 추가 정보(바디)를 담을 수도 있음300 - 다른 곳으로 옮겨라, 404 - 요청한 것찾을 수 없다, 500 - 내부에 문제가 생겼음요청에 대한 응답을 제공(serve)한 컴퓨터가 바로 서버요청을 한 컴퓨터가 Client(고객)문법(첫줄) 상태코드(여러줄) - 헤더한 줄 띄기(여러 줄) - 바디API(Application Programming Interface : 규칙)정해진 약속을 하여 특정 기능을 수행하는 것클라이언트와 서버가 HTTP를 주고 받으며 기능을 동작하는데 정해진 규칙을 API라 함URL(Uniform Resource Locator)주소창@RestController이 클래스를 API의 진입지점으로 만들어 줌그 안에 메소드를 만들어서 그걸 API가 사용하게끔 만들어줄 수 있음@GetMappingapi의 GET@RequestParam쿼리라고 명시주어지는 쿼리를 함수 파라미터에 넣음@RequestParam을 제거하고 클래스로 대체할 수 있음DTO(Data Transfer Object) 역할을 한 것임 POST API => HTTP Body를 이용한다. 이 때 사용되는 문법이 "JSON"JSON(JavaScriptBojectNotation) : 객체 표기법{ “name” : “최태현”, “age” : 99, “dogs” : [”코코”, “초코”], “house” : { ”address” : “서울” } } 한 Controller Class에 여러 API 추가 가능@PostMapping 어노테이션 사용@RequestBody : HTTP Body로 들어오는 JSON을 객체로 변경해준다.이 때 객체의 필드이름과 JSON key의 이름이 같아야 함 Controller에서 getter가 있는 객체를 반환하면 JSON이 된다.public class Fruit { public String getName() { return name; } public long getPrice() { return price; } }이게 가능한 이유는 @RestController가 붙어있기에 가능하다. 섹션2. 생애 최초 Database 조작하기테이블 만들기crate table [테이블 이름] ( [필드1 이름] [타입] [부가조건], [필드2 이름] [타입] [부가조건], ... primary key([필드이름]) );MySQL 타입 - 정수타입tinyint : 1바이트 정수int : 4바이트 정수bigint : 8바이트 정수실수타입double : 8바이트 정수decimal(A, B) : 소수점을 B개 가지고 있는 전체 A자리수 실수Decimal(4,2) = 12.23문자열 타입char(A) : A글자가 들어갈 수 있는 문자열varchar(A) : 최대 A 글자가 들어갈 수 있는 문자열날짜/시간 타입date : 날짜, yyyy-MM-ddtime : 시간, HH:mm:ssdatetime : 날짜와 시간을 합친 타입, yyyy-MM-dd HH:mm:ss위의 SQL이 DDL(Data Definition Language)아래는 DML(Data Manipulation Language)조회 Queryselect * from fruit where id = 1 and price <= 2000;select * from fruit where id = 1 or price <= 2000;select * from fruit where price BETWEEN 1000 AND 2000;select * from fruit where name IN ('사과', '수박');select * from fruit where name NOT IN ('사과', '수박');업데이트 Queryupdate fruit set price = 1500 where name = '사과';where 조건을 주지 않고 실행할 수 있으나, 모든 경우를 모두 변경할 수 있으니 조심해야 함삭제 Querydelete from fruit where name = '사과';where 조건을 붙이지 않으면 모든 데이터가 삭제됨. 주의필요우리의 스프링 서버가 MySQL DB에 접근하게 하자application.yml 파일에 DB 관련 설정을 적어서 가능private final JdbcTemplate jdbcTemplate; public UserController(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; }jdbcTemplate을 이용해 SQL을 쓸 수 있다. 생성자를 만들어 jdbcTemplate을 파라미터로 넣으면, 자동으로 들어간다.jdbcTemplate.update() 는 INSERT/UPDATE/DELETE 쿼리에 모두 사용할 수 있다.첫 파라미터로 sql을 받고, ?를 대신할 값을 차례로 넣으면 된다.return jdbcTemplate.query(sql, new RowMapper<UserResponse>() { @Override public UserResponse mapRow(ResultSet rs, int rowNum) throws SQLException { long id = rs.getLong("id"); String name = rs.getString("name"); int age = rs.getInt("age"); return new UserResponse(id, name, age); } });RowMapper : SQL 쿼리결과를 <>안에 있는 타입으로 변경시켜주는 역할하는 함수람다를 사용해서 간단하게 변경할 수 있었음HTTP Method PUT/DELETEjdbcTemplate.update() 는 sql의 업데이트가 아니라 데이터에 변화가 있는걸 말함없는 유저를 업데이트/삭제하려 해도 200 OK가 나오는 게 문제!자바에선 Exception/Throw로 예외를 던져 처리할 수 있었음.스프링에서 매핑된 함수가 throw 에러를 하면 200 OK 대신 500 Internal Server Error가 나온다.⇒ 데이터 존재 여뷰를 확인하고 예외를 던지면 되겠다jdbcTemplate.query() 를 사용하면 반환값이 List로 감싸진다. 섹션3. 역할의 분리와 스프링 컨테이너Clean Code는 왜 중요한가?현업에서 코드를 읽고 조금 변경하거나 조금의 새 기능을 추가하는 일이 더 많다.그렇기에 코드를 읽는 것을 피할 수 없다. 잘 읽을 수 있도록 하는 능력을 키우는 것도 중요하다.내가 다른 사람의 코드를 읽듯이 다른 사람도 내 코드를 읽게되므로 나 또한 가독성이 좋은 코드를 작성하는 것도 중요하다.왜 한 Controller에서 모든 기능을 구현하면 안될까?<Clean Code>함수는 최대한 작게 만들고 한 가지 일만 수행하는 것이 좋다.클래스는 작아야하며 하나의 책임만을 가져야 한다.반대된 다면 문제가 될 이유함수를 동시에 여러 명이 수정할 수 없다그 함수를 읽고 이해하는 것이 어렵다함수의 일부분을 수정하더라도 함수 전체에 영향을 미칠 수 있어, 수정을 함부로 하기 어렵다.너무 큰 기능이므로 테스트하기 어렵다.종합적인 유지보수성이 매우 떨어진다.Controller의 함수 1개가 하고 있던 역할API 진입지점현재 유저가 있는지 확인 후 예외처리SQL을 사용하여 DB와 통신Controller - API, HTTP 관련 역할 담당, Service를 사용Service - 분기 처리, 로직 담당, Repository를 사용Repository - DB와의 접근 담당이러한 것을 Layered Architecture라고 한다. ※ 트러블슈팅강의내용은 spring boot 2.x버전과 java 11사용으로 시작되었으나, 강의 시작 기준 spring initializr 기준 spring boot 3.x 버전과 java 17 버전을 사용할 수 밖에 없었음spring boot 3.2.5 + java 17 버전 연동(?) 문제(기존 java-home이 java 11이었고, spring boot 3.x 버전부턴 java 17을 꼭 사용해야 해서 발생한 오류)intellij 프로젝트 구조에서 java version을 변경하고, 시스템 환경변수에서 java home을 17버전으로 변경하여 해결mysql workbench safe mode 해제참고 : https://blog.naver.com/kkson50/221251167091@RequestBody에 매핑되는 DTO는 왜 빈 생성자가 필요한가참고 : https://innu3368.tistory.com/181 과제1. 어노테이션을 사용하는 이유(효과)는 무엇일까?https://slime-feels-660.notion.site/acb06609050b490a8d1de99c6395e8dd?pvs=4지금까지 어노테이션들을 너무 자연스럽게 쓰다보니 왜 쓰는지나 개념적인 부분을 생각하지 않고 너무 편해서 기능만 알고 쓴 것 같았는데 조사하다보니 단순 어노테이션이라는 키워드 하나에도 공부할 수 있는 부분이 상당히 많고 깊었다.앞으로도 단순히 사용법만 알고 기능을 사용하기보다 왜? 라는 것에 초점을 맞춰 공부해야 한다는 생각이 들었다.과제2. API 만들기https://slime-feels-660.notion.site/14c2b5efc21c46cd9ec46124704b31ea?pvs=42-1, 2-2 과제를 할 때는 생각보다 금방 했는데, 2-3번 과제를 할 때 다 만들어놓고 해결되지 않는 것을 이해를 못했다.구글링을 통해 결국 이유를 찾았지만 쉽다 생각한 것에도 또 무언가 있었다. 얕게 공부하기보다 깊게 공부할 수 있도록 해야겠다는 마음을 다시 먹게 만들어 준 과제같았다. 과제3. 자바의 람다식은 왜 등장했을까? 람다식과 익명 클래스는 어떤 관계가 있을까? 람다식의 문법은 어떻게 될까?https://slime-feels-660.notion.site/742bd212b32e4830b6fea014dc70c443?pvs=4람다식을 사실 많이 쓰진 않은 것 같다. 익숙한 걸 쓴다 해야할까 쓰면 코드량이 줄고 여러 기능들이 추가되지만 자연스럽게 코딩을 하다보면 편한 방법을 쓰게 된다. 추가적으로 스터디를 해서 내 익숙한 코딩방법을 좋은 방법으로 교정하는 작업이 필요하겠다는 생각을 하게했다.마무리1주를 돌아보며 생각보다 시간이 부족하다. 발자국을 위해, 복습을 위해 내용을 노션에 적으면서 수강을 하니 이 정도 시간이 들겠지 하고 계획한 것보다 시간을 더 쓰게 됐었다. 시간이 있는 날은 여유가 있네 생각하고 바로 쉬는 것보다 조금 더 예습을 해두는 게 공부하기로 계획한 것을 밀리지 않고 계속 해낼 수 있을 것 같아 그렇게 해보려 한다.아, 그리고 실수로 5/3 특강을 날짜를 착각해서 시간을 놓치게 되었는데 너무 아쉽고 17일날에는 꼭 알람을 해놓고 들어야겠다.공부를 하며, 강의를 들으며 더 깊게 공부하고 싶은 것들이 종종 보였는데, 그런 것들도 키워드를 모아 시간을 내 공부하여 궁금한 것들을 채워나가야겠다. 

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

김동현

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

Section 1 - 생애 최초 API 만들기 Java를 공부하기 전에 알아두면 좋을 것들 #1 #2JVM: 자바 가상 머신, 컴파일된 코드를 읽고 실행JDK: JVM을 포함해 자바 컴파일러(javac), 자바 실행 도구, 라이브러리 등 다양한 개발 도구 제공 HTTP, APIHTTP(Hypertext Transfer Protocol): 웹 브라우저가 웹 페이지를 요청하고 서버가 그에 대한 응답을 주는 기본적인 통신 규약API(Application Programming Interface): 소프트웨어 간의 상호작용을 위한 인터페이스를 제공정리컴퓨터간의 통신은 HTTP라는 표준화된 방식HTTP 요청은 HTTP Method (GET, POST)와 Path (/portion) 가 핵심요청에서 데이터를 전달하기 위한 2가지 방법은 쿼리와 바디HTTP 응답은 상태 코드가 핵심클라이언트와 서버는 HTTP를 주고 받으며 기능을 동작하는데 이때 정해진 규칙을 APIGET API, POST APIGET API는 쿼리로, POST API는 바디에 담아 보냄.(무조건은아님)DTO를 만들어서 구현가능 이경우 @RequestParam 제거 !과제 2일차 Section 2 - 생애 최초 Database 조작하기DBDB 없이 만들면 메모리에만 저장됨 => 데이터가 다날아감DB => 데이터를 구조화 시켜 저장 MySQL 연동application.yml 만들기JdbcTemplate 사용직접 sql을 연동하지 않고 JPA만 사용했던 경험이 있다.sql 쿼리를 직접 사용해서 db에 접근가능함도 알음  Section 3 - 역할 분리 클린코드코드만 보고 의미 파악할 수 있게 함함수는 최대한 작게 만들고 한 가지 일만 수행클래스는 작아야 하고 하나의 책임만 가져야 함유지보수도 좋음Controller 3단 분리Controller 역할 - API의 진입 지점으로써 HTTP Body를 객체로 변환Service 역할 - 현재 유저가 있는지, 없는지 등을 확인하고 예외 처리(메인 로직 수행)Repository 역할 - SQL을 사용해 실제 DB와의 통신을 담당Layered Architecture 1주차 회고스터디 시작전 모든 미션과 과제를 수행하고자 했는데 첫번째 과제부터 놓쳐버렸다... 남은 것들은 꼭 다하겠다.오랜만에 스프링을 다시 하는데 당시에 바로 jpa를 바로 사용해서 db랑 연동을 했었는데 쿼리로 연동하는 것도 알게 되었음. 기초가 중요하다.Java에 아직 덜 익숙함도 느꼈음. Java 다형성 부분에 대해서 다시 복습해야겠다.남은 스터디 기간에도 집중해서 꼭 많은 것을 얻어가는 시간이 되어야겠다.

백엔드워밍업백엔드스터디

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

1주차 첫 번째 발자국 이번 주차에는 RESTful api 를 spring 에서 어떻게 사용하는지에 대해 중점적으로 배웠다. 수업내용을 위주로 정리해보자면. URL 및 api 표준데이터를 주고받는 표준 HTTP e.g)GET /portion?color=red&count=2 HOST:spring.com:3000 GET (HTTP Method) HTTP 를 요청하는 행위 Host:spring.com:3000 HTTP 요청을 받는 컴퓨터와 프로그램 정보 /portion => path 요청 자원 color=red&count 자원의 세부조건 & 추가조건 GET: 데이터를 달라, 쿼리 POST: 데이터를 저장하라, 바디 PUT: 데이터를 수정하라, 바디 DELETE: 데이터를 삭제하라, 쿼리  이 때 위와같이 서버와 클라이언트가 정한 규칙을 API 라고 한다.  Springanotaition@RestController 주어진 Class를 Controller 로 등록한다. Controller : API 입구 @GeMapping("/add"): 아래 함수를 HTTP Method 가 Get이고 HTTP path 가 /add 인 API 로 지정한다. @RequestParam 같은 이름을 가진 쿼리의 값이 들어온다 대문자 String, Integer => Null 표현 가능DB RDS => 데이터를 표처럼 구조화시켜 저장함 / MySql SQL => 표처럼 구조화된 데이터를 조회하는 언어 회고록이번 SQL 관련 restful 강의를 들으면서 느낀 점은,현재 실무에서는 ORM 혹은 SP 를 사용하면서 CRUD 행위를 하고 있다. 이 때 강의를 보면서 실제로 sql 날 것으로 적으면서 왜 ORM 을 사용하고, 자체적인 프레임워크가 존재하는지 다시 한번 깨달았고, sql injection 이라던지실제 업무 환경 혹은 코어쪽에서는 신경 쓸 부분이 엄청 많아보였다.   

미플

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

자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]1주차이 끝이 났다. 고민을 많이 하고 시작한 스터디였는데 무엇을 알고, 모르는지 확인함에 도움을 받고 있다. 무엇을 배웠나?강의는 교과서 같았다. 각 강의와 섹션마다 학습목표와 정리가 이뤄진다. 반복되는 과정을 통해 점진적으로 문제가 해결되는 과정을 배웠다. 서버개발자가 되기 위한 최소한의 이론을 다루고 실습을 먼저 시작했다. 간단한 기능으로 시작했던 애플리케이션에 요구사항이 추가되고 어떻게 계층화 아키텍처로 나눌 수 있을지 이야기하는 시간을 가졌다. 1일 차: 서버 개발을 위한 환경 설정 및 네트워크 기초스프링 프로젝트를 시작하는 방법어떻게 새로운 프로젝트를 시작할까?기존에 운영 중인 프로젝트에 투입 됐을 때 어떻게 시작할 수 있을까? 서버 개발자가 되기 위해 알아야 하는 기본적인 지식네트워크, IP, 도메인, 포트, HTTP 요청과 응답, 클라이언트 - 서버, API란 무엇인가  과제: 자바 어노테이션무의식 중에 많이 사용했지만 궁금해하지 않았다. 이전에는 어떻게 문제를 해결했는지 알 수 있었다. 2일 차: 첫 HTTP API 개발Spring Boot를 사용해 API 만들기 GET, POST웹 개발에 기본이되는 HTTP를 다룬다.GET은 쿼리를 사용해 조회에 사용되고, POST는 body를 사용해 생성에 주로 사용된다.   과제: API 실습 1, 2일 차를 제대로 이해하고 있는지 점검을 했다. 문제를 해결하는 데 시간이 오래 걸리지 않았지만 정리하는데 오랜 시간이 걸렸다.3일 차: 기본적인 데이터베이스 사용법디스크와 메모리의 차이, 데이터베이스(Database)는 왜 필요한가?SQL 사용, MySQL 다루기이전에 만들었던 기능들은 서버가 종료되면 데이터가 모두 사라졌다. 데이터를 계속 저장하기 위해서 데이터베이스를 사용하자.테이블 생성, 데이터 추가, 조회, 수정, 삭제 과제: 익명 클래스와 람다 4일 차: 데이터베이스를 사용해 만드는 API스프링 서버와 연결하여 데이터베이스 다루기, API 예외상황 다루기, 예외처리PUT, DELETE를 학습하고 수정데이터베이스와 통신해서 조회되는 데이터가 없으면 어떻게 에러를 반환할지 배운다.  5일 차: 클린코드의 개념과 첫 리팩터링좋은 코드는 왜 중요한가? 계층화 아키텍처(Layered Architecture)의 등장, 리팩터링Controller에 역할을 덜어주기 위해 리팩터링을 진행했다.역할을 나누고 왜 좋은 코드의 개념에 대해 배웠다. 마무리스터디 시작 전에 강의를 듣고 정리해 둬서 다행이다. 주말을 앞두고 몸도 마음도 지쳐서 과제를 제출하지 못할 뻔했다. 문제가 발생했던 이유는 전 날 푹 잠들지 못해서 발생했다. 단거리가 아니라 장거리 달리기라 생각하고 컨디션 관리에 더욱 신경 써야겠다. 다음 주도 미루지 않고 마무리했으면 좋겠다.

백엔드인프런워밍업클럽

최강현

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

강의 수강,과제 수행하면서 생겼던 궁금증을 해결하는 과정을 위주로 블로그 글을 작성하려고 합니다. 강의 수강 1일차 - OT 인프런 워밍업 클럽 스터디 및 일정 소개 코치님과 구글 밋을 통해 온라인 OT를 진행하였습니다.간단한 스터디 과정 및 일정에 대해 소개 해줬고, 코치님이 이거까지 알아야하나? 라는 주제로 의견을 공유해주셨습니다. 2일차 - 서버 개발을 위한 환경 설정 및 네트워크 기초 (1강 ~ 5강)2일차에는 서버, 네트워크, HTTP, API를 배웠다.API가 무엇인지 잘 몰랐는데 Input을 주면 OutPut이 나오는 함수와 비슷하다는걸 알게 되었다. API가 무엇인지 와닿지 않았는데 감을 잡을 수 있었다3일차 - 첫 HTTP API 개발 (6강 ~ 10강)GET API와 POST API를 개발해봤다.GET 요청은 쿼리를 통해서 요청을 주고 POST 요청은 body를 통해 요청을 주는데@RequestParam을 통해 주어지는 쿼리를 함수 파라미터에 넣는다.파라미터 대신에 DTO 객체를 넣어서 쿼리를 받을 수 있다public class CalculatorAddRequest{ private final int number1; private final int number2; public CalculatorAddRequest(int number1, int number2) { this.number1 = number1; this.number2 = number2; } public int getNumber1() { return number1; } public int getNumber2() { return number2; } }  post 요청은 body로 들어오는 JSON을 DTO로 바꿔주기 위해 @RequestBody를 사용해야하는데@RequestBody를 사용하면 DTO 객체에 생성자를 만들지 않아도 괜찮은데 이 이유가 궁금했다public class CalculatorMultiplyRequest { private int number1; private int number2; public int getNUmber1(){ return number1 } public int getNumber2(){ return number2; } }다음과 같은 이유를 찾을 수 있었다.Spring의 동작 방식: @RequestBody 어노테이션이 적용된 메서드 파라미터에는 HTTP 요청의 본문을 기반으로 객체가 생성됩니다. Spring은 이를 위해 클래스의 기본 생성자를 호출하여 빈 객체를 생성하고, 요청의 본문에서 추출한 데이터를 객체에 설정합니다.4일차 - 기본적인 데이터베이스 사용법 (11강 ~ 13강) MySQL의 사용법을 배웠다DDL(데이터 정의어) - CREATE, ALTER, DROPDML(데이터 조작어) - INSERT, UPDATE, SELECT, DELETE이 2개를 사용해서 데이터를 DB에 생성, 조회, 갱신, 삭제하고5일차 - 데이터베이스를 사용해 만드는 API (14강 ~ 16강)이 강의를 통해 사람이 직접 DB에 접속해서 DB를 조작하는게 아닌 Spring 서버가 MySQL DB에 접근해서 DB를 조작하게 API를 만들었다. 6일차 - 클린코드의 개념과 첫 리팩토링(17강~ 18강) 이 강의를 통해 저번 강의를 통해 만든 컨트롤러 클래스를 3개의 클래스로 쪼개 보았다.Controller 클래스 - API의 진입 지점으로써 HTTP Body를 객체로 변환Service 클래스 - 분기처리 로직Repository 클래스 - SQL을 사용해 실제 DB와의 통신을 담당 컨트롤러 클래스 작성 시 JdbcTemplate 객체를 생성하는데 new 키워드를 사용하지 않고 생성했다이게 어떻게 가능한지 궁금해서 찾아보니스프링에서는 보통 dependency injection을 사용하여 객체를 주입합니다. 이 코드에서도 JdbcTemplate jdbcTemplate는 생성자를 통해 주입됩니다.생성자 public UserController(JdbcTemplate jdbcTemplate)에서 JdbcTemplate 객체가 주입됩니다. Spring이 UserController를 생성할 때, 필요한 JdbcTemplate 객체를 찾아서 자동으로 주입해줍니다. 이것이 Spring의 IoC (Inversion of Control) 컨셉입니다.따라서 new 키워드를 사용하여 직접 객체를 생성할 필요가 없고, Spring이 해당 객체를 관리하고 주입해줍니다.미션1일차어노테이션을 미리 정의 해두면 @RequestParam 같은 한 단어만 작성해주면 스프링이 알아서 GET 요청의 쿼리를 메서드의 파라미터로 바꿔준다.어노테이션은 이런 마법 같은 일을 해준다.  2일차문제1Controller에서 getter 메서드가 있는 객체를 반환하면 반환 값이 JSON으로 반환 한다! CalculatorResponse.java public class CalculatorResponse { private int add; private int minus; private int multiply; public CalculatorResponse(int num1, int num2) { this.add = num1 + num2; this.minus = num1 - num2; this.multiply = num1 * num2; } public int getAdd() { return add; } public int getMinus() { return minus; } public int getMultiply() { return multiply; } }  ExController.java@RestController public class ExController { @GetMapping("/api/v1/calc") public CalculatorResponse plusMinusMultiplyCalculator(@RequestParam int num1, int num2) { return new CalculatorResponse(num1, num2); } } Response문제2ExController.java@RestController public class ExController { @GetMapping("/api/v1/day-of-the-week") public DateResponse dayOfTheWeek(@RequestParam String date) { return new DateResponse(date); } } DataResponse.java public class DateResponse { private Enum<DayOfWeek> dayOfTheWeek; public DateResponse(String date) { LocalDate parsed = LocalDate.parse(date); this.dayOfTheWeek = parsed.getDayOfWeek(); } public Enum<DayOfWeek> getDayOfTheWeek() { return dayOfTheWeek; } }  GET 메서드에서 파라미터의 value의 타입은 문자열로 들어오므로 DateResponse의 생성자에서 LocalDate.parse()를 통해 문자열을 LocalDate로 바꿔주었다. 문제3 ExController.java@RestController public class ExController { @PostMapping("/api/v1/multi-number-sum") public int multiNumberSum(@RequestBody CalculatorMultiNumber request) { int[] numbers = request.getNumbers(); int sum = Arrays.stream(numbers).sum(); return sum; } } CalculatorMultiNumber.javapublic class CalculatorMultiNumber { int[] numbers = new int[5]; public int[] getNumbers() { return numbers; } } ResponseResponse크기가 5개인 배열을 선언 하고 body에 길이가 6개를 리스트 넣고 요청해도 6개의 값을 반환한 값을 돌려준다.왜 그런지 이유를 찾고 싶었는데 못찾았다 ㅠㅠ 3일차람다식은 익명 클래스를 좀 더 쉽게 쓸 수 있게 자바8부터 도입된 개념이다. OOP인 자바는 람다식의 도입으로 함수형 프로그래밍도 가능해졌다하루에 몰아서 적으려니까 너무 힘들었다 다음주 회고록은 따로 초고를 그날 그날 적어놔야겠다..이 블로그에 올린 코드와 문제의 출처는 https://www.inflearn.com/course/%EC%9E%90%EB%B0%94-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%84%9C%EB%B2%84%EA%B0%9C%EB%B0%9C-%EC%98%AC%EC%9D%B8%EC%9B%90입니다  

백엔드java인프런워밍업클럽스프링spring자바

13blueberry

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

1주차 발자국 배웠던 것1주차에서는 기본적인 네트워크의 구성과 API, Database, 좋은 코드와 controller에 대해서 학습하였다. 좋았던 것 백엔드 스터디를 신청하게 된 이유는 간단하다. 서버 배포를 해보고 싶었기 때문이다. 본격적인 강의를 듣는 것은 처음인데, 큰 구조를 먼저 따로 공부하지 않고 필요한 것부터 배워도 강의 구성을 워낙 잘 해주셔서 나무만 보는 것이 아니라 큰 숲부터 볼 수 있어서 좋았다.  간단한 프로젝트를 위해 과거에 장고 프레임워크를 벼락치기한 경험이 있었고, 그때 간단하게 당장은 이렇다 하고 넘어간 통신 부분에 대해 자세히 배울 수 있어서 좋았다. 확실히 혼자 벼락치기 하는 상황에서 영어를 만나다 보니 급한 마음이 영향을 주어서 결국 애매하게 아는 상태가 되거나, 이도 저도 아닌 상태로 프로젝트를 엉성하게 마무리 한 경험이 있었다. 하지만 비유를 통해 잘 설명해 주시니 그동안 애매하게 알게 되면서 가진 의문점 등을 모두 해결할 수 있었다.  힘들었던 것이 커리큘럼을 시작하려고 급하게 자바 벼락치기를 해서 그런가 아직 이해하는데 오랜 시간이 걸린다. 모르는 것은 검색해 가면서 진행하지만 스터디에 많은 시간 소요가 들어서 일정 측면에서 부담스러울 때가 있다. 개인적인 문제이기에 이를 극복해 나가려면 주말이나 공휴일을 활용하는 것이 중요해 보인다. 다행히 2주차에는 월요일 진도가 없어서, 복습의 기회로 삼으면 좋을 것 같다. 과제 1질문 1. 어노테이션을 사용하는 이유 (효과) 는 무엇일까?질문 2. 나만의 어노테이션을 어떻게 만들 수 있을까?어노테이션의 사용 이유의 핵심은 간소화에 따른 오류 최소화라 생각했다. 간결한 코드로 수동으로 오랜 시간을 소요할 수 있는 작업을 간단하게 만들어주고, 그 과정에서 오류까지도 잡아줄 수 있다. 또한 어노테이션의 특성 상 자바 프레임워크들은 특정 기능을 쉽게 구현할 수 있었다.나만의 어노테이션은 @interface키워드를 사용하여 정의할 수 있다.과제 2 API 명세를 통해 GET, POST API 만들기여러 블로그글과 gpt를 참고해서 구현해냈다. 확실히 스스로 하나의 예시를 만들어 내니까 이해가 더 잘 되었다. 코드 작성보다 아직 폴더 구조를 이해하는 것이 더 힘들었다. 여러 번 코드가 의미하는 바를 따라가며 구조 자체를 먼저 이해하려고 했던 기억이 남아 있다.과제 3질문 1. 자바의 람다식은 왜 등장했을까?질문 2. 람다식과 익명 클래스는 어떤 관계가 있을까?람다도 결국 코드 간결화를 위해 도입되었다. 또한 람다식은 익명 클래스를 더 간결하게 표현하는 방법이라 볼 수 있기에, 람다식 자체는 결국 익명 클래스다. 

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

정진서

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

첫 걸음인프런 워밍업 클럽 1기 BE에서 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지] 강의를 수강하며 작성하였다.강의 학습HTTP와 APIHTTP란 다른 컴퓨터로 데이터를 보내기 위한 데이터 표준이다.API는 정해진 약속에 따라 특정 기능을 수행하는 코드이다. HTTP Method 중 하나인 GET은 쿼리를 통해 정보를 보낸 후 데이터를 요청한다.→ /add?number1=10&number2=20 Controller는 API가 실행되는 입구와 같다.@GetMapping("/add") public int addTwoNumbers(@RequestParam int number1, @RequestParam int number2) { return number1 + number2; } GET 방식에서 매개변수를 각각 하나씩 입력받을 때에는 @RequestParam을 사용하여 변수에 쿼리의 값을 넣는다.만약 매개변수가 많을 경우, DTO 객체로 만들어 관리한다.@Getter public class CalculatorAddRequest { private final int number1; private final int number2; public CalculatorAddRequest(int number1, int number2) { this.number1 = number1; this.number2 = number2; } }GET 방식의 DTO 객체는 반드시 생성자를 포함해야 한다. DTO 객체를 이용한 Controller는 다음과 같다.@GetMapping("/add") public int addTwoNumbers(CalculatorAddRequest request) { return request.getNumber1() + request.getNumber2(); }DTO를 이용할 때는 @RequestParam을 제거해야 하며 변수를 객체로 감싸 불러오기 때문에 getter를 사용해야 한다. 마찬가지로 HTTP Method인 POST는 Body를 통해 정보를 보낸다.객체 표기법인 JSON을 사용하고, List를 사용하거나 JSON 안에 JSON을 사용하는 것도 가능하다.POST 방식에서 DTO를 이용한 Controller는 다음과 같다.@PostMapping("/multiply") public int multiplyTwoNumbers(@RequestBody CalculatorMultiplyRequest request) { return request.getNumber1() * request.getNumber2(); } @RequestBody를 사용하여 HTTP Body로 들어오는 JSON을 DTO 객체 형태로 변환한다.GET 요청의 @RequestParam과는 달리 DTO 객체를 사용해도 Annotaion을 생략할 수 없다. GET 요청과 달리 POST 요청은 생성자가 필요하지 않다. Domain(Entity)와 DTO의 차이DTO는 계층 간 데이터 교환을 위해 사용된다. 반면, Domain은 DB 테이블과 매핑되어 데이터를 저장하거나 관리하는 실제 비즈니스 도메인을 표현한다. DTO는 단순히 어떤 데이터로 통신할 것인지 정의하고, 상세한 정의는 Domain에서 한다. Spring에서 Database 사용하기private final JdbcTemplate jdbcTemplate; public UserController(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @PostMapping("/user") public void saveUser(@RequestBody UserCreateRequest request) { String sql = "insert into user (name, age) values (?, ?)"; jdbcTemplate.update(sql, request.getName(), request.getAge()); }JdbcTemplate를 이용하면 Spring에 SQL을 전달할 수 있다.SQL문을 작성하여 문자열 변수로 저장하는데, 값이 들어갈 부분에 ?를 사용하면 데이터를 넣을 수 있다.  과제 수행1일차 과제 : JAVA Annotation어노테이션은 실제 데이터가 아닌 메타데이터로써 클래스와 메서드에 추가하여 다양한 기능을 부여한다.반복적인 코드 작성을 줄일 수 있어 코드량이 감소하고, 코드의 역할을 명확히 지정할 수 있어 유지보수가 용이하다는 장점이 있다.사용자가 원하는 기능을 수행하는 커스텀 어노테이션을 만드는 방법도 알아보았다. 2일차 과제 : GET & POST API날짜를 받는 API를 구현할 때, String으로 날짜를 받은 후 LocalDate로 변환하는 과정을 거쳤다.그러나, 스프링 부트 2버전에서는 @DateTimeFormat을 사용해 LocalDate를 바로 받을 수 있다고 한다.3버전대에서는 어노테이션 없이 LocalDate를 바로 받을 수 있다. 3일차 과제 : 람다식과 익명 클래스익명 클래스란 이미 정의되어 있는 부모 클래스의 자원을 일회성으로 재정의한 클래스이며, 자식 클래스를 정의할 필요 없이 객체화가 가능하다.람다란 자바의 인터페이스를 익명 클래스로 구현한 익명 구현 객체를 짧게 표현한 것이다. 메서드 타입과 이름, 매개변수 타입, 중괄호, return문을 생략하고 화살표 기호를 넣는다. 4일차 과제 : 과일 가게 API 만들기enum 타입을 통해 과일의 판매 여부를 ‘SOLD’, ‘NOT_SOLD’의 두 가지 상태로 구분하였다.COALESCE()를 사용하여 팔린 과일 혹은 팔리지 않은 과일이 존재하지 않을 경우, NULL이 아닌 0으로 표시되도록 하였다.쿼리의 결과가 하나이므로 queryForObject를 이용해 SQL의 결과를 직접 long 타입의 객체로 매핑하였다.  느낀 점Spring의 기초를 복습하면서 ‘이건 왜 이렇게 쓰일까’와 같은 질문을 던지며 천천히 학습할 수 있었다.특히, 인프런의 각 강의에 있는 질문 게시판을 활용하였다.강의를 들으며 의문이 든 부분들은 이미 선배 러너들이 질문을 했고, 강의자 분께서 자세하게 답변을 달아 주셨기 때문에 편하게 학습할 수 있었다. 매일 과제가 있지만 하루에 학습할 양을 안내해 주는 진도표가 존재하고, 하루치 공부 양이 그렇게 많지 않았기 때문에 오히려 꾸준하게 하루 공부를 진행할 수 있어 좋았다.일주일을 돌아보며 작성하는 발자국은 그동안 배운 내용을 정리하고, 느낀 점을 회고할 수 있어 좋은 방법인 것 같다.강의를 들으며 개조식으로 정리한 내용을 글로 풀어 쓰니 내가 얼만큼 이해하고 있는지 확인할 수도 있다.

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

변지섭

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

이번 학기 취준을 시작하면서 자바를 공부하기 시작했습니다. 시간이 된다면 스프링도 공부해봐야겠다는 가벼운 마음으로 스터디를 신청했는데, 자바 + 스프링이 만만한 친구들이 아니어서 마음을 고쳐먹었습니다. 학습 내용 요약:Section 0: 스프링으로 프로젝트를 시작하기 위한 환경 세팅 방법을 배웁니다.1. 환경 세팅 과정멘토님(태현님)께서 정말 상세하게 알려주시기 때문에 환경 설정에 큰 어려움은 없었습니다.다만, 저는 MySQL을 이전에 설치했던 적이 있어서 설치 과정에 오류를 겪었습니다. (M1 에어 기준)다른 분들께 도움이 되실까 싶어 해결 방법을 남깁니다. "[MySQL] Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)" 이 오류를 겪었는데요, MySQL 서버와 소켓으로 통신이 잘 안 된다는 얘기입니다.저는 /opt/homebrew/var/sql에 이전 데이터가 남아있어서 충돌이 발생했던 것 같습니다.해결 순서는1) brew uninstall mysql로 기존 MySQL을 삭제2) rm -rf /opt/homebrew/var/mysql로 남은 파일을 제거3) brew install mysql로 MySQL을 재설치4) 설치 후, cd /opt/homebrew/Cellar/mysql/{mysql 버전}/support-files (경로 이동)5) ./mysql.server start로 서버를 실행입니다.출처: [https://velog.io/@shyuuuuni/MySQL-Cant-connect-to-local-MySQL-server-through-socket-tmpmysql.sock-2-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0-%EC%82%AC%EB%A1%80] Section 1:생애 최초 API 만들기(GET, POST API)스프링 부트를 처음부터 시작하는 방법과 서버 개발의 기본이 되는 네트워크 기본 지식, 그리고 GET, POST API를 작성하는 방법을 배웠습니다.1. 라이브러리 vs. 프레임워크- 기존에 라이브러리가 작은 범위, 프레임워크는 좀 더 큰 범위구나 생각하고 있었는데, 강의에서"라이브러리는 미리 만들어진 기능을 (클래스, 메서드 등) 가져다 사용하는 것이고, 프레임워크는 다 준비된 코드에 필요한 정보만 넣어 사용하는 것이다. 즉, 라이브러리를 활용해 프로그램을 작성하는 것은, 김치를 사서 김치찌개를 만드는 것이고, 프레임워크를 활용해 프로그램을 만드는 것은, 원데이 클래스에 가서 선생님이 시키는 대로 김치찌개를 만드는 것이다."는 얘기를 듣고 차이점이 이해되었습니다. 예를 들면, java.lang '패키지'의 System.out.println을 사용하는 것이지, java.lang 프레임워크의 println을 쓰는 게 아닙니다. 2. GET, POST API- 기존에 파이썬으로 몇 번 서버를 작성한 적이 있어 할만하다고 생각했는데, 자바와 스프링으로 API를 구현하면서 에러를 많이 만났습니다.1) private 필드를 사용해야 했는데, getter가 없어서 406 에러가 발생2) 파라미터를 받는 생성자만 정의해두고, 기본 생성자는 정의하지 않아서, 배열을 정상적으로 읽어오지 못하는 문제를 만났습니다. 그리고, 멘토님께서 주신 과제를 수행하면서 스프링보다 자바가 부족하다는 것을 느꼈습니다. 자바 공부를 더 열심히 해야겠습니다. Section 2:생애 최초 Database 조작하기JDBC 템플릿을 활용해 DB를 직접 조작해보았습니다. 파이썬으로 DB를 조작하는 것과 비슷해서 이해가 잘 됐습니다.1. 에러 핸들링업데이트, 삭제 API의 경우 값이 업데이트 되지 않았거나, 삭제되지 않은 경우에도 Status 200을 하지 않도록 에러 핸들링을 한 부분이 기억에 남습니다. 2. 람다식과 익명 클래스 차이람다식과 익명 클래스의 차이를 정리하다 보니, 그리 만만한 주제가 아니라는 생각이 들었습니다. 오라클에서 제공하는 자바 튜토리얼에는 내포 클래스(Nested Classes)라는 주제로 Local Classes부터 설명이 되어 있습니다. Local Classes -> Anonymous Classes -> Lambda Expressions 순으로 코드가 간단해지고, 담을 수 있는 정보의 양도 줄어듭니다. 하지만, 세 경우 모두 새로운 클래스를 만드는 것보다 코드가 간단해진다는 공통점이 있습니다.출처: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html Section 3:역할의 분리와 스프링 컨테이너좋은 코드는 왜 중요한지, Controller를 Controller / Service / Repository 로 3단 분리하는 과정에 대해 배우고 스프링 컨테이너에 대한 기본 지식을 배웠습니다. 1. 좋은 코드(Clean Code)와 역할의 분리사용자 요청을 통해 들어온 HTTP 바디 및 헤더를 처리하는 Controller부분과, DB 서버와 통신하며 값을 저장, 조회, 수정, 삭제하는 Repository, Controller와 Repository를 이어주는 Service까지 역할에 따라 기능이 분리되면서, 코드가 더 간단해지는 것을 볼 수 있었습니다. 2. 스프링 컨테이너 & 스프링 빈스프링 서버를 시작하면 컨테이너라는 클래스 저장소를 시작하게 되는데, 이 안에는 스프링 빈이라고 하는 클래스들이 등록되고, 스프링 컨테이너가 스프링 빈 간의 의존성을 관리해준다는 내용을 배웠습니다.그런데, 한 가지 궁금한 점이 있었습니다. 서버가 시작되고 스프링 컨테이너가 시작된다는데, 왜 컨테이너 안에 서버가 들어가는 게 아니고, 서버 안에 컨테이너가 들어가는지 궁금했습니다.  스프링 컨테이너와 도커 컨테이너가 헷갈려서 검색해보았는데, 둘은 이름은 같지만 아예 다른 개념입니다. 스프링에서 얘기하는 컨테이너는 주로 자바의 객체의 라이프사이클을 관리하는 기능을 합니다. 한편, 도커의 컨테이너는 실행 환경을 가상화하는 방법으로 이름만 같습니다. 그러니까 컨테이너 안에 서버가 들어간다고 할 때는, 도커의 컨테이너를 이야기 하는 것이고, 스프링 서버가 시작돼서 스프링 컨테이너가 시작했다고 하는 것은 서버 내부에 자바 객체를 관리하는 컨테이너가 시작했다는 이야기입니다. 3. IoC and DI수업 시간에 스프링 빈을 이용하면, 사용자는 코드의 변경이 거의 없이 스프링 컨테이너가 필요한 스프링 빈을 찾아서 인스턴스화한다는 내용을 배웠고, 이러한 방식을 IoC(Inversion of Control, 제어의 역전), DI(Dependency Injection, 의존성 주입) 라는 개념을 배웠습니다. IoC, DI 개념이 조금 덜 와 닿았는데, 아래의 글을 읽으면서 조금 이해가 되었습니다. https://velog.io/@ohzzi/Spring-DIIoC-IoC-DI-%EA%B7%B8%EA%B2%8C-%EB%AD%94%EB%8D%B0 글의 내용을 요약하자면 DI는 "패턴"이고, IoC는 프로그램의 제어권을 역전시키는 "개념"입니다. IoC를 구현하기 위해 DI를 사용할 수 있다.로 정리하는 것이 좋은 것 같습니다. 수업 시간에 배운 생성자를 사용하는 방식(Constructor Injection, 스프링 권장), Setter를 사용하는 방식(Setter Injection), 인터페이스를 주입하는 방식(Interface Injection)이 있습니다. 이 중 생성자와 Setter를 이용하는 방식은 수업 때 다루었지만, 인터페이스를 이용하는 방식은 처음 보았습니다. 하지만 세 가지 방식 모두 A라는 객체의 의존성을 외부에서 만들어 넣는(Dependency를 Injection) 하는 방식입니다.IoC, DI를 활용하면 코드가 더 깔끔해지고, 클래스의 테스트가 쉬워진다고 하는데, 테스트 를 공부한 후에, 이게 어떤 의미인지 직접 확인해봐야겠습니다. 스터디에 임하는 자세:스프링을 공부한지 이제 1주차이지만, 스프링이 간단한 프레임워크가 아니라는 것이 느껴졌습니다. 강의를 들으면 들을수록, 스터디 이후에도 계속 공부해야 겠구나 잘하려면 더 많은 시간을 들여야겠다는 생각이 들었습니다. 그리고 자바를 아직 너무 몰라서, 학교 수업 시간에 배운 내용 뿐만 아니라, 프로그램도 더 많이 작성해보고, 알고리즘 문제도 많이 풀어봐야겠습니다.

강예인

[인프런 워밍업 클럽_1기 BE] 첫번째 발자국

강의 수강일주일 동안 학습했던 내용IntelliJ설치, Spring 환경 설정, MySQL 설치개발을 위한 기본적인 환경설정을 해주었다. 네트워크 기초API 통신을 위한 기본적인 API동작 방식에 대해 학습했다.데이터베이스데이터베이스 세팅과 CRUD에 대해 학습했다.API 제작GET,POST,PUT,DELETE를 써서 사용자를 등록하고 수정하고 삭제하고 조회했다.사용자 정보가 없을 경우에 대해 예외처리를 했다.클린 코드클린코드가 왜 중요한지에 대해 학습했다.Controller가 하나의 기능만 하도록 분리하는 작업을 했다.미션1. 어노테이션어노테이션이 무엇인지와 장단점에 대해 알아보고 나만의 어노테이션을 만들어보았다.미션2. API 실습두 수의 합,차,곱을 반환하는 API제작LocalDate를 활용하여 날짜 요청시 요일 반환 API제작배열 안의 숫자를 모두 더하는 API 제작미션3. 람다식자바에서 람다식이 왜 생겨났는지와 람다식 문법을 알아보았다.회고참가 계기내가 주로 쓰고 있는 언어는 javascript와 C#인데 한국에서는 java를 주로 써서 블로그를 봐도 java에 대한 내용이 더 많이 보이기도 했고 코딩 테스트에서나 개발자를 채용할 때도 대부분 java가 기준이였다. 그래서 나도 한 번 java를 사용해서 서버를 만들어볼까 생각했었고 마침 인프런 워밍업 클럽 1기 스터디 모집 글을 보게 됐다. java를 안해본지 좀 오래됐는데 마지막으로 java를 쓴지는 한...3년 전이였나 기억도 나질 않는다. 그래도 기초부터 시작하니 커리큘럼대로 따라가기만 하면 문제 없을 것 같아서 신청하게 되었다.새로운 것IntelliJ  내가 처음에 java를 배웠을 때 Eclipse를 썼는데 이젠 IntelliJ를 쓰나보다. 솔직히 java는 내 관심 영역은 아니었기에 현재 쓰고 있는 컴퓨터엔 전혀 세팅이 되어 있지도 않았다. 내가 친숙한건 vscode,Visual Studio 이것 뿐.. Spring boot도 처음 써본다... mysql?  mysql은 써보긴했는데 이것도 대학생 때 썼으니 오래 전이긴하다. Oracle이랑 비슷해서 문제는 없긴한데 bigint 타입이 있어서 이건 뭐지? 했는데 ORACLE에서 NUMBER(19)를 표현한 거였다. 조금씩 다른데 적다가 헷갈리긴한다. 강의에서 IntelliJ에 DB연결해서 사용하는 부분이 있었는데 유료라서 굳이 돈을 써야할까 싶어서 CLI 창으로 했다. 미션미션 1. 어노테이션어노테이션이 무엇인지와 나만의 어노테이션을 만들어보는 미션이 있었는데 어노테이션이라는 개념을 처음 들어봤다. 그래서 찾아봤는데 C#에서 어튜리뷰트와 좀 비슷한 것 같았다. 이번에 flutter도 시작했는데 dart에도 어노테이션을 지원한다는 것을 알게됐다. java에서 annotation을 만들어보면서 다른 언어에는 어떻게 작동하는지 비교하면서 해결했다.미션2. API 실습  문제2번에서 C#에서 DateTime이 java에서 localDate를 쓰는 것을 확인했다. 작동 방식은 비슷한 것 같았다. 처음에 요청 받을 때 LocalDate로 받는 방식을 썼었다. 에러가 나서 설마 LocalDate로 받아와서 그런가 싶어서 String으로 바꿨었는데 결국 오타 때문에 안된 거였었다. 근데 바꾸기 귀찮아서 다시 안바꿨다. 과제가 끝나고 멘토님이 스프링 부트 2.x.x 버전대에서는 @DateTimeFormat 이라는 어노테이션을 사용해서 LocalDate 를 바로 받을 수 있고 3.x.x 버전 대에서는 어노테이션 추가 없이 LocalDate를 받을 수 있다고 답변 달아주셔서 String으로 받은게 조금 찔려서 다시 수정했다.미션3. 람다식자바에서 람다식에 대한 과제를 내주셨을 때 C#과 javascript,dart에서 쓰고있어서 반가웠다. C# LINQ와 비슷한 스트림(Stream) API도 알게 되었다. 각 언어별로 람다식으로 예제를 만들어서 연습해봤다.느낀점이번주 동안 강의를 듣고 미션을 수행하면서 각 언어 별로 어떻게 다른지 비교하는 방식을 통해 오히려 java에 대한 내용 뿐만 아니라 다른 언어를 이해하는데 도움이 된 것 같다. 언어 별로 독특한 기능과 차이점을 보면서 언어마다 어떤 문제를 해결하기위해 도입했는지 스토리를 찾아보는게 재밌었다.이번주 동안 진도표와 과제제출을 성실하게 수행한 나한테 칭찬한다..ㅎㅎ진도표와 과제제출을 통해 나태한 나에게 압박감을 주는 스터디가 나한테 맞는 것 같다.다음주에도 열심히 따라가야지!!

백엔드발자국인프런워밍업클럽1기BE

성우

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

 Section1 정리API가 무엇인지, 구성요소 , 종류를 배웠다.GET,POST API를 계산기를 이용하여 실습했다.DTO, JSON의 개념에 대해서 배웠다.https://airy-son-f4f.notion.site/Section-1-767980170f1c45fb9b17cdce80cbb5f1Section 2 정리컴퓨터의 핵심 부품의 예시를 들어 데이터베이스의 필요성을 배웠다.SQL 기본 문법을 배웠다. 여태까지 커맨드라인으로만 SQL을 다뤘었는데 인텔리제이에서도 할 수 있다는 것을 배우고 놀랐다.(인텔리제이가 훨씬 편한거 같다...)Jdbc를 이용해 테이블 생성, 갱신, 수정 ,삭제(CRUD)를 배우고 실습했다. 실시간으로 코드와 SQL을 연결해 DB가 바뀌는것이 신기했다. https://airy-son-f4f.notion.site/Section-2-6bec7c7c350d4c46beaa95a3b97fd6f1 1일차 과제어노테이션이 뭔지는 대충 알고 있었는데 커스텀 어노테이션을 만들 수 있다는 것을 알 수 있었고, 어노테이션의 역할에 대해서도 더 확실히 알게되었다.https://velog.io/@sung515/%EC%9D%B8%ED%94%84%EB%9F%B0-%EC%9B%8C%EB%B0%8D%EC%97%85-%ED%81%B4%EB%9F%BD-1%EA%B8%B0-BE-1%EC%9D%BC%EC%B0%A8-%EA%B3%BC%EC%A0%9C2일차 과제DTO와 컨트롤러 개념이 강의를 듣고 난 이후에도 잘 잡혀있지 않았는데 여러 문제를 직접 실습해 보면서 어느 정도 이해를 할 수 있었다.자바 코드 구현 과정에서 날짜를 다루는 부분과 Stream API 를 잘 몰라 이번 기회에 공부하면서 자바에 관해서도 부족하다는 걸 느꼈다..https://velog.io/@sung515/%EC%9D%B8%ED%94%84%EB%9F%B0-%EC%9B%8C%EB%B0%8D%EC%97%85-%ED%81%B4%EB%9F%BD-1%EA%B8%B0-BE-2%EC%9D%BC%EC%B0%A8-%EA%B3%BC%EC%A0%9C3일차 과제개념이 희미했던 익명 클래스에 대해서 다시 한 번 공부할 수 있던 기회였고, 가끔씩 코드에 람다나, Stream API가 나오면 무슨 뜻이지 이해가 안됐었는데 이번 기회에 어느 정도 감을 잡을 수 있는 계기가 되었던 거 같다.  https://velog.io/@sung515/%EC%9D%B8%ED%94%84%EB%9F%B0-%EC%9B%8C%EB%B0%8D%EC%97%85-%ED%81%B4%EB%9F%BD-1%EA%B8%B0-BE-3%EC%9D%BC%EC%B0%A8-%EA%B3%BC%EC%A0%9C 마무리..벌써 발자국을 작성하는 날이 되다니 시간이 정말 빠른 거 같다. 처음에 최태현 님 강의만 들으려던 찰나 우연치 않게 워밍업 클럽에 대해서 알게 되었을 때, 여러 사람들과 함께하면서 의욕을 돋우는 게 좋다고 생각해 워밍업 클럽 스터디를 신청하게 되었다. 아무래도 학교 공부랑 병행하다 보니 쉽지 않았지만... 강의를 듣고 정리하고 이후에도 과제를 하면서 다시 강의 내용을 상기할 수 있는 부분이 정말 좋았던 거 같다. 또 듣다 보면서 자바에 대한 개념이 부족한 부분이 많다는 것을 깨달았다. 앞으로 강의도 들으면서 자바 공부도 틈틈이 해나가야겠다..3일차 강의를 사정이 있어 듣지 못했는데 연휴가 하루 껴있는 만큼 다음 주는 이번 주보다 더 나은 한 주가 되도록 열심히 해야겠다!!

백엔드

김설하

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

 강의 수강인프런 워밍업 클럽 스터디 1주차이다. JavaScript의 전반적인 이론을 복습하였다. 기술 면접을 대비하고자 강의 제목을 보았을 때 내가 먼저 설명해보고 막힌 부분이 있으면 그 부분을 메모해두었다가 확실하게 공부하는 식으로 진행했다.이제는 옛말이지만 수학의 정석 책을 사면 집합(1장) 부분만 닳아 있는 사람들이 많다고 하고 실제로도 그렇다.,ㅎ 모든 학습에 적용되며 경각심을 가질만한 공통의 경험이라고 생각하여 힘조절에 신경쓰려고 했다. 형식이나 타입 변환 같은 부분은 느슨하게 보고, 자주 까먹거나 헤매게 되는 비동기나 이벤트 루프 부분을 집중해서 보았다. 일주일 동안의 학습 방식을 4L식으로 회고해본다.Liked (좋았던 점) + Learned (배운 점) :우선 공식적으로 할 일이 생겨서 너무너무 좋았다 ◠‿◠ 배웠지만 어디에 사용해야할까 막막할 때 이렇게 미션들이 주어지면 최대한 적용해보는 플레이그라운드가 되어서 즐겁다. 또한 A-Z 강의를 들으며 기술 면접 준비 차 자바스크립트를 복습할 수 있어서 더없이 좋다. 또한 과제를 통해서 DOM을 직접적으로 조작하여 기능을 구현하였는데 html을 시멘틱하게 설계하고, css를 입히고, js로 생명력을 불어넣는 과정이 그 어떤 초심으로 돌아간 것 같아서 즐거웠다.  Lacked (부족한 점) : 미션 수행률이 더디다. 이론의 부족한점에 치중하는 경향이 있는데 이론 공부를 하다가 미션이 많이 밀렸다. 우선 완주 목표치는 채우는 것은 당연하고 웜업 스터디가 진행되는 기한 내에 80% 이상의 과제를 하는 것을 목표로 잡았다.이론적으로 부족한 파트 : 이벤트 위임, this, Intersection observer, 커링이벤트 위임은 이론적으로는 잘 받아들이지만 코드로 볼 때 직관적으로 들어오는 느낌은 아니라서 코드 위주로 복습을 해야 한다.커링과 클로저를 엮어 설명한 아티클을 읽었던 기억이 있는데, 다시 한 번 찾아 읽어야겠다.처음 목표는 스터디에서 배운 파트를 You don't know JS Yet 교재로 딥하게 파고드는 것이었다. 힘조절에 신경썼다고 하지만 기본 내용이 완벽하게 숙지되었는가 하는 사실에 매몰되어서 심화 공부를 못하고 있다. 완벽주의를 버리는 연습을 해야 한다.구현을 하다 보면 ‘이왕이면’ 싶어서 CSS를 신경 쓰거나, 내가 쓰는 코드가 맞는 방식일까 생각하게 되는데 이게 시간 잡아먹히는 요인이 아닐까 싶다. 미션이 하루에 하나씩 나오는 꼴이라는 걸 생각하면 어느정도 선에서 타협을 보거나 조절해야 할 듯 싶다.Longed For (바라는 점) :하루의 마감 시간을 정해두고 공부하는 게 좋을 듯하다. 특히 낮시간엔 강의를 듣다가 까무룩 보내고, 뒤늦게 과제를 시작했다가 밤이 늦어지는 경우가 종종 있었다.5/6까지 휴일이니 쉬는 날을 이용해서 이번주의 과제를 최대한 맞춰 해놓고 다음주부터는 진도표에 맞춰서 미션과 강의를 진행할 것이다. + 미션 발자국 기록 제때제때 하기타입 공부할 때 '원시 타입은 Call Stack 메모리 공간을 사용하지만 참조 타입의 경우 Heap 이라는 메모리 공간을 사용한다.' 라는 문장이 있었는데 CS와 접목시켜 이 문장을 제대로 이해하고 싶다.미션 제출 글이 아닌 회고 글을 첫번째 글로 작성하게 되었는데, 미션3까지 완성이 되는 대로 갈무리하여 미션 제출 발자국(1~3)을 빠른 시일 내에 제출하자.  

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

김 동현

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

1주차 후기우선 일주일 간 자바스크립트 강의를 모두 보면서 5개의 과제를 클리어한 나와 다른분들에게 박수를보낸다 (짝짝짝) 백엔드 0기를 참여했을때보다 더 힘들고 정신이없었던것같다. 기존에 백엔드를 공부하고있었고 자바스크립트는 이미 기억저편으로 잊혀진지 오래여서 기억을 더듬어가고 오랜만에 검색엔진을 돌리면서 코딩을 하니 시간이 더 오래걸렸다. 이번 프론트엔드 워밍업클럽을 끝내고 백엔드 프론트 모두 내손으로만든 포트폴리오를 뽑아내겠다는 일념으로 참여했는데자바스크립트가 예상보다 어려워서 놀랐다. (왜 오타가 컴파일 에러가 안나지? 같은거?) 자바와 인텔리제이 단축키에 익숙해진 나는 vscode에서 쓸수있는단축키가 ctrl + c , ctrl + v , ctrl + ` 정도 밖에없었다.  지금은 더 찾아보면서 써서 조금 더 편하게 쓰고는 있지만 아직 익숙해질려면 갈길이 먼듯하다.그래도 수정하면서 바로바로 화면에 반영되는건 조금 감동적이었다. 수정해도 터미널에 코드덩어리 밖에 나오지않는 백엔드와는 확실히 다른 재미인것같다.  1주차는 코드를 잘짜는것보다는 돌아가는 바퀴를 만드는데에 집중했던 시간이었다.어떤 코드가 잘 작성한 코드인지 주로 어떻게 작성하는지에 대한 케이스가 없으니 함수를 나열해놓게되고 각 요소들을 그냥 변수로 잡아서 무분별하게 사용했다. 이런점에서는 코드리뷰를 좀 받고 다른분들 코드를 많이 읽으면서 케이스를 쌓아가야할것같다.  앞으로2주차는 리액트를 들어가면서 또 새로운 방법에 적응하는 시간이 필요할것같다. 그리고 스터디도 시작할듯 한데 서로 코드리뷰를 하면서 다른분들 코드에서 좋은점을 보고 배워서 적용해서 점점 나은 결과물이 만들어지는 과정을 즐겨보려한다.   

프론트엔드워밍업클럽FE1기발자국

kscold

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

인프런워밍업클럽 1주차 발자국 강의 회고사실 최근 들어 백엔드 개발을 많이 하기도 했고 프론트엔드 개발을 할 때는 JSX 기반의 코드가 훨씬 익숙하다 보니 오랜만에 바닐라 자바스크립트를 사용하니 굉장히 어색했고 강의를 들으면서 지금까지 내가 이런 중요한 것들도 모르고 공부와 개발을 해왔다니 했던 부분이 많이 나와, 챌린지를 진행하며 많이 얻어 가야겠다는 생각이 들었다. 강의 정리강의 내용 정리에 경우 개인적으로 Obsidain이라는 메모장 애플리케이션을 너무 사랑하는 사람으로 발자국 자체에 공부 내용을 넣기는 무리가 있고 또한, 링크가 많이 되어있어 그냥 next.js 오픈소스 다운로드해서 조금 코드 수정해서 퍼블리싱 했다. 예전에 끄적였던 자바스크립트 개념 정리에 더해서 정리 중이다.www.kscold.site커밋은 이슈 얼어서 섹션 별로 개인적으로 요즘 애용하고 있는 기능인 github projects 기능을 이용했다.https://github.com/users/kscold/projects/9 1주 차 느낀 점사실 1주 차의 발자국은 성공적이지 못했다... 현시점에도 부랴부랴 열심히 따라가고 있다만... 현 대학교 컴퓨터공학과 4학년으로써 진행하고 있는 졸업작품, 동아리 스터디와 코딩 알바까지... 인생... 쉽지 않지만 우수 러너보다는 수료를 목표로 파이팅 해야겠다.너무 부족하게 진행됐던 1주 차였던 만큼 남은 기간 동안 열심히 따라가 미션 해결과 강의도 얼른 기간 내에 완주해야겠다.너무나 부족한 회고록이지만 혹시나 읽게 되는 모든 분들 파이팅입니다!

프론트엔드자바스크립트인프런워밍업클럽

이슬

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

The four Fs 🍀FACTS (사실, 객관)이번 일주일 동안 있었던 일, 내가 한 일인프런 워밍업 클럽 스터디 1기를 시작했다. 1:1 멘토링권과 인프콘 초대권이 너무나 탐났기에 우수러너를 목표로 JavaScript 강의를 시작했다.스터디를 시작하면서 Firebase, React.js로 채팅앱 만들기 강의도 듣고 있다. 강의의 기술스택을 활용하여 React Query와 함께 해결할 새로운 개인 프로젝트를 생각해두고 있다.스터디 과제로 음식메뉴, 가위바위보, 퀴즈 앱을 바닐라JS로 만들었다.프론트엔드 개발직무로 이력서를 꾸준히 지원하고 있는데, 아직 연락은 없었다..😢FEELINGS (느낌, 주관)나의 감정적인 반응, 느낌, 어려움생각했던 것보다 스터디에 쏟는 시간이 길어서 2주차 때에는 시간관리에 더 신경써야겠다고 느꼈다.올해 초에 모던자바스크립트 딥다이브 책으로 한번 1독을 해서 그런지 호이스팅, 스코프, 프로토타입 섹션은 힘들지않게 이해했다. (과거의 나.. 칭찬해..)과제로 DOM 메서드 사용하며 작업했는데 거의 1년만에 사용하다보니 낯설었고, 기능을 만들 때 배열이나 객체의 어떤 프로토타입 메서드를 사용하는게 나을지 고민하는 것이 재밌었다. + 코딩테스트 문제를 푸는 기분도 들었다. FINDINGS (배운 것)그 상황으로부터 내가 배운 것, 얻은 것, 가장 인상 깊었던 배움기억에 남는 배움으로는 this와 this를 바인딩하는 bind, call, apply 메서드, 이벤트 위임이었다. 특히 이벤트 위임은 과제를 하면서 바로 바로 적용시켰기 때문에 앞으로도 잘 활용할 것 같다.복습하고 싶은 배움으로는 Design Pattern, Intersection observer, 커링이었다. 특히 Intersection observer로 lazy loading을 구현할 수 있다는 걸 이번에 알았기 때문에 더 기억에 남을 것 같다. 커링은 문법으로는 봤었지만 어떤 용어로 부르는지 몰라서 궁금증이 해소되었다.과제를 통해 DOM Node를 직접 변수로 설정하고 값을 바꾸고 업데이트하는 작업을 했는데, 첫 설계의 중요성을 알게되었다. 마음이 급해 기능을 위한 코드를 작성하다가 요소의 위치를 다시 설정해야하는 순간이 있었다. 기능도 중요하지만, 기능을 적용시킬 요소들을 어떻게 배치하고 설계해야할지 처음부터 잘 고민을 해야겠다고 느꼈다.FUTURE (미래)현재 나의 상태와 배운 것을 미래에는 어떻게 적용할 지이번 주가 끝나면 다시 React.js를 공부하게 될텐데, 이번 기회에 모국어(JavaScript)를 복습하게 되어서 좋았다. 이번 주에 배웠던 부분을 곰곰이 복기해보면서 아직 끝내지 못한 나머지 과제들에 녹여보도록 하겠다.2주차에는 강의를 빠르게 보고, 과제를 하며 고민하는 데에 시간을 더 써보는 연습을 해야겠다. 화이팅!

웹 개발인프런워밍업클럽FE1기발자국