에프랩(F-Lab) Java Backend 2개월 후기

수정일 2024-10-21, 작성일 2024-10-16

F-Lab을 신청하게 된 계기

이때까지를 되돌아보면 공부도 열심히하고 회사에 기여하기 위해 바쁘게 지낸 것 같은데, 스스로를 어필할 수 있는 필살기가 없다고 느꼈다.
내가 가진 지식을 그래프(자료구조)에 비유하자면 기존의 그래프에 새로운 노드들을 견고하게 연결하는 학습 패턴을 가져야 하는데, 기존 학습 그래프랑 연결되지 않고 겉핥기 식으로 동떨어진 새로운 그래프를 계속 만들어 내고 있었다.
(새로운 그래프를 만들더라도 그 그래프들을 연결할 수 있는 기회를 잡거나 노력을 해야 했는데 못한 것 같다.)
그렇게 흥미가 있거나 실무에서 사용되지 않는 새로운 분야를 학습하더라도 금방 잊어먹는 아주 비효율적인 학습을 계속했다.

어떤 것을 학습해서 어떤 부분을 개선할 수 있는지 또는 이 부분을 개선하기 위해 어떤 학습,분석,모니터링 등이 필요한지를 혼자서는 아는 만큼 밖에 보이지 않기 때문에 이런 학습이 계속 되지 않았나 싶다.
내가 관심 가지는 도메인에 경험이 많고 학습 방향이나 깊이에 대해 조언을 받을 수 있는 기회를 만들고 싶어 F-Lab을 신청하게 되었다.

첫 번째 달의 과정

  1. 이력서와 경력 기술서 피드백
  2. JVM에서 코드가 실행되기까지 조사하기
    • 바이트 코드를 만들어내는 과정
    • 자바에서 다이나믹 프록시를 사용할 수 있는 이유 (바이너리 바이트 스트림)
    • 바이트 코드의 상수 풀과 런타임 상수 풀의 차이점
    • JVM 런타임 데이터 영역
    • 클래스 로딩 메커니즘
    • 초기화 단계 <clinit>()의 블로킹 가능성
    • 객체 생성에 대한 메모리 동시성 문제
    • 객체의 메모리 레이아웃
  3. 가비지 컬렉션
    • GC 대상에 메서드 영역이 포함되어야 하는가?
    • 대상이 죽었는가? 참조 카운팅 알고리즘, 도당 가능성 분석 알고리즘
    • 세대 단위 컬렉션 이론에 기반한 마크-스윕,마크-카피,마크-컴팩트 알고리즘
    • GC 루트 노드 열거, 안전 지점, 안전 지역
    • STW를 줄이기 위한 기법들 (삼색 표시 기법, 증분 업데이트, 시작 단계 스냅숏, 쓰기 장벽을 통한 기억 집합과 카드 테이블)
    • 클래식 가비지 컬렉터 (신세대 : 시리얼,파뉴,패러렐 스캐빈지, 구세대: 시리얼 올드, CMS, 패러렐 올드)와 G1
    • 최신 가비지 컬렉터 (셰넌도어, ZGC)
  4. 자바 메모리 모델과 스레드
    • 작업 메모리와 메인 메모리간 상호 작용
    • volatile의 원리와 동시성이 지켜지지 않는 케이스
    • 자바 메모리 모델의 원자성, 가시성, 실행 순서
    • 스레드 모델 (N:1, 1:1, N:M) 종류와 한계
    • 가상 스레드와 코루틴을 이해하기 위한 커널 스레드와 사용자 스레드
  5. HashMap 분석
    • tab[(n - 1) & (hash = hash(key)) 또는 newTab[e.hash & (newCap - 1)] 의 모듈러 연산에 대한 이해
    • resize시 사이즈가 2배씩 증가하는 이유 (사이즈가 2의 제곱수인 이유)
    • Node<K,V> loHead = null, loTail = null, hiHead = null, hiTail = null; 네 개의 임시 노드가 존재하는 이유
    • resize 진행시 if ((e.hash & oldCap) == 0) 코드의 의미
  6. 포트폴리오 시나리오 작성

느낀 점

아무리 뛰어난 개발자가 멘토라고 하더라도 학습하고 이해하고 응용할 수 있는 능력은 전적으로 나에게 달려있다.
하지만 학습의 방향성과 깊이에 대한 조언을 받을 수 있다는 것은 학습자 입장에서는 굉장히 중요한 요소라고 느꼈다.
예를 들어, GC가 시작될 때 사용자 스레드를 STW 하지 말고 커널 스레드를 GC 스레드에 모두 매핑하는 것은 왜 안될까요? 라는 질문을 통해 스스로 학습할 수 있도록 도와주신다.

whystw

위와 같이 한 개의 질문에서 여러 개의 질문으로 스스로 확장하며, 질문들을 해결해나가고 다시 질문들을 확장해나가는 과정을 통해 능동적이게 학습할 수 있는 기회를 주었다.
어떤 주제에 대한 스터디나 강의, 책을 통한 학습은 한 개의 태스크를 동기로 진행한다고 비유한다면, 능동적인 학습은 여러 개의 주제에 대한 태스크를 비동기로 진행하는 것과 같다고 느꼈다.
강의나 책을 완강,완독하는 목표가 아니라 근본적인 질문을 이해하기 위해 어떤 것을 학습해야 할지 스스로 판단하고 실행하는 것이 더 좋은 학습인 것 같다.

그리고 멘토님의 경험에 대한 이야기 덕분에 학습에 살이 더 붙어 이해가 더 잘 되었다. 여러 회사들의 내부 이야기를 간접적으로 들어볼 수 있고, 기술의 히스토리나 키워드들을 던져주시는 것도 좋았다.

목표

멘토링 과정은 단방향 교육이 아닌 멘토와 멘티, 사람 간 서로 교류하는 방식이기 때문에 나만 이 멘토링 시간이 즐겁기보다는 멘토님도 이 멘토링 시간이 즐겁도록 내가 더 적극적으로 문제를 해결하고 좋은 질문들을 하는 것이 이 과정의 끝까지 노력할 목표이다.
첫 달 이론을 학습하는 과정에서는 모르는 것이 너무 많아 개인적으로 학습하고 질문을 준비하는 시간이 필요했기에 멘토님을 재밌게 했다고 자신할 수 없지만, 이제 포트폴리오를 시작하면 더 많고 좋은 질문을 할 수 있지 않을까 기대하고 있다.

두 번째 달의 과정

이론 학습 기간이 끝나고 토이 프로젝트를 시작하는 단계가 진행되면서 실무에서는 생각하지 못 했던 부분들을 고민하게 되었다.
gradle로 멀티 모듈을 구성하는 방법부터 모듈간 의존성은 어떻게 관리할지, 소프트웨어 아키텍처의 여러 가지 방법에 대한 장,단점을 이해하고 최선의 선택은 무엇일지 처음으로 고민해보게 된 것 같다.

  1. gradle 멀티 모듈 구성 방법과 기준
  2. 레이어드 아키텍처와 헥사고날 아키텍처의 장,단점
  3. 파사드나 애그리게이트가 서로 다른 문제를 해결하는 것인가?
    • 누군가는 비즈니스의 복잡도를 안고 중개하는 역할을 해야 한다. 그런 관점에서 보면 파사드와 애그리게이트는 서로 같은 문제를 해결하는 것이다.
    • 복잡도를 누구에게 전가하여 중개를 어느 계층에서 어떤 방법으로 복잡도를 관리할지 스스로 어떤 규칙을 정하고 지키는 것이 핵심 아닐까
  4. rest docs 적용

느낀점

실무에서 레이어간 의존성에 대한 고민만 해왔지 멀티 모듈을 사용한 의존성에 대한 고려는 엄청 새로웠다. MSA를 대비한 도메인간 멀티모듈을 적용하는 것과 모놀리식 환경에서 레이어간 멀티모듈을 적용하여 각 모듈이 의존하는 의존성을 완전히 분리하여 서로 침범할 수 없도록 강제하는 것들을 배울 수 있었다.

소프트웨어 아키텍처와 비즈니스 로직 복잡도에 대한 내용들은 구조(또는 방법)을 선택하였을 때 얻는 것과 잃는 것은 무엇인가? 당위성을 설명할 수 있는가?를 생각하게 되는 주제들이였다.
내가 해결해야 할 문제가 무엇인지 이해하지 못하고 특정 기술적인 단어에 집착하여 단편적인 문제 해결 방법들만 고려했던 것은 아닐까?

문제를 해결하기 위한 정형화된 방법을 찾는것이 아니라 현재 환경에서 맞닥뜨린 문제를 이해하고 발전시킬 부분과 포기할 부분을 신중히 선택해야한다.
이번 학습을 통해 토이 프로젝트에 대해 어떤 아키텍처를 사용하게 되었는지 소프트웨어 아키텍처에 대한 고민도 작성하게 되었다.

회사를 구해서 2개월만 진행했다.


정현준

Loading script...