[CS기술면접] 프로그래밍 및 객체지향

bbbbbhyun·2026년 5월 1일

Study

목록 보기
23/28

라이브러리 vs 프레임워크

  • 라이브러리
    • 공통으로 사용될 수 있는 특정한 기능들을 모듈화한 것을 의미
    • 폴더명, 파일명 등에 대한 규칙이 없고 프레임워크에 비해 자유로움
  • 프레임 워크
    • 공통으로 사용될 수 있는 특정한 기능들을 모듈화한 것을 의미
    • 폴더명, 파일명 등에 대한 규칙이 있으며 라이브러리에 비해 좀 더 엄격
    • 다른 곳으로 이동할 때 ‘도구‘인 비행기를 타고 이동하지만 ‘비행기‘가 컨트롤하고 나는 가만히 앉아 있어야 함. 프레임워크는 이와 비슷함

디자인 패턴

디자인 패턴이란 프로그램을 설계할 때 발생했던 문제점들을 객체 간의 상호 관계 등을 이용하여 해결할 수 있도록 하나의 ‘규약‘ 형태로 만들어 놓은 것

  • 싱글톤 패턴
    • 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴
    • 하나의 클래스를 기반으로 여러 개의 개별적인 인스턴스를 만들 수 있지만, 그렇게 하지 않고 하나의 클래스를 기반으로 단 하나의 인스턴스를 만들어 이를 기반으로 로직을 만드는데 쓰임
    • 장점 : 하나의 인스턴스를 만들어 놓고 해당 인스턴스를 다른 모듈들이 공유하며 사용하기 때문에 인스턴스를 생성할 때 드는 비용이 줄어듬
    • 단점
      • 의존성이 높아짐(의존성이란 종속성이라고도 하며 A가 B에 의존성이 있다는 것은 B의 변경 사항에 대해 A 또한 변해야 된다는 것을 의미)
      • TDD할때 단위 테스트를 주로 하는데, 단위 테스트는 테스트가 서로 독립적이어야 하며 테스트를 어떤 순서로든 실행할 수 있어야 하는데 걸림돌이 됨
      • 모듈 간의 결합을 강하게 만들 수 있음
    • 의존성 주입
      • 의존성 주입자가 의존성을 ‘직접‘줌으로써 메인 모듈이 ‘간접‘적으로 의존성을 주입하는 방식
      • 장점
        • 유연성 향상: 코드 변경 없이 구성 요소를 쉽게 교체할 수 있음
        • 재사용성 및 유지보수성: 객체 간 의존성을 분리하여 코드 재사용이 쉬움
        • 테스트 용이성: Mock 객체 등을 이용한 단위 테스트가 수월해짐
      • 단점
        • 복잡성 증가: 초기에 의존성 설정을 위한 코드가 필요하고, 구조가 단순하지 않을 수 있음
        • 추적의 어려움: 실제 동작 방식이 코드 내부에 명시되지 않아 흐름을 파악하기 어려울 수 있음
      • 의존성 주입 원칙
        • 상위 모듈은 하위 모듈에서 어떻나 것도 가져오지 않아야 함
        • 둘 다 추상화에 의존해야 함
        • 추상화는 세부 사항에 의존하지 말아야 함
class Singleton{
    private static class singleInstanceHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return singleInstanceHolder.INSTANCE;
    }
}

public class HellowWorld {
    public static void main(String[] args) {
        Singleton a = SingleTon.getInstance();
        Singleton b = SingleTon.getInstance();
        System.out.println(a.hashCode());
        System.out.println(b.hashCode());
        if (a == b) {
            System.out.println(true); 
        }
    }
}   

상속 vs 구현

  • 상속(extends) : 자식 클래스가 부모 클래스의 메서드 등을 상속받아 사용하며 자식 클래스에서 추가 및 확장을 할 수 있는 것, 이로 인해 재사용성, 중복성의 최소화
  • 구현(implements) : 부모 인터페이스(interface)를 자식 클래스에서 재정의하여 구현하는 것, 부모 클래스의 메서드를 재정의하여 구현해야 함

객체지향 프로그래밍

정의

  • 객체들의 집합으로 프로그램의 상호 작용을 표현하며 데이터를 객체로 취급하여 객체 내부에 선언된 메서드를 활용하는 방식
  • 설계에 많은 시간이 소요되며 처리 속도가 다른 프로그래밍 패러다임에 비해 상대적으로 느림

특징

  • 추상화 : 복잡한 시스템으로부터 핵심적인 개념 또는 기능을 간추려내는 것
  • 캡슐화 : 객체의 속성과 메서드를 하나로 묶고 일부를 외부에 감추어 은닉 하는 것
  • 상속성 : 상위 클래스의 특성을 하위 클래스가 이어받아서 재사용하거나 추가, 확장하는 것
  • 다형성 : 하나의 매서드나 클래스가 다양한 방법으로 동작하는 것

설계 원칙

  • SOLID 원칙 : 객체지향 설계에서 유지보수성, 확장성, 가독성을 높이기 위해 지켜야 할 5가지 핵심 원칙
    • SRP (단일 책임 원칙, Single Responsibility Principle): 모든 클래스는 단 하나의 책임(기능)만 가져야 하며, 클래스를 변경하는 이유는 오직 하나여야 합니다.
    • OCP (개방-폐쇄 원칙, Open/Closed Principle): 소프트웨어 요소는 확장에는 열려 있으나, 변경에는 닫혀 있어야 합니다. 기존 코드를 수정하지 않고 기능 추가가 가능해야 합니다.
    • LSP (리스코프 치환 원칙, Liskov Substitution Principle): 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 합니다. 즉, 부모 클래스 자리에 자식 클래스를 넣어도 작동해야 합니다.
    • ISP (인터페이스 분리 원칙, Interface Segregation Principle): 클라이언트가 사용하지 않는 메서드에 의존하지 않도록, 인터페이스를 구체적으로 분리해야 합니다.
    • DIP (의존 역전 원칙, Dependency Inversion Principle): 추상화에 의존해야 하며, 구체화(구현 클래스)에 의존해서는 안 됩니다. 상위 모듈이 하위 모듈에 의존하지 않는 구조입니다.
    • 장점
      • 유지보수성 향상: 코드가 분리되어 있어 수정이 용이합니다.
      • 확장성: 기존 코드 수정 없이 기능을 쉽게 추가할 수 있습니다.
      • 가독성 및 재사용성: 코드가 명확해지고 모듈화되어 재사용하기 좋습니다

프로그래밍 개념

  • 오버헤드(Overhead) : 어떤 작업을 처리하는 데 필요한 실제 시간·메모리 외에, 추가로 드는 간접적인 자원이나 시간 비용을 의미
  • 보일러플레이트 코드(Boilerplate code) : 최소한의 변경으로 여러 곳에서 재사용되며, 반복적으로 비슷한 형태를 띄는 표준화된 코드 조각
  • 제네릭
    • 데이터 타입을 일반화하여 클래스, 인터페이스, 메서드 설계 시 구체적인 타입을 지정하지 않고, 사용 시점에 타입을 지정하는 기능입니다. 컴파일 시 타입 체크로 안정성을 높이고, 형변환 번거로움과 오류를 줄입니다. 주로 <T> 형태의 타입 파라미터를 사용
    • 컴파일 시점 타입 검사: 런타임에 발생할 수 있는 ClassCastException 같은 타입 에러를 컴파일 시점에 방지하여 안정성을 확보합니다.
    • 형변환(Casting) 생략: 데이터를 가져올 때 구체적인 타입으로 형변환할 필요가 없어 코드가 간결해집니다.
    • 코드 재사용성: 하나의 클래스나 메서드로 다양한 데이터 타입(Integer, String 등)을 처리할 수 있어 코드 재사용성이 높아집니다.
    • 타입 이레이저 (Type Erasure): 제네릭은 컴파일 타임에만 작용하고 런타임에는 사라집니다

제어 흐름

  • 블로킹(Blocking) vs 논블로킹(Non-blocking) & 동기(Sync) vs 비동기(Async)
    • 동기/비동기: 작업의 완료를 기다리느냐(Sync), 완료 알림을 받느냐(Async)
    • 블로킹/논블로킹: 제어권이 넘어가느냐(Blocking), 바로 돌아오느냐(Non-blocking)

API 설계

  • RESTful API
    • HTTP와 URI를 기반으로 리소스(자원)를 명확히 식별하고, HTTP 메소드(GET, POST, PUT, DELETE)를 사용하여 CRUD(생성, 조회, 수정, 삭제)를 처리하는 아키텍처 원칙을 준수한 API
  • 리처드슨 성숙도 모델의 4단계
    • 0단계 (The Swamp of POX): HTTP를 단순한 전송 수단으로 사용. 단일 엔드포인트(POST /service)로 모든 요청 처리 (예: SOAP, XML-RPC).
    • 1단계 (Resources): 개별 자원(Resource) 도입. 리소스마다 고유한 URI를 사용하여 구별.
    • 2단계 (HTTP Verbs): HTTP 메서드(GET, POST, PUT, DELETE)를 사용하여 CRUD 기능 구현. HTTP 상태 코드를 활용해 결과 전달.
    • 3단계 (Hypermedia Controls): HATEOAS(Hypermedia As The Engine Of Application State) 적용. 응답에 링크(Link)를 포함하여 클라이언트가 자원의 상태 전환을 탐색할 수 있게 함.

배포 전략

  • 롤링 배포 (Rolling Deployment)
    • 서비스 중단 없이 순차적으로 인스턴스를 교체하는 방식
    • 방식: 전체 서버 중 일부를 차례로 새 버전으로 교체하며 배포를 진행
    • 장점: 추가적인 인프라 자원이 거의 필요 없어 비용 효율적
    • 단점: 배포 중 구버전과 신버전이 동시에 존재하여 호환성 문제가 발생할 수 있으며, 롤백 시 시간이 오래 걸릴 수 있음
  • 블루-그린 배포 (Blue-Green Deployment)
    • 동일한 규모의 새로운 환경을 구축하여 트래픽을 한 번에 전환하는 방식
    • 방식: 기존 환경(Blue)과 동일한 신규 환경(Green)을 띄운 후, 로드밸런서를 통해 트래픽을 100% 전환
    • 장점: 롤백이 매우 빠르고(라우터 스위칭만으로 가능), 구/신버전 공존 시간이 거의 없어 호환성 리스크가 적음
    • 단점: 인프라 자원이 2배로 필요하여 비용 부담이 큼
  • 카나리 배포 (Canary Deployment)
    • 소수 사용자에게 먼저 배포하여 안정성을 검증한 뒤 전체로 확대하는 방식
    • 방식: 신규 버전을 소수의 서버에만 배포하고, 특정 트래픽(예: 5%)만 유도하여 모니터링한 뒤 점진적으로 늘려감
    • 장점: 실제 운영 환경에서 리스크를 최소화하며 성능과 버그를 테스트할 수 있음
    • 단점: 트래픽 제어(Traffic Routing)를 위한 정교한 설정이 필요하며 관리 복잡도가 높음
profile
BackEnd developer

0개의 댓글