본문 바로가기
CS/기본기 탄탄 🔥시리즈

🔥2. Java(2)

by IMSfromSeoul 2021. 5. 27.
https://hahahoho5915.tistory.com/16

📌 Java

📌 11. Java 버전별 특징

🔥 Java 8

기본 GC -> Parrallel GC

Lambda식 추가

LocalDateTime, LocalDate, LocalTime등 시간 API 추가

Stream API 추가

🔥 Java 9

G1 GC 공식 GC로 채택

🔥 Java 10

var 키워드를 통한 타입추론

병렬 처리 GC

개별 쓰레드로 분리된 Stop The world

🔥 Java 11

기본 GC -> G1 GC

🔥 Java 12

Switch문 확장

https://kudl.tistory.com/entry/JAVA-%EB%B2%84%EC%A0%84%EB%B3%84-%ED%8A%B9%EC%A7%95

📌 12. Reflection 이란?

🔥 구체적인 클래스 타입을 알지 못해도, 해당 클래스에 접근할 수 있도록 해주는 자바 API

 

🔥 Java는 정적언어인데, 동적 언어처럼 런타임 시점에 타입을 결정하게 해주는 API. 동적 바인딩을 가능케 해주는 것.

 

🔥 Binding = 해당 객체에 메모리가 할당되어 고정되는 것

 

📌 정적 언어 vs 동적 언어

정적 언어 : 컴파일 시점에 타입을 결정

    java, C, C++ 등

동적 언어 : 런타임 시점에 타입을 결정

    python, js, ruby 등

리플렉션은 애플리케이션 개발에서보다는 프레임워크, 라이브러리에서 많이 사용됩니다.

프레임워크, 라이브러리는 사용하는 사람이 어떤 클래스
를 만들지 모릅니다. 이럴 때 동적으로 해결해주기 위해서 리플렉션을 사용합니다.

대표적인 사용 예로는 스프링의 DI(dpendency injection), Proxy, ModelM
apper 등이 있습니다.

https://dublin-java.tistory.com/53

https://brunch.co.kr/@kd4/8

이미 로딩이 완료된 클래스에서 또 다른 클래스를 동적으로 로딩(Dynamic Loading)하여 생성자(Constructor), 멤버 필드(Member Variables) 그리고 멤버 메서드(Member Method) 등을 사용할 수 있도록 합니다.

그러니까, 컴파일 시간(Compile Time)이 아니라 실행 시간(Run Time)에 동적으로 특정 클래스의 정보를 객체화를 통해 분석 및 추출해낼 수 있는 프로그래밍 기법이라고 표현할 수 있습니다.

https://madplay.github.io/post/java-reflection

📌 13. Stream API

🔥 함수형 인터페이스인 Lambda Expression을 적용해서 컬렉션, 배열 등에 대해 반복처리를 간편하게 하는 API

코드가 더 간결하고 깔끔해진다.

 

🔥 구조

 

Stream의 구조는 3단계로 나뉜다.

스트림생성 . 중개연산() . 최종연산()

stream()

 

. 으로 이어나가는 것을 pipeline이라고 부른다.

 

중개연산에는 map, filter 등등이 있고, 최종 연산에는 Collect, count 등등이 있다.

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

🔥 Lambda expression

 

함수를 하나의 식으로 표현한 것. 익명함수의 한 종류.

📌 14. 함수형 인터페이스

함수형 인터페이스란, abstract method 가 하나인 인터페이스를 의미한다.
그래서 Single Abstract Method (SAM) 이라고 불리기도 한다.

 

함수형 인터페이스는 '추상 메서드'가 하나이면 조건을 만족한다. static 메서드나 default 메서드가 추가적으로 있어도 추상 메서드가 하나라면, 함수형 인터페이스라고 할 수 있다.
(참고 - 자바8부터 인터페이스에 static method, default method 를 사용할 수 있다.)

https://velog.io/@jaden_94/%ED%95%A8%EC%88%98%ED%98%95-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-Functional-Interface

위와 같이 abstract method가 하나인 것. ( interface에서는 abstract를 생략 가능 )

 

🔥 함수형 인터페이스를 이용해서 작성하면 , 코드가 간결해져서 가독성이 좋아진다.

📌 15. Collection 관련

모든 collection들은 Collection을 상속하고, Collection은 Itrable을 상속한다.

Iterable interface안에는 iterator() method가 정의돼있다.

 

🔥 Java collection의 종류에 대해서 말해주세요.

 

list,map,set,stack,queue등이 있다. list 인터페이스 같은 경우에는 구현체가 ArrayList가 될수도, LinkedList가 될 수도 있다.

 

🔥 list에 대해서 설명해주세요.

 

List는 배열과 비슷한 자료형이지만, 동적으로 값을 할당할 수 있기에 배열보다 편리하게 사용할 수 있다.

대표적 구현체로는 ArrayList와 LinkedList가 있다.

ArrayList는 탐색에는 좋지만, 삽입 삭제에는 좋지 않다.

LinkedList는 삽입 삭제는 좋지만, 탐색은 좋지 않다.

 

🔥 Map에 대해서 설명해주세요.

 

Map에는 HashMap, TreeMap, LinkedHashMap 등이 있다.

그 중 HashMap은 가장 일반적으로 사용하는 Map이다.

 

HashMap은 HashTable을 사용하여 Key값에 해시함수를 적용하여 나온 해당 index값에 value를 저장하는 식으로 이루어져있다. 순서가 없다는 것이 특징이다.

 

TreeMap은 Red-Black Tree 자료구조를 이용한 Map이고, Tree구조이기에 어느정도의 순서를 보장한다.

 

LinkedHashMap은 LinkedList로 구현된 Hashmap이다. List로 구현돼있기에 순서가 보장된다. 하지만 LinkedList 특성상 random접근에 대해서는 느릴 수 있다.

 

🔥 Set에 대해서 설명해주세요.

 

Set에는 HashSet, TreeSet, LinkedListSet 등이 있다.

 

HashSet은 HashMap에서 Key값이 없는 자료형의 집합이다. 순서를 보장하지 않으며, 값의 유일성에 대해서만 관심이 있으므로 중복값을 허락하지 않는다. Set에서는 대표적으로 사용된다.

 

TreeSet은 Reb-Black Tree 자료구조를 이용한 Set이다.

 

LinkedListSet은 LinkedList로 구현된 Set으로, 순서를 보장한다.

 

🔥 Red-Black Tree란?

 

이진 트리 -> 자식이 최대 2개인 트리

이진 탐색 트리 -> 이진트리 + 왼쪽보다 오른쪽이 항상 큰 트리

 

이진 탐색 트리(BST)의 일종이다. BST는 최악의 경우 한 가지로만 BST가 생성될 경우 O(n)이 되는데, 이런 현상을 방지하기 위해 균형이 잡힌 Tree를 생성하는 Tree이다.

https://zeddios.tistory.com/237

 

🔥 Stack과 Queue에 대해서 설명해주세요.

 

Stack은 먼저 들어간 데이터가 나중에 나오는 자료구조이고, Queue는 먼저 들어간 데이터가 먼저 나오는 자료구조이다. 

Deque는 stack과 queue를 합친 형태이다.

 

🔥 Array와 ArrayList의 차이에 대해서 설명해주세요.

 

Array는 크기가 정적이지만, ArrayList는 크기가 동적입니다.

Array는 int, char, byte 같은 원시타입(Primitive Type)을 담을 수 있지만, ArrayList는 참조타입만 (Reference Type) 만 담을 수 있다.

 

🔥 Wrapper class란 무엇인가요?

 

기본 자료형들을 객체로 다루기 위해서 사용하는 클래스

박싱 -> 현재 원시타입의 데이터를 보고 있다고 가정하고 있기 때문에, 참조 타입으로 Boxing 한다.

사용했으면 다시 UnBoxing 한다.

공통 인터페이스를 정의해서 표준을 정의하고 구현하여 표준을 따르도록 함으로써 코드의 일관성을 유지하여 재사용성을 극대화하는 것이 객체지향 프로그래밍의 중요한 목적 중의 하나

https://devlog-wjdrbs96.tistory.com/84

📌16.  Volatile

🔥 Java변수를 Main memory에 저장하겠다는 것을 명시하는 것

 

변수값을 read할 때, cache에서 값을 꺼내지 않고, Main memory에서 값을 읽겠다.

변수값을 wrtie할 때, cache에 뿐만 아니라 main memory에도 작성한다.

 

🔥 사용이유?

멀티 쓰레드 환경에서 값을 읽어들일 때, 다른 cache에 저장되면 '변수값 불일치' 오류가 생길 수 있다.

만약 Thread 1은 Write & Read 연산을 하고, Thread 2는 Read 연산을 한다고 하면 Thread 1의 값은 CPU1 Cache에만 저장이 되기 때문에 Thread 2는 counter=0 값만 가져오게 된다.

 

위와 같은 상황에서 volatile 키워드를 추가해주면 main memory에 값을 저장하므로 문제를 해결할 수 있다.

 

위와 같은 멀티쓰레딩 환경에서 하나의 쓰레드는 write & read를 하고, 하나의 쓰레드는 read만 할 때 volatile키워드를 쓰는 것이 가장 적합하다.

두 쓰레드가 공유변수에 대해 동시에 write & read를 수행할 때는 volatile 선언은 충분하지 않다.

 

이유는 아래 그림과 같다.

위의 예에서 둘다 counter 변수에 +1을 해주었지만 Thread가 메인메모리에 +1한 값을 저장하기 전이기 때문에 counter=2 값을 가져가는게 아니라 둘다 1값을 가져간다. 이는 의도하지 않은 바다.

https://parkcheolu.tistory.com/16
https://nesoy.github.io/articles/2018-06/Java-volatile

📌17. Class, 객체, Instance

🔥 Class

객체를 생성하기 위한 설계도

 

🔥 객체(Object)

클래스 타입으로 선언된 것. 모든 인스턴스를 포괄하는 개념.

oop의 관점에서는 class 타입으로 선언됐을 때 객체라고 부른다.

 

🔥 Instance

객체가 메모리에 할당되어 실제로 사용될 때 instance라고 부른다.

https://gmlwjd9405.github.io/2018/09/17/class-object-instance.html

📌 18. Equals & == 차이

🔥 String 변수 생성시 주소할당

 

1. 리터럴

2. new 연산자

 

리터럴로 선언하게 되면 Stack Frame안에 Constant pool 영역 안에 존재하게 되고, new 연산자로 선언하게 되면 Heap 영역에 존재하게 된다. String을 리터럴로 선언하게 될 경우 String의 intern() 메서드가 호출되게 된다. 

 

intern() 메소드는 주어진 문자열이 상수풀에 존재하게 된다면 주소값을 반환하고, 없다면 상수풀에 값을 넣고 새로운 주소값을 반환하는 함수다.

 

🔥 Equals & == 동작방식 차이

 

== 연산자는 두개의 주소값을 비교한다.

String Equals 연산자는 두개의 내용 자체를 비교한다.

String a="a";
String b="a";

위의 경우 "a"라는 리터럴 값은 String 상수풀에서 같은 위치의 값이 반환된 값이므로 a==b 을 해도 true가 나온다.

 

https://coding-factory.tistory.com/536

📌 19. Stack Frame

Thread1   Thread2   Thread3
+-------+ +-------+ +-------+
|       | |       | |       |
|       | |       | | frame |
|       | |       | | frame |
| frame | |       | | frame |
| frame | | frame | | frame |
+-------+ +-------+ +-------+

JVM 쓰레드가 생길 때, 해당 스레드를 위한 Stack도 같이 만들어진다.

Frame은 메소드 상태 정보를 저장하는 공간이며, 메소드가 호출될 때마다 생성된다.

 

쓰레드가 쓸 수 있는 stack의 사이즈를 넘게 되면 stackoverflow를 발생시킨다.

스택 사이즈를 동적으로 확장할 수도 있는데,

1. 확장할 메모리가 부족하거나

2. 새로운 쓰레드를 생성할 때 할당하는 stack에 대한 메모리가 부족할 때

OutOfMemoryError가 발생하게 된다.

 

🔥 Frame

Frame은 크게 3가지로 구성돼있다.

 

1. Local Variables

2. Operand Stack

3. Constant Pool Referenece

 

🔥 1. Local Variables

class Test {
    public int hello(int a, double b, String c) {
        return 0;
    }
}

위와 같은 코드가 있다고 해보자.

  +-----------+
0 | reference | this (hidden)
  +-----------+
1 | int       | int a
  +-----------+
2 |           | double b
  + double    +
3 |           |
  +-----------+
4 | reference | String c
  +-----------+

reference = heap reference

원시타입은(primitive type) 그냥 frame에 저장한다.

 

🌎 리터럴은 frame에 저장한다.

 

🔥 2. Operand Stack

 

Operand Stack = 메소드 내 계산을 위한 작업공간

 

🔥 3. Constant Pool Reference

 

프레임은 런타임 상수풀의 참조값을 갖는다.

참조블로그
https://johngrib.github.io/wiki/jvm-stack/#local-variables

📌 20. Hashcode

객체 Hashcode란 객체를 식별하는 하나의 정수값을 말한다.

Object의 hashcode() 메소드는 객체의 메모리 주소값을 이용해서 해싱하기 때문에 객체마다 다른 값을 가지고 있다.

이 때, 객체의 값에 대해 동등성 비교를 할시 hashCode()를 overriding할 필요가 있다.

 

equals와 hashcode는 같이 다닌다고 생각하면 좋은데, 그 이유는 eqauls 사용시 hashCode() 메소드를 먼저 실행해서 같은값을 갖고 있는지 확인하고, 다르면 같지 않다고 생각해서 equals까지 실행되지 않기 때문이다.

 

즉, equals() 메소드의 전제조건으로 hashCode() 메소드가 실행된다.

 

그러면 String의 경우 어떻게 논리적으로 값이 같은 경우 equals()가 같은 값을 반환하는지 의문이 들 수 있다. 그 이유는 String class가 hashCode()를 재정의 ( overriding ) 했기 때문이다.

 

hashCode()를 재정의하지 않으면 같은 객체라도 버킷값이 다를 수 있다. 그래서 HashTable에 저장된 해당 객체를 찾을 수 없다.

 

eqauls()를 재정의하지 않으면 hashCode()가 만든 해시값을 이용해 객체가 저장된 버킷은 찾을 수 있지만 해당 객체가 자신과 같은 객체인지 비교할 수 없기 때문에 null을 return하게 된다.

 

그래서 equals()를 정의할 때는, hashCode()역시 재정의해야한다.

참조블로그 hashcode와 equals의 관계(1)
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=travelmaps&logNo=220930144030
참조블로그 hashcode와 equals의 관계(2)
http://blog.naver.com/PostView.nhn?blogId=travelmaps&logNo=220931531769&redirect=Dlog&widgetTypeCall=true
참조블로그 hashcode()와 equals() 메서드는 언제 사용하고 왜 사용할까?
https://jisooo.tistory.com/entry/java-hashcode%EC%99%80-equals-%EB%A9%94%EC%84%9C%EB%93%9C%EB%8A%94-%EC%96%B8%EC%A0%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B3%A0-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C

📌 21. Annotation

Annotation은 메타데이터라고 볼 수 있다.

 

메타데이터는 컴파일 과정과 런타임 과정에서 코드를 어떻게 컴파일하고 처리할 것인지 알려주는 정보이다.

🔥 Annotation의 용도 3가지

1. 컴파일러에게 코드 문법 에러를 체크하도록 정보 제공

2. 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보를 제공

3. 런타임 시 특정 기능을 실행하도록 정보를 제공

https://webcoding-start.tistory.com/17

시스템 설정과 관련된 부가적인 사항들은 annotation에게 위임하고, 개발자는 비지니스 로직 구현에 집중할 수 있게 하도록 사용하는 것.

 

annotation은 소스코드에 붙이는 하나의 라벨이다.

https://www.nextree.co.kr/p5864/

'CS > 기본기 탄탄 🔥시리즈' 카테고리의 다른 글

🔥6 - 데이터 베이스  (1) 2021.06.08
🔥5 - 네트워크  (0) 2021.06.03
🔥4 - 운영체제  (0) 2021.06.02
🔥3. Spring (1)  (0) 2021.05.31
🔥1. Java  (0) 2021.05.25

댓글