24.04.03 기술면접

Amberjack·2024년 4월 3일
0

기술면접

목록 보기
6/7

선택 정렬과 버블 정렬에 대해 설명해주세요.

선택 정렬이란, 정렬 시킬 데이터셋의 맨 앞 데이터를 최소값으로 설정한 후, 이후 데이터들과 비교를 진행하여 배열 내 최소값을 찾아내 앞으로 위치시킨 후, 정렬된 원소를 제외한 나머지에 같은 방법을 반복하여 데이터를 정렬하는 방법입니다.

버블 정렬이란, 인접한 두 원소 값을 비교하여 서로의 자리를 교환하는 방식으로, 구현이 쉽지만 모든 원소를 매번 비교를 하기 때문에 비교 횟수가 많으며, 두 원소끼리 비교를 진행하여 자리를 교환하는 만큼 교환 연산 또한 많이 일어나게 됩니다.

둘의 차이점으로는 교환 연산의 발생 횟수가 있습니다. 버블 정렬은 인접한 두 원소의 값을 비교하고 필요할 경우 교환 연산이 일어나기 때문에, 교환 연산이 자주, 많이 일어납니다. 반면 선택 정렬은 최소값을 설정하고 비교를 한 뒤, 비교를 통해 찾은 최소값을 마지막에 맨 앞으로 교환하기 때문에, 최악의 경우에도 교환 연산이 데이터 셋의 크기 - 1번밖에 일어나지 않습니다.

버블 정렬의 시간 복잡도의 경우 최선, 평균, 최악 모두 O(n^2)입니다. 선택 정렬의 경우도 시간 복잡도는 O(n^2)이나, 버블 정렬에 비해 교환연산이 덜 일어나기 때문에 선택 정렬이 버블 정렬보다 일반적으로 좋다고 할 수 있습니다.

스택, 힙 메모리란 무엇이며 어떤 차이가 있는지 비교해서 설명해주세요.

스택 메모리는 정적 메모리로, 말 그래도 메모리 할당 시 그 크기가 정적으로 정해져 있는 데이터들이 저장되는 메모리입니다. 주로 함수에서 사용되는 지역 변수, 매개 변수들이 저장되며, 함수가 호출될 때 함께 할당되며, 함수가 종료되면 해제됩니다.

힙 메모리는 동적 메모리로, 사용자가 직접 메모리 공간을 할당, 해제할 수 있는 메모리 영역입니다. 주로 데이터의 크기가 정해져 있지 않거나 불분명한 경우, new 키워드를 사용하여 힙 메모리에 할당할 수 있습니다.

스택과 힙의 가장 큰차이는 메모리 할당 시점입니다.
우선 메모리 할당 시점의 경우, 스택은 컴파일러에 의해 메모리 크기가 정해지기 때문에 컴파일 타임에 크기가 결정됩니다. 반면 힙은 프로그램이 동작하는 런 타임 때 그 크기가 결정됩니다.

이외에도 스택은 힙에 비해 액세스 속도가 빠르며, 힙은 GC가 없으면 메모리 관리를 직접 해야한다는 불편함이 있습니다.

값 형식과 참조 형식의 차이에 대해 설명해주세요.

값 형식과 참조 형식의 차이는 메모리 할당 방식입니다. 값 형식의 경우 스택 영역에 할당이 되는 반면, 참조 형식은 힙 영역에 할당이 됩니다. 값 형식은 스택 메모리에 정적으로 할당이 되며, 이는 주로 메모리의 크기가 정해져 있는 지역 변수, 매개 변수들이 해당됩니다.

참조 형식의 경우 힙 영역에 동적으로 할당이 되며, 이는 프로그램이 실행되는 런타임에 그 크기가 결정되게 됩니다. 주로 힙 영역에 데이터가 저장이 되며, 스택 영역에 해당 데이터가 저장되어 있는 힙 영역의 메모리 주소를 저장합니다.

따라서 값 형식의 변수가 복사가 되면 저장되어 있는 실제 값을 복사하게 되지만, 참조 형식의 경우 해당 메모리 주소값을 복사하기 때문에, 참조 형식에서 값의 수정이 발생하게 되면 실제 힙 영역에 할당된 값 또한 수정이 일어나게 됩니다.

자료구조의 종류는 무엇이 있으며 각각 어떤 차이점이 있는지 설명해주세요

자료 구조에는 배열, 리스트, 스택, 큐, 트리, 힙, 해시 테이블과 그래프가 있습니다.

배열은 동일한 타입의 데이터들을 저장할 때 사용되며, 고정된 크기를 가집니다. 인덱스를 통해 데이터에 접근이 가능합니다.

연결 리스트의 경우 배열처럼 동일한 타입의 데이터들을 저장할 때 사용하지만, 그 크기를 동적으로 정할 수 있습니다.

스택은 LIFO의 구조로, 물건을 바닥에 차곡차곡 쌓아 올리듯이 데이터를 저장하는 방식입니다.
Push를 통해 데이터를 넣을 수 있으며, Pop을 통해 가장 마지막에 넣은 데이터를 꺼내올 수 있습니다.

큐는 FIFO의 구조로, 대기열처럼 먼저 들어간 데이터가 먼저 나오게 되는 자료 구조입니다.
Enqueue를 통해 데이터를 저장하고, Dequeue를 통해 가장 먼저 저장했던 데이터를 꺼내올 수 있습니다.

트리는 나무처럼 뿌리에서부터 가지를 뻗는 모양처럼 데이터를 저장하는 자료 구조로, 최상위 노드인 루트 밑으로 노드들이 연결되어 있는 부모 - 자식 형태를 가집니다.

힙은 완전 이진 트리의 형태로 만들어진 구조로, 부모 노드 밑으로 2개의 자식 노드를 가지는 자료 구조입니다.

해시 테이블은 Key-Value의 형태로 데이터를 저장하는 자료 구조로, Key를 통해 Value에 접근을 할 수 있어 검색에 매우 용이합니다.

그래프의 경우 Vertex와 Edge로 이루어진 자료 구조로, Vertex와 그 사이를 잇는 Edge들을 통해 표현되며, Edge에 방향과 가중치를 설정하여 Vertex 간의 관계를 표현할 수 있습니다.

a. 위 자료구조는 무조건 좋은가요?
무조건 좋은 경우는 없다고 생각합니다. 자신이 필요한 상황에 따라 최적의 자료 구조를 선정하여 사용하는 것이 좋다고 생각합니다.

객체지향이란 무엇인지 설명해주세요.

객체지향이란 실세계에 존재하고 인지하고 있는 객체를 소프트웨어의 세계에서 표현하기 위해 객체의 핵심적인 개념 또는 기능만을 추출하는 추상화를 통해 모델링하려는 프로그래밍 방식입니다. 이 객체에는 상태와 행위로 이루어져 있으며, 외부에서의 요청에 따른 행위와, 행위의 결과로 인해 변경된 상태를 통해 외부에 전달하는 방식으로 동작합니다.

1. (꼬리질문) 객체지향의 특징은 무엇이 있나요?

객체 지향의 특징으로는 추상화, 상속, 다형성, 캡슐화가 있습니다.

추상화란 어떠한 객체들의 공통되는 특성, 속성들을 추출하여 정의하는 것을 의미합니다. 예를 들어, 강아지, 고양이, 토끼들에게 공통되는 특성으로는 먹기, 자기를 생각해볼 수 있습니다. 이를 추출하여 동물이라는 객체를 만들고, 이 동물에 먹기, 자기를 정의를 하는 것을 추상화라고 할 수 있습니다.

상속은 기존의 클래스를 재활용하여 새로운 클래스를 만드는 것을 의미합니다. 부모 클래스에 정의되어 있는 필드, 메서드들을 자식 클래스에서 재활용하여 사용할 수 있도록 해주는 것으로, 앞서 설명드린 예의 경우, 동물 클래스를 상속받아 강아지, 고양이, 토끼에서 먹기, 자기를 재활용할 수 있도록 하는 것이 상속입니다. 이 경우, 강아지, 고양이, 토끼에 따로 먹기, 자기를 구현하지 않아도 되기 때문에 같은 코드의 반복 사용을 줄일 수 있다는 장점이 있습니다.

다형성이란 어떤 객체의 속성이나 기능이 상황에 따라 다른 역할을 수행할 수 있는 것을 의미합니다. 예를 들어 메서드의 오버라이딩과 오버로딩이 있습니다. 메서드 오버로딩은 같은 이름의 메서드를 매개 변수만 다르게 설정하여 매개 변수에 따라 실행될 메서드를 다르게 설정하는 것을 의미하며, 오버라이딩은 상속 관계에서 부모의 메서드를 자식이 필요에 맞게 재정의하여 사용하는 것을 의미합니다.

캡슐화란 내부의 약들을 보호하기 위해 캡슐 알약을 만드는 것처럼, 내부 데이터를 외부에서 접근하지 못하도록 보호하는 것을 의미합니다. 캡슐화를 통해 외부에 노출되어선 안되는 데이터를 은닉하거나, 수정을 하지 못하도록 보호할 수 있습니다.

2. OOP란?

객체 지향 프로그래밍이란 프로그램을 객체라는 단위로 나누고, 이들의 상호 작용을 통해 문제를 해결하는 프로그램 방법입니다. 마치 자동차에 엔진, 바퀴, 브레이크 등 여러 부품이 있는 것처럼, 프로그램에도 각각의 기능을 담당하는 객체들을 만들어 이들의 상호 작용을 통해 프로그램을 만드는 방법으로, 유지 보수가 용이하다는 장점이 있습니다.

3. (꼬리질문) SOLID 원칙은 무엇인가요?

SOLID 원칙이란 객체 지향을 설계할 때 지켜야할 5개의 원칙을 의미합니다. 이 원칙에는
단일 책임 원칙, 개방 폐쇄 원칙, 리스코프 치환 원칙, 인터페이스 분리 원칙, 의존 역전 원칙이 있습니다.

단일 책임이란, 한 객체는 하나의 책임만 가져야 한다는 원칙으로, 어떤 객체에서는 하나의 기능을 수행하도록 설계해야 한다는 의미입니다. 이를 통해 여러 객체를 수정할 필요 없이, 문제가 되는 객체 하나만 수정하여 프로그램의 유지 보수성을 높일 수 있습니다.

개방 폐쇄 원칙이란, 확장에는 열려있어야 하며, 수정에는 닫혀있어야 한다는 원칙으로, 확장은 쉽지만 수정은 어렵게 해야 한다는 의미입니다. 기존의 코드를 변경하지 않으면서, 기능은 추가하기 쉽도록 설계를 해야한다는 의미입니다.

리스코프 치환 원칙이란, 하위 객체는 언제나 상위 객체로 교체될 수 있어야 한다는 것을 의미합니다. 하위 객체를 상위 객체로 선언하더라도 동작에 문제가 없어야 한다는 의미입니다.

인터페이스 분리 원칙이란, 인터페이스를 사용 목적에 맞게 잘게 분리해야 한다는 윈칙으로, 앞서 단일 원책처럼 하나의 인터페이스는 하나의 단일 책임을 갖도록 설계해야 한다는 것을 의미합니다.

의존 역전 원칙이란, 어떤 Class를 참조해서 사용해야 하는 상황이 생긴다면, 그 Class를 직접 참조하는 것이 아니라 그 대상의 상위 요소로 참조하여 사용하도록 하는 원칙으로, 이를 통해 각 클래스 간의 결합도를 낮출 수 있습니다.

현재 자신이 최종 프로젝트에서 구현 중인 기능들에 대해 설명해주세요.

현재 저는 아이템, 상점 그리고 룬스톤 기능을 구현하고 있습니다. 아이템의 경우, 무기, 장신구, 소모 아이템, 필드에 드랍이 되는 필드 아이템 4개의 종류로 구현을 하고 있고, 상점의 경우 무기, 장신구, 소모 아이템 중 5개의 아이템이 출력되도록 구현을 했습니다.

그리고 룬스톤 기능을 구현하고 있는데, 룬스톤 기능이란 저희 게임 내 플레이어의 능력치를 올리거나 내리는 기능입니다. 저희 게임에는 플레이어의 능력치를 강화시킬 방법이 2가지가 있는데, 캐릭터 강화 기능과 룬스톤 기능입니다. 먼저 캐릭터 강화 기능의 경우, 던전에 입장하기 전, 플레이어가 캐릭터 선택, 캐릭터 강화를 진행할 수 있는 던전 입장 맵에서 할 수 있는 기능으로, 영구적으로 캐릭터의 능력치를 올릴 때 사용을 합니다.
룬스톤 기능의 경우, 저희가 로그라이크 게임을 만들고 있다보니, 단순히 플레이어가 아이템을 얻고 몬스터를 죽이기만 하면 플레이가 단조로울 것 같아 변주를 주기 위해 만든 기능으로, 해당 도전 내 임시적으로 플레이어의 능력치를 올리고 내릴 수 있는 기능입니다. 플레이어의 특정 능력치가 올라가면 그에 따른 반동으로 다른 능력치가 내려가는 기능입니다.

0개의 댓글