# 09. level interview
# 목표
우아한테크코스에서 진행한 미션의 리뷰와 피드백에 대해 정리한다.
# 레벨 인터뷰란?
- 이전 레벨에 학습한 내용에 대한 자신의 현재 상태를 파악한다.
- 자신이 알고 있는 지식을 말로 표현하는 연습을 통해
메타인지
를 기른다.
# 레벨 2 인터뷰 내용 회고하기
# 자기소개
안녕하세요 항상 코드의 근거를 생각하는 개발자 매트입니다. 이러한 역량을 키우기 위해 자신의 생각과 근거를 나눌 수 있는 아고라를 꾸준히 진행하고 있습니다.
인터뷰 중 일부
인터뷰어
: 시간이 많지 않으니 패스하겠다. 실제 면접을 진행하게 되면 아고라가 무엇이며 어떠한 것을 얻었는지에 대해 미리 대비하는 것이 좋다.
# 레벨 2에서 어떤 것을 배웠는가?
전반적으로 스프링 프레임워크에 대한 그런 지식들을 습득했다. 스프링으로 기반으로 웹 애플리케이션을 개발하는 과정과 인수 테스트를 기반으로한 ATDD를 활용해서 웹 애플리케이션을 개발하는 경험을 진행했다.
개선할 점
긴장한 탓인지 자신감이 떨어지는 듯한 말투를 느꼈고 급작스러운 질문으로 머릿속이 하얘졌다. 미리 대비하지 못한 질문들에 대해 생각한 뒤 떠오르는 단어들을 잘 정돈하여 말하는 연습이 필요함을 느꼈다.
# 스프링에 대해 공부 했다고 했는데 스프링은 무엇인가?
스프링은 동작하는 애플리케이션 개발을 만드는데 유용한 도구이고 거기서 해주는 역할로는 개발자가 직접 객체간의 의존성을 관리하는 것이 아니라 스프링이 대신해서 관리 함으로써 개발자가 좀 더 비즈니스 로직에 집중해서 개발할 수 있도록 도와주는 유용한 프레임워크이다.
# 프레임워크에 대해 이야기 했는데 프레임워크가 무엇인지 설명할 수 있는가?
프레임워크는 개발자가 직접 흐름을 가져가서 개발하는 것이 아니라 프레임워크가 짜여진 틀에 따라서 그것에 맞춰 개발을 도와주는 도구라고 생각한다.
# 틀에 따라 개발한다고 했는데 틀이 무엇을 의미하는가?
보통 프레임워크와 라이브러리를 비교하는데 라이브러리의 경우 개발자가 직접 실행에 대한 로직들을 직접 작성하는데 프레임워크를 사용하게 되면 프레임워크가 의도한 그러한 실행 흐름에 따라서 개발자가 그것에 맞춰서 개발을 진행할 수 있다. 여러 개발자가 하나의 프레임워크를 사용하게 되면 획일화된 틀에 맞춰서 개발을 진행할 수 있기 때문에 보다 더 빠른 속도로 원하는 결과물을 만들 수 있다.
# 프레임워크가 정해진 틀이 있다고 하는데 만약 스프링과 같이 복잡한 프레임워크는 학습하는데 오랜시간이 걸린다. 이것은 오히려 생산성이 떨어지는 것이 아닌가? 그냥 라이브러리를 가져다 빨리 만드는 것이 낫지 않을까?
그것은 이제 혼자 판단하는 것이 아니라 주어진 요구사항이나 실제 만들어야 하는 애플리케이션에 대해 충분히 고민해본 뒤 그 규모나 다양한 요소들을 따져서 선택을 해야 된다고 생각을 해서 단순히 빨리 개발 하기 위해서 라이브러리를 선택하기 보다 저희가 진짜 개발하고자 하는 상황에 맞춰서 선택해야 하지 않을까 생각한다.
개선할 점
이때 부터 대비하지 못한 질문들을 받은 뒤 더욱 긴장하게 되었다. 했던 단어들을 되풀이 하기도 하며 자신 없는 대답에는 끝을 흐리기 까지 했다. 질문에서 뚜렷한 정답이 없는 문제이기 때문에 좀 더 주관을 담아 자신감을 가지고 대답해도 될 것 같다고 판단한다. 특히 말 끝은 흐리는 습관은 더더욱 자신감이 없게 느껴지기 때문에 이러한 습관은 꼭 개선해야 한다.
# 프레임워크가 학습 비용이 높아 그런 문제들이 생기지 않을까에 대한 질문이었다.
충분히 그것을 감수할 만큼 좀 더 장점인 측면들이 많기 때문에 활용을 한다고 생각한다.
개선할 점
위와 동일하다. 자신감이 없는 말투가 지속되었으며 질문의 의도를 정확히 파악하지 못했다. 만약 실제 면접에서 질문을 정확히 이해하지 못했다면 꼭 다시 내가 이해한 바가 맞는지 확인하는 과정이 필요할 것이다. 무턱대고 대답하기 보다 질문을 확실히 이해하고 이에 대비하자.
# IoC란 뭘까?
IoC는 단순히 언어를 해석하면 제어의 역전인데 보통은 개발자가 의존성을 작성하고 그 의존성을 관리해줘야 한다. 그런 부분들을 외부에서 주입을 받아서 외부에서 설정을 해서 객체의 생성과 소멸에 대한 그런 제어의 권한들을 외부에서 관리할 수 있도록 하는 것으로 알고 있다.
개선할 점
앞서 받은 질문 폭격으로 인해 머리가 다소 멍한 상태였다. 미리 대비된 질문이었지만 알고 있는 것들을 잘 정돈하여 대답하지 못했다. 단순히 키워드에 대한 정리보다 나만의 근거나 생각들을 정리해서 자연스럽게 나올 수 있도록 하는 노력이 필요하다.
# 의존성 주입을 이야기 했는데 의존성 주입에는 어떠한 것들이 있을까?
대표적인 의존성 주입으로는 생성자를 활용한 주입과 필드를 활용한 주입, 세터를 활용한 주입이 있는데... 있습니다.
개선할 점
뒤에 설명을 뒷받침하려 했지만 질문의 의도보다 더 많은 대답을 하는 것 같이 느껴져서 보다 더 많은 핑퐁을 주고 받기 위해 급하게 대답을 마무리하였다. 핑퐁을 원한다면 확실하게 알고 있는 것만 간략하게 대답해야 한다.
# 스프링이라는 별개로 의존성 주입 자체에 대해서 설명해줄 수 있는가?
보통 스프링이라는 프레임워크를 제외하고 기본적으로 의존성 주입으로는 생성자를 통한 주입과 세터를 통한 주입, 확실하진 않지만 한 가지 더 있는게 인터페이스를 활용해서 인터페이스에 주입을 위한 메서드를 명시하고 그 인터페이스를 구현하면서 그 메서드를 통해 주입하는 형태로 크게 3가지가 있다고 알고 있다.
개선할 점
이 부분은 사실 대비되지 못한 부분이었고 마지막 인터페이스를 활용한 주입 형태는 이전에 잠깐 스쳐지나가며 본 기억을 끄집어 내어 대답하었다. 또한 의존성 주입 방식이 3가지만 존재하는 것은 아닌데 굳이 강조할 필요는 없다.
# 객체가 의존성을 갖는다는 것이 무슨 말인가?
객체는 결국 객체지향적인 관점에서 객체는 서로간의 ... 객체가 객체를 가짐으로써 의존성을 가진다고 표현을 하는데요. 결국 객체는 혼자서 모든 것을 다 해결할 수 없기 때문에 자신이 필요한 부분을 적절히 다른 객체에게 메시지를 보내기 위해서는 필요한 객체를 가지고 있어야만 객체에게 메시지를 보낼 수 있기 때문에 객체가 객체를 가질 때 의존성을 가진다고 표현한다.
개선할 점
너무 고민 없이 자동 반사적으로 대답부터 시작하였다. 결국 정리 안된 단어들을 계속 반복해서 대답을 했고 생각이 정리가 된 이후 말하고자 하는 말들이 나오기 시작했다. 아는 것에 대한 질문이어도 충분한 정리를 통해 대답하는 것이 더욱 좋다고 판단한다.
# 객체를 가진다는게 무슨 말인지 잘 이해가 안되는데 어떻게 구현하였는가?
어 이제 자바를 기준으로 말씀을 드리면 필드로 객체를 선언하여 가지고 있었다.
# 그냥 필드로 선언하면 객체의 의존성이 생기는 것인가?
생성자를 통해 직접 생성을 할 수도 있고 혹은 아까 말씀드린 것 처럼 외부에서 주입을 통해 실질적인 객체의 의존성을 설정할 수 있다.
# 알규먼트 리졸버가 서비스를 가져야 한다고 생각하는가? 만약 아니라고 생각하면 그 이유를 말하라.
일단 알규먼트 리졸버는 컨트롤러에 종속적인 개념이라고 생각한다. 그렇게 생각한 이유는 결국 알규먼트 리졸버의 역할 자체가 컨트롤러의 매개변수를 온전히 만들어주기 위한 용도이기 때문에 컨트롤러는 결국 표현 계층인데 그 표현 계층에 종속적인 개념이기 때문에 그 표현 계층이 비즈니스 계층을 가지는 것 자체가 저는 전혀 이상하지 않다고 생각을 했고 그래서 알규먼트 리졸버가 서비스를 가져도 된다고 판단했다.
# 서비스가 무엇인가?
서비스는 어떤 부분에서의 서비스를 말하는 것인가?
# 객체는 컨트롤러도 있고 알규먼트 리졸버도 있고 객체들에게 역할을 부여할 수가 있는데 일반적으로 @Service도 있고 계층도 있는걸로 알고 있다. 어떤 객체에 대해서 @Service를 붙일 수 있을까?
제가 생각했을 때 서비스 계층에 있는 서비스를 생각을 했는데 결국 거기에는 저희가 이루고자 하는 핵심 비즈니스 로직이 모두 담기게 되는 계층이라고 생각한다.
# 계층을 나눠서 개발 했을 때 서비스에 대해 말씀했는데 이런식으로 레이어드 아키텍처를 사용하는 이유는 뭐라고 생각하는가?
우선 가장 큰 장점은 관심사에 따라 계층마다 적절한 역할과 책임에 대해서 온전히 집중할 수 있고 계층을 나눔으로써 애플리케이션의 결합도를 낮춰서 예를 들면 영속 계층에 변화로 인해 온전히 서비스 계층에만 영향을 줄 수 있도록, 다른 상위 계층은 그 변화에 대해 알지 못하는게 가장 큰 장점이라고 생각한다.
# 서비스가 서비스를 의존하는 것에 대해 어떻게 생각하는가?
서비스가 서비스를 의존해도 괜찮다고 생각한다. 그러한 근거는 우선 서비스 계층은 DAO를 가지고 있으면 그 DAO에 대한 충분한 검증을 통해서 한번 더 가공된 도메인을 가지고 있기도 하고 그리고 추가적인 트랜잭션 처리로 인해 데이터의 동일성이나 트랜잭션의 장점들을 온전히 가지고 나서 서비스를 사용했을 때 그런 것들을 충분히 활용할 수 있기 때문에 가져도 괜찮다고 생각을 하고 만약 서비스가 하위 계층만 가지게 제한을 할 경우 하위 계층에서 진행한 검증들을 반복적으로 진행해야 하는데 그러한 부분들을 서비스에서 처리해주기 때문에 서비스가 서비스를 가지는 것이 괜찮다고 생각한다.
개선할 점
너무 설명이 장황하다. 충분히 두괄식 표현을 통해 강조하고자 하는 내용을 언급한 뒤 내 생각과 근거를 말하면 된다. 생각과 근거에 대한 정리가 부족하였기 때문에 주절주절 설명을 붙이게 되고 결국 장황한 답변이 되어버렸다. 평소 생각들을 꾸준히 메모하고 갱신하는 습관을 유지해야 한다.
# 그럼 서비스에서 도메인 반환과 dto반황에 대해 언급했다. 어떤 것이 더 좋을까?
우선 의견을 말하자면 서비스에서 도메인을 반환하는 것이 더 좋다고 생각한다. 그것에 대한 근거로는 우선 서비스가 dto를 반환하게 될 경우 서비스가 서비스를 의존할 때 dto에서 도메인으로 변환하는 추가적인 불 필요한 과정이 필요하다고 생각을 해서 차라리 dto를 반환하기 보다 도메인을 반환하는 것이 더욱 적절하다고 생각했고 그 다음 여러 컨트롤러에서 서비스를 사용할 때 하나의 응답 dto로 제한을 할 경우 결국 다른 컨트롤러에서 사용하기 위해서 그 컨트롤러에 맞는 추가적인 응답 dto를 만들어야 해서 그런 부분들을 차라리 컨트롤러에서 그 도메인 객체를 기반으로 응답 객체를 만드는 것이 좀 더 반복 코드를 줄일 수 있지 않을까 생각한다.
# 그럼 dto 생성을 컨트롤러에서 하고 있는 것인가?
그렇다.
# 그렇게 했을 때 문제점은 없을까?
가장 크게 언급한 문제점으로는 표현 계층에서 도메인을 직접적으로 호출하거나 변환하는 행위를 했을 때 가장 큰 문제가 생긴다고 생각했다. 이제 그런 부분들은 함께 협업하는 개발자나 의식을 하며 도메인 객체를 사용하지 않는 쪽으로 개선을 충분히 할 수 있다고 생각한다. 결국 dto를 변환하는 행위 자체가 표현 계층에 있는 것은 문제가 없다고 생각한다.
# 서비스 두개가 다른 트랜잭션을 사용하고 있을 때 컨트롤러에서 각각 개별의 트랜잭션이 생길 수 있다. 그렇다면 결국 일관되지 않은 데이터가 저장될 수 있다. 문제가 있는 것이 아닌가?
그렇다면 결국 컨트롤러에서도 트랜잭션이 묶여야 일관성을 유지하는데 그것이 안되지 않냐에 대해 질문을 주신 것인가?
# 서비스에서 도메인을 반환해서 컨트롤러에서 dto를 만들게 했을 때 다른 서비스 안에 트랜잭션이 개별적으로 생기는데 한 트랜잭션 안에서 처리가 안된다. 즉 데이터가 이상해질 수 있다. 그런 문제는 어떻게 해결하는가?
그러한 관점에서는 고민을 해보지 못했다.
# 그러면 서비스가 dto를 만들 때 서비스를 다 불러모아 하나의 트랜잭션에서 만드는 것이 안전한 것이 아닌가?
만약 그런 상황이 주어지게 된다면 그러한 서비스보다 하나 더 상위의 서비스를 만들어서 처리되는 일련의 트랜잭션 과정을 상위 서비스에서 처리한 다음 거기서 이제 추가적인 dto나 혹은 도메인을 만들어서 컨트롤러에서 활용할 것 같다.
# 그럼 dto를 반환하는 것이 더 낫지 않을까? 이에 대해 어떻게 생각하는가?
그 부분에서 사실 도메인이 무조건적으로 좋고 사용해야 한다기 보다 dto를 반환해야 하는 상황이 주어지면 각각의 이점이 있기 때문에 그 이점들을 잘 활용하고 그 상황에 맞춰서 활용하면 큰 문제가 없다고 생각하기 때문에 기반은 도메인을 반환하되 언급한 것 처럼 특수한 경우에는 추가적인 dto를 활용해도 괜찮다고 생각한다.
# ATDD가 무엇인가?
ATDD는 인수 테스트를 기반으로 개발하는 개발 프로세스를 ATDD로 알고 있다.
# ATDD를 하는 이유나 효용에는 어떤게 있는가?
우선 ATDD는 작업에 명확한 시작과 끝을 정한 뒤 개발을 시작하기 때문에 저희가 보다 더 큰 그림을 기준으로 개발을 진행하기 때문에 옆으로 세지 않고 등대 같이 한 곳을, 하나의 목표를 바라보면서 개발할 수 있는 장점이 있다.
# 인수 테스트랑 E2E 테스트를 비교해줄 수 있나?
제가 생각했을 때 E2E 테스트는 결국 인수 테스트 보다 조금 더 작은 개념이라고 생각을 했는데 결국 인수 테스트는 사용자의 시나리오가 타겟이 되는 테스트를 모두 인수 테스트라고 부르고 그 중에서도 E2E 테스트는 API 관점에서 API가 시나리오대로 정상적으로 동작하는지에 대해서 테스트 하는 것이기 때문에 제가 생각했을 때는 인수 테스트 안에 E2E 테스트가 들어 있다고 생각한다.
# E2E 테스트도 그럼 API를 테스트 하는 것인가?
이것도 결국 시나리오를 기반으로 엔드 포인트가 적절히 저희가 요청한 것과 응답이 적절한지에 대한 테스트를 진행한다.
# 프론트에서도 E2E 테스트라는 표현을 사용한다. 하지만 API를 테스트하지 않는데 어떻게 생각하는가?
백엔드와 프론트가 결국 바라보는 엔드 포인트가 다르기 때문에 백엔드의 경우 API 서버를 구축했을 때 저희 입장에서의 엔드 포인트는 API를 호출하는 쪽이 될 것이고, 프론트 부분에서는 실제 사용자가 사용하고 있는 페이지나 그런 부분들이 엔드 포인트가 되기 때문에 그런 부분에서의 차이가 있는 걸로 생각된다.
# 그러면 테스트 코드를 짜는 과정에서 ATDD를 사용한다고 했다. ATDD 이후에 전체적으로 테스트는 어떤 과정이나 기준을 가지고 진행을 하는 편인가?
가장 큰 비중을 두고 고민을 하는 부분은 도메인이 어느정도 눈에 그려지는지 안그려지는지 부터 시작을 하는데 도메인이 확실히 그려지기 시작하면 도메인 부터 TDD를 시작을 하고 거기서 부터 점차 상위 계층을 개발 하는 식으로 진행을 하고 있고, 만약 도메인이 잘 그려지지 않으면 목킹을 활용해서 큰 그림 부터 안쪽으로 들어가는 식으로 진행을 하고 있다.
# 목킹이라고 말했는데 그럼 목킹을 하는 경우가 있고 실제 클래스를 사용하는 방식이 있는데 어떤 방식이 더욱 낫다고 생각하는가?
결국 목킹을 하는 목적도 테스트 격리를 위해서 라고 생각을 하는데, 목킹을 사용하는 것 보다 실제 객체를 사용하는 것이 더 낫다고 생각한다. 이유는 실질적으로 그 객체가 온전히 동작하는지 확인하기 위해서는 그 객체가 의존하고 있는 다른 객체들도 정확히 동작을 하는지에 대해서도 함께 확인을 해야 그 객체가 테스트가 됐다고 생각을 하기 때문에 목킹을 활용하기 보다 실제 객체를 활용하는 편이 낫다고 생각한다.
# HTTP가 무엇인가?
HTTP는 웹 상에서 서버 혹은 클라이언트 사이에서 주고 받기 위한 통신 규약이다.
# HTTP의 특징은?
HTTP의 가장 대표적인 특징으로는 상태를 가지고 있지 않은 stateless 하다는 것이 가장 큰 특징이고...
# 상태를 가지고 있지 않다는 것이 가장 큰 특징이라고 했는데 왜 그렇게 설계 했을까? 너무 불편하지 않은가?
상태를 가지면 결국 HTTP가 요청 및 응답을 했을 때 그 상태 정보를 항상 바디나 혹은 헤더에 담아야 하는데 결국 그것도 통신에 대한 비용이 지속적으로 늘어나기 때문에 그런 부분을 조금이라도 줄이고자...
# 말씀하신 상황은 HTTP 요청 및 응답에 충분히 담아서 줄 수 있는 것 아닌가? 결국 그 점이 안좋다고 생각하는가? HTTP가 상태를 가진다는게 어떤 의미 일까?
예를들어 로그인을 했다고 가정하면 로그인한 사용자 정보를 어딘가는 알고 있어야 하는데 HTTP는 기본적으로 stateless하기 때문에 요청한 사용자가 누군지 정보를 담아줘야만 서버 측에서 이 사용자가 요청을 정상적으로 보냈구나 확인할 수 있는데 결국 그 정보들을 매번 바디 혹은 헤더에 담아줘야 하는 부분 자체가 자원의 낭비이지 않을까 생각한다.
# 그렇다면 상태를 가지도록 하면 되는 것이 아닌가?
개선할 점
시간이 부족한 관계로 다른 질문으로 넘어가기 위해 답변은 하지 못했다. 질문의 의도를 지금 살펴보면 상태를 가지도록 해서 이러한 단점들을 없애는 방법에 대해 물어본 것으로 추측한다. 가령 서버 측에서 cookie를 세팅해준 뒤 클라이언트에서 매번 쿠키에 값을 담아 보내면 해당 요청이 어디서 날라온 것인지 쉽게 확인할 수 있다. 하지만 이것은 HTTP의 stateless한 방식을 stateful하게 만들기 때문에 약간의 트레이드오프를 가져온다. 관련해서는 좀 더 추가적인 학습이 필요할 것으로 예상한다.
# HTTP 메서드의 종류와 목적에 대해 알고 있는가?
get은 보통 조회의 목적이고 post는 리소스에 대한 추가, put은 리소스에 대한 전체를 바꾸는 전반적인 수정할 때 활용하고, patch는 일부분을 수정할 때 활용을 하고, delete는 해당 리소스를 삭제할 때 활용하고 있다.
# 공통 피드백
- 처음 엄청 긴장했는데 이야기를 나눌 수록 긴장이 풀리는 것을 느꼈다. 대부분 잘 대답했다.
- 스프링과 스프링 프레임워크, 객체와 객체 사이의 의존에 대해서 평소에 많이 고민한 것 같아 잘 설명해준 것 같아서 좋았다. dto를 컨트롤러에서 만드는 것에 대한 문제점을 이야기 했는데 거기에 대한 해결 방법을 바로 이야기한 부분이 좋았다. 대부분의 질문에 대해 막힘없이 대답하는 것을 보고 평소에 설계나 이론에 대해 정리나 공부했다는 것이 느껴진다. 대답을 장황하게 하지 않고 간략하게 해서 알아 듣기 좋았고, 이해되지 않는 부분은 다시 질문하고 잘 마무리한 것이 인상 깊에 느껴졌다. 그런데 긴장을 좀 해서 많이 굳어 보였고 약간 잘 아는 것을 대답할 때는 말이 조금 빨라졌던 것 같다.
- 전반적으로 이해를 잘 하고 있는 것 같고 추가적으로 HTTP를 다시 공부하면 좋을 것 같다. 말하기에서의 장점은 항상 본인의 생각을 담아서 이야기 하는 것이 좋았다. 항상 근거가 확실하고 미션을 진행하면서 기능을 그냥 사용한 것이 아니라 근거를 찾기 위해 노력했던게 답변에서 느껴져서 좋았고, 질문에 대한 답변을 간결하게 해줘서 이해하기 좋았다. 단점으로는 긴장을 너무 많이 한 것 같아서 난처한 표정들이 쉽게 보여진다. 모르면 대답을 듣기 전에도 쉽게 파악할 수 있을 것 같다. 그리고 설명을 하다가 처음에는 아이컨택을 진행하는데 중간에 자꾸 시선이 떨어지는 경우가 많아서 좀 불안에 보이는 느낌이 들었다. 눈 대신 마스크를 보는 식으로 개선하면 좋지 않을까 생각한다. 그리고 말 끝을 조금 흐리는 습관이 있는 것 같아서 말을 끝 까지 잘 말해주면 좋을 것 같다.
- 일단은 자신의 생각 혹은 개발을 하며 얼마나 고민을 했는지 잘 드러났다. 조금 많이 긴장을 했지만 그것에 비해 대답을 전반적으로 잘했다. 그럼에도 계속 긴장을 했기 때문에 좀 풀리면 더 잘 말할 수 있을 것이다.
- 본인만의 철학이 있는 느낌이 들었고, 기계처럼 막힘없이 자신의 생각을 말한다고 느껴졌고, 의존성 주입 같은 경우 명시적인 갯수를 말하지 말고 그냥 여러개가 있다고 말하는 것이 더 좋다고 생각한다. 굉장히 전달력이 높고 잘 말하지만 순간순간 강조를 딱 줬으면 더욱 좋았을 것 같은 느낌이 든다. 지금도 충분히 좋다고 느껴진다. 그리고 자기소개할 때 매주 아고라를 진행한다고 하면 일반인들은 잘 모르기 때문에 사람들이 모여 같이 토론한다고 표현해도 좋을 것 같다.
- 자기소개를 진행할 때 아고라의 목적에 대해 고민해보는 편이 좋을 것이다. 코드의 근거에 대한 이야기도 마찬가지다. 대비를 하고 자기소개를 준비하자. 대답을 들어보니 나름의 개념 정리를 잘 하고 있는 것 같지만 표현을 할 때 너무 추상적으로 하는 부분들을 조금 더 다듣어주면 좋을 것 같다. 긴장해서 약간 말 잘 안나오는 것만 잘 연습하면 면접 잘 진행할 수 있을 것이다.
# 생각 정리
이번 레벨 2 인터뷰는 녹음을 진행하였다. 실제 면접에서 내가 어떠한 말투와 의성어를 사용하는지 온전히 확인할 수 있었고 당황할 때의 떨림까지 온전히 확인할 수 있었다. 공통적으로 받은 피드백으로는 긴장하는 모습이 드러나는 것과 말 끝을 흐리는 것이다. 내가 생각했을 때 가장 크게 개선해야 하는 부분은 바로 말 끝을 흐리는 것이다. 이유에 대해 생각해보면 결국 답변에 대한 자신감과 확신의 부족으로 습관처럼 흐리게 된다. 평소 근거를 고민할 때 단순히 생각에 그치고 나중에 정제되지 않은 지식들을 정리하곤 한다. 이제는 생각에서 그치지 말고 글로 작성한 뒤 읽어보자. 술술 읽히는지 확인하고 근거가 적절한지 판단하자.
또한 질문 이후 머릿속에서 단어를 정리하지 않고 기계적으로 대답 부터 시작한다. 녹음에서도 그러한 습관들이 잘 느껴졌다. 충분히 고민하며 머릿속에 말하고자 하는 문장들을 잘 나열한 뒤 말하는 습관을 만들자. 이러한 습관은 결국 질문에 대한 의도를 적절히 파악할 수 있으며 의도하지 않은 답변을 줄일 수 있다.
칭찬도 많았지만 개인적으로 아쉬운 부분이 너무 많다. 특히 불특정 다수 앞에서 말하는 것은 매순간 떨림으로 다가온다. 남에게 내 치부를 들키고 싶지 않은 마음이 크기 때문에 더 잘해야 한다는 강박이 큰 긴장을 불러온다. 모르는 것을 들키는 것을 두려워 하지 말자. 충분히 인정한 뒤 편안한 마음으로 임해보자.
# 레벨 인터뷰 정리
아래는 이번 레벨 인터뷰를 준비하며 정리한 내용들이다. 대부분 생각과 근거들로 답변을 채웠기 때문에 다소 틀린 부분이 존재할 수 있다.
# Spring & Spring Core
- 왜 스프링을 사용하는가?
- 동작하는 애플리케이션을 쉽게 만들기 위해
- 객체는 의존 관계를 가진다. 개발자를 대신하여 객체를 생성하고 관리하기 때문에 이러한 의존 관계를 손쉽게 관리할 수 있다.
- 스프링이 관리할 객체를 어떻게 지정할까?
@Bean
과@Component
애너테이션을 활용한다.- 어떤 객체를 스프링이 관리하게 할까?
- JwtTokenProvider처럼
애플리케이션 전반에서 사용
되며 특정한 상태에 종속적이지 않는 객체를 빈으로 등록한다. - 도메인 객체의 경우 애플리케이션의 핵심 비즈니스 로직을 담당한다. 스프링에 의존적인 것은 좋지 않고 생명주기 또한 개발자가 직접 관리하는 편이 좋다. 즉 모든 객체를 스프링 빈으로 등록해야 하는 것은 아니다.
- 도메인 객체는 개발자가 객체의 생명주기를 컨트롤 해야 한다. 또한 스프링에 종속적인 구조를 만들 수 있다.
- JwtTokenProvider처럼
- 왜 객체를 스프링으로 관리해야 할까?
- 스프링 컨테이너가 제공하는 IoC/DI와 같은 다양한 기능들을 적절히 활용할 수 있다. 개발자는 관리해야할 포인트가 줄어들며 온전히 비즈니스에 집중할 수 있다.
- 스프링 빈이 상태를 가진 경우 어떠한 문제가 발생하는가?
- 스프링 빈은 기본적으로 싱글톤 스코프를 가지며 동작한다. 즉 여러 객체가 의존할 경우 동시에 특정 상태를 접근할 우려가 있다. 해당 객체가 불변을 보장하지 않을 경우 사용자는 일관성있는 결과를 확인할 수 없게 된다.
- 상태를 가지고 있는데 빈으로 등록하는 상황이라면 이것은 리팩토링의 근거가 될 것이다.
- IoC란?
- Inversion of Control로 제어의 역전이라는 의미로, 메서드나 객체의 호출을 개발자가 결정하는 것이 아닌
외부에서 결정
하는 것을 의미한다. 여기서 의미하는 제어는 객체가 언제 생성되고 사용하는것에 대한 전반을 다룬다. 스프링에서는 이러한 객체 생성 및 의존성에 대한 설정을 스프링 컨테이너가 하고 있다.
- Inversion of Control로 제어의 역전이라는 의미로, 메서드나 객체의 호출을 개발자가 결정하는 것이 아닌
- 의존성 주입 방법에는 어떠한 방법이 있을까?
- 생성자 주입, setter 주입, 필드 주입이 존재한다.
- 의존성 주입을 왜 사용하는가?
- 런타임에 각 객체들 사이의 필요한 의존 관계를 맺을 수 있다. 또한 인터페이스를 활용한 다형성을 사용하면 낮은 결합도를 가지고 확장에 유연한 객체간의 의존성을 만들 수 있다.
- 어떠한 주입 방식을 사용하는 것을 선호하는가?
- 생성자를 활용한 주입 방식을 선호한다. 객체 생성 시점에 객체의 모든 의존성을 결정할 수 있으며 final 키워드를 활용하면 런타임 시점에 객체의 의존성이 변하는 것을 방지할 수 있다.
- 스프링으로 전환 후 우리가 느낀 이점들은 무엇이 있을까?
- 스프링의 IoC/DI를 통해 객체라는 레고를 조립하는 느낌을 받았다. 또한 스프링에 등록된 빈은 다형성을 활용할 수 있기 때문에 런타임 시점에 실제 의존하고 있는 객체를 정할 수 있다. 이러한 특징은 결국 확장에 매우 유연한 구조를 만들어준다. 또한 객체의 생명주기를 스프링에서 관리해주기 때문에 개발자는 좀 더 도메인 로직에 집중할 수 있게 된다.
- Spring은 직접 만든 객체를 손쉽게 붙여 사용할 수 있다. 그만큼 확장할 수 있는 포인트가 열려있기 때문에 객체지향에 가까운 코드를 작성할 수 있다.
- Spring vs Spring Boot
- 바로 실행할 수 있는 애플리케이션을 쉽게 만들 수 있게 도와준다.
- 사실 대립되는 개념이 아니다. Spring을 보다 더 쉽게 사용할 수 있도록 도와준다. 별다른 설정을 안해줘도 자동 설정으로 인해 바로 실행할 수 있는 애플리케이션을 만들 수 있다.
- 스프링 부트를 사용할 때 장점은?
- 스프링 부트는 많은 스프링 애플리케이션에 공통으로 필요한 애플리케이션 기능을 자동으로 구성 해준다.
- 스프링 부트의 자동 구성을 경험한 사례가 있는가?
- 실제 미션을 진행할 때 JdbcTemplate를 명시적으로 Bean 등록을 진행하지 않았다. 이때 스프링 부트가 제공하는 자동 구성으로 인해 JdbcTemplate이 기본적으로 등록된 Bean을 사용한 경험이 있다.
- 외부 라이브러리의 사용?
- 도메인이 외부 라이브러리에 강하게 의존하게 되면 외부 라이브러리의 변경에 도메인이 매우 취약한 구조가 된다. 개선 경험으로는 외부 라이브러리를 사용하는 행위 자체를 추상화하여 실제 도메인 객체에 주입하는 형태로 개선하였다. 이제 도메인 객체는 더 이상 외부 라이브러리에 의존하지 않으며 후에 요구사항의 변경으로 라이브러리가 변경되면 다형성과 Bean 등록을 통해 간단하게 의존 타입을 변경할 수 있다.
# Spring MVC
@Controller
와@RestController
의 차이는?- 기본적으로
@Controller
는 View를 반환한다. 컨트롤러가 반환한 View의 이름으로부터 View를 렌더링하기 위해서 ViewResolver가 사용되며 ViewResolver 설정에 맞게 View를 찾아 렌더링한다. @RestController
데이터를 반환하는 경우 사용한다. 객체를 반환하기 위해서는 ViewResolver대신 HttpMessageConverter가 동작한다. HttpMessageConverter에는 기본적으로 여러 Converter가 등록되어 있으며 반환해야 하는 데이터에 따라 Converter가 선택되어 적용된다.
- 기본적으로
- 계층형 아키텍처란?
- 관심사에 따라 여러 계층을 나눠 서로 근접한 계층 간 통신을 진행하는 아키텍처이다. 서로 다른 계층에서 관심사에 따라 책임과 역할을 나눠 애플리케이션 전반적인 결합도를 낮춘다. 이러한 계층 분리가 없다면 변화가 필요할 때 대대적인 코드 변경을 진행해야 한다.
- service 계층(Business 계층)의 존재이유는 무엇인가?
- 만약 service layer가 없는 경우 controller에서 request 검증, domain의 비즈니스 로직, dao 요청, response 응답 생성 등 모든 기능들을 도맡아 하게 된다. 결국 controller에 대한 역할이 너무 커지게 되며 로직 파악에 어려움을 야기한다. 그렇기 때문에 service에 비즈니스 로직을 위임하고 controller에서는 request 검증 및 response 응답 생성 등에 대한 책임만을 가지도록 한다. 그 밖에도 데이터의 일관성 지키기 위한 트랜잭션 처리도 진행할 수 있다.
- 서비스 계층이 없는 경우 컨트롤러의 책임이 무거워지며 트랜잭션을 위한 처리가 보장되지 않는다.
- 격리성이 없는 계층화는 계층간 결합도가 매우 높은 애플리케이션이 되는 것을 의미하게 된다.
- 계층을 나눠야 하는 이유는?
- 관심 범위가 축소된다. 만약 presentation 계층에서 persistance 계층에 직접 의존하게 되면 영속 계층의 변경 사항에 의해 business 계층과 presentation 계층 모두에 영향을 미치게 된다. 즉 계층간 결합도가 매우 높은 애플리케이션이 될 수 있다. 하지만 적절히 계층화를 이루어 격리시킬 수 있게 되면 각 계층에 대해 독립적으로 고민할 수 있게 된다.
- 비즈니스 로직은 어디서 처리해야 좋을까?
- 비즈니스 로직을 객체 내부로 적절히 캡슐화하여 기능만 외부에 제공하는 방식으로 진행하면 데이터의 변경이 생겨도 핵심 비즈니스 로직에는 최소한의 영향을 끼치며 유지보수를 진행할 수 있게 된다.
- 객체지향 설계를 진행해야 하는 이유는 뭘까?
- 설계에 대한 이해와 유지보수에 용이하다. 각각의 객체는 작은 책임을 가지기 때문에 각 객체의 역할을 쉽게 확인할 수 있으며 책임의 변화에도 쉽게 변경할 수 있다.
- 테스트하기 쉬워진다. 각각의 객체들에 비즈니스 로직이 들어있기 때문에 순수한 Java 코드를 기반으로 독립된 테스트를 진행할 수 있다.
- 확장하기 용이한 구조이다. 다양한 디자인 패턴이나 다형성을 활용하여 실제 코드를 수정하지 않고 내부 구현체를 바꾸는 행위만으로 확장에 용이한 구조를 만들 수 있다.
- ArgumentResolver와 Interceptor를 각각 어떤 역할로 사용하는가?
- Interceptor는 특정 url에 대한 토큰 검증에 대한 역할을 진행했다.
- ArgumentResolver는 검증이 완료된 토큰의 정보를 추출하여 Controller가 필요한 매개변수를 생성하는 역할로 활용했다.
- 지금까지의 비지니스에서 토큰의 검증만 진행한 뒤 처리되는 핸들러가 존재하지 않았다. 즉 모든 로직에서 검증 이후 토큰 정보를 기반으로 객체를 만들었기 때문에 Interceptor에서 진행하던 검증 로직이 불필요하게 느껴졌다. 결국 토큰의 검증 로직 또한 ArugumentResolver에서 처리해도 무방 했을 것이라 판단한다.
- 언급한 기술들은 대부분 Controller에서 활용 가능하다. 그럼에도 사용한 이유는 무엇인가?
- 토큰을 검증하고 검증이 완료된 토큰에서 정보를 추출하는 행위 자체가 중복으로 처리된다. 앞서 언급한 Interceptor와 ArgumentResolver를 적절히 활용하면 이러한 중복을 줄일 수 있다.
- ArgumentResolver가 Service 객체를 가지는 것?
- ArgumentResolver는 Controller에게 온전한 매개변수를 만들어 주기위한 역할을 가지고 있다. 즉 Controller에 종속된 로직이며 결국 Presentation 계층의 일부라고 판단한다. Presentation 계층에서 service와 같은 비즈니스 계층을 가지는 것은 전혀 어색하지 않다.
- 서비스가 서비스를 의존하는 것?
- 서비스 계층에서 주요 비즈니스 로직의 검증과 트랜잭션을 통한 데이터의 일관성을 지키고 있기 때문에 직접적으로 dao를 사용할 때 보다 안전하게 사용이 가능하며 중복 코드를 줄일 수 있다. 하지만 뚜렷한 상위 하위 계층 구조를 가지고 있어야 한다는 것이다. 만약 상호 의존하게 되면 스프링은 이것을 인지하여 애플리케이션이 동작하지 못하도록 제한한다. 또한 이것은 설계에 문제가 있다는 것을 암시하기 때문에 로직을 적절한 책임을 가진 객체로 이전해야 한다.
- Service에서 도메인 반환 vs dto 반환?
- service에서 도메인을 반환하는 것을 선호한다. 다양한 Controller에서 Service를 활용할 수 있으며 Service가 Service를 의존할 때 dto에서 도메인으로 변환하는 불필요한 과정을 줄일 수 있다. Controller에서 응답에 대한 객체를 만드는 책임 정도는 가질 수 있다고 판단한다.
- 예외 처리는 어떤식으로 처리 했는가?
- 일어날 수 있는 예외 상황에 대한 시나리오를 고민한 뒤 적절한 커스텀 예외를 정의한다. 이러한 커스텀 예외를 기반으로 ContollerAdvice를 활용하여 핸들링한 뒤 적절한 상태 코드와 예외 메시지를 ErrorResponse Dto에 담아 사용자에게 전달하였다.
# JDBC
- JDBC란?
- 데이터베이스에 접속할 수 있도록 도와주는 Java API이다.
- 인터페이스 이기 때문에 실제 DB 연결을 위한
Driver
구현체를 손쉽게 교체할 수 있다.
- JdbcTemplate이란?
- JDBC를 편리하게 작성할 수 있도록 도와주는 툴로 반복되는 try-catch문을 줄여주며 자동으로 Connection에 대한 관리를 대신 해준다.
- Spring에서 DB 접근을 위해 사용한 템플릿은 무엇이 있는가?
- JdbcTemplate, SimpleJdbcInsert, NamedParameterJdbcTemplate을 사용한 경험이 있다.
- JdbcTemplate은 어떻게 생성되는가?
- JdbcTemplate도 DB 접근을 위해 DB의 다양한 설정 정보를 가진 DataSource를 주입받아 생성된다. 이러한 DataSource는 application.yml, application.properties에서 명시한 정보를 기반으로 생성된다.
- NamedParameterJdbcTemplate은 JdbcTemplate과 무엇이 다른가?
- JdbcTemplate은 ? 키워드를 활용하여 데이터를 동적으로 바인딩한다. 이러한 방식의 단점은 순서에 크게 의존적이며 가독성을 떨어뜨린다. NamedParameterJdbcTemplate은 기본적으로 가변적인 이름을 기반으로 바인딩한다. 보다 더 직관적으로 활용가능하며 순서에 의존적이지 않다.
- SimpleJdbcInsert는 JdbcTemplate과 무엇이 다른가?
- 데이터를 간단히 저장하기 위한 용도이다. 불필요한 SQL 작성을 줄일 수 있기 때문에 간편하게 로직 작성이 가능하다.
- JdbcTemplate은 어떻게 생성되는가?
- JdbcTemplate, SimpleJdbcInsert, NamedParameterJdbcTemplate을 사용한 경험이 있다.
- H2란?
- 설치가 필요하지 않은 내장형 DB이다.
- 실제 운영이 아닌 샘플 프로젝트나 테스트에서 활용할 수 있다.
# Test
- 테스트 격리는 왜 해야할까?
- 각각의 테스트는 서로의 순서에 상관 없이 독립적으로 수행해야 하기 때문이다. 즉 각각의 테스트는 서로 관여하지 않고
격리
하여 진행해야 한다. 격리 시키는 위한 조건으로 각각의 테스트는 자원을 공유하면 안된다. 하지만 DB라는 자원은 공유하지 않고 Dao를 격리하여 테스트하는 것은 매우 어려운 일이었다. - 격리를 진행한 방법으로 무엇을 활용했나?
@SpringBootTest
를 사용하면 context를 로드하기 때문에 여러 테스트에서 context를 캐싱하여 재사용한다.@DirtiesContext
를 사용하면 매번 새롭게 context를 새로 구성하기 때문에 오랜시간이 걸리게 된다. 대신 DB의 truncate 키워드를 활용하여 각각의 테스트를 진행할 때 모든 테이블을 비워낼 수 있도록 설정하였다.- 보통 테스트에서
@Transactional
애노테이션을 활용하면 트랜잭션이 롤백된다. 하지만@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
와 같이 PORT를 명시하게 되면 트랜잭션이 롤백되지 않기 때문에 실제 환경과 비슷한 인수 테스트에서는 활용이 불가능하다.
- 각각의 테스트는 서로의 순서에 상관 없이 독립적으로 수행해야 하기 때문이다. 즉 각각의 테스트는 서로 관여하지 않고
- 슬라이스 테스트란?
- 계층을 하나의 단위로 나눠 테스트하는 것이다. 스프링 환경에 모든 Bean을 등록하지 않고 계층에서 사용하고 있는 특정 Bean 혹은 자원만 함께 Spring 환경에서 테스트할 수 있도록 제공한다.
- 단위 테스트란?
- 구현부의 단위를 검증한다.
- 작은 코드 조각(단위)를 검증한다.
- 빠르게 수행이 가능하며 격리된 방식으로 처리한다.
- 통합 테스트란?
- 독립된 단위가 서로 연결될 때 올바르게 작동하는지 확인한다.
- 나눠진 단위들을 유기적으로 검증한다.
- ATDD란?
- 테스트가 가능한 요구사항으로 소프트웨어를 개발하는 프로세스이다.
- ATDD는 시나리오 형태의 요구사항을 등대의 역할로 활용한다. (TDD의 경우 작은 단위의 요구사항이 등대가 된다.)
- 요구사항을 검증하는 테스트로 소프트웨어를 개발하는 프로세스이다.
- 인수 테스트로 소프트웨어를 개발하는 프로세스이다.
- 인수 테스트란?
- 사용자의 스토리를 검증하는 기능 테스트이다.
- 사용자 스토리로 테스트할 시나리오를 지정한다.
- 소프트웨어 이외의 다른 분야에서도 사용되는 언어이며 보통 마지막 단계에서 수행하는 테스트를 의미한다.
명세나 계약의 요구 사항이 충족되는지 확인
하기 위해 수행되는 테스트이다.- 인수 테스트는 내부 구현이나 기술에 의존하지 않는
블랙 박스 테스트
의 성격을 띄고 있다. - API 레벨의 블랙박스 테스트를 진행하기 위해서는 API 레벨의 E2E 테스트를 진행하곤 한다.
- ATDD를 하는 이유는 무엇인가?
- 작업의 명확한 시작과 끝을 제시한다.
- 빠른 피드백으로 생산성을 증가시킬 수 있다.
- 테스트를 활용한 문서화 등 귀찮은 작업을 프로세스로 강제할 수 있다.
- 테스트 더블이란?
- 실제 객체 대신 사용되는 모든 종류의 객체에 대한 일반적인 용어이다. 즉 실제 객체를 가짜 버전으로 대체한다는 것을 의미한다.
- 통합 vs 고립
- 실제 객체를 사용하면 협력 객체의 행위를 협력 객체 스스로가 정의한다. 협력 객체의 상세 구현에 대해 알 필요가 없지만 협력 객체의 정상 동작 여부에 영향을 받는다.
- 가짜 객체를 사용하면 협력 객체의 행위를 테스트가 정의한다. 테스트 대상을 검증할 때 외부 요인으로 부터 철저리 격리된다. 하지만 협력 객체의 상세 구현을 알아야 한다.
- Outside In vs Inside Out
- Outside In은 도메인에 대한 이해도가 높지 않은 상태에서 진행이 가능하다. 상대적으로 프로덕션 코드에 의존적인 테스트가 작성될 수 있다. 즉 깨지기 쉬운 테스트가 된다.
- Inside Out은 도메인 설계가 충분히 이루어져야 가능하다. 그렇기 때문에 TDD 사이클을 이어나가기 어렵다. 하지만 프로덕션 코드에 덜 의존적인 테스트를 작성할 수 있다.
- E2E 테스트 vs 인수 테스트
- 테스트의 구분은 검증하는 대상에 따라 달라진다.
- E2E 테스트는 엔드 포인트 검증에 집중한다.
- 인수 테스트는 요구사항 대로 동작 하는지 검증한다.
- 형태는 같을 수 있으니 칼 같이 구분하지 말자.
- 처음 접하는 기술에 대해서는 어떻게 적용하는가?
- 학습 테스트를 진행한다. 이전에 jgrapht를 활용하여 최단경로에 대한 미션을 진행한 경험이 있다. 이때 처음 사용해보는 라이브러리 였기 때문에 공식 문서와 예시들을 기반으로 간단한 학습 테스트를 진행하여 빠르게 사용법을 익혀 사용한 경험이 있다.
# 네트워크
- HTTP란 무엇인가?
- HTTP는 웹 서버와 웹 클라이언트간의, 즉 웹 상에서 약속된 통신 규약이다.
- REST API란?
- 웹의 장점을 최대로 활용할 수 있는 설계로 URI를 통해 자원의 위치를 표현하고 HTTP 메서드로 행위를 표현한다.
- REST API의 장점은?
- HTTP를 활용하는 환경에서는 대부분 적용이 가능했기 때문에 굉장히 범용적으로 활용이 가능하다.
- REST API를 사용하며 느낀 단점은?
- URI를 통해 자원의 위치를 표현하고 HTTP 메서드를 활용하여 모든 행위를 명시하는 것은 한계가 있었다. 가령 특정 customer의 자신의 정보를 조회하기 위한 URI를 설계해야 했는데 이때 명확한 가이드 라인이 없었기 때문에 식별자를 넣어야 할지 혹은 me와 같은 새로운 URI를 활용해야 할지 고민이 많았다.
- 멱등성이란?
- 동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것으로 리소스 관점에서 동일한 상태를 가지면 멱등성을 가졌다고 표현한다.
GET
,PUT
,DELETE
등이 멱등성을 보장하는 메서드이다. 이러한 멱등성은 일종의 규약이기 때문에 서버 측에서 규약을 지키지 않고 구현할 경우 멱등성 제약을 어길 수 있다. 반대로 멱등성을 보장하도록 구현하면PATCH
의 경우에서 멱등성을 보장할 수 있다.
- 동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것으로 리소스 관점에서 동일한 상태를 가지면 멱등성을 가졌다고 표현한다.
- CORS?
- 교차 출처 리소스 공유는 HTTP 헤더를 사용하여 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주기 위한 체제이다. 웹 애플리케이션은 리소스가 자신의 출처와 다를 때 교차 출처 HTTP 요청을 실행한다.
- 이때 브라우저는 본 요청을 보내기 전에 preflight라고 하는 예비 요청을 통해 요청을 보내는 것이 안전한지 확인하는 작업을 진행한다.
# ETC
- 프레임워크란?
- 프레임워크는 어떠한 목적을 달성하기 위해 복잡하게 얽혀있는 문제를 해결하기 위한 구조이다. 소프트웨어 개발에 있어 하나의 뼈대 역할을 한다.
- 프레임워크를 이용하면 일정한 형태의 틀을 가지고 원하는 결과물을 만들어낼 수 있다.
- 애플리케이션의 흐름은 프레임워크가 가지고 있으며 프레임워크가 만든 틀에 따라 개발을 진행한다.
- 라이브러리란?
- 라이브러리는 단순 활용가능한 도구들의 집합을 말한다. 즉, 개발자가 만든 클래스에서 호출하여 사용, 클래스들의 나열로 필요한 클래스를 불러서 사용하는 방식을 취하고 있다. 사용자가 애플리케이션에서 라이브러리 사용의 흐름을 가지고 있다.
- 식별자를 가진 객체의 동등성 비교는 어떻게 진행해야 할까?
- 대한민국에 사는 국민이라면 유일한 식별자 번호인 주민번호를 가지고 있을 것이다. 내 이름이 단순히 매트에서 패트로 변경되어도 주민번호라는 식별자는 변하지 않기 때문에 유일한 객체임을 보장한다. 즉 객체의 입장에서 동일한 식별자를 가진다면 동일한 객체임을 보장해야 한다.
- 인증(Authentication) vs 인가(Authorization)?
- 인증은 유저가 누구인지 확인하는 절차이다. 보통 로그인 과정을 통해 인증을 확인한다.
- 인가는 유저에 대한 권한을 확인한다.
- JWT란?
- JWT은 유저를 인증하고 식별하기 위한 토큰 기반의 인증이다. 이러한 토큰은 기존에 많이 사용하던 세션 & 쿠키와 다르게 서버가 아닌 클라이언트 측에 저장되기 때문에 서버의 부담을 덜 수 있게 된다. 이러한 JWT에는 토큰 내부에 유저의 식별 정보나 권한 정보를 가질 수 있다. 그렇기 때문에 담겨있는 정보가 많은 경우 토큰의 크기가 커질 수 있기 때문에 최소한의 정보만 담아야 한다.