CS면접 대비

주홍영·2022년 5월 1일
0

면접

목록 보기
3/4

정적 바인딩(static binding)이란? / 동적 바인딩 (dynamic binding)이란?

+) 바인딩(binding)
함수를 만들어 컴파일을 하면, 각각의 코드가 메모리 어딘가에 저장된다.
그리고 함수를 호출하는 부분에는 그 함수가 저장된 메모리 번지 즉, 주소값이 저장된다.
프로그램 실행 → 함수 호출 → 함수가 저장된 주소로 점프 → 함수 실행 → 원래 위치로
위 과정에서 함수를 호출하는 부분에 함수가 위치한 메모리 번지로 연결시켜주는 것을 바인딩이라고 한다.
쉽게 말해, 함수의 호출부와 정의부를 연결시켜주는 것이 바인딩이라고 할 수 있다.

정적 바인딩(static binding)이란?
컴파일 타임에 호출될 함수가 결정되는 것으로, 함수는 기본적으로 정적 바인딩된다. 컴파일러는 선언되어있는 자료형을 보고 바인딩을 하기 때문에 실제로 가리키는 객체가 무엇이든 포인터의 자료형을 기반으로 호출의 대상을 결정한다.

동적 바인딩(dynamic binding)이란?
런타임에 호출될 함수가 결정되는 것으로, virtual 키워드를 통해 동적 바인딩하는 함수를 가상 함수라고 한다. 함수가 가상 함수로 선언이 되면, 포인터 변수가 실제로 가리키는 객체에 따라 호출의 대상이 결정된다.
(가상 함수 호출 → vptr를 통해 vtable을 찾아감 → 실제 호출 되어야할 함수의 위치 정보를 찾아 호출)

  1. 벡터 vs 리스트
    벡터는 배열기반 구조이고 list는 노드 기반 방식이다
    배열의 경우에는 임의 접근에 유리함, list는 하나씩 거쳐서 찾아야 됨
    list의 경우 중간 삽입 삭제가 편리함 그리고 capacity를 고려하지 않아도 됨

  2. c# dictionary, c++ map
    dictionary는 해쉬테이블 구조이고, map은 레드블랙 이진트리로 되어있어 탐색 속도에서 차이가 날 수 있다. dictionary는 map보다 빠르지만 메모리를 좀 더 차지하고, map은 dictionary보다 조금 더 느리지만 메모리를 덜 차지한다

가비지 컬렉터

  1. C++ vs C# - 유니티
    유니티에서는 C#스크립트를 사용하고 있기 때문에 C++과는 다른점이 많다. 대표적인 이유로 가비지 컬렉터가 있다. C++에서는 가비지 컬렉터가 없고 포인터가 있기 때문에 할당을 해주면 반드시 해제를 해줘야되고, C#에서는 가비지 컬렉터가 알아서 해제를 해주기 때문에 해제를 안해줘도 된다.
    C#에서는 포인터가 없고 class로 생성하게 된다면 Reference(참조)형 타입이 된다는 특징이 있다. 그래서 참조 접근을 많이하며 처음에 구조체를 만들 때 (struct인지 class인지)신중해야 한다

프로세스 스레드

https://gmlwjd9405.github.io/2018/09/14/process-vs-thread.html

아래 사이트에 자세하게 정리되어 있음
https://velog.io/@raejoonee/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C%EC%9D%98-%EC%B0%A8%EC%9D%B4

프로그램이란 : 어떤 작업을 위해 실행할 수 있는 파일

프로세스란

  • 컴퓨터에서 연속적으로 실행되고 있는 컴퓨터 프로그램
  • 메모리에 올라와 실행되고 있는 프로그램의 인스턴스(독립적인 개체)
  • 운영체제로부터 시스템 자원을 할당받는 작업의 단위

할당 받는 시스템 자원의 예

  • CPU 시간
  • 운영되기 위해 필요한 주소 공간
  • Code Data Stack Heap의 구조로 되어 있는 독립된 메모리 영역

특징

  • 프로세스는 각각 독립된 메모리 영역(Code, Data, Stack, Heap의 구조)을 할당받는다.
  • 기본적으로 프로세스당 최소 1개의 스레드(메인 스레드)를 가지고 있다.
  • 각 프로세스는 별도의 주소 공간에서 실행되며, 한 프로세스는 다른 프로세스의 변수나 자료구조에 접근할 수 없다.
  • 한 프로세스가 다른 프로세스의 자원에 접근하려면 프로세스 간의 통신(IPC, inter-process communication)을 사용해야 한다.

스레드(Thread)란?

  • 프로세스 내에서 실행되는 여러 흐름의 단위
  • 프로세스의 특정한 수행 경로
  • 프로세스가 할당받은 자원을 이용하는 실행의 단위

특징

  • 스레드는 프로세스 내에서 각각 Stack만 따로 할당받고 Code, Data, Heap 영역은 공유한다.
  • 스레드는 한 프로세스 내에서 동작되는 여러 실행의 흐름으로, 프로세스 내의 주소 공간이나 자원들(힙 공간 등)을 같은 프로세스 내에 스레드끼리 공유하면서 실행된다.
  • 같은 프로세스 안에 있는 여러 스레드들은 같은 힙 공간을 공유한다. 반면에 프로세스는 다른 프로세스의 메모리에 직접 접근할 수 없다.
  • 각각의 스레드는 별도의 레지스터와 스택을 갖고 있지만, 힙 메모리는 서로 읽고 쓸 수 있다.
  • 한 스레드가 프로세스 자원을 변경하면, 다른 이웃 스레드(sibling thread)도 그 변경 결과를 즉시 볼 수 있다.

멀티 프로세스와 멀티 스레드의 차이

멀티 프로세스 (멀티 태스킹)

하나의 운영체제 안에서 여러 프로세스가 실행되는 것을 의미한다
장점

  • 여러 개의 자식 프로세스 중 하나의 문제가 발생하면 그 프로세스만 죽는 것으로 다른 프로세스로 영향이 확산되지 않는다

단점

  • context switch에서 오버헤드
    프로세스의 경우 서로 독립적인 메모리 공간이므로 context switching에 비용이 많이 들어간다

참고 Context switching이란?
CPU에서 여러 프로세스를 돌아가면서 작업을 처리하는데 이 과정을 context switching이라고 한다
구체적으로 동작 중인 프로세스가 대기를 하면서 해당 프로세스의 상태를 보관하고, 대기하고 있던 다음 순서의 프로세스가 동작하면서 이전에 보관했떤 프로세스의 상태를 복구하는 작업을 말한다

멀티 스레딩

하나의 응용프로그램을 여러 개의 스레드로 구성하고 각 스레드로 하여금 하나의 작업을 처리하도록 하는 것이다.

장점

  • 시스템 자원 소모 감소 (자원의 효율성 증대)
    프로세르를 생성하여 자원을 할당하는 시스템 콜이 줄어들어 자원을 효율적으로 관리할 수 있따

  • 시스템 처리량 증가 (처리 비용 감소)
    스레드간 데이터를 주고 받는 것이 간단해지고 시스템 자원소모가 줄어들게 된다
    스레드 사이의 작업량이 작아 context switching이 빠르다 (stack을 제외한 나머지 메모리 영역을 공유하므로)

  • 간단한 통신 방법으로 인한 프로그램 응답 시간 단축
    스레드는 프로세스 내의 stack 영역을 제외한 모든 메모리를 공유하기 때문에 통신의 부담이 적다

단점
주의 깊은 설계가 필요하다.
스레드 하나가 프로세스 내 자원을 망쳐버린다면 모든 프로세스가 종료될 수 있따
디버깅이 까다롭다.
단일 프로세스 시스템의 경우 효과를 기대하기 어렵다.
다른 프로세스에서 스레드를 제어할 수 없다. (즉, 프로세스 밖에서 스레드 각각을 제어할 수 없다.)
멀티 스레드의 경우 자원 공유의 문제가 발생한다. (동기화 문제)
하나의 스레드에 문제가 발생하면 전체 프로세스가 영향을 받는다.

context switching 설명

https://woo-dev.tistory.com/163
우선 이 개념은 여러 프로세스 또는 여러 스레드가 존재하는 환경에서 하나의 프로세스(스레드)만 실행되는데, 실행 중인 프로세스의 CPU 할당 시간이 끝나면 해당 프로세스를 중지시키고 다음 프로세스를 실행해야 한다. 따라서 실행 중이던 프로세스의 데이터(종료지점 등)들을 백업해두고, 다음 프로세스의 데이터를 불러오는 작업이 필요하다. 이처럼 프로세스의 데이터를 백업하고 불러오는 작업을 context switching이라 한다. 추가로 프로세스는 4개의 모든 영역이 독립적이라 저정하고 불러오는데 필요한 데이터가 많다. 반면 스레드는 3개의 영역을 공유하기 때문에 나머지 영역만 백업하고 불러오면 된다. 따라서 스레드는 프로세스 간의 context switching보다 더 적은 소요 시간을 가진다 라고 설명했음

메모리 구조 (code, data, stack, heap)

프로그램이 실행되기 위해서는 먼저 프로그램이 메모리에 로드(load)되어야 합니다
또한, 프로그램에서 사용되는 변수들을 저장할 메모리도 필요합니다.

따라서 운영체제는 프로그램의 실행을 위한 다양한 메모리 공간을 제공하고 있습니다.
프로그램이 운영체제로부터 할당받는 대표적인 메모리 공간은 다음과 같습니다.

  1. 코드(code) 영역
  2. 데이터(data) 영역
  3. 스택(stack) 영역
  4. 힙(heap) 영역

다음 그림은 운영체제가 제공하는 메모리 공간을 표현하고 있습니다.

코드영역

메모리의 코드(code) 영역은 실행할 프로그램의 코드가 저장되는 영역으로 텍스트(text) 영역이라고도 부릅니다.
CPU는 코드 영역에 저장된 명령어를 하나씩 가져가서 처리하게 됩니다.

데이터 영역

메모리의 데이터(data) 영역은 프로그램의 전역 변수와 정적(static) 변수가 저장되는 영역입니다.
데이터 영역은 프로그램의 시작과 함께 할당되며, 프로그램이 종료되면 소멸합니다.

힙(heap)영역

메모리의 힙(heap) 영역은 사용자가 직접 관리할 수 있는 '그리고 해야만 하는' 메모리 영역입니다.
힙 영역은 사용자에 의해 메모리 공간이 동적으로 할당되고 해제됩니다.
힙 영역은 메모리의 낮은 주소에서 높은 주소의 방향으로 할당됩니다.

그리고 Heap 영역은 대개 '낮은 주소에서 높은 주소로 할당(적재)됩니다'

스택(stack)영역

메모리의 스택(stack) 영역은 함수의 호출과 관계되는 지역 변수와 매개변수가 저장되는 영역입니다.
스택 영역은 함수의 호출과 함께 할당되며, 함수의 호출이 완료되면 소멸합니다.
이렇게 스택 영역에 저장되는 함수의 호출 정보를 스택 프레임(stack frame)이라고 합니다.

스택 영역은 함수를 호출 할 때 지역변수, 매개변수들이 저장되는 공간입니다. 메인(main) 함수안에서의 변수들도 당연 이에 포함되죠. 그리고 함수가 종료되면 해당 함수에 할당된 변수들을 메모리에서 해제시킵니다.

Stack영역은 Heap영역과 반대로 높은주소에서 낮은주소로 메모리에 할당됩니다.

그림을 보면 stack은 위로 가고 heap은 아래로 온다

운영체제가 사용하는 메모리 영역

운영체제 메모리 구조는 크게 유저 영역, 커널 영역으로 나뉜다

시스템 운영에 필요한 메모리, 그리고 운영체제가 커널 영역에 올라가 있는데 만약 사용자가 운영체제가 올라가 있는 커널 영역에 마음대로 접근할 수 있다면…? 시스템이 안정적으로 운용될 수 없을것이다.

그렇기 때문에 사용자가 함부로 커널 영역에 접근할 수 없도록 메모리를 유저영역과 커널영역을 나누어 사용하는 것이다. 나누는 크기는 운영체제마다 다르고, 설정에 따라 영역의 크기를 조정할 수도 있다는 점.

리틀 엔디안 빅엔디안

엔디안은 컴퓨터의 메모리에 저장되는 정보를 배열하는 방식을 뜻한다

엔디언은 보통 큰 단위가 앞에 나오는 빅 엔디언 (big-endian)과 작은 단위가 앞에 나오는 리틀 엔디언(litte endian)으로 나눌 수 있다.

메모리 주소가 커질 수록 마지막 정보를 저장하면 빅엔디안
MSB(most significant byte)부터 차례로 저장하는 방식
메모리 주소가 작아질 수록 마지막 정보를 저장하면 리틀엔디안
LSB(Least Significant bye)부터 차례로 저장하는 방식

메모리 주소가 우측방향으로 늘어난다는 가정하에
사람이 보기 편리한게 빅엔디안

x86 아키텍쳐는 리틀 엔디언을 쓰며 이를 '인텔 포맷'이라고 한다.

차이점
숫자를 비교할 때 빅엔디언은 msb 부터 써져있으므로 앞에부터 차례대로 스택에 집어 넣는 반면
리틀 엔디언은 뒤에서부터 스택에 집어 넣기 때문에 빅 엔디언보다 느리다

그러나 수치 계산시에는 리틀 엔디안이 빅 엔디안 보다 속도가 더 빠른데 낮은 자리에서부터 계산하며 올림수를 판단할 수 있기 때문이다

RISC-V는 빅엔디안 인텔 x86 아키텍처는 리틀엔디안

2's complement

덧셈 뺄셈을 할때 magnitude 고려 없이
더하기만 하면 된다
결과도 msb를 보고 양수인지 음수인지 판별한다음 보수를 구해 절대값을 구할 수 있다.

컴퓨터 구조 메모리 종류

보통 레지스터, 캐시, RAM을 주 기억장치라고 부른다. 프로그램이 실제로 구동될 때 이 세 기억장치를 사용하기 때문이다.

  • 레지스터는 제일 빠른 메모리로, CPU 계산과정의 일부로 작동한다
  • 캐시 메모리는 레지스터 다음으로 빠른 메모리로 L1, L2, L3 캐시 등 여러 단계로 나뉘어진다. 숫자가 작을 수록 용량이 작고 빠르며 숫자가 클 수록 용량이 크고 느리다
  • RAM은 매우 빠르지만 CPU > Cache > Ram 순서로 빠르다

메인메모리 = 주기억장치 = RAM

  • RAM은 Random Access Memory의 약자이다.
  • RAM은 DRAM과 SRAM이 있는데 주기억장치는 주로 DRAM을 의미한다. (SRAM은 캐시나 레지스트리)
  • 컴퓨터의 CPU가 현재 처리중인 데이터나 명령만을 일시적으로 저장하는 휘발성 메모리이다. 전원이 꺼지면 메인 메모리에 저장된 내용들은 모두 사라진다. 따라서 컴퓨터가 꺼진 이후에도 데이터를 유지하고 싶을 경우에는 데이터를 하드디스크에 저장해야 한다.
  • 보조기억장치보다 접근속도가 빠르다.
  • 모든 프로그램은 컴퓨터에서 실행되기 위해 메모리의 일부를 차지한다.

캐시

자주쓰는 데이터는 계속 자주 쓰인다

컴퓨터과학에서 증명된 법칙이다. 대부분 프로그램은 한 번 사용한 데이터를 다시 사용할 가능성이 높고 그 주변의 데이터도 곧 사용할 가능성이 높은 데이터 지역성을 가지고 있다. 이를 이용해서 OS나 CPU는 자동으로 자주 쓰이는 데이터와 자주 쓰일 것 같은 데이터를 메모리에서 캐시로 읽어온다.

메인 메모리의 데이터를 캐시 메모리에 넣어두고 필요한 데이터를 캐시에서 먼저 찾도록 할 경우 시스템 성능을 향상시킬 수 있다.

하드디스크 (HDD - Hard Disk Driver)

  • 보조기억장치
  • 사용자가 사용하고자 하는 데이터와 프로그램을 저장한다
  • 전원을 끄더라도 저장된 데이터나 정보가 날아가지 않는 비휘발성 메모리이다.

CPU - Central Processing Unit

  • 중앙 처리장치
  • 컴퓨터 내부의 모든 명령(연산)을 담당한다
  • CPU는 컴퓨터 부품 중에서 가장 빠르다,
  • 그래서 자주 쓰는 데이터들을 캐시메모리에 넣어놓고 사용하는 것이다
  • 속도 차이는 CPU > 캐시메모리 < RAM 순서이다

Register

  • CPU 안에 내장되어 있는 메모리로 CPU연산을 위한 저장소를 제공한다

추가용어
DRAM - Dynamic RAM
동적 메모리
전원이 계속 공급되더라도 주기적으로 재충전되어야 기억된 내용을 유지할 수 있다.
주로 대용량의 기억장치에 사용되며 가격이 저렴하다.
주로 RAM이라고 표현하는 것(주기억장치)은 거의 DRAM을 칭하는 것이다.
SRAM - Static RAM
정적 메모리
전원 공급이 되는 동안은 기록된 내용이 지워지지 않기 때문에 재충전이 필요없다.
접근 속도가 빠르고 가격이 비싸다는 특징이 있으며 주로 캐시메모리나 레지스터로 사용된다.

C#과 c++의 가장 큰 차이는 뭔가?

garbage collection아닐까?

Garbage Collection이란?

메모리 관리 기법 중 하나로 프로그램이 동적으로 할당했던 메모리 영역 중에서 필요없게 된 영역을 해제하는 기능이다.
즉, 동적 할당된 메모리 영역 가운데 어떤 변수도 가리키지 않는 메모리 영역을 탐지하여 자동으로 해제하는 기법이다.

장점
GC를 이용하게 되면 프로그래머가 동적으로 할당한 메모리 영역 전체를 완벽하게 관리하지 않아도 된다. 즉, GC를 통해 아래와 같은 버그를 줄이거나 막을 수 있다.

유효하지 않은 포인터 접근 : 이미 동적 할당한 메모리를 해제한 영역에 접근하게 되는 버그
이중 해제 : 이미 해제된 메모리를 또 다시 해제하는 오류를 줄일 수 있다. 대표적으로 C에서는 free()를 통해 해제하고 또 다시 free()를 하면 정상 종료 되지 않는다.

메모리 누수 : 더이상 사용하지 않는 메모리 영역을 해제하지 않고 남겨진 것이 쌓이게 되면 메모리 누수가 일어난다는 것이다. 이러한 메모리 누수가 지속되면 메모리 고갈로 인해 프로그램이 중단 될 수 있다.

단점
어떤 메모리를 해제해야 할 지 결정하는데 사용되는 알고리즘에 의해 비용이 든다. 객체가 필요없어지는 시점을 프로그래머가 알고 있는 경우에도 GC 알고리즘이 메모리 해제 시점을 추적해야하기에 비용이 들게된다.

GC가 행동하는 타이밍이나 GC의 점유 시간을 사전에 예측하기 어렵기에 실시간 시스템에는 적합하지 않다.
할당된 메모리가 해제되는 시점을 알 수 없게 된다.

컴퓨터 구조 파이프라이닝 이유

instruction을 세분화 시켜서 연산자원을 최대한 효율적으로 사용하기 위한 방법
fetch decode execute writeback 등의 stage가 있을 때
연산에 필요한 클락이 있을 것이고 ㅊ

profile
청룡동거주민

0개의 댓글