오늘은 코드카타 SQL 61번 문제와 알고리즘 57~59번 문제를 풀고, 심화 Spring 강의를 다 들을 뻔 했다.
오늘은 1개의 SQL 문제를 풀었는데, 사실 사전캠프 때 풀었던 문제였다..
join을 사용해 2개의 테이블을 매핑하고, 거기에서 조건을 걸어 데이터를 검색하는 것이었다.
오늘은 드디어!! 오랜만에 알고리즘 문제를 풀었다.
오늘 푼 첫 번째 문제는 어제 끝내지 못한 문제였는데,, 일정한 패턴을 가지고 답을 내는 3명의 학생의 답안지를 채점하고, 그중 가장 높은 점수를 받은 학생 배열을 반환하는 것이다.
어제 점수를 채점하는 것까지는 했지만, 높은 점수를 받은 학생 배열을 반환하는 것을 풀지 못했다.
그런데, 그냥 점수 배열의 max를 뽑고, max 값과 일치한 점수를 가진 학생을 List 컬렉션에 저장한 뒤, 그 컬렉션을 배열로 다시 바꾸며 해결할 수 있었다.
최대한 임포트문 없이 해결하고 싶었지만,, 결국 실패하였다..
그래도 다른 사람들의 풀이도 나와 크게 다를 바가 없었기에, 이 문제는 여기에서 멈추기로 했다.
두 번째 문제는 숫자 배열을 입력받으면 그 중 3개의 숫자를 더했을 때 소수가 되는 경우의 수를 구하는 것이었다.
이건 정말 정말 쉽게 해결할 수 있었는데!!
이전에 3개의 숫자를 더하는 것은 이미 해보았고, 소수인지 아닌지를 판단하는 것도 해보았었다.
그래서 그냥 두개의 풀이 방식을 합쳐서 쉽게 해결할 수 있었다.
마지막으로 세 번째 문제는 벽에 페인트를 덧칠하는 문제였다..
요즘은 풀기 어렵다기 보다는 문제를 이해하는 것부터가 어렵다..
그래도 문제를 이해하고 나니 접근하는 것에는 큰 어려움이 없었고, 중간에 뻘짓을 해서 OutOfBound 예외가 생기긴 했지만, 금방 해결할 수 있었다.
오늘 푼 문제와 풀이는 깃허브를 통해 업로드해두었다.
GitHub 보러가기
오늘은 4주차 강의를 끝내고, 5주차 강의는 2개 빼고 다 들었다..
4주차 강의는 JPQL과 N+1 문제의 해결법에 대한 내용이었다.
JPQL은 지난 팀 프로젝트 때 해야만 하는 상황이 생겨 어쩔 수 없이 배워버렸었다..
하지만 사실 기본 SQL 문법과 크게 다를 바가 없었기 때문에, SQL 코드카타를 매일 하는 나에게는 껌이었다ㅎ
N+1 문제도 팀 프로젝트 때 해결해보자 이야기가 나왔었지만, 시간 상의 이유로 해결하지 못하고 끝냈었다..
N+1 문제는 엔티티 1개를 조회할 때 필요하지 않은 추가 쿼리 N개가 더 실행되는 상황인데,
이게 프로젝트가 커지게 되면 1개의 쿼리문을 실행해야 하는 상황에 100개, 1000개의 쿼리문이 발생되고,
그러다보면 시스템이 과부하되어 큰 장애로 이어지게 될 수도 있다.
처음에는 어차피 자바는 라인 순서대로 실행되니 어쩔 수 없는 상황이 아닌가 싶었는데, 프로젝트가 고도화될 때를 생각해보니 매우 심각한 문제이겠더라.
이걸 해결하는 방법은 총 4가지가 있는데,
두 개의 테이블을 join하는 쿼리문을 직접 작성하여 한 번의 쿼리로 조회하는 Fetch Join을 사용하는 방법과
Hibernate 설정을 통해 연관된 엔티티를 배치로 로딩하게 하는 BatchSize를 사용하는 방법,
즉시 로딩하도록 지원하는 EntityGraph 어노테이션을 사용하는 방법,
그리고 원하는 컬럼만 선택하여 바로 DTO로 직접 매핑하는 방법이 있다.
각각의 방식에는 장단점이 있기에 상황과 필요에 맞는 방식을 선택하면 된다.
5주차의 내용은 테스트 코드를 작성하는 방법에 대한 것이었는데,
테스트 코드를 사용하면 개발 과정에서 문제를 미리 파악할 수 있고, 코드의 의도를 명확하게 표현할 수 있게 된다.
테스트를 할 때는 하나의 메서드를 독립적으로, 최소 단위로 테스트를 진행할 수도 있고,
한 API에 대해 전체 계층을 묶어 통합 테스트를 진행할 수도 있고,
실제 사용자가 프로그램을 사용하는 시나리오를 기반으로 여러 API를 실행해보는 종단 테스트를 진행할 수도 있다.
오늘 들은 강의에서는 단위 테스트를 중점적으로 다뤘는데,
단위 테스트에서 주의할 것은 테스트의 독립성, 즉 하나의 테스트에는 하나의 역할만을 부여해야 한다는 것이다.
예를 들어, 하나의 메서드가 객체를 생성함과 객체를 저장함 2가지를 진행한다면,
하나의 테스트에서는 객체를 생성하는 것만 확인하고, 다른 테스트에서 객체를 저장하는 것을 확인해야 한다.
또, 테스트의 독립성을 지키기 위해서는 테스트 코드가 DB나 외부 API 등에 의존해서는 안 된다.
예를 들어, Post Service에서 하나의 메서드가 User Repository와 Post Repository를 사용한다면,
테스트 코드를 만들 때에는 이걸 의존하도록 만들어서는 안 된다.
그래서 실제처럼 동작하지만, 테스트를 위해 가짜로 만든 객체, Mock 객체를 만들어서 사용한다.
더 자세한 설명과 실습 내용은 노션에 정리해두었다.
Notion 확인하기
오늘은 오랜만에 코드카타도 잔뜩 풀었다!
강의는.. 그냥 공부가 너무너무 하기 싫었다..
그래서 내용이 어려웠던 것은 아니었지만.. 계속 미루고 미루고 미뤘다..
내일은 남은 2개 강의 빨리 듣고 과제 시작해야겠다.