블로그

꼬마돌

조직구조와 동기를 이끌어 내는 일.

https://www.youtube.com/watch?v=HtC9APOIvkw   영상 내용이 좋아서 요약해보았습니다. :-)   경영에 있어 제일 중요한 건 조직을 구성하는 일이다. (화자는 그렇게 생각한다.) 조직 관련 용어중에 사일로 현상이란 단어가 있다. 사일로란 곡물이나 가축의 사료를 저장하는데 저장되는 시설이다. 곡물이 서로 섞이지 않도록 칸을 구분지어 놓은 것인데, 조직 구성을 이렇게 해놓고 왜 같이 일하지 않아요? 라고 물으면 안된다. 조직 형태를 그렇게 만들어 놓았기 때문이다.         섞진 않더라도 횡으로 묶일 수 있도록 만들어 주는 것. 그래서 종으로 횡으로 엮이고 서로 커뮤니케이션 하며 일하는 방식이 요즘의 애자일 방식이다. 애자일 조직에선 보스가 2명이다. 종과 횡으로 상사가 있다. 실리콘밸리에선 익숙하고 발달된 형태의 조직 구조이다. 이런 조직에선 커뮤니케이션이 발달할 수 밖에 없다. 줌 같은 커뮤니케이션 툴도 이런 배경에서 나왔다.    <조직을 구성할때 고려해야 할 사항>  1. 전략을 토대로 형성되어야 한다.  2. 정보의 프로세스를 규정해야 한다. 3. 명확한 보상 체계가 있어야 한다. 4. 용병술   이 네가지를 디테일하게 세워넣고 조직을 구성해야 사람들이 움직이고 조직이 돌아간다. 다만 구글 / 카카오가 이렇게 일한다고 해서 기존 한국 기업들의 수직적인 조직구조가 좋지 않다고 생각하지 않는다. 그 방식으로 일해온 조직들도 충분히 대단한 성과를 내어왔다. 그걸 다 바꿔야 한다고 말하고 싶지 않다.    "구성원에게 얼마만틈 동기와 열망을 끄집어 낼 것인가?"는 우리의 일이 세상을 어떻게 더 낫게 만드는가? 비전과 미션, 가치와 목표 같은 것들이라고 생각한다. 더불어 지위나 금전적인 보상이 가까이 눈에 보일때 동기와 열망이 움질일 것이다.    팀원의 몰입과 행복을 끄집어 내는 것이 중요하다. 우리 팀원들은 언제 몰입하고 열심히 일하지? 그들은 누구와 밀접하게 일하지? 무엇 때문에 떠나고, 남아있는가? 를 생각해야 한다. 결국 팀원은 본인의 매니저, 본인이 속한 조직, 동료와 일한다. 그가 속한 조직장, 동료와의 관계가 중요하다. 실리콘밸리의 큰회사들은 피플 애널리틱스라는 걸 도입해 실험을 지속한다. 매일 바이오리듬을 체크해 어느 시간대에 가장 능률이 오르는지 분석하기도 한다. 오후 1시~3시 사이에 집중력이 낮기에 해당 시간대에 회의나 미팅을 잡도록 권장하는 식이다.    구체적인 것들을 바꾸라고 조언하고 싶다. 1. 실질적으로 일하는 방법. 2. 피드백 하는 문화, 그리고 과거의 일을 이야기하기보다 다음 6개월에 무엇을 할 건지 이야기하면 좋겠다. 또한 평가의 대상이 개인보다 조직이어야 한다고 생각한다.    스타트업은 스포츠 팀과 같다. 우리는 이겨야 하는 싸움을 하고 있고, 개인이 아니라 팀으로 이겨야 한다. "winnig as a team" 개인의 행동 변화를 이끌어내려면 피드백이 중요하다. 좋은 피드백은 맥락을 짚고, 그때그때 바로 이루어지는 피드백이다. 2월에 일어난 일을 연말에 평가한다면 맥락을 다까먹고 결과만 남는다. 피드백은 바로, 적시에 하는것이 좋다. 인사팀이 시켜서 하는 평가가 아니라 팀원이 서로 피드백을 주고 받고 회고하는 걸 매일하는 습관으로 몸에 배도록 해야 한다.    피드백할때 감정을 표출하거나 '너 이 자식~!@#$!@#%', 인생을 언급하거나 가족, 인간성을 언급하지 말라. 당시의 상황, 행동만을 언급하라. 상황과 행동에 따른 결과와 미래에 어떻게 개선할지를 이야기하면 된다. SBIT를 생각하며 피드백하자. (Situation | Behavior | Impact | Tommorow) 시간이 많이 지난뒤 결과만을 두고 질책하면 근본적으로 나아지기 어렵다. 당시 상황과 액션, 그에 따른 결과와 미래의 개선 지점을 이야기하자. 그것만 하면된다.     "winnig as a team"             

보안 · 네트워크 기타조직구조피드백회고

셰리

IT 업계 회고 문화 겉핥기 🍉

'뒤를 돌아본다'는 의미의 회고. 1~4주 정도의 짧은 주기(스프린트) 안에 결과물을 구현, 배포한 뒤 빠르게 제품을 개선하는 루틴을 반복하는 애자일(Agile) 프로세스와 관련이 깊다고 해요.오늘은 직장인들에게, 특히 IT 업계 종사자에겐 일상과도 같은 회고 문화를 빠르게 훑어보려고 합니다. 회고에 대한 인프런 팀원의 생각도 담겨 있으니 끝까지 읽어보세요! 😆회고는 왜 해야 할까?회고는 지나온 프로젝트 과정에서의 문제를 찾고 발전하기 위해 진행한다고 해요. 반복적인 문제 상황을 줄이고 효율적인 업무 방식을 찾기 위한 과정인 것이죠.비케이(Product Designer) ⚒️회고의 목적은 'Better'라고 생각해요. 문제 상황을 공유하면서 피드백이나 개선점을 찾고, 잘한 부분은 칭찬하고. 그러면서 프로젝트를 통해 무엇을 얻었는지 확인할 수 있는 것 같아요.프로젝트를 함께한 팀원과의 회고는 서로의 감정을 공유하는 자리이기도 해요. 함께 일하는 팀원의 생각을 조금 더 이해하고 팀워크를 다지는 계기가 되기도 하죠.보니(Product Mananger) 🦊스프린트 회고와 최종 회고의 역할이 조금 다르다고 생각해요. 스프린트 회고(주간 회고)는 프로젝트 자체가 잘 운영되기 위한 회고에 가까워요.최종 회고는 팀이나 개인 차원에서의 장기적인 발전을 위한 회고인 것 같아요. 서로의 생각을 공유하고 앞으로 더 잘하기 위한 반성이 포함된 느낌?출처: MBC 무한도전  회고를 '잘' 하려면?1. 팀이나 개인에 맞는 회고 방식을 모색하는 시간이 필요해요.인프랩은 보통 KPT 방식으로 회고를 진행해요.빠삐코(Front-end Engineer) 🍦회고를 잘하기 위해서 개인적으로 여러 시도를 해봤는데요. 매일 업무 일지를 작성하는 게 도움이 많이 됐어요. 간단하게만 작성해둬도 나중에 전체 회고를 할 때 도움이 되는 경우가 많았어요. 프로젝트 과정에서 발생했던 문제를 시간이 지나면 잊기도 하는데, 업무 일지가 그런 것들까지 떠올리게 해줬습니다. 2. 프로젝트의 목표를 명확하게 정해두는 게 좋아요.엠제이(Product Designer) Ⓜ️처음에 프로젝트의 목표를 명확하게 정해두는 게 꼭 필요하다고 생각해요. 목표가 명확해야 회고할 때의 기준이 생기고, 업무에 대한 동기부여가 되는 것 같아요. 프로젝트가 목표에 맞게 잘 진행이 되었는지를 중심으로 이야기하니까 회고하기도 수월했어요.중요한 점은 목표를 반드시 팀원 다같이 논의해서 정하는 거예요. 3. 프로젝트에 대한 설계나 계획이 잘 되어 있어야 해요.보니(Product Mananger) 🦊프로젝트 동안 팀원 각자 역할에 대한 계획을 세우는데, 그 계획을 잘 세워두면 좋은 회고가 가능한 것 같아요. 프로젝트 동안 팀원 개개인이 매일 어떤 일을 했는지 스스로 알고 있어야 회고할 거리가 생기더라고요. 그렇지 않으면 느낌이나 기억에 의존한 감정적인 회고에만 그칠 수 있다고 생각해요. 4. 프로젝트를 함께한 팀원에 대한 존중과 배려가 필요해요.비케이(Product Designer) ⚒️회고할 때 감정이 아닌 행동 중심으로 이야기하라는 말에 공감해요.빠삐코(Front-end Engineer) 🍦서로를 존중하되, 솔직하게 말하는 태도가 필요하다고 생각해요. 서로를 존중하느라 진짜 하고 싶은 이야기를 놓치면 안되니까요.출처: MBC 아빠! 어디가?회고에 대한 정답이 정해져 있는 건 아니지만, 회고의 목적이 업무의 효율성과 앞으로의 성장에 있다는 점은 누구나 공감할 것 같아요.여러분은 회고를 해야 하는 이유가 무엇이라고 생각하시나요? 회고를 잘하기 위한 방법은 뭐라고 생각하시나요? 회고에 대한 다양한 의견을 댓글로 남겨주세요! 회고 문화를 더 깊게 다룬 글을 읽어보고 싶다면?[개발자의 공유 문화 이모저모 (2) 회고 문화] 읽어보기 >> 인프랩 팀원이 작성한 다양한 회고록을 살펴보고 싶다면?[인프랩 실Log] 읽어보기 >>

개발 · 프로그래밍 기타회고회고문화애자일

[워밍업 클럽 2기 - Clean Code & Test Code] 4주차 발자국

워밍업 클럽 2기: Clean Code & Test Code의 4주차 발자국 작성입니다.3주차 발자국 보러가기 📝 학습 내용Presentation Layer 테스트 작성Mock더 나은 테스트를 작성하기 위한 여러 팁REST Docs ✍ 학습 내용 복습Q. Presentation Layer의 특징은?클라이언트로 부터 입력을 받아서 비즈니스 계층으로 해당 요청을 보내는 계층요청을 제일 먼저 받는 계층입력 데이터에 대한 기본적인 검증을 수행한다Presentation 계층에서의 검증과 Business 계층에서의 검증을 분리해서 생각해야 한다Presentation 계층에서는 보통 형식적인 검증을 한다예시: 필수 입력 값 검사, 데이터 타입 검사, null 검사, 빈 문자열 검사Business 계층에서는 비즈니스 로직에 따른 도메인 유효성 검사가 이루어진다Business 계층으로 부터 결과를 받아서 클라이언트로 반환한다컨트롤러에서 사용하는 요청 DTO가 서비스 계층으로 침투하지 못하도록 컨트롤러 계층에서 서비스 전용 DTO로 변환하는 것을 권장한다(상황에 따라 다를 수 있을것 같다. 만약 받는 포맷이 변할 가능성이 거의 없다면, 그냥 컨트롤러의 DTO를 쭉 사용해도 괜찮지 않을까 생각이 된다.)Q. Presentation Layer의 테스트 방법은?Business, Persistence 계층을 모킹해서 테스트한다MockMvc 같은 도구를 사용해서 HTTP요청과 응답을 시뮬레이션 한다모킹을 위해서 Mockito 같은 프레임워크를 사용할 수 있다 Q. Test Double의 종류를 정리해보자면?Dummy: 아루런 동작도 하지 않는 객체. 잘 사용되진 않지만, 보통 파라미터 전달용으로 사용된다.Fake: 실체 객체와 동일한 기능은 수행하지만, 프로덕션 용도로 사용하기에는 적합하지 않은 객체.예시: 인메모리로 맵을 사용해서 가짜 레포지토리를 구현하는 경우Stubs: 테스트에서의 요청에 대해 미리 준비된 결과를 제공하는 객체. 미리 반환할 데이터가 정의되어 있고, 호출하는 경우 해당 데이터를 반환한다. 미리 정의되어 있지 않은 것들은 응답하지 않는다.Spies: Stub이지만 정복 기록도 함께하는 객체. 호출 여부, 호출 횟수 등의 정보를 기록할 수 있다. 일부는 실제 객체 처럼 동작하고, 일부는 Stubbing할 수 있다.Mocks: 행위에 대한 기대를 명세하고, 그 명세에 따라 동작되도록 설계 된 객체. 그러니깐 개발자가 직접 그 객체의 행동을 관리하는 객체이다.Q. Stub과 Mock을 구분하는 기준은?Stub : 상태 검증(State Verification)Mock : 행동 검증(Behavior Verification) TIP. 테스트 작성을 위한 여러 팁을 정리해보면Mockito 프레임워크를 한번 래핑하는 BDD Mockito 프레임워크를 사용해서 조금 더 자연스러운 API 네이밍으로 프레임워크를 사용할 수 있다테스트 간의 독립성을 보장하자 테스트에서 전역 변수를 정의해서 사용하는 것은 권장하지 않는다@BeforeEach또는 @AfterEach 메서드를 사용한 레포지토리 클렌징@Transactional사용 Test Fixture용 클래스를 따로 분리해서 사용하는 것은 권장하지 않는다Test Fixture를 @BeforeEach를 사용한 셋업 메서드에서 사용하는 경우, 중복 제거보다 해당 테스트에 해당 내용을 알아야하는지 고려해보고 적용하자테스트 내용은 동일한데 입력값만 변경해보면서 테스트 해보고 싶으면 @ParameterizedTest 사용private메서드에 대한 테스트가 필요하다면 해당 메서드의 책임을 분리할지 고민해본다단순히 테스트하기 위해서 public으로 열어두는 것은 권장하지 않는다 Q. REST Docs vs Swagger의 차이는?REST Docs테스트를 통과해야 문서가 만들어지기 때문에 신뢰도가 높다프로덕션 코드에 비침투적이다코드의 양이 많고 설정이 상대적으로 어렵다Swagger적용이 쉽다문서에서 바로 API 호출이 가능하다애노테이션을 달아줘야 하기 때문에 프로덕션 코드에 침투적이다🤔 회고워밍업 클럽의 마지막 주차가 되었다. 강의 양이 많아도 내가 정말 필요한 내용을 담아서 만들어져있어서, 시간 가는 줄 모르고 시청했다.강의와 미션을 따라가면서 학습에 많은 도움을 받았다. 만약 워밍업 클럽 3기가 있다면 다시 참가할 예정이다.지금까지 학습 내용을 다시 복습해보고 더 나아가서 프로젝트에 적용하는 것이 목표이다. 🔍 참고Practical Testing: 실용적인 테스트 가이드

백엔드테스트코드워밍업클럽2기백엔드발자국4주차회고

suover

인프런 워밍업 클럽 스터디 2기 - 백엔드 프로젝트 4주차 발자국

입문자를 위한 Spring Boot with Kotlin - 나만의 포트폴리오 사이트 만들기강의와 함께한 인프런 워밍업 클럽 스터디 2기 - 백엔드 프로젝트 (Kotlin, Spring Boot) 4주차 발자국 입니다. 강의 수강이번 주에는 Spring Boot와 JPA를 사용한 뷰 개발 및 Thymeleaf를 활용한 프론트엔드 템플릿 작업에 중점을 두었습니다. 주로 Bootstrap 템플릿을 가져와 활용하고, Thymeleaf의 fragment 기능을 사용하여 재사용 가능한 HTML 구조를 만들었으며, 배포 작업까지 진행했습니다.주요 학습 내용Bootstrap 템플릿 가져오기 및 적용Bootstrapmade 사이트에서 Admin 템플릿을 다운로드하여 프로젝트에 적용했습니다.템플릿 파일을 프로젝트의 resources 디렉토리에 추가하고, 필요한 CSS, JS 파일들을 적용했습니다.Thymeleaf와 프론트엔드 분리 작업Thymeleaf의 fragment 기능을 활용해 HTML 구조를 모듈화하였습니다. head, header, footer 등 여러 공통 요소를 별도의 fragment로 분리하여 재사용성을 높였습니다.타임리프 문법을 통해 동적으로 페이지를 구성하고 유지보수가 용이하도록 개선했습니다.프로젝트 배포 작업Docker를 이용해 MySQL을 컨테이너로 실행하고, Spring Boot 애플리케이션을 Docker 이미지로 빌드하여 배포했습니다.Nginx를 사용해 80포트와 8080포트를 연결하여 클라이언트 요청을 처리하도록 설정했습니다.Let's Encrypt를 이용해 HTTPS 인증서를 설정하고, 웹사이트를 HTTPS로 안전하게 접근할 수 있도록 구성했습니다. 회고이번 주는 Thymeleaf와 Bootstrap을 활용하여 프론트엔드 작업을 진행하며, 뷰를 모듈화하고 효율적으로 구성하는 방법을 배울 수 있었습니다. 특히 Thymeleaf의 fragment 기능은 HTML 코드의 재사용성과 유지보수성을 크게 개선해 주어 프로젝트의 구조를 더욱 체계적으로 만들 수 있었습니다. 또한, 직접 템플릿을 가져와 수정하고 적용하는 과정을 통해 프론트엔드 개발 역량을 키울 수 있었고, Docker와 Nginx를 이용한 배포 작업을 통해 실제 서비스 환경에서의 배포 경험도 쌓을 수 있었습니다.칭찬할 점Thymeleaf를 사용하여 공통 레이아웃을 fragment로 분리하여 재사용성을 높인 점.Bootstrap 템플릿을 프로젝트에 무리 없이 적용하고, 필요한 수정 작업을 성공적으로 수행한 점.Docker와 Nginx를 이용한 배포 과정을 원활히 진행한 점.아쉬웠던 점 및 보완할 점Thymeleaf 문법에 대한 익숙함이 아직 부족하여 일부 동적 작업에서 어려움을 겪었습니다. 추가적인 연습과 학습을 통해 더 익숙해질 필요가 있습니다.프론트엔드 요소의 커스터마이징에 있어 부족함을 느꼈으며, 좀 더 세밀한 스타일 수정 방법을 연구하고자 합니다. 미션이번 주 미션은 삽입, 수정, 삭제 REST API를 개발하고, 이를 검증하는 테스트 코드를 작성하는 것이었습니다. API는 각 기능별로 POST, PUT, DELETE 요청을 처리하도록 설계하였으며, 모든 케이스에 대해 성공적으로 테스트를 완료했습니다.미션 과정게시글 삽입 API 설계 (POST /api/posts)새로운 게시글을 작성하고, 작성된 데이터를 JSON 형태로 반환하도록 설계했습니다.게시글 수정 API 설계 (PUT /api/posts/{postId})특정 게시글을 수정하고, 수정된 결과를 반환하는 기능을 구현했습니다.게시글 삭제 API 설계 (DELETE /api/posts/{postId})특정 게시글을 삭제하고, 삭제 후 상태 코드 204 No Content를 반환하도록 했습니다.테스트 코드 작성 및 검증각 엔드포인트에 대해 최소 3개의 테스트 케이스를 작성해, 다양한 상황에서의 시스템 동작을 검증했습니다.필수 값이 누락된 경우, 잘못된 ID로 요청했을 때의 예외 처리 등도 함께 테스트하여 안정성을 확보했습니다.  미션 과정추가적으로 가상 프로필을 나의 프로필로 바꾸기 미션과 배포한 프로젝트 공유하기 미션까지 모두 마무리하며, 스터디의 모든 미션을 마무리 하였습니다. 이 발자국을 끝으로 모든 미션과 발자국, 강의 수강 100% 까지 마무리 하며, 스터디를 성공적으로 완주하였습니다. 회고이번 미션을 통해 RESTful한 API 설계 및 테스트의 중요성을 다시 한번 체감할 수 있었습니다. 또한, Thymeleaf를 활용해 프론트엔드를 모듈화하고 코드의 재사용성을 높이는 작업이 실제 프로젝트에서 어떻게 활용될 수 있는지 직접 경험할 수 있는 시간이었습니다. 배포 작업을 통해 실제 서비스 환경에서 발생할 수 있는 문제들을 다루며, 더 나은 품질의 소프트웨어를 개발하기 위한 실무 경험을 쌓을 수 있었습니다. 앞으로 JPA 연관 관계에 대한 이해를 깊이 있게 다지고, 테스트 코드의 가독성을 더욱 높이는 방법을 연구하여 더 나은 품질의 소프트웨어를 개발해 나가겠습니다.

백엔드인프런워밍업클럽스터디백엔드프로젝트발자국회고SpringBoot

Practical Testing 3주차 발자국

서문테스트에 대해서는 늘 많은 고민이 있었다.테스트를 작성하다보니 많은 선택지들이 있었는데 이번 3주차 간의 강의를 통해서 이전에 수강했던 강의를 복습하는 차원에서 다시 한 번 바라보았다.특히나 처음에 강의를 들었을 경우에 가장 와닿고 도움이 많이 되었던 말은 테스트 코드는 좋은 구조를 설계해나가는 과정이라는 것이다.테스트를 작성해나가다 보면 내가 짜놓은 코드의 설계가 확장성 있게 작성이 되지는 않았는지, BDD 기반으로 테스트 코드를 작성해 나가면서 내가 짠 메서드의 행위가 테스트 하기 쉽도록 작성되어 있는지에 대해서 쉽게 파악 할 수 있었다.취업 전에 이 강의를 보고 난 이후의 경험과 현재 취업을 하고 나서 여러가지 테스트 서적을 보고 난 이후의 경험이 합쳐져서 더 많은 도움이 되고는 한다.단위 테스트기존에는 단위 테스트의 기준을 항상 비즈니스 레이어 기준으로 잡았었다. 단위 테스트는 책 한권으로 다룰 만큼 되게 폭 넓은 분야인데 그렇게 넓게 다룰 필요가 있는가? 라고 생각을 하기도 하였다.하지만, Effective Software Testing 책에서 읽어 본 바로는 하나의 계층만 테스트 할 수 있는 구조라면 단위 테스트이다.라는 말이 나의 모호함을 해결해주었다. 다른 말로, 통합 테스트와 단위 테스트의 기준은 무엇을 바라보아야 하지? 라고 했을 때, 다른 계층과의 결합이 생기는 순간 이는 통합 테스트를 바라보면 된다는 것이다.이 관점에서 통합 테스트를 작성 할 때 Mocking 하는 것을 더 생각해 볼 필요가 있다. Mock은 주어진 행위에 대한 결과가 내가 예측한 값을 사용하게 된다. 이는, 실제로 그 값이 내려오지 않을 수 있음을 시사하는데 이로써 해당 계층에 대한 테스트가 신뢰도 있는 테스트가 작성되지 않는다는 것이다.따라서, Mock을 사용한 테스트를 하게 되면 이는 단위 테스트를 작성하는 형태가 된다. 내 계층에서 어떠한 메서드가 이 값을 받았을 때 해당 계층의 결과는 이 결과가 나와야 해. 라는 의미를 가지게 되는 것이다.프레젠테이션 레이어이 부분은 강의를 보면서도 아직 고민이 많다.우리는 프레젠테이션 레이어 테스트를 작성하면서 강의에서도 컨트롤러 영역에서의 서비스 계층 영역을 mocking 하여 결과 값을 가지고 오는 것을 볼 수 있다. 물론 전제는 서비스가 테스트되었기 때문에 서비스 계층에서의 결과 값은 예측 값이 맞겠지만, 이는 서비스 영역에서 결과 값이 필드가 바뀌는 경우에 놓칠 수 있는 경우를 시사하게 된다.물론 이 부분은 개발자가 신경써야 하는 부분이기도 하지만 휴먼 에러를 방치하는 것은 또 좋지 않다고 생각을 하긴 한다. 이 방법을 해결하기 위해서는 결국 E2E (End-To-End) 테스트를 진행하기 위해서 assured 테스트를 사용해보기도 하였는데, 이럴 경우에 Persistent 레이어까지 전부 test container를 띄우면서 실 상황과 유사한 상황으로 테스트를 진행하다보니 테스트에 많은 시간이 소요되게 된다.물론, 우빈님이 소개해주신 스프링 부트 컨테이너의 빈 목록을 한데 모아서 관리한다면 속도 개선은 많은 부분 이루어지지만, 그 이전에 테스트를 실행 할 때마다 해당 테스트에 필요한 데이터들을 새로이 만들어주는 과정이 많은 시간을 잡게 되고, 이는 결국 비즈니스 개발에 많은 시간을 잡아먹게 된다.추가적으로, E2E로 작성하게 되는 경우에 나타나는 문제점은 어찌됐든 서비스 영역의 테스트 결과 값이 서비스 계층의 비즈니스가 완성되기전까지 문서화를 위하여 Dummy 형태의 응답 값을 가지게 된다는 것이다.이러한 여러가지 상황 속에서 아직까지 나만의 답을 찾지 못하였으니 계속 경험을 가지면서 적절한 나만의 기준을 찾는 것이 좋을 것 같다. 해당 내용에 대해서는 우빈님께 질문을 드릴 예정이다.영속성 레이어이 부분도 많은 고민을 가지고 있었다. 취업 준비를 할 때에는 H2 인메모리 DB를 사용하여 많은 부분 영속성 레이어의 테스트를 구성 할 수 있었으나, 실제로 현업에 왔을 때에는 H2에서는 정상 동작하나 실제 DB에서는 작성하지 않는 상황들이 적지 않게 발생하는 것을 볼 수 있었다. 이를 대체 할 방법이 Test Container를 띄워서 테스트를 작성하는 것인데, 시간이 생각보다 오래 걸린다. 아직 이 부분도 해결이 되지 않은 것 같다. 우빈님 강의 뿐만이 아니라 더 많은 서적들을 보면서 영속성 계층을 어떻게 처리하는게 좋을지 이 부분도 경험치를 쌓아나가야 하는 것 같다.모든 상황에서는 은탄환은 존재하지 않는다. 실제로 어떻게 하는지 지금 내 레벨에서는 최대한 카피하여 많은 경험치를 쌓아가는 과정이 중요하다고 생각한다. 또 좋은 기술이 나오지 않을까? 라는 생각이 들기도 한다.마무리옛날에는 테스트를 짜는데 시간이 오래걸린다는 말이 어느정도 맞는 말이라고 생각한다. 하지만, 현재에는 기술이 너무 좋아졌다. copilot을 사용하면서 테스트를 짜는 시간을 거의 300%는 더 빠르게 작성 할 수 있게 해주는 것 같다.기술을 적절히 활용하면서 회사 내에 테스트를 짜는 문화를 좀 더 거부감 없게 만들어나가고 싶다.

소프트웨어 테스트테스트단위테스트회고

suover

인프런 워밍업 클럽 스터디 2기 - 백엔드 프로젝트 3주차 발자국

입문자를 위한 Spring Boot with Kotlin - 나만의 포트폴리오 사이트 만들기강의와 함께한 인프런 워밍업 클럽 스터디 2기 - 백엔드 프로젝트 (Kotlin, Spring Boot) 3주차 발자국 입니다. 강의 수강이번 주에는 실습 중심으로 Spring Boot와 JPA를 사용한 컨트롤러 개발과 API 설계를 진행했습니다.API 테스트 코드를 작성해보고, Thymeleaf를 활용한 프론트 개발 작업도 수행했습니다.주요 학습 내용Spring MVC와 JPA를 활용한 컨트롤러 개발PresentationApiController 및 PresentationViewController에서 다양한 API 엔드포인트를 구현했습니다.JPA를 통해 데이터베이스와 상호작용하며 데이터를 처리하는 방법을 학습했습니다.Thymeleaf 프론트엔드 개발템플릿을 활용하여 데이터를 프론트엔드에 전달하고 뷰를 생성했습니다.커스터마이징을 통해 유지 보수가 용이한 뷰를 구성했습니다.컨트롤러 테스트 코드 작성API 테스트 코드를 작성하여 정확하게 동작하는지 검증했습니다.실제 API가 예상대로 동작하는지 검증하는 방법을 배웠습니다. 회고이번 주는 Spring Boot와 JPA를 활용한 컨트롤러 개발과 API 설계, 그리고 테스트 코드 작성까지 다양한 실습을 통해 실질적인 개발 경험을 쌓는 데 집중한 한 주였습니다. 특히, 데이터를 조회하고 처리하는 API를 설계하면서 RESTful 구조에 대해 깊이 고민했고, 테스트 코드 작성이 얼마나 중요한지 다시 한번 깨닫게 되었습니다. 실습을 통해 새로운 개념들을 익히고, 실제 프로젝트에 적용해보며 기술적 성장을 이뤘습니다.칭찬할 점테스트 코드를 작성하여 API의 주요 기능들을 효율적으로 검증했습니다.Thymeleaf 템플릿 커스터마이징을 통해 프론트엔드를 구성하고, 유지 보수가 용이하도록 최적화했습니다.아쉬웠던 점 및 보완할 점Thymeleaf 문법에 대한 이해가 부족하여 복잡한 작업에서 어려움이 있었습니다.테스트 코드를 더 간결하고 효율적으로 작성하기 위해 리팩토링 기법을 학습할 계획입니다.미션이번 주 미션은 게시글 조회 REST API를 개발하고, 이를 검증하기 위한 테스트 코드를 작성했습니다.API는 전체 게시글 조회와 특정 게시글 조회 두 가지 기능을 제공합니다. 미션 과정전체 게시글 조회 API 설계GET /api/posts 엔드포인트에서 전체 게시글을 조회하고, JSON 형식으로 데이터를 반환합니다.특정 게시글 조회 API 설계GET /api/posts/{postId}로 특정 게시글 ID를 기반으로 게시글을 조회하여 반환하는 기능을 구현했습니다.테스트 코드 작성 및 검증각 엔드포인트에 대해 단위 테스트를 작성하여 모든 기능이 예상대로 동작하는지 검증했습니다.특히 게시글이 없는 경우와 같은 예외 상황을 처리하는 테스트도 포함시켜 로직의 완성도를 높였습니다.  회고이번 미션을 통해 RESTful한 API 설계의 중요성을 다시 한번 느꼈습니다. 엔드포인트를 직관적이고 간결하게 설계하기 위해 많은 고민을 했으며, 테스트 코드를 작성하며 API 동작을 검증하는 과정에서 테스트의 중요성을 다시 한번 실감할 수 있었습니다.아쉬운 점 및 보완할 점테스트 코드의 가독성과 효율성을 높이기 위해 추가적인 리팩토링이 필요합니다.JPA의 복잡한 연관 관계 처리에서 어려움을 겪었으며, 이러한 부분을 더 명확하게 이해하기 위해 추가적인 학습이 필요합니다.이번 주의 학습과 미션을 통해 부족했던 부분들을 확인할 수 있었고, 앞으로도 지속적인 학습과 실습을 통해 문제를 개선해 나갈 계획입니다. 특히, JPA 연관 관계와 테스트 코드의 리팩토링에 집중하여 더 나은 품질의 코드를 작성하고, 실무에 적용할 수 있도록 역량을 키워가겠습니다.

백엔드인프런워밍업클럽스터디백엔드프로젝트발자국회고SpringBoot

suover

인프런 워밍업 클럽 스터디 2기 - 백엔드 프로젝트 2주차 발자국

입문자를 위한 Spring Boot with Kotlin - 나만의 포트폴리오 사이트 만들기강의와 함께한 인프런 워밍업 클럽 스터디 2기 - 백엔드 프로젝트 (Kotlin, Spring Boot) 2주차 발자국 입니다. 강의 수강이번 주에는 JPA를 활용해 데이터를 초기화하고, 기본적인 CRUD 작업을 진행하면서 프로젝트의 기초적인 부분을 다졌습니다. 강의를 통해 실습을 진행하며, 코드 작성과 실행 과정을 통해 JPA와 Spring Boot에 익숙해질 수 있었습니다. 특히, 강의를 통해 코드를 작성하는 과정에서 JPA의 기본 사용법을 익히는 데 집중했습니다.주요 학습 내용Spring Data JPA의 기본 CRUD 기능 실습엔티티 간의 기본적인 연관 관계 설정JPA와 데이터베이스 초기화를 통한 실습 환경 설정테스트 코드 작성과 JUnit을 활용한 기본적인 테스트 환경 설정 회고강의와 함께 실습 프로젝트를 진행하면서 JPA와 Spring Boot의 기능을 익혔습니다. 이론 학습보다는 코드 작성에 집중하여, Spring Boot와 JPA의 실질적인 사용법을 몸에 익히는 데 중점을 두었습니다. 실습을 통해 프로젝트 구조와 JPA의 기초 개념을 이해하는 데 도움을 받았습니다.칭찬할 점매일 강의를 듣고 실습 프로젝트를 꾸준히 진행한 점새로운 기술을 익히며 이를 프로젝트에 바로 적용해 본 점실습을 통해 테스트 코드 작성법을 익혀본 점 아쉬웠던 점 및 보완할 점강의를 따라가는 데 집중하다 보니 개념적인 이해가 부족한 부분이 있습니다.실습을 통해 얻은 질문이나 궁금증을 정리해두고, 추가적인 학습을 통해 보완할 계획입니다.미션이번 주 미션은 REST API 설계하기로, 사용자가 게시글과 댓글을 작성하고, 좋아요를 추가하거나 삭제할 수 있는 RESTful API를 설계하는 것이 목표였습니다. 이를 통해 사용자 관리, 게시글과 댓글 관리, 좋아요 기능을 포함한 API를 구축했습니다. 미션 과정API 설계사용자 API: 회원가입, 로그인, 로그아웃, 사용자 정보 조회 및 수정, 비활성화 기능을 설계했습니다.게시글 API: 게시글 작성 및 수정, 삭제 기능과 더불어 게시글 목록 조회 및 특정 게시글 조회를 위한 엔드포인트를 설계했습니다. 또한, 좋아요 추가 및 취소 기능도 포함하여 사용자의 상호작용을 풍부하게 했습니다.댓글 및 답글 API: 댓글 작성, 수정, 삭제 기능과 게시글별 댓글 목록을 조회할 수 있는 기능을 설계했습니다. 댓글에 좋아요를 추가하거나 삭제할 수 있는 기능도 포함하여 사용자가 게시물과 댓글에 대해 보다 활발히 상호작용할 수 있도록 했습니다.  구체적인 API 엔드포인트 및 메서드사용자 API: /api/users 및 /api/users/{userId}를 통해 사용자를 관리할 수 있도록 하였고, 로그인, 로그아웃, 비활성화 기능을 위한 별도의 엔드포인트를 설정했습니다.게시글 API: /api/posts 및 /api/posts/{postId}를 통해 게시글 CRUD와 좋아요 기능을 관리할 수 있도록 설계했습니다.댓글 및 답글 API: /api/posts/{postId}/comments 및 /api/comments/{commentId}로 댓글 CRUD와 좋아요 기능을 관리할 수 있도록 했습니다. 회고이번 API 설계는 RESTful한 접근 방식을 유지하며, 간결하고 직관적인 구조를 갖도록 신경을 썼습니다. 테이블 간의 관계를 고려하여 API를 설계하는 과정에서 실무에서의 데이터 흐름과 REST API의 설계 원칙을 이해하는 데 도움이 되었습니다.아쉬운 점 및 보완할 점아직 JPA 관련 용어와 개념이 생소해서, 이해도가 높아지기까지 시간이 걸렸습니다. 다음 주에는 API 설계를 더욱 구체화하고, 실습하면서 느낀 궁금한 점들을 정리해 해결해 나갈 계획입니다.이번 주는 강의를 통해 프로젝트를 진행하고 API 설계를 하는 경험을 통해 많은 것을 배울 수 있었고, 다음 주에도 꾸준히 학습하며 부족한 부분을 보완해 나가겠습니다.

백엔드인프런워밍업클럽스터디백엔드프로젝트발자국회고SpringBoot

zooxop

인프런 워밍업 스터디 클럽 2기 백엔드(클린코드&테스트코드) 발자국 - 2주차

인프런 워밍업 클럽 2기, 백엔드(클린코드&테스트코드) 과정에 참여하고 있습니다.이번 2주차에는 코드를 다듬을 때 기억하면 좋은 스킬과 팁을 배우고, 강사님께서 제공해주신 예제 프로젝트를 직접 리팩토링 해보는 시간을 가졌습니다.강의 링크: Readable Code: 읽기 좋은 코드를 작성하는 사고법  [학습내용 핵심 요약]자세한 설명이나 예제 및 코드는 강의 저작권 보호를 위해 기재하지 않았습니다. 추상주석의 양면성: 코드 품질 저하 vs. 필요한 정보 전달좋은 주석: 의사 결정 히스토리, 코드로 표현 불가능한 정보 전달주석 관리: 자주 변하는 정보 지양, 코드 변경 시 주석 업데이트변수/메서드 나열: 사용 순서, 중요도, 그룹화로 의도 전달패키지 구조: 문맥 정보 제공, 적절한 분할로 관리 용이성 확보패키지 변경: 같은 프로젝트에서 작업하는 팀과 합의 후 변경하는 것이 중요하다.(초기 설계의 중요성)객체 지향 설계로 인해, 버그 수정 용이성이 증가할 수 있다.재귀 알고리즘을 사용할때는 Stack Overflow 에러를 주의해야 한다. 이를 피하기 위해, Stack 자료 구조를 사용할 수 있다.IDE 활용: 코드 포맷팅, 품질 체크 도구(Sonarlint), .editorconfig 사용코드 스타일: 팀과 합의된 기준을 지키는 것이 중요하고, 지속적인 개선을 해나가는 것이 중요하다. 공개/비공개 메서드 배치: 객체의 기능 드러내기메서드 그룹화: 중요도, 종류별 배치로 일관성 유지스택 메모리 이해: 재귀 함수 사용 시 주의점코드 품질 관리를 위해서는 지속적인 리팩토링과 개선에 관심을 갖는 것이 중요하다. 기억하면 좋은 조언들능동적 읽기: 복잡한 코드 이해를 위한 리팩토링 접근법코드 이해 방법: 단락 구분, 추상화, 주석 활용 코드 읽기 목표: 도메인 지식 증진, 작성자 의도 파악오버 엔지니어링: 불필요한 복잡성 증가, 유지보수 어려움인터페이스 남용: 구현체가 하나일 때는 인터페이스를 남용하지 않도록 주의가 필요함이른 추상화 위험: 복잡도 증가, 의도 파악 어려움은탄환은 없다: 클린 코드도 만능 해결책이 아님실무 현실: 품질과 빠른 결과물 사이의 균형클린 코드 사고: 미래 수정 가능성 고려한 코드 작성적정 기술: 상황에 맞는 방법론 적용 중요성도구 사용 능력: 극한 사용과 적절한 제한에 대한 이해 필요적정 수준 파악을 위한 경험 축적을 위해, 클린 코드를 극단적으로 시도해보는 경험이 도움이 된다. 지속적 학습: 다양한 상황 경험을 통한 판단력 향상[후기]강의를 따라하기 전에, 혼자서 리팩토링 하며 고민해보는 시간을 가져본 다음 강사님의 강의를 따라가는 과정이 매우 효과적인 학습법으로 느껴져서 좋았던 시간이었습니다. 리팩토링 할 때 제가 놓친 부분들이 너무 많았던 것 같아 아쉽기도 했지만, 현재 내 실력을 보다 객관적인 관점으로 체감할 수 있었던 시간이라 더 좋았던 것 같습니다.이번 주차에서 배운 내용을 토대로 느낀점은 다음과 같습니다.내가 중요하게 생각했던 도메인의 추상 포인트와 다른 사람이 생각하는 포인트는 매번 다를 수 있다.추상화에 정답은 없고, 현재 시점에 적용할 수 있는 최선의 방법을 찾아내는 것이 그 시기에 할 수 있는 가장 최선의 방법이다.위의 두가지 내용은 계속 머리속에 새기고 있으면 좋을 것 같다는 생각이 들었습니다.이상으로, 2주차 학습 내용 요약과 후기를 정리한 발자국 포스팅을 마칩니다.

백엔드워밍업클럽백엔드리팩터링클린코드테스트코드발자국회고

ykm8864

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

학습 내용리팩토링을 왜할까? 클린코드를 왜 작성할까?우리는 생산을 해냈다고 끝이 아니다. 이후에 조상들이 작성한 코드를 후손들이 유지보수하는 일이 생기기 마련이다. 이에 관련하여 여러가지 방법에 대하여 배워보자추상? 그게 뭔데의미를 담을 수 있는 더 작은 단위, 책임이름짓기단수와 복수의 구분관용어가 아닌 이상 줄임말 자제그 집단만 알 수 있는 은어/방언 사용하지 않기좋은 코드를 많이 보기메서드로의 분리의미를 담을 수 있는 더 작은 단위로 메서드를 분리하기기준 : 추상화되는 의미가 있는가? 이미 이해가 잘 간다면 그대로 두는게 더 나을 수 있다.추상화 레벨 구체에 가깝다 = 추상화 레벨이 낮다. (디테일한 코드 상세) 추상에 가깝다 = 추상화 레벨이 높다. (디테일한 코드를 외부세계로 감싸는 메서드)하나의 세계 안에서는, 추상화 레벨이 동등해야 한다. 내가 너무 주변 레벨에 비해서 구체화시키고 있다면 추상화를 고려해보자매직넘버와 매직스트링의미를 갖고 있으나, 상수로 추출되지 않은 숫자상수를 추출하고 이름을 짓고 의미를 부여함으로서 가독성이 향상될 수 있다.상수로 뺀다는건, 이거는 중요한 숫자야~ 유지보수할때 중요깊게 봐야할 필요가 있을거야~ 라는 의미를 줄 수 있다.  논리 사고의 흐름#최소의 인지적 노력으로 최대의 정보를 제공# 뇌는 한번에 한가지 일 밖에 하지 못한다. 멀티태스킹? 그건 저글링일 뿐이다.뇌에 메모리를 적게 쓰게 하기.Early return논리의 흐름을 빠르게 중단시켜 생각 회로를 단순화 한다.코드 흐름을 단순화하고 가독성을 향상중첩분기, 중첩반복문에 대한 최적화depth를 1로 만들 수 있는지 생각해보기때로는 stream에 대한 활용도 고려할 수 있다.2중 중첩구조 안에도 사고에도움이 된다면 중첩 안에 메서드를 분리하여 두어도 좋다.사용할 변수는 가깝게 선언하기공백라인도 의미를 가진다복잡한 로직의 의미 단위를 나누어 보여줌으로써 읽는 사람에게 추가적인 정보를 전달할 수 있다.부정어를 대하는 자세논리를 거꾸로하여 생각하는 과정을 거친다는 것은 가독 저하의 요인일 수 있다.부정어구를 쓰지 않아도 되는 상황인지 체크하기 (무조건 부정조건으로검사해야하는 상황인지)부정의 의미를 담은 다른 단어자체가 존재하는지 고민하기 or 부정어구로 메서드 명 구성해피케이스와 예외 처리예외가 발생할 가능성 낮추기검증로직은 생성자 or 별도의 분리가 필요의도한 예외와 예상하지 못한 예외를 구분하기Null을 대하는 자세equals작성시 상수를 앞에 둔다.Optional은 비싼 객체라 항상 좋은건 아니지만 값이 있을 수도 있고 없을 수도 있는 상황에는 고려할 수 있다. 이때 멤버변수에 Optional은 좋지 않다. 만들어진 목적이 메서드의 반환타입에 쓰게금 설계되어있다.[orElse() : 괄호 안에 값이 항상 실행orElseGet() : 옵셔널안에 원본값이 null인 경우 실행orElseThrow() : 값이 있으면 쓰고 없으면 예외를 던지겠다. 라는 의미라서 그냥 써도된다.StackTrace는 안티패턴이다. 추상의 관점으로 바라보는 객체 지향객체지향 패러다임객체 간의 협력과 객체가 담당하는 책임객체간의 협력과 객체가 담당하는 책임의 관점으로 추상화를 접목시켜 이해하는 것이 중요하다.관심사의 분리관심사끼리 객체를 분리한다.높은 응집도, 낮은 결합도 유지객체 설계하기객체도 추상화와 같이 객체로 나누는 순간 외부와 경계가 발생한다. 이때 외부세계와 소통을 위해서 공개메서드를 활용한다.객체는 외부로 기능을 제공해준다. (개념의 가시화 = 관심사)비공개필드(데이터), 비공개로직(기능 구현부), 공개 메서드 선언부만 외부로 노출하여 이루어진다.여러 객체를 사용하는 입장에서는 구체적인 구현에 신경쓰지 않고 보다 높은 추상화 레벨에서 도메인 로직을 다룰 수 있다.새로운 객체를 만들 때 주의할 점1개의 관심사로 명확하게 책임이 정의되었는지 확인유효성 검증setter 사용 자제(데이터의 불변성)getter가 꼭 필요한지 생각해보기 (객체에 메시지를 보내서 필요한 정보를 메서드로 가져올 수 없는지?)필드의 수는 적을 수록 좋다. 객체지향 패러다임(SOLID)SRP : ”책임을 볼 줄 아는 눈”전문가가 되어야한다. 하나 이상의 일을 책임지게 되면 업무의 효율성이 떨어지게 된다. 이를 어기면 각각의 역할에 집중할 수 없고 공통 업무의 변화가 생기면 모두 바뀌어야한다.OCP : "기존 코드의 변경 없이 , 시슽템의 기능을 확장할 수 있어야한다. (추상화와 다형성의 활용)"전기콘센트 같은것. 허용 전압 규격만 맞으면 냉장고, 가스레인지 등 모든 가전제품을 사용 가능하다. 가전제품이 늘어나도 규격이 맞으면 사용 가능하고 전기콘센트를 교체할 필요 없다.LSP : "자식클래스는 부모클래스의 책임을 준수하며, 부코클래스의 행동을 변경하지 않아야한다."엄마말을 잘 듣자. 상속의 세계에서는 자식은 부모를 이길 수 없다. 따라서, 자식은 부모의 규칙을 어기거나 변경할 수 없이 말을 잘 들어야한다.ISP : "인터페이스를 기능단위로 잘게 쪼개라"덜어냄의 미학. 흑백요리사에서처럼 인터페이스도 많은 기능(책임)을 가진다고 좋은게 아니다. 필요한 만큼만 가지는게 최고다.DIP : "상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 된다. 둘 모두 추상화에 의존해야 한다."수준에 맞게 놀자. 고수준(추상 : 핵심비지니스 로직) 모듈이 저수준(구체 : 구현세부사항)모듈을 직접적으로 참조하는 것은 저수준모듈의 변경에 민감하게 반응하게된다. 객체지향 적용하기상속과 조합상속보다는 조합을 사용하자상속은 시멘트처럼 굳어진 구조다. (부모와 자식의 결합도가 높다.)조합과 인터페이스를 활용하는 것이 유연한 구조다.상속을 통한 코드의 중복 제거가 주는 이점보다, 중복이 생기더라도 유연한 구조 설계가 주는 이점이 더 크다.상속 : extends → 부모 - 자식 간의 필수 오버라이딩 제약이 없고, 부모의 구현을 자식이 알고있는 관계 → 자식.부모메서드() 로 호출이 가능하여 재사용성이 향상됐다고 볼 수 있지만 객체 지향 관점에서는 캡슐화가 깨진 상태라고도 볼 수 있음조합 : 부모에는 공통 스팩 제공하는 인터페이스를 사용하고, 해당 부모의 구현체들은 부모의 스팩만 유지한 상태라면 부모에 독립적이고 변경이 많아질 수 있는 부분은 부모 클래스에 두지 않고 별도의 클래스로 분리함으로써 캡슐화와 확장성을 지킨다.주입 : 외부에서 부모 클래스나 자식 클래스가 의존하는 객체들을 주입함으로써, 객체 간의 강한 결합을 방지하고, 필요 시 구현체를 쉽게 교체할 수 있게 하여 유지보수와 테스트의 용이성을 높인다.Value Object도메인의 어떤 개념을 추상화하여 표현한 값 객체 값으로 취급하기 위해서, 불변성, 동등성, 유효성 검증 등을 보장해야 한다.엔티티와 vo의 차이(식별자 유무 차이)일급 컬렉션일급시민이란? -> 다른 요소(누군가의 파라미터, 변수, 함수의 결과로 return)에게 사용 가능한 모든 연산을 지원하는 요소일급컬렉션이란?컬렉션을 포장하면서 필드로 무조건 해당 컬렉션 하나만을 가지고 있는 객체컬렉션을 다른 객체와 동등한 레벨로 다루기 위함getter로 컬렉션을 반환할 일이 생긴다면 필드에서 가지고 있는 컬렉션과 같은 참조를 리턴하는 일이 생기지 않도록 new해서 새로운 컬렉션을 반환하자.enum의 특성과 활용상수의 집합변경이 정말 잦은 개념이면 enum보다 db로 관리하는게 좋을 수 있음.다형성 활용하기변하는 것과 변하지 않는 것을 분리하여 추상화하는 것.변하지 않는 것을 지켜야[추상] → 변경에는 닫혀있는 상태를 유지 가능변화하는 것에는 유동적으로 해결이 되어야[구체] → 확장에 열려있는 상태가 된다. 숨겨져 있는 도메인 개념 도출하기완벽한 설계는 없다. 그 당시의 최선이 있을 뿐.도메인 지식은 만드는 것이 아니라 발견하는 것설계할 때는 근시적, 거시적 관점에서 최대한 미래를 예측하려는 시도가 필요하다시간이 지나 만약 틀렸다는 것을 인지하면 언제든 돌아올 수 있도록 코드를 만들어야 한다.미션-> 주어진 코드에 대한 리팩토링얼리리턴추상화레벨 맞추기처리해야할 예외와 그렇지 않은 예외의 분리변수명, 함수명책임의 분리등.. 배운 지식을 활용하여 최적화하는 연습을 해보았다.   1주차 회고Keep (만족했고, 앞으로도 지속하고 싶은 부분)현재 코드를 작성하면서 "조상"과 "후손"이라는 표현을 사용한 점이 인상 깊었다. 이 표현은 코드의 지속성과 유지보수의 중요성을 잘 드러낸다고 생각이 들었다. 실무에서는 생산성과 클린 코드를 상반된 개념으로 보는 경우가 많은데, 이는 조직의 코드 문화에 긍정적이지 않다는 생각도 같이 들곤 했다. 이러한 문화를 개선하기 위한 방법론을 이번 학습을 통해 구체적으로 알게 되어 만족스러웠다..Problem (아쉬웠던 점)처음 보는 코드에 대한 빠른 이해가 부족하다는 점을 느꼈다. 즉, 현재 짜여진 코드를 너무 쉽게 납득해버리는 경향이 있는게 아닌가 싶다. 강사님처럼 코드를 보고 잠재적인 문제와 개선 가능성을 구조적으로 접근하는 시야가 필요하다고 생각한다. 이를 통해 "보는 눈"에 대한 중요성을 느꼈다.Try (다음에 시도해볼 점)구체적인 코드 설계에서 추상과 구체를 명확하게 분리하는 연습을 해보고 싶다. 처음부터 완벽한 설계를 할 수는 없겠지만, 도메인의 책임을 분리하고 리팩토링을 고려한 설계를 시도해봐야겠다. 우선 흐름대로 코드를 작성한 후, 리팩토링을 통해 개선하는 과정을 반복하며 사고력을 기르는 과정을 연습해보아야 할 거 같다.

백엔드워밍업클럽회고자기계발몰입하는개발자BE백엔드

suover

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

입문자를 위한 Spring Boot with Kotlin - 나만의 포트폴리오 사이트 만들기강의와 함께한 인프런 워밍업 클럽 스터디 2기 - 백엔드 프로젝트 (Kotlin, Spring Boot) 1주차 발자국 입니다. 강의 수강이번 주에는 웹 개발의 기본 개념을 학습하며, Spring Boot를 중심으로 한 웹 개발에 대한 전반적인 내용을 다루었습니다. 특히, 웹 서비스의 구성 요소인 클라이언트, 서버, 데이터베이스의 상호작용 방식을 이해하고, 클라이언트와 서버가 데이터를 주고받는 과정에서 발생하는 HTTP 통신과 REST API의 개념을 명확히 정리했습니다.Spring Boot를 활용한 프로젝트 구조와 레이어드 아키텍처(Controller, Service, Repository)를 학습하며, 각 레이어의 역할과 책임에 대해 더욱 깊이 이해할 수 있었습니다. 또한, MVC 패턴과 디자인 패턴의 중요성도 학습하며, 어떻게 하면 코드의 결합도를 낮추고 유지보수성을 높일 수 있는지 고민하는 시간을 가졌습니다. 회고일주일간 강의를 들으면서 웹 개발의 전반적인 흐름과 기본 개념을 더 체계적으로 정리할 수 있었습니다. 이전에도 어느 정도 개념을 알고 있었지만, 이번에는 MVC 패턴이나 레이어드 아키텍처의 필요성에 대해 더 명확히 이해하게 되어 좋았습니다. 프레임워크와 라이브러리의 차이도 명확해져, 앞으로 어떤 상황에서 어떤 도구를 선택할지에 대한 기준이 생긴 것 같아 뿌듯합니다.칭찬할 점매일 꾸준히 강의를 들으며 웹 개발의 기본기를 다진 점학습한 내용을 직접 실습 프로젝트에 적용하면서 이론과 실제를 연결 지은 점이번 주 계획했던 학습 목표를 모두 달성한 점 아쉬웠던 점스프링의 의존성 주입(Dependency Injection)에 대한 이해가 조금 부족하다는 느낌이 있었습니다. 강의에서 개념을 배웠지만, 실제로 이를 프로젝트에 어떻게 적용해야 하는지 고민하는 시간이 좀 더 필요할 것 같습니다. 보완할 점의존성 주입을 주제로 더 깊이 파고들어 실습해보고, 관련된 자료를 찾아보면서 이해도를 높여야겠습니다. 특히, 생성자 주입 방식을 더 명확하게 습득하고 싶습니다. 다음 주 목표다음 주에는 이번 주에 학습한 내용을 바탕으로 더 구체적인 프로젝트를 진행하며, 의존성 주입과 스프링 빈 관리에 대한 이해를 심화할 계획입니다. 이를 통해 Spring Boot의 기능을 제대로 활용할 수 있도록 하겠습니다.미션이번 주 미션은 미니 프로젝트 개발을 주제로, 웹 개발의 기본적인 데이터베이스 테이블을 설계하고 이를 GitHub에 업로드하는 것이 목표였습니다. 프로젝트의 주제는 다양한 활동에서 함께할 사람을 찾고 소통할 수 있는 게시판 서비스로, 사용자, 카테고리, 게시글, 댓글, 그리고 좋아요 기능을 포함한 테이블을 설계했습니다. 미션 과정테이블 설계 사용자 테이블 (users): 사용자의 이메일, 비밀번호, 이름, 닉네임 등을 저장하며, user_role 필드로 사용자 권한을 설정할 수 있습니다.카테고리 테이블 (categories): 게시글의 카테고리를 관리하기 위해 설계된 테이블로, 카테고리 이름을 저장할 수 있습니다.게시글 테이블 (posts): 사용자가 작성한 게시글을 저장하는 테이블로, 사용자와 카테고리와의 관계를 참조하도록 했습니다.댓글 테이블 (comments): 게시글에 달린 댓글을 저장하는 테이블로, 답글까지 고려한 설계를 진행했습니다.좋아요 테이블 (post_likes, comment_likes): 게시글과 댓글에 대한 '좋아요' 기능을 구현하기 위한 테이블을 설계했습니다.  프로젝트 깃허브에 업로드미니 프로젝트를 깃허브에 올리는 작업을 진행했습니다. 이번 작업을 통해 버전 관리와 협업의 중요성을 다시 한번 확인할 수 있었습니다. 회고테이블 설계를 처음부터 끝까지 진행하면서, 데이터베이스 간의 관계를 설계하는 것이 얼마나 중요한지 다시 한번 깨달았습니다. 또한, 테이블 관계를 명확히 이해하지 못했던 부분에서 여러 번 수정을 거치면서 실무적인 감각도 더 키울 수 있었습니다. 특히, 외래 키 제약 조건을 걸어 테이블 간의 참조 무결성을 유지하는 방법을 다시 복습하게 된 것이 큰 수확이었습니다.아쉬운 점테이블 설계를 처음 진행할 때, 부모-자식 관계나 외래 키 제약 조건을 제대로 설정하지 못해 몇 번의 수정을 반복해야 했습니다. 이를 통해 초기 설계의 중요성을 다시 한번 느끼게 되었고, 더 많이 연습해야 한다는 생각이 들었습니다.보완할 점초기 설계 단계에서 더 철저하게 준비하여, 데이터베이스 구조를 명확하게 하고 오류를 최소화하는 방향으로 나아갈 계획입니다.이번 주는 강의와 미션 모두에서 많은 것을 배웠고, 실습을 통해 이론을 실제 프로젝트에 적용하면서 자신감을 얻었습니다. 다음 주에도 꾸준히 학습하며 부족한 부분을 보완해 나갈 계획입니다.

백엔드인프런워밍업클럽스터디백엔드프로젝트발자국회고SpringBoot

세뇨르

인프런 워밍업 클럽2기 백엔드 - 발자국 1주차 (회고)

인프런 워밍업 클럽 2기 발자국 1주차1. 한 주를 돌아보며..인프런 워밍업 클럽, 읽기 좋은 코드를 작성하는 사고법 스터디도 벌써 한 주가 지났다.사실 시간에 비해 한 주 동안 공부해야 할 양이 많은 것은 아니었지만 이해하고 몸으로 체화하는 데 시간을 더 많이 쓴 것 같다.이번 주는 추상 / 논리,사고의 흐름 / 객체 지향 패러다임에 대해 공부했다. Section 1: 추상 (抽象)이번 주에 '추상'에 대해 배웠다. 추상과 구체의 개념, 적절한 이름 짓기의 중요성, 메서드 선언부의 의미, 추상화 레벨 맞추기, 그리고 매직 넘버와 매직 스트링의 사용에 대해 학습했다.추상화 레벨을 맞추는 게 생각보다 어려웠다. 너무 추상적이면 이해하기 어렵고, 너무 구체적이면 코드가 복잡해지는데, 이 balance를 맞추는 게 관건인 것 같다. 매직 넘버를 상수로 바꾸는 건 알고 있었지만, 이게 가독성과 유지보수성에 큰 영향을 미친다는 점을 새삼 깨달았다.Section 2: 논리, 사고의 흐름인지적 경제성, Early return, 사고의 depth 줄이기, 공백 라인과 부정어 사용, 해피 케이스와 예외 처리, 그리고 stream API와 Optional 사용에 대해 배웠다.Early return이 코드의 가독성을 크게 높인다는 점이 인상 깊었다. 지금까지 작성한 코드를 되돌아보니 불필요하게 복잡한 구조가 많았던 것 같다. 또한, 부정어 사용을 줄이는 것이 생각보다 어려웠는데, 이를 위해 메서드 추출 등의 방법을 사용할 수 있다는 점이 새로웠다.Section 3: 객체 지향 패러다임객체 간 협력과 책임, 관심사의 분리, getter/setter 사용 자제, 객체에 메시지 보내기, SOLID 원칙, 그리고 DI/IoC에 대해 학습했다.getter/setter를 무분별하게 사용하는 것이 객체 지향적이지 않다는 점을 배웠다. 객체에 메시지를 보내는 방식으로 코드를 작성하는 것이 더 객체 지향적이라는 점이 인상 깊었다. SOLID 원칙은 들어본 적은 있었지만, 실제로 적용하는 것은 쉽지 않을 것 같다. 특히 단일 책임 원칙(SRP)을 지키는 것이 가장 어려울 것 같다. 2. 미션이번 주에는 추상과 구체에 대해 생각해보고 생각나는 추상과 구체의 예시를 적어보는 미션이었다. (Day2)나는 러닝으로 추상과 구체를 나누어 보았다.러닝을 한다.- 오른발 뒤꿈치가 지면에 닿으며, 발바닥이 지면을 따라 앞으로 구르듯 펴진다.- 오른발이 지면을 밀어내는 동안, 왼발은 지면에서 떨어지면서 무릎이 구부러지고 몸 앞쪽으로 들어 올려진다.- 왼발이 앞으로 나아가는 동시에 오른팔이 앞으로 움직이고, 왼팔은 뒤로 젖혀진다.- 몸통이 약간 앞으로 기울어진 채 오른발을 축으로 전방으로 회전하듯 움직인다.- 왼발 뒤꿈치가 지면에 닿으면서 1-4번 과정이 반대 방향으로 반복된다.'러닝'이라는 추상적인 개념을 구체적인 동작으로 풀어 설명했다. 처음에는 '달린다'라고만 생각했는데, 실제로 각 동작을 하나하나 떠올려보니 생각보다 복잡한 과정이었다. 이런 식으로 추상적인 개념을 구체화하는 연습을 하면 코드 작성 시에도 도움이 될 것 같다. 또 다른 미션은 코드를 리팩토링하는 것과 SOLID 원칙을 정리하는 미션이었다. (Day4)https://www.inflearn.com/blogs/8385[미션 Day4] 코드 리팩토링주어진 validateOrder 메서드를 리팩토링했다. Early return 패턴을 적용하고, 반복되는 로직을 Order 클래스의 메서드로 추출했다. 또한 부정 조건문을 제거하여 가독성을 향상시켰다.이렇게 접근한 이유는 다음과 같다:Early return으로 코드의 depth를 줄여 가독성을 높였다.Order 클래스에 메서드를 추가하여 객체의 책임을 명확히 하고 캡슐화를 강화했다.부정 조건문을 제거하여 코드의 의도를 더 명확히 했다.리팩토링 과정에서 가장 어려웠던 점은 적절한 메서드명을 짓는 것이었다. hasNoItems(), isInvalidTotalPrice() 등의 이름을 고민하는 데 시간이 꽤 걸렸다. 하지만 이런 고민이 결국 코드의 가독성을 높인다는 것을 깨달았다. SOLID 원칙 정리SOLID 원칙을 정리하면서, 각 원칙이 왜 중요한지 깊이 생각해볼 수 있었다. 특히 DIP(의존성 역전 원칙)가 어떻게 코드의 유연성을 높이는지 이해하는데 시간이 좀 걸렸다. 실제 프로젝트에서 이 원칙들을 적용해보면 코드의 구조가 훨씬 개선될 것 같다는 생각이 들었다. 정리이번 미션을 통해 추상화의 개념을 실제로 적용해보고, 코드 리팩토링의 중요성을 체감할 수 있었다. SOLID 원칙을 정리하면서 객체 지향 설계의 핵심을 이해하게 되었다. 앞으로는 이런 원칙들을 항상 염두에 두고 코드를 작성해야겠다는 생각이 들었다. 다만, 이론적으로 아는 것과 실제로 적용하는 것은 큰 차이가 있을 것 같다. 앞으로 더 많은 연습이 필요할 것 같다.다음 주에는 이번 주 내용도 다시 복습하면서 강의 내용을 더 깔끔하게 정리해 봐야 겠다.

회고1주차

zooxop

인프런 워밍업 스터디 클럽 2기 백엔드(클린코드&테스트코드) 발자국 - 1주차

인프런 워밍업 클럽 2기, 백엔드(클린코드&테스트코드) 과정에 참여하고 있습니다.이번 1주차에는 클린 코드를 추구하는 이유와 클린한 코드를 작성하는 방법, 객체 지향적 사고, 객체 지향으로 프로젝트를 리팩토링하는 디테일한 스킬을 예제와 함께 배웠습니다.강의 링크: Readable Code: 읽기 좋은 코드를 작성하는 사고법  [학습내용 핵심 요약]자세한 설명이나 예제 및 코드는 강의 저작권 보호를 위해 기재하지 않았습니다. 1. 추상클린 코드의 목적: 가독성 향상, 유지보수 용이성 증대, 시간과 자원 절약추상화: 중요 정보 추출, 불필요 정보 생략하는 과정컴퓨터에서 추상화: 복잡한 데이터와 로직 단순화, 이해도 향상적절한 추상화: 도메인 문맥 고려, 핵심 개념만 표현이름 짓기: 추상적 사고 기반, 도메인 문맥 내 이해 가능한 용어 사용메서드 추상화: 단일 책임 원칙, 명확한 의도 전달메서드 선언부: 적절한 메서드명, 파라미터, 반환 타입 선택추상화 레벨: 동일한 추상화 수준 유지, 일관성 있는 코드 작성매직 넘버/스트링 제거: 상수 추출로 의미 부여, 가독성 향상좋은 코드 습득: 업계 표준 용어 학습, 지속적인 개선 2. 논리, 사고의 흐름뇌 메모리 효율화: 최소 인지 노력으로 최대 정보 제공범주화와 인지적 경제성: 효율적 정보 처리 위한 핵심 전략Early return: 코드 가독성 향상, 불필요한 중첩 구조 제거사고의 depth 줄이기: 반복문, 조건문 구조 단순화, 변수 근접 선언부정어 사용 주의: 긍정 표현 선호, 메서드명에 부정 의미 포함 고려해피 케이스와 예외 처리: 예외 발생 가능성 최소화, 의도적/비의도적 예외 구분Null 처리: NullPointerException 방지, Optional 활용 고려Optional 사용 지침: 반환 타입에만 사용, 파라미터로 받지 않기, 빠른 해소Optional 해소 방법: 풍부한 API 활용 (orElseGet, orElseThrow, ifPresent 등)orElse, orElseGet, orElseThrow 차이 이해: 실행 시점과 용도 구분즉시 평가와 지연 평가 개념 숙지: Optional 메서드 사용 시 고려 3. 객체 지향 패러다임객체 지향: 추상화된 데이터와 코드의 결합, 객체 간 협력과 책임 중시관심사의 분리: 높은 응집도, 낮은 결합도 추구객체 설계: 비공개 필드/로직, 공개 메서드로 외부와 소통객체 생성 주의점: 단일 책임, 생성자에서 유효성 검증, setter 자제getter 사용 최소화: 객체에 메시지 전송 권장필드 수 최소화: 복잡도 감소, 불필요한 데이터 제거SOLID 원칙: 객체 지향 설계의 기본 원칙들SRP: 단일 책임 원칙, 변경 이유 하나로 제한OCP: 확장에는 열려있고, 수정에는 닫혀있어야 함LSP: 상속 관계에서 하위 클래스가 상위 클래스를 대체 가능해야 함ISP: 인터페이스 분리, 불필요한 의존성 제거DIP: 추상화에 의존, 의존성 역전을 통한 유연성 확보도메인 지식: 만드는 것이 아닌 발견하는 것의존성 주입(DI)과 제어의 역전(IoC) 개념 이해 4. 객체 지향 적용하기상속보다 조합 선호: 유연성 증가, 결합도 감소Value Object: 도메인 개념 추상화, 불변성/동등성/유효성 보장VO vs Entity: 식별자 유무와 동등성 판단 기준 차이일급 컬렉션: 컬렉션을 포장한 객체, 가공 로직 포함 가능Enum 활용: 상수 집합과 관련 로직 관리, 도메인 개념 명시적 표현다형성 활용: 반복적 if문 단순화, OCP 원칙 적용변하는 것과 변하지 않는 것 분리: 추상화와 구체화 구분도메인 개념 도출: 발견하는 과정, 현실 세계 흉내내기설계 접근: 근시적/거시적 관점에서 미래 예측유연한 코드 작성: 변경 가능성 고려, 재설계 용이성 확보완벽한 설계 없음: 현 시점 최선의 설계 추구일급 시민 개념: 변수 할당, 파라미터 전달, 함수 반환 가능컬렉션 반환 시 주의: 새로운 컬렉션으로 복사하여 반환Enum vs DB: 변경 빈도에 따른 선택객체 지향 설계: 현실 세계 완벽 반영이 아닌 모방  [고민했던 점]섹션 5. 객체지향 적용하기 중 CellPosition 을 분리하는 부분에 대한 강의를 들을 때, 강사님이 치고 계신 코드가 Minesweeper 파일인지 GameBoard 파일인지 헷갈릴때가 많았습니다. 강의를 멈추고 코드를 다시 읽어보다보니, 어떤 클래스에 들어있는지 한눈에 안들어오거나, 위치가 기억이 잘 안나거나 헷갈리는 메서드가 꽤 많았다고 느꼈습니다.Cell 이나, GameLevel, Handler 는 명확한 느낌을 받았습니다. Cell 안에 들어있는 메서드는 명확하게 Cell 에 대한 update 또는 get 동작을 수행하도록 설계되어 있다고 느꼈기 때문입니다.그런데 제 머릿속에는 "지뢰찾기" 라는 게임 그 자체에 "Board" 라는 개념이 항상 함께하는데, 그 "Board"를 Minesweeper 가 아닌 다른 파일로 쪼개놓았기 때문에 메서드의 위치가 헷갈린다는 느낌을 받았습니다. 제가 생각하기에는, GameBoard 라는 클래스가 일반적인 Board 기반 게임이 아닌, "지뢰찾기"에 특화된 로직을 포함하고 있기 때문에 헷갈린다는 느낌이 강하게 드는 것 같습니다. 예를 들어, initialize() 메서드 내부에는 Cell을 지뢰 칸으로 설정하는 로직과 숫자 칸으로 설정하는 로직이 녹아들어 있습니다. "지뢰찾기"만을 위한 로직이 녹아있는 것입니다. 그렇다면..?1. 추가적인 추상화?처음에는 GameBoard 내의 지뢰찾기 관련 로직을 별도의 클래스로 분리하는 것을 고려했습니다. 하지만 이는 "이른 최적화"의 함정에 빠질 수 있다는 생각이 들었습니다.2. 현실적인 접근현재로서는 이 GameBoard를 다른 보드 게임에 재사용할 계획이 없습니다. 따라서 과도한 추상화는 오히려 코드의 가독성을 해칠 수 있다고 판단했습니다. 결론지금으로서는 가장 좋은 방법은 GameBoard 라는 클래스 이름을 MinesweeperBoard 라는 이름으로 바꾸는게 좀 더 낫지않을까? 라는 결론을 내리는것이 가장 최선의 선택이 아닌가 싶습니다. 애초에 GameBoard 라는 이름이 추상적인 "Game"으로 시작하기 때문에, initialize 내부에 지뢰찾기와 관련된 로직이 녹아있는 것이 어색하게 느껴진것 아닌가? 라는 생각입니다. 그래서 클래스의 이름을 좀 더 구체적으로 변경하면, 비교적 덜 헷갈리지 않을까? 라는 생각입니다. 이상으로, 1주차 학습 내용 요약과 강의를 들으며 고민해봤던 내용을 정리한 발자국 포스팅을 마칩니다.

백엔드워밍업클럽백엔드클린코드테스트코드발자국회고

lar

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

1. 3주차 학습한 내용 [10일차 - 객체지향과 JPA 연관관계]1. JPA 연관관계에 대한 추가적인 기능들1:1 관계 - @OneToOne예) 한 사람은 한 개의 실거주 주소만을 갖고 있다.@OneToOne 어노테이션을 사용한다.연관관계 주인이 아닌 쪽에 mappedBy 옵션을 사용한다.연관관계의 주인 효과객체가 연결 기준이 된다.상대 테이블을 참조하고 있으면 연관관계의 주인이다.연관관계 주인이 아니면 mappedBy를 사용한다.연관관계의 주인의 setter가 사용되어야만 테이블을 연결한다.연관관계의 사용 시 주의해야 할 점트랜잭션이 끝나지 않았을 때, 한 쪽만 연결해두면 반대 쪽은 알 수 없다. > setter 한번에 둘이 같이 이어주면 된다.N:1 관계 - @ManyToOne과 @OneToMany@ManyToOne을 단방향으로만 사용할 수도 있다.cascade 옵션 : 한 객체가 저장되거나 삭제될 때, 연결되어 있는 객체도 함께 저장되거나 삭제되는 옵션이다.orphanRemoval 옵션 : 객체간의 관계가 끊어진 데이터를 자동으로 삭제하는 옵션이다.실제 DB에서 데이터를 삭제하고 싶을 때 사용한다.@JoinColumn연관관계의 주인이 활용할 수 있는 어노테이션을 의미한다.필드의 이름, null여부, 유일성 여부, 업데이트 여부 등을 지정한다.N:M 관계 - @ManyToMany구조가 복잡하고, 테이블이 직관적으로 매핑되지 않아 사용하지 않는 것을 권장한다.도메인 계층에 비즈니스 로직이 들어갔다?BookService는 UserLoanHistory 객체를 직접 사용하지 않도록 변경하였다.User와 UserLoanHistory, 2개의 객체가 서로 협력하도록 변경하였다. 이를 도메인 계층에 비즈니스 로직이 들어갔다라고 표현한다.2. 영속성 컨텍스트의 4번째 특징지연 로딩(Lazy Loading) : 연결되어 있는 객체를 꼭 필요한 순간에만 가져온다.@OneToMAny의 fetch 옵션이다.(기본적으로 Lazy로 설정되어 있다.)연관관계를 사용하면 무엇이 좋을까?각자의 역할에 집중하게 된다. (=응집성)새로운 개발자가 코드를 읽을 때 이해하기 쉬워진다.테스트 코드 작성이 쉬워진다.연관관계를 사용하는 것이 항상 좋을까?지나치게 사용하면 성능 상의 문제가 생길 수도 있고, 도메인 간의 복잡한 연결로 인해 시스템을 파악하기 어려워질 수 있다.비즈니스 요구사항, 기술적인 요구사항, 도메인 아키텍쳐 등 여러 부분을 고민해서 연관관계 사용을 선택해야 한다.[11일차 - 기본적인 배포를 위한 준비]1. 배포란?최종 사용자에게 SW를 전달하는 과정을 의미한다.전용 컴퓨터(AWS)에 우리의 서버를 옮겨 실행시키는 것이다.최종 사용자가 우리의 서버를 쓸 수 있는 방법전용 컴퓨터에 코드를 옮기고 스프링, MYSQL 등을 설치해 사용자가 접속하게 한다.AWS에서 컴퓨터를 빌릴 때 알아둬야 할 점컴퓨터를 살 때 운영체제도 같이 선택한다.윈도우, 리눅스, 맥OS2. profile과 H2 DBprofile 적용스프링 서버를 실행할 때 db와 같은 설정들을 코드 변경 없이 제어할 수 있는 방법spring: config: activate: on-profile: local datasource: url: "jdbc:h2:mem:library;MODE=MYSQL;NON_KEYWORDS=USER" username: "sa" password: "" driver-class-name: org.h2.Driver jpa: hibernate: ddl-auto: create properties: hibernate: show_sql: true format_sql: true dialect: org.hibernate.dialect.H2Dialect h2: console: enabled: true path: /h2-console --- spring: config: activate: on-profile: dev datasource: url: "jdbc:mysql://localhost/library" username: "root" password: "" driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: none properties: hibernate: show_sql: true format_sql: true dialect: org.hibernate.dialect.MySQL8Dialect 3. git과 githubgit이란?코드를 쉽게 관리할 수 있도록 해주는 버전 관리 프로그램을 의미한다.버전 A, 버전 B를 쉽게 만들 수 있게 해주고 여러 버전을 쉽게 취합이 가능하다.github이란?git으로 관리되는 프로젝트의 코드가 저장되는 원격 저장소를 의미한다.왜 github에 코드를 저장하는걸까?컴퓨터의 있는 소스코드가 소실될 수 있기 때문에 코드를 원격의 저장하는 것이다.배포할 때도 활용한다.4. git 기초 사용법git을 활용해서 github 프로젝트 업로드하기github 사이트 접속github 저장소 생성한다.(Create Repository)IntelliJ Terminal을 이용해 git 명령어 입력git 프로젝트 시작하기 / git init : 이 프로젝트를 이제 git이 관리하겠다는 의미git 프로젝트의 github 저장소 설정하기 / git remote add origin [각자의 주소]기초 셋팅 완료git 기초 명령어코드를 git에 추가할 때 명령어git add.git에 메세지 붙이는 명령어git commit-m "메세지"git을 github에 보내기git push현재 상황 확인하기git status파일들 빼주기git reset5. AWS의 EC2 사용하기회원가입AWS 계정 생성(회원가입) - 회원정보/결제정보/본인인증/Support 플랜 (무료) 선택로그인루트 사용자 선택 - 계정입력 후 로그인콘솔 홈지역(서버) 서울로 설정서비스에서 EC2 검색 및 클릭 - 리소스 : 인스턴스(빌린 컴퓨터) 클릭인스턴스 시작 클릭 - 이름 및 태그 : 이름 입력 - 아마존 리눅스 선택 - 인스턴스 유형(빌린 컴퓨터의 사양) CPU 및 메모리 t2.micro 선택 - 키 페어 : 새 키 페어 생성 - 키 페어 이름 입력 수 생성 - 네트워크 설정 : 보안 그룹 생성 선택 - 스토리지 구성(용량) 8gib - 설정 후 인스턴스 시작 클릭인스턴스 목록을 보면 실행 중인 서버가 확인된다. [12일차 - AWS와 EC2 배포]1. EC2에 접속해 리눅스 명령어 다뤄보기다운로드 받은 키 페어를 이용하는 방법우리가 접속하려는 EC2의 IP 주소 : 퍼블릭 IPv4 주소이전 시간에 다운로드 받았던 키 페어접속하기 위한 프로그램(git CLI 또는 Mac treminal)기본적인 리눅스 명령어mkdir : 폴더를 만드는 명령어ls : 현재 위치에서 폴더 또는 파일을 확인하는 명령어cd : 폴더 안으로 들어가는 명령어pwd : 현재 위치를 확인하는 명령어2. 과제여섯 번째 과제(6일차)일곱 번째 과제(7일차)3. 회고프로젝트 배포 하는 법을 알 수 있어서 좋았고, 배포를 하면서 오류가 발생해서 한번에 되지 않아 시간이 오래 걸렸다. 리눅스에 대한 공부도 해야겠다는 생각이 들었다. 아직 미니 프로젝트를 진행하진 못했지만 배운 것을 활용해서 잘 마무리해야겠다!

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

lar 6개월 전
슬프구나

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

FE 강의 진도율 100% 달성자바스크립트 과제 완료음식 메뉴 앱가위 바위 보 앱퀴즈 앱책 리스트 나열 앱Github Finder 앱비밀번호 생성 앱타이핑 테스트 앱리액트 과제 완료예산 계산기 앱디즈니 플러스 앱포켓몬 도감 앱리덕스를 이용한 쇼핑몰 앱(Nextjs 사용) 드디어, 3주가 다 지나갔다.강의는 라디오를 청취하듯이 듣고, 과제를 진행하면서 막히는 경우에 재청취 하였다.자바스크립트 강의는 총 12시간, 리액트 강의는 총 18시간 분량이었는데 청취하면서 사실 쉽지는 않았다. 아는 내용은 가볍게 넘기기도 하였다. 개인적으로 좋았던 점은 강의에 대부분의 내용이 담겨있어서 복습하기 좋았다. 그리고 리액트 강의에서는 React v18 에 추가된 부분도 있고 Docker 를 사용하여 컨테이너 기반으로 리액트 프로젝트를 해보는 강의도 있어서 좋았다.React v18 에 제일 큰 변화는 향상된 automation batching 과 Suspense 가 SSR도 지원하여 Streaming HTML 이 아닐까 생각한다. SSR은 데이터가 다 준비가 되고 렌더링이 될 때까지 기다려야 한다. 하지만 리액트팀은 이러한 부분을 개선하여 UX를 향상 시켰다. 해당 스터디를 참여를 해야하나 조금 고민을 했었다. 혼자서 공부가 가능한 내용들이기 때문이었는데 결론적으로는 참여하길 잘 했다고 생각한다. 반 강제적이긴 하지만 과제들을 하면서 복기를 할 수 있었고 강의를 들으면서 내용을 다시 한번 흩어볼 수 있어서 유익한 시간이었다. 리액트 과제같은 경우에는 전부 TS 를 기반으로 작성 하였다. JS를 활용한 프론트엔드 또는 백엔드 개발에서 TS는 사실 이제 필수라고 생각한다. JS 자료형이 외부 도구에 의존을 해야 할 만큼 나쁜가? 라고 생각을 한다면 꼭 나쁘다고 단정 지을 수는 없다. 아무래도 동적 타이핑에서 발생하는 문제를 해결해주는 가치가 크기 때문이 아닐까 생각한다.동적 타이핑은 값이 할당 된 순간 타입이 결정이 되므로, 타입 관련 에러가 런타임 환경에 발생할 수 있다.동적 타이핑은 값이 할당 된 순간 타입이 결정이 되므로, 타입 관련 에러가 발생 했을 때 규모가 큰 프로젝트에서 이를 추적하기 어렵거나 예측하기 어렵다.위 문제를 해결하고자 우리는 TS 를 사용한다. 조기에 더 많은 오류를 포착해주기 때문이다. 그리고 정적 타이핑을 통한 코드 가독성이 향상 된다.(어떤 함수를 호출한다고 가정하면, 해당 인자가 어떤 타입인지 추론이 가능하기 때문이다)TS 를 사용함으로써 제일 큰 이점은 리팩토링이다. 예를 들어, API Response 명세가 바뀌었다고 가정하자. 프론트엔드단에서 이 명세에 맞게 모델을 바꿔야 할 거다. 해당 모델에 대한 타입이 정의가 되어있으므로 우리는 자신있게 이 부분을 리팩토링 할 수 있다.(틀리면 바로 에러로 알려주기 때문이다.)만약, 그냥 JS 환경이라면 실행이 잘 될수도 있고 놓친 부분이 있다면 런타임에서 에러가 발견이 될 거다. Angular 는 애초에 First party 로 TS 를 사용해 왔다.Vue, React 는 이후에 지원을 하기 시작했다. 이런거 보면, Angular 를 관리하는 구글이 선견지명이 있는거같다. 그렇지만, TS도 만능은 아니다.TSC 를 통해 나온 컴파일 결과물인 js 파일들을 확인해보면, TS 관련 코드들은 전부 사라져 있다. 결국에는 완벽하게 런타임 오류를 완전히 방지하지는 못한다. 그리고 TS를 사용하면 코드량이 증가하며 학습 비용이 발생하므로 이 부분도 프로젝트 규모의 따라 고민을 해보면 좋을 것 같다.(킹치만, 사용 안하면 너무 불안한걸?)

프론트엔드인프런워밍업클럽FE1기회고

lar

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

1. 2주차 학습한 내용 [6일차 - 스프링 컨테이너의 의미와 사용 방법]1. UserController와 스프링 컨테이너스프링 빈이란?서버가 시작되면, 스프링 서버 내부에 컨테이너를 생성한다.컨테이너 안에 클래스가 들어간다.이때 다양한 정보도 들어있고, 인스턴스화도 이루어진다.들어간 클래스를 스프링 빈이라고 한다.JdbcTemplate 의존성 주입이 되어있다.JdbcTemplate을 스프링 빈으로 등록해주는 설정 코드가 있다.dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' } 서버 시작 시스프링 컨테이너 시작 -> 기본적으로 많은 스프링 빈 등록 -> 우리가 설정한 스프링 빈(UserController) 등록 -> 의존성 자동으로 설정스프링 빈으로 등록각 클래스가 JdbcTemplate을 가져오기 위해 스프링 빈으로 등록한다.어노테이션 추가한다.2. 스프링 컨테이너를 왜 사용할까?Interface 활용BookController는 BookService을 사용한다.BookService는 BookRepository 인터페이스 사용한다.또 다른 Repository(Repository1, Repository2)가 있다. BookService 코드를 변경하지 않고 BookRepository을 변경할 수 있는 방법이 스프링 컨테이너이다.스프링 컨테이너 사용시컨테이너가 Repository1 또는 Repository2 중 하나를 선택한 후 BookService를 생성해준다. 이러한 방식을 제어의 역전(IoC, Inversion of Control)이라고 한다.컨테이너가 BookService를 생성할 때, Repository1와 Repository2 중 하나를 선택해서 넣어준다. 이러한 과정을 의존성 주입(DI, Dependency Injection)이라도 한다.우선권을 부여하는 어노테이션 활용@Primary : 우선권을 결정하는 어노테이션을 의미한다.@Primary 어노테이션을 사용 시 Service 코드 변경없이 해당 Repository를 사용할 수 있다.3. 스프링 컨테이너를 다루는 방법빈을 등록하는 방법@Configuration클래스에 붙이는 어노테이션이다.@Bean을 사용할 때 함께 사용해야 한다.@Bean메서드에 붙이는 어노테이션이다.메서드에서 반환하는 객체를 스프링 빈에 등록한다.@Configuration과 @Bean 사용하는 경우외부 라이브러리, 프레임워크에서 만든 클래스를 등록할 때 사용한다.@Component주어진 클래스를 컴포넌트로 간주한다.이 클래스들은 스프링 서버를 시작할때 자동으로 감지된다.언제 @Component가 사용될까?Controller, Service, Repository가 아닌 추가적인 클래스를 스프링 빈으로 등록할 때 종종 사용된다.스프링 빈 주입 받는 방법생성자 사용(@Autowired 생략 가능) -> 가장 권장한다.@Setter와 @Autowired 사용 -> 누군가 Setter를 사용하면 오작동할 수 있다.필드에 직접 @Autowired 사용 -> 테스트를 어렵게 만드는 요인이다.@Qualifer("value") 사용여러가지 후보군이 있을 때 특정 하나를 가져오고 싶을때 사용한다.스프링 빈을 사용하는 쪽과 스프링 빈을 등록하는 쪽 모두 사용할 수 있다.적어준 값이 동일한 것끼리 연결된다.@Primary와 @Qualifer 함께 사용할 경우우선권을 결정해주는 @Primary와 @Qualifer을 함께 사용했을 때 누가 사용될까?@Qualifer을 사용한다.> 스프링 빈을 사용하는 쪽에서 특정 빈을 지정해준 것의 우선순위를 더 높게 간주한다.  [7일차 - Spring Data JPA를 사용한 데이터베이스 조작]1. 문자열 SQL을 직접 사용하면 좋지 않은 이유문자열을 작성하기 때문에 실수할 수 있고, 실수를 인지하는 시점이 느리다. 컴파일 시점에 발견되지 않고 런타임 시점에 발견된다.특정 데이터베이스에 종속적이게 된다. DB의 종류마다 문법이 조금씩 다르다.반복 작업이 많아진다. 테이블 하나 만들 때마다 CRUD 쿼리가 항상 필요하다.데이터베이스의 테이블과 객체는 패러다임이 다르다.2. JPA(Java persistence API)JPA란?자바 진영의 ORM(Object-Relational Mapping) 기술 표준을 의미한다.객체와 관계형 DB의 테이블을 매핑하여 데이터를 영구적으로 저장할 수 있도록 정해진 Java 진영의 규칙을 의미한다.Hibernate규칙을 구현한 구현체를 Hibernate(하이버네이트)라고 한다.Hibernate는 내부적으로 JDBC를 사용한다.3. 유저 테이블에 대응되는 Entity Class 만들기 - Java 객체와 MySQL Table 매핑하기JPA 어노테이션@Entity : 저장되고, 관리되어야 하는 데이터를 의미한다.@Id : 해당 필드를 primary key로 간주한다.@GeneratedValue : primary key는 자동 생성되는 값이다.@Column(생략 가능) : 객체의 필드와 Table의 필드를 매핑한다.기본 생성자 추가기본 생성자도 추가해야 한다.@Entity public class User { protected User() { } } application.yml - JPA 설정 옵션 추가spring: jpa: hibernate: ddl-auto: none properties: hibernate: show_sql: true format_sql: true dialect: org.hibernate.dialect.MySQL8Dialect 4. Spring Data JPA 사용 - 자동으로 쿼리 전송하기SQL을 작성하지 않고 유저 생성/조회/업데이트 기능 리팩토링하기유저 생성 기능 리팩토링하기Interface UserRepository인터페이스 UserRepository 생성 후 JpaRepository를 상속 받는다.UserServicesave() 메서드에 객체를 삽입하면 Insert SQL이 자동으로 전송된다.저장이 된 후 User에는 id가 들어간다. 유저 조회 기능 리팩토링하기UserResponse 생성자 추가코드를 더 깔끔하게 만들기 위해 생성자를 추가한다.UserServicefindAll 메서드를 사용하면 모두 유저의 데이터를 조회하는 SQL이 전송된다.그 결과, List가 반환되고, UserResponse로 변경해서 전달한다.유저 수정 기능 리팩토링하기UserfindById를 사용하면 id를 기준으로 1개의 데이터를 가져온다.Optional의 orElseThrow를 사용해 User가 없을 경우 예외처리한다.객체를 수정해주고, save 메서드를 호출한다.자동으로 UPDATE SQL이 전송된다.SQL을 작성하지 않아도 동작 하는 이유Spring Data JPA를 통해 SQL을 작성하지 않아도 동작한다.Spring Data JPA : 복잡한 JPA 코드를 스프링과 함께 쉽게 사용할 수 있도록 도와주는 라이브러리이다.5. Spring Data JPA 사용 - 다양한 쿼리 작성하기By 앞에 들어갈 수 있는 구절 정리find : 데이터 1건을 가져온다. 반환 타입은 객체, Optional<타입>이다.findAll : 쿼리의 결과물이 N개인 경우 사용한다. List<타입>을 반환한다.exists : 쿼리 결과가 존재하는지 확인한다. 반환 타입은 boolean이다.count : SQL의 결과 개수를 센다. 반환 타입은 long이다.각 구절은 and 또는 or로 조합할 수 있다.By 뒤에 들어갈 수 있는 구절 정리GreaterThan : 초과GreaterThanEqual : 이상LessThan : 미만LessThanEqual : 이하Between : 사이에StartsWith : ~로 시작하는EndsWith : ~로 끝나는 [8일차 - 트랜잭션과 영속성 컨텍스트]1. 트랜잭션(Transaction)트랜잭션이란?쪼갤 수 없는 업무의 최소 단위를 의미한다. (모두 성공하거나 실패하는 경우)트랜잭션 동작 명령어트랜잭션 시작하기 : start transaction;트랜잭션 정상 종료하기 (SQL 반영) : commit;트랜잭션 실패 처리하기 (SQL 미반영) : rollback;2. 트랜잭션 적용과 영속성 컨텍스트트랜잭션 적용하기@Transactional 어노테이션을 사용한다.@Service public class UserServiceV2 { //조회 - readOnly 옵션 사용 가능(SELECT 쿼리) @Transactional(readOnly = true) public List<UserResponse> getUsers() { return userRepository.findAll().stream().map(UserResponse::new).collect(Collectors.toList()); } } 메서드가 시작될때 Transactional 시작된다.메서드 로직이 정상적으로 성공하면 commit되고, 문제가 생길 경우 rollback된다.트랜잭션을 사용 하는 이유트랜잭션이 없으면 코드가 한줄 한줄 반영된다.오류가 생겨도 다른 코드는 반영된다.주의사항org.springframework.transaction.annotation.Transactional을 붙여야 한다.IOException과 같은 Checked Exception은 롤백이 일어나지 않는다.영속성 컨텍스트이란?테이블과 매핑된 Entity 객체를 관리 및 보관하는 역할을 의미한다.트랜잭션과 영속성 컨텍스트의 관계트랜잭션 사용 -> 영속성 컨텍스트 시작트랜잭션 종료 -> 영속성 컨텍스트 종료영속성 컨텍스트의 특징변경 감지(Dirty Check) : 영속성 컨텍스트 안에서 확인된 Entity는 명시적으로 save하지 않아도 변경을 감지해서 자동으로 저장한다.쓰기 지연 : DB의 INSERT/UPDATE/DELETE SQL을 바로 전송하지 않고, 트랜잭션이 commit될 때 SQL을 모아서 한번만 전송한다.1차 캐싱 : ID를 기준으로 Entity를 기억한다. 최초 1회만 쿼리가 전송되고, 나머지는 보관하고 있는 데이터를 활용한다. 이렇게 반환된 객체는 동일하다. [9일차 - 조금 더 복잡한 기능을 API로 구성하기]1. 책 생성/대출/반납 기능 API 개발하기book 테이블 및 객체 생성, DTO, Repository, Service, Controller 구현대출 기록에 대한 Table 추가, 대출 기록 Table에 대한 객체 생성, DTO, Repository, Service, Controller 구현생성한 테이블로 구현이 충분하지만, DTO를 새로 만드는 게 낫다.다른 기능들 중 한 기능에 변화가 생길 경우 더 유연하게 side-effect가 없이 대처가 가능하기 때문이다.2. 미션네 번째 과제(4일차)다섯 번째 과제(5일차)3. 회고1주차보다 학습한 내용이 많아진 만큼 정리를 잘하고 공부를 많이 해야겠다고 느꼈다. 금요일에 해주신 특강도 너무 도움이 되었다. 내용이 나한테는 아직 어려웠지만 다른 사람들의 코드를 보면서 나도 좀 더 고민해보고 코드를 짜고 과제도 해봐야겠다.

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

lar 6개월 전
슬프구나

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

2주차는 드디어 본격적으로 리액트와 Next.js 를 하는 주간이었다! useState()useEffect()useLayoutEffect()useRef()useMemo()useCallback()useContext()useReducer()등에 다양한 훅을 복습 하였다. 리액트 훅은 16.8 에 추가가된 기능이다. 등장하면서, 클래스 컴포넌트의 시대는 저물었다. 리액트 훅 함수는 반드시 함수 컴포넌트에서만 사용해야만 한다.리액트 훅은 조건에 또는 반복문에 따라 호출이 되면 안된다.useState() 는 함수 컴포넌트내에서 상태를 관리하는 훅이다.useEffect(), useLayoutEffect 는 함수 생명주기에 대응하는 훅이다.2번째 인자로 배열을 가지는(의존성 배열) 훅들은 사용할 때 항상 주의해야한다. -> 안그러면 클로저로 인해 이전 값을 계속 참조한다.useEffect() 훅은 함수 컴포넌트가 반환하는 JSX 구문 즉 ReactElement 가 실제DOM에 렌더링 된 후 paint 후에 비동기로 동작하는 반면 useLayoutEffect() 훅은 동기적으로 페인트 이전에 실행이 된다. 리액트 함수 컴포넌트 생애주기는Render 단계와 Commit 단계로 나뉜다.Render 단계에서는 함수가 실행되어, JSX 를 반환한다. JSX 는 ReactElement 를 생성하는 함수로 변환이 되어 ReactElement 를 생성한다. 이걸 가지고 가상 DOM을 만든다. 이전에 만든 가상DOM이 있다면 이를 비교하는 작업을 한다.Commit 단계에서는 가상DOM을 실제 DOM에 반영한다.  Next.js는 React 프레임워크를 기반으로 한 웹 개발 도구로, 서버 사이드 렌더링(SSR), 정적 사이트 생성(SSG), 그리고 최근에는 클라이언트 사이드 렌더링(CSR)과 같은 다양한 렌더링 방식을 지원합니다. 각 렌더링 방식에 대한 설명과 특징을 살펴보겠습니다. 서버 사이드 렌더링 (Server-Side Rendering, SSR)개념: SSR은 각 요청이 있을 때마다 서버에서 HTML을 동적으로 생성하여 클라이언트에게 전송하는 방식입니다. 이는 초기 페이지 로딩 시 서버에서 모든 페이지를 미리 렌더링하고, 완성된 HTML을 클라이언트에게 보내줍니다.장점: 검색 엔진 최적화(SEO)에 유리하고, 초기 로딩 시 사용자에게 완성된 페이지를 보여줄 수 있어 사용자 경험이 개선됩니다.단점: 서버 부하가 늘어날 수 있으며, 렌더링 시간이 길어질 수 있습니다.정적 사이트 생성 (Static Site Generation, SSG)개념: 빌드 시 모든 페이지를 미리 HTML로 변환하여 저장합니다. 사용자의 요청에 따라 미리 생성된 HTML 파일을 그대로 전송합니다.장점: 서버 부하가 감소하고, 빠른 로딩 속도를 제공합니다. 보안이 강화되며, CDN을 통한 쉬운 배포가 가능합니다.단점: 실시간 업데이트가 필요한 경우 적합하지 않을 수 있습니다. 사이트 빌드 시간이 길어질 수 있습니다.클라이언트 사이드 렌더링 (Client-Side Rendering, CSR)개념: 초기 로딩에서는 기본적인 HTML과 JavaScript를 로드하고, 이후 모든 렌더링은 브라우저에서 JavaScript를 통해 이루어집니다.장점: 서버 부하가 줄어들고, 사용자 인터랙션에 따라 동적인 페이지 변화를 빠르게 구현할 수 있습니다.단점: 초기 로딩 시 필요한 자원이 많아져서 속도가 느려질 수 있으며, SEO에 불리할 수 있습니다.증분형 정적 재생(Incremental Static Regeneration, ISR)개념: ISR을 사용하면, 빌드 시 생성된 정적 페이지를 배포 후에도 필요에 따라 업데이트할 수 있습니다. 이는 특정 페이지를 새로운 데이터로 다시 생성하게 할 수 있는 옵션을 제공하여, 정적 사이트의 장점을 유지하면서도 동적 콘텐츠의 필요성을 충족시킬 수 있습니다. 장점성능과 캐싱: 정적 파일로 서빙되기 때문에 빠르고, CDN을 통해 캐싱될 수 있어 성능이 우수합니다.스케일링: 정적 파일을 사용하기 때문에 트래픽 증가에 따른 서버 부하가 적습니다.신선도: revalidate 옵션을 통해 정적 콘텐츠임에도 불구하고 일정 기간마다 콘텐츠를 자동으로 업데이트하여 최신 상태를 유지할 수 있습니다.단점복잡성: ISR 설정과 관리는 일반적인 SSG나 SSR에 비해 복잡할 수 있습니다.비용: 재생성 로직에 따라 추가 서버 자원이 필요할 수 있으며, 이로 인해 비용이 발생할 수 있습니다.Next.js 에서는 개발자를 위해 다양한 기능을 제공해 주고 있다.파일 기반 라우팅api 라우팅Image 최적화Metadata API등 다양해서 좋다. 그런데 프로젝트를 작성해나가다보면 예약어 파일들이 너무 많아져서 큰 회사들은 이걸 어떻게 관리하는지 궁금해진다.

프론트엔드인프런워밍업클럽FE1기회고

crispin

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

0기에 백엔드 스터디에 이어 1기 프론트엔드 스터디를 신청하고, 참여하였다.신청 이유신청하게된 가장 큰 이유는 자바스크립트 랑 JQuery 를 조금씩 사용했었는데, 사실 자바스크립트 를 제대로 공부했던 적이 없고, 이직하는 곳에서는 백엔드와 프론트엔드가 명확하게 나뉘게 되어 이직하기전 프론트엔드 지식을 조금이라도 학습하면 협업을 할때 도움이 많이 될것 같아 신청하게 되었다.자바스크립트 미션아직 1단계 완료 후 2단계를 진행하고 있다. 생각외로 많이 어려워서 진행 속도가 많이 느리다. 리액트 부분으로 넘어가면 훨씬 어려워진다고 했는데 0기때 왜 프로트엔드에서 우수 러너가 적게 나왔는지 새삼 느끼고 있다. 1주차 느낀점하필 이직 시기와 겹치는 바람에(심지어 지역이동..) 거주지를 알아보고, 이직회사에서 사용하는 기술을 다시 한번 살펴보는 등 스터디외에도 할게 너무 많아 정신없이 보내고있다. 우선순위를 잘 정해서 2주차를 진행해야할것 같다.정리현재 서포터로도 참여하고 있을 정도로 애정이 정말 많이 가는 스터디다. 이런저런일로 많이 바쁘고 정신이 없지만 조금이라도 함께하는 러너분들에게 도움이 되기 위해 노력해야겠다.

프론트엔드워밍업클럽스터디프론트엔드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주차

lar 6개월 전
이혜리

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

1주일간의 백엔드 공부를 정리해 보려한다.자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]위 강의를 듣고 1주일간 배운 것은 restful API 작성법,이를 database와 연결하는 법,람다식과 익명 클래스 차이에 대한 것이다. 이번주는 집중을 잘 못했다. 다른 일이 겹쳐서 강의 듣는 것 조차 버거웠는데,현재 13강까지 마쳤으며,과제는 1차,3차를 제출한 상태이다. 과제 기간이 2~3일 마다 1번인 것을 감안할 때,매일 강의를 2개씩 듣고,이에 대한 정리를 노션에 짧게 한다음,평일에 1번 , 주말에 1번 정리하는 식으로 내 개별 블로그에 쓰고,이를 각각 발자국 글로 작성 후,회고 형식으로 발자국 글을 쓰려 한다.별도로 과제에 대한 글도 개별 블로그에 쓰려한다. ot와 Q&A 를 참여했었는데Q&A에서 프로젝트 주제 선정은 자신이 가고 싶은 회사의 어플리케이션 혹은 관련 부분을 구현하는게좋을 것 같다는 답변을 듣고이 강의와 스터디를 마치고 어떤 프로젝트를 구현하면 좋을지 생각중이다.전반적으로 이번주는 스터디에 대한 적응을 하고 강의 초입부를 들은 상태이다.다음주도 힘내서 참여해야겠다. 

백엔드워밍업1기1주차회고백엔드

슬프구나

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

인프런 워밍업 클럽이 스터디 1기 FE 를 시작한지 어느덧 1주차현재 과제 1~7까지 완료를 해놓은 상태다.음식 메뉴 앱가위 바위 보퀴즈책 리스트 나열Github Finder비밀번호 생성타이핑 테스트 과제들을 진행하면서, DOM API 에 대한 복기를 할 수 있어서 좋았다. 그리고 퀴즈 및 타이핑은 이런저런 로직을 고민하게 해줘서 좋았다. 퀴즈는 처음에 뭔가 가상의 데이터를 통해서 처리를 해야하는줄 알았다.(실제 현업에서는 DB에 문제은행식으로 관리하는걸로 알고 있다.)이걸 Math 객체를 생성하여 랜덤하게 문제와 정답을 생성하는 방식으로 처리하였다.Math.random() 함수는 0~1 사이의 난수를 발생 시킨다.(1은 포함하지 않는다)Math.random() * 10; 을 하게된다면 0~9까지의 난수를 얻을 수 있다. 이때 소수점 이하를 버려주면 정수값을 추출하는거다.그러면, 1~10까지를 얻고싶다면 어떻게 해야할까? 간단하다.min = 1;max = 10;(Math.random() * (max - min + 1) + min);max - min + 1 = 100 ~ 9 까지 난수를 얻을 수 있다. 그럼 여기에, 소수점 버린 정수에 min 을 더해주면?1~10 까지가 되는거다. 그리고 반복되는 UI 는 template 요소를 활용하여 처리 하였다.<template id="myTemplate"> <p>This is a template. It will not be rendered.</p> </template>template 요소는 렌더링 되지 않는다. 렌더링 하려면, JS로 무조건 조작을 해줘야 한다.물론 DOM Node 를 조작할 때, 원본 Node 에 영향을 끼치지 않으려면 cloneNode 또는 importNode 등으로 조작을 해줘야 한다. 마무리하며변수와 데이터 타입: 자바스크립트의 기본적인 변수 선언부터 시작하여, 다양한 데이터 타입(문자열, 숫자, 객체 등)을 배웠습니다.함수: 함수의 기본적인 선언 방법과 화살표 함수 등 최신 문법에 대해서도 배웠습니다.DOM 조작: HTML 요소를 자바스크립트를 통해 조작하는 방법을 배우고, 실제로 몇 가지 프로젝트를 통해 연습했습니다.비동기 처리: Promise, async/await를 통해 비동기 처리 방법을 배웠습니다. API 호출과 같은 작업을 처리하는 방법을 실습했습니다. null 과 undefined: 둘다 원시타입이다. 하지만 typeof 로 null 을 출력해보면 object 를 출력한다. 이는 JS 초기 설계 오류가 지금까지 이어져온것이며 웹 호환성을 위해 수정을 하지 않았다. 그러니 null 은 체크할때 이 특성을 기억해야 한다.자바스크립트 공부를 통해, 단순히 코드를 작성하는 것 이상의 귀중한 경험을 하였다. 문제 해결 능력, 창의적 사고, 그리고 끊임없는 학습의 중요성을 깨닫게 되었으며, 앞으로도 지속적으로 새로운 기술을 배우며 성장해 나갈 것이다.

웹 개발인프런워밍업클럽FE1기회고

구르밍

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

1강spring.io ⇒ springboot 프로젝트 만들기spring boot는 톰캣이 내장되어 있음 (Packaging - Jar)2강 @SpringBootApplication과 서버@ → 어노테이션@SpringBootApplication ⇒ 자동으로 설정서버란 ?: 기능을 제공하는 것, 어떠한 기능을 제공하는 프로그램, 그 프로그램을 실행시키고 있는 컴퓨터기능을 제공하기 위해서는 누군가의 요청이 있어야 한다.3강 네트워크란 무엇인가?각각의 PC에는 고유 IP 존재IP를 모두 외우기 어렵기 때문에 도메인 이름을 사용 (ex - naver.com / spring.com ) ⇒ DNS (Domain Name System)4강 HTTP와 API란 무엇인가?데이터를 주고 받는 표준이 존재HTTP (HyperText Transfer Protocol)GETPOSTPUTDELETEAPI (Application Programming Interface): 클라이언트와 서버는 HTTP를 주고 받으며 기능을 동작하는데 이때 정해진 규칙을 API라고 한다.URL (Uniform Resource Locator)HTTP 응답 코드2003004005005강 GET API 개발하고 테스트하기@RestController→ API의 진입지점 만들기@RestController를 사용하면 API의 진입지점인것을 알수 있다.6강 POST에서는 데이터를 어떻게 받을까 ?HTTP Body를 이용!10강 Database와 MySQL컴퓨터의 핵심 부품CPU : 연산RAM : 임시 기억장치DISK : 장기 기억장치DatabaseRDB (Relational Database)SQL (Structured Query Language)MySQL 접근intellij ultimateCLImysql -u root -p11강 MySQL에서 테이블 만들기 DDL (Data Definition Language)데이터베이스 만들기create database [데이터베이스 이름];데이터베이스 목록보기show databases;데이터베이스 지우기drop database [데이터베이스 이름];데이터베이스 안으로 들어가기use [데이터베이스 이름];테이블 목록 확인하기show tables;테이블 만들기create table [테이블 이름]([필드1 이름][타입][부가조건],[필드2 이름][타입][부가조건],…primary key ([필드이름]));create table fruit (id bigint auto_increment, name varchar(20), price int, stocked_date date, primary key (id)); 테이블 제거하기drop table [테이블 이름];MySQL 타입tinyint : 1바이트 정수int : 4바이트 정수bigint : 8바이트 정수 (21억건이상)double : 8바이트 정수decimal(A,B) : 소수점을 B개 가지고 있는 전체 A자릿수 실수char(A) : A글자가 들어갈 수 있는 문자열varchar(A) : 최대 A글자가 들어갈 수 있는 문자열date : 날짜, yyyy-MM-ddtime : 시간, HH:mm:ssdatetime : 날짜와 시간을 합친 타입, yyyy-MM-dd HH:mm:ss12강 DML (Data Manipulation Language)CRUD데이터 넣기INSERT INTO [테이블 이름] (필드1이름, 필드2이름,…) VALUES (값1, 값2,…)INSERT INTO fruit (name, price, stocked_date) values ('사과', 1000, '2023-05-01');데이터 조회, 업데이트, 삭제select * from [테이블명] where [조건]update [테이블 이름] set 필드1이름 = 값, 필드2 이름 = 값,… where [조건]delete From [테이블 이름] where [조건];13강 Spring에서 Database 사용spring 프로젝트 Resource폴더 아래에 application.yml 파일 생성spring: datasource: url: "jdbc:mysql://localhost/library" //jdbc를 이용해 Mysql에 접근 username : "root" password: "" driver-class-name: com.mysql.cj.jdbc.Driverapplication.yml @GetMapping("/user") public List<UserResponse> getUsers() { String sql = "SELECT * FROM user"; 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@GetMapping("/user") public List<UserResponse> getUsers() { String sql = "SELECT * FROM user"; return jdbcTemplate.query(sql, (rs, rowNum) -> { long id = rs.getLong("id"); String name = rs.getString("name"); int age = rs.getInt("age"); return new UserResponse(id, name, age); }); }RowMapper에 option + enter ⇒ 람다식으로 변경14강 ~ 16강public void updateUser( UserUpdateRequest request) throws IllegalAccessException { boolean isUserNotExist = userRepository.isUserNotExist(request.getId()); if(isUserNotExist){ throw new IllegalAccessException(); } userRepository.updateNameUser(request.getName(), request.getId()); } public void deleteUser(String name) throws IllegalAccessException { boolean isUserNameNotExist = userRepository.isUserNameNotExist(name); if(isUserNameNotExist){ throw new IllegalAccessException(); } userRepository.deleteUser(name); }수정, 삭제 전 사용자가 DB에 존재하는 데이터인지 확인하기 위해 예외처리를 해주었다.jdbcTemplate.query ……. ⇒ List로 반환된다.isEmpty()를 붙여 boolean 타입인지 확인하도록 한 후 조건문 실행만약 존재 하지 않는 유저라면 IlleagalAccessException()이 호출된다.PostMan으로 확인한 결과홍합이란 유저가 없어서 500이 떴다!17강 좋은 코드란 무엇인가코드는 요구사항을 표현하는 언어개발자는 요구사항을 구현하기 위해 코드를 읽고 작성한다. 코드를 읽는 것은 필수적이고 피할 수 없다안좋은 코드가 쌓이면, 시간이 지날 수록 생산성이 낮아진다! Controller에서 모든 기능을 구현하면 왜 안될까?⇒ 함수는 최대한 작게 만들고 한 가지 일만 수행하는 것이 좋다.  18강. Controller를 3단 분리하기 - Service와 Repository기존 Controller의 함수 1개가 하고 있던 역할API의 진입 지점으로써 HTTP Body를 객체로 변환하고 있다. ⇒ Controller현재 유저가 있는지, 없는지 등을 확인하고 예외 처리를 해준다. ⇒ ServiceSQL을 사용해 실제 DB와의 통신을 담당한다. ⇒ RepositoryLayered ArchitectureController ← Service ← Repository미션 & 일주일 회고미션 (1 ~ 3번째 과제)https://charm-vise-f40.notion.site/016b87f39bbe4c31991ab1c51632bd73https://charm-vise-f40.notion.site/2-372b48a579674c988a990fa4b9a14ebb?pvs=4https://charm-vise-f40.notion.site/3-212dca4aeb81494c9d63f66689b90e4f?pvs=4워밍업 클럽이 벌써 시작한 지 일주일 정도가 흘렀다.진도표에 맞춰 강의를 듣고 과제를 진행하다 보니 시간이 금방 흐른 느낌이다!!강의를 보다 보면 내가 다 아는 것 같은 느낌이 들었는데 역시 과제를 하면 내가 어느 정도 까지 이해했는지 알수있었다 ㅎㅎ두 번째 과제를 할 때에는 출력값이 JSON으로 문제에는 나와 있지만 처음에 무작정 하다 보니 나는 그냥 단순 값으로 포스트맨에 출력되었다.뭐지? 뭐가 잘못된 거지 하면서 고민하다 보니까 객체로 반환을 하면 되는 것이었다 ㅜ세 번째 과제는 강의를 들으면서 익명, 람다식 등 잘 기억이 나지 않았는데 마침 강사님께서 과제로 내주셨다나도 코딩 님의 자바 강의에 들으면서 익명함수, 람다 식을 다시 공부했다. 좀 더 익숙해질 때까지 계속 사용해 봐야겠다.아직 초반이라 그런지 사실 강의는 매우 재밌었다. 그렇지만 스스로 자바개념이 아주 부족하다고 생각하기에주말을 활용하여 자바 개념과 강의 내용을 복습해 봐야겠다!

웹 개발인프런워밍업회고

crispin

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

3주차 회고벌써 스터디가 종료되었다. 배운것도 너무 많고, 배워야 할것도 너무 많지만 확실한건 3주전의 나와 비교해 배운게 많다는것다른 미션들도 재미있고, 많이 배웠지만 미니 프로젝트 미션은 정말 많은걸 배울 수 있었다.다른 5분의 스터디원분들과 서로 코드리뷰를 하며 미니프로젝트를 진행했는데, 코멘트 하나하나 너무 많은걸 배울 수 있었어서 하길 잘했다는 생각이 든다.3주차 미션day11 ~ 15미션다양한 요구사항이 있는 미니 프로젝트를 진행했다.난이도가 조금은 쉬운듯 해서, 고민을 최대한 많이 하면서 다양한 방법을 시도하며 프로젝트를 진행했다TDD 를 적용하고, 각 레이어간의 추상화와 좋은 설계 등등 코드를 한줄 작성할때도 최대한 의미있는 코드를 작성하려 노력했다.4단계까지 있는 미션을 모두 진행하지는 못했다. 생각외로 TDD 가 정말 어려웠다. TDD 로 개발을 한다고 작정을 하고 개발을 진행해도 중간중간 기존 개발 습관들이 나와서 어려움이 많았다. 그러다 보니 하루에 5시간 이상을 프로젝트에 매달렸는데 2단계 미션까지 밖에 진행하지 못했다.다만, 다음주 수료식 전 까지 미션을 진행하고 다른 동료분들과 코드 리뷰를 함께 하기로 해서 다행이다.스터디 회고이 스터디를 참여할지 고민하는 분들에게 만약 다음 기수 스터디가 열린다면 무조건 참여하라고 말해주고 싶다.쉬도때도 없이 많은 질문들을 빠르게 답변해주고 많은걸 알려주시려는 코치님과 성장하고자 많은걸 배우고 공유하려하는 스터디 원 분들 등등 좋았던게 너무 많다.또 우리가 함께 만들어가는 스터디라는 취지 답게 스터디 안에서도 다양한것들을 시도해 볼 수 있어 좋았다.다른분들과 일주일 넘게 코드리뷰를 하면서, 정말정말 많은걸 배울 수 있었다.앞으로도 이런 기회가 많이 생겨 더 많은걸 배울 수 있었으면 좋겠다. 

백엔드워밍업스터디0기백엔드회고발자국

유원준

[인프런 워밍업 클럽 0기 백엔드] 3주차(최종) 발자국 (내용 정리)

인프런 워밍업 스터디의 마지막 주차가 마무리되어 가고 있습니다.3주차에 학습했던 내용들을 전체적으로 정리해 보고자 합니다.미니 프로젝트 수행은 하단의 깃허브 주소를 남겨두도록 하겠습니다.이전과 동일하게 학습한 내용, 미니 프로젝트 관련 내용들을 개인 블로그, 깃허브에 모두 정리하고 있습니다.하단은 학습 내용을 정리한 제 블로그 주소입니다.https://twojun-space.tistory.com/category/%EA%B8%B0%EB%A1%9D%2C%20%ED%9A%8C%EA%B3%A0/InFlearn%20Warming-up%200%EA%B8%B0%20BE (1) GitHub (Mini project)https://github.com/twojun/inflearn_warmingup_be_project   1. [11일 차] - 배포(Deployment), H2 DB를 통한 Profile 적용, Git & GitHub, AWS EC2(1) 11일 차 관련 학습 내용 개인 블로그 정리https://twojun-space.tistory.com/194 1-1. 배포의 뜻, 스프링 Profile(1) 애플리케이션에서의 배포의 뜻, 배포의 특징에 대해 알아보았다.(2) 사용자가 최종적으로 서비스를 이용할 수 있게 진행하는 일련의 작업으로 보면 된다.(3) 그리고 profile에 대해서도 알아보았는데 우리는 개발을 하면서 자연스럽게 profile 기능을 사용하고 있었다.(4) 이처럼 profile의 경우 똑같은 서버 코드를 실행시키지만 실행환경과 장소에 따라 각 다른 프로그램과 자원을 사용할 수 있도록 하는 것을 의미하게 된다.  1-2. Profile 적용(1) 간단하게 인메모리 DB인 H2 Database에 대해 알아보고, application.properties 또는 application.yml에서 DB profile을 설정하기 위한 옵션 적용이 가능함을 학습했다. (2) Run/Debug Configurations 메뉴에서 Active profiles를 yml 또는 properties에서 설정한 값으로 채워두고 서버를 실행시킨다.  1-3. Git & GitHub(1) Git, GitHub의 특징과 차이점을 알아보고 GitHub를 왜 많은 개발자들이 사용하고 있는지 그 장점과 특징에 대해 중점적으로 알아보았다. (2) git init, git remote, git status 등 Git의 기본적인 명령어 학습  1-4. AWS EC2(Amazon Web Service Elastic Computer Cloud)(1) 아마존에서 웹 서비스의 배포와 운영을 위해 제공하는 클라우드 서비스인 AWS EC2와 특징에 대해 학습했다.(2) AWS EC2를 통해 개발한 서비스의 배포와 운영을 위해 가상 서버 인스턴스를 생성할 수 있으며 애플리케이션의 트래픽, 규모 등을 고려하여 생성한 서버 인스턴스의 리소스를 확장할 수도 있다.  1-5. 11일 차 학습 내용 개인 회고(1) 개발만큼 배포와 운영 단계도 백엔드 개발에서 가장 중요한 부분이다. 이 부분에 대해 학습하고 실제 프로젝트에도 적용할 수 있는 능력을 기르고자 한다.   2. [12일 차] - AWS EC2 접속, 기본적인 Linux command, AWS Computing 환경에서 서버 배포를 위한 환경 구성, & 배포, 종료되지 않는 실행(foreground & background)(1) 12일 차 관련 학습 내용 개인 블로그 정리https://twojun-space.tistory.com/195  2-1. AWS EC2의 두 가지 접속 방법(1) key pair를 통한 접속 (Mac os의 경우 Iterm을 통해 접속 가능)(2) AWS Console을 통한 접속  2-2. 기본적인 리눅스 커맨드 학습(1) 디렉토리 생성 및 삭제, 경로 이동 등 기초적인 리눅스 명령에 대해 학습  2-3. AWS Linux에서 서버 배포 준비(1) 우선 Console에서 Git을 별도로 설치한다. (2) 서버 코드의 실행을 위한 JDK를 설치한다. (3) DBMS 설치(RDB : MySQL)  2-4. EC2 환경에서도 동일하게 데이터베이스 구성, 빌드와 배포(1) EC2 환경에서도 동일한 테이블 구조를 세팅한다. (2) Remote repository에서 Git Clone으로 기존 서버 코드를 모두 가져온다. (3) AWS EC2 Free tier의 경우 성능이 좋지 않다. 요즘은 가벼운 애플리케이션이더라도 서버 리소스를 많이 잡아먹기 때문에 Swap Setting을 통해 저사양의 인스턴스를 대상으로 메모리와 함께 추가적으로 스토리지도 함께 사용할 수 있도록 설정한다. (4) gradlew를 통해 빌드를 진행한다. 무료 서버를 사용하는만큼 테스트는 돌리지 않는 것이 성능상 유리하다. (5) 빌드 성공 시 빌드 디렉토리가 생성되고 내부로 이동하면 .jar 파일이 생성되어 있다. 이제 빌드된 .jar 파일을 통해 서버 실행이 가능한 상태이다. java -jar 명령으로 서버를 실행한다.  2-5. 종료되지 않는 실행(1) foreground & background의 차이에 대해 알아보았다. (2) nohup 명령어를 알아보고, 파일 내부를 확인할 수 있는 cat, tail 등 명령어에 대해 추가 학습했다.  2-6. 12일 차 학습 내용 개인 회고(1) 배포에 대한 전반적인 내용을 빠르게 학습해볼 수 있는 파트였던 것 같다. 서버 애플리케이션의 경우 대부분 리눅스 환경에서 다루어지기 때문에 리눅스에 대한 이해와 커맨드를 빠르게 체화시키는 부분이 중요할 것 같다.      3. [13일 차] - build.gradle, Spring & Spring Boot(1) 13일 차 관련 학습 내용 개인 블로그 정리https://twojun-space.tistory.com/196  3-1. build.gradle(1) build.gradle이 무엇인지 빌드 도구인 gradle이 무엇인지 알아보고 프로젝트에 필요한 의존성을 관리할 수 있는 도구임을 학습했다. (2) build.gradle을 이루는 plug-in, repositories, dependencies, dependencies에 대해 학습했다.  3-2. Spring & Spring Boot(1) Spring, Spring Boot를 시기별로 출시된 버전, 버전이 갖는 의미에 대해 학습했다. (2) 기존 스프링과 스프링 부트의 차이에 대해 학습했다.스프링, 스프링 부트와의 차이점 : (1) 간편한 설정 제공스프링, 스프링 부트와의 차이점 : (2) 간단한 의존성(라이브러리, 프레임워크) 설정 관리스프링, 스프링 부트와의 차이점 : (3) 강력한 확장성, MSA(Micro-Service Architecture)에 적합한 모니터링 기준 제공 등  3-3. application.yml(properties), Lombok library(1) application.yml, application.properties 모두 스프링 프로젝트의 전반적인 설정 정보를 정의하기 위한 파일로 볼 수 있다. (2) yml은 계층 구조를 갖고 properties는 동일한 key, value 타입이지만 계층 구조가 존재하지 않는다. (3) Lombok 라이브러리는 개발자에게 많은 편리성을 제공해주는 라이브러리이다. Getter, Setter와 같이 반복되는 Boiler plate code를 제거할 수 있게 도와준다.  3-4. 13일 차 학습 내용 개인 회고(1) 스프링으로 개발을 진행하며 의존성을 관리하는 도구인 build.gradle과 스프링, 스프링 부트의 차이점, 설정 정보를 관리하는 application.yml에 대해 학습할 수 있었다. 무심하게 사용해오던 도구들이지만 의미를 다시 한 번 더 정리하고 제대로 알고 사용할 수 있으면 좋겠다는 생각을 하게 되었다.   4. 14일 차 마지막 마무리 영상, 스터디 마지막 최종 회고(1) 마무리 섹션에서는 코치님께서 백엔드 개발에 있어 전체적인 학습 방향성을 개인적으로 조언해 주시는 시간과, AWS 호스팅 서비스의 과금 계산, 강의에서 소개되지 않았던 SQLMapper인 MyBatis, ORM 기반 기술인 JPA의 비교, 클라이언트 사이드 렌더링, 서버 사이드 렌더링에 대해 간단하게 정리해 주셨다. (2) 약 3주 간 온라인 강의와 세션 외에도 수강생들의 끊임없는 질문에 항상 웃으며 친절하게 대답해 주셨던 열정이 가득한 최태현 코치님, 열심히 배우고 성장하기 위해 끊임없이 달리는 러너분들이 있어서 스터디를 잘 마무리할 수 있었던 것 같습니다. 짧았다면 짧고, 길었다면 긴 시간이었지만 스터디를 완주할 수 있게 되어서 기쁘고 이번 스터디 수료를 통해 많은 성장은 아니지만 개인적으로 어느 정도 성장하는 데 도움이 되었다고 생각합니다. 스터디를 참여하면서 많은 분들을 만났고, 꾸준히 배움을 멈추지 않는 수강생분들을 보며 저 자신도 많이 반성하게 되었던 기간이었던 것 같습니다 다시 한 번 코치님, 러너분들, 이 스터디 기회를 만들어주신 인프런 관계자 여러분들께 감사하다는 말씀을 드리고 싶습니다. 코치님, 0기 백엔드 러너분들, 인프런 관계자분들을 항상 응원하겠습니다!모두 화이팅입니다. 😁  

백엔드인프런워밍업백엔드스프링발자국회고

채널톡 아이콘