Java
자바 코딩 테스트 프로그래머스를 풀면서 많이 고민했던 문제를 정리해두려고 한다..
우선 문제는 정수가 들어있는 배열을 순회하면서 배열의 각각의 원소를 x라는 정수로 나누었을 때 0이 되는 원소들을 찾고
그 원소들만 들어있는 배열을 리턴하는 문제이다. 리턴할 때는 배열원소를 오름차순으로 정렬해야한다.
처음에 이것을 어떻게 해결할 것인가를 생각해보았다.
1. for문을 사용해서 배열을 순회하면서 각각의 원소들을 x라는 정수를 나누었다. 나누어 떨어지는 것들을 if 분기를 사용해서 값을 찾아내긴 했는데 값을 어떻게 담을것인가 고민을 했다.
2. 값을 넣는 방법으로 새로운 배열을 다시 생성해서 위에서 도출된 원소들만 새로운 배열에 넣어주는 것이다.
여기서 문제가 생겼는데 기존 배열의 크기만큼 돌아서 새로운 배열에 넣어주기 때문에 참조 범위가 벗어나게 된다.
3. 1번에서 도출된 값들을 새로운 배열에 먼저 담기 전에 값을 먼저 저장을 해둘까 생각을 했지만 배열에 들어오는 정수의 갯수는 정해져 있는 것이 아니기때문에 불가능하다 생각하고 이건 시도해보지 않았다.
4. 그러다 생각난 것이 컬렉션 프레임워크 List 클래스이다.
5. List 로 하나의 ArrayList 를 만들어두었고, 1번에서 도출된 값들만 List.add 형식으로 저장을 해두었다.
6. 이제 그러면 오름 차순으로 변경을 해줘야 하는데 이 것또한 구글링으로 List Method 를 검색을 해보았고, List Method 중에서 sort 라는 메서드가 있었고, 옵션 값으로 Comparator 를 줄 수 있다는 것을 알게됐다. Comparator 에는 오름차순으로 할지, 내림차순으로 할지 선택할 수 있어서 오름차순인 naturalOrder() 값을 주었다.
7. 리턴값으로 요구하는 것이 배열이기 때문에 List를 배열로 변환해서 주었다. 성공 !!!
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
class Solution {
public int[] solution(int[] arr, int divisor) {
int[] fail = {-1};
List<Integer> list = new ArrayList<>();
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % divisor == 0) {
count++;
list.add(arr[i]);
}
}
if(count ==0){
return fail;
}
list.sort(Comparator.naturalOrder());
int[] answer = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
answer[i] = list.get(i);
}
return answer;
}
}
팀 프로젝트 Deilvery Management
오늘은 배민 같은 웹 사이트를 만드는 프로젝트에서 내가 맡은 부분인 가게 부분을 개발했다..
개발하면서 남길만한 것은 데이터 삭제하는 부분이다.
클라이언트가 데이터 삭제를 요청할 시 DB에 남겨두어야 한다고 생각을 했다. 왜냐하면 삭제 요청한 이후에 다시 재가입을 요청할 수도 있고, 클라이언트가 원치않는 삭제가 될 수 있는 경우가 있다 생각했다.
그래서 이것을 어떻게 할까 생각을 해보았는데,
삭제 요청시 jpa에서 제공하는 delete 기능을 수행하는 것이 아니라, 해당 요청이 들어오면 서비스 계층에서 상태 필드값만 바꿔주는 것을 생각해보았다.
전체 조회하거나 단일 조회 할때 상태값이 삭제되어있는것만 제외해서 내보내주기로 해보았는데 성공했다.
제어의 역전 IoC : Inversion of Control
사용할 객체를 직접 생성하지 않는다. 그리고 객체의 생명주기 관리를 스프링 컨테이너 또는 IoC컨테이너에 위임해준다.
객체의 관리를 컨테이너에 맡겨 제어권이 넘어간 것을 제어 역전이라고 부른다.
제어 역전을 통해 의존성 주입(DI), 관점 지향 프로그래밍(AOP)가 가능해집니다.
IoC 하지 않는 경우
private final User user = new User();
IoC 되는 경우
private final User user;
여기서 끝나는 것이 아니라 위에 IoC 되는 경우에 필드를 보면 user 객체를 넣어 줘야 한다.
이 때 사용하는 방법이 의존성 주입(DI) 라는 기술이 등장한다.
의존성 주입에는 생성자를 통한 주입, 필드를 통한 주입, 세터를 통한 주입 방법등이 있는데 세 가지 모두 의존성 주입하기 위해서는 @Autowired 라는 키워드가 필요하고 등장한다.
스프링 공식 문서에서는 생성자를 통해 의존성을 주입받는 것을 권장하고 있다고 한다.
참고로 생성자를 통한 DI를 할 때는 @Autowried 애너테이션이 필요하지 않음.
Entity 필드 작성
Entity 작성할 때 기본 생성자는 PROTECTED로 제한을 해야한다. JPA에서 권장 가이드로 내놓았으며, 무분별한 new 예약어를 사용하여 만들어 내는 것을 막기 위함 같다. PRIVATE 로 만들게 되면 가짜 객체를 생성해서 HIBERNATE 에서 사용하지 못한다고 들었다.
그러면 서비스 레이어 계층에서 해당 객체를 만들기 위해 어떻게 해야하나
-> 빌더를 사용한 객체 생성
-> 정적 팩토리 메서드 객체 생성
두 가지 방법이 있는데 빌더를 사용한 방법은 단점이 명확하기 때문에 정적 팩토리 메서드 객체 생성 방법을 선호한다.
빌더를 사용하게 되면 값을 넣지 않아도 객체 생성에 자유롭고 컴파일 오류가 발생하지 않는다.
만약 사용자 회원정보를 저장하는데 이름을 넣지 않고 저장하여도 저장이 된다는 말이다. 이 사용자를 조회하려고 하거나 이름을 수정하려고 할 때 NullPointerException 제일 무서운 예외가 발생할 것이다. 이 것을 방지 하기 위해 정적 팩토리 메서드 방법을 선호한다.
정적 메서드 방법은 static 메서드를 하나 public 으로 열어두면서 객체 생성을 객체 안에서 진행하게 된다. 그리고 메서드에서 생성한 객체를 리턴값으로 던져준다.
기타
DTO
GetMapping 을 사용하여 Request Param형식으로 값을 서버에게 보내줄 때 DTO 를 사용하여 값을 전달 받을 수 있다.
DTO를 사용하게 되는 이유가 받아야 할 파라미터가 많은 경우에 사용하는데 궁금한 점이 생겼다.

DTO 객체를 사용하지 않고 직접 변수명을 매핑했을 때 우리가 요청을 보낼때 name 을 nam으로 보내게 되면 400 응답코드를 보내준다. 실패했다는 뜻이고 클라이언트 쪽에서 요청을 잘못했다는거다

MemberDto 클래스 안에는 동일하게 name, emial, organization 이라는 필드가 존재한다.
그런데 요청을 서버로 보낼때 name 을 nam이라고 보내도 400응답 코드가 아닌 성공 응답 코드와 함께 데이터가 전달이 되어 온다.
'TIL & STUDY' 카테고리의 다른 글
| TIL 18 : 도커로 주키퍼 & 카프카 실행 및 토픽 생성 테스트 (0) | 2025.11.19 |
|---|---|
| TIL 17 : 블로킹과 논블로킹 (0) | 2025.11.08 |
| TIL 15 : URI 버전관리와 다국어 언어 처리 (0) | 2025.10.02 |
| Daily Study : 14 (0) | 2025.10.01 |
| Daily Study : 13 (0) | 2025.09.30 |