본문 바로가기

이론(면접)

C# 구조

엔진: 라이브러리의 집합

 

C# 언어의 문법을 숙지해야 하는 이유
유니티 엔진에서 기본적으로 스크립트는 대부분 C# 스크립트를 이용, 유니티 엔진의 활용성을 높이기 위해선 C#에 대한 지식이 필요
C / C++ 스타일로 C# 문법을 모르고 작성하는 것도 가능하지만 결국엔 한계에 부딪히게 된다.



C# 프로그램 동작방식
C# 프로그램은 CLR(Common Language Runtime)이라는 자바의 가상 머신과 비슷한 프로그램 위에서 구동이 된다.
C / C++ 언어와 달리 결과물이 컴퓨터가 바로 실행할 수 있는 실행 파일로 생성되지 않는다는 것을 의미한다.


CLR(Common Language Runtime)
마이크로 소프트에서 개발한 가상 머신의 구성 요소(windows 전용)
기능은 크게 두 가지.
1. 중간 언어를 JIT컴파일러를 이용해 기계어로 변환 가능
2. 가비지 컬렉션을 통한 동적 메모리 관리


가상머신(virtual Machine)
컴퓨터에서 가상으로 사용하는 컴퓨터
컴퓨터에서 1대 이상의 컴퓨터를 구동하는 것으로 하드웨어 등 모든 컴퓨터 자원을 가상화 시킨 것.
C#은 CLR이라는 중간 과정을 거쳐 다른 언어를 사용할 수 있게 지원을 한다.
CLR은 CIT 코드를 읽얻ㄹ여 OS가 이해할 수 있는 Native Code로 변환하는 역할을 한다.
이 때 서로 다른 언어들이 만나는 지점이 IL이라는 중간 언어이며 이 언어로 쓰여진 코드를 다시 CLR이 자신이 실행한 플랫폼으로 맞춰서 컴파일하는 구조

    
가비지 컬렉션.. 이거가 성능 떨어트리는 주범임

메모리 관리는 C++이 좀 더 쉽다. 포인터라는 개념 때문에. C#은 가비지 컬렉션으로 메모리를 관리하나, 이것은 쉬운 게 아니라 편한 것이다. 가비지 컬렉션을 최대한 호출하지 않는 방향으로 프로그래밍 해야 한다. 박싱/언박싱이 잦으면 퍼포먼스가 떨어지므로 foreach, List는 최소한으로 쓰는 게 낫다. 가비지컬렉션은 2세대까지 있다. 유니티에서 에디터타임(실행 전)에 사용되는 게 0세대 가비지컬렉션으로 죽은메모리...? 1세대 호출 시 동면된다. 플레이 시 1세대 사용. 다 차면 2세대를 부르게 된다. 2세대 기준으로 재앙이 시작된다...... 플레이어가 눈치채기 시작함(프레임드랍) 메모리 단편화(간편화, 파편화) : 메모리가 파편처럼 쪼개져 있는 상태로, 이걸 방지하기 위해 가비지컬렉션이 돌고 있다. 그 과정에서 퍼포먼스를 많이 먹는다.

 

요약하면 CLR은 따로 컴파일을 해서 실행을 시키고 그걸 해당 플랫폼에 다시 맞춰 컴파일을 하게 하는 기능을 뜻함

참고로 C / C++은 컴파일을 진행해서 프로그램을 바로 만들어낸다.

 

 

CIL(Common Intermediate Language): 공통 중간 언어

닷넷 프레임워크에서 실행되는 언어

닷넷 프레임워크 언어로 개발된 프로그램 코드는 컴파일 시 바이너리 형태로 CIL이라는 파일로 작성된다.

 

 

※ .Net Framework: Windows 프로그램 개발 및 실행 환경

네트워크 작업, 인터페이스 등의 많은 작업을 캡슐화하여 코딩의 효율을 올려준다.

특징으로는 CLS(닷넷 프ㅔ임워크의 언어가 반드시 지켜야 하는 언어 스펙)을 따르는 언어라면 어떠한 언어라도 닷넷 프레임워크에서 실행이 가능하며 CLR이라는 가상 기계 위에서 작동하기 때문에 플랫폼에 독립적이며 궁극적으로는 프로그래머가 코딩을 하는데 더 편한 환경을 제공한다.

그리고 CLR 구독 중에 IL 코드를 읽어들여서 특정 운영체제에 맞는 네이티브 코드로 변환시켜주는 작업을 JIT(Just in Time 컴파일 방식) 이라고 한다.

 

즉, C# 프로그램은 컴파일 방식 + 인터프리트 방식의 혼합 하이브리드 방식으로 구동된다.

 

실행 순서

C# 컴파일 -> IL 생성 -> CLR -> 실행 파일

 

 

 

JIT 컴파일 방식의 장점

프로그램이 구동 중에 즉시 네이티브 코드를 생성하기 때문에 특정 운영 체제에 맞는 최적화 코드를 만들어내는 것이 가능.

 

JIT 컴파일 방식의 단점

프로그램이 구동 중에 네이티브 코드를 생성하기 떄문에 해당 코드를 생성하기 위한 시간이 필요하다.

 

 

 

CLR의 두드러지는 세 가지 역할

- 메모리 관리(가비지 컬렉션)

- 예외 처리

- 프로그래밍 언어간의 호환성

    ㄴ .Net FrameWork는 C# 언어만 위한 프레임 워크가 아니기 때문에 C# 언어를 제외한 다른 언어에서도 닷넷 프레임 워           크를 이용하는 것이 가능하다.

         이 때 발생하는 언어간의 문법적인 차이를 CLR을 통해서 통일화시키는 것이 가능

 

 

 

C# 언어가 다른 언어와 호환이 가능한 이유

C# 언어는 내부적으로 CTS(Common Type System) 규칙에 따라 데이터 타입을 구현하기 때문에 

 

 

 

CTS(Common Type System): 공용 타입 시스템. 닷넷 호환 언어가 지켜야 할 타입의 표준 규격으로 닷넷 호환 언어를 만든다면 CTS 규격을 반드시 지켜야 한다. 그렇기 때문에 CTS를 모두 만들 필요는 없지만 필요한 규격만 지원해도 도며 CTS 규격을 벗어나는 새로운 타입은 만들 수 없다.

 

 

 

C# 프로그램의 메모리 관리 방식 (가비지 컬렉션)

1. 스택 메모리 관리(정적)

2. 힙 메모리 관리(동적)

 

 

C# 언어는 힙 메모리를 프로그래머가 직접적으로 관리하는 C / C++ 언어와 달리 C# 언어의 힙 메모리는 가비지 컬렉션에 의해 관리된다.

즉, 메모리 릭을 염두하지 않고 프로그램 로직을 구성하는 것이 가능하다.

 

 

스택 메모리 특징

- 스택 메모리는 지역적인 특징을 지니고 있기 때문에 시스템에 의해 메모리가 관리된다.

- 즉 스택에 할당된 메모리는 따로 관리하기 위한 로직이 불필요하다.

 

힙 메모리 특징

- C / C++ 언어와는 달리 C# 언어에서 힙 메모리는 프로그래머에 의해 직접적으로 관리되지 않는다

- 즉 해당 메모리 영역은 가비지 컬렉션에 의해 관리된다.

 

 

가비지 컬렉션에 의한 메모리 관리 방식의 장점

메모리 릭을 염두하지 않고 프로그램 로직을 구성하는 것이 가능하기 때문에 편하다.

 

가비지 컬렉션에 의한 메모리 관리 방식의 단점

C#언어는 힙 메모리를 할당하는 것은 가능하지만 직접적으로 관리되지 않기 때문에 불필요한 메모리 공간이 있다는 것을 알아도 즉시 제거하는 것이 불가능하다. 권한이 없기 때문에 가비지 컬렉션이 구동될 때까지 해당 데이터는 메모리에 계속 상주하게 된다.

그렇기 때문에 가비지 컬렉션에 의한 메모리 관리는 많은 부하를 일으키는 원인이 된다. 그래서 프로그램을 작성할 때에는 가비지 컬렉션의 상태에 따라 프로그램의 로직에 신경 써야 한다.

또한 높은 퍼포먼스를 요구하는 프로그램에서는 최적화에 대한 많은 노력이 필요하다.

 

 

C#언어 자료형의 특징

-C#언어는 기본적으로 모든 데이터가 클래스 또는 객체로 인식이 된다.

C/C++/C# 자료형의 차이점에 대해서

즉 int, float, double 등의 기존 자료형도 C#에서는 내부적으로 클래스로 표현된다는 것을 의미한다.

또한 C# 자료형의 데이터 타입에 따라서 값 타입과 참조 타입으로 나뉜다.

데이터의 형식에 따라서 기본 데이터 형식과 복합 데이터 형식으로 구분된다.

 

복합 데이터 형식: 구조체와 클래스 + 배열

 

 

값 형식 데이터 타입의 특징

-값 형식의 데이터 타입은 스택 메모리에 할당된다.

즉 시스템에 의해서 메모리가 관리된다.

참조형태보다 값 형식이 느림.

 

참조 형식 데이터 타입의 특징

- 참조 형식 데이터 타입은 실제적인 값을 스택에 할당하는 값 형식과는 달리 실제 값은 힙 메모리에 할당되며 해당 메모리에 대한 참조 값을 스택에 할당하는 변수에 보관한다.

즉, 참조 형식의 데이터 타입은 가비지 컬렉션에 의해 메모리가 관리된다.

 

이는 C# 언어는 기본적으로 다른 언어와의 호환성을 지닐 필요가 있기 때문에 C# 언어의 자료형이 CTS 표준을 따르고 있기 때문이다.

프로그래머가 최적화할 때 가장 신경써야 할 부분은 힙 영역.

 

C#언어의 변수 특징

C# 언어의 모든 클래스는 object 클래스를 직/간접적으로 상속하는 것이 원칙.

즉 Object 타입의 변수로 모든 데이터를 보관하는 것이 가능

object 타입을 다른 데이터 형식의 값으로 제어하는 것을 박싱 / 언박싱이라고 지칭한다.

-박싱은 데이터를 보관하는 행위

-언박싱은 데이터를 읽어들이는 행위

 

 

object 타입의 변수는 기본적으로 참조 타입이기 떄문에 해당 변수에 참조 타입에 값을 보관할 때는 퍼포먼스 저하를 일으키지 않지만 값 형식의 데이터를 보관할 떄에는 박싱, 언박싱이 수행되기 떄문에 퍼포먼스 저하가 발생한다.

 

 

값 형식의 종류

- byte / sbyte

- int uint, long

- float(7자리), double(15자리), decimal(29자리)

=> 정밀도라 생각하면 됨. dscimal을 쓰는게 좋겠네~ 싶어도 연산 느리고 메모리 많이 잡아먹음.(16Byte)

- char

- enum

- struct

- Nullable => 값 형식에서의 null 체크를 도와줌

 

 

- C 계열 언어는 타입에 매우 엄격한 언어이다. => 오류를 방지하기 위함.

 

 

참조 형식의 종류

- 참조 형식은 기본적으로 null 대입이 가능하다.

- Object

- string

- Class

- Delegate

 

 

 

값 형식과 참조 타입의 차이점

- 기본적으로 C#의 Object 타입은 모든 데이터를 가리키는 것이 가능하지만 Object 타입은 참조 타입에 해당되기 떄문에 해당 타입의 변수에 값 타입의 데이터를 할당할 경우 내부적으로 박싱 / 언박싱이 발생한다.

- 값 타입의 자료형은 스택에 할당되기 때문에 시스템에 의해 메모리가 관리되고 값을 할당할 때에는 내부적으로 복사가 발생한다. 즉 값 자체가 복사된다.

- 반면 참조 타입의 자료형은 힙에 해당되기 떄문에 가비지 컬렉션에 의해 메모리가 관리되고 값을 할당할 때 참조값의 복사가 아루어진다.(메모리 주소 할당)

- 단 C# 언어의 문자열은 기본적으로 변경이 불가능하기 때문에 (권한이 없기 때문) 기본 문자열을 편집한 새로운 문자열을 얻기 위해서는 새로운 메모리 공간에 문자열을 생성해야 한다. 즉 한 번 할당되어 만들어진 문자열은 더 이상 편집이 불가능하다. 이거 해주는 클래스가 따로 있음

 

 

 

Nullable 타입이란?

- 기본적으로 C# 언어는 참조 타입 데이터의 유효하지 않는 여부를 null 키워드를 통해 구분할 수 있다. 반면 값 타입의 데이터는 null 키워드를 이용하는 것이 불가능하다. 이는 오류를 미리 방지할 수 없음을 의미한다.

- 그렇기 때문에 Nullable타입이라는 자료형이 주어지며, 해당 자료형은 값 타입에 null 키워드를 사용할 수 있게 하는 기능을 제공한다.

- Nullable은 값 타입의 데이터에만 사용하는 것이 가능하다. 

'이론(면접)' 카테고리의 다른 글

Attribute  (0) 2022.07.01
SendMessage (ray)  (0) 2022.07.01
변수 표기법  (0) 2022.06.30
배열 / 정적 클래스 / 확장메서드  (0) 2022.06.29
[C#] $ (문자열 보간), Nullable  (0) 2022.06.29