제네릭(Generics)은 C# 2.0에서 도입된 기능으로, 이 언어에서 가장 중요한 개념 중 하나로 꼽힙니다. 제네릭을 사용하면 컴파일 시점에 타입 안전성을 보장하면서 재사용 가능하고 고성능인 코드를 작성할 수 있습니다. 즉, 코드를 작성하는 시점에 타입을 미리 알지 못해도 나중에 해당 타입을 유연하게 사용할 수 있습니다.제네릭은 .NET 전반에서 폭넓게 활용됩니다. 컬렉션, 델리게이트, 비동기 코드 등이 대표적인 예입니다. 제네릭을 사용하면 컬렉션의 크기를 미리 알 필요가 없으며, 직접 정의한 사용자 지정 데이터 타입을 포함한
C 프로그래밍 경험이 있다면 대리자(delegate)를 함수 포인터와 유사한 개념으로 이해할 수 있습니다. 하지만 C#의 대리자는 단순한 함수 포인터를 훨씬 뛰어넘는 강력한 기능입니다. 이 글에서는 대리자의 핵심 개념과 일상적인 프로그래밍에서의 활용 방법을 자세히 살펴보겠습니다.대리자란 무엇인가?본질적으로 대리자는 간접 참조(indirection) 계층을 제공합니다. 대리자는 코드 조각을 캡슐화하여 타입 안전(type-safe)한 방식으로 전달하고 실행할 수 있게 해줍니다. 동작을 즉시 실행하는 대신, 그 동작을 객체 안에 담아두고
C# 인터페이스란 무엇일까요?인터페이스(Interface)는 클래스(class)나 구조체(struct)가 반드시 구현해야 하는 계약(contract)을 정의하는 특별한 형식입니다. 인터페이스에는 메서드, 속성(property), 이벤트, 인덱서(indexer)를 포함할 수 있습니다.인터페이스는 겉모습만 보면 클래스와 비슷하지만 결정적인 차이가 있습니다. 인터페이스 자체는 어떠한 데이터도 저장하지 않으며, 오직 무엇을 할 수 있는지만 규정합니다. 실제 동작은 해당 인터페이스를 구현하는 클래스가 담당합니다.하나의 클래스는 하나 이상의
C#은 null 값을 안전하고 간결하게 처리할 수 있도록 세 가지 전용 연산자를 제공합니다. 이 연산자들을 활용하면 복잡한 조건문 없이도 NullReferenceException을 예방하고 코드의 가독성을 크게 높일 수 있습니다.1. null 병합 연산자 (??)null 병합 연산자(??)는 변수의 값이 null이 아닐 경우 해당 값을 그대로 반환하고, null일 경우에만 지정한 기본값을 대신 사용할 수 있게 해주는 연산자입니다.이 연산자는 기존의 삼항 조건식을 다음과 같이 대체합니다.string resultOne = value !
C#에서 const와 readonly 키워드는 모두 한 번 선언되면 수정할 수 없는 불변(immutable) 값을 정의하는 데 사용됩니다. 하지만 두 키워드 사이에는 몇 가지 중요한 차이점이 존재합니다.const란?const 한정자는 컴파일 시점에 값이 확정되며 이후 변경되지 않는 상수를 선언합니다. C#에서는 기본 제공 타입(built-in types)만 const로 지정할 수 있으며, 클래스나 구조체 같은 사용자 정의 타입은 const로 선언할 수 없습니다. 또한 메서드, 프로퍼티, 이벤트 같은 클래스 멤버에도 const를 적용
배열(Array)은 특정 타입의 요소를 고정된 개수만큼 담는 자료구조입니다. 배열의 요소들은 메모리상에 연속된 공간에 저장되므로, 인덱스만 알고 있다면 각 요소에 매우 효율적으로 접근할 수 있습니다.배열의 선언과 초기화C#에서 배열을 선언하고 초기화하는 기본 문법은 다음과 같습니다.// 3개의 언어 이름을 저장할 문자열 배열 생성string[] languages = new string[3];배열을 선언한 후에는 대괄호([]) 표기법을 사용해 각 항목에 값을 할당할 수 있습니다.languages[0] = csharp;languages
.NET에는 수많은 네임스페이스가 포함되어 있으며, 서드파티 라이브러리까지 더하면 그 종류는 더욱 방대해집니다. 하지만 실제 개발 과정에서 반복적으로 사용하게 되는 네임스페이스는 생각보다 많지 않습니다. 아래에서 소개하는 20가지 네임스페이스만 제대로 익혀두면, 일상적인 프로그래밍 문제의 약 80%를 손쉽게 해결할 수 있습니다.System.NET에서 가장 근본적인 타입들을 담고 있는 핵심 네임스페이스입니다. 자주 사용되는 클래스, 구조체, 열거형(enum), 이벤트, 인터페이스 등 대부분의 기본 타입이 여기에 포함됩니다.System
C#에서 문자열은 불변(Immutable)입니다C#에서 string 타입은 불변(immutable)입니다. 즉, 문자열이 한 번 생성되면 내용을 직접 수정할 수 없습니다. 문자열에 어떤 변경을 가하면 항상 변경된 내용을 담은 새로운 문자열 객체가 반환되며, 원본 문자열은 그대로 유지됩니다.string word = aaabbbccc; string newWord = word.Replace(b, d); Console.WriteLine(word); // aaabbbccc 출력 Console.WriteLine(newWord); //
C# System.Reflection 네임스페이스란?C#의 System.Reflection 네임스페이스는 메타데이터를 검사하여 어셈블리(Assembly), 모듈, 멤버, 매개변수 등 코드에 대한 정보를 제공하는 타입들을 포함합니다. 이 네임스페이스의 Assembly 클래스는 어셈블리를 나타내며, 일반적으로 Type 객체의 Assembly 속성을 통해 접근할 수 있습니다.어셈블리 ID(Identity)의 4가지 구성 요소어셈블리의 정체성은 다음 네 가지 항목으로 구성됩니다.단순 이름(Simple Name)버전(Version) — As
종속성(dependency)이란 한 객체가 다른 객체에 의존할 때 그 의존 대상이 되는 객체를 말합니다. 종속성 주입(Dependency Injection, DI)은 객체가 필요로 하는 객체를 스스로 생성하지 않고 외부에서 공급받는 기법으로, 제어 역전(Inversion of Control)이라고도 부릅니다. 의존 객체를 목(mock)으로 쉽게 대체할 수 있어 테스트를 한결 수월하게 만들어 주는 유용한 기술입니다. 예를 들어 클래스 A가 클래스 B의 메서드를 호출하고, B가 다시 클래스 C의 메서드를 호출한다면 A는 B에, B는 C
행렬에서 왼쪽 위에서 오른쪽 아래로 내려가는 모든 대각선에 같은 요소들이 있을 때, 이 행렬을 토플리츠(Toeplitz) 행렬이라고 합니다. 즉, 각 대각선을 따라 값이 일정하게 유지되어야 한다는 의미입니다.예제 1[[1,2,3,4],[5,1,2,3],[9,5,1,2]]출력 결과 −true위 행렬의 대각선 요소들을 살펴보면 다음과 같습니다.[9], [5, 5], [1, 1, 1], [2, 2, 2], [3, 3], [4].모든 대각선에 포함된 요소들이 각각 동일하므로, 이 행렬은 토플리츠 행렬입니다. 따라서 결과는 true입니다.예
정렬된 행렬 검색 문제란?가장 단순한 해결 방법은 입력 행렬에 저장된 모든 요소를 처음부터 끝까지 훑어보며 주어진 키를 찾는 것입니다. 그러나 이러한 선형 검색 방식은 행렬의 크기가 M×N일 때 O(MN)의 시간이 걸려 상당히 비효율적입니다.핵심 아이디어: 1차원 배열처럼 바라보기행과 열 단위로 오름차순 정렬된 행렬은 하나의 정렬된 1차원 배열로 볼 수 있습니다. 모든 행을 위에서 아래 순서대로 이어 붙이면 전체가 오름차순으로 정렬된 1차원 배열이 되기 때문입니다.예를 들어 다음 3×4 행렬은,{ 1, 2, 3, 4 }{ 5,
이 문제의 가장 기본적인 해결 방법은 입력 행렬에 저장된 모든 요소를 처음부터 끝까지 훑어보며 주어진 키를 찾는 것입니다. 이러한 선형 탐색(linear search) 방식은 행렬의 크기가 MxN일 때 O(MN)의 시간 복잡도를 가지므로, 행렬이 클수록 매우 비효율적입니다.행별로 증가하는 행렬의 특성을 활용하면 훨씬 빠른 탐색이 가능합니다. 핵심 아이디어는 행렬의 오른쪽 상단(top-right)에서 탐색을 시작하는 것입니다. 찾으려는 값이 현재 위치의 값보다 크면 행(row)을 한 칸 증가시키고, 반대로 작으면 열(column)을
배열에 들어 있는 숫자 중 세 개를 골라 그 합이 0이 되는 조합을 모두 찾는 문제는 코딩 테스트와 알고리즘 인터뷰에서 자주 등장하는 대표적인 주제입니다. 이 글에서는 C#을 이용해 합이 0이 되는 고유한 삼중항을 찾는 여러 가지 접근 방식을 단계별로 살펴보고, 실제로 동작하는 전체 예제 코드까지 함께 확인해 보겠습니다.방법 1 – 브루트 포스(무차별 대입)가장 직관적인 방법은 세 개의 중첩 반복문을 만들어 가능한 모든 조합을 하나씩 확인하는 것입니다. 세 원소의 합이 0이라면 해당 원소들을 출력하면 됩니다.시간 복잡도 – O(n3
문자열 s와 문자 c가 주어졌을 때, 문자열의 각 인덱스에서 가장 가까운 문자 c까지의 거리를 담은 배열을 반환하는 문제입니다. 이 문제는 양방향 탐색(Two-Pass) 기법을 사용하면 선형 시간 안에 효율적으로 해결할 수 있습니다.접근 방식핵심 아이디어는 다음과 같습니다.먼저 leftDis와 rightDis라는 두 개의 배열을 생성합니다. leftDis는 왼쪽에서 오른쪽 방향으로 이동하며 계산한 거리를 저장하고, rightDis는 오른쪽에서 왼쪽 방향으로 이동하며 계산한 최단 거리를 저장합니다. 탐색 중에 목표 문자 c를 만나면
문자열과 특정 문자가 주어졌을 때, 문자열의 각 위치에서 해당 문자까지의 가장 긴 거리를 구하는 문제입니다. 이 문제는 양방향 탐색(Two-Pass) 기법을 사용하면 선형 시간 안에 효율적으로 해결할 수 있습니다.접근 방법핵심 아이디어는 두 개의 배열을 활용하는 것입니다.leftDis: 왼쪽에서 오른쪽으로 이동하며 각 위치에서 대상 문자까지의 거리를 저장합니다.rightDis: 오른쪽에서 왼쪽으로 이동하며 각 위치에서 대상 문자까지의 거리를 저장합니다.탐색 중에 대상 문자를 만나면 해당 위치의 거리를 0으로 설정하고, 이후로는 카운
문제 개요정수 배열과 목표값(target)이 주어졌을 때, 배열에서 세 개의 숫자를 골라 그 합이 목표값에 가장 가까운 조합을 찾는 것이 이번 글의 목표입니다. 이 문제는 코딩 인터뷰에서 자주 등장하는 대표적인 배열 탐색 유형 중 하나입니다.접근 방식: 투 포인터(Two Pointers) 패턴이 문제는 투 포인터 패턴을 활용하며, 합이 0이 되는 삼중항 찾기 문제와 유사한 방식으로 해결할 수 있습니다. 배열을 순회하면서 한 번에 하나의 숫자를 기준으로 삼고, 나머지 두 수는 왼쪽·오른쪽 두 포인터를 이동시키며 탐색합니다.매 단계마다
문제 개요정수 배열이 주어졌을 때, 배열 안에서 네 개의 숫자를 골라 그 합이 0이 되는 모든 고유한 조합(사중항)을 찾는 것이 이 글의 목표입니다. 같은 조합이 중복되어 출력되어서는 안 되며, 각 조합의 네 숫자는 서로 다른 인덱스에서 선택되어야 합니다.예를 들어 입력 배열이 {1, 0, -1, 0, -2, 2}라면, 결과는 [[-2,-1,1,2], [-2,0,0,2], [-1,0,0,1]]가 됩니다.방법 1: 브루트 포스 (4중 반복문)가장 직관적인 방법은 네 개의 중첩 반복문을 만들어 가능한 모든 네 숫자 조합을 하나씩 확인하
배열에서 네 개의 숫자를 골라 그 합이 주어진 타깃(target) 값과 최대한 가까워지도록 만드는 문제를 4Sum Closest(사중합 최근접) 문제라고 합니다. 이 문제는 투 포인터(Two Pointers) 패턴을 활용하면 효율적으로 해결할 수 있으며, 합이 0이 되는 사중항 찾기 문제와 매우 유사한 접근 방식을 사용합니다.핵심 아이디어는 다음과 같습니다. 먼저 배열을 정렬한 뒤 숫자를 하나씩 선택하며 배열을 순회하고, 각 단계마다 선택된 네 숫자의 합과 타깃 값 사이의 차이를 계산합니다. 이 차이를 지금까지 기록한 최소 차이와
파스칼 삼각형이란?파스칼 삼각형(Pascals Triangle)은 삼각형 형태로 배열된 숫자 패턴입니다. 수학과 통계학 분야에서 폭넓게 활용되며, 특히 조합(combination)을 손쉽게 계산할 때 유용하게 쓰입니다.삼각형에서 각 숫자는 바로 위 두 숫자의 합으로 이루어집니다. 예를 들어 4번째 행의 가운데 값은 바로 윗행에 있는 3과 3을 더한 결과입니다. 또한 모든 행의 첫 번째 숫자와 마지막 숫자는 항상 1이라는 규칙이 있습니다.파스칼 삼각형의 기본 구조는 다음과 같습니다.11 11 2 11 3 3 11