백엔드 경력 면접 질문 - baeg-endeu gyeonglyeog myeonjeob jilmun

해당 버전을 자세하게 물어본 이유는, 면접을 본 곳의 경우 과제가 주어졌는데 그 과제는 내가 얘기한 개발 환경으로 구성이 되있어야 한다고 했다. 추가로 과제에서 JPA 를 사용할 계획이 있는지, TDD 코드도 추가 할건지 ? H2 DB 를 사용할건지 ? 등등 물어보았다.

나의 경우 H2 DB + JPA + JUnit 적용시켜서 과제를 제출 했던 기억이 있다. (기한은 3일)

3. 배포 환경 및 구성

이전 회사에서는 배포 환경 구성이 어떻게 되어 있는지 물어보고, war 배포 인지 jar 파일 배포 인지 확인 하였다.

예시: dev / staging / prod 로 되어 있고, war 배포 하였다.

이후 타겟서버는 몇대 인지 확인 하였고, 소스 배포는 어떤 방식으로 했는지도 물어 보았다.

예시: 개발 환경과 스테이징은 각 1대씩 구성되어 있었고 , 운영환경은 4대로 구성 되어 있었으며 배포는 Jenkins를 통하여 진행 하였다.

그 외 Jenkins 설정에 관련한 파이프 라인 및 Git Repository 등에 대해 물어보았고, 배포 전략에 관한 카나리, 롤링 Blue/Green 배포 방식에 대한 개념을 알고 있는지 간략하게 물어봤던 기억이 난다. 아! 그리고 서비스 운영시 트래픽에 관련한 사항도 추가적으로 물어보았다.

배포 전략에 관해서도 한번 스윽 읽고 면접을 보는게 도움이 될 듯 하다.

https://onlywis.tistory.com/10

4. 암/복호화 방식 

내 이력서 내용중 암/복호화를 경험했던 이력이 있어, 질문을 했던걸로 생각 된다.

암/복호화 종류와 간단한 개념을 물어보았고 다행히(?) 대답을 하였으며, 추가적으로 소스를 직접 건드린 경험이

있는지 확인을 해본거 같은데 몇 바이트로 키를 생성하고 어떻게 적용 시켰는지와 몇개의 핵심 키워드를 말해달라고

얘기했었다.

5. API 문서 

타 팀과 연동작업을 할때 API 문서는 어떤식으로 작성하고 관리 했는지를 물어보았다.

  • 메일로 API 프로토콜을 정의하여 전달하고 피드백을 받는 형식 
  • 사내 파일관리 시스템 해당 폴더에,  API를 정의한 한글 및 엑셀 파일을 업로드 하는 형식
  • Swagger UI 

위와 같이 경험했던 내용을 말했고,  swagger 를 사용할때가 개인적으로 좋았다고 말씀드리며 기회가 되면 Spring Rest Docs 도 해보고 싶다고 나름 어필(?) 하였다.

6. MSA 관련한 질문 사항 및 버전 관리

이 부분은 주로 개념에 대해 알고 있는지 확인을 하고 너무 Deep 한 질문은 하지 않으셨다.

Monolithic Arichitecture 와 Microservice Arichitecture 의 개념과 각각의 장단점에 대해서 설명을 요구 하셨고,

내가 생각하기에 이런이런 서비스에서는 Mono, 이런이런 서비스에서는 MSA 방식을 사용하는게 좋을 거 같다고

예시를 하였다. 아래 그림은 내가 스터디 당시 이해하기 쉬웠던 이미지 !!

백엔드 경력 면접 질문 - baeg-endeu gyeonglyeog myeonjeob jilmun
Monolithic Arichitecture
백엔드 경력 면접 질문 - baeg-endeu gyeonglyeog myeonjeob jilmun
Microservice Arichitecture

아래 사이트는 영문으로 되어잇는데, 크롬 번역기를 킨 후 참고 했던 내용.

https://www.nginx.com/blog/introduction-to-microservices/

7. REST API 

GET / POST / UPDATE / DELETE 방식에 기본적인 질문들이었고 대답하기 쉬운 부분이였다.

Ajax 에서 파라미터로 던질때 어떤식으로 던져야 하는지 정도? 그리고 각각에 대해 언제 사용해야 되는지?

그리고 API 설계시 주의해야 하는 사항?

추가로 fetch 에 대해 물어보기도 하였으니, 사용을 해보진 않았더라도 스터디는 하고 준비할 것 !! 

아래 두개의 블로그만 정독하고 가도 대답은 다 할 수 있을 것이다. 

https://meetup.toast.com/posts/92

https://juunone.github.io/fetchAPI/

8. 탐색 알고리즘 

경력직 기술면접에서 디자인 패턴과 알고리즘 관련한 문제는 많이 나오고 있어 대비를 하였던게 천만다행 !

탐색 알고리즘에 대해 물어보았고, 이진 탐색과 순차 탐색에 대해 답변을 하고 난 후 면접관님이 문제를 내셨다.

면접관: 제가 1 ~ 100 까지 자연수 중에서 특정한 숫자를 생각할거고 그것을 맞추면 됩니다. 전 YES or NO 만 대답 합니다.

대장장이: 50 !!!!

면접관 : Nope! 

(음.... ;;;;;;;;; 음.............) 

대장장이: 50보다 큰가요 ? 

면접관: 여기까지 할게요~ 

간단한 질문을 통해 이진 탐색에 대해서 알고 있는지 확인을 해보셨던 것 같다 ( - . - )

9. 페이지 교체 알고리즘

이 부분에 대해서는 공부를 제대로 하지 않아 답변을 못하였다 ㅠㅠ 

답변을 하지 못하니 힌트식으로 "FIFO" 라는 단어를 던져 주웠고, ehCache 에서 max heap size를 넘겼을때

처리하는 방식이 떠올라 연달아 LRU, LFU 에 대해 말씀을 드렸는데 얻어 걸렸다 !!

되새김질을 하기 위해 여기다 간략하게 정리.

페이지 부재가 발생하면 요청된 페이지를 디스크에서 메모리로 읽어와야 한다.
이때, 물리적 메모리에 빈 프레임이 존재하지 않을 수 있다. 이 경우에는 메모리에 올라와 있는 페이지 중 하나를 디스크로 쫓아내어 메모리에 빈 공간을 확보하는 작업이 필요하다. 이것을 페이지 교체(page replacement)라고 한다.

페이지 교체를 할때, 어떠한 프레임에 있는 페이지를 쫓아낼 것인지를 결정하는 알고리즘을 페이지 교체 알고리즘(replacement algorithm)이라고 한다. (가까운 미래에 참조될 가능성이 가장 적은 페이지를 선택해서 내쫓는 것이 성능을 향상시킬 수 있는 방안이다.)

페이지 교체 알고리즘의 성능은 주어진 페이지 참조열(page reference string)에 대해 페이지 부재율을 계산함으로써 평가할 수 있다.

  • FIFO(First-In-First-Out) 알고리즘 : 페이지 교체시 물리적 메모리에 가장 먼저 올라온 페이지를 우선적으로 내쫓는다.
  • LRU(Least Recent Used) 알고리즘 : 최근에 가장 오랫동안 사용하지 않은 페이지를 교체하는 기법
  • LFU(Least-Frequently-Used) 알고리즘 : 페이지의 참조횟수로 교체할 페이지를 결정하는 기법.

참고: https://eunhyejung.github.io/os/2018/07/24/operatingsystem-study15.html 

10. 예외처리 

일단 오류(Error)와 예외(Exception)에 대해서 명확히 알고 있는지 확인 하였다.

또한 Checked Exception 과 Unchecked Exception 의 차이에 대해서 여러가지를 물어 보셨다.

예를 들면, 트랜잭션의 처리는 어떤 부분이 다르죠? 각각의 대표 클래스를 말해보시겠어요?? 등등.

(Checked: IO Exception / Unchecked: NPE ) 

그리고 Spring framework 에서 예외처리 전략에 관한 제 생각을 물어보기도 하였습니다.

그래서 제가 공통 작업을 진행하는 담당자라면 ~ 이라는 가정하에 생각(?) 나는 것에 대해 답변을 하였습니다.

  • 통일된 Error Response 를 정의 하겠다 -> ResponseEntity 
  • Response 에서는 message, code, status, pointer, errors 가 Root element 로 두도록 하겠다.
  • @ControllerAdvice 어노테이션을 통해 모든 예외를 핸들링 하겠다.
  • 필수 파라미터가 없거나 비즈니스 로직 에러일 경우, RuntimeException을 상속받는 커스텀 클래스를 생성후
    사용한다. (용도 및 기능별)
  • 커스텀 클래스의 경우 에러코드 및 에러 메시지를 Enum으로 관리하며 이를 파라미터로 받는 생성자도 추가 한다.

11. Collection framework interface 특징 

컬렉션의 상속 구조에 대해 질문을 하셨고, 각 인터페이스의 특징을 물어 보셨다.

나는 컬렉션에 대한 설명을 따로 정리하여 달달 외워서 갔고, 추가적인 질문에 대해서는 개발업무 하면서 배웠던

내용으로 대답 하였다.

List 인터페이스는 순서가 있고, 데이터의 중복을 허용 하며 색인을 사용하여 특정위치에 삽입하거나 접근할 수 있다.

구현 클래스의 ArrayList 경우 빠르고 순차적인 접근에 강점이 있고, vector는 모든 메소드가 동기화 되어 있는 강점이 있고, LinkedList 는 양방향 포인터 구조로 삽입/삭제가 빈번할때 빠른 성능을 보장 한다.(스택, 큐, 양방향 큐등을 만들기 위한 용도)

Map 인터페이스는 Key, Value 가 쌍으로 이루어져 있다.

구현 클래스의 HashMap 은 해시 테이블을 사용하고 중복을 허용하지 않으며, key-value 가 null을 허용 합니다.

HashTable 은 HashMap 보다 느리지만 동기화를 지원하고 key-value 가 null 을 허용하지 않습니다.

TreeMap 은 이진검색트리의 형태로 키와 값의 쌍으로 이루어진 데이터를 저장하며, 정렬된 순서로 저장이 되므로 검색이

빠릅니다. LinkedHashMap 은 HashMap을 상속받아 흡사 하나, 입력한 순서대로 반복 가능 합니다.

추가로 ArrayList, HashSet, HashMap은 멀티 스레드 환경에서 안전하지 않는데, thread-safe 있게 사용하려면 어떻게

해야하는지에 대해 물었습니다. synchronized 를 통해서 thread-safe 한 리스트를 만들수 있다고 설명 하였습니다.

하지만 락이 걸렸을 때 대처 방안에 대해서는 제대로 답변을 하지 못하였습니다. 

면접이 끝난 후 집에 돌아와 검색을 해보고 다시 되새김질을 하기 위해 조사한 결과는 아래와 같습니다. 

(참고: https://cornswrold.tistory.com/209)

자바에서는 멀티스레드환경에서 안전하면서도, 스레드가 병렬적으로 작업을 처리할 수 있도록 java.util.concurrent 패키지에서 ConcurrentHashMap, ConcurrentLinkedQueue를 제공 한다. 이 구현체들은 부분(segment) 잠금을 사용하기 때문에 병렬적으로

작업 수행이 가능하다. 예를 들면, Map에 10개의 요소가 저장되어 있을 경우, 1개의 요소를 처리할 때 그 처리하는 곳이 포함된 부분만 락을 걸고 나머지부분은 다른스레드가 변경할 수 있게 하는 것이다. (1개의 요소를 처리할 때 나머지 10개 요소에 락을 거는것이 전체 잠금)

  • Mapmap = new ConcurrentHashMap();

  • Queuequeue = new ConcurrentQueue();

12. 디자인 패턴 

디자인이 패턴이 나온 이유와 개념에 대해 먼저 질문을 하셨고, 내가 알고 있는 디자인 패턴들에 대해서 자유롭게

말해보라고 하셨다. 그래서 나는 디자인 패턴을 생성(Creational) / 구조(Structural) / 행위(Behavioral) 3가지로 분류하여

생성 쪽에는 싱글톤과 팩토리를,  구조에는 어댑터와 프록시를, 행위에는 옵저버와 템플릿 패턴에 대해 설명하였다.

추가로 실제로 사용한 경험이 있어서 사례를 들며 답변 하였다. 

13. 개발자 학습(?) 관련

외부 세미나 및 교육, 스터디 활동, 최근에 읽은 책 5권, 책의 저자도 아는지? 등등 내가 공부를 적극적(?)으로

하고 있는지와 관심이 있는지 확인해 본 것 같다.  (책도 몇권 추천해주심)

14. JVM / 가비지 컬렉터(GC) 관련

가비지 컬렉터에 대한 내용은 아래 블로그를 통해 학습 하였고, 답변을 하고 나서 바로 다음 질문으로 넘어 갔다.

(워... 원하는 키워드가 다 나왔던거 같은 분위기 였다 !! )

- 참고: https://12bme.tistory.com/57

자바에서는 메모리를 가비지 컬렉터(GC) 라는 알고리즘을 통하여 관리하기 때문에 , 개발자는 메모리를 처리하기 위한

로직을 만들 필요도 없고, 구현해서도 안된다고 알고 있습니다. JVM의 메모리는 크게 클래스 영역, 스택 영역, 힙 영역,

네이티브 메소드 스택 영역으로 나뉘고 있는데 GC는 힙 영역을 다루게 됩니다. 

메모리를 할당을 하고, 사용중인 메모리와 사용하지 않는 메모리를 인식하여 처리를 합니다. 

JVM 힙 영역은 다시 Young, Old, Perm 세영역으로 나뉩니다. 

[       Eden      | Survivor | Survivor |     Virtual     ]  [            Old           | Virtual ] [            Perm            | Virtual ]

Perm 영역은 거의 사용되지 않고, 클래스와 메소드 정보와 같이 자바언어 레벨에서는 사용되지 않습니다.

(application을 실행할때 클래스의 메타 데이터를 저장하는 영역)

Young 영역은 Eden 과 두개의 Survivor 영역으로 나뉩니다.

(새로 생성한 객체를 저장하는 영역)

일단 메모리에 객체가 생성되면, Eden 영역에 객체가 지정됩니다.  Eden 영역에 데이터가 어느 정도 쌓이면, 이 영역에 있던 객체가 어디론가 옮겨지거나 삭제됩니다. 이 때 옮겨가는 위치가 survivor 영역입니다. 두개의 Survivor 영역 사이에 우선 순위가 있는 것은 아닙니다. 하지만, 이 두 개의 영역 중 한 영역은 반드시 비어 있어야 합니다. 그 비어있는 영역에 Eden 영역에 있던 객체가 할당됩니다.

Eden에서 survivor 둘 중 하나의 영역으로 할당 되고, 할당된 Survivor 영역이 차면, GC가 되면서 Eden 영역에 있는 객체와 꽉 찬 Survivor 영역에 있는 객체가 비어 있는 Survivor 영역으로 이동합니다. 그러다가 더 큰 객체가 생성되거나, 더 이상 Young 영역에 공간이 남지 않으면 객체들은 Old 영역으로 이동하게 됩니다.