블로그

miiro

[인프런 워밍업 스터디 클럽 1기] BE 스터디 참여 후기

인프런 워밍업 클럽 1기 백엔드 과정의 참여했던회고 및 후기에 대한 내용입니다. 처음으로 프로젝트나 스터디를 마무리한 후에 최종적으로 써보는 회고록입니다.약 4주 간의 스터디를 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지!해당 강좌를 통해서 과제를 진행하고 미니프로젝트를 구현하면서대강 알고 있던 수준을 넘어 성장을 할 수 있는 토대를 마련할 수 있었던 거 같습니다. 신청유튜브와 다양한 인터넷 강의를 통해 관심 있는 내용만 선택적으로 공부해왔습니다. 그러나 실제 현업에서 사용하는 기술이나 개발자로서 중요한 이론에 대해서는 간략하게만 알고 있었고, 정확한 내용은 잘 알지 못한 상태였습니다. 그러던 중, 운 좋게 인프런에서 '워밍업 클럽' 홍보 배너를 확인하게 되었습니다. 이 강의를 통해 필수 기술을 체계적으로 학습할 수 있고, 진도표를 통해 계획적으로 진행할 수 있다는 점이 꾸준히 실력을 쌓는 데 큰 도움이 될 것이라 생각하여 도전하게 되었습니다.또한, 디스코드를 통해 여러 교육생들과 커뮤니티가 형성되어 실시간으로 질문할 수 있고, 자신의 정보를 공유하며 공부했던 내용을 기록하는 등 열정 넘치는 모습들이 눈에 띄었습니다. 이러한 열정적인 분위기 속에서 다른 교육생들에게 뒤처지지 않기 위해 이전 기수의 교육생들이 작성한 회고록이나 과제 내용을 참고하며 스터디에 집중하고 적응하기 위해 노력했습니다.진행스터디 진행이번 강의를 통해 백엔드의 주 언어인 Java에 대해 기존에 알고 있던 내용을 바탕으로 하여, 서버의 정의부터 기본적인 API 작성, DB 연동, 배포에 이르기까지 서버 개발의 전체 사이클을 경험할 수 있었습니다. 기존에 공부했던 내용이 많아 비교적 쉽게 접근할 수 있을 것이라 생각했으나, 실제로 강의를 진행하면서 제가 제대로 알고 있던 내용이 많지 않다는 것을 깨달았고, 여러 부분에서 부족함을 느꼈습니다. Java의 기본 문법부터 시작해, Spring Boot를 활용한 RESTful API 개발, JPA를 사용한 데이터베이스 연동, 그리고 AWS를 통한 배포에 이르기까지, 서버 개발의 전 과정을 마치 처음부터 다시 배우는 듯한 자세로 강의 내용에 집중하며 하나하나 이해하면서 스터디를 진행했었습니다. 기록의 중요성이번 스터디를 통해 개발자로서 중요한 덕목 중 하나인 기록의 중요성을 다시금 깨닫게 되었습니다. 주차별 과제를 블로그에 정리하고, 주차별 회고록을 작성하면서 공부한 내용을 공유했습니다. 이 과정을 통해 학습한 지식을 더욱 확실하게 이해하고 기억할 수 있었습니다. 또한, 몰랐던 부분이나 더 공부해야 할 내용들을 알게 되었습니다. 주차가 거듭될수록 이전 내용에 대해 헷갈리거나 지식이 겹쳐 혼란스러웠던 부분들을 기록해둔 회고록이나 과제 내용을 보며 빠르게 해결할 수 있었습니다. Q&A 시간의 소중함격주로 진행된 라이브 Q&A 시간을 통해 스터디를 하면서 막힌 부분이나 궁금한 점에 대해 질문하고 답을 얻으면서 지식을 채워나갈 수 있었습니다. 또한, 다른 러너들의 질문을 들으며 생각지 못한 다양한 방면에서 지식을 얻을 수 있었습니다. 과제를 진행하면서 코치님께서 주신 코멘트와 추가로 공부해보면 좋을 내용을 통해 스터디에 더욱 열심히 임할 수 있었고, 성장할 수 있는 동력을 얻은 것 같습니다. 📃 과제 진행 링크과제 1~7주차 블로그 정리📃 나의 주차별 회고록BE 1주차 회고록BE 2주차 회고록BE 3주차 회고록BE 4주차 회고록 마무리인프런 워밍업 클럽을 진행하면서 가장 첫 번째 목표는 완주하는 것이었습니다. 공부를 하다 보면 나태해지기 쉬웠기 때문에, 스터디를 끝까지 마치는 것이 목표였습니다. 스터디를 진행하면서 다른 러너분들이 적극적으로 질문하고, 과제나 회고록을 작성하며, 자신이 찾은 유튜브나 기술 블로그 링크를 공유하는 열정을 보면서 더욱 열심히 참여할 수 있었습니다.스터디를 참여하면서 개발자로써 간접적으로나마 프로젝트에 사용하는 기술에 대한 학습을 하여 블로그에 작성을 하고, 그 내용을 토대로 프로젝트를 구현하고, 이를 끝마치면 회고록을 작성하여 개발의 서사를 작성하는 습관을 길렀다고 생각이 들 정도로 유익했던 거 같습니다. 스터디가 마무리되면서 다시 홀로 공부를 시작하게 되었지만, 이전에 진행했던 스터디의 열정을 잃지 않도록 꾸준히 노력해야겠다는 다짐을 하게 되었습니다. 이번 스터디를 참여하신 모든 스터디원 분들과 해당 프로그램을 기획하신 인프랩 임직원분들께 감사드리며이 시간을 활발하게 이끌어주신 코치님께 감사의 인사를 전달드립니다.

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

이용수

[인프런 워밍업 클럽 1기] 오프라인 수료식 참여 및 클럽 과정 후기

[인프런 워밍업 클럽 1기] 오프라인 수료식 참여 및 클럽 과정 후기 참여 계기IT 취준생 톡방에서 우연히 워밍업 클럽에 대해 정보를 얻을 수 있었고, 내가 들을만한 좋은 강의가 있을까 찾아보니 마침 최근에 포트폴리오 때매 관심 있었던 스프링으로 직접 서버를 배포하는 방법이 강의 주제로 있어서 신청하게 되었다.무엇보다 혼자 강의를 듣는게 아닌 디스코드 커뮤니티에서 서로 물어보며 강의를 같이 듣는다는 것이 흥미 있었고 모든 과정을 수강 완료하면 인프런 포인트로 일부분 환급 된다는 것이 마음에 들었다.참여 과정과정 자체는 강의 취지에 맞게 Spring Boot를 이용해 기초적인 API 설계와 배포까지 진행하는 정도로 진행했으며, 강의 난이도도 적절했다고 생각한다.무엇보다 다음 아래와 같이 학습 내용을 정리할 수 있도록 제출 기한을 설정해 학습에 대한 일정 관리를 별도로 진행하지 않아도 되서 좋았다. [인프런 워밍업 클럽 1기] BE 1일차 과제 - 이용수님의 블로그 - 인프런 | 커뮤니티 (inflearn.com)[인프런 워밍업 클럽 1기] BE 2일차 과제 - 이용수님의 블로그 - 인프런 | 커뮤니티 (inflearn.com)[인프런 워밍업 클럽 1기] BE 3일차 과제 - 이용수님의 블로그 - 인프런 | 커뮤니티 (inflearn.com)[인프런 워밍업 클럽 1기] BE 1주차 발자국 - 이용수님의 블로그 - 인프런 | 커뮤니티 (inflearn.com)[인프런 워밍업 클럽 1기] BE 4일차 - 이용수님의 블로그 - 인프런 | 커뮤니티 (inflearn.com)[인프런 워밍업 클럽 1기] BE 5일차 - 이용수님의 블로그 - 인프런 | 커뮤니티 (inflearn.com)[인프런 워밍업 클럽 1기] BE 2주차 발자국 - 이용수님의 블로그 - 인프런 | 커뮤니티 (inflearn.com)[인프런 워밍업 클럽 1기] BE 6일차 - 이용수님의 블로그 - 인프런 | 커뮤니티 (inflearn.com)[인프런 워밍업 클럽 1기] BE 7일차 - 이용수님의 블로그 - 인프런 | 커뮤니티 (inflearn.com)[인프런 워밍업 클럽 1기] BE 3주차 발자국 - 이용수님의 블로그 - 인프런 | 커뮤니티 (inflearn.com)[인프런 워밍업 클럽 1기] BE 미니 프로젝트 - 이용수님의 블로그 - 인프런 | 커뮤니티 (inflearn.com) 오프라인 수료식 참여오프라인 수료식은 인프랩에서 진행했으며, 집에서 인프랩 사무실까지 가까운 거리는 아니였지만, 어차피 취준생이고 시간이 남아돌 뿐더러 가까운 일정에 중요한 시험도 없기 때문에 한번쯤 가보는 것도 괜찮다고 생각했다.인프랩 사무실은 스타트업 캠퍼스 5층에 위치하고 있었다. 내 추측으로는 한층을 대여해서 사용하고 있는것 같았다. 건물 입구 수료식 진행 화면 제공한 저녁식사와 인프런 스티커, 명찰 최종 후기오프라인 수료식까지 모두 진행하고 돌아온 과정을 돌이켜 보니 꽤 많은 경험을 했다고 느꼈다.비록 우수 러너는 되지 못했지만, 우수 러너가 된 스터디원의 학습 방법을 들어보니 우수 러너로 선정된 이유를 알것 같기도 했고, 학습 방법에 대해 많은 배움을 얻었다.네트워킹 시간에 코치님과 직접 만나보고, 꽤 많은 내용, 내가 평소에 궁금했던 내용을 질문하고 답변 받으면서, 내가 가는길이 험난하진 않은지, 어떤것을 바라보고 가는 것이 도움이 될지 내 나름대로 생각을 확실히 할 수 있는 시간이 되었던것 같다.워밍업 클럽을 모두 수료하며 강의 과정을 정리한 내용도 주차별로 정리해뒀으니 앞으로 필요할때마다 과정을 복습하기도 쉬울거 같다.워밍업 클럽 디스코드 커뮤니티에서도 개발자로서 얻어가는 것도 많았다. 개발자로서 가져야할 마음가짐과 같은 심상적인 정보부터, 어떻게 효율적으로 개발해야하는지와 같은 기술적인 정보까지 꽤 다양한 정보를 얻을 수 있었다.이렇게 워밍업 클럽 과정은 끝이 났지만, 개발자로서 나의 과정은 계속해서 진행될 것이다.

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

S.M KIM

[인프런 워밍업 클럽 Study] 1기 백엔드 후기

 1. 신청 사실 저는 인프런 워밍업 클럽 0기 참여자였지만, 이때에는 참여하고 있던 부트캠프에서 프로젝트를 진행하는 도중이라 너무 바빠 중간에는 참여하지 못했습니다. 이러한 이유로 아쉽게도 0기 워밍업 클럽 스터디는 중도포기 하였지만 당시에 진행중이었던 프로젝트는 무사히 끝났고, 이후 1기에 다시 모집을 시작하는 것을 보고 다시 재도전을 하게 되었습니다.  2. 진행 강의는 Spring Boot를 이용한 기초적인 프로젝트를 통해 직접 배포까지 하는 것을 목표로 하는 것이었습니다. 좋았던 점은 Front 부분에 대해서는 예제 코드를 제공하고 있어 수강생들은 온전히 Back-end 공부에만 전념할 수 있다는 점이었습니다. 강의 난이도는 전체적으로 쉬운 편이었다고 생각합니다. 개인적으로 Spring Boot와 JPA, 배포에 대해 이렇게 쉽게 설명해 주시는 강사님께 감탄하기도 하였습니다. 그렇지만 아무래도 강의 중점이 Java보다는 Spring Boot에 초점이 맞춰져 있기 때문에 강의 내용이 쉽다 하더라도 기본적인 Java 지식은 충분히 갖추고 있어야지 이해하기 쉽겠다는 생각은 하였습니다. 스터디에 참여한 이유는 아무래도 혼자서 공부하기에는 동기부여가 잘 되지 않아서라는 점이 컸던 것 같습니다. 단순히 스터디에 참여하는 것 뿐만이 아니라 과제나 발자국 작성을 통하여 배운 내용들을 복습할 수 있도록 하고, 추가로 인프런 포인트까지 준다고 하니 마다할 이유가 없었습니다. 덕분에 스터디를 진행하면서 새로 배웠던 지식들과 기존에 가지고 있던 지식들을 정리할 수 있는 시간이 되어 유익했습니다. 3. 후기 개인적으로는 강의 외적으로도 많은 것을 배웠던 시간이었던 것 같습니다. 특히 금요일에 있었던 Q&A 시간에서 클린 코드와 Test-driven Development에 대해 다뤘던 시간이 있었는데, 이전에 프로젝트를 진행하면서 마감에 쫒겨 구현에만 급급했던 점을 반성하고 효율적인 개발론, 보다 더 바람직한 개발론에 대해 고찰해보는 기회가 되었습니다. 또한 저 혼자 공부하게 될 경우 다른 사람에게 도움을 받기 어려워 과연 제대로 하고 있는 것인가에 대해 생각하기 어렵지만 이번 스터디를 통하여 다른 사람들과 코드를 공유하며 다른 사람의 코드와 나의 코드의 다른 점이 무엇인지, 어떤 코드가 더 좋은 코드인지 생각할 수 있는 기회가 되어 유익했습니다. 아쉽게도 현재 지방에 거주하고 있는 상황이라 서울에서 진행되는 오프라인 수료식에는 참석하지 못했지만, 대신에 Q&A 시간에는 참석할 수 있어서 이 자리를 통해 신입 개발자로서 가질 수 있는 여러 가지 궁금한 점에 대해 해소할 수 있어 좋았습니다. 이러한 자리를 만들어 주신 인프런 측과 강의를 진행하신 최태현 강사님, 그리고 같이 스터디에 참여한 워밍업 클럽 1기 분들께 모두 감사하다는 말씀을 마지막으로 이만 후기를 마치겠습니다.  

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

Kim AJin

인프런 워밍업 클럽 1기 백엔드 후기

인프런 워밍업 클럽 1기가 끝났다.백엔드 강사님이신 최태현 강사님의 강의가 좋다는 말을 들은 적이 있긴 했으나 들어본 적은 없었다. 이번에 듣게 됐는데 진작에 들어봤다면 좋았겠다는 생각이 들었다.인프런 워밍업 클럽에 참여하면서 나에게 이런 게 더 필요할까 하는 생각을 했었으나 과제를 수행하면서, 그리고 강의를 점점 더 들으면서 이번 스터디에 참여하지 않았다면 강의를 듣고, 과제를 수행하는 일은 훨씬 더 기약이 없었겠다는 생각이 들었다. 인프런, 강사님과 다른 러너분들에게도 감사해야겠다 싶었다.나는 비전공자 출신으로 국비 교육과정을 수료한 후 개인적 사정으로 쉬다가 다시 부트캠프 수료 후 현재는 취준중이다. 강의를 들으면서 아는 건 별로 없는데 할줄 안다는 착각만 많이 하며 살았구나, 싶었다. 앞으로 해야 할 일이 많으니 더 열심히 해야 할 것 같다. 자바, 스프링, DB 뿐만 아니라 앞으로 코틀린, 파이썬도 해볼 생각이다.스터디를 처음해서 레포를 처음 열었을 때 막막함이 가시지 않은 것이 아니고 초보이던 사람이 갑자기 고수가 된 것도 아니지만 앞으로 열심히 하면 언젠가 되지 않을까 하며 열심히 해보려 한다.

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

[인프런 워밍업 클럽 1기] BE 6일차 과제

문제 1과제 #4에서 만들었던 API를 Controller - Service - Repository로 분리하기4일차 과제 내용: https://www.inflearn.com/blogs/6676Controller@RequiredArgsConstructor @RestController @RequestMapping("/api/v1/fruit") public class FruitController { private final FruitService fruitService; @PostMapping public ResponseEntity<?> savedFruit(@RequestBody FruitRequest request) { fruitService.save(request); return ResponseEntity.ok().build(); } @PutMapping public ResponseEntity<?> FruitStateUpdate(@RequestBody FruitRequest request) { fruitService.stateUpdate(request); return ResponseEntity.ok().build(); } @GetMapping("/stat") public ResponseEntity<?> isSaleStateTotalPrice(@RequestParam String name) { return ResponseEntity.ok(fruitService.getSum(name)); } }Service@RequiredArgsConstructor @Service public class FruitService { private final FruitRepository fruitRepository; public void save(FruitRequest request) { fruitRepository.saveFruit(request); } public void stateUpdate(FruitRequest request) { boolean isFruitNotExist = fruitRepository.isFruitNotExist(request.getId()); if (isFruitNotExist) { throw new IllegalStateException("일치하는 과일 정보가 없습니다."); } fruitRepository.updateFruit(request.getId()); } public FruitTotalPriceResponse getSum(String name) { boolean isFruitNotExist = fruitRepository.isFruitNotExist(name); if (isFruitNotExist) { throw new IllegalStateException("일치하는 과일 정보가 없습니다."); } List<FruitTotalPriceResponse> sumResult = fruitRepository.getSum(name); long salesAmount = 0; long noSalesAmount = 0; for (FruitTotalPriceResponse result : sumResult) { salesAmount += result.getSalesAmount(); noSalesAmount += result.getNoSalesAmount(); } return new FruitTotalPriceResponse(salesAmount, noSalesAmount); } } Repository @RequiredArgsConstructor @Repository public class FruitRepository { private final JdbcTemplate jdbcTemplate; public void saveFruit(FruitRequest request) { String sql = "insert into fruit (name, warehousingDate, price) values (?, ? ,?)"; jdbcTemplate.update(sql, request.getName(), request.getWarehousingDate(), request.getPrice()); } public void updateFruit(long id) { String sql = "update fruit set is_sale = 1 where id = ?"; jdbcTemplate.update(sql, id); } public List<FruitTotalPriceResponse> getSum(String name) { String sql = "select is_sale, sum(price) as totalPrice from fruit " + "where name = ? group by is_sale"; return jdbcTemplate.query(sql, new Object[]{name}, (rs, rowNum) -> new FruitTotalPriceResponse( rs.getBoolean("is_sale") ? rs.getLong("totalPrice") : 0, !rs.getBoolean("is_sale") ? rs.getLong("totalPrice") : 0)); } public boolean isFruitNotExist(long id) { String sql = "select * from fruit where id = ?"; return jdbcTemplate.query(sql, (rs, rowNum) -> 0, id).isEmpty(); } public boolean isFruitNotExist(String name) { String sql = "select * from fruit where name = ?"; return jdbcTemplate.query(sql, (rs, rowNum) -> 0, name).isEmpty(); } } 문제 2 FruitRepository를 FruitMemoryRepository 와 FruitMemoryRepository 로 나누자 먼저 FruitRepository를 만든다public interface FruitRepository { public void saveFruit(FruitRequest request); public void updateFruit(long id); public List<FruitTotalPriceResponse> getSum(String name); public boolean isFruitNotExist(long id); public boolean isFruitNotExist(String name); }FruitMemoryRepository@Primary @Repository public class FruitMemoryRepository implements FruitRepository{ private final List<FruitRequest> fruits = new ArrayList<>(); @Override public void saveFruit(FruitRequest request) { fruits.add(request); } @Override public void updateFruit(long id) { fruits.stream() .filter(fruit -> fruit.getId() == id) .findFirst() .ifPresent(fruit -> fruit.setSale(true)); } @Override public List<FruitTotalPriceResponse> getSum(String name) { return fruits.stream() .filter(fruit -> fruit.getName().equals(name)) .collect(Collectors.groupingBy(FruitRequest::isSale, Collectors.summingLong(FruitRequest::getPrice))) .entrySet().stream() .map(entry -> new FruitTotalPriceResponse( entry.getKey() ? entry.getValue() : 0, !entry.getKey() ? entry.getValue() : 0)) .collect(Collectors.toList()); } @Override public boolean isFruitNotExist(long id) { return fruits.stream().noneMatch(fruit -> fruit.getId() == id); } @Override public boolean isFruitNotExist(String name) { return fruits.stream().noneMatch(fruit -> fruit.getName().equals(name)); } } FruitMySqlRepository@Qualifier("mysql") @RequiredArgsConstructor @Repository public class FruitMySqlRepository implements FruitRepository { private final JdbcTemplate jdbcTemplate; public void saveFruit(FruitRequest request) { String sql = "insert into fruit (name, warehousingDate, price) values (?, ? ,?)"; jdbcTemplate.update(sql, request.getName(), request.getWarehousingDate(), request.getPrice()); } public void updateFruit(long id) { String sql = "update fruit set is_sale = 1 where id = ?"; jdbcTemplate.update(sql, id); } public List<FruitTotalPriceResponse> getSum(String name) { String sql = "select is_sale, sum(price) as totalPrice from fruit " + "where name = ? group by is_sale"; return jdbcTemplate.query(sql, new Object[]{name}, (rs, rowNum) -> new FruitTotalPriceResponse( rs.getBoolean("is_sale") ? rs.getLong("totalPrice") : 0, !rs.getBoolean("is_sale") ? rs.getLong("totalPrice") : 0)); } public boolean isFruitNotExist(long id) { String sql = "select * from fruit where id = ?"; return jdbcTemplate.query(sql, (rs, rowNum) -> 0, id).isEmpty(); } public boolean isFruitNotExist(String name) { String sql = "select * from fruit where name = ?"; return jdbcTemplate.query(sql, (rs, rowNum) -> 0, name).isEmpty(); } } FruitService 부분에 생성자에 @Qualifier("mysql")가 있기 때문에 FruitMemoryRepository에 @Primary 어노테이션이 있더라도 직접 지정한 클래스가 우선순위가 높기 때문에 FruitMemoryRepository 주입 받는다. public FruitService(@Qualifier("mysql")FruitRepository fruitRepository) { this.fruitRepository = fruitRepository; }

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

xicodey

[인프런 워밍업 클럽 1기] BE 5일차 과제

문제주어지는숫자를 하나를 받고 해당 숫자만큼 주사위를 돌려, 각 숫자가 몇 번 나오는지 출력하는 문제 public class Main { public static void main(String[] args) { System.out.println("주사위 면의 수를 입력하세요:"); Scanner scanner = new Scanner(System.in); int a = scanner.nextInt(); int r1 = 0, r2 = 0, r3 = 0, r4 =0, r5 = 0, r6 = 0; for (int i = 0; i < a; i++) { double b = Math.random() * 6; if (b >= 0 && b < 1) { r1++; } else if (b >= 1 && b < 2) { r2++; } else if (b >= 2 && b < 3) { r3++; } else if (b >= 3 && b < 4) { r4++; } else if (b >= 4 && b < 5) { r5++; } else if (b >= 5 && b < 6) { r6++; } } System.out.printf("1은 %d번 나왔습니다.\n", r1); System.out.printf("2은 %d번 나왔습니다.\n", r2); System.out.printf("3은 %d번 나왔습니다.\n", r3); System.out.printf("4은 %d번 나왔습니다.\n", r4); System.out.printf("5은 %d번 나왔습니다.\n", r5); System.out.printf("6은 %d번 나왔습니다.\n", r6); } } 제시된 코드를 최대한 클린하게 만들어라 public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int rolls = inputDice(scanner); int sides = inputSide(scanner); int[] results = rollTheDice(rolls, sides); resultPrint(sides, results); } private static int inputSide(Scanner scanner) { System.out.print("주사위 면를 입력해주세요 :"); int sides = scanner.nextInt(); return sides; } private static int inputDice(Scanner scanner) { System.out.print("던질 횟수를 입력해주세요 :"); int rolls = scanner.nextInt(); return rolls; } private static int[] rollTheDice(int rolls, int sides) { int[] results = new int[sides + 1]; for (int i = 1; i <= rolls; i++) { int number = (int)(Math.random() * sides) + 1; results[number]++; } return results; } private static void resultPrint(int sides, int[] results) { for (int i = 1; i <= sides; i++) { System.out.printf("%d은 %d번 나왔습니다.\n", i, results[i]); } } }주사위 면을 받을 수 있는 inputSide함수와 몇번 주사위를 굴릴건지 입력을 받을 수 있는 inputDice 함수,주사위를 돌려 결과를 저장하는 rollTheDice함수와 결과를 출력하는 resultPrint 함수로 구성했다.각 변수는 의미있는 변수명으로 바꾸고 메서드명도 그에 맞게 바꾸었다.

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

xicodey

[인프런 워밍업 클럽 1기] BE 3일차 과제

자바의 람다식은 왜 등장했을까? 자바는 람다식 함수형 프로그램밍이 사용한 이유는 불필요한 코드를 줄이고, 가독성을 높이기 위해서다 .그리고 함수 만드는 과정없이 한번에 처리 할 수 있기 때문에 생산성이 높아진다.병령 프로그램밍에 용이하다. 람다식과 익명 클래스는 어떤 관계가 있을까? 함수형 프로그래밍이란 함수를 정의하고 이 함수를 데이터 처리부로 보내 데이터를 처리하는 기법이다.데이터 처리부는 데이터만 가지고 있을 뿐, 처리 방법이 정해져 있지 않아 외부에서 제공져 있지 않아 외부에서 제공된 함수에 의존한다.데이터 처리부는 제공된 함수의 입력값으로 데이터를 넣어 함수에 정의된 처리 내용을 실행하고, 동일한 데이터라도 함수 A를 제공한 결과 값과 함수 B를 제공하여 처리된 결과 값은 다를 수 있다 이것이 함수형 프로그램의 특징인 데이터 처이의 다형성이다.람다식은 함수를 하나의 식으로 표현하여 익명 함수를 반환한다.익명 클래스는 선언된 클래스 내에서만 한 번만사용될 경우 별도로 변수에 담을 필요가 없다.람다식을 쓰면 함수형 인터페이스로 인스턴스를 만들 수 있으며 코드를 줄 일 수 있다.메서드 매개변수와 리턴 타입, ㅌ변수로 만들어 사용도 가능하다. 람다식의 문법은 어떻게 될까? 데이터 처리부에 제공되는 함수 역활 하는 매개변수를 가진 중괄호 블록이다.{매개변수, ...} -> {처리 내용};  인터페이스가 단 하나의 추상 메소드를 가질 경우 이를 함수형 인터페이스라고 한다.public interface Runnable { void run(); }람다식() -> { ...}; @FunctionalInterface public interface Calculable { void calculate(int x, int y); }람다식(x, y ) -> { ...}@FunctionalInterface 어노테이션을 사용한 이유는 인터페이스가 함수형 인터페이스를 보장하기 위해서다.붙이는 것은 선택사항이지만, 컴파일 과정에서 추상 메소드가 하나인 검사하기 때문에 정확한 함수형 인터페이스를 작성하게 도와주는 역활을 해준다.매 매개변수가 없는 람다식실행문이 하나일 경우 중괄호를 생략 가능하고 두개 이상일 경우는 생략할 수 없다.() -> 실행문; () -> { 실행문; 실행문; } 매개변수가 있는 람다식매개변수를 선언할 때 타입은 생략할 수 있고, 구체적인 타입 대신에 var를 사용할 수 있다.(타입, 매변수, ... ) -> { 실행문; 실행문; }(타입, 매변수, ... ) -> 실행문;(var 매개변수, ...) -> { 실행문; 실행문; }(var 매개변수, ...) -> 실행문;(매개변수, ...) -> { 실행문; 실행문; }(매개변수, ...) ->실행문;매개변수 -> { 실행문; 실행문 };매개변수 -> 실행문; 리턴값이 있는 람다식return 문 하나만 있는 경우에는 중괄호와 함께 return 키워드를 생략가능하다.(매개변수, ...) -> { 실행문; return 값 )(매개변수, ...) -> 값 메소드 참조메소드를 참조하여 매개변수의 정보 및 리턴 타입을 알아내 람다식에서 불필요한 매개변수를 제거한다. (left, right) -> Math.max(left, right);Math.max() 메소드의 매개값은 전달하는 역활만 하기 때문에 다음과 같이 생략이 가능하다.Math :: max;정적 메소드를 참조할 경우에는 클래스 이름 뒤에 :: 기호를 붙이고 메소드 이름을 기술한다.클래스 :: 메서드참조변수 :: 메소드 매개변수의 메소드 참조(a, b) -> {a.instaceMethod(b);}메소드 참조는 a 클래스 이름 뒤에 :: 기호를 붙이고 매소드 이름을 기술한다.작성 방법은 메소드 참조와 동일하지만, a의 인스턴스 메소드가 사용된다는 점이 다르다.클래스 :: instaceMethod Reference이것은 자바다(책)

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

xicodey

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

어노테이션 사용하는 이유어노테이션은 사용 용도로 3가지가 있습니다.1. 컴파일 시 사용하는 정보 전달2. 빌드 툴이 코드를 자동으로 생성할 때 사용하는 정보 전달3.실행 시 특정 기능을 처리할 때 사용하는 정보 전달컴파일 시 사용하는 정보 전달의 대표적인 예는 @Override 어노테이션입니다.컴파일러가 메소드 재정의 검사를하도록 설정합니다. 재정의되지 않았다면 컴파일러는 에러를 발생시킵니다.웹 개발에 많이 사용하는 Spring Framework 또는 Spring Boot는 다양한 종류의 어노테이션을 사용해서 웹 애플리케이션을 설정하는데 사용합니다.나만의 어노테이션은 어떻게 만들 수 있을까? 어노테이션을 정의하는 방법은 인터페이스를 정의하는것과 유사합니다.@interface 뒤에 사용할 어노테이션을 이름을 정의합니다.오노테이션은 속성을 가질 수 있으며, 속성은 타입과 이름으로 구성됩니다. 속성은 기본값 default 키워드로 지정할 수 있습니다.어떤 대상에 설정 정보를 적용할 것인지, 적용대상을 정의 해야 합니다.클래스 명위에 @Target 어노테이션을 붙어 정의 합니다.적용할 수 있는 대상의 종류는 ElememtType 열거 상수로 정의되어 있습니다.TYPE : 클래스, 인터페이스 열거타입ANOTATION_TYPE: 어노테이션FIELD: 필드CONSTERUCTOR: 생성자METHOD: 메서드LOCAL_VARIABLE: 로컬 변수 예시어노테이션 정의@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface PrintAnnotation { String value() default "-"; int number() default 15; } 서비스 어노테이션 적용public class Service { @PrintAnnotation public void method1() { System.out.println("실행 내용1"); } @PrintAnnotation("*") public void method2() { System.out.println("실행 내용2"); } @PrintAnnotation(value = "#", number = 20) public void method3() { System.out.println("실행 내용3"); } } 실행 코드public class PrintAnnotationExample { public static void main(String[] args) throws InvocationTargetException, IllegalAccessException { Method[] declaredMethods = Service.class.getDeclaredMethods(); for (Method method : declaredMethods) { PrintAnnotation printAnnotation = method.getAnnotation(PrintAnnotation.class); printList(printAnnotation); method.invoke(new Service()); printList(printAnnotation); } } public static void printList(PrintAnnotation printAnnotation) { if (printAnnotation != null) { int number = printAnnotation.number(); for (int i = 0; i < number; i++) { String value = printAnnotation.value(); System.out.print(value); } System.out.println(); } } } 출력 내용

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

xicodey

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

문제 1두 수를 입력하면, 다음과 같은 결과가 나오는 GET API만들기@GetMapping("api/v1/calc") public ResponseEntity<?> calc(Calculator request){ CalculatorResponse response = calculatorService.calc(request); return ResponseEntity.ok(response); }CalculatorController에 Post 요청 메서드로 외부 파라미터를 받기 위해 응답 객체로 Calculator 를 정의했습니다. @Getter @AllArgsConstructor public class Calculator { private final int num1; private final int num2; } calulatorService 정의하여 비지니스 로직을 작성했습니다.@Service public class CalculatorService { public CalculatorResponse calc(Calculator request) { return new CalculatorResponse( add(request), minus(request), multiply(request)); } private static int add(Calculator request) { return request.getNum1() + request.getNum2(); } private static int minus(Calculator request) { return request.getNum1() - request.getNum2(); } private static int multiply(Calculator request) { return request.getNum1() * request.getNum2(); } }응답용 객체로 CalculatorResponse를 정의를 했습니다.@Data @NoArgsConstructor @AllArgsConstructor public class CalculatorResponse { private int add; private int minus; private int multiply; }그리하여 calulatorService에 요청 받은 두 데이터를 처리하여 CalculatorResponse로 ResponseEntity에 담아 200 응답으로 JSON 반환값으로 보냅니다.문제 2날짜를 입력하면, 몇 요일인지 알려주는 GET API 만들기@RestController @RequestMapping("/api/v1") public class DateController { @GetMapping("/getDayOfWeek") public ResponseEntity<?> getDayOfWeek(@RequestParam String date) { try { LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")); String dayOfTheWeek = localDate.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.ENGLISH).toUpperCase(); return ResponseEntity.ok(Collections.singletonMap("dayOfTheWeek", dayOfTheWeek)); } catch (DateTimeException e) { return ResponseEntity.badRequest().body("Invalid date format"); } } }클라이언트 요청을 처리하고 응답을 반환하기 위해 @RestController 어노테이션을 씁니다.@GetMapping("/getDayOfWeek") 어노테이션을 써서 GET 요청이 오면 메소드가 호출됩니다.@RequestParam을 써서 date 파리미터를 받습니다.받은 날짜 문자열을 'LocalDate' 객체로 반환하기 위해 'DateTimeForrmatter'를 사용하여 날짜 형식을 지정합니다. 그리고 LocalDate 객체의 getDayofWeek() 메서드를 사용하여 요일을 구할 수 있습니다.마지막으로 JSON 형식으로 반환하기 위해 Collections.singletonMap을 사용하여 간단하게 키-값 쌍을 만들어 JSON형식으로 반환할 수 있습니다.문제3여러 수를 받아 총 합을 반환하는 POST API 만들기 @Data public class CalculatorRequest { private List<Integer> numbers; }클라이언트로 부터 받기 위해 숫자 배열릉 받기 위해 List<Integer> 필드를 가진 클래스를 만듭니다. @PostMapping("/sum") public int calculateSum(@RequestBody CalculatorRequest request) { return request.getNumbers().stream() .mapToInt(Integer::intValue) .sum(); }CalculatorController에 Post요청을 처리하기 위해 @PostMapping 어노테이션을 사용합니다.@@RequestBody를 사용하여 JSON 데이터를 CalculatorRequest 객체로 변환됩니다.stream을 돌려 합계를 계산한 다음, 그 결과를 반환합니다.

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

채널톡 아이콘