딱콩이의 봄

JAVA공부 본문

개발/JAVA

JAVA공부

코린이딱콩 2022. 8. 16. 16:51

싱글톤 패턴

인스턴스를 불필요하게 생성하지 않고 오직 한 개의 인스턴스만 생성하여 사용되는 디자인 패턴입니다.

생성자의 호출이 반복적으로 이루어져도 실제로 생성되는 객체는 최초로 생성된 객체를 반환해주는 것입니다.

인스턴스가 한 개만 존재하는 것을 보증하고 싶은 경우, 싱글톤 패턴을 사용합니다.

싱글톤 패턴의 대표적인 예로 스피링 빈이 있습니다. 스프링 빈 등록 방식은 기본적으로 싱클톤스코프이고 스프링 컨테이너는 모든 빈들을 싱글톤으로 관리합니다. 스프링은 요청할 때마다 새로운 객체를 생성해서 반환하는 기능도 제공합니다.


JAVA의 클래스 멤버 변수 초기화 순서

static 변수 선언부는 클래스가 로드될 때 변수가 제일 먼저 초기화됩니다. 필드변수 선언부는 객체가 생성될 때 heap메모리에 올라가고 생성자 block보다 앞서 초기화 됩니다. 생성자 block은 객체가 생성될 때와 마찬가지로 heap메모리에 올라갑니다. 이때 필드 변수가 초기화될 때까지 JVM에서 내부적으로 로킹 해줍니다.


Vector와 List차이

벡터는 데이터 삽입시 원소를 밀어내지만 리스트는 노드를 연결만 하기 때문에 삽입 삭재 부분에서 리스트가 시간 복잡도의 우위를 가집니다. 벡터는 랜덤 부분 접근이 가능하지만 , 리스트는 더블링 토드 리스트 즉 노드가 양쪽으로 연결되어 있기 때문에 랜덤 접근이 되지 않습니다. 검색적인 측면에서는 벡터가 우위에 있지만 벡터는 리스트와 달리 항상 동기화되는 장점이자 단점을 가지고 있습니다. 멀티 스레드 환경에서 안전하게 객체를 추가하고 삭제할 수 있지만 단일 스레드 환경일 때도 동기화를 하기 때문에 List보다 성능이 떨어집니다.


ArrayList와 LinkedList 차이

ArrayList는 기본적으로 배열을 사용합니다. 일반 배열은 처음 메모리를 할당할 때 크기를 지정해 주어야 하지만 ArrayList는 크기를 지정하지 않고 동적으로 값을 삽입하고 삭제할 수 있습니다.

ArrayList는 각 데이터의 index를 가지고 있고 무작위 접근이 가능하기 때문에 해당 index의 데이터를 한 번에 가져올 수 있습니다.

하지만 데이터의 삽입과 삭제 시 ArrayList는 그만큼 위치를 맞춰 주어야 하기 때문에 삽입과 삭제가 많다면 ArrayList는 비효율적입니다.

LinkedLIst는 내부적으로 양방향의 연결 리스트로 구성되어 있어 참조하려는 원소에 따라 처음부터 정방향 또는 역순으로 순회가 가능합니다. LinkedList는 순차적 접근이기 때문에 검색의 속도가 느립니다. LinkedLIst는 데이터 추가·삭제 시 가리키고 있는 주소 값만 변경해주면 되기 때문에 ArrayList에 비해 상당히 효율적입니다. 정적인 데이터를 활용하면서 조회가 빈번하다면 ArrayList를 동적으로 추가/삭제 요구사항이 빈번하다면 LinkedList를 사용하는 것이 좋습니다.


직렬화와 역직렬화 차이

자바에서 입출력에 사용되는 것은 스트림이라는 데이터 통로를 통해 이동합니다. 하지만 객체는 바이트형이 아니기 때문에 스트림을 통해 저장하거나 네트워크로 전송하는 것이 불가능합니다. JVM의 메모리에 상주(힙 or스택)되어 있는 객체 데이터를 바이트 형태로 변환하는

따라서 객체를 스트림으로 입출력하기 위해 바이트 형태로 변환하는 것을 직렬화라고 하고, 반대로 직렬화된 바이트 형태의 데이터를 다시 객체로 변환하는 과정을 역직렬화라고 합니다.


InputStream & InputStreamReader & Buffered Reader

  • InputStream

InputStream은 바이트 기반 입력 스트림의 최상위 추상 클래스입니다. 모든 바이트 기반 입력 스트림은 이 클래스를 상속받습니다. 파일 데이터나 네트워크 소켓 또는 키보드에서 입력한 데이터를 읽을 때 사용합니다.

 

  • InputStreamReader

InputStreamReader는 byteStream을 characterStream으로 변경해주는 역할을 합니다. InputStreamReader클래스는 생성자의 파라미터로 InputStream 객체를 전달받습니다. 또한, 생성자의 파라미터로 charset정보를 전달받아서, 읽어 들이는 stream의 charset을 지정할 수 있습니다.

 

  • BufferedReader

BufferedReader는 입력 스트림에서 문자를 읽는 함수인데 문자나 배열, 라인들을 효율적으로 읽기 위해서 문자들을 버퍼에 저장하고 읽는 방법을 취합니다. 버퍼 사이즈는 지정할 수도 있지만, 지정하지 않을 경우 기존 디폴트 사이즈가 사용됩니다.


멀티 스레드와 싱글 쓰레드

멀티스레드는 CPU의 최대 활용을 위해 둘 이상의 프로그램을 동시에 실행하는 기술입니다. 콘텍스트스위칭을 통해 이루어지는데 하나의 스레드에서 다음스레드로 이동하면서, 컨텍스트 스위칭이 일어납니다. 그리고 스위칭이 일어나면서 부분적으로 조금씩 각각의 스레드에 대한 작업을 끝내게 됩니다. 메인 스레드 외의 추가적인 스레드를 이용하여 병렬적으로 작업을 처리합니다.

 

싱글 스레드는 메인 스레드 하나만을 가지고 작업을 처리합니다. 하나의 프로세서에서 오직 하나의 스레드로만 실행하고, 작업을 차례대로 수행합니다. 하나의 레지스터와 스택으로 표현이 가능합니다.


StackOverFlow

스택 영역의 메모리가 지정된 범위를 넘어갈 때 발생합니다. 스택 메모리는 보통 지역변수가 저장되는 영역인데 함수에서 지역변수를 선언하면 지역변수는 스택메모리에 할당되고 함수를 빠져나오면 스택 메모리에서 해제됩니다. 만약 한 함수에서 너무 큰 지역변수를 선언하거나 함수를 재귀적으로 무한정 호출하게 되면 stackoverflow가 발생할 수 있습니다.

stackoverflow가 발생하면 컴파일러 옵션에서 스택영역의 크기를 늘리거나 또는 함수에서 사용하는 지역변수 크기를 줄이거나 지역변수를 전역 변수로 바꾸어 해결할 수 있습니다.


MemoryLeak(메모리 누수)

프로그램이 필요하지 않은 메모리를 계속 점유하고 있는 현상을 말합니다.

할당된 메모리를 사용한 다음 반환하지 않고 누적이 되기 때문에 메모리 릭이 발생합니다. 자바에서는 더 이상 사용되지 않는 객체가 GarbageCollection에 의해서 회수되지 않고 계속 누적되는 현상입니다. Old영역에 누적된 객체로 인해 MajorGC가 계속 발생하게 되고, 프로그램의 응답속도가 늦어지다 결국 OutOfMemory오류가 발생되어 프로그램이 종료됩니다. 

누수원인 중에는 WrapperClass의 무의미한 객체 생성, 캐시 데이터를 해제하지 않는 경우, 스트림 객체를 사용하고 closing하지 않는 경우 등이 있습니다.


Synchronized

여러 개의 스레드가 한 개의 자원을 사용하고자 할 때, 현재 데이터를 사용하고 있는 스레드를 제외하고 나머지 스레드들은 데이터에 접근하지 못하게 막는 개념입니다. 데이터의 thread-safe를 하기 위해 자바에서 synchronized를 제공해 멀티스레드 환경에서 스레드 간 동기화를 시켜 데이터의 thread-safe를 보장합니다.

synchronized는 변수와 메서드를 사용해 동기화 할 수 있으며, synchronized 키워드를 남발하게 되면 프로그램의 성능저하를 일으킬 수 있습니다.


Set과 Map타입이 Object를 받을 때 중복검사

hashcode() 메소드를 오버 라이딩하여 리턴된 해시 코드 값이 같은지를 보고 해시코드 값이 다르다면 다른객체로 판단하고, 해시코드 값이 같으면 equals() 메서드를 오버 라이딩하여 다시 비교합니다. 이 두 개가 모두 맞으면 중복 객체입니다.

'개발 > JAVA' 카테고리의 다른 글

HashMap과 HashTable의 차이  (0) 2022.08.16
Hash 기본 개념과 구조  (0) 2022.08.16
JAVA 공부  (0) 2022.08.16
JAVA공부  (0) 2022.08.16
JAVA공부  (0) 2022.08.15
Comments