<인프런 워밍업 스터디 클럽 0기> - BE 발자국 1주차

<인프런 워밍업 스터디 클럽 0기> - BE 발자국 1주차

사실 강의 수강은 워밍업 클럽이 열리기 전부터 듣고 있었어요. 이미 JPA로 전환하는 부분까지 다 넘어갔었습니다. 사실 이것때문에 30% 할인 쿠폰을 미리 받지 못한 것에 대해서는 조금 아쉽긴 했습니다 ㅋㅋㅋ. 강의를 수강하게 된 이유는 저는 국비교육을 수료한 이후로 다른 정량적 스펙이나 코딩테스트, 자기소개서에 시간을 너무 많이 쓰게 되었고 중간에 인턴이나 현재 재직중인 직장에서는 스프링 부트나 스프링 5이상 버전, JDK 11~21 버전을 사용하지 않는 환경에 있었어요. 그래서 최근 개발 트렌드나 버전에 따른 변화에 뒤쳐지지 않기 위해 강의를 수강하기 시작했습니다.

 

1주차 동안은 주로 강의를 다시 듣는 것은 아니었고 이미 들었던 강의, 강의를 들으면서 작성했던 코드들을 다시 한번 보게 되었어요. 이 과정에서 JPA를 주로 사용하는 바람에 JdbcTemplate을 잘 사용해본 적이 없어서 이에 다시 적응하는 시간이 되어서 좋았습니다. 그리고 정말 레이어드 아키텍처에 따른 모든 코드들을 오랜만에 작성하면서 예전에 국비 교육때 열심히 했던 시간들을 다시 한번 되새길 수 있었고, 취업 준비를 하면서 많이 꺾였던 마음을 다시 세울 이유와 동기를 얻는 과정이어서 좋았습니다. 아쉬웠던 점은 시간이 그렇게 많지 않아, 과제 수행 중에 발견한 문제점이나 궁금했던 점에 대해 따로 깊이 파볼 시간이 조금 부족했던 것이 있습니다. 아무래도 2월부터 회사에 다니게 되었고 이 루틴이 익숙치 않아 오는 문제점인것 같은데 어떻게든 해결책을 마련해서 극복해야겠습니다.

 

워밍업 클럽을 진행하면서, 혹은 강의를 수강하면서 스스로에게 그나마 좋았다고 말해줄 수 있는 점은 질문을 적극적으로 하는 자세였습니다. 아마도 태현님 강의에서 질문을 제일 많이 한 것 같아요. 그리고 그 질문들중 좋은 질문이라고 반응해주셔서 행복했고, 태현님이 제 질문에 답변을 주신 것을 다른 분들의 질문에 대한 답변으로 대신하시는 것을 보고 '내가 의미있는 질문을 했구나'하는 생각을 했습니다. 세상에 멍청한 질문은 없다지만, 그 질문들 가운데서도 핵심을 짚는, 가치가 높은 질문들은 있다고 생각을 하는데 그런 질문을 하는 사람이 되어간다는 느낌을 받았습니다. 앞으로도 그런 질문을 계속 던질 수 있는 개발자가 되어야겠다고 다짐했던 좋은 경험이었습니다.

 

미션 수행과 관련해서...

미션 수행은 저 말고도 다른 분들도 크게 어렵지 않게 해결하셨을거 같아요. 다만 저의 경우엔 몇 가지 아쉬운점이 있었어요. 어노테이션 관련해서 딥다이브를 하는 과정에서 과연 '딥'하게 들어갔는지에 대해는 의문이었어요. 다른 분들은 어노테이션이 '마법'을 일으키는 과정을 따라들어가보면 '리플렉션'이라는 개념이 등장하는데 제가 이 리플렉션 코드를 직접 짜보거나 하지는 않았거든요. 반성해야할 지점이었습니다. 단순히 개념적인 것, 글만 읽고 끝내는 공부를 또 반복하게 된듯한 느낌이었거든요.

 

나머지 미션들이 크게.. 특별히 어려웠던 점은 없었는데 코치님께서 남겨주신 4일차 과제 피드백을 듣고 다음에 비슷한 동작을 수행하는 코드를 작성할 때 더 좋은 코드를 작성할 수 있는 법을 배웠어요. 코치님이 남기신 피드백 내용은 다음과 같습니다.

image

제가 이 피드백에서 교훈을 얻은 이유는 코치님이 언급하신, 데이터베이스에서 데이터를 전달해주고, 서버에서 연산 작업을 처리하게 되어 네트워크 대역폭 증가와 서버 자원 사용량의 증가라는 효과를 불러일으키는 방식으로 코드를 작성했기 때문이에요.

 

그렇다면 왜 그런 코드를 작성했을까요?

사실 그냥 이 과제가 SQL 문제로 주어졌다면, 저는 아무런 고민없이 데이터베이스에서 바로 연산을 하는 SQL문을 바로 짤 수 있었을 거에요. 하지만 서버 애플리케이션 프로그래밍을 배우면서 이런 얘기를 들었어요.

'데이터베이스에서 비즈니스 로직을 처리하게 되면 DB 종속적으로 프로그래밍을 하게 되어 서버 애플리케이션의 존재 의미가 흐릿해진다.'

실제로도 현재 근무하고 있는 회사에서는 비즈니스 로직이 오라클 데이터베이스의 프로시져에 몽땅 때려박혀있는 구조이고 저는 이것을 지금 개선하고 있기 때문에 DB라는 것에서 어떤 처리를 최소한으로 하려고 하는 습관이 생겼어요. 그리고 여기에 더해 강의를 통해 자바 스트림을 적극적으로 사용하는 것을 보고, 스트림 처리를 적극적으로 사용하는 것이 간결하고 명확하며 멋져보여서 이를 적극적으로 사용하는 것이 머리 속을 지배했습니다.

하지만 저는 과제의 요구사항이 '통계성 데이터를 반환하는 것'이라는 것을 잊고 있었고 이에 따른 트레이드 오프를 고민하는 자세를 갖지 못하고 바로 서버에서 스트림으로 연산을 처리해야겠다는 사고에 지배를 당해 아래와 같이 코드를 작성했습니다.

@Transactional(readOnly = true)
public List<Long> fruitStat(String name) {
fruitRepository.findFruitsByName(name);
	List<Fruit> findFruits = fruitRepository.findFruitsByName(name);

	if (findFruits.size() == 0) {
		throw new IllegalArgumentException("해당 이름을 갖고 있는 과일이 없습니다.");
	}

	Long salesAmount = findFruits.stream().filter(Fruit::getSold).mapToLong(Fruit::getPrice).sum();
	Long notSalesAmount = findFruits.stream().filter(fruit -> !fruit.getSold()).mapToLong(Fruit::getPrice).sum();

	return List.of(salesAmount, notSalesAmount);
}

 

이름 하나를 넘겨받고 그 이름과 동일한 이름을 가진 과일을 모두 가져오고, 팔린 물건과 그렇지 않은 물건을 따로따로 계산해주고 있습니다. 하지만 저 코드는 Fruit 테이블에 엄청나게 많은 데이터가 있었다면, 합을 구하는데 오랜 시간이 걸릴 수 있음이 분명했습니다. 통계성 데이터 처리는 그냥 한꺼번에 디비에서 해서 넘겨주는 것이 더 컴퓨팅 자원을 덜 소모할 수 있는 방법이라는 것을 분명 공부했지만 하나의 문제를 해결할 수 있는 방법을 여러개 놓고 그 중에 고른다기보다 저는 기존에 배웠던 것을 새로 배운 것으로 덮어쓰기 해버리는 바람에 트레이드 오프를 고려하는 습관을 유지하지 못한 부끄러움이 있었습니다.

 

그래서 우선 오늘은 자고 내일 개선해보자라고 생각했으나 마침 6일차 과제에 JPA가 아닌 JdbcTemplate을 사용할 것을 가정하고 나온 과제 내용을 다시 보고 개선할 수 있는 기회를 얻었습니다. 그래서 작성한 코드는 아래와 같습니다.

image

동일한 작업을 모두 SQL로 작성하고 이를 DB에서 처리하게 했습니다. 이렇게 하고 단순히 응답을 맵으로 감싸서 넘기는 방식을 취하고 있죠. 만약 통계 결과를 얻기 위한 데이터가 엄청 많다면 이러한 방식이 더 효율적일 것 같습니다. 다음엔 좀 더 많은 임의의 데이터를 넣고 코드를 시험해봐야겠습니다.

 

감사합니다.

댓글을 작성해보세요.