객체지향이란?
객체지향 프로그래밍이란 현실 세계의 사물들을 객체로 바라보는 인간 관점 프로그래밍 패러다임이라 할 수 있다.
프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 상호작용을 통해 로직을 구성하는 프로그래밍 방법
객체지향 프로그래밍 장점
- 코드 재사용이 용이하고 상속을 통한 확장이 가능하다.
- 클래스 단위로 모듈화가 되어있어 대형 프로젝트에 적합하고, 유지보수가 용이하다.
클래스와 객체의 차이점
클래스는 객체를 정의하는 틀, 설계도이다.
객체는 식별 가능한 개체 또는 사물을 뜻한다. 클래스를 통해 만들어지는 인스턴스를 대신해 말하기도 한다.
C와 Java의 차이점
C는 절차 지향 언어이고, Java는 클래스를 이용한 설계적인 측면이 강조된 객체지향 언어라는 점이 가장 큰 차이라 생각한다.
Java의 특징
- 객체지향언어이기 때문에 캡슐화, 상속, 다형성, 추상화의 특징을 가진다.
- JVM을 이용하기 때문에 OS에 독립적이다.
- Garbage Collector 지원한다.
객체지향 4대 원칙
- 추상화
- 불필요한 정보는 숨기고 중요한 정보만을 표현함으로 공통의 속성이나 기능을 묶어 이름을 붙인다.
- 캡슐화
- 상태와 행위를 클래스라는 캡슐에 담아 모듈화한 것이다. 코드 재사용이 용이해진다.
- 상속
- 부모 클래스의 속성과 기능을 이어받아 사용할 수 있다.
- 기능의 일부분은 수정하고 싶다면 오버라이딩하여 사용 가능하다.
- 다형성
- 오버라이딩
- 자식 클래스에서 부모 클래스의 메소드를 재정의하는 것을 의미합니다.
- 코드 중복이 줄고, 확장에 용이하다.
- 오버로딩
- 같은 이름의 메소드의 매개변수 타입 및 개수를 달리하여 호출하는 방법
- 가독성이 좋아진다.
- 오버라이딩
객체지향 설계 5원칙
SOLID 설계 원칙은 객체 내부의 응집도를 높이고, 객체 외부간의 결합도를 낮추는 것이 목표입니다. 이를 통해 요구 사항이나 변경 사항에 유연하게 대처가 가능하고, 확장성 있는 구조로 설계 할 수 있습니다.
- 단일 책임 원칙: SRP
- 한 클래스는 단 하나의 책임을 가져야 한다.
- 개방 폐쇄 원칙: OCP
- 확장에는 열려있고 변경에는 닫혀 있어야 한다. 추상화를 통해 관계를 구축하고 다형성을 이용하여 객체지향적 설계를 하는 원칙이다.
- 리스코프 치환 원칙: LSP
- 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
- 인터페이스 분리 원칙: ISP
- 사용하는 인터페이스만 구현하기 위하여 각 행위에 대한 인터페이스는 서로 분리되어야 한다.
- 의존 역전 원칙: DIP
- 구체적인 것에 의존하지 말고, 변하기 쉬운 것에 의존하지 말자.
- 즉 구상 클래스에는 의존하지 말고, 인터페이스에 의존해야 한다.
인터페이스와 추상 클래스의 차이점
추상클래스
- 추상 메서드 한개 이상 선언해주어야 한다. 일반 메서드 선언도 가능하다.
- 상속을 통해 서브 클래스에서 완성하도록 유도하는 클래스이다.
- 클래스이기 때문에 하나만 상속이 가능하다.
- 사용처: 추상 클래스는 객체의 추상적인 상위 개념으로 공통된 개념을 표현할 때 사용한다. 그리고 추상 클래스를 상속하는 집합 간에는 연관 관계가 있다.
인터페이스
- 추상 클래스와 유사하지만 일반 메소드, 멤버 변수를 갖을 수 없다는 점을 포함하여 추상 클래스보다 추상화 정도가 높다.
- 인터페이스 다중 구현으로 다중 상속을 허용하지 않는 자바의 문제를 해결할 수 있다.
- 추상 메서드와 상수만 선언 가능하다. default 메서드 생성 가능하긴 하다.
- 사용처: 인터페이스는 구현 객체가 같은 동작을 한다는 것을 보장하기 위해 사용한다. 인터페이스를 구현하는 집한 간에는 관계가 없을 수 있다.
Java에서 다중 상속을 허용하지 않는 이유
'다이아몬드 문제'라고도 한다.
같은 이름의 메소드를 가진 두 클래스에게 상속을 받는 한 클래스가 있다면 이 클래스는 어떤 클래스의 메소드를 사용해야할지 모호하여 충돌이 생긴다.
인터페이스로 다중 상속을 대신 구현할 수 있는데 인터페이스는 기능(메소드)을 따로 작성해주어야 함으로 문제가 발생하지 않는다.
GC란?
- 힙 영역에서 사용하지 않는 인스턴스들을 정리해주는 작업을 말한다.
- C와 C++와는 다르게 Java는 메모리를 자동으로 정리해준다.
- 객체는 힙 영역에 저장되고, 스택 영역에는 이를 가리키는 주소값이 저장된다. 힙 영역에서 자신을 가르키는 주소값이 없으면 참조되고 있지 않다고 판단하고 GC는 이를 제거한다.
Reflection이란?
- 구체적인 클래스 타입을 알지 못해도, 클래스의 메소드, 타입, 변수들에 접근할 수 있게 해주는 Java API이다.
- JVM에서 실행되는 어플리케이션의 런타임 동작을 검사하거나 수정할 수 있는 기능이 필요한 프로그램에서 사용된다.
Generics란?
컴파일 과정에서 타입 체크하여 객체의 타입 안정성을 높이고 형변환의 번거로움을 줄여줍니다.
- 데이터 타입을 일반화 하는 것
- 컴파일 과정에서 객체의 타입을 체크하여 넣어준다.
- 객체의 타입 안정성을 높이고 형 변환의 번거로움을 줄여준다.
Java 접근 제어자
접근제어자를 사용함으로 외부 객체의 무분별한 접근으로부터 내부 데이터를 보호할 수 있다. (데이터 무결성).
- public : 모든 패키지 허용
- protected : 같은 패키지, 다른 패키지인 경우 자식 클래스의 접근 허용
- (default) package : 같은 패키지 접근 허용
- private : 같은 클래스 내 접근만 허용
final
변경 불가능하도록 만드는 Java 키워드이다.
선언하면 절대 변하지 않는 값, 즉 상수라는 개념을 갖게된다.
static
- 정적 멤버(클래스 멤버)를 만들 수 있는 키워드이다.
- static 키워드를 통해 생성하면 메모리에 적재될 때 스태틱 영역에 할당됩니다.
- 때문에 객체의 존재 여부 없이 사용 가능하고 모든 객체가 공유가 가능합니다.
- GC 관리 영역 밖에 존재하기 때문에 너무 남발하면 성능에 문제를 줄 수 있다.
JVM
Java Virtual Machine은 운영체제 위에서 동작하는 프로세스로 자바 소스코드를 컴파일해서 얻은 바이트코드를 운영체제에 맞게 기계어 코드로 해석해준다. 이런 과정으로 인해서 속도와 메모리에서 단점이 있을 수 있지만 OS에 종속적이지 않다는 장점이 있습니다. 그리고 GC를 통해 메모리 관리를 해줍니다.
- JVM 동작 과정
- 프로그램이 실행되면 JVM은 OS로부터 메모리를 할당받는다.
- 자바 컴파일러(javac)가 자바 소스코드(.java)를 읽어들여 자바 바이트코드(.class)로 변환시킨다.
- 클래스 로더가 class 파일들을 JVM으로 로딩합니다.
- 로딩된 class 파일들은 실행 엔진(Execution Engine)을 통해 해석됩니다.
- 해석된 바이트코드는 메모리(Runtime Data Area)에 적재되어 수행됩니다.
Java는 Multi Thread 환경이다, MultiThread란?
하나의 프로세스 내에서 둘 이상의 스레드가 동시에 작업을 수행하는 것이다.
멀티 스레드 프로그램은 공유하는 자원에 대해 동기화 문제가 발생할 수 있으므로 동기화 처리를 해주어야 한다.
Java SE와 Java EE 차이
- Java SE : 자바 표준 에디션
- Java EE : Java SE API + 추가 API 탑재 (JSP, Servlet 등)
Call By Value / Call By Reference
- Call By Value
- 기본 자료형 변수를 복사하는 경우 발생하며, 값 자체로 해석하기 때문에 서로에게 영향을 주지 않는다.
- 원래의 값이 보존 된다.
- 복사를 하기 때문에 메모리 사용량이 늘어난다.
- Call By Reference
- 객체 참조 변수를 복사하는 경우에 발생하며, 참조 자료형 변수는 저장하고 있는 값을 주소로 해석하기 때문에 객체를 참조하게 된다.
- 참조를 하기 때문에 빠르다.
- 참조를 하기 때문에 원래 값이 영향을 받는다.
JAVA는 Call By Value? Reference?
Java는 Call By Value라고 생각합니다.
객체를 넘겨주어 값을 수정한 경험이 있어서 Reference라고 생각할 수 있지만,
값을 넘겨줄때 주소값만 전달해주고 그 주소값을 보고 객체를 같이 참조하고 있는 것입니다.
즉, 호출자 변수와 수신자 파라미터는 Stack 영역 내에서 각각 다른 변수라는 것이 핵심입니다.
*주소값을 넘기는게 Reference 아닌가? A. Call By Reference라면 새로운 객체를 할당했을 때 원본 변수도 영향을 받아야 합니다.
try-with-resources
자바 7 버전 이전에는 finally 문에서 자원을 해제시켜주어야 했습니다.
try-with-resources는 try()안에 사용할 리소스 객체를 선언해주면 try 블록이 끝났을 때 자원을 자동으로 반납해주는 문법입니다.
자바 9버전에서는 try 블록 밖에서 객체를 선언하고 try() 안에는 인스턴스의 변수를 넣어주는 것도 가능하게 되었습니다.
Java 8 / Java 11 특징
- Java 8
- 람다 표현식 : 함수형 프로그래밍을 지원하기 위한 기능입니다.
- Stream : 고차함수를 지원합니다.
- Optional : Null-Safety를 제공합니다.
- 날짜 시간 API / StringJoiner 기능 제공
- Java 11
- String 메서드 추가
- strip() / stripLeading() / stripTrailing()
- isBlacnk() (= String.trim().isEmpty())
- repeat(n) : 문자열 n개 반복하여 붙인다
- Java 11의 Default GC 성능 개선
- 람다에서 로컬 변수
- String 메서드 추가
람다
자바 8부터 추가된 익명 함수 람다는 함수형 프로그래밍을 가능하게 하는 기능 중 하나입니다. 이로 인해 특정 메소드를 파라미터로 넘기거나 결과로 반환할 때 인터페이스를 넘기던 형태를 코드 한 줄로 간결하게 표현하는 것이 가능해졌습니다.
@FunctionallInterface
함수형 인터페이스는 하나의 추상 메서드만을 갖는 인터페이스입니다. 람다식을 다루기 위한 인터페이스이기도 하는데요 그 이유는 람다식과 인터페이스의 메서드가 1:1로 연결되어야 하기 때문입니다. @FunctionalIInterface 어노테이션은 인터페이스에 대해서 강제적으로 하나의 메서드만 갖게 해주며 2개 이상인 경우 컴파일 오류가 발생하게 합니다.
직렬화
자바는 입출력시 스트림이라는 통로를 통해 데이터가 이동한다.
하지만 객체는 바이트형이 아니라서 스트림을 통해 파일에 저장하거나 네트워크로 전송할 수 없다. 객체를 스트림을 통해 입출력하기 위해서는 바이트 배열로 변환해주어야 하는데 이를 직렬화라고 한다.
스트림을 통해 받은 직렬화된 객체를 원래 모양으로 만드는 과정을 역직렬화라고 한다.
SerialVersionUID
- JVM은 직렬화와 역직렬화를 하는 시점의 클래스에 대한 버전 번호를 부여하는데, 만약 그 시점에 클래스의 정의가 바뀌어 있다면 새로운 버전 번호를 할당하게 된다.
- 그래서 직렬화할 때의 버전 번호와 역직렬화를 할 때의 버전 번호가 다르면 InvalidClassException이 발생하기 때문에 이런 문제를 해결하기 위해 SerialVersionUID를 사용한다.
String / StringBuffer / StringBuilder
- String
- 객체를 할당하면 메모리 공간에 별동이 없고 불변이다.
- 불변이기 때문에 여러 스레드에서 동시에 참조하려 하더라도 동기화를 신경쓰지 않아도 된다.
- 많은 문자열을 선언 및 연산 시 성능저하 우려된다.
- StringBuffer
- 가변
- 동기화를 지원하여 멀티 스레드 환경에서 사용된다.
- StringBuilder
- 가변
- 동기화를 지원하지 않아 싱글 스레드 환경에서 주로 사용한다.
리터럴("")과 new String()의 차이
- new String()은 객체를 생성하는 것이기 떄문에 Heap 메모리 영역에 저장된다.
- ""는 Heap안에 있는 String Constant Pool 영역에 저장된다.
Synchronized(동기화)
- 여러 개의 쓰레드가 하나의 자원에 접근하려 할 때 하나의 쓰레드만 접근 가능하도록 하는 것
- 동기화 방법
- synchronized 메서드를 만들어 사용
- synchornized 블록 사용
어노테이션
런타임 또는 컴파일 시 해석되는 어노테이션은 인터페이스를 기반으로 한 문법으로 주석처럼 코드에 달아 클래스에 의미를 명시하거나 기능을 주입할 수 있습니다.
'CS > 면접 준비' 카테고리의 다른 글
백엔드 면접 질문 (0) | 2023.02.05 |
---|---|
웹과 네트워크 면접 질문 (0) | 2022.12.23 |
운영체제 면접 질문 (0) | 2022.12.22 |
Database 면접 질문 (0) | 2022.12.22 |
Spring & Spring Boot 면접 질문 (0) | 2022.12.22 |