🔥딱 8일간! 인프런x토스x허먼밀러 역대급 혜택

블로그

sein

[워밍업 클럽 4기 - 백엔드] Day 2 미션

미션강의에서 안내하는 것처럼, 프로젝트를 개인 계정으로 fork하고 강의를 수강해 주세요.github 주소 : https://github.com/techhan/readable-code.git 추상과 구체" 강의를 듣고, 생각나는 추상과 구체의 예시가 있다면 한번 3~5문장 정도로 적어봅시다.추상 : 택배를 받았다.구체 과정고객이 주문한다.판매자가 확인 후 택배 송장을 뽑는다.계약된 회사가 택배를 수거하러 방문한다.택배를 수거해서 한 번 이상의 상하차를 거친다.택배 배달원이 고객에게 택배를 전달한다. 짧은 회고두 번째 문제를 처음 맞닥뜨렸을 때는 좀 당황스러웠다. 추상과 구체. 프로그래밍을 배우면서 추상과 구체에 대해 들어본 적은 있었다. 단순히 '동물-강아지' 이런 수준. 들어만 봤지 내가 직접 생각해 본 적은 별로 없었고, 더군다나 3~5문장으로 적어 본 적은 더 없어서 꽤나 생각하는데 애를 먹었다. 그래도 한 번 생각의 물꼬가 터지니, 위에서 도출해 낸 구체 과정에서도 완벽한 구체가 아닌, 그 안에 또 구체, 또 구체, 또 구체...가 있는 걸 알게 됐다. 예를 들면 고객이 주문하는 과정에서도 '핸드폰 켜기 > 사이트 들어가기 > 장바구니에 담기 > 결제하기 > 완료하기' 등등의 구체들이 숨어 있다는 게 별 거 아닌 것 같지만 흥미로웠다. 추상과 구체는 기억에 매우 오래 남을 것 같다.  출처 인프런_워밍업_클럽_4기_BEReadable Code: 읽기 좋은 코드를 작성하는 사고법 

백엔드인프런워밍업클럽4기백엔드박우빈ReadableCodeCleanCodeBackend

규현

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

한번정도는 배워보고 싶었던 코틀린 + Spring에 대한 스터디라서 더욱 흥미로웠던 1주일이었다. ✏ 강의 후기 프로젝트 설정 ~ 엔티티 개발 까지의 분량이었다.사실 앞 부분에서 웹에 대한 지식과 Spring, JPA에 대한 지식들 역시 공유해주셨지만, 이미 알고 있는 부분이라서 해당 부분은 강의 내용은 스킵하고 자료만 확인했는데, 짧은 시간이지만 디테일한 내용들을 다뤄주셔서 웹 백엔드, 그리고 스프링, JPA가 처음인 분들도 어느정도 이해도를 높일 수 있는 자료라고 생각한다. 개인적으로는 패키지를 나누는 방법들이 많은 개발자들이 모두 다른 것 같아서(인프런 강사님들 조차) 흥미롭게 다가왔었고, Java와는 다른 코틀린의 매력을 이제 막 느낄 수 있어서 좋았다. 아직은 본격적인 개발 단계는 아니라서 아마 다음주가 더 재밌는 시간을 보낼 수 있을 것 같다. 🎯 미션 후기아직은 워밍업 단계라서 그런지 크게 어려움이 있는 단계는 아니었다미션1간단하게 깃허브 Repo를 만들고 업로드하는 과제다. https://github.com/kgh2120/url-shortener 미션21:N 관계를 갖는 테이블 설계하는 과제였다. 그 전까지는 따라서 치다가 갑자기 새로운 아이디어를 생각해야 해서 살짝 머리가 아팠지만, 평소에 해보고 싶었던 URL단축기 를 만드는 프로젝트의 설계 단계를 해볼 수 있었던 동기가 되었다. 분명 이 글을 작성하기 전에는 N:M 관계인 줄 알았는데 1:N 이라니.. 살짝 충격이다. 아직은 어떤 기능들을 넣을지에 대해서 정리가 안되어서 이후에 수정이 될 수 있는데, 다음주에 미니 프로젝트를 개발하기 전까지는 정리가 되기를 바란다.https://www.erdcloud.com/d/s7AEHgGR3mj6eXgzM 

백엔드KotlinSpringBackendStudy

hmkim199

[워밍업 클럽 0기 BE] 3주차 발자국

학습 내용출처: 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지] 3주차에서는 배포와 AWS, Git, Github, Spring Boot에 대해 알게 되었습니다. 익숙한 내용이 많아 미션을 하며 학습한 내용 위주로 작성하려 합니다.  미션https://github.com/hmkim199/spring-commute-app미니 프로젝트를 하며 강의와 실습, 과제를 통해 배웠던 것들을 스스로 적용해보고 고민해볼 수 있어서 유의미했습니다. @ManyToOne과 @OneToMany를 좀 더 이해하게 되었고 둘 다 써주기 보다는 무한 참조가 걸리는 것을 방지하기 위해 @ManyToOne 을 많이 쓴다는 것을 찾아보며 알게 되었습니다. 또한 fetch 방식은 LAZY로 설정해주어 불필요한 부하를 방지하는 방법도 알게 되었습니다. 현업에서는 왜래키를 잘 쓰지 않는데, 왜래키를 쓰지 않고 테이블간 연관 관계를 표시해주고 동작하도록 로직을 구현했습니다.LocalDate 타입을 Postman을 통해 Json으로 넘겨주는 것에서 오류가 있었는데, JsonFormat이라는 애노테이션을 이용해서 오류를 수정할 수 있었습니다. 다만 패턴에 따라 오류 발생 유무의 차이가 있어 이 부분은 차후 좀 더 알아보아야 할 것 같습니다.@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul") // 이렇게 오류 해결 @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyyMMdd", timezone = "Asia/Seoul") // 이렇게는 오류가 발생 회고 및 목표회사와 스터디를 병행하다 보니 어려운 점도 많았지만 피곤해도 강의를 들으며 헷갈렸던 개념들이 이해가 되기 시작하니 뿌듯하고 개운한 느낌이 들기도 했습니다. 설명을 너무 잘 해주셔서 도움이 많이 되었고 스터디가 끝나더라도 다시 강의를 들으면서 하나하나 따라해보고 과제나 미션들도 다시 해보면서 복습하고 싶습니다. 부족했던 부분을 스스로 보완하는 시간을 가지려고 합니다. 누군가에게 보여주기 위한 공부가 아닌 스스로 만족하기 위한 학습을 해나갈 수 있어 좋았습니다. 

백엔드SpringBootBackend

hmkim199

[워밍업 클럽 0기 BE] 2주차 발자국

학습 내용출처: 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]섹션 4. 생애 최초 JPA 사용하기문자열 SQL을 직접 작성하는 것의 단점문자열을 작성하기 때문에 실수할 수 있고, 실수를 인지하는 시점이 느리다.특정 데이터베이스에 종속적이게 된다. 반복작업이 많아진다.데이터베이스의 테이블과 객체는 패러다임이 다르다. => 그래서 JPA가 등장! JPA란? Java Persistence API의 약자로 자바 진영의ORM(Object-Relational Mapping) 기술 표준을 의미.데이터를 영구적으로 보관하기 위해 Java 진영에서 정해진 규칙Spring Data JPA4. 영속성 컨텍스트테이블과 매핑된 Entity 객체를 관리/보관하는 역할을 수행스프링에서는 트랜잭션을 사용하면 영속성 컨텍스트가 생겨나고, 트랜잭션이 종료되면 영속성 컨텍스트가 종료변경 감지 (Dirty Check): 영속성 컨텍스트 안에서 불러와진 Entity는명시적으로 save 를 해주지 않더라도 알아서 변경을 감지하여 저장쓰기 지연 : 트랜잭션이 commit 되는 시점에 SQL을 모아서 한 번만 수행1차 캐싱 : ID를 기준으로 Entity를 기억하는 기능지연 로딩: 필요한 순간에 연결되어 있는 객체를 가져온다. (fetch 옵션 LAZY, EAGER 중 @OneToMany는 LAZY가 기본)섹션 5. 책 요구사항 구현하기상대 테이블을 가리키는 테이블이 연관관계의 주인이다. 연관관계의 주인이 아닌 객체는 mappedBy 를 통해 주인에게 매여 있음을 표시해 주어야 한다.양쪽 모두 연관관계를 갖고 있을 때는 양쪽 모두 한 번에 맺어주는 게 좋다.cascade 옵션을 활용하면, 저장이나 삭제를 할 때 연관관계에 놓인 테이블까지 함께 저장 또는 삭제가 이루어진다.orphanRemoval 옵션을 활용하면, 연관관계가 끊어진 데이터를 자동으로 제거해 준다. 미션6일차7일차의존성 주입을 어디에서 어떻게 하는지를 강의를 들으며, 미션을 하면서 자연스럽게 익히게 되어서 좋았습니다. sql을 직접 사용하는 것과 JPA를 통한 변화가 어떤 차이가 있는지 코드 상으로 확인할 수 있어서 기존에 헷갈리고 불명확한 부분들이 또렷이 보여서 좋았습니다. 회고 및 목표이전에는 @OneToMany와 같은 애노테이션을 어디에 사용하는지, 왜 사용하는 지를 모르고 그냥 동작하게 만들기 위해서 썼는데 2주차 강의를 수강하면서 각 테이블끼리 객체지향적으로 연결시키면서 자연스럽게 이해할 수 있었던 것 같아서 의미있고 재밌게 느껴졌습니다. 영속성 컨텍스트도 어렵게 생각하다가 강의를 들으니 이해가 잘 되어서 좋았고 전반적인 스프링 부트 기술들에 대해 필요성과 관계성 등을 알게 되어 좋았습니다.3주차에는 미니 프로젝트를 하면서 배웠던 것들을 스스로 적용해보고 다시 복습하는 시간을 가지고 싶습니다.

백엔드SpringBootJAVABackend

hmkim199

[워밍업 클럽 0기 BE] 1주차 발자국

학습 내용출처: 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지] 섹션 1. 생애 최초 API 만들기1. (웹을 통한) 컴퓨터 간의 통신은 HTTP 라는 표준화된 방식이 있다.2. HTTP 요청은 HTTP Method (GET, POST)와 Path(/portion)가 핵심이다.3. 요청에서 데이터를 전달하기 위한 2가지 방법은 쿼리와 바디이다.4. HTTP 응답은 상태 코드가 핵심이다.5. 클라이언트와 서버는 HTTP를 주고 받으며 기능을 동작하는데 이때 정해진 규칙을 API라고 한다.@RestController주어진 Class를 Controller로 등록한다. (Controller : API의 진입 지점)@GetMapping("/add")아래 함수를 HTTP Method가 GET이고 HTTP path가 /add인 API로 지정한다.@RequestParam주어지는 쿼리를 함수 파라미터에 넣는다. @PostMapping(”/multiply”)아래 함수를 HTTP Method가 POST이고 Path가 /multiply인 API로 지정한다.@RequestBodyHTTP Body로 들어오는 JSON을 요청 DTO 로 바꿔준다!HTTP body를 객체로 바꾸는 @RequestBody 를 사용하는 경우는, 생성자를 만들지않아도 괜찮다. API의 응답 결과를 JSON으로 반환하는 방법: Controller에서 그냥 객체를 반환하면, JSON으로 응답되며 객체에는 getter가 있어야 함-> getter 없는 객체 반환하면? 에러났음. (Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation]) 섹션 2. 생애 최초 Database 조작하기CPU : 연산담당RAM : 메모리, 단기기억DISK : 장기기록우리가 서버를 실행시켜 API를 동작시키기까지 이 3가지 장치는 다음과 같은 역할을 수행1. 우리가 개발하고 있는 스프링 부트 서버는 DISK에 파일로 잠들어 있다.2. 서버를 실행시키면 DISK에 있는 코드 정보가 RAM으로 복사된다.3. API가 실행되면 ‘연산'이 수행되며, CPU와 RAM을 왔다 갔다 한다.4. 즉 POST API를 통해 생긴 유저 정보는 RAM에 쓰여 있다.5. 만약 서버가 종료되면 RAM에 있는 모든 정보가 사라진다.6. 때문에 다시 서버를 시작하면, 유저 정보가 없는 것이다!-> 서버에서는 Java에 있는 File 클래스를 사용해 직접 DISK에 접근할 수도 있지만, 이럴 때 바로 Database를 사용할 수 있다. 섹션 3. 역할의 분리와 스프링 컨테이너함수 하나로 모든 기능을 구현한다면?1. 그 함수를 동시에 여러 명이 수정할 수 없다.2. 그 함수를 읽고, 이해하는 것이 너무 어렵다.3. 그 함수의 어느 부분을 수정하더라도 함수 전체에 영향을 미칠 수 있기 때문에 함부로건들 수 없게 된다.4. 너무 큰 기능이기 때문에 테스트도 힘들다.5. 종합적으로 유지 보수성이 매우 떨어진다. 기존 컨트롤러에서 모든 기능을 구현했을 때의 컨트롤러 역할1. API의 진입 지점으로써 HTTP Body를 객체로 변환하고 있다.2. 현재 유저가 있는지, 없는지 등을 확인하고 예외 처리를 해준다.3. SQL을 사용해 실제 DB와의 통신을 담당한다.-> 각각을 Controller, Service, Repository로 분리! 미션1일차2일차3일차4일차 1주차 미션을 수행하면서는 학습한 것을 스스로 적용할 수 있도록 하는 것에 가장 집중하였습니다. 2일차 과제를 해결하며 Json 배열 받는 방법(List를 요청 DTO에서 필드로 갖기), Getter나 생성자가 없는 경우 발생하는 에러 등을 겪으면서 새로운 문제를 마주하고 해결하는 방법을 알게 되었습니다. 회고 및 목표회사와 함께 스터디를 병행하니 4-5일차 과제는 수행하지 못해서 아쉬웠습니다. 하지만 2주차 학습을 진행하며 틈틈이 1주차에 미흡했던 부분을 보완하고자 합니다.4일차 추가: 2024-02-26 

백엔드SpringBootJAVABackend

Shallow copy vs Deep copy

자바스크립트에서 기존에 존재하는 객체를 복사해서 새로운 무언가를 만들고 싶을 때가 있다. 하지만 그냥 새로운 변수를 선언해서 기존의 객체를 대입하면.. 새로운 변수를 변형했을 때 기존의 값까지 영향을 받아 상황에 따라 골치아파질 수 있다.. 이건 후술할 shallow copy가 된다.   Shallow copy는 원본의 값을 '참조'하는 형태로 복사한다. 따라서 복사한 값의 형태가 바뀌면 그 원본의 값도 영향을 받는다. Deep copy는 원본의 값을 정말 그 값만 복사해오고, 원본과는 완전히 별개의 객체가 된다. 이를 수정하거나 해도 원본의 값은 영향을 전혀 받지 않는다. ex) //JavaScript 환경에서.. obj = {a: 1, b: 2}; new_obj = obj; new_obj.a = 3; console.log(obj.a);    //3   JavaScript에서는 객체를 deep copy하기 위해 lodash의 ._clone()이나 ._cloneDeep()을 많이 이용한다. clone()은 객체를 deep copy하지만, 내부 객체까지는 deep copy하지 못한다. ex) obj = {a: 1, b: 2,  c: {2, 4}}; clone_obj= ._clone(obj); clone_obj.c === obj.c;    //true   때문에 내부 객체가 포함되어있다면 ._cloneDeep()을 쓴다. obj = {a: 1, b: 2,  c: {2, 4}}; clone_obj= ._cloneDeep(obj); clone_obj.c === obj.c;   //false   추가로 shallow copy는 deep copy에 비해 상대적으로 속도가 빠르다.   Shallow copy와 Deep copy를 상황에 따라 적절히 섞어서 쓰도록 하자.

백엔드JavaScriptBackend

채널톡 아이콘