티스토리 뷰

개인공부/Spring

스프링1

날따라해봐요요롷게 2022. 5. 9. 16:44

JAVA

  • OOP의 특징인 상속, 캡슐화, 다형성, 추상화 를 설명할 수 있습니다.

- 캡슐화 (자바 접근 제한자)

: 정보의 은닉

  • 실제로 구현 부분을 외부에 드러나지 않도록 하는 것
  • 변수와 메소드를 하나로 묶음
  • 데이터를 외부에서 직접 접근하지 않고 함수를 통해서만 접근

public : 모두가 접근 가능
protected : 상속 / 같은 패키지 내 클래스에서 접근 가능
default : 같은 패키지 내 클래스에서 접근 가능
private : 본인만 접근 가능

 

-상속

: 재사용 + 확장

  • 자식 클래스가 부모 클래스의 특성과 기능을 물려받는 것
  • 기능의 일부분을 변경하는 경우 자식 클래스에서 상속받아 수정 및 사용함
  • 상속은 캡슐화를 유지, 클래스의 재사용이 용이하도록 해 준다.

-추상화

  • 인터페이스로 클래스들의 공통적인 특성(변수, 메소드)들을 묶어 표현하는 것

-다형성 

  • 어떤 변수,메소드가 상황에 따라 다른 결과를 내는 것

오버로딩(Overloading) : 하나의 클래스에서 메소드의 이름이 같지만 시그니처(이름, 반환형, 인자)가 다른 것

오버라이딩(Overriding) : 부모 클래스의 메소드를 자식 클래스의 용도에 맞게 재정의하여 코드의 재사용성을 높임

 

역할과 구현을 분리
• 역할과 구현으로 구분하면 세상이 단순해지고, 유연해지며 변경도 편리해진다.

 

장점
• 클라이언트는 대상의 역할(인터페이스)만 알면 된다.
• 클라이언트는 구현 대상의 내부 구조를 몰라도 된다.
• 클라이언트는 구현 대상의 내부 구조가 변경되어도 영향을 받지 않는다.
• 클라이언트는 구현 대상 자체를 변경해도 영향을 받지 않는다.

 

자바 언어의 다형성을 활용
• 역할 = 인터페이스
• 구현 = 인터페이스를 구현한 클래스, 구현 객체
• 객체를 설계할 때 역할과 구현을 명확히 분리
• 객체 설계시 역할(인터페이스)을 먼저 부여하고, 그 역할을 수행하는 구현 객체 만들기

 

다형성의 본질
• 인터페이스를 구현한 객체 인스턴스를 실행 시점에 유연하게 변경할 수 있다. (DI)
• 다형성의 본질을 이해하려면 협력이라는 객체사이의 관계에서 시작해야함
• 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있다.

 

스프링과 객체 지향
• 다형성이 가장 중요하다!
• 스프링은 다형성을 극대화해서 이용할 수 있게 도와준다.
• 스프링에서 이야기하는 제어의 역전(IoC), 의존관계 주입(DI)은 다형성을 활용해서 역할과
구현을 편리하게 다룰 수 있도록 지원한다.
• 스프링을 사용하면 마치 레고 블럭 조립하듯이! 공연 무대의 배우를 선택하듯이! 구현을 편
리하게 변경할 수 있다.

 


  • 좋은 객체 지향 설계를 위해 SOLID 원칙을 지키려 노력합니다.

- SRP (Single Responsibility Principal)

: THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE.

작성된 클래스는 하나의 기능만 가지며 클래스가 제공하는 모든 서비스는 그 하나의 책임을 수행하는 데 집중되어 있어야 한다는 원칙입니다.

이는 어떤 변화에 의해 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 함을 의미합니다. SRP원리를 적용하면 무엇보다도 책임 영역이 확실해지기 때문에 한 책임의 변경에서 다른 책임의 변경으로의 연쇄작용에서 자유로울 수 있습니다. 뿐만 아니라 책임을 적절히 분배함으로써 코드의 가독성 향상, 유지보수 용이라는 이점까지 누릴 수 있으며 객체지향 원리의 대전제 격인 OCP원리뿐 아니라 다른 원리들을 적용하는 기초가 됩니다.

 

하나의 책임이라는 것은 모호하다.
• 클 수 있고, 작을 수 있다.
• 문맥과 상황에 따라 다르다.
• 중요한 기준은 변경이다. 변경이 있을 때 파급 효과가 적으면 단일 책임 원칙을 잘 따른 것

 

-OCP (개방폐쇄의 원칙: Open Close Principle)

: YOU SHOULD BE ABLE TO EXTEND A CLASSES BEHAVIOR, WITHOUT MODIFYING IT.

소프트웨어의 구성요소(컴포넌트, 클래스, 모듈, 함수)는 확장에는 열려있고, 변경에는 닫혀있어야 한다는 원리이다.
이것은 변경을 위한 비용은 가능한 줄이고 확장을 위한 비용은 가능한 극대화 해야 한다는 의미로, 요구사항의 변경이나 추가사항이 발생하더라도, 기존 구성요소는 수정이 일어나지 말아야 하며, 기존 구성요소를 쉽게 확장해서 재사용할 수 있어야 한다는 뜻입니다. 로버트 C. 마틴은 OCP는 관리가능하고 재사용 가능한 코드를 만드는 기반이며, OCP를 가능케 하는 중요 메커니즘은 추상화와 다형성이라고 설명하고 있습니다

 

적용방법
- 변경(확장)될 것과 변하지 않을 것을 엄격히 구분합니다.
- 이 두 모듈이 만나는 지점에 인터페이스를 정의합니다.
- 구현에 의존하기보다 정의한 인터페이스에 의존하도록 코드를 작성 합니다

 

OCP 개방-폐쇄 원칙
문제점

• MemberService 클라이언트가 구현 클래스를 직접 선택
• MemberRepository m = new MemoryMemberRepository(); //기존 코드
• MemberRepository m = new JdbcMemberRepository(); //변경 코드
• 구현 객체를 변경하려면 클라이언트 코드를 변경해야 한다.
• 분명 다형성을 사용했지만 OCP 원칙을 지킬 수 없다.
• 이 문제를 어떻게 해결해야 하나?
• 객체를 생성하고, 연관관계를 맺어주는 별도의 조립, 설정자가 필요하다.

 

 

-LSP (리스코브 치환의 원칙: The Liskov Substitution Principle)
FUNCTIONS THAT USE POINTERS OR REFERENCES TO BASE CLASSES MUST BE ABLE TO USE OBJECTS OF DERIVED CLASSES WITHOUT KNOWING IT

LSP를 한마디로 한다면, “서브 타입은 언제나 기반 타입으로 교체할 수 있어야 한다.”라고 할 수 있습니다. 즉, 서브 타입은 언제나 기반 타입과 호환될 수 있어야 합니다. 달리 말하면 서브 타입은 기반 타입이 약속한 규약(public 인터페이스, 물론 메소드가 던지는 예외까지 포함됩니다.)을 지켜야 합니다.

상속은 구현상속(extends 관계)이든 인터페이스 상속(implements 관계)이든 궁극적으로는 다형성을 통한 확장성 획득을 목표로 합니다. LSP원리도 역시 서브 클래스가 확장에 대한 인터페이스를 준수해야 함을 의미합니다. 다형성과 확장성을 극대화 하려면 하위 클래스를 사용하는 것보다는 상위의 클래스(인터페이스)를 사용하는 것이 더 좋습니다. 일반적으로 선언은 기반 클래스로 생성은 구체 클래스로 대입하는 방법을 사용합니다. 생성 시점에서 구체 클래스를 노출시키기 꺼려질 경우 생성 부분을 Abstract Factory 등의 패턴을 사용하여 유연성을 높일 수 있습니다. 상속을 통한 재사용은 기반 클래스와 서브 클래스 사이에 IS-A관계가 있을 경우로만 제한 되어야 합니다. 그 외의 경우에는 합성(composition)을 이용한 재사용을 해야 합니다. 상속은 다형성과 따로 생각할 수 없습니다. 그리고 다형성으로 인한 확장 효과를 얻기 위해서는 서브 클래스가 기반 클래스와 클라이언트 간의 규약(인터페이스)를 어겨서는 안 됩니다. 결국 이 구조는 다형성을 통한 확장의 원리인 OCP를 제공 하게 됩니다. 따라서 LSP는 OCP를 구성하는 구조가 됩니다. 객체지향 설계 원리는 이렇게 서로가 서로를 이용하기도 하고 포함하기도 하는 특징이 있습니다. LSP는 규약을 준수하는 상속구조를 제공 합니다. LSP를 바탕으로 OCP는 확장하는 부분에 다형성을 제공해 변화에 열려있는 프로그램을 만들 수 있도록 합니다.

 


• 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀수 있어야 한다
• 다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다는 것, 다형성을 지원하기 위한 원칙, 인터페이스를 구현한 구현체는 믿고 사용하려면, 이 원칙이 필요하다.
• 단순히 컴파일에 성공하는 것을 넘어서는 이야기
• 예) 자동차 인터페이스의 엑셀은 앞으로 가라는 기능, 뒤로 가게 구현하면 LSP 위반, 느리더라도 앞으로 가야함

 

 

- ISP (인터페이스 분리의 원칙: Interface Segregation Principle)
CLIENTS SHOULD NOT BE FORCED TO DEPEND UPON INTERFACES THAT THEY DO NOT USE.

: ISP원리는 한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다는 원리입니다. 즉 어떤 클래스가 다른 클래스에 종속될 때에는 가능한 최소한의 인터페이스만을 사용해야 합니다. ISP를 ‘하나의 일반적인 인터페이스보다는, 여러 개의 구체적인 인터페이스가 낫다’라고 정의할 수 도 있습니다. 만약 어떤 클래스를 이용하는 클라이언트가 여러 개고 이들이 해당 클래스의 특정 부분집합만을 이용한다면, 이들을 따로 인터페이스로 빼내어 클라이언트가 기대하는 메시지만을 전달할 수 있도록 합니다. SRP가 클래스의 단일책임을 강조한다면 ISP는 인터페이스의 단일책임을 강조합니다. 하지만 ISP는 어떤 클래스 혹은 인터페이스가 여러 책임 혹은 역할을 갖는 것을 인정합니다. 이러한 경우 ISP가 사용되는데 SRP가 클래스 분리를 통해 변화에의 적응성을 획득하는 반면, ISP에서는 인터페이스 분리를 통해 같은 목표에 도달 합니다

 

사용방법

 

- 클래스의 상속을 이용하여 인터페이스를 나눌 수 있습니다.
이와 같은 구조는 클라이언트에게 변화를 주지 않을 뿐 아니라 인터페이스를 분리하는 효과를 갖습니다. 하지만 거의 모든 객체지향 언어에서는 상속을 이용한 확장은 상속받는 클래스의 성격을 디자인 시점에 규정해 버립니다. 따라서 인터페이스를 상속받는 순간 인터페이스에 예속되어 제공하는 서비스의 성격이 제한 됩니다.

 

- 위임(Delegation)을 이용하여 인터페이스를 나눌 수 있습니다.
위임이란, 특정 일의 책임을 다른 클래스나 메소드에 맡기는 것입니다. 만약 다른 클래스의 기능을 사용해야 하지만 그 기능을 변경하고 싶지 않다면, 상속 대신 위임을  사용 합니다.

 

• 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다
• 자동차 인터페이스 -> 운전 인터페이스, 정비 인터페이스로 분리
• 사용자 클라이언트 -> 운전자 클라이언트, 정비사 클라이언트로 분리
• 분리하면 정비 인터페이스 자체가 변해도 운전자 클라이언트에 영향을 주지 않음
• 인터페이스가 명확해지고, 대체 가능성이 높아진다.

 

- DIP (의존성역전의 원칙: Dependency Inversion Principle)
A. HIGH LEVEL MODULES SHOULD NOT DEPEND UPON LOW LEVEL MODULES. BOTH SHOULD DEPEND UPON ABSTRACTIONS.
B. ABSTRACTIONS SHOULD NOT DEPEND UPON DETAILS. DETAILS SHOULD DEPEND UPON ABSTRACTIONS

 

의존 관계의 역전 Dependency Inversion 이란 구조적 디자인에서 발생하던 하위 레벨 모듈의 변경이 상위 레벨 모듈의 변경을 요구하는 위계관계를 끊는 의미의역전입니다. 실제 사용 관계는 바뀌지 않으며, 추상을 매개로 메시지를 주고 받음으로써 관계를 최대한 느슨하게 만드는 원칙입니다.

DIP의 키워드는 ‘IOC’, ‘훅 메소드*(슈퍼클래스에서 디폴트 기능을 정의해두거나 비워뒀다가 서브클래스에서 선택적으로 오버라이드할 수 있도록 만들어둔 메소드를 훅(hook) 메소드라고 합니다. 서브클래스에서는 추상 메소드를 구현하거나, 훅 메소드를 오버라이드하는 방법을 이용해 기능의 일부를 확장합니다.)*’’, ‘확장성’입니다. 이 세 가지 요소가 조합되어 복잡한 컴포넌트들의 관계를 단순화하고 컴포넌트 간의 커뮤니케이션을 효율적이게 합니다.

 

• 프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안된다.” 의존성 주입은 이 원칙
을 따르는 방법 중 하나다.
• 쉽게 이야기해서 구현 클래스에 의존하지 말고, 인터페이스에 의존하라는 뜻
• 앞에서 이야기한 역할(Role)에 의존하게 해야 한다는 것과 같다. 객체 세상도 클라이언트
가 인터페이스에 의존해야 유연하게 구현체를 변경할 수 있다! 구현체에 의존하게 되면 변
경이 아주 어려워진다.

 

 

----------

 

• 객체 지향의 핵심은 다형성
• 다형성 만으로는 쉽게 부품을 갈아 끼우듯이 개발할 수 없다.
• 다형성 만으로는 구현 객체를 변경할 때 클라이언트 코드도 함께 변경된다.
• 다형성 만으로는 OCP, DIP를 지킬 수 없다.
• 뭔가 더 필요하다. --> DI(Dependency Injection): 의존관계, 의존성 주입

사용 영역(클라이언트 코드)과 구성 영역(config 파일)으로 분리하였을 때, 구성 영역에서만 변경해 준다면
사용 영역의 코드를 손 대지 않고 변경할 수 있습니다.

 


객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다. (협력)

• 객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용된다.


 

  • JVM 메모리 구조를 설명 할 수 있습니다.

-> 

 

jvm

: 자바 가상 머신으로 자바 바이트 코드를 실행할 수 있는 주체다.

CPU나 운영체제(플랫폼)의 종류와 무관하게 실행이 가능하다.

즉, 운영체제 위에서 동작하는 프로세스로 자바 코드를 컴파일해서 얻은 바이트 코드를 해당 운영체제가 이해할 수 있는 기계어로 바꿔 실행시켜주는 역할을 한다.

 

JVM의 구성을 살펴보면 크게 4가지(Class Loader, Execution Engine, Garbage Collector, Runtime Data Area)로 나뉜다.

JVM은 Java Virtual Machine의 약자로, 자바 가상 머신이라고 부릅니다. 그리고 자바와 운영체제 사이에서 중개자 역할을 수행하며, 자바가 운영체제에 구애 받지 않고 프로그램을 실행할 수 있도록 도와줍니다. 또한, 가비지 컬렉터를 사용한 메모리 관리도 자동으로 수행하며, 다른 하드웨어와 다르게 레지스터 기반이 아닌 스택 기반으로 동작합니다.

 

 

jvm 실행 과정

먼저, 자바 컴파일러에 의해 자바 소스 파일은 바이트 코드로 변환됩니다.

그리고 이러한 바이트 코드를 JVM에서 읽어 들인 다음에, 복잡한 과정을 거쳐서 어떤 운영체제든간에 프로그램을 실행할 수 있도록 만드는 것입니다.

 

 

1. Class Loader

자바에서 소스를 작성하면 Person.java 처럼 .java파일이 생성된다.

.java 소스를 자바컴파일러가 컴파일하면 Person.class 같은 .class파일(바이트코드)이 생성된다.

이렇게 생성된 클래스파일들을 엮어서 JVM이 운영체제로부터 할당받은 메모리영역인 Runtime Data Area로 적재하는 역할을 Class Loader가 한다. (자바 애플리케이션이 실행중일 때 이런 작업이 수행된다.)

 

2. Execution Engine

Class Loader에 의해 메모리에 적재된 클래스(바이트 코드)들을 기계어로 변경해 명령어 단위로 실행하는 역할을 한다.

명령어를 하나 하나 실행하는 인터프리터(Interpreter)방식이 있고 JIT(Just-In-Time) 컴파일러를 이용하는 방식이 있다.

JIT 컴파일러는 적절한 시간에 전체 바이트 코드를 네이티브 코드로 변경해서 Execution Engine이 네이티브로 컴파일된 코드를 실행하는 것으로 성능을 높이는 방식이다.


클래스 로더를 통해 JVM 내의 Runtime Data Area에 배치된 바이트 코드들을 명렁어 단위로 읽어서 실행합니다. 최초 JVM이 나왔을 당시에는 인터프리터 방식이었기때문에 속도가 느리다는 단점이 있었지만 JIT 컴파일러 방식을 통해 이 점을 보완하였습니다. JIT는 바이트 코드를 어셈블러 같은 네이티브 코드로 바꿈으로써 실행이 빠르지만 역시 변환하는데 비용이 발생하였습니다. 이 같은 이유로 JVM은 모든 코드를 JIT 컴파일러 방식으로 실행하지 않고, 인터프리터 방식을 사용하다가 일정한 기준이 넘어가면 JIT 컴파일러 방식으로 실행합니다.

 

3. Garbage Collector

Garbage Collector(GC)는 Heap 메모리 영역에 생성(적재)된 객체들 중에 참조되지 않는 객체들을 탐색 후 제거하는 역할을 한다.

GC가 역할을 하는 시간은 정확히 언제인지를 알 수 없다. (참조가 없어지자마자 해제되는 것을 보장하지 않음)

또 다른 특징은 GC가 수행되는 동안 GC를 수행하는 쓰레드가 아닌 다른 모든 쓰레드가 일시정지된다.

특히 Full GC가 일어나서 수 초간 모든 쓰레드가 정지한다면 장애로 이어지는 치명적인 문제가 생길 수 있는 것이다.

 

Garbage Collector(GC)는 힙 메모리 영역에 생성된 객체들 중에서 참조되지 않은 객체들을 탐색 후 제거하는 역할을 합니다. 이때, GC가 역할을 하는 시간은 언제인지 정확히 알 수 없습니다.

 

4. Runtime Data Area

JVM의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역이다.

이 영역은 크게 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack로 나눌 수 있다.


4-1. Method area (메소드 영역)

클래스 멤버 변수의 이름, 데이터 타입, 접근 제어자 정보같은 필드 정보와 메소드의 이름, 리턴 타입, 파라미터, 접근 제어자 정보같은 메소드 정보, Type정보(Interface인지 class인지), Constant Pool(상수 풀 : 문자 상수, 타입, 필드, 객체 참조가 저장됨), static 변수, final class 변수등이 생성되는 영역이다.

 

모든 쓰레드가 공유하는 메모리 영역입니다. 메소드 영역은 클래스, 인터페이스, 메소드, 필드, Static 변수 등의 바이트 코드를 보관합니다.

 

4-2. Heap area (힙 영역)

new 키워드로 생성된 객체와 배열이 생성되는 영역이다.

메소드 영역에 로드된 클래스만 생성이 가능하고 Garbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역이다.


모든 쓰레드가 공유하며, new 키워드로 생성된 객체와 배열이 생성되는 영역입니다. 또한, 메소드 영역에 로드된 클래스만 생성이 가능하고 Garbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역입니다.

Heap 에서는 참조되지 않는 인스턴스와 배열에 대한 정보 또한 얻을 수 있기 때문에 GC 의 주 대상이기도 합니다. 이때, 인스턴스가 생성된 후 시간에 따라서 다음과 같이 5가지 부분으로 나눌 수가 있습니다.

 

Eden, Survivor0, Survivor1, Old , Perm 으로 나누어지게 됩니다.

Young Gen 이라고 불리는 비교적 신생 데이터 부분은 Eden , Survivor0 , Survivor1 입니다. Eden 에는 new 를 통해 새롭게 생성된 인스턴스가 위치하며, 이후에는 Survivor 로 이동하게 됩니다. 이곳에서도 참조되지 않는 인스턴스와 배열 대상으로 Minor GC 가 일어납니다. 하지만 가장 주요하게 GC 가 일어나는 부분은 그 이후의 부분인 Old 부분입니다.

Perm 의 경우에는 클래스의 메타 정보 및 static 변수를 저장하고 있었습니다. Java 8 버전 이후로 Native 영역에 존재하는 Metaspace 라는 영역으로 대체되었습니다. 

또한, 각 Thread 별로 메모리를 할당받는 Java Stack 영역과 달리 조금은 속도가 느린 점이 있습니다. 그리고 앞서 언급했듯이 모든 Thread 들이 해당 영역인 Heap 을 공유하여 Java 의 동시성 문제가 발생하게 됩니다. 각각의 Thread 메모리가 따로 관리되는 것과 달리 이 부분은 Thread 에 의해서 공유가 되기 때문에 Thread Safe 하지 않습니다. 이 때문에 해당 영역에 있는 객체나 인스턴스를 사용하게 되면, synchronized 블록을 사용하는 방법 등을 비롯하여 동시성을 지켜주는 방법을 사용해야 합니다.

 

 

4-3. Stack area (스택 영역)

 

지역 변수, 파라미터, 리턴 값, 연산에 사용되는 임시 값등이 생성되는 영역이다.

int a = 10; 이라는 소스를 작성했다면 정수값이 할당될 수 있는 메모리공간을 a라고 잡아두고 그 메모리 영역에 값이 10이 들어간다. 즉, 스택에 메모리에 이름이 a라고 붙여주고 값이 10인 메모리 공간을 만든다.

클래스 Person p = new Person(); 이라는 소스를 작성했다면 Person p는 스택 영역에 생성되고 new로 생성된 Person 클래스의 인스턴스는 힙 영역에 생성된다.

그리고 스택영역에 생성된 p의 값으로 힙 영역의 주소값을 가지고 있다. 즉, 스택 영역에 생성된 p가 힙 영역에 생성된 객체를 가리키고(참조하고) 있는 것이다.

메소드를 호출할 때마다 개별적으로 스택이 생성된다.

 

메서드 호출 시마다 각각의 스택 프레임(그 메서드만을 위한 공간)이 생성합니다. 그리고 메서드 안에서 사용되는 값들을 저장하고, 호출된 메서드의 매개변수, 지역변수, 리턴 값 및 연산 시 일어나는 값들을 임시로 저장합니다. 마지막으로, 메서드 수행이 끝나면 프레임별로 삭제합니다.

 

각 Thread 별로 따로 할당되는 영역입니다. Heap 메모리 영역보다 비교적 빠르다는 장점이 있습니다. 또한, 각각의 Thread 별로 메모리를 따로 할당하기 때문에 동시성 문제에서 자유롭다는 점도 있습니다. 각 Thread 들은 메소드를 호출할 때마다 Frame 이라는 단위를 추가(push)하게 됩니다. 메소드가 마무리되며 결과를 반환하면 해당 Frame 은 Stack 으로부터 제거(pop)가 됩니다.

Frame 은 메소드에 대한 정보를 가지고 있는 Local Variable, Operand Stack 그리고 Constant Pool Reference 로 구성이 되어 있습니다. Local Variable 은 메소드 안의 지역 변수들을 가지고 있습니다. Operand Stack 은 메소드 내 연산을 위해서, 바이트 코드 명령문들이 들어있는 공간입니다. Constant Pool Reference 는 Constant Pool 참조를 위한 공간입니다. 이렇게 구성된 Java Stack 은 메소드가 호출될 때마다 Frame 이 쌓이게 됩니다.

 

 

4-4. PC Register (PC 레지스터)

Thread(쓰레드)가 생성될 때마다 생성되는 영역으로 Program Counter 즉, 현재 쓰레드가 실행되는 부분의 주소와 명령을 저장하고 있는 영역이다. (*CPU의 레지스터와 다름)

이것을 이용해서 쓰레드를 돌아가면서 수행할 수 있게 한다.


쓰레드가 시작될 때 생성되며, 생성될 때마다 생성되는 공간으로 쓰레드마다 하나씩 존재합니다. 쓰레드가 어떤 부분을 무슨 명령으로 실행해야할 지에 대한 기록을 하는 부분으로 현재 수행중인 JVM 명령의 주소를 갖습니다.

 


 

  • JAVA 8 에서 제공하는 Stream API를 설명할 수 있습니다.

-> 

 

절차적 프로그래밍 방식

입력을 받아 명시된 순서대로만 처리하고 결과를 내는 방식

구조적 프로그래밍 방식

절차적 프로그래밍 방식의 개선된 형태
프로그램을 함수단위로 나누고 함수끼리 호출하는 방식
큰 문제를 해결하기 위해 문제를 작은 단위들로 나누어 해결하는 방식
Top-Down 방식이라고도 한다.

 

객체 지향 프로그래밍 방식

구조적 프로그래밍 방식의 개선된 형태
큰 문제를 작게 쪼개는 것이 아니라, 작은 문제들을 해결하는 객체를 만든다.
객체들을 조합해 큰 문제를 해결하는 Bottom-Up 방식

 

😉OOP의 장점과 단점

장점

코드의 재사용성이 높아진다.
유지보수가 쉽다.
코드가 간결해진다.

단점

처리 시간이 비교적 오래 걸린다.
프로그램을 설계할 때 많은 고민과 시간을 투자해야한다.

 


출처 : https://www.nextree.co.kr/p6960/

 

객체지향 개발 5대 원리: SOLID

현재를 살아가는 우리들은 모두 일정한 원리/원칙 아래에서 생활하고 있습니다. 여기서의 원칙 이라 함은 좁은 의미로는 개개인의 사고방식이나 신념, 가치관 정도가 될 수가 있겠고, 넓게는 한

www.nextree.co.kr

https://jeong-pro.tistory.com/148

 

JVM 구조와 자바 런타임 메모리 구조 (자바 애플리케이션이 실행될 때 JVM에서 일어나는 일, 과정

JVM(Java Virtual Machine) : 자바 가상 머신으로 자바 바이트 코드를 실행할 수 있는 주체다. CPU나 운영체제(플랫폼)의 종류와 무관하게 실행이 가능하다. 즉, 운영체제 위에서 동작하는 프로세스로 자

jeong-pro.tistory.com

https://steady-coding.tistory.com/305

 

JVM 메모리 구조란? (JAVA)

안녕하세요? 코딩 중독입니다. 오늘은 JVM 메모리 구조에 대해 알아보겠습니다. JVM이란? JVM 메모리 구조를 설명하기 전에 JVM이 무엇인지 알아야 합니다. JVM은 Java Virtual Machine의 약자로, 자바 가상

steady-coding.tistory.com

https://tecoble.techcourse.co.kr/post/2021-08-09-jvm-memory/

 

JVM에 관하여 - Part 3, Run-Time Data Area

Java 로 작성된 코드는 어떻게 돌아가는 걸까? 해당 물음에 답을 찾기 위한 JVM 시리즈 3편, JVM 의 구성요소 중 Run-Time Data Area 에 관한 글입니다. 이번 글에서는 JVM…

tecoble.techcourse.co.kr

https://www.baeldung.com/java-stack-heap

 

Stack Memory and Heap Space in Java | Baeldung

Explore how Stack Memory and Heap Space works and when to use them for developing better Java programs.

www.baeldung.com

 

 

'개인공부 > Spring' 카테고리의 다른 글

스프링2  (0) 2022.05.12
면접 준비 - spring framework  (0) 2022.05.11
CRUD 구현  (0) 2021.11.02
설정 - ORACLE DB  (0) 2021.09.15
Lombok  (0) 2021.09.15
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함