Back-end

JAVA...

elysia365 2021. 4. 21.

JAVA의 특징

 - 썬 마이크로 시스템즈에서 개발하여 1996년 공식적으로 발표한 객체지향언어

 - 객체지향 언어이기 때문에 개발 후 유지보수 용이

 - JVM(Java Virtual Machine)을 통해 실행되므로 운영체제 독립적이며, 자동으로 메모리 관리를 해주며, 안정적

 

JAVA 소스의 실행 과정

 - Java Compiler 는 source code를 byte code로 컴파일함

 - Class Loader 는 class 파일을 JVM의 메모리 영역인 Runtime Data Area 로 로딩함

 

JAVA의 메모리 구조

JVM (Java Virtual Machine) 의 메모리 구조

 - Method Area 와 Heap은 모든 스레드가 공유하는 공간이며, Stack, PC Register, Native Method Stack 은 스레드 별 공간 할당

 1) Method Area : JVM이 시작될 때 생성되는 공간으로 바이트코드가 이 영역에 저장 (클래스 정보, 변수 정보, static 변수가 저장되고 모든 스레드가 공유하는 영역)

 2) Heap : 동적으로 생성된 객체가 저장되는 영역으로 Garbage Collction의 대상이 되는 공간

 3) Stack : 지역변수나 매서드의 매개변수, 임시적으로 사용되는 변수, 메서드의 정보가 저장되는 영역

 4) PC Register : 스레드가 어떤 부분을 어떤 명령어로 수행할지 저장하는 공간

 5) Native Method Stack : JAVA가 아닌 다른 언어로 작성된 코드를 위한 공간이며, JNI(Java Native Method Interface)를통해 호출되는 C/C++ 등의 코드를 수행하기 위한 공간

   

Stack 과 Heap 메모리 저장 예시

※ Primitive Type (원시 타입) 이 아닌 Reference Type 은 실행될 때마다 Stack 에 쌓여서 넣었다 뺐다 하면 비효율적이므로 Heap 영역에 저장하고 그 메모리의 주소를 참조하는 변수를 Stack 영역에 저장

 

 

 

JVM (Java Virtual Machine) 의 코드 실행

 - Runtime Data Area에 로딩된 클래스 파일은 Execution Engine 을 통해 해석됨

 - Interpreter 는 명령어를 한줄씩 해석하면서 실행

 - JIT(Just In Time) Compiler 는 Interpreter의 단점을 해결하기 위한 방법으로 Runtime 시간에 한번에 해석하여 실행

JAVA 코드의 실행 단계

 - JNI (Java Native Method Interface) 는 JVM에 의해 실행되는 코드 중 네이티브로 실행하는 것이 있다면 해당 네이티브 코드를 호출하거나 호출 될 수 있도록 만든 일종의 프레임워크

 - Native Method Library 는 네이티브 메소드 실행에 필요한 라이브러리

 

 

 

JVM의 구조

 1. 프로그램이 실행되면 OS로부터 프로그램이 필요하는 메모리를 먼저 할당 받는다.

 2. 자바 컴파일러를 통해 개발자가 작성한 소스코드(.java) 를 바이트코드(.class)로 컴파일한다.

 3. Class Loader에서 바이트코드를 Runtime Data Area 에 로딩 시킨다.

 4. 로딩된 바이트코드를 execution engine을 통해 기계어로 해석한다.

 5. 해석된 바이트코드들은 Runtime Data Area에 배치되어 실질적인 수행이 이루어진다.

 

 

 

객체지향 프로그래밍 (OOP : Object Oriented Programming) 이란?

 - 객체 중심적 프로그래밍 기법이며, 현실 세계를 프로그래밍화한 것이다. 현실 세계의 사물들을 객체라고 보고, 그 객체들로부터 개발하고자 하는 애플리케이션에 필요한 특징들을 뽑아와 프로그래밍 하는 것

 - 대표적인 특징으로는 캡슐화, 추상화, 상속, 다형성 이 있다.

 

1) 캡슐화 (Encapsulation)

 - 하나의 객체에 대해 속성과 메소드를 하나로 묶는 것 이며, 캡슐화를 하는 중요한 목적은 정보의 은닉화이다. 외부로부터 보호해야하는 속성은 private 로 선언하여 getter나 setter 등의 메서드를 통해서만 간접적으로 접근이 가능하도록 하는 것이 캡슐화의 중요한 목적

 

2) 추상화 (Abstraction)

 - 공통의 속성이나 기능을 묶는 것이며, 객체에서 공통된 속성과 행위를 추출하는 것을 추상화라고 한다. 대표적으로 기린, 코뿔소, 사자, 소 라는 객체를 동물이라는 추상적인 객체로 정의할 수 있다.

 

3) 상속 (Inheritance)

 - 상위의 부모 객체의 속성을 하위 객체가 물려 받는 것이며, 부모 클래스가 가지고 잇는 속성(프로퍼티, 메서드) 등을 그대로 자식 클래스가 물려 받아 재사용이 가능하며, 기능을 재정의하여 사용 가능하다.

 

4) 다형성 (Polymorphism)

 - 상속을 통해 기능을 확장하거나 변경하는 것을 가능하게 한다. 이를 통해 코드의 재사용, 코드 길이 감소 등의 효과로 유지보수가 용이하도록 해준다. 다형성을 구현하는 방법으로는 Overriding 과 Overloading 이 있다.

Overriding 은 부모 클래스를 상속받은 자식 클래스에서 부모 클래스의 메서드 이름, arguments를 받아서 새롭게 정의하는 것이며, 다른 기능을 하는 메서드를 재정의할 수 있다. 

Overloading 은 같은 클래스에서 같은 이름을 가진 메서드가 여러개 존재하고 있는 상태이다. 메서드의 이름은 같지만 매개변수(arguments) 가 다르다. 

 

 

 

인터페이스 (Interface) 란?

 - 자바에서 인터페이스는 클래스들이 구현해야 하는 내용을 지정하는데 사용되는 일종의 추상 클래스이다. 프로토콜의 개념과 비슷하다.

 - 인터페이스는 대규모 프로젝트 개발 시 일관되고 정형화된 개발을 위한 표준화가 가능하다.

 

자바의 접근제한자란?

 - 객체의 멤버 중에 외부에 공개되면 안되는 것들이 있을 수 있는데, 이러한 경우에 사용하는 것이 접근제한자이다.

 1) public : 모든 접근을 허용

 2) protected : 같은 패키지에 있는 객체와 상속관계의 객체들만 허용 

 3) default : 같은 패키지에 있는 객체들만 허용

 4) private : 현재 겍체 내에서만 허용 

 

자바8에서의 변화

 1) 람다 표현식 (Lambda expression) : 함수형 프로그래밍이 가능해짐

 - 이름이 없는 일회용 클래스인 익명 클래스의 한 개의 메서드를 식으로 표현한 것이며, 람다 표현식을 사용하면 기존의 불필요한 코드를 줄여주고, 가독성을 높여준다.

 

 2) 스트림 API (Stream API) : 데이터를 추상화하여 다룰 수 있게 됨

 - 자바에서는 여러 개의 데이터를 저장하기 위해 배열이나 컬렉션을 사용하고, 데이터에 접근할 때는 반복문이나 반복자(iterator) 를 사용하기 때문에 매번 코드를 작성해야하며, 코드의 재사용이 거의 불가능했는데, 스트림API는 데이터를 추상화해서 다양한 형태로 저장된 데이터를 공통적인 방법으로 처리할 수 있다.

 - 필터-맵(filter-map) 기반의 API를 사용하여 lazy 연산을 통해 성능을 최적화

 

 3) java.time 패키지 : 더 직관적이고 개선된 Date, Time API를 제공

 - Date 클래스와 Calendar 클래스의 문제점 (월을 나타낼 때 0~11로 표현) 을 개선해서 java.time 패키지를 제공한다.

 

 4) 나즈혼 (Nashorn) : 자바스크립트의 새로운 엔진을 도입

 - 지금까지 자바스크립트의 기본 엔진은 모질라의 라이노 였는데, 새로운 엔진인 오라클의 나즈혼을 도입하여 성능이나 메모리 관리 측면에서 크게 개선된 스크립트 엔진

 

 

디자인 패턴

 1) 싱글톤 패턴 : 하나의 객체만을 생성해서 이후에 호출되는 곳에서는 이미 생성된 객체를 반환해서 프로그램 전반에서 하나의 인스턴스만 사용하게 하는 패턴으로 생성자를 private 로 외부에서 인스턴스 생성을 못하게 하고, static 변수에 인스턴스를 만들어 바로 초기화 하는 방법으로 구현 가능하다.

 

 - 싱글톤 패턴의 사용처 : 주로 공통된 객체를 여러개 생성해서 사용해야 하는 곳에 사용되며, Database connection pool 같은 곳에 사용된다. 

 

 2) 템플릿 메서드 패턴 : 전체적인 로직은 추상클래스의 일반 메소드로 선언해서 작성하며, 상속하는 구현클래스 마다 달라질 수 있는 부분은 추상메서드로 선언해두고, 구현클래스에서 오버라이딩하여 구현하도록 하는 디자인 패턴

템플릿 메서드 디자인 패턴 예제 (추상클래스 부분)

 

 3) 팩토리 메서드 패턴 : 팩토리 클래스가 객체 생성을 담당하고, 객체의 자료형은 하위클래스에 의해 결정되므로 동일한 형태로 프로그래밍이 가능하고 확장성 있는 프로젝트 구성 가능

 

프레임워크와 라이브러리의 차이

 - 프레임워크 : 개발자가 프로그래밍을 쉽게 하기 위한 기반과 틀을 제공하는 프로그램

 - 라이브러리 : 활용 가능한 도구들의 집합이며, 개발자가 필요한 라이브러리를 사용함

 ※ 프로그램은 프레임워크한테 호출 당하는 것이며, 라이브러리는 프로그램 내에서 호출 당하는 것

 

객체지향설계의 5대 원칙 (SOLID)

 - 클래스 안의 응집도는 높이고 타 클래스 간 결합도는 낮추는 관점의 원칙

 - 재사용성을 높이고 수정을 최소화 하여 유지보수를 용이하기 위한 목적

 

 - SRP (Single Responsibility Principle) 단일 책임 원칙 : 클래스와 메소드는 하나의 역할만 수행해야 한다.

 - OCP (Open Closed Principle) 개방 폐쇄 법칙 : 자신의 확장에는 개방되고, 주변의 변화에 대해서는 폐쇄되어야한다.

 - LSP (Liskov Substitution Principle) 리스코프 치환원칙 : 서브타입은 언제나 자신의 상위 타입으로 교체할 수 있다.

 - ISP (Interface Segregation Principle) 인터페이스 분리원칙 : 하나의 클래스에서 많은 역할을 해야 한다면, 각각의 인터페이스로 메소드를 분리하고, 각각의 상황에 맞게 인터페이스의 메소드를 구현해서 사용할 수 있다.

 - DIP (Dependency Inversion Principle) 의존 역전 원칙 : 추상클래스 또는 상위클래스는 구체적인 구현클래스 또는 하위클래스에 의존적이면 안된다. 구체적인 클래스는 변화에 민감하기 때문이다.

 

 

 

RESTFUL API란?

 - REST 기반으로 서비스 API를 구현한 것으로 HTTP 통신에서 어떤 자원에 대한 CRUD 요청을 Resource (URI) 와 Method (get, post, put, patch, delete) 로 표현하여 특정한 형태로 전달하는 방식이다.

 

 

 

Spring framework 의 특징

 - 경량의 프레임워크이다. 

 

 - IOC (Inversion of Control) 제어의 역전 : 스프링 전까지는 개발자가 프로그램의 흐름을 제어하는 주체였지만, 스프링에서는 프로그램의 흐름을 프레임워크가 주도하게 된다. 객체의 생성 부터 생명주기 관리를 컨테이너가 관리한다.

 

 - DI (Dependency Injection) 패턴을 지원하여 설정 파일을 통해 의존 관계를 설정할 수 있어서 개발자가 객체를 생성할 때 클래스 간의 의존성을 고려해서 프로그래밍 할 필요가 없다. 그리고, 소스 코드의 변경 없이 환경설정만으로 프로그램을 제어할 수 있다.

 

 - AOP (Aspect Oriented Programing) 를 지원하여 트랜잭션이나 로깅, 보안과 같은 공통 기능을 분리해서 각각의 모듈에 적용할 수 있다. 이 때문에, 개발자는 핵심 비즈니스 로직에만 집중할 수 있다.

 

 - POJO (Plain Old Java Object) 를 지원하기 때문에 스프링에서 객체간의 관계를 구성할 때 별도의 API를 사용하지 않고 그냥 일반적인 java 코드를 이용하여 객체를 구성할 수 있다. 이 때문에 개발자가 특정 라이브러리나 컨테이너의 기술에 종속적이지 않는다. 

 

 

 

 

리액티브 프로그래밍이란?

 - 기존의 명령형 프로그래밍이 정해진 절차에 따라 순서대로 실행되는 프로그램이었다면, 리액티브 프로그래밍은 데이터의 흐름을 미리 정의하고 데이터의 값이 변경되었을 때 관련 함수나 수식을 업데이트하는 것이다. 일종의 옵저버 패턴과 유사한 개념이며, 이벤트가 발생하면 해당 이벤트에 대한 동작이 실행된다.

 

 

 

 

마지막 궁금한 점?

 

 

 

 

추상클래스(Abstract Class)와 인터페이스(Interface) 차이 (JAVA 8 기준)

 - 목적의 차이 : 추상클래스는 그 추상클래스를 상속받아서 기능을 이용하고 확장하는데 목적이 있지만, 반면에 인터페이스는 함수의 껍데기만 존재하며, 함수의 구현을 강제하기 위해서 존재합니다.

 - 외형의 차이 : 인터페이스를 구현하는 어떤 클래스는 다른 여러개의 인터페이스들을 함께 구현할 수 있다. 하지만, 추상 클래스는 상속을 통해 구현하는데, 자바에서는 다중상속을 지원하지 않으므로 추상클래스를 상속받은 서브클래스는 다른 클래스를 상속받을 수 없다.

 

 - 용도의 차이 : 추상클래스는 관련성이 높은 클래스 간에 코드를 공유하고 싶은 경우 사용하며, 상속받은 클래스들이 공통으로 가지는 메서드와 필드가 많은 경우와 non-static, non-final 필드 선언이 필요한 경우. 즉, 각 인스턴스에서 state 변경을 위한 메서드를 선언할 수 있다. 반면, 인터페이스는 서로 관련성이 없는 클래스들이 인터페이스를 구현하게 되는 경우 사용한다. 그리고, 다중상속을 허용하고 싶은 경우에 사용한다.

 

※ JDK 에서 추상클래스와 인터페이스의 사용 예시

 - JDK에서 추상클래스의 대표적인 예시는 Collections Framework 의 일부인 AbstractMap 이다. AbstractMap의 서브클래스인 HashMap, TreeMap, ConcurrentHashMap 에서는 AbstractMap 에 정의되어 있는 get, put, isEmpty, containsKey 등의 메서드를 공유한다.

 반면, 여러개의 인터페이스를 구현하는 JDK의 클래스 예시로는 HashMap 이 있다. HashMap은 Serializable, Cloneable, Map<K,V> 를 구현한 클래스이다. 위 인터페이스를 통해 HashMap의 인스턴스는 복제가능하며, 직렬화가 가능하며, map으로써의 기능을 가질 수 있다.

 

 

쓰레드(Thread)란?

 - 프로그램을 실행하면 OS로부터 실행에 필요한 자원(메모리)를 할당받아 프로세스가 된다. 프로세스는 프로그램을 수행하는 데 필요한 데이터와 메모리 등의 자원과 쓰레드로 구성되어 있으며, 프로세스의 자원을 이용해서 실제로 작업을 수행하는 것이 쓰레드(Thread)이다. 그래서 모든 프로세스에는 최소한 하나 이상의 쓰레드가 존재하며, 둘 이상의 쓰레드를 가진 프로세스를 멀티쓰레드 프로세스라고 한다.

 

 - 멀티쓰레드의 장점은 CPU의 사용률을 향상시키고, 자원을 효율적으로 사용할 수 있으며, 사용자에 대한 응답성이 향상된다. 하지만 같은 프로세스 내에서 자원을 공유하면서 작업을 하기 때문에 발생할 수 있는 동기화(synchronization) 와 교착상태(deadlock) 과 같은 문제들을 고려해서 Thread safe 하게 프로그래밍해야 한다.

 

 

동기화(Synchronized)란?

 - Thread 의 불규칙적인 자원 공유를 막기 위해 사용하며, 보통 메서드의 선언부에 synchronized 키워드를 작성하여 사용한다.

 

 

직렬화(Serialize)란?

 - 컴퓨터의 메모리 상에 존재하는 데이터를 파일로써 저장하거나, 통신하는 다른 컴퓨터에게 알맞은 형식에 맞추어 전달하기 위해 바이트 스트림 형태로 만드는 것을 의미한다.

 - 프로그램에서 사용되는 데이터들은 연속적으로 위치해 있지 않고 내부적으로 포인터에 의해 참조 되고 있는데, 이는 프로그램이 실행중인 컴퓨터에서만 인식할 수 있는 형태이기 때문에, 다른 컴퓨터와 통신하며 데이터를 알맞게 전달하기 위해서는 데이터를 한 데 모아 포인터가 존재하지 않는 일련의 바이트 형태로 만들어서 보내야하기 때문에 직렬화라고 한다.

 

 

'Back-end' 카테고리의 다른 글

Oracle SQL을 MySQL로 전환하기  (0) 2024.05.21
Snowflake ID Generator  (0) 2023.04.16
Javascript 에서 9천조 이상의 숫자를 다룰때 고민할 부분  (0) 2023.04.13
Java 메모장  (0) 2021.05.16
스트림 (Stream) - JAVA 8  (0) 2021.05.15

댓글