객체지향 프로그래밍의 정의와 특징

데이터를 상태와 행위를 가진 객체로 추상화화여, 이런 데이터간 유기적인 상호작용을 통해 프로그램 로직을 구성하는 것 장점 :

  • 코드의 재사용성이 높다.
  • 변경이 용이하다.
  • 직관적으로 코드를 분석 할 수 있다.

단점 :

  • 처리속도가 느림
  • (객체)설계 중요, 많은 시간과 노력이 필요

특징 :

  • 추상화
  • 상속 : 하위 클래스가 상위 클래스의 속성과 행위를 물려받는 것
  • 캡슐화 : 외부에서 특정 속성이나 메서드를 사용하지 못하도록 은닉하는 것
  • 다형성 : 하나의 요소를 여러방식으로 구현하도록 하는 것

다형성이란?

객체지향 프로그래밍을 구성하는 주요 특징중 하나. 하나의 클래스 혹은 함수가 다양한 방식으로 동작할 수 있도록 하는 방식이다.


Overloading vs Overriding

다형성을 구현하는 대표적인 방법.

  • Overloading : 같은 메소드에 다른 타입 혹은 갯수의 파라미터를 정의함으로써 함수를 확장한다.
  • Overriding : 부모 클래스로부터 상속받은 함수를 하위클래스가 재정의 하는 것을 말한다.

추상클래스와 인터페이스의 차이

추상클래스와 인터페이스 모두 대부분 메소드를 선언만 하고, new 연산자로 인스턴스화가 불가능하다는 점이 비슷하다. 하지만 추상클래스는, 공통적인 속성을 가진 객체의 집합(공통점)을 묶어놓는 것을 주로 하고, 인터페이스는 객체들에게 어떠한 행동을 하기 위한 역할을 강제하는데 주로 둔다.


Wrapper Class란 ?

기본 자료형 타입을 객체로 다루기 위해서 사용하는 클래스들을 래퍼 클래스라고 한다.

  • 매개변수가 객체로 요구될 때
  • 기본형 값이 아닌 객체로 저장해야 할 때
  • 객체간 비교가 필요할 때

주로 사용된다.


컴파일 과정

개발자가 작성한 java파일은 컴파일러에 의해 바이트코드(클래스파일)로 변환된다. 여기서 JVM내 클래스로더에 의해 클래스파일이 적재되고, 링크되는 과정을 거쳐 메모리에 적재된다. 인터프리터 방식과 JIT컴파일러 방식을 통해 기계어로 변환된 파일이 실행된다.


JVM 구조

  • Class Loader : 컴파일러에 의해 변환된 바이트코드를 로드하고, 링크를 통해 배치시키는 작업을 하는 역할
  • Execution Engine : Runtime Data Area에 바이트코드를 실행시키는 역할
  • Garbage Collector : Heap영역에서 더이상 참조되지 않는 객체를 소멸시키는 역할
  • Runtime Data Area : 운영체제로부터 할당받은 메모리를 관리하는 영역

Java의 메모리 영역

Java JVM 메모리 영역은 크게 5가지로 구성되어 있다.

  • 메소드 영역 : 클래스와 static으로 선언된 변수들이 저장되는 공간
  • 스택 영역 : 쓰레드가 실행중일 때, 메소드 콜에 의해 저장되는 파라미터, 지역변수등이 저장되는 공간
  • 힙 영역 : new로 생성된 모든 객체들이 저장되는 공간, GC가 수행된다.
  • PC 레지스터 : 쓰레드가 실행중인 명령어 주소를 담는 공간
  • Native Method Stack : Java외 다른 언어로 작성된 코드들이 실행될 때 사용되는 공간 메소드영역과 힙영역은 쓰레드간 공유하며, 나머지는 독립적으로 할당받는다.

Heap영역의 구성은 어떻게 되어있나요?

  • Young 영역 : Eden, Survivor 1,2로 이루어져 있다.
  • Old 영역 : young영역에서 오래 살아남은 객체가 저장되는 공간이다.
  • MetaSpace(이전 Permanent 영역) : 클래스 로더에 의해 로딩된 클래스, 메소드에 대한 메타정보를 저장하는 영역

GC에 대해 설명해주세요

GC는 크게 Minor GC와 Major GC로 나뉜다.

  • Minor GC : Young 영역에 발생하는 GC. 처음 생성된 객체가 Eden영역에 저장이되고, 가득 차게 되면 계속 참조되는 객체들만 Survivor영역 중 한 곳으로 이동된다. 이 과정에서 Minor GC가 발생한다. 여기서 또 Eden영역이 가득차면, Eden영역과 이미 일부 찬 Survivor영역에서 참조되는 객체들만 찾아 다른 Survivor영역으로 이동한다.
  • Major GC : Old영역에서 발생하는 GC이다. Old영역이 Young영역보다 훨씬 크기에 GC할 때 더 많은 시간이 소요된다.

동등성과 동일성

  • 동등성 : 객체에 대한 정보가 같을 경우 - equals()로 보통 판단
  • 동일성 : 객체가 완전히 같은 객체일 경우 - ==로 판단

equals()와 hashcode()의 차이

우선 재정의하지 않은 equals()는 객체의 주소값을 비교한다. 하지만 통상적으로, 객체 내부 내용이 일치한지를 판단하기에 재정의하여 사용하는 경우가 많다. hashcode()는 객체의 메모리 주소의 해쉬 값을 반환한다. 객체가 동등할 때 비교할 수 있다. 보통 HashSet, HashMap, HashTable 등에서 객체 비교시 이 hashCode()를 사용한다.


자바의 접근제어자의 종류와 특징

  • public : 모두 접근 가능
  • protected : 자식 클래스와 같은 패키지 내 접근 가능
  • default : 같은 패키지 내 접근 가능
  • private : 해당 클래스 내에서만 접근 가능

static을 붙이면 ?

클래스가 로딩될 때, 메모리 공간을 할당하는데 처음 설정된 이 공간이 변하지 않는 것을 의미한다. 모든 객체가 해당 변수를 공유하며 사용 할 수 있다.


final 키워드?

  • 클래스에서 사용시 : 상속 불가
  • 메소드에서 사용시 : 오버라이딩 불가
  • 변수에서 사용시 : 값 변경 불가

List / Set / Map 차이

  • List : 순서가 있는 집합이며 중복을 허용한다
  • Set : 중복을 허용하지 않고, 보통 순서는 의미 없다
  • Map : 키-값 쌍으로 데이터를 저장하는 구조

String / StringBuilder / StringBuffer의 차이

우선 String은 Immutable하며, 나머지는 mutable하다. 즉, “hello”라는 문자열로 선언하고 그 후에 “hello world”라는 문자열로 치환하면, String은 두개의 String 상수가 생성되지만, 나머지는 뒤에 append되는 방식으로 사용된다. 그리고 StringBuffer는 Thread-safe하지만, StringBuilder는 Thread-safe하지 못하다.


ArrayList와 LinkedList의 차이?

ArrayList는 연속적으로 데이터를 저장하고, LinkedList는 노드로 이어져 있어 추가/삭제가 용이하다.
추가로, 데이터를 많이 할당해 기존 배열을 확장해야 할 때, ArrayList는 기존 배열의 값을 다시 복사해오는 작업이 필요하지만 LinkedList는 그런 작업이 필요하다.


HashTable / HashMap / ConcurrentHashMap의 차이

  • HashTable :
    • key,value에 null값을 허용하지 않는다.
    • Thread-safe하다.(메소드마다 synchronized를 이용해 동기화를 지원해 느리다)
    • enumeration으로 각 데이터 요소를 접근한다.
  • HashMap :
    • key, value에 null값을 허용한다.
    • Thread-safe하지 않다.
    • Iterator에 fail-fast방식으로 접근한다.
  • ConcurrentHashMap
    • key,value에 null값을 허용하지 않는다.
    • Thread-safe하다.(메소드마다가 아닌 각 데이터를 세그먼트화하여 쪼개진 데이터를 기준으로 동기화처리한다)
    • Iterator에 fail-safe방식으로 접근한다.

자바에 다중상속을 막은 이유

다중상속을 지원할 경우, 변수명 충돌 혹은 중복된 클로스 상속으로 오버라이딩이 모호한 다이아몬드 문제가 발생할 수 있다. 객체지향의 단일 책임 원칙과 리스코브 치환 원직을 지키기 위해 다중상속을 금지하였다.

  • 단일 책임 원칙 : 클래스는 오직 하나의 기능을 가지고 그 책임에 집중해야 한다.
  • 리스코프 치환 원칙 : 자식 클래스를 몰라도 부모 클래스의 함수를 사용할 수 있도록 대치가 가능해야 한다.

String new 연산자 통한 방식과 리터럴을 이용한 방식의 생성 차이

  • new 연산자 : Heap영역에 데이터가 존재한다.
  • 리터럴 방식 : 내부적으로 intern()메소드가 호출된다. String constant pool에 해당 리터럴이 있을 경우, 이 리터럴의 주소 값을 반환하고, 없으면 상수 풀에 리터럴을 생성하여 반환한다. 이 String Constant Pool은 자바 7부터 Heap영역에 저장된다.

checkedException과 uncheckedException의 차이

  • checkedException : 컴파일에러, 주로 IOException이 있다. 해당 Exception 발생시 트랜잭션 처리를 하지 않는다.
  • uncheckedException : 런타임에러, 주로 IndexOutOfBoundsException이 있다. 해당 Exception 발생시 데이터를 모두 롤백한다.

try-catch와 throw의 차이

  • try-catch : 예외를 발생하는 구간을 찾아서 직접 해결한다.
  • throw : 직접 예외를 발생시켜서 외부로 위임한다.

Thread를 구현하는 방법 2가지

  • Runnable인터페이스를 통해 구현
  • Thread클래스를 상속받아 구현

제너릭이란 ?

클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 방법이다.
객체 타입을 컴파일할 때 체크하고, 형변환을 따로 해주지 않아도 되는 이로움이 있다.


Optional이란 ?

Optional객체란 null일수도 있는 객체를 감싼 Wrapper 클래스이다. 개발을 하면서 개발자가 Null에 대한 체크나, 그에 따른 예외처리를 하지 않아도 되도록 덜어주는 좋은 클래스이다.


Java 7에서 달라진 점은 ?

Java 8에서 달라진 점은 ?


oksusutea's blog

꾸준히 기록하려고 만든 블로그