면접 후 답변 못한 것들 정리

Taeseon Kim·2023년 4월 13일
0

으으... 너무 부끄럽고 죄송했다.
물론 어제 연락을 받게 되어 급히 진행한 면접이긴 했지만, 너무너무 준비가 되지 않았고, 면접관님들의 시간을 괜히 뺏은 것은 아닌가 싶을 정도로 죄송한 마음이 앞선다.

오늘 면접은 내 스스로에게 화가 났다.
면접관님들은 너무 감사하게도 젠틀하셨고, 고민을 하거나 생각을 할 때에는 시간도 주셨다. 어디까지나 내 스스로에게 화가 났다.
개발을 해오면서 공부를 나름 해오고 있다고 생각했는데, 부정당하는 느낌? 그냥 공부를 깊이 안했구나 라는 생각이 들었다.
공부하지 않는 개발자가 되기 싫었는데, 스스로가 그런 개발자가 된 것 같아 보여 참 내 자신에게 미안하다.

그래서 면접관님들께서 하는 질문들을 하나하나 머릿속에 넣으면서 다시는 이런 경험을 하지 않을 만큼, 언제든 대답할 수 있도록, 정리해야겠다고 생각했다.

오늘 면접 질문과 이에 대한 정리다. 자바의 특징은 뭔가요? 와 같은 질문은 이제 오지 않는다. 더 깊이 공부해야 더 크게 성장한다.

tcp(소켓통신)가 http에 비해 나은 점은 무엇인가?

4계층 관점에서 보면 두 가지 모두 연결 지향적 통신이지만, 7계층 관점에서 본다면 http는 stateless, 소켓통신은 세션을 유지하기 때문에 연결 지향적인 통신이다.
따라서 연결 지향적이고 동기적 통신(실시간 통신)이 필요할 떄에는 tcp를 통한 소켓 통신이 낫다.

osi L3와 L4의 장비에 대해 설명할 수 있는가?

l3은 네트워크 계층으로, ip계층이다. 데이터를 전송하기 위해 경로를 선택(라우팅)하고, ip 주소를 정해 경로에 따라 패킷을 전달하는 것이 주된 역할이다.(결국 라우터의 역할을 한다.)
l4 장비는 로드밸런서이다. 트래픽을 분배해주는 역할(port)을 하는데, 사용자들이 갑자기 몰릴 때, 트래픽을 각 서버로 분배하는 기능을 한다.

가비지 컬렉션의 원리

할당 된 메모리 중 사용하지 않는 영역을 탐지해 해제하는 기능이다.
gc 실행은 다음 과정을 공통적으로 따른다.
1. stw(stop the world) : gc를 실행하기 위해 모든 어플리케이션 쓰레드를 중지하는 작업. gc를 위한 쓰레드만 작동한다.
2. mark & sweep : mark - 사용 객체와 사용하지 않는 객체를 식별하는 작업, sweep - mark 단계에서 사용하지 않는 객체로 식별된 객체를 제거하는 작업이다.

가비지 컬렉션이 stop the world현상이 일어 나는 이유와 대처방안

이유 - 가비지 컬렉터를 실행하기 위해 jvm이 application 실행을 멈추는 것이다.
배경 - 만약 가비지 컬렉터 가동이 0.1 -0.3초 단위로 짧은 시간이라면 상관 없지만, 1초를 넘어가는 순간부터는 튜닝이 필요하다. 보통 minor gc는 0.5초를 넘지 않고, full gc가 오래 걸리게 되는데, 멈추는 동안 client의 요청이 큐에 쌓이게 되며, gc가 끝난 후 한꺼번에 처리하게 되면 과부하가 발생할 수있다. 따라서 튜닝은 full gc를 관리하는 방법이 중요하다고 볼 수 있다.

대처 방안 - stw현상을 아예 없앨 수는 없다. 하지만 어플리케이션 특성과 환경에 따라 gc 관련 vm옵션을 조정함으로써 stw현상으로 인한 문제를 최소화할 수 있다.
만약 stw로 인해 서버가 멈추는 현상이 발생한다면, gc 과정 이후 요청이 쌓여 이를 한꺼번에 수행하다보니 문제가 발생했을 수 있다. 이 경우 stw 수행 시간을 줄이거나, 로드밸런싱을 통해 부하를 분산하는 방향으로 진행한다.

*GC
1. 대부분 객체는 오래 살아 있지 않는다.
2. 오래된 객체에서 새로운 객체로의 참조는 아주 적게 존재한다.
두 가지 조건 하에 GC를 효율적으로 동작하기 위해 vm은 메모리를 크게 두개의 물리적 공간으로 나누었다.
이를 오래된 걕체와 새로운 객체를 나누는 old/young 영역이다. 이를 generational gc라고 한다.
자바의 메모리 영역은 크게 위 두개(old/young)와 perm영역으로 나뉜다.
young - 생성된지 얼마 안된 객체들이 저장되는 장소, 대부분이 이 영역에서 생성되었다가 minor gc를 통해 사용되지 않으면 제거된다.
old - 생성된지 오래된 객체들이 저장되는 장소, young 영역에서 살아남은 객체가 이곳으로 옮겨지고 full gc를 통해 사용되지 않으면 제거된다.
metaspace(perm) - 프로그램 코드가 올라가는 장소, 코드가 모두 로딩되면 거의 일정한 수치를 유지한다. old영역에서 살아남았다고 해서 여기에 영원히 남아 있는 곳은 아니다. 여기서 gc가 발생하면 major gc에 포함되게 된다.

*gc 종류
minor gc - young 영역의 생명주기가 다한 객체를 비우는 작업이다. young 영역은 eden, survivor 1, survivor2로 나뉜다. minor gc는 이 중 eden이 꽉 차게 될 경우 트리거된다. 따라서 할당 비율이 높을 수록 minor gc가 더 자주 실행된다.
eden - 객체가 생성되자마자 저장되는 곳
survivor - 한번 이상 minor gc를 경험한 살아있는 객체가 저장되는 곳
minor gc가 발생하면 eden과 survivor1에 살아 있는 객체를 survivor2로 복사하고, eden과 survivor1을 비운다.
다음 minor gc가 발생하면 eden과 survivor2에 살아 있는 객체를 survivor1로 복사하고, eden과 survivor2를 비운다.
(survivor1,2 중 하나는 무조건 비어있는 상태여야 한다. 두 영역 모두에 데이터가 존재하거나, 사용량이 0이라면 정상적인 상황이 아니다.)
이와 같이 옮겨가며 minor gc를 돌리다가, MaxTenuringThreshold 값 이상 살아 남은 객체를 old영역으로 보내게 된다. 비교적 빠르다.(느려봤자 0.5초 내외)
major gc - old 영역의 생명주기가 다한 객체를 비우는 작업이다. minor gc가 실패할 경우 트리거된다. 비교적 느리다.
full gc - 힙 메모리 전체 영역의 생명주기가 다한 객체를 비우는 작업이다. minor gc나 major gc가 실패할 경우 트리거된다. 가장 느리다.

*튜닝을 위한 vm option 파라미터
1. Xms, Xmx - 최소 최대 힙사이즈, 이 둘을 같게 두면 일정 힙사이즈를 유지하여 메모리 누수, 부족에 의한 불필요한 로드를 피할 수 있다. 다르게 하는 경우는 시간대별로 메모리 사용량이 급격히 변화하는 경우가 있는 어플리케이션에 적합하다.
2. XX:MaxPermSize - 자바 클래스가 로딩되는 영역으로 어플리케이션 시작 시 out of memory 에러가 발생할 경우 이 옵션을 의심할 수 있다.
3. XX:NewRatio - young - old 간 비율을 잡는 옵션이다. 만약 -XX:NewRatio=3 이라면 young 1 : old 3의 비율로 힙 메모리를 구성하게 된다.
4. XX:SurvivorRatio - survivor - eden 간 비율을 잡는 옵션이다. 만약 -XX:SurvivorRatio=4라면 survivor(1, 2 모두 합한 사이즈) 1 : eden 4 의 비율로 young generation을 구성하게 된다.
5. -server / -client -
-server의 경우 서버에 적합하다. 부팅 시간은 길어도 되지만 요청에 대한 응답 시간이 빠른 것이 중요하다. 요청에 대한 응답이 끝나거나 세 션이 끊기면 특정 사용자에 관한 객체는 모두 사라지기 때문에 메모리에서도 새로운 객체가 많이 발생한다. 따라서 -client 옵션에 비해 old 가 작고 young이 크다.
-client의 경우 클라이언트에 적합하다. 부팅 시간이 길어야하고, 상태를 저장하고 있는 경우가 많기 때문에 상대적으로 객체가 오래 살아 남 는다. 따라서 -server옵션에 비해 old가 크고 young이 작다.
6. gc 알고리즘 선택

*gc 튜닝 절차
1. application의 종류 및 튜닝 목표값 설계 : 메모리를 적게 쓰는 것이 목표인지, gc 횟수를 줄이는 것이 목표인지, gc 소요 시간이 목표인지, application 성능 향상이 먼저인지를 먼저 정의하고, 해당 목표치에 근접할 수 있게 vm option을 조정하는 것이 필요하다.
2. heap & metaspace size 결정
3. 테스트 & 로그 분석 : 변경한 vm option이 제대로 작동하는지 로그를 분석한다. 2-3을 반복하며 원하는 목표치에 근접한다.

*gc 분석
튜닝 절차 1에서 정한 목표 값을 참고해야 한다. 예를 들어 full gc가 너무 길어 수행시간을 줄이고자 old영역을 줄인다면, full gc의 횟수는 오히려 늘어나는 효과가 나타난다. 반대의 경우도 마찬가지다.
서버 어플리케이션에서는 보통 로드밸런싱을 통해 서버 부하를 분산시킨다. 그리고 old영역을 작게 하여 full gc 수행시간을 줄인다. 하나의 서버가 full gc에 의해 멈추더라도 로드밸런서가 부하를 분산시키기 때문에 영향을 최소화할 수 있다.
gc 튜닝은 어플리케이션의 성격, 구조, client들의 패턴에 의해 크게 좌우된다. 따라서 얼마만큼의 파라미터를 설정해야하는지보다, 테스트와 로그를 통해 어플리케이션에 맞는 튜닝을 진행하는 것이 중요하다.

profile
공부하여 이해가 된 것만 정리합니다.

0개의 댓글