kdonghan0529
수강평 작성수
-
평균평점
-
블로그
전체 5#카테고리
- 백엔드
![[인프런 워밍업 스터디 클럽] 백엔드 과제5](https://cdn.inflearn.com/public/main/blog/default_thumbnail.png?w=260)
2024. 02. 22.
0
[인프런 워밍업 스터디 클럽] 백엔드 과제5
문제public class Main { public static void main(String[] args) throws Exception { System.out.println("숫자를 입력하세요 : "); Scanner scanner = new Scanner(System.in); int numberOfThrows = scanner.nextInt(); int[] counts = new int[6]; // 각 주사위 횟수를 저장할 배열 for (int i = 0; i
![[인프런 워밍업 스터디 클럽] 백엔드 과제4](https://cdn.inflearn.com/public/main/blog/default_thumbnail.png?w=260)
2024. 02. 22.
0
[인프런 워밍업 스터디 클럽] 백엔드 과제4
문제 1private final FruitService fruitService; public FruitController(FruitService fruitService) { this.fruitService = fruitService; } @PostMapping("/api/v1/fruit") public void saveFruit(@RequestBody FruitCreateRequest request) { fruitService.saveFruit(request); }public class FruitCreateRequest { private String name; private LocalDate warehousingDate; private long price; public String getName() { return name; } public LocalDate getWarehousingDate() { return warehousingDate; } public long getPrice() { return price; } }private final FruitRepository fruitRepository; public FruitService(FruitRepository fruitRepository) { this.fruitRepository = fruitRepository; } public void saveFruit(FruitCreateRequest request) { fruitRepository.saveFruit(request.getName(), request.getWarehousingDate(), request.getPrice()); }private final JdbcTemplate jdbcTemplate; public FruitRepository(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public void saveFruit(String name, LocalDate warehousingDate, long price) { String sql = "INSERT INTO fruit (name, stocked_date, price) VALUES (?, ?, ?)"; jdbcTemplate.update(sql, name, warehousingDate, price); }문제 2 @PutMapping("/api/v1/fruit") public void soldFruit(@RequestBody FruitUpdateRequest request) { fruitService.updateFruit(request); }public class FruitUpdateRequest { private long id; private String name; private LocalDate warehousingDate; private long price; private String status; public long getId() { return id; } public String getName() { return name; } public LocalDate getWarehousingDate() { return warehousingDate; } public long getPrice() { return price; } public String getStatus() { return status; } }public void updateFruit(FruitUpdateRequest request) { if (fruitRepository.isFruitNotExist(request.getId())) { throw new IllegalArgumentException(); } fruitRepository.updateFruit(request.getId()); }public void updateFruit(long id) { String sql = "UPDATE fruit SET status = 1 WHERE id = ?"; jdbcTemplate.update(sql, id); } public boolean isFruitNotExist(long id) { String readSql = "SELECT * FROM fruit WHERE id = ?"; return jdbcTemplate.query(readSql, (rs, rowNum) -> 0, id).isEmpty(); }문제 3@GetMapping("/api/v1/fruit/stat") public ResponseEntity getFruitStat(@RequestParam String name) { FruitStatResponse response = fruitService.getFruitStat(name); return new ResponseEntity(response, HttpStatus.OK); }public class FruitStatResponse { private long salesAmount; private long notSalesAmount; // Constructor public FruitStatResponse(long salesAmount, long notSalesAmount) { this.salesAmount = salesAmount; this.notSalesAmount = notSalesAmount; } // Getters and setters public long getSalesAmount() { return salesAmount; } public void setSalesAmount(long salesAmount) { this.salesAmount = salesAmount; } public long getNotSalesAmount() { return notSalesAmount; } public void setNotSalesAmount(long notSalesAmount) { this.notSalesAmount = notSalesAmount; } } public FruitStatResponse getFruitStat(String fruitName) { long salesAmount = fruitRepository.sumPriceByFruitNameAndIsSoldTrue(fruitName); long notSalesAmount = fruitRepository.sumPriceByFruitNameAndIsSoldFalse(fruitName); return new FruitStatResponse(salesAmount, notSalesAmount); } public long sumPriceByFruitNameAndIsSoldTrue(String name) { String sql = "SELECT SUM(price) FROM fruit WHERE name = ? AND status = 1"; return jdbcTemplate.queryForObject(sql, new Object[] {name}, Long.class); } public long sumPriceByFruitNameAndIsSoldFalse(String name) { String sql = "SELECT SUM(price) FROM fruit WHERE name = ? AND status = 0"; return jdbcTemplate.queryForObject(sql, new Object[] {name}, Long.class); }
![[인프런 워밍업 스터디 클럽] 백엔드 과제3](https://cdn.inflearn.com/public/main/blog/default_thumbnail.png?w=260)
2024. 02. 19.
0
[인프런 워밍업 스터디 클럽] 백엔드 과제3
문제 1 자바의 람다식은 왜 등장했을까?1. 람다식(Lambda Expression) 이란?Stream 연산들은 매개변수로 함수형 인터페이스(Functional Interface)를 받도록 되어있다. 그리고 람다식은 반환값으로 함수형 인터페이스를 반환하고 있다. 그렇기 때문에 우리는 Stream API를 정확히 이해하기 위해 람다식과 함수형 인터페이스에 대해 알고 있어야 한다. [ 람다식(Lambda Expression) 이란? ]람다식(Lambda Expression)이란 함수를 하나의 식(expression)으로 표현한 것이다. 함수를 람다식으로 표현하면 메소드의 이름이 필요 없기 때문에, 람다식은 익명 함수(Anonymous Function)의 한 종류라고 볼 수 있다.익명함수(Anonymous Function)란 함수의 이름이 없는 함수로, 익명함수들은 모두 일급 객체이다. 일급 객체가 무엇인지는 앞선 포스팅에서 자세히 다루었다. 일급 객체인 함수는 변수처럼 사용가능하며 매개 변수로 전달이 가능하는 등의 특징을 가지고 있다.기존의 방식에서는 함수를 선언할 때 다음과 같이 선언하였다.// 기존의 방식반환티입 메소드명 (매개변수, ...) { 실행문}// 예시public String hello() { return "Hello World!";} 하지만 람다 방식으로는 위와 같이 메소드 명이 불필요하며, 다음과 같이 괄호() 와 화살표-> 를 이용해 함수를 선언하게 된다.// 람다 방식(매개변수, ... ) -> { 실행문 ... }// 예시() -> "Hello World!"; 이렇게 람다식이 등장하게 된 이유는 불필요한 코드를 줄이고, 가독성을 높이기 위함이다. 그렇기 때문에 함수형 인터페이스의 인스턴스를 생성하여 함수를 변수처럼 선언하는 람다식에서는 메소드의 이름이 불필요하다고 여겨져서 이를 사용하지 않는다. 대신 컴파일러가 문맥을 살펴 타입을 추론한다. 또한 람다식으로 선언된 함수는 1급 객체이기 때문에 Stream API의 매개변수로 전달이 가능해진다. 람다식(Lambda Expression) 의 특징람다식 내에서 사용되는 지역변수는 final이 붙지 않아도 상수로 간주된다. 람다식으로 선언된 변수명은 다른 변수명과 중복될 수 없다. 람다식(Lambda Expression) 의 장점코드를 간결하게 만들 수 있다.식에 개발자의 의도가 명확히 드러나 가독성이 높아진다.함수를 만드는 과정없이 한번에 처리할 수 있어 생산성이 높아진다.병렬프로그래밍이 용이하다. 람다식(Lambda Expression) 의 단점람다를 사용하면서 만든 무명함수는 재사용이 불가능하다.디버깅이 어렵다.람다를 남발하면 비슷한 함수가 중복 생성되어 코드가 지저분해질 수 있다.재귀로 만들경우에 부적합하다. 결국 무조건 람다가 좋다는 보장은 없다. 상황에 따라 필요에 맞는 방법을 사용하는 것이 중요하다.출처: https://mangkyu.tistory.com/113 [MangKyu's Diary:티스토리] 문제 2 람다식과 익명 클래스는 어떤 관계가 있을까? - 람다식의 문법은 어떻게 될까?람다식과 익명 클래스는 두 가지 모두 자바에서 익명 함수를 표현하는 방법입니다.관계:익명 클래스는 인터페이스나 추상 클래스의 익명 구현을 생성할 때 사용됩니다. 이는 Java 7 이전에는 주로 이벤트 핸들러나 스레드 등을 처리할 때 유용하게 활용되었습니다.람다식은 Java 8에서 등장한 것으로, 간결하게 함수를 표현하는 방법입니다. 익명 클래스와 마찬가지로 함수형 인터페이스의 익명 구현을 생성할 수 있습니다. 그러나 람다식은 보다 간결하고 가독성이 좋으며, 함수형 프로그래밍 스타일을 자바에 도입하는 데 중점을 두고 있습니다.람다식의 문법:람다식은 파라미터 목록, 화살표(->), 그리고 바디로 구성됩니다.기본 문법: (파라미터) -> {바디}예를 들어, 정수 두 개를 받아서 더한 결과를 반환하는 함수는 다음과 같이 표현할 수 있습니다.cssCopy code(int a, int b) -> { return a + b; } 람다식은 타입 추론을 통해 타입을 유추할 수 있으므로, 일반적으로 파라미터의 타입을 생략할 수 있습니다.cssCopy code(a, b) -> { return a + b; } 바디가 단일 문장인 경우 중괄호({})와 return 키워드를 생략할 수 있습니다.cssCopy code(a, b) -> a + b 람다식은 함수형 인터페이스의 익명 구현을 생성하는데 사용되므로, 해당 인터페이스의 메서드와 동일한 시그니처를 가져야 합니다. 함수형 인터페이스는 단 하나의 추상 메서드만을 가지는 인터페이스를 말합니다.이렇게 람다식은 익명 함수의 표현을 간결하게 만들어주며, 자바에서 함수형 프로그래밍을 보다 쉽게 할 수 있도록 도와줍니다.
![[인프런 워밍업 스터디 클럽] 백엔드 과제2](https://cdn.inflearn.com/public/main/blog/default_thumbnail.png?w=260)
2024. 02. 19.
0
[인프런 워밍업 스터디 클럽] 백엔드 과제2
문제 1public class CalcResult { private int add; private int minus; private int multiply; public CalcResult(int add, int minus, int multiply) { this.add = add; this.minus = minus; this.multiply = multiply; } public int getAdd() { return add; } public int getMinus() { return minus; } public int getMultiply() { return multiply; } }@GetMapping("/api/v1/calc") public CalcResult calculate(@RequestParam("num1") int num1, @RequestParam("num2") int num2) { int addResult = num1 + num2; int minusResult = num1 - num2; int multiplyResult = num1 * num2; return new CalcResult(addResult, minusResult, multiplyResult); }문제2public class DayOfTheWeekResponse { private String dayOfTheWeek; public DayOfTheWeekResponse(String dayOfTheWeek) { this.dayOfTheWeek = dayOfTheWeek; } public String getDayOfTheWeek() { return dayOfTheWeek; } }@GetMapping("/api/v1/day-of-the-week") public DayOfTheWeekResponse getDayOfTheWeek(@RequestParam("date") String dateString) { // 입력된 날짜를 Date 객체로 변환 Date date = parseDate(dateString); // 날짜에서 요일을 계산 String dayOfWeek = calculateDayOfTheWeek(date); // 결과를 DayOfTheWeekResponse 객체로 반환 return new DayOfTheWeekResponse(dayOfWeek); } // 입력된 문자열을 Date 객체로 파싱하는 메서드 private Date parseDate(String dateString) { try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); return sdf.parse(dateString); } catch (Exception e) { throw new IllegalArgumentException("Invalid date format. Please provide date in yyyy-MM-dd format."); } } // 요일을 계산하는 메서드 private String calculateDayOfTheWeek(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); // 요일을 문자열로 변환하여 반환 return new SimpleDateFormat("EEE", Locale.ENGLISH).format(date).toUpperCase(); }문제 3public class AddTotalController { @PostMapping("/addTotal") public int addTotal(@RequestBody NumbersRequest request) { return request.getNumbers().stream().mapToInt(Integer::intValue).sum(); } }public class NumbersRequest { private List numbers; public List getNumbers() { return numbers; } }
![[인프런 워밍업 스터디 클럽] 백엔드 과제1](https://cdn.inflearn.com/public/main/blog/default_thumbnail.png?w=260)
2024. 02. 19.
1
[인프런 워밍업 스터디 클럽] 백엔드 과제1
[질문]어노테이션을 사용하는 이유 (효과) 는 무엇일까? - 코드량이 감소하고 유지보수하기 쉬우며, 생산성이 증가한다.나만의 어노테이션은 어떻게 만들 수 있을까?[ 커스텀 어노테이션 만들기 ]예를 들어 다음과 같은 RestMemberController를 개발하여 Swagger로 문서화한다고 하자. 여기서 @Api와 @RestController 어노테이션은 다른 RestController들에도 공통적으로 적용되는데, 이를 커스텀 어노테이션으로 만들어 반복 작업을 줄여보도록 하자.@Api @RestController @RequiredArgsConstructor @RequestMapping("/member") public class RestMemberController { private final MemberService memberService; @ApiOperation("멤버 목록 반환") @GetMapping("/list") public ResponseEntity upload() { return ResponseEntity.ok(memberService.getList()); } }1. 어노테이션 생성어노테이션은 다음과 같이 인터페이스 앞에 @를 붙여서 생성할 수 있다.public @interface RestControllerWithSwagger { }위와 같이 생성된 어노테이션은 다른 곳에서 참조되지만 아무런 기능도 하지 않는다. 2. 메타 어노테이션 추가앞서 다른 어노테이션에 적용되기 위한 메타 어토네이션에 대해 살펴보았다. 그 중에서 필요한 것들을 적용하면 된다.@Retention(RetentionPolicy.RUNTIME) @Inherited @Documented @Target(ElementType.TYPE) public @interface RestControllerWithSwagger { } 위의 예제에서는 컴파일 이후에도 JVM에 의해 계속 참조가 가능하도록 @Retention(RetentionPolicy.RUNTIME) 을 적용하였으며, 하위 클래스에도 적용가능하도록 @Inherited를 적용하였다. 또한 javadoc에 의해 문서화가 되도록 @Documented를 적용하였으며, 타입 선언 시 어노테이션을 적용할 수 있도록 @Target(ElementType.TYPE)를 적용하였다. 여러 타겟을 원하는 경우에는 @Target({ElementType.TYPE, ElementType.Field}) 와 같이 사용하면 된다. 3. 적용할 어노테이션 추가추가적으로 적용할 어노테이션이 있으면 추가해준다. 우리는 @Api와 @RestController라는 어노테이션을 공통으로 묶을 것이므로 이를 추가해준다.@Api @RestController @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented @Target(ElementType.TYPE) public @interface RestControllerWithSwagger { String name() default "RestController"; String value(); } 4. 변수 추가어노테이션에 값을 부여하기를 원한다면 변수를 다음과 같이 선언해줄 수 있다.@Api @RestController @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented @Target(ElementType.TYPE) public @interface RestControllerWithSwagger { String name() default "RestController"; String value(); } 5. 적용하기위와 같은 과정으로 어노테이션을 생성하였으면 이제 다음과 같이 적용할 수 있다.@RestControllerWithSwagger(value = "RestMemberController", name = "RestMemberController") @RequiredArgsConstructor @Test1 @RequestMapping("/member") public class RestMemberController { private final MemberService memberService; @ApiOperation("멤버 목록 반환") @GetMapping("/list") public ResponseEntity upload() { return ResponseEntity.ok(memberService.getList()); } }출처: https://mangkyu.tistory.com/130 [MangKyu's Diary:티스토리]
백엔드




