이번 스프린트는 키보드 스프린트다. 7개의 에픽을 진행했다.
순번 | 구분 | 에픽 | 시작 스프린트 | 에픽 완료 여부 |
1 | 웹사이트 | 1일 ?개 알고리즘 문제 풀기 | 1회차 | |
2 | 스터디 | 백엔드 스터디 | 1회차 | |
3 | 책 | Real MySQL 8.0 1권 | 13회차 | |
4 | 인프런 | 스프링 배치 - Spring Boot 기반으로 개발하는 Spring Batch | 12회차 | |
5 | 프로젝트 | URL 단축 서비스 프로젝트 (four days) | 16회차 | |
6 | 인프런 | 제대로 파는 Git & GitHub - by 얄코 | 17회차 | O |
7 | 인프런 | 타입스크립트 입문 - 기초부터 실전까지 | 18회차 | O |
1. 1일 ?개 알고리즘 문제 풀기
총 7개 문제를 풀었다. 백준 문제만 풀었고 난이도는 실버 2~5 정도였다. 이번 스프린트에서는 특별히 기억에 남는 문제는 없다. 다만, 문제를 잘못 이해하고 초반에 삽질을 했던 문제들이 있었다. 집중해서 풀어야겠다.
2. 백엔드 스터디 & 3. Real MySQL 8.0 1권
Real MySQL 8.0 (1권) - YES24
『Real MySQL 8.0』은 『Real MySQL』을 정제해서 꼭 필요한 내용으로 압축하고, MySQL 8.0의 GTID와 InnoDB 클러스터 기능들과 소프트웨어 업계 트렌드를 반영한 GIS 및 전문 검색 등의 확장 기능들을 추가로
www.yes24.com
이번 스프린트에서는 9.4장부터 10.2장까지 학습했다. 스터디원들의 사정으로 백엔드 스터디 모임은 진행하지 않았고, 각자 학습을 했다.
이번에는 쿼리 힌트와 실행 계획에 대해 학습을 했다. 아래 목록은 공부하면서 정리한 내용이다.
- 인덱스를 잘 사용하지 못하거나 실행 계획에 대해 잘 모른다면 힌트로 옵티마이저의 실행 계획에 영향을 미치는 것은 자제하자.
- 통계 정보의 수집 설정은 STATS_AUTO_RECALC 옵션으로 조정할 수 있다.
- STATS_AUTO_RECALC=1 : MySQL 5.5 이전의 방식대로 자동 수집(테이블의 통계 정보가 메모리에만 저장되었다. MySQL 서버가 재시작되면 통계 정보가 초기화된다)
- STATS_AUTO_RECALC=0 : ANALYZE TABLE 명령을 실행할 때만 수집한다.
- STATS_AUTO_RECALC=DEFAULT : 테이블의 통계 정보 수집을 innodb_stats_auto_recalc 시스템 설정 변수의 값으로 결정한다.
- MySQL 서버는 쿼리를 실행할 때 전체 작업 비용을 계산한 결과를 바탕으로 실행 계획을 찾는다. 이러한 작업들의 비용을 코스트 모델이라고 한다. 코스트 모델에서 중요한 것은 각 단위 작업에 설정된 비용 값이 커지면 어떤 실행 계획들이 고비용 또는 저비용으로 바뀌는지를 파악하는 것이다.
- MySQL 8.0 버전부터는 EXPLAIN 명령에 FORMAT 옵션을 사용해 JSON이나 TREE, 단순 테이블 형태로 실행 계획을 확인할 수 있다.
- MySQL 8.0.18 버전부터는 실행 계획의 단계별 소요 시간 정보를 확인할 수 있는 EXPLAIN ANALYZE 기능이 추가되었다. 이 기능은 EXPLAIN 명령과 다르게 실행 계획만 추출하는 것이 아니다. 실제 쿼리를 실행하고 사용된 실행 계획과 소요 시간을 보여준다. 따라서 실행 시간이 긴 쿼리를 EXPLAIN ANALYZE 명령으로 실행하면 쿼리 실행이 종료되어야 결과를 확인할 수 있다.
4. 스프링 배치 - Spring Boot 기반으로 개발하는 Spring Batch
스프링 배치 - Spring Boot 기반으로 개발하는 Spring Batch - 인프런 | 강의
초급에서 중~고급에 이르기까지 스프링 배치의 기본 개념부터 API 사용법과 내부 아키텍처 구조를 심도있게 다룹니다. 그리고 스프링 배치 각 기능의 흐름과 원리를 학습하게 되고 이를 바탕으
www.inflearn.com
이번 스프린트에서는 섹션 8부터 섹션 10까지 들었다. 각각 ItemReader, ItemWriter, ItemProcessor에 대해서 학습했다.
저번 스프린트에서는 ItemReader, ItemWriter, ItemProcessor를 묶어서 강의하는 파트였는데, 이번 섹션들에서는 각각 조금 더 자세하게 강의를 하신다. FlatFile, XML, Json, Database에서 데이터를 읽고 처리하고 쓰는 과정에 대해서 배울 수 있다(Jpa의 경우 현재 사용하지 않고 있어서 강의를 생략 했다).
다음 섹션은 오류 제어(섹션 11)와 멀티 스레드(섹션 12)에 관한 내용인데, 이 파트는 생략하려고 한다. 세션 13부터 진행해서 애플리케이션 개발을 마친 후에 듣거나, 개인 프로젝트에서 간단한 배치 프로그램을 만들어보고 필요할 때 들을 생각이다(바뀔 수 있음).
위 강의가 워낙 강의 시간이 길어서 모든 강의 내용을 체득하는데 시간이 오래 걸리겠지만, 스프링 배치를 사용하면서 두고두고 복습을 해야 될 것 같다.
5. URL 단축 서비스 프로젝트 (four days)
GitHub - four-days/core-server
Contribute to four-days/core-server development by creating an account on GitHub.
github.com
이번 스프린트에서는 core server에 API 1개를 추가했다. 원본 URL 조회 API다.
원본 URL 조회 API 개발
원본 URL 조회 API 개발 by 0xe82de · Pull Request #20 · four-days/core-server
github.com
API의 로직은 간단하다. key를 받아서 그에 해당하는 URL을 반환하면 된다. 그런데 테스트 코드를 작성하면서 작은 문제가 있었다.
아래는 문제가 되었던 코드다. 현재 데이터베이스를 연동하지 않고 인메모리 데이터베이스를 구현해서 개발을 하고 있는데, 아래의 Map<String, URL> 타입의 store 객체가 URL 객체를 보관한다. findByUrlKey 메서드는 urlKey를 받아서 원본 URL 객체를 반환한다.
@Repository
public class UrlRepositoryMemory implements UrlRepository {
private static final Map<String, URL> store = new HashMap<>();
// ...
@Override
public Optional<URL> findByUrlKey(String urlKey) {
return Optional.ofNullable(store.get(urlKey));
}
}
아래는 원본 URL 조회 API를 개발하면서 새롭게 추가한 테스트 코드다. 데이터가 존재하는 경우와 존재하지 않는 경우를 나누어서 테스트했다. 두 테스트 모두 UrlRepositoryMemory 객체를 생성해서 사용한다. 테스트를 실행하면 두 번째 테스트인 findOriginalUrlByUrlKeyTest_notExists() 테스트는 실패한다.
@Test
@DisplayName("findOriginalUrlByUrlKey > exists")
void findOriginalUrlByUrlKeyTest_exists() {
UrlRepositoryMemory urlRepository = new UrlRepositoryMemory();
urlRepository.save(new URL("urlKey", "https://four.days/"));
UrlServiceImpl urlService = new UrlServiceImpl(urlRepository, new Base62EncoderUsingNanoTime());
String originalUrl = urlService.findOriginalUrlByUrlKey("urlKey");
assertThat(originalUrl).isEqualTo("https://four.days/");
}
@Test
@DisplayName("findOriginalUrlByUrlKey > not exists")
void findOriginalUrlByUrlKeyTest_notExists() {
UrlRepositoryMemory urlRepository = new UrlRepositoryMemory();
UrlServiceImpl urlService = new UrlServiceImpl(urlRepository, new Base62EncoderUsingNanoTime());
String originalUrl = urlService.findOriginalUrlByUrlKey("urlKey");
assertThat(originalUrl).isNull();
}
위 테스트가 실패하는 이유는 UrlRepositoryMemory 객체의 store 객체가 static 하기 때문이다. static 필드는 클래스 정보가 JVM에 로드될 때 초기화되는데, 이때 store 객체가 생성된다. 그 후에 객체가 생성되어도 store 객체는 새롭게 생성되지 않는다. 따라서 위 2개의 테스트 코드에서 각각 UrlRepositoryMemory 객체를 생성했지만, 첫 번째 테스트의 데이터가 store 객체에 남아 있었고, 그로 인해 두 번째 테스트가 실패하게 되는 것이다.
아래는 위 문제를 해결하기 위해 고친 코드다. UrlRepositoryMemory의 store 객체를 static이 아닌 인스턴스 변수로 바꿨고, UrlRepositoryMemory 객체가 생성될 때마다 store 객체도 새롭게 생성된다.
@Repository
public class UrlRepositoryMemory implements UrlRepository {
private final Map<String, URL> store;
public UrlRepositoryMemory() {
this.store = new HashMap<>();
}
// ...
@Override
public Optional<URL> findByUrlKey(String urlKey) {
return Optional.ofNullable(store.get(urlKey));
}
}
스프링 애플리케이션을 실행하면 UrlRepositoryMemory는 bean으로 등록되므로 store 객체도 하나라고 생각했다(싱글톤 bean 일 경우에). 그래서 static 하게 만들었는데, 테스트 코드를 작성하면서 테스트 시에는 static 필드가 문제가 될 수 있음을 알게 되었다.
처음 구상한 core server의 기능은 모두 만들었다. 이제 간단하게 화면을 만들어야 하는데, 앵귤러로 정말 간단한 웹 화면을 만들려고 한다. 원래 크롬이나 웨일의 확장 프로그램부터 만들려고 했는데, 난이도를 낮춰서 웹으로 먼저 만들어보려고 한다.
6. 제대로 파는 Git & GitHub - by 얄코
제대로 파는 Git & GitHub - by 얄코 - 인프런 | 강의
코알못도 따라올 수 있는 친절하고 쉬운 강좌! 현업 개발자는 Git 박사로 들어주는 끝판왕 강좌!, - 강의 소개 | 인프런
www.inflearn.com
이번 스프린트에서 강의를 완강했다. 섹션 5부터 끝까지 강의를 들었고 commit과 branch, github에 대해 조금 더 자세하게 학습을 할 수 있었다. 개인적으로는 git stash 기능을 알게 된 것이 큰 수확인 것 같다. 잘 써먹어야겠다.
강사님의 강의 실력도 좋은 것 같고 구성도 알찬 것 같아서 git 입문 강의로 추천한다.
7. 타입스크립트 입문 - 기초부터 실전까지
타입스크립트 입문 - 기초부터 실전까지 - 인프런 | 강의
타입스크립트를 시작하는 분들을 위한 강의입니다. 최신 자바스크립트 문법을 모르는 분들도 쉽게 배울 수 있도록 교과 과정을 구성하였습니다. 어렵게만 느껴지는 타입스크립트를 입문자 관
www.inflearn.com
이번 스프린트에서 위 강의를 완강했다(약 6시간 분량의 강의인데.. 내용이 크게 어렵지 않아서 빠르게 들을 수 있었다). 얼마 전부터 회사에서 앵귤러로 만들어진 시스템을 담당하는 팀원들과 앵귤러를 같이 학습하기로 했는데, 앵귤러의 기반이 되는 타입스크립트를 공부할 목적으로 위 강의를 수강했다.
그동안 자바스크립트는 간간이 사용해왔다. vue, react로 화면을 만들거나 express.js로 서버를 구성할 때 사용했다. 사용하면서 조금 불편했던 것은 자바와 다르게 타입이 없다는 것이었는데, 이번 기회에 자바스크립트에 타입 시스템을 적용한 타입스크립트를 학습하고 사용해 보면서 편리하다고 느꼈다. 진작 배워둘 걸 그랬다.
앞으로 앵귤러를 많이 다루게 될 텐데, 타입스크립트를 잘 활용해 봐야겠다.
타입스크립트 강의는 위 강의가 처음인데, 실습 위주의 강의여서 좋았다. 개인적으로는 실습을 많이 할 수 있는 강의를 좋아하는데, 위 강의가 그랬다. 실습을 좋아한다면 위 강의를 추천한다.
'후기 & 회고' 카테고리의 다른 글
1주 1스프린트 20회차 회고 (0) | 2023.04.23 |
---|---|
1주 1스프린트 19회차 회고 (0) | 2023.04.15 |
1주 1스프린트 17회차 회고 (0) | 2023.04.01 |
1주 1스프린트 16회차 회고 (0) | 2023.03.25 |
1주 1스프린트 15회차 회고 (0) | 2023.03.18 |
댓글