안녕하세요 B-6조 부담당 튜터 서동규 입니다.
담당 튜터님과 프로젝트 관련한 부분은 잘 하고 계시니
여러분들이 노션에 작성해준 문서를 토대로 이력서를 작성 했을 때 면접에서 물어볼 만한 질문위주로 5가지 준비해봤습니다.
-
기술 스텍 선정 관련 질문
<aside>
💡 1-1. 자바 17 버전을 선택했는데 왜 선택을 했나요? 17버전에는 기존 버전과 비교했을 때 어떤 부분이 장점이 될거라고 생각하셨나요?
-
자바 17의 새 기능인 record를 도입
- 데이터 표현을 간단하게 하고자 함, 주로 DTO에 사용, 명확한 의도 표현
-
자바 17의 새 기능인 switch expression 도입
- 다수의 불필요한 중복 case 간소화와 break 생략 가능
-
자바 17의 새 기능인 stream.toList() 도입
- 기존 .collect(Collectors.toList()) → 17 .toList()로 간소화
-
LTS버전 장기적으로 안정적인 지원을 제공
-
JVM의 성능 향상, 가비지 컬렉션의 개선
→ ZGC의 성능 개선, 이 가비지 컬렉터는 특히 대용량 힙을 다루는데 탁월하며, 가비지 컬렉션으로 인한 중단 시간을 최소화합니다. 이전 버전에서는 실험적이었지만, 자바 17부터는 제품 수준에서 사용할 수 있게 됨
-
최신 보안 패치 및 버그 수정
</aside>
<aside>
💡 1-2. 마이 팔도 트립에는 왜 백엔드 기술로 스프링 부트를 선택하셨나요?
- 의존성 관리: 스프링 부트는 '스타터(arter) 의존성'을 제공하여 프로젝트 설정과 관련된 복잡성을 줄여줍니다. 이로 인해 개발자는 프로젝트 설정보다는 비즈니스 로직에 집중할 수 있습니다. 스타터에는 웹mvc,jackson,validation,로깅 등 여러 의존성을 한번에 묶어서 제공
- 자동 설정(Auto-configuration): 스프링 부트는 클래스패스 설정, 다양한 설정 프로퍼티, 애플리케이션에 추가한 라이브러리 등을 기반으로 자동 설정을 제공합니다. 이를 통해 개발자는 빠르게 애플리케이션을 실행하고 개발에 집중할 수 있습니다.
- 내장 서버: 스프링 부트는 내장 Tomcat, Jetty, Undertow 등의 서버를 제공하여, 별도 WAS를 설치하고 관리할 필요가 없습니다. 이로 인해 어플리케이션의 배포과정이 간소화됩니다.
액추에이터(Actuator): 스프링 부트는 애플리케이션의 상태를 모니터링하고 관리하는 기능을 제공합니다. 이를 통해 애플리케이션의 운영 및 관리를 효과적으로 수행할 수 있습니다.
다양한 프로젝트와의 호환성: 스프링 부트는 스프링 관련 프로젝트들과의 호환성이 뛰어나며, JPA, Thymeleaf, Security 등 다양한 스프링 프로젝트를 쉽게 통합할 수 있습니다.
</aside>
<aside>
💡 1-3. RDB에서 Mysql을 고르셨는데 왜 postgre나 다른 RDB를 선택하지 않고 Mysql을 선택 하셨나요?
- 무료 사용: MySQL은 오픈소스 데이터베이스로, 상용 또는 개인 프로젝트에서 무료로 사용할 수 있습니다. 이는 초기 비용을 절약할 수 있는 큰 장점입니다.
- 풍부한 커뮤니티 지원: MySQL은 세계적으로 널리 사용되는 데이터베이스로, 풍부한 커뮤니티 지원을 받고 있습니다. 이로 인해 문제가 발생했을 때 해결책을 찾기 쉽습니다.
- 다양한 플랫폼 지원: MySQL은 다양한 운영체제에서 사용할 수 있으며, 여러 언어와 프레임워크와의 호환성이 좋습니다.
- 높은 확장성: MySQL은 레플리케이션(replication)과 샤딩(sharding) 등의 기능을 통해 데이터베이스의 확장성을 높일 수 있습니다.
- 레플리케이션은 데이터베이스의 복사본을 여러 서버에 분산시키는 기술입니다. 주로 읽기 쿼리의 성능을 향상시키고, 데이터의 안정성을 보장하는 데 사용
- 딩은 데이터를 여러 데이터베이스에 분할하여 저장하는 기술입니다. 샤딩은 대량의 데이터를 처리하거나, 쓰기 쿼리의 성능을 향상시키는 데 유용
- 편리한 관리 도구: MySQL Workbench와 같은 시각적인 관리 도구를 제공하여, 데이터베이스 관리를 더욱 편리하게 할 수 있습니다.
</aside>
<aside>
💡 (인증관련해서 stateless로 구현했을 경우) 왜 그렇게 구현 하셨나요?
- 확장성: 각 요청이 독립적이므로, 서버의 확장성이 향상됩니다. 즉, 추가적인 사용자 요청을 처리하기 위해 서버를 추가하거나 확장하는 것이 쉽습니다.
- 서버 자원 절약: 서버가 사용자의 상태를 추적하거나 저장할 필요가 없으므로, 서버의 메모리를 절약할 수 있습니다.
- 로드밸런싱 쉬움: 상태가 없는 요청은 어떤 서버에서도 처리할 수 있으므로, 로드 밸런싱이 더욱 효율적입니다.
stateful
- 추적 가능: 서버가 사용자의 세션을 추적하기 때문에, 사용자의 활동을 추적하고 분석하는 것이 쉽습니다.
- 보안: 상태를 유지하는 인증 방식은 토큰이 탈취되더라도 서버에서 세션을 관리하기 때문에, 비교적 안전합니다.
- 토큰 관리의 유연성: 서버가 세션을 관리하므로, 필요에 따라 세션을 만료시키거나 갱신하는 등의 조치를 취하기 쉽습니다.
</aside>
<aside>
💡 코스 좋아요 기능이 있는데 (구현을 다 했을 때) 해당 구현 방식에서 하나의 코스에 동시에 100명이 좋아요를 누르면 어떻게 되나요? 문제가 생긴다면 어떤 문제가 생겼고 그 문제를 어떻게 해결할 수 있을까요?
- 저희 프로젝트에서는 100명이 좋아요를 누를 때는 디비 쿼리 자체를 원자적으로 만드는 방법: 데이터베이스 쿼리 자체를 원자적(atomic)으로 만들어, 여러 요청이 동시에 들어와도 각 요청이 독립적으로 처리되도록 합니다. 예를 들어, "좋아요" 수를 증가시키는 쿼리를 "현재 수 + 1"이 아닌, "좋아요" 행을 추가하는 방식으로 구현해서 동시성 문제가 생기지 않고, 같은 사람이 100번 누를 때 같은 유저가 같은 게시글을 여러번 좋아요를 누를 수 있는 동시성 문제가 생긴다고 생각합니다. 스프링 시큐리티 ratelimiting 을 이용하면 같은 사용자가 동시에 보내는 요청을 제한 할 수 있음
</aside>
<aside>
💡 여행 정보 목록이 2억건 정도 들어가있다고 가정 했을 때 여행 정보 목록 조회시 느려질 수 있을 것 같은데 어떻게 해결할 수 있을까요?
- 엔티티 대신 dto로 조회
- 기존 필요없는 엔티티의 필드까지 조회한 엔티티를 구한 다음 dto로 변환하는 방법보다 dto로 반환 할 필드만 조회해서 바로 반환하면 조회 성능 향상
- 페이징
- 한번에 모든 데이터를 조회하는 대신, 한번에 보여주려는 정보만 조회해서 보여줌, batchsize 이용해서 조회 개수 최적화
- 샤딩
- 병렬 처리 가능, 여러 데이터베이스에 분산 저장된 데이터를 동시에 찾으므로 빠름
</aside>
<aside>
💡 채팅 기능을 구현하셨는데 왜 샌드버드 같은SASS를 사용하지 않고 직접 구현 하셨나요? 직접 구현해야하만 하는 특별한 이유가 있을까요?
- 유연성: 직접 구현하면 프로젝트의 요구사항에 맞게 유연하게 기능을 조정하거나 확장할 수 있습니다. SaaS 제품은 일반적인 케이스를 커버하도록 설계되어 있기 때문에 특수한 요구사항을 수용하기 어렵습니다.
- 비용: SaaS 제품은 사용량에 따라 비용이 발생합니다. 직접 구현하면 초기 개발 비용은 들지만, 장기적으로 보면 비용을 절약할 수 있습니다.
- 데이터 보안과 개인정보 보호: 직접 구현하면 사용자 데이터를 외부에 노출시키지 않고 내부 시스템에서 관리할 수 있습니다. 이는 데이터 보안과 개인정보 보호에 중요한 요소입니다.
</aside>
<aside>
💡 CI/CD가 무엇이고 장점이 무엇인지 설명해주세요.
- 지속성 통합과 지속적 배포로
ci는 코드 검증에 들어가는 시간을 절약, 코드 품질 유지
cd는 자동화를 통해 개발 편의성 증가
</aside>
<aside>
💡
파일 업로드에 S3를 사용하셨는데 S3를 선택하신 이유가 있을까요?
- 사용자 커뮤니티 커서 문제가 생겼을 때 참고할 자료가 많음
- ec2,rds 등 다른 aws 기능들을 사용하고 있어서 S3와 통합 시 쉬운 사용 가능
- 저희 서비스는 게시글에 파일 업로드 후 수정될 가능성이 적기 때문에 자주 액세스하지 않는 데이터를 저렴한 비용에 저장할 수 있는 S3 Infrequent Access나 아카이브용 S3 Glacier에 파일을 저장하여 비용을 절약할 수 있음
</aside>
<aside>
💡 채팅 저장에 몽고DB를 선택 하셨는데 RDB와 비교 했을 때 어떤 이점 때문에 선택을 하셨을까요?
소
- 유연성: MongoDB는 스키마가 없는 구조로, 각 채팅 메시지에 대해 다양한 형태의 데이터를 저장할 수 있습니다. 예를 들어, 텍스트 메시지, 이미지, 이모티콘, 파일 등 다양한 타입의 메시지를 효과적으로 저장할 수 있습니다.
- 확장성: 채팅 애플리케이션은 사용자가 많아짐에 따라 데이터가 급속도로 증가할 수 있습니다. MongoDB는 수평적인 확장이 가능하여, 이런 상황에도 유연하게 대응할 수 있습니다.
- 속도: MongoDB는 빠른 읽기 및 쓰기 성능을 제공합니다. 채팅 애플리케이션에서는 실시간으로 메시지를 저장하고 읽어야 하므로, 이런 빠른 성능은 매우 중요합니다.
- 시간 순서 데이터: MongoDB는 시간 순서로 데이터를 저장하고 검색하는 데 유용한 기능을 제공합니다. 채팅 메시지는 시간 순서로 저장되고 보여지므로, 이 기능은 채팅 애플리케이션에 매우 적합합니다.
- JSON 형태의 데이터 저장: MongoDB는 데이터를 BSON(Binary JSON) 형태로 저장합니다. 이는 JSON 형태의 데이터를 효율적으로 저장하고 처리할 수 있게 해주며, 채팅 메시지와 같은 복잡한 데이터 구조를 표현하는 데 유용합니다.
</aside>
<aside>
💡 인증에 JWT를 사용했는데 JWT가 무엇인지 또 어떤 장 단점이 있는지 설명해주세요.
- JWT란 Json Web Token으로 Json 객체를 사용하여 정보를 포함하고 있는 클레임을 토큰 형태로 저장하는 방법?
- 장점
- 상태 저장이 필요 없음: JWT는 자체적으로 필요한 모든 정보를 가지고 있으므로, 서버 측에서 별도의 세션을 유지할 필요가 없습니다. 이는 서버의 부하를 줄이고 확장성을 향상시킵니다.
- 분산 세션: JWT는 쿠키와 달리, 여러 도메인 간에 안전하게 전송될 수 있습니다. 이는 마이크로서비스 아키텍처나 모바일 애플리케이션과 같이 여러 시스템 간에 인증 정보를 전달해야 하는 시나리오에서 유용합니다.
- 성능: JWT는 클라이언트에서 생성되므로, 서버에서 세션을 생성하고 저장하는데 드는 비용을 절약할 수 있습니다.
- 자체 포함: JWT는 필요한 모든 정보를 자체적으로 가지고 있으므로, 별도의 인증 저장소가 필요 없습니다.
- 확장성: JWT는 토큰에 필요한 데이터를 자유롭게 추가할 수 있다는 점에서 확장성이 좋습니다. 이는 사용자의 권한, 역할 등 세부적인 정보를 토큰에 추가할 수 있음을 의미합니다.
- 언어 독립성: JWT는 JSON 형식을 사용하기 때문에 언어 독립적입니다. 따라서 다양한 프로그래밍 언어에서 사용할 수 있습니다.
- 단점
- 크기: JWT는 많은 정보를 포함하므로, 헤더에 포함되는 쿠키에 비해 크기가 큽니다. 이는 네트워크 부하를 증가시킬 수 있습니다.
- 보안: JWT는 클라이언트에서 생성되므로, 토큰이 탈취되면 사용자의 인증 정보가 유출될 수 있습니다. 이를 방지하기 위해 HTTPS 등의 안전한 채널을 통해 토큰을 전송해야 합니다.
- 로그아웃: JWT는 상태가 없으므로, 일반적인 방법으로는 사용자의 로그아웃 상태를 서버에서 추적할 수 없습니다. 사용자가 로그아웃하면 토큰이 무효화되지 않고 계속 유효하기 때문입니다.
</aside>
<aside>
💡 queryDsl의 장점과 도입한 이유를 설명해주세요.
- 문자가 아닌 코드로 쿼리를 작성해서 문법 오류를 찾기 쉬움, IDE의 도움을 받을 수 있어서 컴파일 시점에 오류 발견 가능
- 복잡한 쿼리 작성이 쉬움
- Querydsl을 통해서 동적 쿼리를 생성하는 방식이 Spring Data Specification에 비해서 가독성이 더 좋음
- BooleanExpression, OrderSpecifier<?>을 이용해 동적 쿼리를 작성하는데 편리함과 메서드 분리와 적절한 메서드 네이밍을 통해 코드 가독성을 향상 시킴
- 메서드 분리를 통한 재사용성 향상
- 저희 서비스에서는 동적 쿼리를 이용하는 목록 조회 기능 다수 포함하고 있어서 이를 개발하는데 드는 비용을 줄일 수 있고 문법 오류를 자동으로 찾아줘서 검증에 대한 시간 절약하고, 복잡한 조건 조회 시 쿼리 작성을 수월하게 할 수 있을 것으로 예상해서 도입
</aside>