1. 프록시란 무엇인가요 ?
- 포워드 프록시 (클라이언트) :
- 리버스 프록시 (서버) :
2. context switch란 무엇인가요 ?
- 멀티프로세스 환경에서 cpu가 한 프로세스를 실행하고 있는 상태에서 인터럽트 요청에 의해 다른 프로세스가 실행되어야 할 때, 기존 프로세스 상태 또는 레지스터 값을 저장하고 cpu가 다음 프로세스 수행을 위해 새로운 프로세스 상태 또는 레지스터 값으로 교체하는 작업을 context switching이라고 합니다.
- 간단 설명 : context swith를 담당하는것은 운영체제의 핵심 구성 요소 중 하나인 커널입니다. cpu는 하나의 프로세스만 실행 가능합니다. cpu에서 실행되고 있는 프로세스나 스레드를 다른 프로세스나 스레드로 스위칭 하기 위해 변경하는 과정입니다. 운영체제는 멀티테스킹 환경을 제공하기에 하나의 프로세스나 스레드만 실행 가능한 cpu를 멀티태스킹을 지원하기 위해 빠르게 여러 프로세스간의 전환이 이루어져야 합니다.
* 인터럽트 - cpu가 프로그램 실행하고 있을 때 실행중인 다른 프로그램에서 예외 상황이 발생하여 처리가 필요한 경우 cpu에게 알려 예외 상황을 처리할 수 있도록 하는 것을 말합니다.
*context - 단어 뜻 그대로 문맥이라는 뜻이 아닙니다. 여기서는 cpu가 해당 프로세스를 실행하기 위한 해당 프로세스 정보들을 가리킵니다.
3. 커널의 역활이 무엇인가요 ?
1. 프로세스 스케줄링
- 커널은 시스템에서 실행중인 여러 프로세스를 관리합니다. 스케줄러를 사용하여 어떤 프로세스가 언제 cpu를 사용할 지를 결정합니다.이때 프로세스 상태 체크 후, 각 프로세스가 필요로 하는 자원을 할당합니다.
2. 상태 저장
- context switch가 발생하면, 현재 실행중인 프로세스의 레지스터 값, 프로그램 카운터(PC), 스택 포인터, 메모리 정보 등을 저장합니다. 커널은 이 정보를 프로세스 제어 블록(PCB)에 저장합니다.
3. 저장해둔 프로세스 가져옴
- 커널은 실행할 새 프로세스의 PCB를 찾아 해당 프로세스의 상태를 복원합니다. 이때 저장된 정보(레지스터 값, 프로그램 카운터 등)를 복원하여 프로세스가 중단된 지점부터 실행을 재개할 수 있도록 합니다.
컨텍스트 전환이 발생하는 상황
컨텍스트 전환은 여러 가지 상황에서 발생할 수 있습니다:
- 타임슬라이스(Time-slice) 종료: 프로세스가 할당된 CPU 시간을 다 사용한 경우.
- 프로세스 우선순위 변경: 우선순위가 높은 프로세스가 실행되어야 할 때.
- I/O 작업: I/O 요청을 처리하는 동안 다른 프로세스가 CPU를 사용할 수 있도록 전환될 수 있습니다.
- 시스템 호출 또는 인터럽트: 운영 체제의 요청이나 하드웨어 인터럽트로 인해 컨텍스트 전환이 발생할 수 있습니다.
4. Critical Section(임계영역)이 무엇인가요 ?
- 프로세스간 공유자원에 접근하는데 문제가 발생하지 않게 하기 위해서 한번에 하나의 프로세스만의 이용하도록 다른 프로세스의 접근을 제한하는 영역입니다.
5. 데드락이 무엇인지를 설명하고 데드락이 걸리는 코드와 해결 방안을 말해보세요.
- 데드락이란, 여러 쓰레드가 lock을 서로 잡고 있어서 풀거나 새로 얻지 못하는 교착상태를 의미합니다.
ex)
int sum = 0; // 공유자원
mutex mutexA;
mutex mutexB;
void A() {
for (int i = 0; i < 100; i++) {
mutexA.lock();
mutexB.lock();
++sum;
mutexA.unlock();
mutexB.unlock();
}
}
void B() {
for (int i = 0; i < 100; i++) {
mutexB.lock();
mutexA.lock();
--sum;
mutexB.unlock();
mutexA.unlock();
}
}
int main()
{
thread t1(A);
thread t2(B);
t1.join();
t2.join();
cout << sum << endl;
}
- 해결방법
1. A와 B함수에서 mutex.lock 순서를 같게 해주면 오류 발생을 차단합니다.
2. std::lock함수를 사용하여 다중 뮤텍스를 한 번에 잠금하는 기능으로 데드락을 방지합니다.
6. close()와 shutdown()의 차이는 무엇인가요 ?
- 네트워크 통신을 닫기 위해서는 close()와 shutdown()을 사용합니다.
소켓을 열면 참조 카운터가 자동으로 1이 올라갑니다. 그 소켓을 자식 프로세스에서 참조해서 사용하면 카운터가 하나씩 올라가는데,
close()는 참조 카운터가 0이면 닫고 0이 아니면 열린 상태로 두고,
shutdown은 참조 카운터에 상관없이 TCP 종료 절차를 시작합니다.
다른 차이점으로는 종료할때 close()는 양방향 둘다 통신을 종료시켜 종료 후 데이터를 받을 수 없지만,
shutdown은 howto인자로 데이터 수신을 제어할 수 있습니다.
1. SD_RECEIVE
- 소켓의 입력스트림을 종료하여, 이 소켓으론 이제 데이터를 받을 수 없고 recv에 남은 buffer도 폐기 됩니다.
2. SD_SEND
- 소켓의 출력스트림을 종료하여, 이 소켓으론 이제 데이터를 보낼 수 없고 send에 남은 buffer는 모두 전송 후,
TCP연결 종료 절차가 시작됩니다.
3. SD_BOTH
- 소켓의 입출력스트림을 종료하여, 이 소켓으론 이제 데이터 송수신이 불가능 합니다.
위의 SD_RECEIVE → SD_SEND 절차를 차례로 진행합니다.
사용법 ex) shutdown(int socket_, SD_BOTH);
7. SO_LINGER란 무엇인가요 ?
- C에서 제공되는 TCP 소켓 옵션입니다. SO_LINGER를 사용하면 소켓을 닫을때 남은 데이터를 어떻게 처리 할 것 인지 조정할 수 있습니다.
struct linger
{
int l_onoff;
int l_linger;
}
위는 SO_LINGER 구조체로 l_onoff는 링거옵션 활성화/비활성화를 결정하고, l_linger 링거옵션이 활성화 될때 기다릴 시간을 결정합니다.
l_onoff = 0이면 링거 옵션 비활성화하고 default 값으로 설정 되어 있습니다. 소켓버퍼에 남아있는 모든 데이터를 전송하는 일반적인 소켓의 정상 종료가 이루어집니다.
l_onoff >0, l_linger= 0이면 close 즉시 리턴하며, 소켓버퍼 남은 데이터 전부 버리는 비정상 종료가 이루어집니다.
l_onoff >0, l_linger> 0이면 linger에 설정한 시간만큼 대기하며 남은 데이터를 전부 보내줍니다. 시간안에 데이터 전부 보냈으면 정상 종료가 이루어지고, 시간안에 전부 전송이 안되면 에러와 함께 리턴되는 비정상 종료가 이루어집니다.
8. IPv4와 IPv6의 차이점을 설명해 보세요.
- IPv4는 라우터 전송 단계에서 조각화가 가능하여 패킷 크기 조정이 가능합니다. 하지만 MTU(MAXIMUM TRANSMISSION UNIT)크기를 넘어가면 조각화 하면서 성능저하와 오류가 발생할 가능성이 있습니다.
- IPv6는 라우터에서 조각화 하지 않고, 소스 노드가 미리 MTU를 계산하여 최적화된 크기의 패킷으로 전송합니다. 성능저하와 오류를 개선하였지만 전송전 MTU 계산하는 추가 작업이 필요하고 주소가 길어서 사람들이 관리하는것이 어렵습니다.
. IOCP를 사용하는 이유를 설명해 보세요.
. 데드락에 대해 설명해보고, 예시를 하나 말해보세요.
. OverLapped Io가 무엇인가요 ?
. 뮤텍스 세마포어 크리티컬 섹션에 대해 아는대로 설명해 보세요.
'면접준비' 카테고리의 다른 글
[C++] 자료구조, 알고리즘 공부 (2) | 2024.09.07 |
---|---|
[DB] 데이터베이스 공부 (1) | 2024.09.05 |
[C++] C++ 공부 (0) | 2024.09.02 |