20240905Thu 🗣️1on1 기술 면접 예상 질문 답변 준비 (통합)
Index
- RESTful한 API를 설계하는 장점은?
- 적절한 관심사 분리가 필요한 이유는?
- Setter를 무분별하게 사용하면 안되는 이유 무엇인가요?
- NoSQL과 RDBMS에 대해 아는대로 설명해주세요.
- 객체지향 프로그래밍이란 무엇이고 어떻게 활용할 수 있나요?
[Q1] RESTful한 API를 설계하는 장점은? |
우선, REST는 Representational State Transfer 의 약자로 소프트웨어 아키텍처의 한 형식으로, HTTP URI (Uniform Resource Indentifier 를 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE)를 통해 자원에 대한 CRUD Operation을 적용하는 것을 의미한다. 여기서 말하는 자원(Resource)란, 모든 자원에 고유한 ID가 존재하고, 이 자원은 Server에 존재한다. 자원을 구별하는 ID는 '/todos/{todoId}'와 같은 HTTP URI 이다.
RESTful 한 설계를 하게 되면 얻게 되는 장점들에는 여러가지가 있는데,
[1] HTTP 프로토콜의 인프라를 그대로 사용하므로, REST API 사용을 위한 별도의 인프라를 구축할 필요가 없다.
[2] HTTP 프로토콜의 표준을 최대한 활용하여 여러 추가적인 장점을 함께 가져갈 수 있게 해준다.
[3] HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하다.
[4] Hypermedia API 의 기본을 충실히 지키면서 범용성을 보장한다.
[5] REST API 메시지가 의도하는 바를 명확하게 나타내므로 의도하는 바를 쉽게 파악할 수 있다.
[6] 여러가지 서비스 디자인에서 생길 수 있는 문제를 최소화한다.
[7] 서버와 클라이언트의 역할을 명확하게 분리한다.
라는 장점들이 있다. RESTful 한 설계의 단점도 몇 가지를 살펴보면,
[1] 표준이 존재하지 않는다.
[2] HTTP Method 형태가 제한적이다.
[3] 브라우저를 통해 테스트할 일이 많은 서비스라면, 쉽게 고칠 수 있는 URL보다 Header 값이 더 어렵게 느껴질 수 있다.
그럼에도 REST가 필요한 이유는
[1] 애플리케이션 분리 및 통합
[2] 다양한 클라이언트의 등장
[3] 최근의 서버 프로그램은 다양한 브라우저와 안드로이드폰, 아이폰과 같은 모바일 디바이스에서도 통신을 할 수 있어야 한다.
이러한 멀티 플랫폼에 대한 지원을 위해 서비스 자원에 대한 아키텍처를 세우고, 이용하는 방법을 모색할 결과에 REST에 관심이 쏠리게 되었다.
[Q2] 적절한 관심사 분리가 필요한 이유는? |
유지보수성 향상 / 확장성 / 가독성 및 관리 용이성 / 테스트 용이성 / 버그 감소
[1] 유지 보수성 향상 : 각 클래스나 모듈이 하나의 명확한 책임만 가지고 있으면, 특정 기능을 수정할 때, 다른 부분에 영향을 미치지 않고 변경할 수 있습니다. 코드 수정 시 발생할 수 있는 사이드 이펙트를 최소화할 수 있습니다.
[2] 확장성 : 시스템이 성장하거나 새로운 기능이 추가될 때, 이미 잘 분리된 코드에서는 새로운 요구 사항을 쉽게 추가할 수 있습니다. 각 관심사에 맞게 코드를 잘 분리해놓으면, 특정 부분을 개선하거나, 추가하는 작업이 더 쉬워집니다.
[3] 가독성 및 관리 용이성 : 한 클래스나 메서드가 너무 많은 책임을 가지고 있지 않아지기 때문에 코드가 간결해져서 가독성이 높아집니다. 관심사를 분리하면, 각 컴포넌트가 하는 일이 명확해지기 때문에, 코드를 읽고 이해하기가 쉬워집니다.
[4] 테스트 용이성 : 관심사가 명확히 분리되면 개별 컴포넌트들의 동작을 쉽게 테스트 할 수 있습니다. 단위 테스트가 더 간단해지고 테스트 커버리지를 높여줍니다. 테스트 커버리지를 높여준다는 것은 테스트 효율을 높여준다는 말입니다.
[5] 버그 감소 : 서로 다른 기능이 명확하게 분리되어 있으면, 한 부분에서 발생한 버그가 다른 부분에 영향을 미칠 가능성을 줄여줍니다.
즉, 적절한 관심사가 분리된다는 것은 더욱 기능을 세분화하고 간결하고 독립적으로 만들기 때문에, 하나하나의 기능에 대해서 유지보수성 및 확장성이 향상되고, 각각을 읽고 관리하는 것이 쉬워집니다. 테스트하기도 편해지며, 각각이 서로 영향을 덜 미치기 때문에 버그도 줄어듭니다.
[Q3] Setter 를 무분별하게 사용하면 안되는 이유는 무엇인가요? |
객체의 무결성 손상 / 캡슐화 원칙 위반 / 예상치 못한 사이드 이펙트 / 불변성 유지 어려움 / 테스트 및 유지 보수의 어려움
[1] 객체의 무결성 손상 : Setter 는 객체의 내부 상태를 외부에서 쉽게 변경할 수 있게 만듭니다. 모든 필드를 공개된 Setter 로 설정하면, 예상치 못한 방식으로 객체의 상태가 변할 수 있어 객체의 무결성이 깨질 수 있습니다. 무결성이란, 데이터나 시스템, 소프트웨어 등이 의도하지 않은 요인에 의해 손상되어 완전성, 정확성, 일관성을 유지함을 보장하는 특성을 의미하고, 암호프로토콜이 보장하는 3가지 기능 중 하나에 속하기도 합니다. 즉 무결성이 깨져버리면, 객체의 상태를 일관성있게 유지해야 할 때 문제가 발생하게 됩니다.
[2] 캡슐화 원칙 위반 : 객체 지향 프로그래밍의 중요한 원칙 중 하나는 캡슐화 (Encapsulation) 입니다. 객체의 내부 상태는 숨겨지고, 필요한 경우에만 제한적으로 접근할 수 있도록 해야합니다. Setter 를 남용하면, 객체의 상태를 외부에서 쉽게 조작할 수 있어, 캡슐화 원칙을 위배하게 됩니다.
[3] 예상치 못한 사이드 : 객체의 상태를 외부에서 쉽게 변경할 수 있기 때문에 코드의 다른 부분에서 객체의 상태가 바뀌는 상황이 발생할 수 있습니다. 이는 위에서 말한, 관심사가 분리되지 않는다 라는 말과도 연결되는 말이기도 합니다. 이는 독립성을 낮추기 때문에, 디버깅을 어렵게 만들고, 코드의 동작을 예측하기 힘들게 합니다.
[4] 불변성 유지 어려움 : 불변 객체는 멀티스레드 환경 ( 여러 스레드가 병렬적으로 프로그래밍 되는 환경, 스레드 : 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위 ) 이나 동시성 이슈 ( 여러 프로세스가 동시에 공유 자원에 접근하는 경우 ) 에서 안전하고 신뢰성이 높은 객체입니다. 하지만 Setter 가 있으면, 불변 객체로 사용하기 힘들고, 동시성 문제나 예기치 못한 상태 변화로 인해 버그가 발생할 가능성이 커집니다.
[5] 테스트 유지 보수의 어려움 : Setter 가 많이 사용되면, 객체가 어디서든 변경될 수 있기 때문에, 어디서 Setter 가 사용되었는지 추적하기 어려워집니다. 이는 테스트를 복잡하게 만들고, 유지보수 또한 어렵게 만듭니다.
즉, 객체의 무결성을 깨뜨리기 때문에, 불변객체를 사용할 수 없어 예상치 못한 사이드이펙트를 발생시키고, 이는 캡슐화 원칙을 위반하는 일이기도 합니다. 객체가 어디서든 쉽게 변경될 수 있다는 말은 버그 발생 가능성이 높아지고, 어디서 사용되었는지 추적이 어려워지기 때문에, 유지보수 또한 어려워집니다. 그러면 어떻게 해야 하나요? 대신, Setter 사용을 최소화하여 정말 필요한 경우에만 상태를 변경할 수 있도록 하고, 불필요한 Setter 를 제거하거나, 생성자를 통해 초기값을 설정하는 방식이 권장됩니다.
[4] NoSQL 과 MySQL 에 대해 아는대로 설명해 주세요. |
NoSQL과 RDBMS 는 데이터베이스 관리 시스템(DBMS)에서 2가지 주요 유형에 해당됩니다.
1. RDBMS
- 관계형 데이터베이스, 데이터를 테이블 형태로 관리
- 각 테이블은 행(Row)과 열(Column)로 구성되어 있으며, 데이터를 테이블 간의 관계로 정의
- 데이터를 관리하기 위해 SQL (Structured Query Language) 이라는 구조화된 질의 언어를 사용
- 스키마를 기반으로, 데이터를 저장하기 전에 테이블 구조를 정의하고, 엄격하게 따릅니다. 그로 인해 데이터가 정해진 형식에 맞춰져야 저장이 가능합니다.
( 스키마 : 3계층이 존재하며, 외부스키마 , 개념스키마 , 내부스키마가 존재한다. 외부 스키마는 사용자 뷰를 말하고, 개념스키마는 전체적인 뷰를 의미한다. 내부 스키마는 저장스키마라고도 하며, 저장장치 입장에서 본 데이터베이스 구조이다. 각각은 서로 독립적, 즉 서로에게 영향을 주지 않는다. )
- ACID 특성 : 트랜잭션에서 원자성(Atomicity) , 일관성 (Consistency), 격리성(Isolation), 지속성(Durability)을 보장합니다. 이는 최대한의 데이터 안전성과 무결성을 보장해줍니다.
트랜잭션(Transaction)이란, 여러개의 작업을 하나로 묶은 실행 유닛을 말합니다. 여러 개의 작업 중 하나라도 실패하게 되면, 트랜잭션도 실패이고, 모든 작업이 성공이면, 트랜잭션 또한 성공이게 됩니다. 주식거래나 금융업(은행)을 생각하면 쉽게 이해가 됩니다.
원자성 : 트랜잭션이 하나의 유닛이 되어서 원자성을 띄는 것을 의미합니다. 하나의 유닛에 포함되는 작업들이 모두 성공해야 데이터를 저장하고, 그렇지 않으면 모든 작업을 실패하게 만들어서 기존의 데이터를 보호하도록 합니다. 즉, 롤백(RollBack)시키는 것을 의미합니다. 돈을 입금했다가 출금하는 과정에서 어딘가에서 오류가 발생한다면, 원래의 데이터 상태로 롤백시켜서 오류로 부터 데이터를 보호합니다. |
일관성 : 데이터베이스의 유효한 상태는 다를 수 있지만, 데이터의 상태에 대한 일관성은 변하지 않아야 한다. 데이터들이 테이블 구조를 엄격하게 따름으로써 일관성을 유지할 수 있게 됩니다. 돈을 뽑을 때, 어떤 프로세스들을 항상 따르게 됩니다. 이런 하나의 트랜잭션을 따름으로써, 우리는 일관성을 유지합니다. 이러면 DB 에서도 정보들을 저장하는 데에 있어서 효율이 높아지게 됩니다. |
격리성 : 모든 트랜잭션은 다른 트랜잭션으로 부터 독립적이어야 한다. A가 2차례의 돈을 넣는다고 가정했을 때, 각각의 트랜잭션은 독립적이어야 하며, 서로에게 영향을 미치지 않아야 합니다. |
지속성 : 하나의 트랜잭션이 성공적으로 수행되었다면, 이는 하나의 로그로 남아야 하는 성질을 말합니다. 또한 오류가 발생했어도, 해당 기록은 영구적으로 남아 추후에 참조할 수 있어야 합니다. |
- 정교한 쿼리 : 테이블들을 Join 하여 여러 테이블 간의 정보 관계들을 쉽게 조회할 수 있게 됩니다.
대표적인 RDBMS 에서는 MySQL, Oracle Database 가 있습니다.
2. NoSQL (Not Only SQL)
위처럼 관계형 모델을 따르지 않는 비관계형 데이터베이스를 말합니다.
테이블 대신 문서 / 키 - 값 / 그래프 등의 데이터 모델을 사용할 수 있습니다.
스키마가 구조적이지 않고, 유연하기 때문에 데이터 처리에 유연해집니다.
- 확장성 : 대규모 데이터를 처리할 수 있습니다.
- RDBMS 처럼 엄격하지 않기 때문에 다양한 데이터 형식을 저장합니다.
- CAP 이론을 따릅니다. ( Consistency - 일관성, Availability - 가용성, Partition Tolerance - 분할 허용성 )
대부분의 NoSQL 데이터베이스는 주로 CA 나 AP 시스템이다.
CAP 은 게임으로 생각해보면 접근이 쉬울 것 같다.
CAP 이란? 분산 시스템은 3가지 특성 중 2가지만 제공할 수 있음을 증명한 정리이다.
C : 다중 클라이언트 (어러 접속자)가 같은 시각에 조회하는 데이터는 항상 동일한 데이터임을 보장해야 한다.
한 게임에 접속한 여러 접속자의 데이터가 항상 같아야 함을 의미한다.
A : 서버 내에서 몇가지 노드가 망가지더라도 정상적인 서비스가 가능해야 한다.
P : 지역적으로 분할된 네트워크 환경에서 동작하는 시스템에서 두 지역간의 단절이 일어나더라도 시스템은 정상적으로 동작해야함을 의미한다.
대표적으로 MongoDB, Redis, Neo4j 등이 있습니다.
RDBMS | 차이점 | NoSQL |
[5] 객체 지향 프로그램이란? |
모든 프로그램들을 객체로 구성하고, 속성과 메서드를 가집니다.
캡슐화, 상속, 다형성, 추상화
다형성은 동일한 이름의 메서드가 여러 객체에서 다른방식으로 오버라이드 되어 사용되는 것을 의미합니다.