질문[1]:
기존의 단순 반복문 방식과 비트마스킹 방식을 비교할 때, 성능이 개선된 이유를 코드 구조적 관점에서 설명해보세요.
대답[1]:
기존 중첩 반복문이 여러 개 사용되어 각 반복문이 독립적으로 n번씩 수행되는 방식이며, O(n^5)의 시간이 소요되었습니다.
반면 비트마스킹 방식을 도입함으로써 시간 복잡도를 O(n^2)로 줄일 수 있었습니다. 비트마스크를 활용하여 정수 하나로 팀 구성 정보를 표현하고, 각 비트를 이용해 팀 구성을 구분하였습니다.
질문[2]:
기존의 백트래킹 방식과 비트마스킹 방식을 비교할 때, 성능이 개선된 이유를 코드 구조적 관점에서 설명해보세요.
대답[2]:
기존 백트래킹 방식에서는 재귀호출로인한 스택메모리의 사용, 입력값이 커지면 오버헤드가 발생될 수 있는 우려가 있었습니다. 또한 단순하게 모든 경우의수를 찾기만 하면되었기 떄문에 백트래킹 보다는
비트마스킹 방식을 도입하여, 각 팀원들을 하나의 비트로 계산하여 더욱 효율적으로 찾을 수 있었습니다
질문:
MyBatis의 네이티브 쿼리를 활용하여 JPA 대비 쿼리 수를 줄인 방식에 대해 설명하고, 쿼리 수를 줄이는 것이 성능에 어떤 영향을 미치는지 기술적으로 설명해보세요.
대답:
기존에 리스트 형태의 데이터를 saveAll로 저장하다 보니, 각 데이터가 개별적으로 저장될 때마다 다중의 INSERT 쿼리가 발생하였고, 이로 인해 네트워크 I/O 비용이 증가되었습니다.
이를 MyBatis의 foreach를 활용한 배치 인서트로 개선하여,
기존 38번의 쿼리 호출을 3번의 쿼리 호출로 최적화하였습니다.
질문:
Look Aside와 Write Around 캐싱 전략의 차이를 설명하고, 왜 Look Aside를 선택했는지 구체적인 사용 사례를 들어 설명해주세요.
대답:
Look Aside: 캐시 히트시 캐시 데이터 반환, 캐시 미스시 DB에서 조회후 데이터 반환
Write Around: 캐시 미스시 DB에 캐시에 데이터 저장, 맨처음 요청이 들어올때 항상 DB에 저장
각 유저는, 10명의 플레이어들끼리 서로 대전한 히스토리를 불러올 수 있습니다
해당 히스토리는 항상 DB에 저장되고, 히스토리를 불러올일이 잦다고 판단하여 캐시를 활용하여 네트워크 레이턴시를 낮추는데에 초점을 두었습니다
질문:
Redis의 List 자료구조를 이용한 큐 기반 순차 처리 방식에서, 동시성 문제가 해결된 원리를 설명하고, 이 방식을 적용할 때 고려해야 할 트레이드오프는 무엇인가요?
대답:
여러개의 서버에서 동시에 하나의 회사에 매칭 할 수 있었습니다
이를 순서있게, 동시성문제가 발생되지않게 해결해야 하였기 때문에
Redis의 싱글쓰레드 특성을 활용하여 클라이언트의 요청들을 Redis의 LeftPush를 활용하여 Queue방식으로 하나씩 꺼내어 처리하는 방법으로 해결할 수 있었습니다
하지만 queue방식을 도입함으로써, 클라이언트의 요청량이 많다면 응답속도가 지연될 수 다는 단점이 있습니다
질문:
TTL을 사용하는 캐싱 시스템에서 데이터 불일치가 발생할 수 있는 상황을 설명하고, 이를 어떻게 방지할 수 있는지 설명해주세요.
대답:
TTL주기동안 살아있는 캐시데이터가 존재할때, DB의 데이터가 수정되어버린다면 데이터 불일치 문제가 발생 할 수 있습니다
데이터 정합성문제에 대해 예민하게 다루어져야 하는 문제라면 아예 Wrtie Through 방식을 도입하여 항상 캐시에 먼저 저장된후, DB에 저장하는 방식으로 방지 가능합니다
또는 DB의 내용이 수정될때 캐시 무효화 전략도 사용 가능합니다
질문:
S3 업로드 과정에서 비동기 처리와 메모리 관리를 어떻게 최적화했는지, 해당 방식이 메모리 사용량과 사용자 경험에 미치는 영향을 설명해보세요.
대답:
사용자가 100개의 파일을 첨부하기까지의 시간이 상당 소요되어, 해당 처리가 될떄까지 기다린후 응답을 보내자니 사용자의 UX측면에서 손실이 발생하였습니다
따라서 S3파일 첨부는 백그라운드의 서브쓰레드에서 돌아가게끔 진행하여, 응답속도를 개선 할 수 있었습니다
질문:
내전 팀 구성 로직에서 단일 책임 원칙(SRP)을 적용한 구체적인 사례를 설명하고, 이를 적용함으로써 코드 유지보수성에 어떤 이점을 얻었는지 설명해주세요.
대답:
단일 책임 원칙이란, 무언가 변경되야할떄 그 이유는 하나여야 한다는 뜻입니다
초기 로직에는 하나의 클래스안에 팀을 무작위로 나누는 로직, 밸런스 맞추는 로직 등이 여러가지 섞여 있었지만, 이를 SRP원칙에 맞게 수정한결과
밸런스가 이상할때는 밸런스 클래스만, 팀이 이상하게 나뉘어 질때는, 팀을 나누는 클래스만 조작하여 획기적인 이점을 얻을 수 있었습니다
또한 각각의 클래스들로 구분하여 개발하니, AOP도 유용하게 사용할수 있어 좋았습니다
질문:
대규모 트래픽을 처리할 수 있는 플랫폼을 설계할 때, 데이터베이스, 캐시, 비즈니스 로직 계층을 어떤 기준으로 나누고 설계했는지 설명해보세요.
대답: