1. DateTime.Parse 사용 시 주의할 점
DateTime.Parse(myString)는 문화권 정보(CultureInfo)를 명시하지 않으면, 운영체제의 기본 지역 설정을 사용하여 문자열을 해석합니다. 예를 들어, "5/2/2005"라는 문자열은 영문 환경에서는 5월 2일로 해석되지만, 인도(히ند어) 환경에서는 2월 5일로 해석됩니다.
해결 방법으로는 DateTime.Parse에 CultureInfo를 직접 전달하고, 형식 스타일을 지정해야 합니다:
string sDate = "5/2/2005";
CultureInfo ci = new CultureInfo("en-US", true);
DateTime result = DateTime.Parse(sDate, ci, DateTimeStyles.AllowWhiteSpaces);
하지만 정확한 포맷이 확정되지 않은 경우, ParseExact가 필요합니다. 이때는 형식 문자열을 명시해야 하며, 잘못된 형식은 FormatException을 발생시킵니다.
자세한 포맷을 지정하려면 커스텀 패턴을 사용하세요:
DateTime dt = DateTime.ParseExact(sDate, new[] { "yyyy/MM/dd" },
CultureInfo.InvariantCulture, DateTimeStyles.None);
2. PDB 파일의 역할과 위치
PDB(Program Database)는 컴파일 및 링크 과정에서 생성되는 디버깅 정보를 포함하는 바이너리 파일입니다. 디버그 빌드 시 생성되며, 실행 파일과 동일한 디렉터리에 위치해야 제대로 동작합니다. 디버거는 이 파일을 통해 변수 이름, 라인 번호, 함수 정보 등을 참조합니다.
디버깅 정보를 접근하기 위해 다음과 같은 단계를 거칩니다:
IDiaDataSource생성loadDataFromPdb또는loadDataForExe호출openSession로 세션 열기IDiaSession메서드를 통해 심볼 탐색IDiaEnum*인터페이스로 심볼 목록 반복
3. 원형 복잡도 (Cyclomatic Complexity)란?
원형 복잡도는 조건문의 수를 기반으로 한 코드 복잡도 측정 지표입니다. 판단 구조의 독립 경로 수를 의미하며, 테스트 필요 경로 수와 직결됩니다. 높은 복잡도는 유지보수성 저하, 버그 발생 가능성 증가를 의미합니다. 일반적으로 10 이상의 값은 개선이 필요합니다.
4. 이중 검사 잠금 패턴 (Double-Check Locking)
싱글턴 패턴에서 동시성 문제를 해결하기 위한 표준적인 잠금 방식입니다. 객체가 이미 생성되었는지 먼저 확인한 후, 잠금을 걸어 재확인하는 방식입니다.
public sealed class Singleton
{
private static readonly object lockObj = new object();
private static Singleton instance;
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (lockObj)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
5. FullTrust 권한과 GAC
FullTrust는 모든 시스템 리소스에 접근할 수 있는 최고 수준의 권한입니다. .NET 프레임워크 내부에서 GAC(Global Assembly Cache)에 등록된 어셈블리는 자동으로 FullTrust 권한을 부여받습니다. 따라서 보안상 믿을 수 있는 어셈블리만 GAC에 등록해야 합니다.
6. 보안 특성의 장점
특성(Attribute)을 통해 실행 시점에 필요한 권한을 선언할 수 있습니다. 이를 통해 permview.exe나 리플렉션을 활용해 권한 정보를 사전에 확인 가능하며, 애플리케이션 시작 시 즉시 권한 요구 여부를 판단할 수 있어, 실행 중 오류 발생을 피할 수 있습니다.
7. gacutil /l | find /i "Corillian" 명령어 설명
gacutil /l은 전역 어셈블리 캐시(GAC)에 설치된 어셈블리를 나열합니다. find /i는 결과 내에서 대소문자를 무시하고 문자열 "Corillian"을 검색합니다. 즉, 이름에 "Corillian"이 포함된 어셈블리들을 찾아냅니다.
8. sn -t foo.dll 명령어 의미
sn은 강명 어셈블리(.dll)의 공개 키를 추출하는 도구입니다. -t 옵션은 지정된 어셈블리의 공개 키 토근을 출력합니다. 만약 어셈블리가 강명되지 않았다면, Invalid public key 오류가 발생합니다.
9. DCOM의 네트워크 포트 구성
DCOM은 135번 포트를 통해 초기 연결을 설정하고, 실제 통신은 1024~65535 사이의 동적 포트를 사용합니다. 135번 포트는 클라이언트가 서버의 사용 가능한 동적 포트를 요청하는 역할을 하며, 이는 RPC(Remote Procedure Call) 기반의 분산 통신을 지원합니다.
10. OOP vs SOA 비교
OOP(Object-Oriented Programming)는 현실 세계의 실체를 모델링하고, 상속, 다형성 등을 통해 코드 재사용을 추구합니다. 반면, SOA(Service-Oriented Architecture)는 서비스 중심 설계를 통해 시스템 간의 통합, 재사용, 유연한 변경을 가능하게 합니다. 목적은 각각 '구조적 모델링'과 '시스템 통합 및 관리'입니다.
11. XmlSerializer 작동 방식 및 권한 요건
XmlSerializer는 클래스 인스턴스를 XML로 변환하거나 반대로 변환할 수 있습니다. [XmlRoot], [XmlElement], [XmlAttribute] 등의 특성을 통해 시리얼라이제이션 규칙을 제어합니다.
예시:
var serializer = new XmlSerializer(typeof(Theater));
using (var fs = new FileStream("data.xml", FileMode.Create))
serializer.Serialize(fs, theater);
// 역직렬화
using (var fs = new FileStream("data.xml", FileMode.Open))
var deserialized = (Theater)serializer.Deserialize(fs);
이 작업 수행 시, C:\Windows\Temp 디렉터리에 일시 파일을 생성할 수 있어, 해당 경로에 대한 읽기/쓰기 권한이 필요합니다.
12. catch(Exception) 사용 금지 이유
catch(Exception)는 모든 예외를 포괄하지만, 성능 저하와 예기치 못한 예외(예: 메모리 부족)까지 처리하도록 강제합니다. 이러한 예외는 프로그램 상태를 불안정하게 만들 수 있으므로, 특정 예외만 처리하는 것이 안전하고 효율적입니다.
13. Debug.Write vs Trace.Write 차이
Debug.Write는 디버그 빌드에서만 활성화되며, Release 빌드에서는 컴파일러에 의해 제거됩니다. 반면 Trace.Write는 모든 빌드에서 작동하며, 트레이싱 정보를 로그로 남길 수 있습니다. 디버깅에는 Debug, 운영 환경 추적에는 Trace를 사용하는 것이 적절합니다.
14. Debug Build vs Release Build 차이
| 항목 | Debug | Release |
|---|---|---|
| 조건 컴파일 상수 | Debug;Trace | Trace |
| 코드 최적화 | False | True |
| 출력 경로 | bin\Debug | bin\Release |
| 디버그 정보 포함 | True | False |
Release 빌드는 최적화되어 속도가 빠르며, 디버그 정보가 없기 때문에 크기가 작습니다. Debug 빌드는 디버깅 용이성을 위해 .pdb 파일과 함께 제공됩니다.
15. JIT 컴파일 단위
JIT(Just-In-Time) 컴파일은 메서드 단위로 이루어집니다. 사용되는 메서드만 컴파일되며, 이후 다시 호출 시에는 컴파일된 코드를 재사용합니다. 이로 인해 초기 실행 시간이 느릴 수 있지만, 실행 중 메모리 효율과 성능이 향상됩니다.
16. 추상 클래스와 인터페이스의 차이
추상 클래스는 구현을 포함할 수 있으며, 단일 상속을 지원합니다. 인터페이스는 계약을 정의하며, 다중 상속이 가능합니다. 구현이 필요한 경우 추상 클래스, 인터페이스는 행동 계약을 정의할 때 적합합니다.
17. a.Equals(b) vs a==b 차이
값 형식에서는 두 연산자가 동일한 동작을 합니다. 참조 형식에서는 ==는 참조 주소를 비교하고, Equals는 내용을 비교합니다. 다만 string은 ==도 내용 비교를 수행합니다. 커스텀 클래스는 Equals를 오버라이드할 수 있으므로, 항상 동작을 확인해야 합니다.
18. 객체 일치와 객체 동등성
객체 일치는 동일한 메모리 주소를 가진지를 의미하며, 얕은 비교입니다. 객체 동등성은 멤버 변수의 값이 동일한지를 의미하며, 깊은 비교입니다. 데이터의 내용이 같아야 동등하다고 판단합니다.
19. 깊은 복사 (Deep Copy) 구현 방법
ICloneable 인터페이스를 구현하여 깊은 복사를 수행합니다. 새 인스턴스를 생성하고, 모든 멤버를 복사하는 방식입니다.
public class Person : ICloneable
{
public string Name { get; set; }
public Address Address { get; set; }
public object Clone()
{
var clone = new Person();
clone.Name = this.Name;
clone.Address = new Address(this.Address.City, this.Address.ZipCode);
return clone;
}
}
20. ICloneable 인터페이스의 역할
기본적인 MemberwiseClone 외에, 사용자가 정의한 복사 로직을 제공하기 위해 Clone() 메서드를 오버라이드할 수 있도록 하는 인터페이스입니다. 깊은 복사, 복사 시 필터링 등 다양한 복사 전략을 구현할 수 있습니다.
21. 박싱 (Boxing)의 의미
값 형식을 참조 형식으로 변환할 때 발생하는 과정입니다. 예를 들어, int 값을 object 타입으로 저장하면, 값 형식이 힙에 복사되고 참조가 생성됩니다. 이 과정은 성능 저하를 초래하므로, 자주 발생하는 경우 피해야 합니다.
22. string 타입의 특수성
string은 참조 형식이지만, 내용이 동일한 문자열은 공유 풀에 저장되며, 동일한 인스턴스를 반환합니다. 또한, 문자열 변경 시 새로운 인스턴스가 생성되므로, 반복적인 수정은 비효율적입니다. 대량 문자열 조작에는 StringBuilder를 사용하는 것이 좋습니다.
23. XmlSerializer의 특성 사용의 이점
[XmlIgnore]를 사용해 시리얼라이즈에서 제외할 멤버를 지정할 수 있으며, 불필요한 데이터 전송을 줄이고 성능을 향상시킵니다. 또한 커스텀 형식, 요소 이름, 속성 등을 제어하여 맞춤형 XML 구조를 생성할 수 있습니다.
24. out 매개변수 사용의 문제점
out 매개변수는 여러 값을 반환할 수 있게 해주지만, 초기화되지 않은 변수를 전달할 수 있어 오류를 유발할 수 있습니다. 컴파일러는 out 매개변수가 반드시 함수 내에서 할당됨을 보장하지만, 의도하지 않은 사용이 가능하므로, ref 또는 반환 값으로 대체하는 것이 더 안전합니다.
25. 메서드 매개변수에 특성 적용
특성은 매개변수에도 적용 가능합니다. 예를 들어, 입력 값의 범위를 검증하는 커스텀 특성을 만들 수 있습니다.
[AttributeUsage(AttributeTargets.Parameter)]
public class MinValueAttribute : Attribute
{
public int Min { get; set; }
}
public void Process(int value)
{
var param = typeof(Process).GetMethod("Process").GetParameters()[0];
var attr = param.GetCustomAttribute<MinValueAttribute>();
if (attr.Min > value)
throw new ArgumentException($"값은 {attr.Min} 이상이어야 합니다.");
}