# 질문리스트
[좋은 사이트](https://github.com/JaeYeopHan/Interview_Question_for_Beginner)
## DB 관련
Q. apache 보다 nginx 가 가벼움. node 자체 서버가 더 복잡함. 서로 장단점이 무엇인지 판단하기!
A-원호. A. Nginx 가 서버의 부담이 상대적으로 적기 때문입니다. 요청당 쓰레드 또는 프로세스가 처리하는 구조인 아파치( 쓰레드와 프로세스가 많아질수록 CPU 를 많이 사용한다 ) 보다 비동기 이벤트 기반으로 요청하기 때문에 서버의 부담이 덜가서 사용했습니다.사용이 매우 심플하고 규모가 작은 서비스이면서 정적 데이터 처리가 많은 서비스에 적합합니다.
A-석민. 먼저 apache의 확장모듈이 압도적으로 많지만, 그 중 사용하지 않아서 메모리만 먹는 모듈이 많습니다. 또한 아파치의 쓰레드/프로세스 구조는 많은 사용자가 접속할 시 메모리를 많이 먹으며, nginx의 비동기 이벤트 핸들러 방식은 하나의 요청을 하나의 이벤트로 관리합니다. 따라서 메모리 누수가 적어서 현재 특별한 이유가 없으면 nginx를 사용하는 추세이기에 nginx를 사용하였습니다.
Q. noSQL은 왜 읽기쓰기에 좋다
A-원호. 일단 대용량 쓰기를 할 때 NoSQL 이 유리하다. 특히 로그나 오류 내역같은 것은 앞으로 수정될 일이 없으니 일관성을 지켜줄 필요가 없기 때문에, 대용량 쓰기에 중요한 NoSQL 을 선택한 것이다.데이터가 애플리케이션이 필요로하는 형태(JSON같이)로 저장되어 읽는 속도가 빠르다. ACID 를 위해 transcation을 안지켜도 된다.
실제로 데이터를 넣어보는 실험을 했는데. Insert 는 약간 바른 정도고 Select는 은근 차이가 난다.
Q. noSQL이 SQL보다 빠른이유
A. 수직적확장(성능 향상)의 경우 비용문제, SQL은 분산저장을 지원하지 않는 경우가 많다.(수평확장x => 여러개의 장치에서 동시처리)
Q. 왜 저런 설계가 나오게 되었나요 ?
A-원호. NoSQL 인 MongoDB를 RDBMS 처럼 생각하고 Issue 를 만드는 부분에서 레퍼런스를 정의해서 그렇습니다.
A-석민. 처음 MongoDB를 써보게 되어서 설계 방식을 익숙한 관계형 데이터 베이스로 짜게 되었습니다. 그래서 익숙한 관계형처럼 설계를 하되 이로 인해서 생길 수 있는 단점을 확실히 알고자 하였습니다.
Q. 실제로 사용해보니 어떤 단점이 있나요?
A-석. 먼저 수정 및 삭제의 경우 관계형 데이터베이스와 비슷하게 로직이 단순하지만, populate라는 함수를 사용하여 join로직을 쓰게 됩니다. 이는 여러 collection을 참고해야 되기 때문에 성능저하가 급격히 커집니다. 따라서 관계형이 많이 필요한 데이터베이스일 경우 설계 이후로 mongoDB보단 MySQL을 선택해야 합니다. 하지만 join이 적게 일어나는 경우에는 mongoDB의 빠른 읽기 쓰기 속도를 이용하여 더 빠른 서버를 운영하는 것이 효과적이라고 생각합니다.
추가설명:
populate: projectId = ref: 'project'
projectId: 623r39rfj329f23fj9,
populate('projectId')
projectId: {
_id: 623r39rfj329f23fj9,
name: 'firstProject'
}
Q. SQL 대신 NoSQL을 사용할 상황은 어떨 경우일까요?
A-. 수정삭제보다 읽기쓰기가 자주일어나고 , 일관성을 처리속도와 충분히 Trad Off 가능한 경우에 사용하면 NoSQL이 빠를 것 같습니다. 저희 서비스 처럼 많은 로그와 오류들이 넘어오고 그 데이터들을 수정할 일이 없는 상황에서 좋은 것 같습니다.
A-석: ERD 설계 후 자신에게 맞는 디비를 선택해야 합니다. 관계가 많이 생기는 DB의 경우 관계형 데이터베이스를 사용하는게 더 좋습니다. 하지만 관계보다 읽기쓰기가 더 많이 생기는 경우에는 속도가 빠른 NoSQL을 사용하는 것이 좋습니다.
NoSQL과 SQL을 같이 쓰는 방법도 존재합니다.
Q. 인덱스 방식을 쓰셨는데, 인덱스의 장단점을 명확히 알고 계신가요?
A-석. 자세한 정보는 좋은사이트 참고, 인덱스 방식을 사용할 경우 기존에 find 로직의 시간복잡도가 n에서 log n 으로 줄어드는 장점이 있습니다. (이거 정확히 설명하기 왜 줄어드는가?), 하지만 인덱스를 설정하게 되면 객체 하나하나(noSQL에서는 도큐먼트)의 크기가 커진다는 단점이 있습니다. 따라서 find를 많이 사용하는 부분에 인덱스를 추가하여 시간적 효율과 공간적 효율을 동시에 잡는것이 좋습니다.
Q.트랜잭션 대신에 인덱스를 통한 해결을 하셨는데, 트랜잭션은 어떤 상황일 때 사용할 예정이신가요?
A-석. NoSQL에서는 최대한 트랜잭션 사용을 자제할 계획입니다. 빠른 성능 때문에 사용하는데 트랜잭션을 사용할 경우 이 목표를 이루기 힘듭니다. SQL은 공부하기! (좋은 사이트에 있습니다.)
Q. 왜 MongoDB 동시에 읽기가 가능한가요?
A-석. 동시 읽기가 불가능할경우 트랜잭션을 이용하는것과 비슷하다고 볼 수 있습니다. 이로 인해서 성능이 저하되는 것은 당연한 원리이며, 동시 쓰기가 필요한 로직의 경우 findOneAndUpdate와 같은 함수를 통해서 동시성 문제를 해결할 수 있습니다.
추가공부: findOneAndUpdate와 같은 함수의 원리 ???
A-원.
Q. 왜 쓰기를 할때는 동시에 되지않고 순차적으로 진행되었을까요 ??
(이슈가 4개 생기는 문제)
A-석. 서버에서 mongoDB로 저장될 때 로직은 다음과 같습니다.
메모리상(서버)에서 document생성 (new DB) => save() 로직을 통해서 DB로 저장.
따라서 save()전에 다른 쓰레드 및 서버에서 findOne을 통해 없다는 것을 인지해서 생성 로직을 불러옵니다.
Q. Lock 을 걸어서 해결하면 왜 처리속도가 느려지나요 ??
A-석. 저희서버는 클러스터링을 통해 4개의 작업이 동시에 진행되도록 설계하였습니다. 하지만 Lock을 걸어 해결할 경우 4개의 서버가 운영되는 것이 아닌 1개의 서버가 운영되는 것과 비슷한 개념이 되기 때문에 성능이 느려질 수 밖에 없습니다.
https://chrisjune-13837.medium.com/db-lock-%EB%9D%BD%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-d908296d0279
https://lucas.codesquad.kr/boostcamp-2020/course/%EA%B7%B8%EB%A3%B9-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8/%EB%B0%B1%EC%97%94%EB%93%9C-%ED%95%99%EC%8A%B5%EC%9E%90%EB%A3%8C/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98
## 서버 관련
Q. 스레드와 프로세스의 차이?
A-석.
1-프로그램상의 쓰레드와 프로세스 개념(크롬과 파이어폭스의 차이)
먼저 쓰레드와 프로세스의 차이는 공유자원을 사용하는가 아닌가로 구분할 수 있습니다. 일단 쓰레드는 한 프로세스안에서 공유자원을 정해두고 그것을 이용해 여러 쓰레드를 만듭니다. 하지만 프로세스의 경우 공유자원을 두지않고 독립적으로 동작합니다. 대표적인 예로 파이어폭스와 크롬의 탭을 예로 들 수 있습니다. 파이어폭스는 하나의 프로세스의 여러개의 쓰레드 형식으로 탭을 만듭니다. 이로인해 크롬에 비해 적은 램을 사용하지만, 하나의 탭에 문제가 생겼을 경우 같이있는 모든 탭을 강제로 종료해야 되는 상황이 발생합니다. 반대로 크롬의 경우 그런 문제는 없지만, 아시다시피 램을 많이 먹는것으로 유명합니다.
2-CPU상의 프로세스와 쓰레드 개념
프로그램상의 쓰레드와 프로세스 개념과 비슷합니다. 대체로 하이퍼쓰레딩을 지원하는 경우 4코어 8쓰레드와 같이 표기를 합니다. 저희 백엔드 서버는 하이퍼쓰레딩이 지원되지않는 CPU이기 때문에 4코어에 맞춰 4개의 앱을 실행 하도록 하였지만, 만약 하이퍼쓰레딩이 지원되는 모델일 경우 클러스터링 기능을 쓸경우 8개의 앱을 실행하였을 것입니다.
Q. passport를 제거하신 이유가 있을까요?
A-석. 서버테스트를 통해서 Login 로직이 압도적으로 느리다는것을 발견 하였습니다. 저희는 처음에 원인으로 Passport때문에 느린 것이라고 생각했습니다. 디버그를 걸어서 확인할 경우 Passport에 거치는 부분이 많기 때문입니다. 하지만 결국 원인은 bcrypt를 사용해서였고, 최고의 보안을 위해서는 성능이 어느정도 희생되기 때문에 저희는 saltRound를 조금 낮춰서 성능상 이점을 챙겼습니다.
Q. 로그인이 유지되는것은 어떻게 확인하시나요 ?
A-원호. local Storage 에 Json Web Token 을 저장하고 있어서 이것을 Admin 에 API 를 이용할 때마다 계산해서 사용하고 있습니다. 이는 서버가 stateless 한 상태를 유지하고 싶어서 로그인한 정보를 server 에 저장하고 싶지 않아서 입니다.
Q. Local Storage 와 cookie 의 차이.
A-석. 먼저 Local Storage의 경우 브라우저 내 저장소라고 이해하시면 쉽습니다. 필요할 때 선택적으로 꺼내쓰고, 삭제가 가능합니다. 또한 저장 공간이 cookie에 비해 1000배가량 높습니다. (쿠키 4kb, 로컬스토리지 약5MB). 반면 쿠키는 모든 request마다 자동적으로 따라오게 되며 필요한 경우 no-cookie를 통해 쿠키를 못보내게 할 수 있지만 선택적으로 못보내게 하는 경우 로직이 복잡해집니다. 또한 쿠키와 CORS와 조합은 최악에 가까워서 최근에는 Local Storage를 많이 사용합니다.
Q. 만약에 토큰이 만료되면 어떻게 처리하시나요 ?
Q. exec() 를 굳이 넣으신이유가 뭔가요?
Q. Webpack을 서버에 적용하셨는데 어떤 이유인가요?
Q. 서버의 구조는 어떻게 하였는지?
Q. 왜 그런 구조로 구성하게 되었는지 ?
Q. 테스트 코드 구성을 어떻게 하였는지 ?
## SDK
Q. 만약 다른 언어의 플랫폼을 늘린다면 어떤 방식으로 할 것 인가.
Q. multi-repo와 mono-repo중에 mono-repo를 선택하셨는데, 어떤상황일때 당신은 mono-repo대신 multi-repo를 선택해서 개발할 것인가요?
A. 현재 플랫폼을 볼 경우 node / browser 같이 공통기능을 공유하는 패키지일 경우 모노레포가 더 어울립니다. base-santry 같은 경우 모든 플랫폼이 공유하기 위해 추상클래스로 제작하는등 base-santry를 기준으로 플랫폼이 구성됩니다. 하지만 하나의 패키지가 방대해진다는 문제점이 발생합니다. express와 koa를 예시로 둘 수 있습니다. koa는 express와 다르게 router모듈을 따로 설치합니다. 즉 koa는 express 자체를 muilti-repo로 관리한다고 생각하면 편할 듯합니다.
Q. TypeScript 로 개발하였는데 이것이 SDK 의존성에 문제를 주지않는가 ?
Q. 추상클래스와 인터페이스의 차이
Q. lerna 개념을 이해하는 게 어렵다
## admin
Q. 어떤 구조로 짜게 되었는가 ?
api/common/page/store/theme/util
page- container/presenter
material ui를 사용하다보니 이미 어느정도 atom-molecule 형태의 컴포넌트들이 있는 상황이었고
이를 조합하는 것이기 때문에 page단위의 분리가 적당하다고 생각했다.
해당 page 안에서 컴포넌트가 중복되어 재사용할 수 있다거나 분리하여 해당 컴포넌트 내에서만 상태를 관리할 필요가 있는 부분들은 추가적으로 component 폴더를 만들어 관리하였다.
Q. 여러 로딩 스타일이 있는데 왜 원형 프로그레스로 하였는가 ?
Q. redux, redux-thunk ? redux 에 대해서 잘 아나요?
redux
## 보류
Q. 저런 설계가 아니면 어떻게 설계 해야 더 효율적일까요?
A. 최근에 join로직이 나와서 관계형으로 설계가 가능하지만 성능상 이점은 높지 않습니다.
Q. 웹팩 번들된 코드.
Q. Nginx 를 사용한 이유.
A. Nginx 가 서버의 부담이 상대적으로 적기 때문입니다. 요청당 쓰레드 또는 프로세스가 처리하는 구조인 아파치( 쓰레드와 프로세스가 많아질수록 CPU 를 많이 사용한다 ) 보다 비동기 이벤트 기반으로 요청하기 때문에 서버의 부담이 덜가서 사용했습니다.사용이 매우 심플하고 규모가 작은 서비스이면서 정적 데이터 처리가 많은 서비스에 적합합니다.
## Node
Node 자바스크립트 런타임
Node 는 하나의 쓰레드, 32bit에서는 512MB 메모리, 64Bit 1.5GB 메모리 ( V8 엔진 성능에 따라서
)
cluster 동작 원리.
Node 는 싱글 쓰레드 이다. 이때 cluster manager 가 fork 를 한다.
In the context of clustering, you first need to be sure that your application has no internal state.
Use Redis or other databases instead to share the states between processes.
# sdk 버전문제
생각해보자.
# lerna script root 에 대해서
생각해보자.
# server 코드 웹팩 사용하기
오브젝트 참조 에러날 수 있음
tsc 쓰는게 좋지 않았을까 ?
# admin ts-loader , babel-loader
같이 쓴 이유
# findone
에러 이슈의 중요도
### 공통
- dotenv 를 활용해서 환경변수를 설정하는 것을 확인했는데요. .env 파일들이 저장소내에 존재하지 않아서 빌드 및 실행이 안되는 케이스들이 있다.
- Test 를 수행하는데 Test coverage 값은 어느 정도인지?
- eslint, prettier, jest 를 이용한 test 를 수행하고 있는데 이를 pull request 시에 강제할 수 있도록 CI 서버와의 연동을 수행하고 있는지?
### SDK
- locking(.lock) 파일이 gitignore 에 들어가있는데 이유가 있을까요? dependency 내 ^(캐럿)으로 버전명시를 해두어서 프로젝트 참여자들간의 설치 모듈 버전이 달라질 수 있어보인다. 이로 인해 개발자간 설치 모듈 버전이 상이한 상황이 연출될 수 있음.
- definition 파일내 init, captureError function 의 두번째 param 이 필수로 선언되어있는데 admin 쪽에서 프로젝트 생성후 전달해주는 가이드에서는 두번째 파람에 대한 정보가 없다.
### Admin
- 에러를 한번 발생시켰는데 동일 에러에 대한 알람 메일이 여러번 날라오는 것이 확인됨.
- 에러 알람의 내용이 단순 에러가 발생했다라는 텍스트만이 있는데 에러와 관련된 추가 정보들이 좀 더 포함되는 것이 좋지 않을지?