기술 면접 - java 2편

박경서·2024년 8월 13일

기술면접

목록 보기
1/2

1. Optional에 대해 설명해주세요. Optional을 사용하면 무슨 이점이 있을까요?

  • Optional 은 Null 이 될 수 있는 값을 감싸는 Wrapper 클래스입니다.
  • 명시적으로 Null 가능성을 표현할 수 있고, Null 체크를 직접 하지 않아도 되고, NPE 가 발생할 가능성이 있는 값을 직접 다룰 필요가 없다는 점이 장점입니다.
  • Null 이 될 수 있는 값을 감싸는 Wrapper 클래스
  • 장점
    • 명시적으로 변수에 대한 Null 가능성을 표현할 수 있다.
    • Null 체크를 직접 하지 않아도 된다.
    • Null Pointer Exception 이 발생할 가능성이 있는 값을 직접 다룰 필요가 없다.
  • 단점
    • Wrapper 클래스이기 때문에 생성 비용이 비싸다.
    • 직렬화가 불가능하기 때문에 클래스의 인스턴스 필드로 사용하면 안된다.
    • 필드로 사용하기 위해 고안된 것이 아니므로 값을 반환하는 용도로 사용해야 한다.

2. Optional을 사용하면서 주의해야할 점이 있을까요?

  • Optional 은 직렬화를 구현하지 않았기 때문에 필드로 사용하는 것을 주의해야 합니다. 또한 생성자나 메서드 인자로 사용하는 것을 주의해야 합니다. 생성 비용이 비싼 Optional 대신 일반 객체를 넘겨 null 체크를 하는 것이 좋습니다.
  • 필드로 사용하지 말자
    • Optional 은 Serializable 을 구현하지 않았기 때문에 직렬화가 되지 않는다.
  • 생성자나 메서드 인자로 사용하지 말자
    • 생성비용이 비싼 Optional 대신 일반 객체를 넘겨 호출받는 쪽에서 null 체크를 하자. Optional 이 오더라도 Optional 에 null 이 할당되어 있을 수도 있다.
  • orElse 대신 orElseGet 을 사용하자
    • null 일 경우에만 반환하는 코드가 호출되므로 더 효율적이다.
  • 컬렉션을 Optional 로 감싸지 말자

3. Object 클래스의 equals()와 hashcode()는 무슨 역할을 하나요?

  • equals 는 객체의 내부 요소를 비교하여 객체의 동등성을 확인할 떄 사용합니다.
  • hashcode 는 런타임 시점에 객체의 유일한 값을 반환하는 것입니다.
  • 이는 HashMap, HashTable 등 여러 Collection 클래스에서 객체끼리 구분할 때 사용합니다.

4. equals()와 hashcode()는 언제 재정의해야할까요? 또, 왜 같이 오버라이딩 하는게 좋을까요?

  • equals 를 재정의하지 않으면 객체의 주소값만 비교하는 것이 기본 구현입니다.

  • 하지만 객체가 같은 값을 가질 때 같은 객체로 인식하기 위해서는 클래스의 필드에 맞게 재정의가 필요합니다.

  • hashcode 는 객체간의 구분을 위해 사용하므로 유일하게 객체를 식별할 때 재정의해야 합니다. - Object 의 명세에 의하면 equals 가 동일하면 동일한 해시코드를 반환해야 합니다. 이 때문에 같이 오버라이드 해야합니다.

  • equals 만 구현했을 때 문제점

    • 만약 equals 만 구현하여 동등한 객체로 인식되는데 다른 해시 값이 나온다면, Object 명세에도 어긋나지만, 의미상으로도 이상하다. 동등한 객체인데 HashMap 이나 다른 Collection 객체에서는 다른 객체로 인식되는 문제가 생긴다.
  • hashcode 만 구현했을 때 문제점

    • 만약 hashcode 만 구현하여 동일한 해시코드가 나오는데 동등성이 보장되지 않는다면, 마찬가지로 Collection 객체에서 같은 객체로 인식했는데 equals 메서드를 통해 비교할 때는 다르다는 결과가 나오게 된다. 이는 프로그램의 잠재적인 위험이 된다.
  • hashcode 를 구현할 때 주의할 점

    • 핵심 필드를 꼭 포함해서 구현하자
      • 성능보다는 핵심필드를 포함하자
    • 자세한 구현 사항을 API 사용자는 모르는 것이 좋다.
      • 사용자가 구현에 의존하지 않을 수 있다.

5. 서로 다른 인스턴스가 같은 hashcode값을 가질 수 있을까요?

  • 서로 다른 인스턴스더라도 해시코드 값을 가질 수 있습니다. 이때문에 해시 충돌을 해결하는 것이 중요해졌습니다. 해시 충돌을 완화하는 방법에는 크게 Open Addressing 과 Separate Chaining 방식이 존재합니다. 자바의 HashMap 에서는 Separate Chaining 방식을 사용하며, 이는 해시 버킷에 들어갈 수 있는 엔트리의 제한을 두지 않는 방식입니다.

  • Open Addressing

    • 한 버킷당 들어갈 수 있는 엔트리가 하나
    • 해시 충돌이 일어난 경우, 다른 버킷에 저장
    • 이를 위해 빈 버킷을 찾는 여러 알고리즘이 존재한다.
      • Linear probing
      • Quadratic probing
      • Dobule hasing
    • 특징
      • 전체 버킷 중 사용중인 버킷의 비율이 커지면 탐사 비용이 비약적으로 상승한다.
      • 데이터를 삭제할 때 비효율적이다.
  • Separate Chaining

    • 한 버킷에 여러 엔트리가 들어갈 수 있음
    • 버킷은 주로 LinkedList 또는 Tree 를 사용
    • 특징
      • 위의 방식과 비교하여 추가적인 메모리 공간 필요
      • 적재율에 따라 선형적으로 성능이 저하됨
  • 자바에서의 hash 충돌 발생 해결 방법 (HashMap)

    • Separate Chaining
    • Java 7 까지는 LinkedList 를 고정적으로 사용
    • Java 8 부터 데이터의 개수에 따라 적으면 LinkedList, 많으면 Tree 사용

6. String 클래스는 final로 선언되어있습니다. 왜 그런걸까요?

  • String 클래스가 final 로 선언되면서 불변성을 가지게 되었습니다.

  • 이 이유로는 String Pool 을 통한 메모리 절약, 다수의 클래스에 매개변수로 사용되기 때문에 보완 관련 문제, 해시 기반 Collection 의 키 값으로 사용하기 위함 등이 있습니다.

  • String Pool

    • String 은 자바를 설계할 때 가장 많이 사용할 것으로 예상된 데이터 타입이다.
    • 이를 최적화하기 위해 String Pool 에 String 리터럴을 포함하는 방법을 이용했다.
    • String 객체를 공유하여 잉여 객체 생산을 막는 것이 목표이다.
    • 이를 위해서는 final 또는 불변이어야 가능하다.
  • Security

    • String 은 다수의 자바 클래스의 매개 변수로 쓰이고 있다.
    • 만약 String 이 불변이지 않으면, String 의 조작을 통해 시스템의 특점 파일에 대한 액세스 권한을 얻는 등 심각한 보안 문제가 발생한다.
  • Multithreading
    - 자바에서 멀티 스레드를 지원하기 위해 String 객체는 thread safe 를 보장해야 한다.

  • Optimization and Performance

    • String 을 불변 클래스로 만들면서 성능 최적화를 할 수 있게 되었다.
    • 값이 변경되지 않는 것을 이용해서 해시 코드 값을 lazy 하게 계산하고 일단 생성 되면 String Pool 에 캐싱한다.
    • 이를 통해 한번 계산된 해시 코드 값을 계속 사용하는 등 성능 개선을 할 수 있다.
    • HashMap 등 해시 관련 함수에 이용할 시 성능 향상의 원인이 된다.

7. String을 new 또는 "" 로 생성했을 때의 차이점을 설명해주세요.

  • String 을 "" 와 같이 리터럴로 생성했을 때는 String Pool 에 캐시됩니다. 따라서 객체를 재활용하는 특징이 있습니다.
  • 반면, new 키워드로 생성했을 때는 다른 객체와 똑같이 Heap 메모리에 생성되고 객체를 공유하지 못하는 특징이 있습니다.
  • String Pool 도 GC 가 될까?
    • Java 7 이전
      • String Pool 은 PermGen 이라는 곳에 저장되어 있었습니다.
      • 이 공간은 런타임에 확장할 수 없고, GC 에 적합하지 않습니다.
      • 그리고 일반 Heap 메모리에 비해 공간이 작아서 문자열을 많이 생성할 경우 메모리 부족 에러가 발생했습니다.
    • Java 7 이후
      • String Pool 은 이후 일반 Heap 공간에 저장되고 이는 GC 대상이 되는 공간입니다.
      • 이 방식을 통해 참조되지 않은 문자열을 풀에서 제거해 메모리 부족 위험이 줄어들었습니다.

8. String, StringBuilder, StringBuffer 를 각각 비교해주세요.

  • String 은 다른 두 클래스와 다르게 새로운 값을 할당할 때마다 새로운 클래스에 대한 객체가 생성됩니다.

  • 또한 + 연산을 통해 String 객체를 합치는 경우 GC 되기 전까지 메모리에 부하를 주게 됩니다.

  • 이와 반대로 StringBuilder, StringBuffer 는 메모리에 append 하는 방식으로 클래스에 대한 객체를 생성하지 않습니다.

  • 다만 이 둘의 차이는 StringBuilder 는 thread safe 하지 않고, StringBuffer 는 thread safe 하다는 점이 있습니다.

  • JDK 1.5 이전 버전

    • 문자열 연산을 할 때 각 리터럴마다 새로운 메모리를 할당
  • JDK 1.5 이후 버전

    • 문자열 연산을 할 때 컴파일 과정에서 StringBuilder 로 컴파일 되도록 변경
    • 단 반복문을 사용하여 문자열 연산을 할 경우 이전과 똑같이 새로운 메모리 할당
  • 성능

    • StringBuilder > StringBuffer >>> String

9. 컬렉션 프레임워크에 대해 설명해주세요.

  • 컬렉션 프레임워크는 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 클래스의 집합입니다.

  • 주요 인터페이스로는 List, Set, Map, Queue 등이 있습니다.

  • 이중 Map 은 다른 것들과 특징이 달라 Collection 을 상속하지 않고 나머지는 Collection 을 상속합니다. 장점으로는 효율적이고 빠른 코드 작성을 할 수 있습니다.

  • 정의: 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 클래스 집합

  • 특징

    • 가변적
    • 데이터 삽입, 탐색, 정렬 등 편리한 API 다수 제공
    • JDK 1.2 버전부터 지원
      • 초기에는 Vector, Properties, Stack, HashTable, Dictionary 등이 제공되고, 통일성있고 표준화된 인터페이스가 존재하지 않았다.
  • 장점

    • 다수의 데이터 처리를 직접 구현하지 않고 사용하면 되서 편리하다.
    • 효율적인 데이터 처리로 인해 성능 향상이 있다.

10. List 인터페이스의 구현체에 대해 설명해주세요.

  • List 의 구현체로는 ArrayList, LinkedList, Vector, Stack 이 존재합니다.

  • ArrayList 는 배열처럼 연속된 메모리에 저장되어 검색은 용이하나 삽입, 삭제에는 부적절합니다.

  • LinkedList 는 양방향 포인터 구조로 데이터 검색보다는 삽입과 삭제가 빈번하게 일어나는 경우에 유용합니다.

  • Vector 는 ArrayList 와 동일하게 배열로 구현되어있고 내부에서 동기 처리가 일어나는 것이 특징입니다.

  • 마지막으로 Stack 은 Vector 를 상속받아 동기 처리가 일어납니다.

  • ArrayList

    • 내부적으로 배열을 사용하여 메모리가 연속적으로 저장된다.
    • 배열과 달리 메모리가 동적이다.
    • 데이터 삽입, 삭제 시 해당 데이터 이후 모든 데이터의 복사가 이루어지므로 빈번한 삽입, 삭제는 비효울적이다.
    • 인덱스를 통해 검색하므로 검색에 효율적이다.
  • LinkedList

    • 양방향 포인터 구조로 저장된다.
    • 데이터의 삽입, 삭제 시 포인터의 위치만 바꾸면 되기 때문에 효율적이다.
    • 데이터 검색 시 포인터를 타면서 순회하기 때문에 비효율적이다.
  • Vector

    • 내부적으로 배열을 사용한다.
    • 동기화 처리를 하여 Thread Safe 하다.
    • 성능이 좋지 않고 무거워 잘 쓰이지 않는다.
    • 멀티 스레드 환경에서도 ArrayList 를 활용하는 것이 좋다.
    class MyList {
      ArrayList<T> list = new ArrayList<>(Collections.synchronizedList());
    }
  • Stack

    • Vector 를 상속받아 구현하였다.
    • 동기화 처리를 하여 Thread-safe 하다.

11. Array와 ArrayList는 어떤 차이점이 있을까요?

  • Array 와 ArrayList 의 차이는 길이의 가변성, 제네릭 지원, 기본 데이터 타입 저장 유무에 차이가 있습니다.
  • 배열은 길이가 불변에 제네릭을 지원하지 않고 기본 데이터 타입을 저장할 수 있고, ArrayList 는 길이가 가변이고 제네릭을 지원합니다. 기본 데이터 타입은 저장할 수 없습니다.

12. ArrayList 와 LinkedList를 비교해주세요.

  • ArrayList 는 배열로 구현되어 메모리에 순차적으로 데이터가 저장되게 됩니다.
  • 이러한 특성 때문에 데이터를 검색할 때 인덱스를 통해 찾을 수 있어 효율적입니다.
  • 하지만 삽입 또는 삭제 시 해당 데이터의 이후 데이터들을 모두 복사하는 과정이 필요하므로 빈번한 삽입, 삭제에는 비효율적입니다.
  • 반면, LinkedList 는 양방향 포인터 구조로 되어있어 데이터가 메모리에 불연속적으로 저장됩니다. 데이터와 데이터 사이의 포인터를 통해 연결되어 삽입, 삭제 시 포인터만 바꾸면 되서 효율적이지만 검색 시 데이터들을 순회해야 하기 때문에 비효율적입니다.

13. Map 인터페이스의 구현체에 대해 설명해주세요.

  • Map 의 구현체로는 엔트리가 배열로 저장되고 해시 값을 인덱스로 사용하는 HashMap, 엔트리가 Linked List 를 사용하는 LinkedHashMap, 레드 블랙 트리로 저장되는 TreeMap, 다중 락을 지원하는 ConCurrentHashMap, 싱글 락을 지원하는 HashTable 이 있습니다.
  • HashMap
    • Entry<Key, Value> 가 배열의 형태로 저장
    • 배열의 인덱스로 Key 객체의 해시코드 값 이용
      • 입력과 무관하게 출력.
      • 정렬 제공 X
    • Key, Value 모두 null 값을 허용
    • Thread-safe 하지 않음
    • 검색 및 삽입 시간 복잡도: O(1)
    • Fail-Fast Iterators
  • LinkedHashMap
    • Entry<Key, Value> 가 LinkedList 형태로 저장
    • 입력 받은 순서대로 저장
      • 입력한 순서대로 출력.
    • Key, Value 모두 null 값을 허용
    • Thread-safe 하지 않음
    • 검색 및 삽입 시간 복잡도: O(1)
  • TreeMap
    • Red Black 자료구조로 저장
    • 키 값을 기준으로 오름차순으로 정렬
      • 입력받은 순서 보장 X
    • Key null 값을 허용안함
    • Thread-safe 하지 않음
    • 검색 및 삽입 시간 복잡도: O(logn)
  • ConCurrentHashMap
    • Key, Value 모두 null 값을 허용 X
    • Thread-safe 보장
      • 버킷 단위로 lock
      • 버킷의 수 == 동시작업 가능한 쓰레드 수
      • 수정 작업시 동기 처리
  • HashTable
    • Key, Value 모두 null 값을 허용 X
    • Thread-safe 보장
      • 모든 작업에 동기 처리
    • Fail-Safe Iterators

14. HashTable에 대해 설명해주세요.

  • 키 벨류 형태로 데이터를 저장하는 자료구조로 배열을 이용합니다.
  • 모든 메서드에 synchronized 키워드가 붙어있어 thread-safe 하다는 특징이 있습니다. 다만 이때문에 성능 저하가 존재할 수 있습니다.

15. HashMap과 HashTable을 비교해주세요.

  • HashMap 과 HashTable 모두 배열의 형태로 저장되는 점에서 동일합니다. 다만 키 값에 null 을 허용하는지, 동기 처리를 하는지에 차이가 존재합니다.

16. HashMap과 ConcurrentHashMap은 어떤 차이가 있나요?

  • HashMap과 ConcurrentHashMap은 키 값에 null 허용 유무, 동기 처리 유무에 차이가 있습니다.
  • ConcurrentHashMap 은 버킷에 lock 을 걸어 버킷의 수만큼 스레드를 동작시킬 수 있습니다. 또한 읽기 작업에는 락을 걸지 않고 수정 시에만 적용한다는 특징이 있습니다.

17. Set 인터페이스의 구현체에 대해 설명해주세요.

  • Set 의 구현체로는 해시 값을 사용하는 HashSet, 저장된 순서를 유지하는 LinkedHashSet, 레드 블랙 트리의 형태로 저장되는 TreeSet 등이 있습니다.
  • HashSet
    • 저장된 순서 유지 X
    • null 입력 가능
    • 해시 값으로 저장
      • 검색 속도가 빠르다.
    • 내부적으로 HashMap 을 사용함
  • LinkedHashSet
    • 저장된 순서 유지 O
    • null 입력 가능
    • 내부적으로 LinkedHashMap 을 사용함
  • TreeSet
    • 데이터가 정렬된 형태로 저장
      • Red Black 트리 자료구조 이용
    • null 입력 가능 X
    • 내부적으로 TreeMap 을 사용함

18. List와 Set을 비교해주세요.

  • List 와 Set 은 인덱스를 통해 접근하는지, 동일한 요소를 저장할 수 있는지에 차이가 있습니다.
  • 구현체에 따라 다르지만 List 는 인덱스를 통해 접근할 수 있고 동일한 요소를 저장할 수 있습니다. 반면, Set 은 인덱스를 통해 접근할 수 없고 동일한 요소를 저장할 수 없습니다.
ListSet
indexed sequencenon-indexed sequence
중복 허용중복 허용 X

19. Java의 컴파일(실행) 과정을 설명해주세요.

  • 먼저 JVM 이 OS 로부터 메모리를 할당받습니다.
  • 이후 컴파일러에 의해 소스코드가 바이트코드로 변환됩니다. 다음 Class Loader 를 통해 Class 파일들을 JVM 으로 로딩시킨 후 이 파일들을 Execution Engine 이 해석한 후 실행하게됩니다.
  1. 자바로 개발된 프로그램을 실행하면 JVM은 OS로부터 메모리를 할당합니다.
  2. 자바 컴파일러(javac)가 자바 소스코드(.java)를 자바 바이트코드(.class)로 컴파일합니다.
  3. Class Loader를 통해 JVM Runtime Data Area로 로딩합니다.
  4. Runtime Data Area에 로딩 된 .class들은 Execution Engine을 통해 해석합니다.
  5. 해석된 바이트 코드는 Runtime Data Area의 각 영역에 배치되어 수행하며 이 과정에서 Execution Engine에 의해 GC의 작동과 스레드 동기화가 이루어집니다.

20. JDK, JRE, JVM에 대해 설명해주세요.

  • JVM 은 자바 가상머신으로 바이트 코드를 실행시킬 수 있습니다. JRE 는 자바 실행 환경으로 실행하는데 필요한 도구들이 들어있습니다. JVM 이 이 안에 포함됩니다. JDK 는 개발을 위한 도구입니다. 컴파일러와 JRE 가 포함됩니다.
  • JVM
    • 바이트 코드(.class)를 돌리는 자바 가상머신
    • 운영체제 별 제공
      • 플랫폼에 독립적
  • JRE
    • 실행 환경을 제공하는 도구들
    • JVM 과 Java Class 라이브러리들, Class Loader 로 구성
      • Class Loader: 프로그램을 실행하는데 필요한 클래스를 JVM 에 로딩하는 역할 수행
  • JDK
    • 프로그램을 개발하기 위해 필요한 도구 모음
    • JRE 와 컴파일러, 디버깅 툴 등으로 구성

21. JVM의 메모리 구조에 대해 설명해주세요.

  • JVM 의 Runtime Data 영역에는 클래스의 정보를 저장하는 메서드 영역, 참조타입이 저장되는 힙 영역, 스레드 별 지역 변수, 매개변수 등이 저장되는 스택 영역, 스레드가 실행중인 스택 프레임 주소를 저장하는 PC 레지스터, 자바가 아닌 다른 언어로 작성된 코드를 저장하는 Native 메서드 스택가 있습니다.
  • Method Area
    • Class Area, Static Area
    • 클래스 정보가 저장됨
      • 멤버변수, 메서드 정보(이름, 타입, 접근제어자 등)
      • class 인지 interface 인지, static 변수, final 변수
    • 상수 자료형을 위한 Runtime Constant Pool 존재
    • 모든 스레드에서 공유
    • GC 대상
  • Heap Area
    • 레퍼런스 타입이 저장됨
      • new 연산자로 생성된 객체와 배열 저장
      • String Pool
    • 모든 스레드에서 공유
    • 런타임 시 동적으로 할당되어 사용
    • 참조가 없는 객체는 GC 대상이 됨
  • Stack Area
    • 프로그램 실행 과정에서 임시로 할당되거나 메서드 영역에서만 존재하는 데이터 저장
      • 지역변수, 매개변수, 임시 데이터 등
    • 스레드마다 스택 하나씩 할당
  • PC register
    • 스레드에서 실행할 명령어 주소값 저장
    • 스레드가 시작될 때 생성됨
  • Native Method Stack
    • .class 의 바이트 코드가 아닌 기계어로 작성된 프로그램을 실행시키는 영역
    • JAVA 가 아닌 다른 언어로 작성된 코드를 위한 영역

22. 정적 바인딩, 동적 바인딩

  • 바인딩
    - 값이 할당되어 변경할 수 없는 상태
  • 정적 바인딩
    • 값이 컴파일 시점에 확정되는 것
    • static, private, final 메서드 및 변수
      • override 가 불가능
    • 성능상으로 이점이 있음
  • 동적 바인딩
    • 값이 런타임 시점에 확정되는 것
    • method overriding
    • 다형성에 유리
    • 힙 영역에 vtable(가상 메서드 테이블) 생성
      • vtable 은 클래스가 자신이 상속받은 메서드를 포함한 모든 메서드의 주소값을 저장하는 곳이다.
      • vtable -> 4byte
      • 메서드를 오버라이딩 했을 경우 오버라이딩한 메서드의 주소값을 가지기 때문에 부모 클래스 타입으로 선언되어도 오버라이딩한 메서드가 호출된다.
  • 예상 질문
    - 정적 바인딩과 동적 바인딩의 차이점에 대해 설명해주세요.

23. 가비지 컬렉터

  • 가비지 컬렉터란?
    • Heap 메모리에 있는 사용하지 않는 객체를 제거하는 역할을 수행합니다.
    • Weak Generational Hypothesis: Heap 영역 설계 시 고려한 전제
      • 대부분의 객체는 금방 접근 불가능한 상태가 된다.
      • 오래된 객체에서 새로운 객체로의 참조는 아주 적게 존재한다.
    • Heap 메모리 영역은 객체의 생존 기간에 따라 Young, Old 2가지 영역으로 설계되었다.
    • 장점
      • 메모리를 수동으로 관리하던 것에서 비롯된 에러를 예방할 수 있다.
    • 단점
      • GC 의 메모리 해제 타이밍을 개발자가 정확히 알기 어렵다.
      • 삭제될 객체를 탐색하고 삭제하는 과정에서 오버헤드가 발생한다.

24. 객체 지향 프로그래밍(캡상추다)

  • 객체지향 프로그래밍이란?
    - 프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법
    • 장점
      • 코드 재사용 용이
      • 유지보수 용이
      • 대형 프로젝트에 적합
    • 단점
      • 처리 속도 느림
      • 설계가 어려움
  • 객체지향의 특징
    - 캡슐화
    - 클래스 안에 서로 연관있는 속성과 기능들을 하나의 캡슐로 만들어 데이터를 외부로부터 보호하는 것
    - 목적
    - 데이터 보호: 외부로부터 클래스에 정의된 속성과 기능들을 보호
    - 데이터 은닉: 내부의 동작을 감추고 외부에는 필요한 부분만 노출 (각 객체 고유의 독립성과 책임 영역을 안전하게 지킬 수 있다.)
    - 접근제어자와 getter/setter 를 통해 구현
    - 상속
    - 기존의 클래스를 재활용하여 새로운 클래스를 작성하는 자바의 문법요소
    - 코드의 재사용을 통해 반복적인 코드를 최소화하고 공유하는 속성과 기능에 간편하게 접근할 수 있다.
    - 상속과 구현
    - 상속: 상위 클래스의 속성과 기능들을 하위 클래스에서 그대로 받아 사용하거나 오버라이딩을 통해 선택적으로 재정의해서 사용
    - 구현: 반드시 인터페이스에 정의된 추상 메서드의 내용이 하위 클래스에서 정의
    - 추상화
    - 객체의 공통적인 속성과 기능을 추출하여 정의하는 것
    - 추상클래스와 인테페이스로 구현
    - 제어 추상화
    - 메서드의 작동방식과 같은 내부 로직을 숨기는 것
    - 프로그래밍을 빠르게 설계하고 구현할 수 있다.
    - 데이터 추상화
    - 객체를 간단한 개념으로 일반화 시키는 것
    - 공통 기능을 미리 개발함으로써, 구조를 빠르게 확장시킬 수 있다.
    - 다형성
    - 객체의 속성이나 기능이 상황에 따라 여러 가지 형태를 가질 수 있는 성질
    - 메서드 오버라이딩과 오버로딩을 통해 구현
    - 가능한 것 예시
    - 여러 종류의 객체를 배열로 다룰 수 있다.
    - 하나의 타입만으로 여러 가지 타입의 객체를 참조할 수 있다.

25. SOLID 원칙

  • SRP(Single Responsibility Principle): 단일 책임 원칙
    • 어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 한다.
      • 클래스는 하나의 책임만 가진다.
  • OCP(Open Closed Priciple): 개방 폐쇄 원칙
    • 확장에는 열려있으나 변경에는 닫혀있어야 한다.
    • 다형성과 연관이 있다.
  • LSP(Listov Substitution Priciple): 리스코프 치환 원칙
    - 하위 타입은 상위 타입으로 대체할 수 있다.
  • ISP(Interface Segregation Principle): 인터페이스 분리 원칙
    • 클라이언트의 목적과 용도에 적합한 인터페이스만 제공하는 것
    • 불필요한 간섭을 최소화할 수 있다.
  • DIP(Dependency Inversion Principle): 의존 역전 원칙
    • 고수준의 모듈은 저수준의 모듈에 의존하면 안된다.
    • 추상화된 것은 구체적인 것에 의존하면 안된다.
    • 변하기 쉬운 것에 의존하는 것보다 변하지 않는 것에 의존해야 한다.

26. 객체 지향 프로그래밍 vs 절차 지향 프로그래밍

  • 설계 방식
    - 객체지향
    - 자료구조와 이를 중심으로한 모듈들을 설계한 후 이들의 실행 순서와 흐름을 조합하는 방식
    - 절차지향
    - 프로그램의 순서와 흐름을 먼저 세우고 필요한 자료구조와 함수들을 설계하는 방식
  • 목적
    - 객체지향
    - 필요한 객체들의 종류과 속성등이 중심
    - 절차지향
    - 실행 순서, 절차 중심
  • 장단점
    - 객체지향
    • 장점
      • 코드의 재사용성이 높다.
      • 디버깅이 쉽다.
    • 단점
      • 설계가 어렵다.
      • 처리 속도가 느리다.
  • 절차지향
    • 장점
      • 컴퓨터의 처리구조와 유사해 실행 속도가 빠르다.
    • 단점
      • 유지보수가 어렵다.
      • 실행 순서가 정해져 있어 순서가 바뀌면 결과가 바뀐다.
      • 디버깅이 어렵다.
profile
안녕하세요, 박경서입니다.

0개의 댓글