우아한형제들, 인프랩, 넥스트스탭에서 주최한 유스콘 2021 웨비나를 듣고 왔다.
마침 어떻게 공부할지 고민이 많기도 했고, 웨비나 들은 경험이 많이 없기도 했으며, 스프링과 java 웨비나라서 한 번 들어보는 것도 좋겠다 싶어서 참여하였다.
https://frost-witch-afb.notion.site/YOUTHCON-21-365e94c3df3443e5b1322520a8b1a2ef
다 듣지는 않았고 일부 참여하였는데
간단하게 요약 및 느낀점을 포스팅하겠다.
축사
컨퍼런스를 자주 보다 보면, 발표하는 사람들은 원래 했던 사람들만 하는 경향이 있다고 한다.
아마 첫걸음을 떼기가 어렵기 때문일 것이다.
'시작이 반이다'라는 말이 있듯이 무엇이든간에 처음 시작하는 순간만 어렵지, 그 이후론 관성이 붙어 계속 하는 것은 어렵지 않을 것이다.
좋은 기회라고 생각되면 무조건 시작해보자.
Java와 스프링에서 나의 멘토 찾기
발표대상: 학생, 취준생, 신입
Java의 Scanner를 살펴보자.
Scanner sc = new Scanner(System.in); 과 같이 사용하는 것을 알 수 있다.
Scanner는 문자든 숫자든 관계없이 편리하게 입력받을 수 있다.
JDK 1.5 이전에는 Scanner이 태어나기 전이므로 InputStream을 사용했었다.
InputStream은 상당히 불편한 입력방식을 가지고 있으며, 타입에 따라 다른 통합되지 않은 입력방법을 요구한다.
이를 개선하여 통합적인 입력방법, 편리한 방식으로 태어난 것이 Scanner인 것이다.
이와 비슷한 맥락으로 Spring에서의 ApplicationContext가 존재한다.
다양한 형태로 제공되는 빈 설정정보를 하나의 통합적인 접근 방식으로 접근 가능하게 한다.
실무 경험이 비교적 적은 신입 입장에선 다양한 요구 및 수정사항을 받아들여 코딩하기가 쉽지 않다.
이럴 때 한번, 기능맥락을 파악한 후에 이전과 비슷한 상황이 시뮬레이션된다면 그 상황을 벤치마킹해보는 것은 어떨까?
그리고 보다 통합적이고 편리한 방법으로 만들면 요구사항에 따른 수정이 줄어들어 보다 유지보수하기 편하지 않을까?
느낀점.
마치 백준에서 어떤 문제를 풀 때 이전에 비슷한 알고리즘이 요구되거나 상황이 비슷할 때 도움이 됐었던 때가 떠오르는 강연이었다. 확실히 그만큼 경험이 있으면 훨씬 부담감도 적고 설계도 잘 할 수 있게 되기 때문에 공감이 많이 됐다.
그리고 이번에 우테코 프리코스를 하면서 느낀 점이기도 하다.
MVC 패턴으로 객체지향을 최대한 지키면서 코드를 작성한 이유가 통합적이고 편리한 방법으로 만들어 유지보수를 편리하게 하기 위함이므로 아무래도 많이 공감할 수 있었던 것 같다.
SI에서 왕이었던 나, 알고보니 초보 개발자
발표대상: 취준생, 신입, 우물 안 개구리
SI회사, 게임회사, 이커머스(서비스)회사 등 다양한 회사를 많이 경험해보신 시니어 개발자님이 발표하신 강연이다.
특히 SI회사에서는 남의 코드를 만들어주는 것이다보니 test code, 코드 퀄리티보단 잘돌아가는 데에 집중한 코드를 만드는 것이 우선이었기 때문에 위와 같은 제목을 쓰셨던 걸로 기억한다.
1. IT 회사들의 차이점
- SI 회사: 코드 퀄리티나 테스트코드와 같은 유지보수보단, 돌아가는데에 우선
- 게임회사: 코드 퀄리티 좋음. 테스트코드 문화 괜찮음. 다만 배포일이 매월 말이라 중순부터 휴가를 사용하는게 불가능하고, 어떤 업무량을 상상하든 그 이상으로 굉장한 업무량을 자랑한다고 함.
- 이커머스 회사: 코드 퀄리티, 문화 괜찮음. 이커머스 경력을 요구하는 회사들이 꽤 있음. 대체로 워라벨 굳.
2. 코딩테스트 준비과정
- 유튜브 및 인프런 강의시청 -> 짬짬이 문제해결
- 인텔리제이에 미리 문제 수만큼 클래스 준비
3. 공부했던 방법
- 하루 10시간 정도 공부하셨고, 특히 책을 굉장히 강조하셨다.
- 추천도서: 모던 자바 인 액션, 이펙티브 자바, 자바 성능 튜닝 이야기, 클린코드, 클린 아키텍처, 토비의 스프링 등
4. 면접 준비 및 후기
- 깃 잔디 무지성 채우는 건 오히려 독. 퀄리티 있는 프로젝트 위주로.
- 비슷한 실력끼리 면접준비는 비추천. 실제 면접에서는 쉬운 주제로 시작한 후 점점 깊게 들어가는데, 비슷한 실력끼리 하면 서로 쉬운 질문만 하고 어려운 질문은 안하거나 인터넷에서 긁어와 심도있게 불가능.
- 면접을 볼 때 '난 초보다'라는 생각이 많이 들었다고 함.
- 좋은 회사는 면접 질문도 좋음.
- 스타트업 고려 시 CTO를 보고 회사 선택. 페이스북, 링크드인으로 확인해보자.
- 테스트 코드 작성, 코드리뷰 문화를 회사한테 질문해보자.
- 이력서의 정답은 아무도 모른다. 일단 지원부터 해보자.
- 커리어를 생각하는 것은 생각보다 중요하다.
- 연봉 높은 회사를 가고 싶지만 현실을 파악하자. ex. 실력이 부족한데 초봉 5000 이상만 찾는 행위 X
느낀점.
SI는 가지 말아야지... 근데 사실 이건 2020년에 si회사에서 알바할 때부터 느끼긴 했다.
짬짬이 백준해두길 정말 잘한듯. ps는 백해무익이라 생각했는데 무익까진 아니고 1익 정도는 하는 거 같다 ㅎㅎ
면접 꿀팁이 갠적으론 도움이 많이 됐다. 비슷한 실력끼리 면접 준비하면 서로 으쌰으쌰할 수 있어 좋을 것 같았는데 전혀 아니라는 것을 알게 됐다.
마지막으로, 요즘 책의 중요성을 간과하고 있는 나에게 다시 한 번 중요성을 일깨워준 강연이었다.
객체지향 설계와 JPA 연관관계 구현
발표대상: 객체지향 설계 이해하는 사람, JPA 이해한사람, JPA 적용원하는 사람
1. JPA 사용 이유
Java는 객체지향적 언어이다.
그리고 개발을 할 때 db는 빼놓을 수 없다.
그런데 OOP개발을 할 때, RDB를 사용하다보면 패러다임이 불일치해서 스트레스를 받을 때가 종종 있다.
OOP는 객체간의 참조를 이용하며, 직렬화를 통한 데이터 CRUD를 진행하는데 이 때 오버헤드가 발생할 수 있다.
RDB는 트랜잭션으로 대용량 데이터 처리에는 좋으나, OOP의 기능(ex. 다형성)은 사용이 불가능하다.
이러한 패러다임 불일치를 해소해주는 것이 JPA이다.
2. 객체지향 설계 및 @ManyToOne과 @OneToMany
객체에게 메시지를 보내기 위해선 객체 간 참조가 필요하다.
JPA에선 이를 위해 연관관계 매핑을 진행하는데, 책에서든 강연에서든 @ManyToOne을 강조한다.
@ManyToOne 단방향 매핑이 부가 쿼리가 없어 성능도 좋고, 연관관계 주인을 고려할 때 이해하기 편하기 때문이다.
만약 단방향 매핑으로 코드를 짜기 어려운 요구사항이 존재할 경우 양방향 매핑을 사용하자.
물론 이 때, 순환참조가 발생할 수 있고, 의존성이 높아 결합도가 증가한다는 단점도 같이 생겨난다.
그러나 만약 @ManyToOne을 이용할 때 요구사항을 지키긴 하지만 객체지향적이지 못한 문제나 이슈가 발생한다면?
@OneToMany 단방향 매핑 또한 고려해보자.
무지성으로 @OneToMany를 배제하는 것은 옳지 않다.
@OneToMany를 이용할 경우 편의메소드를 이용하지 않더라도 영속성 전이, 고아객체 관리를 통해 생명 주기 관리가 가능해지며, 경우에 따라 @ManyToOne보다 나은 객체지향적 설계가 가능할 수도 있다.
모든 설계는 트레이드오프의 산물, 정답은 없다. 무조건 @OneToMany를 무지성으로 배제하는 마인드는 버리자.
+) JPA에서 모든 개발자를 괴롭히는 N+1 문제는 fetch join을 고려하자.
느낀점.
나도 @ManyToOne을 주로 사용하고 @OneToMany는 무의식적으로 사용하지 않으려 했었던 경험이 있다.
그러나 소프트웨어는 공학이자 예술이라는 말이 있듯이 (feat. 객체지향의 사실과 오해) 소프트웨어에 은탄환은 없다.
충분히 이해하고 제대로 사용하자.
그리고 JPA를 요즘 사용하지 않았더니 뒷부분은 내용이 좀 어려워서 제대로 이해하지 못한 내용도 존재한다...
꾸준히 공부하도록 해야겠다.
Spring Boot TDD Start!
발표대상: 스프링 0~3년차 개발자, TDD를 들어본 사람
web test도구는 여러가지가 있다.
rest-assured, web client test (web-flux), mockMVC 등.
(와... 내가 아는거 진짜 하나도 없네...)
이 강의에서는 rest-assured를 이용한다.
@SpringBootTest를 붙인다는 것은 스프링이 제공하는 수많은 기능들을 모두 이용할 수 있다는 것을 의미하는데,
그만큼 속도가 저하되므로 주의해야 한다. @WebMvcTest보다 느리다.
그렇지만 모든 빈을 로드하기 때문에 실제와 가장 비슷한 환경으로 테스트해볼 수 있다.
따라서 Application을 test할 때는 @SpringBootTest를 붙인다고 한다.
@SpringBootTest를 붙일 때 WebEnvironment는 주로 RANDOM_PORT나 Mock을 이용한다.
RANDOM_PORT가 실제 서블릿 환경을 구성해주는 어노테이션이라 한다. 이를 사용할 경우 @LocalServerPort로 서버포트를 변수에 저장해준 후, @BeforeEach로 포트를 초기화해주자.
만약 실제 객체를 만들기에 어렵거나 의존성이 많이 요구될 경우 Mock을 이용하도록 하자.
@AutoConfigureMockMvc를 이용하면 필요 의존성을 자동으로 주입해주기 때문에 보다 편리한 테스트가 가능하다.
given(), when(), then() 메소드를 이용하여 준비, 실행, 검증으로 나누어 test code를 작성하자.
실행 단계에서 getMapping 매핑값을 get해주고, 검증 단계에서 assert 해주자.
모킹할 때 매직넘버는 상수화해주자.
Repository Test는 @DataJpaTest 어노테이션을 사용하는 것을 권장한다.
이 때 스프링 자원을 가져오지 않아 빨간줄이 뜬다면 JpaRepository와 같은 Spring jpa 기능을 사용해주자.
하향식(탑다운) 접근으로 tdd를 해보자.
만약 테스트코드가 실패한다면 상위 단인 ControllerTest에서 test code를 실행해보고, 문제가 없을 경우 하위 단인 Service Test에서 assertThat 또는 assertThatThrownBy로 테스트해보자.
일부러 실패하는 test code를 만들어보는 것도 좋기 때문에 assertThatThrownBy를 적극 이용하자.
물론 숙련자일 경우 탑다운 tdd, 바텀업 tdd 둘다 각각의 장단점이 있기 때문에 그때그때 다른 tdd 방법을 이용하면 된다고 한다.
TDD 장단점 정리가 잘 된 포스팅
https://velog.io/@modolee/tdd-overview
그리고 test code는 속도가 생명이라고 한다.
현업에서 TDD를 할 때, tdd 코드가 느리다면 사용하지 않아버리는 경우가 많다.
따라서 test code는 최대한 빠르게 돌아가도록 짜자.
느낀점.
그동안 아무생각 없이 test code를 짜왔던 나를 반성하게 됐다.
특히 Mock은 개인적으로 예전에 필요에 의해 한 번 짜놓고 귀찮다고, 그리고 너무 어렵다고 결국은 안해버린 케이스가 꽤 있기도 했다.. 일부러 repository만 테스트한다던지 등...
test code를 자주 짤 때 즉각적으로 로직 오류를 잡아내는 것은 확실히 큰 장점으로 느껴졌다.
tdd 방법에 대해 고민해보는 시간을 가져야겠다.
뒤로 갈수록 어려워져서 제대로 웨비나 내용을 흡수했는지는 의문이지만,
확실한건 많은 도움이 됐다.
공부 방향이나 행동양식을 올바르게 고치는데에 도움이 된 듯.
우테코 프리코스도 끝났고 어느정도 마음의 여유도 생겼으니
다시 한 번 책을 읽으면서 객체지향적 설계와 스프링에 대해 공부해보려 한다.
물론 리액트, 백준 공부도 틈틈이 하면서!
'JAVA > JAVA | Spring 학습기록' 카테고리의 다른 글
[TDD 리팩토링] @ParameterizedTest을 이용한 테스트 메소드에서의 여러 값 검증 (0) | 2022.02.11 |
---|---|
[ERROR] 스프링 어노테이션 인식이 안될 때 (2) | 2021.12.25 |
[JAVA] 스트림 filter을 anyMatch, allMatch로 바꿔보자 (0) | 2021.12.11 |
[JAVA] JDK 환경설정 / WARNING: An illegal reflective access operation has occurred 경고 해결 (7) | 2021.11.26 |
[Spring+React] 스프링과 리액트 연동해보기 (IntelliJ + Spring + Gradle + React) (2) | 2021.11.15 |