(1)

package com.example.demo;

import java.util.Arrays;
import java.util.Comparator;

public class StringComparator {

    public static void main(String[] args) {
        String[] names = { "today", "sirena", "apple" };
        Arrays.sort(names, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo( o2 );
            }
        });

    }
}

(2) : (1)번 코드를 Replace with lambda

package com.example.demo;

import java.util.Arrays;
import java.util.Comparator;

public class StringComparator {

    public static void main(String[] args) {
        String[] names = { "today", "sirena", "apple" };
        Arrays.sort(names, (o1, o2) -> o1.compareTo( o2 ));

    }
}

(3) : (2)번 코드를 Replace with method reference

package com.example.demo;

import java.util.Arrays;
import java.util.Comparator;

public class StringComparator {

    public static void main(String[] args) {
        String[] names = { "today", "sirena", "apple" };
        Arrays.sort(names, String::compareTo);

    }
}

 

- Lambda의 등장 배경

> 자바8에서는 병렬화를 위한 컬렉션( 배열, List, Set, Map )을 강화했고,

> 이러한 컬렉션을 더 효율적으로 사용하기 위하여 Stream이 추가되었고,

> 또 Stream을 더 효율적으로 사용하기 위하여 함수형 프로그램이 추가되었고,

> 또 함수형 프로그램을 더 효율적으로 사용하기 위하여 Lambda가 추가되었고,

> 또 Lambda를 위하여 인터페이스의 변화가 이루어졌다. (함수형 인터페이스)

장점 단점
1. 코드의 간결성 1. 호출이 까다롭다.
2. 지연연산 수행
- 불필요한 연산을 최소화
2. stream()에서 람다를 사용할 때 단순 for문 / while문 보다 성능이 떨어진다.
3. 병렬처리 가능 
- 멀티쓰레드를 활용하여 병렬처리를 사용 할 수 있다.
3. 불필요하게 사용하게 되면 오히려 가독성을 떨어뜨린다.

 

'STUDY' 카테고리의 다른 글

Annotation  (0) 2021.02.08
JVM / Compile / run / javac / bite code / binary code / JIT / JDK / JRE  (0) 2021.01.18

1. 정의하는 방법

package annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Hello {
}

2. Annotation의 종류

- @Override

> 메소드가 override 되었는지 알려주는 역할을 한다. 생략이 가능하지만, 실수를 방지하기 위해서 생략하지 않는 것이 좋다.

 

- @Target 

> annotation이 적용 가능한 대상을 지정하는데 사용된다.

> METHOD, TYPE, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, LOCAL_VARIABLE, MODULE, PACKAGE, PARAMETHER, TYPE_PARAMETER, TYPE_USE에 사용할 수 있다고 한다.

 

- @Retention(RetentionPolicy.RUNTIME)

>  annotation이 유지되는 범위를 지정하는데 사용된다.

 

 3개의 레벨 순서 : SOURCE -> CLASS -> RUNTIME 

 

1. SOURCE : 소스코드에만 유지하겠다. 컴파일 하고 나면, 애너테이션이 없어진다.

(바이트 코드에 남아있지 않음!! 즉, 주석으로만 사용하겠다.)

ex) @Override

 

2. CLASS : 바이트 코드에 남겨두겠다. 컴파일시까지 유지됨

 

3. RUNTIME : reflection이 가능해진다.

Q. reflection이란?? 

- 객체를 통해 클래스에 대한 정보를 분석해 내는 프로그램 기법

 

package annotation;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Hello
@RestController
public class HelloController{

    private static final String hello = "hello";

    @GetMapping(hello)
    public String hello(){
        return "hello";
    }
}

getAnnotatiions 메소드로 해당 클래스에 쓰인 annotation 정보들을 알아볼 수 있다.

package annotation;

import java.lang.annotation.Annotation;

public class HelloMain {

    public static void main(String[] args) {

        Annotation[] annotations = HelloController.class.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }
}
@annotation.Hello()
@org.springframework.web.bind.annotation.RestController(value=)

- @Inherited

> 상속받은 클래스에도 annotation이 유지된다는 뜻

 

- @Id

>

 

- @GeneratedValue

>

 

 

3. ServiceLoader

> interface 클래스를 만들어 놓고, 구현체는 누군지 모르는 상황에서.. jar 파일만 바꿔서 동작하게끔 하는 것!!

'STUDY' 카테고리의 다른 글

lambda  (0) 2021.03.07
JVM / Compile / run / javac / bite code / binary code / JIT / JDK / JRE  (0) 2021.01.18

 

1. JVM이란 무엇인가?

A Java virtual machine (JVM) is a virtual machine that enables a computer to run Java programs as well as programs written in other languages that are also compiled to Java bytecode. - wikipedia

자바 가상 머신은 컴퓨터가 자바 프로그램을 실행할 수 있도록 도와준다.

 

Q. JVM은 왜 필요한 것 일까?

A. 기계어는 하나의 언어가 아니기 때문이다.

컴퓨터, 정확히 말하자면 CPU가 이해할 수 있는 언어 기계어는 하나의 언어가 아니다.

CPU 제조사마다 다르기에 특정 프로그램 A를 X, Y, Z라는 각각 다른 컴퓨터 환경에서 실행하려면 각각의 제조사에 맞는 기계어를 알고 있어야 한다.

 

Q. 그렇다면 개발자는 모든 종류의 CPU에 맞는 기계어 패턴을 알고 있어야 할까?

하드웨어 엔지니어가 아닌 이상 일반적인 소프트웨어 엔지니어의 목표는 요구 사항을 충족하는 프로그램을 개발하는 것이다.

CPU 제조사마다 다른 기계어 패턴을 알 필요 없이 요구 사항을 충족하는 프로그램을 하나의 고급 언어로 작성하는 것이 이상적일 것이다.

 

자바 가상 머신이란 컴퓨터가 자바 프로그램을 실행할 수 있도록 도와준다.

결국 JVM은 자바 프로그램(바이트 코드)을 다양한 CPU 환경에서 이식성 문제없이 실행할 수 있도록 도와주는 가상 머신

 

2. 컴파일 하는 방법

자바 소스를 컴파일 및 실행하기 위해서는 기본적으로 아래의 두 프로그램이 필요하다.

javac.exe

java.exe

javac.exe는 자바 소스코드를 컴파일할 때 사용하는 프로그램이며 컴파일된 바이트 코드를 실행할 때 java.exe 사용

 

또한 javac.exe는 JDK, java.exe는 JRE에 포함되어 있기에 JDK과 JRE를 설치해야 하지만 과거와 다르게 요즘은 JDK에 JRE가 포함된 형태로 배포되고 있기에 JDK만 설치해도 무관

 

3. 실행하는 방법

java.exe 파일을 사용하여 바이트코드로 컴파일 된 .class 실행

단, 실행 시에는 소스 파일명의 확장자는 붙이지 않음

 

Q. java compile option

 

 

4. 바이트코드란 무엇인가

바이너리 코드

바이트코드

0과 1로 구성되어 있는 코드

C언어로 작성 된 .c 파일을 컴파일한 .obj 파일이 바이너리 코드

하지만 .obj 파일만으로는 실제 컴퓨터가 이해하여 실행할 수 없다. 이때 필요한 것이 링커로 링커는 여러 개의 코드와 데이터를 모아서 연결하여 메모리에서 실행 가능 한 파일로 만드는 역할을 한다.

위 과정이 모두 진행된 후 생성되는 실행 파일이 컴퓨터가 이해 할 수 있는 기계어로 구성

0과 1로 구성되어 있는 이진 코드이지만 바이너리 코드와 다르게 가상 머신이 이해할 수 있는 코드

사람에게 더 친숙한 고급언어보다는 덜 추상적이지만 기계어보다는 추상적이다.

컴퓨터가 이해 할 수 있는 기계어로 만들기 위해서는 인터프리터의 도움이 필요하다.

 

5. JIT(짓) 컴파일러란 무엇이며 어떻게 동작하는지

 

일반적으로 인터프리터 언어(python)보다는 정적 컴파일 언어(C)가 실행 속도가 더 빠르다고들 한다.

 

Q. why??

 

그 이유는 JIT 컴파일러의 목적을 보면 알 수 있다.

정적 컴파일 언어의 경우 컴파일에 시간이 오래 걸리는 반면 컴파일 후 결과물(.exe)은 CPU가 이해할 수 있는 '기계어'이기 때문에 실시간으로 번역하여 실행하는 인터프리터 언어보다 빠를 수 밖에 없다.

Java는 컴파일 언어이지만 동적 컴파일 언어이다.

CPU가 이해할 수 있는 기계언어가 아닌 JVM이 이해 할 수 있는 바이트 언어로 컴파일한 뒤 인터프리터에 의해 실시간으로 번역되어 실행된다.

JIT 컴파일러는 반복되어 사용되는 코드나 기계어로 변환 시 많은 리소스가 필요한 부분을 코드가 실행되는 과정(Just-In-Time)에 실시간으로 변환(기계어)하여 캐싱한다.

 

Java는 이러한 최적화 과정이 존재하기에 인터프리터 언어(Python) 보다 좋은 실행 성능을 낼 수 있다.

 

6. JVM 구성 요소

- JVM은 크게 클래스 로더 시스템(Class Loader),실행 엔진(Execution Engine), Runtime Data Area 나뉘어져 있다.

 

(1) 클래스 로더 시스템 : JRE의 일부로, 바이트코드를 실행할 때 class 객체를 메모리에 load하는 요소

자바 소스 프로그램이 컴파일되어 실행되기까지의 순서를 간략하게 확인

개발자가 자바 언어를 사용하여 프로그램 작성 .java

작성 한 프로그램을 컴파일 .class

프로그램 실행에 필요한 .class 파일들을 모두 읽어 연결

프로그램 실행 전 메모리 초기화 작업 진행

바이트 코드로 작성된 프로그램을 인터프리터가 기계어로 번역하여 실행

 

클래스 로더 시스템은 컴파일된 바이트코드들을 읽어 연결한 뒤 메모리에 저장하는 역할을 수행

내부적으로는 로딩, 링크, 초기화의 단계가 존재

클래스 로더 시스템 초기화 단계에서 전역 변수를 메모리에 할당하기 때문에 필요 이상으로 전역 변수를 남용할 경우 메모리 이슈를 겪을 수 있음

 

(2) 실행 엔진 : 메모리에 load된 바이트코드를 실행하는 역할

클래스 로더 시스템에 의하여 실행에 필요한 준비 과정이 완료되었다면 이제 인터프리터를 사용하여 바이트 코드를 번역하여 실행할 차례이다.

실행 엔진 내부적으로는 인터프리터, JIT 컴파일러, GC가 있다.

< 인터프리터 >

컴파일된 .class의 바이트코드를 실행하는 역할

< JIT 컴파일러 >

프로그램이 실행될 때 인터프리터가 바이트코드를 읽어 기계어로 번역하지만 프로그램에는 반복적으로 사용하는 코드가 존재한다.

반복적으로 사용되는 코드를 매 번 번역하는 것보다는 최초 1회만 번역하여 특정 저장소(캐시)에 저장 한 뒤 추가 참조가 필요할 때마다 불러온다면 성능 향상을 이끌어 낼 수 있을 것이다.

이 역할을 수행하는 것이 JIT 컴파일러이다.

< GC >

프로그램이 실행되면서 특정 데이터를 저장할 때 주로 메모리를 사용한다.

다양한 로직이 순차적으로 실행되다 보면 한정돼있는 메모리는 여러 데이터로 점령될 것이다.

더 이상 참조되지 않는 데이터를 정리하는 역할을 수행하는 것이 GC이다.

 

(3) Runtime Data Area : JVM의 메모리 영역

- 클래스 영역> 실행에 필요한 클래스들을 로드하여 저장> 내부에서 메소드 영역과 상수 영역으로 나뉘어 저장

 

- 가비지 컬렉션 힙 영역> GC에 의해 관리되는 영역> 동적 메모리 할당 영역> 소스상에서 new 연산자로 객체를 만들 때 할당되는 영역

 

- 런타임 스택 영역> 프로그램 실행 중 발생하는 메소드 호출과 복귀에 대한 정보를 저장

 

- 네이티브 메소드 스택 영역> 자바에서 하드웨어를 직접 제어하는 기능이 없기 때문에, 필요한 경우 c언어와 같은 다른 언어의 기능을 빌려 사용한다.. 이떄!!! 사용하는 기술이 JNI(Java Native Interface)이다.. 네이티브 메소드들이 바이트코드로 변환되면서 사용되고 기록되는 것

 

7. JDK와 JRE의 차이

JDK

JRE

Java Development Kit로 오라클 자바 9부터는 JRE 포함하고 있으며 개발에 필요한 여러 가지 툴을 제공

Java Runtime Environment로 바이트 코드로 컴파일된 자바 프로그램을 실행할 때 사용

>> 자바 언어로 프로그램을 '개발'하기 위해서는 ?? JDK 설치 필요

>> 자바 언어로 작성된 프로그램을 '실행'하기 위해서는 ?? JRE 설치 필요 

 

Q. javac는 어디에 들어있을까???

> 개발할 때 필요한 것이기 때문에 JDK에 들어있다!!!

'STUDY' 카테고리의 다른 글

lambda  (0) 2021.03.07
Annotation  (0) 2021.02.08

+ Recent posts