Array(배열) : 배열은 동일한 타입의 데이터를 연속적인 메모리 공간에 저장하는 자료구고입니다. 배열의 크기는 고정되어 있고, 인덱스를 지정하여 접근하기 때문에 모든 요소에 빠르게 접근이 가능합니다.
Linked List(연결 리스트) : 연결 리스트는 노드라는 요소가 데이터와 포인터를 가지고 한 줄로 연결되어 있는 방식으로 데이터를 저장하는 자료구조입니다. 각 노드는 데이터와 다음 노드를 가리키는 포인터로 구성됩니다.
Stack(스택) : 스택(쌓다)은 데이터를 후입선출LIFO(Last In First Out) 방식으로 저장하는 자료구조입니다. 프링글스를 만들때는 위에서 아래로 넣어 완성하고 소비자가 먹을 때는 위에서 꺼내먹는 것처럼 가장 마지막에 들어온 데이터가 가장 먼저 나가는 구조로 중간에 값을 끼어 넣어 저장할 수 없고, 같은 크기의 자료를 정해진 한 방향으로만 입력, 저장, 삭제가 가능합니다.
Queue(큐) : 큐(대기줄)는 데이터를 FIFO(First In First Out)방식으로 저장하는 자료구조입니다. 은행에서 대기표를 뽑고 줄을 서면 먼저 온 사람이 먼저 나가듯이, 가장 먼저 들어온 데이터가 가장 먼저 나가는 구조입니다.
Tree(트리) : 노드들이 서로 연결된 구조를 가지는 자료구조입니다. 트리는 계층적인 관계를 표현하며, 노드들이 나무 가지처럼 계층적으로 연결된 비선형 자료구조입니다.
Heap(힙) : 힙은 완전 이진트리의 일종으로, 특정 조건("최대 힙"은 부모 노드의 키 값이 자식 노드의 키 값보다 크거나 같은 완전 이진 트리, "최소 힙"은 부모 노드의 키 값이 자식 노드의 키 값보다 작거나 같은 완전 이진트리)을 만족하는 자료구조입니다.
Hash Table(해시 테이블) : 해시테이블은 키(Key)와 값(Value)의 쌍을 저장하는 자료구조입니다. 해시 함수를 통해 키를 해시코드로 변환하고, 이를 인덱스로 사용하여 값을 저장하거나 검색하며, 데이터의 크기에 관계없이 삽입 및 검색에 매우 효율적입니다.
Graph(그래프) : 그래프는 복잡한 네트워크 관계를 표현합니다. 정점(Vertex)과 간선(Edge)으로 이루어져 있으며, 정확히는 정점간의 관계를 표현하는 조직도입니다. 그래프는 정점마다 간선이 없을수도 있으며 루트 노드 및 부모 자식 개념이 존재하지 않는 부분에서 트리와 다릅니다.
정점(Vertex) : 노드(node) 정점에는 데이터가 저장
간선(Edge) : 링크(arcs)라고도 하고, 노드간 관계를 나타냄
a : 아닙니다. 자료구조의 각각 그 자체로는 좋거나 나쁘다 라고 단정하기에는 어렵습니다. 주어진 상황이나 문제에 따라서 달라지기 때문입니다. 예를 들어서, 배열은 인덱스를 통해 빠르게 접근이 가능하지만 크기가 고정되어 있어서 데이터의 추가나 삭제가 불가능합니다. 연결 리스트의 경우는 데이터의 추가 삭제가 가능하지만 특정 인덱스에 접근하기 위해서는 순차적으로 탐색해야 하기 때문에 배열에 비해 비교적 느립니다. 이처럼 '각 상황에 맞는 좋은 자료구조는 존재'하지만 '무조건적으로 좋은 자료구조는 존재하지 않습니다'.
객체지향이란 : 객체지향이란 프로그래밍에서 주로 사용되는 설계 원칙중에 하나로, 프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법으로 코드의 재사용성, 확장성, 유지보수성을 높이는 것입니다.
a : 객체지향의 특징으로는
캡슐화(Encapsulation) - 객체의 상태와 행동(변수와 함수)을 하나로 묶어 객체의 상태를 외부에서 직접 변경하지 못하게 숨김,
상속 (Inheritance), - 기존 클래스를 확장하여 새로운 클래스를 만듬
다형성(Polymorphism) - 어떤 객체의 속성이나 기능이 상황에 따라 여러가지 형태를 가질 수 있는 성질
추상화(Abstraction) - 공통된 특징, 본질만을 모아 추출, 설계(역할)와 구현을 분리
가 있습니다.
b : OOP란 객체지향 프로그래밍(Object Oriented Progtamming, OOP)의 약자로 프로그램을 객체들의 모임으로 보고, 이 객체들이 서로 상호작용 하도록 설계하는 프로그래밍 패러다임 입니다. (객체들은 상태(속성, 필드)와 행동(메서드)을 가지고 이를 통해 데이터와 기능을 하나로 묶어서 처리)
c : SOLID 원칙으로는
단일책임의 원칙 (Single Responsibility Principle, SRP)
하나의 클래스는 하나의 책임만 갖는다는 원칙입니다.
개방폐쇄의 원칙 (Open Closed Principle, OCP)
확장에 대해서는 개방적이고, 수정에 대해서는 폐쇄적이어야 한다는 원칙입니다.
리스코프 치환 원칙 (Liskov Substitution Principle, LSP)
부모 클래스가 들어갈 자리에 자식 클래스를 넣어도 (자식은 부모를 완전히 대체가 가능) 올바르게 작동해야 한다는 원칙입니다.
인터페이스 분리 원칙 (Interface Segragation Princiole, ISP)
범용적인 인터페이스 하나보다는 특정 클라이언트를 위한 여러 개의 인터페이스로 분리하여 사용하는 원칙입니다.
의존관계 역전 원칙 (Dependency Inversion Principle, DIP)
객체는 하위 모듈(구현된 객체)보다 상위 모듈(인터페이스와 같은 객체의 형태 or 추상적 개념)에 의존해야한다는 원칙입니다.
가 있습니다.
상속이란 객체지향 프로그래밍의 핵심 개념중에 하나로, 기존에 정의된 클래스의 필드와 메서드를 다른 새로운 클래스가 물려 받아 확장하여 사용하는 것을 말합니다. 상속을 함으로써 코드의 재사용성을 높일 수 있고 중복을 줄일 수 있습니다.
저는 Behavior Tree를 이용하여 Enemy의 AI를 구현할 때, 모든 Enemy의 기본이 되는 BasicEnemyAI를 만들고 그 기본에서 파생되는 (근거리 or 원거리) Enemy들을 BasicEnemyAI를 상속받게 하여 확장하여 설계하였습니다. 또한 그 밑으로 근거리의 경우 탱커, 암살 등으로 근거리 타입을 상속받아 새로운 타입들을 확장 설계 해본 경험이 있습니다.
오버로딩(Overloading)과 오버라이딩(Overriding)은 메서드의 이름은 같지만, 동작 방식이 다른 경우를 처리하는 방법입니다. 하지만 둘의 적용 방법과 사용 목적은 다릅니다.
오버로딩(Overloading) : 오버로딩은 같은 이름의 메소드를 여러개 정의할 때, 매개변수의 타입이나 개수가 다른 경우를 의미합니다. 같은 기능을 하는 메소드를 동일한 이름으로 사용이 가능하고, 매개변수에 따라 다르게 동작하게 할 수 있습니다.
오버라이딩(Overriding) : 오버라이딩은 상속 관계에서 부모 클래스에서 정의된 메소드를 자식 클래스에서 재정의 하는것을 의미합니다. 자식 클래스는 부모 클래스의 메소드를 그대로 사용하거나, 메소드를 재정의 하거나 확장시킬 수 있습니다. base 키워드를 사용하여 부모 클래스의 메소드를 호출 하여 사용하거나 그 밑에 재정의/확장이 가능합니다.
인터페이스와 추상클래스는 객체지향 프로그래밍에서 상속과 다형성을 활용하기 위한 개념입니다. 하지만 두 개념은 몇 가지 차이점이 있습니다.
인터페이스(Interface) : 인터페이스는 메소드, 속성, 이벤트 등의 "정의"만 가질 수 있습니다. 정의를 하는 것만이 가능하고 그 실제 구현 내용은 가질 수 없습니다. 인터페이스는 해당 인터페이스를 상속받는 클래스가 반드시 구현해야할 메소드나 속성의 형태를 정의하는 역할을 합니다. 또한 C# 유니티에서는 인터페이스는 여러 다중으로 상속받을 수 있습니다.
추상 클래스(Abstract Class) : 추상 클래스는 인터페이스와 달리 메소드의 "정의"와 실제"구현"이 가능합니다. 메소드의 실제 구현을 하여 기본 구현형태를 제공할 수 있고, 메소드를 추상 메소드로 구현하면 구현을 강제할 수 있습니다. 또한 추상 클래스는 인터페이스와 달리 필드를 가질 수 있고, C# 유니티에서는 추상 클래스는 단인 상속만 가능합니다.