티스토리 뷰
JAVA
- • 왜 getter, setter 함수를 써야하는지?
- 일반적으로 프로그래밍시 객체들의 데이터(필드)를 외부에서 직접적으로 접근하는 것을 막아놓습니다
- 필드들을 private 접근 제한자로 막아두고, 각 필드의 Getter, Setter로 접근하는 방식
- 왜???
- 객체의 무결성을 보장하기 위함입니다
- 사람 몸무게는 음수값을 가질 수 없습니다
- 그렇기에 외부에서 직접적으로 접근해서 음수로 변경하는 경우 해당 객체의 무결성이 깨지는 상황이 발생합니다
- 그렇기에 필드를 private 으로 만들어 외부의 접근을 제한한 후 , Setter 를 사용하여 전달받은 값을 내부에서 가공해 필드에 넣어주는 방식을 사용합니다
- 또한 필드를 가져올 때도, Geeter 를 사용해 본 필드의 값을 숨긴 채, 내부에서 가공된 값을 꺼낼 수 있습니다.
- 접근제한자 설명
- 멤버들은 객체 자신들만의 속성이자 특징이므로 대외적으로 공개되는 것은 좋은 것이 아닙니다
- 프로그래머스가 객체의 멤버들에게 접근 제한을 걸 수 있는 데 자바에서는 이를 접근 제한자라고 함
- public
- 모든 접근을 허용
- protected
- 같은 패키지(폴더) 에 있는 객체와 상속관계의 객체들만 허용
- default
- 같은 패키지(폴더) 에 있는 객체들만 허용
- private
- 현재 객체 내에서만 허용
- 객체지향이란?구성요소
- 크게 클래스, 객체, 메서드
- 클래스
- 객체를 정의하는 틀, 게임에서의 (플레이어)라는 클래스를 만들고
- 해당 클래스에서 파생하여 여러 격투 캐릭터를 만들어낼 수 있음
- 구성요소
- 필드 (클래스에 포함된 변수), 메서드(특정 작업을 수행하기 위한 문장들의 집합), 생성자 ( 인스턴스 초기화 메서드)
- 객체와 인스턴스
- 클래스로부터 객체를 만들는 과정을 클래스의 인스턴스화라고 함
- 메서드
- 함수
- 먼저 만들어 놓고 언제든지 필요할 때 가져와서 사용하는 개념
- 객체 지향 언어??
- 우리가 살고 있는 세게를 모델링으로 한 개발 방법
- 절차지향
- 순서도 차트에 보이는 것 처럼 시작 기준에서 순서대로 진행
- 순서가 틀려도 안됨! 어느 한 부분이 오류나면 그 다음 부분 전체가 마비
- 객체 지향
- 순서 상관없이 독립적으로 사용 가능
- 이러한 객체들을 상호작용하여 설계가능
- 하나의 객체가 오류날지라도 다른 객체에 영향을 주지 않음
- 다중 상속에 대해 설명왜 다중상속을 지원하지 않는가??
- GranFather A() 메서드를 Father 클래스에서 각각 오버라이딩해서 구현함
- 하지만 Son 입장에서는 A() 메서드 호출시 누구의 메서드를 가져다 써야할지 알 수 없음
- 인터페이스는 기능 에 대한 선언만 하기에, 위와 같은 경우더라도 충돌할 여지가 없음
- 인터페이스 안에서는 추상메서드만을 선언! 하위 클래스들은 추상메서드를 오버라이딩 해서 구현함
- 정의
- 자바의 인반 클래스는 부모 클래스를 단 하나만 가져야함
- 다중 상속을 지원하지 않는다
- 하지만,
- 인터페이스는 추상 클래스보다 더 추상적이기에 여러 인터페이스를 상속받는 다중 상속을 지원합니다
- Java의 JVM에서 5가지 메모리 구조에 대해 설명JVM 은 다섯 가지의 컴포넌트로 구성
- 클래스 로더 시스템
- 컴파일 결과로 만들어진 .class 바이트 코드 파일을 읽어들여 메모리에 배치
- 로딩, 링크, 초기화의 세 가지의 과정을 거친다
- 컴파일 결과로 만들어진 .class 바이트 코드 파일을 읽어들여 메모리에 배치
- 메모리
- Runtime Engine
- 바이트 코드를 읽어들이는 인터프리터가 작동하는 영역
- 바이트 코드를 기계어로 변환하면서 Line by Line 으로 실행
- 인터프리터가 기계어 코드를 실행시, 한 번 변환한 바이트코드를 또 변환하는 대신 실행한 코드를 저장하는 영역이 존재
- Code Cache == JIT Compiler
- 프로그램 실행속도를 향상시킴
- Code Cache == JIT Compiler
- Garbage collection
- 바이트 코드를 읽어들이는 인터프리터가 작동하는 영역
- Native Method interface
- Native Method library
- 클래스 로더 시스템
- JVM 의 메모리 구조
- Heap Memory
- JVM이 객체의 인스턴스나 동적 할당된 데이터를 저장하는 공간
- Garbage Collection이 일어나는 장소
- Garbage Collection 을 위해.. 메모리를 분리한다?
- Young 과 Old 라는 두 개의 영역으로 논리적으로 분할해 사용
- Young
- 인스턴스를 처음 생성시 메모리에 배정되는 영역
- Eden : 인스턴스를 생성시 이곳에 배정
- Survivor space : Minor GC 로 Garbage를 걸러내고 살아남은 인스턴스가 배정
- 인스턴스를 처음 생성시 메모리에 배정되는 영역
- Old
- Minor Gc를 여러 번 거치고 살아남은 인스턴스가 배정
- 이곳의 GC 는 MajorGC
- Thread Stacks
- 메모리에서의 Stack.. 스레드ㅡ마다 하나씩 배정되는 메모리 영역, 메서드의 변환값 / 결과를 저장하거나 지역변수를 저장하는 용도
- Meta Space
- 애플리케이션의 클래스나 메서드 정보 또는 static으로 정의된 멤버 변수가 저장ㄷ
- Code Cache
- Shared Library
- Heap Memory
객체지향이란
- 객체
- 현실세계의 실체 및 개념을 반영하는 상태와 행위를 정의한 데이터의 집합
- 객체지향 프로그래밍
- 각자의 역할을 지닌 객체들끼리 서로 메시지를 주고받으며 동작할 수 있도록 프로그래밍 하는 것
객체 지향의 강점
객체를 중심으로 프로그래밍 하기 때문에
- 사람의 관점에서 프로그램을 이해하고 파악하기 쉽다
- 강한 응집력과 약한 결합력을 가진다
- 재사용성, 확장성, 융통성이 높다
이러한 강점 때문에 디버깅과 유지보수가 용이하고 설계와 분석이 비교적 쉽다
객체지향의 단점(한계)
- 객체 간의 정보 교환이 모두 메시지 교환을 통해 일어나므로 실행 시스템에 많은 overhead가 발생함
- 처리속도가 상대적으로 느리다
- 하지만 하드웨어의 발전으로 이러한 단점은 어느정도 해소되었다.
- 객체가 상태를 갖기 때문에 예상치 못한 부작용이 발생할 수 있다. 변수가 존재하고 이 변수를 통해 객체가 예측할 수 없는 상태를 갖게 되어 애플리케이션 내부에서 버그를 발생시킬 수 있다.
- 이는 함수형 프로그래밍 등장의 패러다임
객체지향적 설계원칙 SOLID
- SRP(Single Responsibility Principle) 단일 책임 원칙
- 클래스는 단 하나의 책임을 가져야 하며 클래스를 변경하는 이유는 단 하나의 이유이어야 한다.
- OCP(Open-Closed Principle) : 계방 - 폐쇄 원칙
- 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다.
- LSP(Liskov Substitution Priciple) : 리스코프 치환 원칙
- 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
- ISP(Interface Segregation Principle) : 인터페이스 분리 원칙
- 인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다
- DIP(Dependency Inversion Principle) : 의존 역전 원칙
- 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안됨
객체지향의 특징
- 추상화
- 객체에서 공통된 속성이나 기능을 추출하는 것. 중요하지 않은 것(관심 대상이 아닌 것)은 감추거나 무시하고, 중요한 것(관심있는 것)만을 강조하여 추출하는 것.
- 캡슐화
- 관심있는 데이터와 기능을 모아놓고 패킹한 것이다. 객체지향에서는 이를 클래스를 정의하고 외부에서 마음대로 접근 X. 정보의 은닉화!
- 다형성
- 같은 코드라 하더라고 상황에 따라 다른 방식으로 동작하는 성질. Java 에서 다형성을 구현할 수 있는 대표적으로 Overrinding 과 Overloading
- Overriding
- 임의의 클래스가 다른 클래스를 상속 받거나 인터페이스를 구현했을 때, 상위 클래스 또는 인터페이스에 정의되어 있는 메소드를 재정의 하여 사용하는 것이다.
- 메서드 호출 시 재정의되어 있지 않다면 상위 클래스의 메서드가 호출된다.
- Overloading
- 메소드 주어진 인자(parameter) 에 따라 동작을 다르게 구현할 수 있다. 코드의 중복 줄어들고, 가독성이 늘어난다. 반환 형 관계 X, 인자의 개수 타입을 다르게 구현가능
- 상속
- 부모의 형질을 이어받는다는 의미, 부모 클래스의 속성과 메서드를 그대로 활용할 수 있다.
- 클래스(class)
- 객체를 만들기 위해 상태(field)와 행위(method)를 정의한 틀.
- 메시지
- 객체지향적으로 구현된 프로그램은 객체들끼리의 메시지를 주고받고 상호작용하며 동작.
- 코드는 임의의 객체에게 인자를 전달, 메서드를 호출하며, 반환값을 받아 처리
자바의 장, 단점
- 장점
- 자바의 가장 큰 장점은 JVM 을 이용한 플랫폼 독립적이라는 점입니다, 자바에서 코드를 컴파일하면 바이트코드(.class) 형태로 출력됩니다. 하나의 바이트코드를 가지고 서로 다른 운영체제나 기계마다 해당 JVM 만 설치되어 있다면, 다시 컴파일 할 필요없이 나머지는 JVM 이 해당 기계에 맞게 실행해줍니다
- 단점
- 자바의 단점은 JVM 을 사용하는 데에 있습니다. 자바 프로그램이 실행되기 위해서는 먼저 JVM 이 실행되어야 하는데 JVM 실행과정은 많은 메모리를 소모하고 실행속도가 느립니다.
- JVM > 운영체제 각 JVM .. >> 의존적임 ,, Java 운영체제에 독립적이다. (Mac Java...이런건 없습니다)
기본 자료형과 참조 자료형
- 기본 자료형
- byte , short , int , long, float , double , char, boolean 이 존재합니다. 기본 자료형은 call by value 로서 값 자체가 저장되며, OS 에 따라 자료형의 길이가 변하지 않고, null값을 가질 수 없다는 특징이 있습니다
- 참조 자료형
- class , interface , array , enum 이 존재합니다. 참조 자료형은 생성한 변수에는 객체의 주소값이 저장됩니다. 주소값이 저장된다고 하여 call by reference 라고 생각할 수도 있지만. 주소의 위치 값 자체가 전달되는 call by value 입니다. null값을 가리킬 수 있습니다.
객체 지향 프로그래밍이란
- 실세계의 특정 사물을 추상화하며 그에 필요한 멤버 변수와 메서드를 정의하는 데서 출발합니다. OOP 의 특징에는 캡슐화, 상속, 추상화, 다형성이 있습니다.
- 꼬리질문
- 캡슐화란?
- 멤버 변수와 메서드의 이용가능범위를 적절하게 제한하여 안전한 프로그래밍을 지원하는 특징입니다.
- 상속이란?
- 부모 클래스의 기능을 자식 클래스에서 물려받을 수 있는 특징입니다
- 추상화란?
- 자식 클래스에서의 공통점을 취합하여 부모 클래스로 반영하는 특징
- 다형성이란?
- 하나의 메서드나 클래스가 다양한 방법으로 동작하게하는 요소를 말한다, 메서드 오버라이딩, 오버로딩이 존재합니다.
- 메서드 오버라이딩은 자식 클래스에서 부모 클래스의 메서드를 새롭게 재정의하는 것. 선언부는 동일하지만 함수 기능코드가 다른 역할을 수행 할 수 있습니다.
- 메서드 오버로딩은 하나의 클래스에서 같은 이름을 가졌지만 파라미터의 종류나 숫자가 다른 메서드를 구현하는 것입니다.
- 캡슐화란?
접근 제어자
- 접근제어자는 객체 지향 프로그래밍에서 클래스의 멤버 변수 또는 메서드에 설정하는 키워드로 접근 영역을 제한하는 데 사용합니다. public default protected private이 존재합니다
- 꼬리질문
- 접근제어자 범위 설명
- public
- 접근제한 X
- default
- 접근제어자 사용 X 같은 패키지내에서만 가능
- protected
- 같은 패키지내, 다른 패키지의 자식 클래스 내에서 접근
- private
- 같은 클래스 내에서만 접근가능
- public
- 접근제어자 범위 설명
- 꼬리질문
추상 클래스와 인터페이스
- 추상 클래스 (상속을 강제할떄 사용)
- 형태만 정의해 놓고 몸체는 없는 상태를 포함하고 있는 클래스를 의미한다. 클래스기에 extends키워드를 이용해 상속을 진행. 해당 추상클래스를 상속받은 자식 클래스에서는 반드시 추상메서드를 재정의해야함.
- 인터페이스(큰 프로젝트인 경우 다중 상속가능하기에)
- 추상 클래스보다 추상화 정보다 높은 상태를 정의하기 위해 사용한다. 멤버변수와 일반 메서드를 가질 수 없으며, 상수와 추상메서드만 선언가능합니다 ( 추상 클래스와 다른점)
- implements 키워드를 사용하여 상속을 진행하며(추상 클래스와 다른점), 자식 클래스에서 반드시 메서드는 재정의 해야한다.
- 다중 상속이 가능함 (추상 클래스와 다른점)
- 응집도 결합도프로그램의 한 요소가 해당 기능을 수행하기 위해 얼마만큼의 연관된 책임과 아이디어가 뭉쳐있는지를 나타내는 정도이다. 일반적으로 프로그램의 한 요소가 특정 목적을 위해 밀접하게 연관된 기능들이 모여서 구현되어 있고, 지나치게 많은 일을 하지 않으면 그것을 응집도가 높다고 표현한다. 응집도가 높으면 프로그램을 쉽게 이해할 수 있으므로 유지보수성이 높아진다.
- 이해하기 힘들고
- 따로 재사용하기 힘들며
- 유지보수하기 힘들고
- 다른 클래스의 변화에 민감하다.
- 이런 클래스는 대개 X and Y와 같은 식으로 이름을 붙인다. 한 클래스 안에 여러 기능 영역의 메소드가 들어 있어, 클래스가 한 가지 기능에 집중하지 못하는 일이 많다. 예를 들어, 이미지 처리하는 기능과 사운드 처리하는 기능을 같이 갖고 있으면 그 클래스는 응집도가 낮은 것이다.
- 같은 기능영역의 메소드로 구성되었지만 클래스내에 그들이 모두 구현된 경우로서 너무 많은 책임을 짊어지다 보니 클래스의 크기가 엄청나게 커진 경우이다. 다른 클래스가 해야 적당한 기능을 자신이 억지로 하려고 하니까 크기가 커진 것이다. 예를 들어, 돈의 지불(현금, 수표, 신용카드)과 관련된 모든 기능을 Payment(지불)라는 클래스에 넣으면 이 클래스는 응집도가 낮아진다. 이럴때는 현금, 수표, 신용카드의 공통된 결제 기능을 Payment 클래스에 정의하고, 각자 고유한 기능은 Cash, Check, CreditCard 등의 Payment를 상속받은 하위 클래스에 정의하는 것이 응집도를 높이는 방법이다.
- 클래스의 목적에 부합하는, 같은 기능영역( function area )의 메소드들로 구성되어 있다.
- 메소드의 개수가 상대적으로 작다. 그것은 오로지 자신만이 할 수 있는 책임을 부여 받았다는 뜻이다.
- 혼자 너무 많은 일을 하지 않는다. 다른 클래스와 협력한다.
- 한 모듈이 변경되기 위해서 다른 모듈의 변경을 요구하는 정도
좋은 설계란 높은 응집도를 가지고 결합도는 느슨해야 한다. 그 이유는 설계를 변경하기 쉽기 때문이다. - 의존성의 정도를 나타내며 다른 모듈에 대해 얼마나 많은 지식을 갖고 있는지를 나타내는 척도다. 어떤 모듈이 다른 모듈에 대해 너무 자세한 부분까지 알고 있다면 두 모듈은 높은 결합도를 가진다.
- 다른 기능 영역의 메소드들을 다수 포함한 클래스
- 응집도가 낮은 클래스의 문제점
- 응집도(Cohesion)
static 키워드의 쓰임새
- 클래스 내부의 메서드나 멤버 변수에 static 키워드를 사용하면 하나의 인스턴스에 속하지 않고 해당 클래스로부터 생성된 모든 인스턴스가 공통으로 공유하는 메서드와 변수로 변경됩니다
컬렉션 프레임워크에서 제네릭을 사용하는 이유
- 컴파일러가 특정 타입만 포함될 수 있도록 컬렉션을 제한합니다. 런타임시에 발생할 수 있는 잠재적인 모든 예외를 컴파일시에 잡아낼 수 있도록 도와주는 역할입니다.
- 런타임에서는 타입에 대한 제약 조건을 적용, 컴파일시 타입에 대한 정보를 소거하는 프로세스.
- 컴파일 시 발생하는 에러
- 컴파일러는 구문 오류로 프로그램을 컴파일 할 수 없다.
- 대체로 문법상의 에러
- 에러가 발생한 부분을 알려준다.
- 컴파일에러 예
- ’;’ 이 누락 된 문법 에러 (systax 오류)
- 괄호가 안 맞는 등 구문 에러
- classpath에 누락 된 클래스(컴파일시)
- 실행 시 발생하는 에러
- 프로그램이 컴파일 된 후 실행하면서 에러 발생
- 대체로 개발 시 설계 미숙(논리적)으로 발생하는 에러
- 에러 발생 시 프로그래머가 역추적해서 원인 확인해야함
- 런타임에러 예
- NullPointerException
- 무한루프
- 0으로 나누는 경우 등
- 컴파일타임 에러 (Compile-time Error)
컬렉션 프레임워크 대표 인터페이스
- 크게 list ,set , map 이 존재합니다
- list 는 순차적인 데이터를 저장하고, 중복을 허용합니다
- ArrayList , LinkedList , Stack ,vector 가 하위 클래스로 존재
- 주로 ArrayList는 검색이 많은 경우에 사용하고 LinkedList는 잦은 삽입/삭제 시 사용합니다.
- LinkedList > 왜 조회가 느린가?
- 첫 번쨰 값과 맨 뒤 값이 존재한다면..
- 첫번째부터 순차적으로 노드의 주소값을 찾아나간다.
- ArrayList
- n 속도
- 찾는 인덱스를 바로 찾아간다.
- set는 순서를 유지하지 않고 데이터의 중복만 허용하지 않는 자료구조
- hashset , treeset , LinkedHashSet > (특이)순서 O 중복 X
- hashset
- 해시 알고리즘으로 조회 > 조회가 빠름
- treeset
- 이진트리 방식 > heapq 에서 사용
- 범위 검색 > treeSet
- 일반 검색 > hashMap
- map 은 키와 값으로 이루저니 데이터를 순서 유지하지 않고 키의 중복만 허용하지 않는 자료구조
- hashmap treemap hashtable ...등이 하위 클래스
객체의 직렬화
- 객체에 저장되어 있는 데이터를 스트림(파일로 저장 혹은 네트워크를 이용하여 전송) 에 바로 쓰기 위하여 연속적인 데이터로 변환하는 과정
- 역직렬화
- 스트림으로부터 데이터를 읽어 객체로 변환하는 과정
- IO 패키지 내에서 Serializable 인터페이스를 상속받는 경우 직렬화가 가능한 클래스로 변경할 수 있음.
래퍼 클래스
- 기본 자료형으로 표현된 데이터를 참조 자료형으로 만들어야 할 경우 래퍼클래스 사용
- 특정 메서드에서 참조 자료형을 인자로 받거나,, 객체간의 비교가 필요한 경우 사용..
- 그리고 null 값을 래퍼 클래스를 받을 수 있기에.. 사용함
자바 쓰레드 구현하기 위한 방법 2가지
- lang 패키지내 > Thread 클래스 상속
- Runnable 인터페이스를 상속받아 run 메서드는 재정의해서 구현
- 하지만 자바에서는 다중 상속을 하용하지 않기 때문에, Thread 클래스를 확장하는 클래스는 다른 클래스를 상속받을 수 없습니다.
String에서 ==과 equals()는 어떤 차이가 있나요?
- ==은 참조형 변수의 값 자체, 즉 주소값을 비교하는 연산자이고 equals는 그 주소값이 가리키는 값을 비교하는 메소드.
StringPool에 대해서 설명해보세요.
- String의 값들이 저장되어있는 특별한 공간. 참조형 변수가 가리키고자 하는 String이 이미 String pool에 있다면 같은 주소값을 가지게 됨.
- new 생성자를 이용하여 String 값을 직접 heap에 저장했다면 String pool에 같은 String 값이 있더라도 메모리를 새로 할당 (리터럴은 StringPool 에서 들고옴)
- 리터럴만 StringPool
- 생성자 new >> Heap 영역에 할당 >>
쓰레드의 동기화와 데드락
- 스레드 동기화
- 2개 이상의 스레드가 하나의 공유 자원에 접근하여 값을 변경하려고 할때, 동기화를 적용하지 않으면 값이 올바르게 변경되지 않을 가능성이 있습니다. 그래서 synchorinized 키워드로 하나의 스레드가 공유 자원을 점유하는 경우 다른 스레드가 대기상태에 머물도록 할 수 있다.
- 데드락
- a 쓰레드가 foo 라는 공유변수에 락을 걸어둔 상태로 작업 진행. b 스레드가 bar 라는 공유변수에 락을 걸어둔 상태로 작업 진행
- a 스레드가 bar 공유변수에 접근 > b 스레드 bar 이미 점유중. >> a 스레드 대기상태 변경 >> 동시에 b 스레드에 foo 공유 변수가 필요 >> b 스레드 대기상태 변경
- 두 스레드 모두 대기 상태에 계속 머물게 되는 현상
String , StringBuffer , StringBuilder
- String
- 문자열 처리하는 래퍼 클래스
- 변경불가능한 성질을 가집니다.
- 문자열을 변형하는 경우가 많은 경우 매번 새로운 String 객체가 생성되기에 메모리나 속도 측면에서 비효율적
- StringBuffer , StringBuilder
- 새로운 객체를 생성하지 않고 기존의 문자열을 변경함
- StringBuilder
- 스레드 동기화 지원 X
- StringBuffer
- 스레드 동기화 지원
- 속도는 동기화를 지원하지 않는 StringBuilder 가 더 빠름. > 스레드 사용하지 않는 환경에는 StringBuilder 가 유리
JVM 메모리 구조,,, GC
- JVM 메모리의 구조
- class stack heap native메서드 pc레지스터로 나뉨
- class 영역
- 클래스 변수 메서드 상수 static 변수에 대한 정보가 저장
- stack
- 메서드 호출에 따른 메서드를 위한 공간인 프레임이 생성
- 메서드 안에서 필요한 각종 값이 임시 저장
- 메서드 수행이 끝나면 프레임별로 삭제가 진행
- heap
- new 연산자로 생성된 객체와 배열이 저장되는 공간
- permanent generation | new | old 영역으로 나뉨
- permanent
- 생성된 객체들의 주소값이 저장됨
- new
- 다시 eden | survivor 영역으로 나뉨
- eden
- 객체들이 최초로 생성되는 영역
- survivor
- eden 영역에서 참조되는 개체들이 저장되는 영역
- eden
- 다시 eden | survivor 영역으로 나뉨
- old
- new 영역에서 일정 시간 참조되고 있는 객체들이 저장
- permanent
- native 메서드
- 자바 이외의 다른 언어에서 제공되는 메서드가 저장됨
- pc register 영역
- 스레드가 생성될 때 생성되는 영역으로 스레드가 어떤 명령을 실행할지 저장
- GC
- minor , major 로 나뉩니다
- minor
- new 영역을 대상으로 실행됨.
- new 영역 안의 eden 영역이 가득 차면 survivor1 영역으로 이동하고 나머지 영역의 객체를 삭제
- eden 영역과 survivor1 영역이 기준치 이상으로 차면 참조가 실제로 되고 있는지 검사 후 참조되는 객체만 survivor2 영역에 복사한 후 나머지 영역의 객체를 삭제
- 마지막으로 일정시간 참조되고 있는 객체들을 old영역으로 이동
- major
- old 영역을 대상으로 실행됨
- minor에 비해 느리며. old 영역이 가득 차 프로세스가 정지될 가능성이 있는 경우 실행되며
- odl 영역에 있는 모든 객체를 검사하여 참조되지 않은 객체들을 한꺼번에 삭제함
call-by-value, call-by-reference
- call-by-value
- 값에 의한 호출
- 함수 호출 시 전달되는 변수 값을 복사해서 함수인자로 전달
- call-by-reference
- 참조에 의한 호출
- 함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달함
- 자바에서는 call-by-value 로 값을 넘깁니다. 참조자료형도 해당 객체의 주소값 자체를 들고오는 것이지 원본 객체 자체를 변경할 수는 없다.
자바의 형변환 규칙
- 크게 2가지가 존재합니다. 묵시적 형변환과 명시적 형변환입니다.
- 묵시적 형변환은 자바에서 작은 단위를 큰 단위로 변경하는 경우 지원합니다 (업캐스팅)
- 명시적 형변환은 자바에서 큰 단위를 작은 단위로 변경하는 경우 지원합니다(다운캐스팅)
자바의 클래스 멤버 변수 초기화 순서
- 멤버 변수는 클래스 변수와 인스턴스 변수로 나뉜다
- 클래스 변수는 클래스가 처음 로딩될 때 한번만 초기화된다
- 인스턴스 변수는 인스턴스가 생성될 때마다 인스턴스별로 초기화가 이루어진다.
class Car{
int instanceVariable = 1; // 인스턴스 변수
static int staticVariable =1 ; // 클래스 변수(static, 공유)
// 인스턴스 초기화 블럭
{ instanceVariable = 2; }
// 클래스 초기화 블럭, 앞에 static이 붙음.
static{ staticVariable = 2; }
// 생성자, 인스턴스 변수 초기화 과정이 들어있음.
Car(){
instanceVariable = 3;
}
}
- 기본값 → 명시적 초기화 → 초기화 블럭 → 생성자(인스턴스에만 해당)
- 클래스 변수 초기화
- 클래스 로딩시 staticVariable 0으로 기본값
- 명시적 초기화 : staticVariable 1
- 클래스 초기화 블럭 : staticVariable 2
- 인스턴스 변수 초기화
- 인스턴스 생성
- 기본값 instanceVariable 0
- 명시적 초기화 : 1
- 인스턴스 초기화 블럭 : 2
- 생성자 3
자바에서 메모리 누수가 발생하는 경우와 해결 방안에 대해서 설명하시오.
.class 와 .java 의 차이점
JAVA
- • 왜 getter, setter 함수를 써야하는지?
- 일반적으로 프로그래밍시 객체들의 데이터(필드)를 외부에서 직접적으로 접근하는 것을 막아놓습니다
- 필드들을 private 접근 제한자로 막아두고, 각 필드의 Getter, Setter로 접근하는 방식
- 왜???
- 객체의 무결성을 보장하기 위함입니다
- 사람 몸무게는 음수값을 가질 수 없습니다
- 그렇기에 외부에서 직접적으로 접근해서 음수로 변경하는 경우 해당 객체의 무결성이 깨지는 상황이 발생합니다
- 그렇기에 필드를 private 으로 만들어 외부의 접근을 제한한 후 , Setter 를 사용하여 전달받은 값을 내부에서 가공해 필드에 넣어주는 방식을 사용합니다
- 또한 필드를 가져올 때도, Geeter 를 사용해 본 필드의 값을 숨긴 채, 내부에서 가공된 값을 꺼낼 수 있습니다.
- 접근제한자 설명
- 멤버들은 객체 자신들만의 속성이자 특징이므로 대외적으로 공개되는 것은 좋은 것이 아닙니다
- 프로그래머스가 객체의 멤버들에게 접근 제한을 걸 수 있는 데 자바에서는 이를 접근 제한자라고 함
- public
- 모든 접근을 허용
- protected
- 같은 패키지(폴더) 에 있는 객체와 상속관계의 객체들만 허용
- default
- 같은 패키지(폴더) 에 있는 객체들만 허용
- private
- 현재 객체 내에서만 허용
- 객체지향이란?구성요소
- 크게 클래스, 객체, 메서드
- 클래스
- 객체를 정의하는 틀, 게임에서의 (플레이어)라는 클래스를 만들고
- 해당 클래스에서 파생하여 여러 격투 캐릭터를 만들어낼 수 있음
- 구성요소
- 필드 (클래스에 포함된 변수), 메서드(특정 작업을 수행하기 위한 문장들의 집합), 생성자 ( 인스턴스 초기화 메서드)
- 객체와 인스턴스
- 클래스로부터 객체를 만들는 과정을 클래스의 인스턴스화라고 함
- 메서드
- 함수
- 먼저 만들어 놓고 언제든지 필요할 때 가져와서 사용하는 개념
- 객체 지향 언어??
- 우리가 살고 있는 세게를 모델링으로 한 개발 방법
- 절차지향
- 순서도 차트에 보이는 것 처럼 시작 기준에서 순서대로 진행
- 순서가 틀려도 안됨! 어느 한 부분이 오류나면 그 다음 부분 전체가 마비
- 객체 지향
- 순서 상관없이 독립적으로 사용 가능
- 이러한 객체들을 상호작용하여 설계가능
- 하나의 객체가 오류날지라도 다른 객체에 영향을 주지 않음
- 다중 상속에 대해 설명왜 다중상속을 지원하지 않는가??
- GranFather A() 메서드를 Father 클래스에서 각각 오버라이딩해서 구현함
- 하지만 Son 입장에서는 A() 메서드 호출시 누구의 메서드를 가져다 써야할지 알 수 없음
- 인터페이스는 기능 에 대한 선언만 하기에, 위와 같은 경우더라도 충돌할 여지가 없음
- 인터페이스 안에서는 추상메서드만을 선언! 하위 클래스들은 추상메서드를 오버라이딩 해서 구현함
- 정의
- 자바의 인반 클래스는 부모 클래스를 단 하나만 가져야함
- 다중 상속을 지원하지 않는다
- 하지만,
- 인터페이스는 추상 클래스보다 더 추상적이기에 여러 인터페이스를 상속받는 다중 상속을 지원합니다
- Java의 JVM에서 5가지 메모리 구조에 대해 설명JVM 은 다섯 가지의 컴포넌트로 구성
- 클래스 로더 시스템
- 컴파일 결과로 만들어진 .class 바이트 코드 파일을 읽어들여 메모리에 배치
- 로딩, 링크, 초기화의 세 가지의 과정을 거친다
- 컴파일 결과로 만들어진 .class 바이트 코드 파일을 읽어들여 메모리에 배치
- 메모리
- Runtime Engine
- 바이트 코드를 읽어들이는 인터프리터가 작동하는 영역
- 바이트 코드를 기계어로 변환하면서 Line by Line 으로 실행
- 인터프리터가 기계어 코드를 실행시, 한 번 변환한 바이트코드를 또 변환하는 대신 실행한 코드를 저장하는 영역이 존재
- Code Cache == JIT Compiler
- 프로그램 실행속도를 향상시킴
- Code Cache == JIT Compiler
- Garbage collection
- 바이트 코드를 읽어들이는 인터프리터가 작동하는 영역
- Native Method interface
- Native Method library
- 클래스 로더 시스템
- JVM 의 메모리 구조
- Heap Memory
- JVM이 객체의 인스턴스나 동적 할당된 데이터를 저장하는 공간
- Garbage Collection이 일어나는 장소
- Garbage Collection 을 위해.. 메모리를 분리한다?
- Young 과 Old 라는 두 개의 영역으로 논리적으로 분할해 사용
- Young
- 인스턴스를 처음 생성시 메모리에 배정되는 영역
- Eden : 인스턴스를 생성시 이곳에 배정
- Survivor space : Minor GC 로 Garbage를 걸러내고 살아남은 인스턴스가 배정
- 인스턴스를 처음 생성시 메모리에 배정되는 영역
- Old
- Minor Gc를 여러 번 거치고 살아남은 인스턴스가 배정
- 이곳의 GC 는 MajorGC
- Thread Stacks
- 메모리에서의 Stack.. 스레드ㅡ마다 하나씩 배정되는 메모리 영역, 메서드의 변환값 / 결과를 저장하거나 지역변수를 저장하는 용도
- Meta Space
- 애플리케이션의 클래스나 메서드 정보 또는 static으로 정의된 멤버 변수가 저장ㄷ
- Code Cache
- Shared Library
- Heap Memory
객체지향이란
- 객체
- 현실세계의 실체 및 개념을 반영하는 상태와 행위를 정의한 데이터의 집합
- 객체지향 프로그래밍
- 각자의 역할을 지닌 객체들끼리 서로 메시지를 주고받으며 동작할 수 있도록 프로그래밍 하는 것
객체 지향의 강점
객체를 중심으로 프로그래밍 하기 때문에
- 사람의 관점에서 프로그램을 이해하고 파악하기 쉽다
- 강한 응집력과 약한 결합력을 가진다
- 재사용성, 확장성, 융통성이 높다
이러한 강점 때문에 디버깅과 유지보수가 용이하고 설계와 분석이 비교적 쉽다
객체지향의 단점(한계)
- 객체 간의 정보 교환이 모두 메시지 교환을 통해 일어나므로 실행 시스템에 많은 overhead가 발생함
- 처리속도가 상대적으로 느리다
- 하지만 하드웨어의 발전으로 이러한 단점은 어느정도 해소되었다.
- 객체가 상태를 갖기 때문에 예상치 못한 부작용이 발생할 수 있다. 변수가 존재하고 이 변수를 통해 객체가 예측할 수 없는 상태를 갖게 되어 애플리케이션 내부에서 버그를 발생시킬 수 있다.
- 이는 함수형 프로그래밍 등장의 패러다임
객체지향적 설계원칙 SOLID
- SRP(Single Responsibility Principle) 단일 책임 원칙
- 클래스는 단 하나의 책임을 가져야 하며 클래스를 변경하는 이유는 단 하나의 이유이어야 한다.
- OCP(Open-Closed Principle) : 계방 - 폐쇄 원칙
- 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다.
- LSP(Liskov Substitution Priciple) : 리스코프 치환 원칙
- 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
- ISP(Interface Segregation Principle) : 인터페이스 분리 원칙
- 인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다
- DIP(Dependency Inversion Principle) : 의존 역전 원칙
- 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안됨
객체지향의 특징
- 추상화
- 객체에서 공통된 속성이나 기능을 추출하는 것. 중요하지 않은 것(관심 대상이 아닌 것)은 감추거나 무시하고, 중요한 것(관심있는 것)만을 강조하여 추출하는 것.
- 캡슐화
- 관심있는 데이터와 기능을 모아놓고 패킹한 것이다. 객체지향에서는 이를 클래스를 정의하고 외부에서 마음대로 접근 X. 정보의 은닉화!
- 다형성
- 같은 코드라 하더라고 상황에 따라 다른 방식으로 동작하는 성질. Java 에서 다형성을 구현할 수 있는 대표적으로 Overrinding 과 Overloading
- Overriding
- 임의의 클래스가 다른 클래스를 상속 받거나 인터페이스를 구현했을 때, 상위 클래스 또는 인터페이스에 정의되어 있는 메소드를 재정의 하여 사용하는 것이다.
- 메서드 호출 시 재정의되어 있지 않다면 상위 클래스의 메서드가 호출된다.
- Overloading
- 메소드 주어진 인자(parameter) 에 따라 동작을 다르게 구현할 수 있다. 코드의 중복 줄어들고, 가독성이 늘어난다. 반환 형 관계 X, 인자의 개수 타입을 다르게 구현가능
- 상속
- 부모의 형질을 이어받는다는 의미, 부모 클래스의 속성과 메서드를 그대로 활용할 수 있다.
- 클래스(class)
- 객체를 만들기 위해 상태(field)와 행위(method)를 정의한 틀.
- 메시지
- 객체지향적으로 구현된 프로그램은 객체들끼리의 메시지를 주고받고 상호작용하며 동작.
- 코드는 임의의 객체에게 인자를 전달, 메서드를 호출하며, 반환값을 받아 처리
자바의 장, 단점
- 장점
- 자바의 가장 큰 장점은 JVM 을 이용한 플랫폼 독립적이라는 점입니다, 자바에서 코드를 컴파일하면 바이트코드(.class) 형태로 출력됩니다. 하나의 바이트코드를 가지고 서로 다른 운영체제나 기계마다 해당 JVM 만 설치되어 있다면, 다시 컴파일 할 필요없이 나머지는 JVM 이 해당 기계에 맞게 실행해줍니다
- 단점
- 자바의 단점은 JVM 을 사용하는 데에 있습니다. 자바 프로그램이 실행되기 위해서는 먼저 JVM 이 실행되어야 하는데 JVM 실행과정은 많은 메모리를 소모하고 실행속도가 느립니다.
- JVM > 운영체제 각 JVM .. >> 의존적임 ,, Java 운영체제에 독립적이다. (Mac Java...이런건 없습니다)
기본 자료형과 참조 자료형
- 기본 자료형
- byte , short , int , long, float , double , char, boolean 이 존재합니다. 기본 자료형은 call by value 로서 값 자체가 저장되며, OS 에 따라 자료형의 길이가 변하지 않고, null값을 가질 수 없다는 특징이 있습니다
- 참조 자료형
- class , interface , array , enum 이 존재합니다. 참조 자료형은 생성한 변수에는 객체의 주소값이 저장됩니다. 주소값이 저장된다고 하여 call by reference 라고 생각할 수도 있지만. 주소의 위치 값 자체가 전달되는 call by value 입니다. null값을 가리킬 수 있습니다.
객체 지향 프로그래밍이란
- 실세계의 특정 사물을 추상화하며 그에 필요한 멤버 변수와 메서드를 정의하는 데서 출발합니다. OOP 의 특징에는 캡슐화, 상속, 추상화, 다형성이 있습니다.
- 꼬리질문
- 캡슐화란?
- 멤버 변수와 메서드의 이용가능범위를 적절하게 제한하여 안전한 프로그래밍을 지원하는 특징입니다.
- 상속이란?
- 부모 클래스의 기능을 자식 클래스에서 물려받을 수 있는 특징입니다
- 추상화란?
- 자식 클래스에서의 공통점을 취합하여 부모 클래스로 반영하는 특징
- 다형성이란?
- 하나의 메서드나 클래스가 다양한 방법으로 동작하게하는 요소를 말한다, 메서드 오버라이딩, 오버로딩이 존재합니다.
- 메서드 오버라이딩은 자식 클래스에서 부모 클래스의 메서드를 새롭게 재정의하는 것. 선언부는 동일하지만 함수 기능코드가 다른 역할을 수행 할 수 있습니다.
- 메서드 오버로딩은 하나의 클래스에서 같은 이름을 가졌지만 파라미터의 종류나 숫자가 다른 메서드를 구현하는 것입니다.
- 캡슐화란?
접근 제어자
- 접근제어자는 객체 지향 프로그래밍에서 클래스의 멤버 변수 또는 메서드에 설정하는 키워드로 접근 영역을 제한하는 데 사용합니다. public default protected private이 존재합니다
- 꼬리질문
- 접근제어자 범위 설명
- public
- 접근제한 X
- default
- 접근제어자 사용 X 같은 패키지내에서만 가능
- protected
- 같은 패키지내, 다른 패키지의 자식 클래스 내에서 접근
- private
- 같은 클래스 내에서만 접근가능
- public
- 접근제어자 범위 설명
- 꼬리질문
추상 클래스와 인터페이스
- 추상 클래스 (상속을 강제할떄 사용)
- 형태만 정의해 놓고 몸체는 없는 상태를 포함하고 있는 클래스를 의미한다. 클래스기에 extends키워드를 이용해 상속을 진행. 해당 추상클래스를 상속받은 자식 클래스에서는 반드시 추상메서드를 재정의해야함.
- 인터페이스(큰 프로젝트인 경우 다중 상속가능하기에)
- 추상 클래스보다 추상화 정보다 높은 상태를 정의하기 위해 사용한다. 멤버변수와 일반 메서드를 가질 수 없으며, 상수와 추상메서드만 선언가능합니다 ( 추상 클래스와 다른점)
- implements 키워드를 사용하여 상속을 진행하며(추상 클래스와 다른점), 자식 클래스에서 반드시 메서드는 재정의 해야한다.
- 다중 상속이 가능함 (추상 클래스와 다른점)
- 응집도 결합도프로그램의 한 요소가 해당 기능을 수행하기 위해 얼마만큼의 연관된 책임과 아이디어가 뭉쳐있는지를 나타내는 정도이다. 일반적으로 프로그램의 한 요소가 특정 목적을 위해 밀접하게 연관된 기능들이 모여서 구현되어 있고, 지나치게 많은 일을 하지 않으면 그것을 응집도가 높다고 표현한다. 응집도가 높으면 프로그램을 쉽게 이해할 수 있으므로 유지보수성이 높아진다.
- 이해하기 힘들고
- 따로 재사용하기 힘들며
- 유지보수하기 힘들고
- 다른 클래스의 변화에 민감하다.
- 이런 클래스는 대개 X and Y와 같은 식으로 이름을 붙인다. 한 클래스 안에 여러 기능 영역의 메소드가 들어 있어, 클래스가 한 가지 기능에 집중하지 못하는 일이 많다. 예를 들어, 이미지 처리하는 기능과 사운드 처리하는 기능을 같이 갖고 있으면 그 클래스는 응집도가 낮은 것이다.
- 같은 기능영역의 메소드로 구성되었지만 클래스내에 그들이 모두 구현된 경우로서 너무 많은 책임을 짊어지다 보니 클래스의 크기가 엄청나게 커진 경우이다. 다른 클래스가 해야 적당한 기능을 자신이 억지로 하려고 하니까 크기가 커진 것이다. 예를 들어, 돈의 지불(현금, 수표, 신용카드)과 관련된 모든 기능을 Payment(지불)라는 클래스에 넣으면 이 클래스는 응집도가 낮아진다. 이럴때는 현금, 수표, 신용카드의 공통된 결제 기능을 Payment 클래스에 정의하고, 각자 고유한 기능은 Cash, Check, CreditCard 등의 Payment를 상속받은 하위 클래스에 정의하는 것이 응집도를 높이는 방법이다.
- 클래스의 목적에 부합하는, 같은 기능영역( function area )의 메소드들로 구성되어 있다.
- 메소드의 개수가 상대적으로 작다. 그것은 오로지 자신만이 할 수 있는 책임을 부여 받았다는 뜻이다.
- 혼자 너무 많은 일을 하지 않는다. 다른 클래스와 협력한다.
- 한 모듈이 변경되기 위해서 다른 모듈의 변경을 요구하는 정도
좋은 설계란 높은 응집도를 가지고 결합도는 느슨해야 한다. 그 이유는 설계를 변경하기 쉽기 때문이다. - 의존성의 정도를 나타내며 다른 모듈에 대해 얼마나 많은 지식을 갖고 있는지를 나타내는 척도다. 어떤 모듈이 다른 모듈에 대해 너무 자세한 부분까지 알고 있다면 두 모듈은 높은 결합도를 가진다.
- 다른 기능 영역의 메소드들을 다수 포함한 클래스
- 응집도가 낮은 클래스의 문제점
- 응집도(Cohesion)
static 키워드의 쓰임새
- 클래스 내부의 메서드나 멤버 변수에 static 키워드를 사용하면 하나의 인스턴스에 속하지 않고 해당 클래스로부터 생성된 모든 인스턴스가 공통으로 공유하는 메서드와 변수로 변경됩니다
컬렉션 프레임워크에서 제네릭을 사용하는 이유
- 컴파일러가 특정 타입만 포함될 수 있도록 컬렉션을 제한합니다. 런타임시에 발생할 수 있는 잠재적인 모든 예외를 컴파일시에 잡아낼 수 있도록 도와주는 역할입니다.
- 런타임에서는 타입에 대한 제약 조건을 적용, 컴파일시 타입에 대한 정보를 소거하는 프로세스.
- 컴파일 시 발생하는 에러
- 컴파일러는 구문 오류로 프로그램을 컴파일 할 수 없다.
- 대체로 문법상의 에러
- 에러가 발생한 부분을 알려준다.
- 컴파일에러 예
- ’;’ 이 누락 된 문법 에러 (systax 오류)
- 괄호가 안 맞는 등 구문 에러
- classpath에 누락 된 클래스(컴파일시)
- 실행 시 발생하는 에러
- 프로그램이 컴파일 된 후 실행하면서 에러 발생
- 대체로 개발 시 설계 미숙(논리적)으로 발생하는 에러
- 에러 발생 시 프로그래머가 역추적해서 원인 확인해야함
- 런타임에러 예
- NullPointerException
- 무한루프
- 0으로 나누는 경우 등
- 컴파일타임 에러 (Compile-time Error)
컬렉션 프레임워크 대표 인터페이스
- 크게 list ,set , map 이 존재합니다
- list 는 순차적인 데이터를 저장하고, 중복을 허용합니다
- ArrayList , LinkedList , Stack ,vector 가 하위 클래스로 존재
- 주로 ArrayList는 검색이 많은 경우에 사용하고 LinkedList는 잦은 삽입/삭제 시 사용합니다.
- LinkedList > 왜 조회가 느린가?
- 첫 번쨰 값과 맨 뒤 값이 존재한다면..
- 첫번째부터 순차적으로 노드의 주소값을 찾아나간다.
- ArrayList
- n 속도
- 찾는 인덱스를 바로 찾아간다.
- set는 순서를 유지하지 않고 데이터의 중복만 허용하지 않는 자료구조
- hashset , treeset , LinkedHashSet > (특이)순서 O 중복 X
- hashset
- 해시 알고리즘으로 조회 > 조회가 빠름
- treeset
- 이진트리 방식 > heapq 에서 사용
- 범위 검색 > treeSet
- 일반 검색 > hashMap
- map 은 키와 값으로 이루저니 데이터를 순서 유지하지 않고 키의 중복만 허용하지 않는 자료구조
- hashmap treemap hashtable ...등이 하위 클래스
객체의 직렬화
- 객체에 저장되어 있는 데이터를 스트림(파일로 저장 혹은 네트워크를 이용하여 전송) 에 바로 쓰기 위하여 연속적인 데이터로 변환하는 과정
- 역직렬화
- 스트림으로부터 데이터를 읽어 객체로 변환하는 과정
- IO 패키지 내에서 Serializable 인터페이스를 상속받는 경우 직렬화가 가능한 클래스로 변경할 수 있음.
래퍼 클래스
- 기본 자료형으로 표현된 데이터를 참조 자료형으로 만들어야 할 경우 래퍼클래스 사용
- 특정 메서드에서 참조 자료형을 인자로 받거나,, 객체간의 비교가 필요한 경우 사용..
- 그리고 null 값을 래퍼 클래스를 받을 수 있기에.. 사용함
자바 쓰레드 구현하기 위한 방법 2가지
- lang 패키지내 > Thread 클래스 상속
- Runnable 인터페이스를 상속받아 run 메서드는 재정의해서 구현
- 하지만 자바에서는 다중 상속을 하용하지 않기 때문에, Thread 클래스를 확장하는 클래스는 다른 클래스를 상속받을 수 없습니다.
String에서 ==과 equals()는 어떤 차이가 있나요?
- ==은 참조형 변수의 값 자체, 즉 주소값을 비교하는 연산자이고 equals는 그 주소값이 가리키는 값을 비교하는 메소드.
StringPool에 대해서 설명해보세요.
- String의 값들이 저장되어있는 특별한 공간. 참조형 변수가 가리키고자 하는 String이 이미 String pool에 있다면 같은 주소값을 가지게 됨.
- new 생성자를 이용하여 String 값을 직접 heap에 저장했다면 String pool에 같은 String 값이 있더라도 메모리를 새로 할당 (리터럴은 StringPool 에서 들고옴)
- 리터럴만 StringPool
- 생성자 new >> Heap 영역에 할당 >>
쓰레드의 동기화와 데드락
- 스레드 동기화
- 2개 이상의 스레드가 하나의 공유 자원에 접근하여 값을 변경하려고 할때, 동기화를 적용하지 않으면 값이 올바르게 변경되지 않을 가능성이 있습니다. 그래서 synchorinized 키워드로 하나의 스레드가 공유 자원을 점유하는 경우 다른 스레드가 대기상태에 머물도록 할 수 있다.
- 데드락
- a 쓰레드가 foo 라는 공유변수에 락을 걸어둔 상태로 작업 진행. b 스레드가 bar 라는 공유변수에 락을 걸어둔 상태로 작업 진행
- a 스레드가 bar 공유변수에 접근 > b 스레드 bar 이미 점유중. >> a 스레드 대기상태 변경 >> 동시에 b 스레드에 foo 공유 변수가 필요 >> b 스레드 대기상태 변경
- 두 스레드 모두 대기 상태에 계속 머물게 되는 현상
String , StringBuffer , StringBuilder
- String
- 문자열 처리하는 래퍼 클래스
- 변경불가능한 성질을 가집니다.
- 문자열을 변형하는 경우가 많은 경우 매번 새로운 String 객체가 생성되기에 메모리나 속도 측면에서 비효율적
- StringBuffer , StringBuilder
- 새로운 객체를 생성하지 않고 기존의 문자열을 변경함
- StringBuilder
- 스레드 동기화 지원 X
- StringBuffer
- 스레드 동기화 지원
- 속도는 동기화를 지원하지 않는 StringBuilder 가 더 빠름. > 스레드 사용하지 않는 환경에는 StringBuilder 가 유리
JVM 메모리 구조,,, GC
- JVM 메모리의 구조
- class stack heap native메서드 pc레지스터로 나뉨
- class 영역
- 클래스 변수 메서드 상수 static 변수에 대한 정보가 저장
- stack
- 메서드 호출에 따른 메서드를 위한 공간인 프레임이 생성
- 메서드 안에서 필요한 각종 값이 임시 저장
- 메서드 수행이 끝나면 프레임별로 삭제가 진행
- heap
- new 연산자로 생성된 객체와 배열이 저장되는 공간
- permanent generation | new | old 영역으로 나뉨
- permanent
- 생성된 객체들의 주소값이 저장됨
- new
- 다시 eden | survivor 영역으로 나뉨
- eden
- 객체들이 최초로 생성되는 영역
- survivor
- eden 영역에서 참조되는 개체들이 저장되는 영역
- eden
- 다시 eden | survivor 영역으로 나뉨
- old
- new 영역에서 일정 시간 참조되고 있는 객체들이 저장
- permanent
- native 메서드
- 자바 이외의 다른 언어에서 제공되는 메서드가 저장됨
- pc register 영역
- 스레드가 생성될 때 생성되는 영역으로 스레드가 어떤 명령을 실행할지 저장
- GC
- minor , major 로 나뉩니다
- minor
- new 영역을 대상으로 실행됨.
- new 영역 안의 eden 영역이 가득 차면 survivor1 영역으로 이동하고 나머지 영역의 객체를 삭제
- eden 영역과 survivor1 영역이 기준치 이상으로 차면 참조가 실제로 되고 있는지 검사 후 참조되는 객체만 survivor2 영역에 복사한 후 나머지 영역의 객체를 삭제
- 마지막으로 일정시간 참조되고 있는 객체들을 old영역으로 이동
- major
- old 영역을 대상으로 실행됨
- minor에 비해 느리며. old 영역이 가득 차 프로세스가 정지될 가능성이 있는 경우 실행되며
- odl 영역에 있는 모든 객체를 검사하여 참조되지 않은 객체들을 한꺼번에 삭제함
call-by-value, call-by-reference
- call-by-value
- 값에 의한 호출
- 함수 호출 시 전달되는 변수 값을 복사해서 함수인자로 전달
- call-by-reference
- 참조에 의한 호출
- 함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달함
- 자바에서는 call-by-value 로 값을 넘깁니다. 참조자료형도 해당 객체의 주소값 자체를 들고오는 것이지 원본 객체 자체를 변경할 수는 없다.
자바의 형변환 규칙
- 크게 2가지가 존재합니다. 묵시적 형변환과 명시적 형변환입니다.
- 묵시적 형변환은 자바에서 작은 단위를 큰 단위로 변경하는 경우 지원합니다 (업캐스팅)
- 명시적 형변환은 자바에서 큰 단위를 작은 단위로 변경하는 경우 지원합니다(다운캐스팅)
자바의 클래스 멤버 변수 초기화 순서
- 멤버 변수는 클래스 변수와 인스턴스 변수로 나뉜다
- 클래스 변수는 클래스가 처음 로딩될 때 한번만 초기화된다
- 인스턴스 변수는 인스턴스가 생성될 때마다 인스턴스별로 초기화가 이루어진다.
class Car{
int instanceVariable = 1; // 인스턴스 변수
static int staticVariable =1 ; // 클래스 변수(static, 공유)
// 인스턴스 초기화 블럭
{ instanceVariable = 2; }
// 클래스 초기화 블럭, 앞에 static이 붙음.
static{ staticVariable = 2; }
// 생성자, 인스턴스 변수 초기화 과정이 들어있음.
Car(){
instanceVariable = 3;
}
}
- 기본값 → 명시적 초기화 → 초기화 블럭 → 생성자(인스턴스에만 해당)
- 클래스 변수 초기화
- 클래스 로딩시 staticVariable 0으로 기본값
- 명시적 초기화 : staticVariable 1
- 클래스 초기화 블럭 : staticVariable 2
- 인스턴스 변수 초기화
- 인스턴스 생성
- 기본값 instanceVariable 0
- 명시적 초기화 : 1
- 인스턴스 초기화 블럭 : 2
- 생성자 3
자바에서 메모리 누수가 발생하는 경우와 해결 방안에 대해서 설명하시오.
.class 와 .java 의 차이점
JAVA
- • 왜 getter, setter 함수를 써야하는지?
- 일반적으로 프로그래밍시 객체들의 데이터(필드)를 외부에서 직접적으로 접근하는 것을 막아놓습니다
- 필드들을 private 접근 제한자로 막아두고, 각 필드의 Getter, Setter로 접근하는 방식
- 왜???
- 객체의 무결성을 보장하기 위함입니다
- 사람 몸무게는 음수값을 가질 수 없습니다
- 그렇기에 외부에서 직접적으로 접근해서 음수로 변경하는 경우 해당 객체의 무결성이 깨지는 상황이 발생합니다
- 그렇기에 필드를 private 으로 만들어 외부의 접근을 제한한 후 , Setter 를 사용하여 전달받은 값을 내부에서 가공해 필드에 넣어주는 방식을 사용합니다
- 또한 필드를 가져올 때도, Geeter 를 사용해 본 필드의 값을 숨긴 채, 내부에서 가공된 값을 꺼낼 수 있습니다.
- 접근제한자 설명
- 멤버들은 객체 자신들만의 속성이자 특징이므로 대외적으로 공개되는 것은 좋은 것이 아닙니다
- 프로그래머스가 객체의 멤버들에게 접근 제한을 걸 수 있는 데 자바에서는 이를 접근 제한자라고 함
- public
- 모든 접근을 허용
- protected
- 같은 패키지(폴더) 에 있는 객체와 상속관계의 객체들만 허용
- default
- 같은 패키지(폴더) 에 있는 객체들만 허용
- private
- 현재 객체 내에서만 허용
- 객체지향이란?구성요소
- 크게 클래스, 객체, 메서드
- 클래스
- 객체를 정의하는 틀, 게임에서의 (플레이어)라는 클래스를 만들고
- 해당 클래스에서 파생하여 여러 격투 캐릭터를 만들어낼 수 있음
- 구성요소
- 필드 (클래스에 포함된 변수), 메서드(특정 작업을 수행하기 위한 문장들의 집합), 생성자 ( 인스턴스 초기화 메서드)
- 객체와 인스턴스
- 클래스로부터 객체를 만들는 과정을 클래스의 인스턴스화라고 함
- 메서드
- 함수
- 먼저 만들어 놓고 언제든지 필요할 때 가져와서 사용하는 개념
- 객체 지향 언어??
- 우리가 살고 있는 세게를 모델링으로 한 개발 방법
- 절차지향
- 순서도 차트에 보이는 것 처럼 시작 기준에서 순서대로 진행
- 순서가 틀려도 안됨! 어느 한 부분이 오류나면 그 다음 부분 전체가 마비
- 객체 지향
- 순서 상관없이 독립적으로 사용 가능
- 이러한 객체들을 상호작용하여 설계가능
- 하나의 객체가 오류날지라도 다른 객체에 영향을 주지 않음
- 다중 상속에 대해 설명왜 다중상속을 지원하지 않는가??
- GranFather A() 메서드를 Father 클래스에서 각각 오버라이딩해서 구현함
- 하지만 Son 입장에서는 A() 메서드 호출시 누구의 메서드를 가져다 써야할지 알 수 없음
- 인터페이스는 기능 에 대한 선언만 하기에, 위와 같은 경우더라도 충돌할 여지가 없음
- 인터페이스 안에서는 추상메서드만을 선언! 하위 클래스들은 추상메서드를 오버라이딩 해서 구현함
- 정의
- 자바의 인반 클래스는 부모 클래스를 단 하나만 가져야함
- 다중 상속을 지원하지 않는다
- 하지만,
- 인터페이스는 추상 클래스보다 더 추상적이기에 여러 인터페이스를 상속받는 다중 상속을 지원합니다
- Java의 JVM에서 5가지 메모리 구조에 대해 설명JVM 은 다섯 가지의 컴포넌트로 구성
- 클래스 로더 시스템
- 컴파일 결과로 만들어진 .class 바이트 코드 파일을 읽어들여 메모리에 배치
- 로딩, 링크, 초기화의 세 가지의 과정을 거친다
- 컴파일 결과로 만들어진 .class 바이트 코드 파일을 읽어들여 메모리에 배치
- 메모리
- Runtime Engine
- 바이트 코드를 읽어들이는 인터프리터가 작동하는 영역
- 바이트 코드를 기계어로 변환하면서 Line by Line 으로 실행
- 인터프리터가 기계어 코드를 실행시, 한 번 변환한 바이트코드를 또 변환하는 대신 실행한 코드를 저장하는 영역이 존재
- Code Cache == JIT Compiler
- 프로그램 실행속도를 향상시킴
- Code Cache == JIT Compiler
- Garbage collection
- 바이트 코드를 읽어들이는 인터프리터가 작동하는 영역
- Native Method interface
- Native Method library
- 클래스 로더 시스템
- JVM 의 메모리 구조
- Heap Memory
- JVM이 객체의 인스턴스나 동적 할당된 데이터를 저장하는 공간
- Garbage Collection이 일어나는 장소
- Garbage Collection 을 위해.. 메모리를 분리한다?
- Young 과 Old 라는 두 개의 영역으로 논리적으로 분할해 사용
- Young
- 인스턴스를 처음 생성시 메모리에 배정되는 영역
- Eden : 인스턴스를 생성시 이곳에 배정
- Survivor space : Minor GC 로 Garbage를 걸러내고 살아남은 인스턴스가 배정
- 인스턴스를 처음 생성시 메모리에 배정되는 영역
- Old
- Minor Gc를 여러 번 거치고 살아남은 인스턴스가 배정
- 이곳의 GC 는 MajorGC
- Thread Stacks
- 메모리에서의 Stack.. 스레드ㅡ마다 하나씩 배정되는 메모리 영역, 메서드의 변환값 / 결과를 저장하거나 지역변수를 저장하는 용도
- Meta Space
- 애플리케이션의 클래스나 메서드 정보 또는 static으로 정의된 멤버 변수가 저장ㄷ
- Code Cache
- Shared Library
- Heap Memory
객체지향이란
- 객체
- 현실세계의 실체 및 개념을 반영하는 상태와 행위를 정의한 데이터의 집합
- 객체지향 프로그래밍
- 각자의 역할을 지닌 객체들끼리 서로 메시지를 주고받으며 동작할 수 있도록 프로그래밍 하는 것
객체 지향의 강점
객체를 중심으로 프로그래밍 하기 때문에
- 사람의 관점에서 프로그램을 이해하고 파악하기 쉽다
- 강한 응집력과 약한 결합력을 가진다
- 재사용성, 확장성, 융통성이 높다
이러한 강점 때문에 디버깅과 유지보수가 용이하고 설계와 분석이 비교적 쉽다
객체지향의 단점(한계)
- 객체 간의 정보 교환이 모두 메시지 교환을 통해 일어나므로 실행 시스템에 많은 overhead가 발생함
- 처리속도가 상대적으로 느리다
- 하지만 하드웨어의 발전으로 이러한 단점은 어느정도 해소되었다.
- 객체가 상태를 갖기 때문에 예상치 못한 부작용이 발생할 수 있다. 변수가 존재하고 이 변수를 통해 객체가 예측할 수 없는 상태를 갖게 되어 애플리케이션 내부에서 버그를 발생시킬 수 있다.
- 이는 함수형 프로그래밍 등장의 패러다임
객체지향적 설계원칙 SOLID
- SRP(Single Responsibility Principle) 단일 책임 원칙
- 클래스는 단 하나의 책임을 가져야 하며 클래스를 변경하는 이유는 단 하나의 이유이어야 한다.
- OCP(Open-Closed Principle) : 계방 - 폐쇄 원칙
- 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다.
- LSP(Liskov Substitution Priciple) : 리스코프 치환 원칙
- 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
- ISP(Interface Segregation Principle) : 인터페이스 분리 원칙
- 인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다
- DIP(Dependency Inversion Principle) : 의존 역전 원칙
- 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안됨
객체지향의 특징
- 추상화
- 객체에서 공통된 속성이나 기능을 추출하는 것. 중요하지 않은 것(관심 대상이 아닌 것)은 감추거나 무시하고, 중요한 것(관심있는 것)만을 강조하여 추출하는 것.
- 캡슐화
- 관심있는 데이터와 기능을 모아놓고 패킹한 것이다. 객체지향에서는 이를 클래스를 정의하고 외부에서 마음대로 접근 X. 정보의 은닉화!
- 다형성
- 같은 코드라 하더라고 상황에 따라 다른 방식으로 동작하는 성질. Java 에서 다형성을 구현할 수 있는 대표적으로 Overrinding 과 Overloading
- Overriding
- 임의의 클래스가 다른 클래스를 상속 받거나 인터페이스를 구현했을 때, 상위 클래스 또는 인터페이스에 정의되어 있는 메소드를 재정의 하여 사용하는 것이다.
- 메서드 호출 시 재정의되어 있지 않다면 상위 클래스의 메서드가 호출된다.
- Overloading
- 메소드 주어진 인자(parameter) 에 따라 동작을 다르게 구현할 수 있다. 코드의 중복 줄어들고, 가독성이 늘어난다. 반환 형 관계 X, 인자의 개수 타입을 다르게 구현가능
- 상속
- 부모의 형질을 이어받는다는 의미, 부모 클래스의 속성과 메서드를 그대로 활용할 수 있다.
- 클래스(class)
- 객체를 만들기 위해 상태(field)와 행위(method)를 정의한 틀.
- 메시지
- 객체지향적으로 구현된 프로그램은 객체들끼리의 메시지를 주고받고 상호작용하며 동작.
- 코드는 임의의 객체에게 인자를 전달, 메서드를 호출하며, 반환값을 받아 처리
자바의 장, 단점
- 장점
- 자바의 가장 큰 장점은 JVM 을 이용한 플랫폼 독립적이라는 점입니다, 자바에서 코드를 컴파일하면 바이트코드(.class) 형태로 출력됩니다. 하나의 바이트코드를 가지고 서로 다른 운영체제나 기계마다 해당 JVM 만 설치되어 있다면, 다시 컴파일 할 필요없이 나머지는 JVM 이 해당 기계에 맞게 실행해줍니다
- 단점
- 자바의 단점은 JVM 을 사용하는 데에 있습니다. 자바 프로그램이 실행되기 위해서는 먼저 JVM 이 실행되어야 하는데 JVM 실행과정은 많은 메모리를 소모하고 실행속도가 느립니다.
- JVM > 운영체제 각 JVM .. >> 의존적임 ,, Java 운영체제에 독립적이다. (Mac Java...이런건 없습니다)
기본 자료형과 참조 자료형
- 기본 자료형
- byte , short , int , long, float , double , char, boolean 이 존재합니다. 기본 자료형은 call by value 로서 값 자체가 저장되며, OS 에 따라 자료형의 길이가 변하지 않고, null값을 가질 수 없다는 특징이 있습니다
- 참조 자료형
- class , interface , array , enum 이 존재합니다. 참조 자료형은 생성한 변수에는 객체의 주소값이 저장됩니다. 주소값이 저장된다고 하여 call by reference 라고 생각할 수도 있지만. 주소의 위치 값 자체가 전달되는 call by value 입니다. null값을 가리킬 수 있습니다.
객체 지향 프로그래밍이란
- 실세계의 특정 사물을 추상화하며 그에 필요한 멤버 변수와 메서드를 정의하는 데서 출발합니다. OOP 의 특징에는 캡슐화, 상속, 추상화, 다형성이 있습니다.
- 꼬리질문
- 캡슐화란?
- 멤버 변수와 메서드의 이용가능범위를 적절하게 제한하여 안전한 프로그래밍을 지원하는 특징입니다.
- 상속이란?
- 부모 클래스의 기능을 자식 클래스에서 물려받을 수 있는 특징입니다
- 추상화란?
- 자식 클래스에서의 공통점을 취합하여 부모 클래스로 반영하는 특징
- 다형성이란?
- 하나의 메서드나 클래스가 다양한 방법으로 동작하게하는 요소를 말한다, 메서드 오버라이딩, 오버로딩이 존재합니다.
- 메서드 오버라이딩은 자식 클래스에서 부모 클래스의 메서드를 새롭게 재정의하는 것. 선언부는 동일하지만 함수 기능코드가 다른 역할을 수행 할 수 있습니다.
- 메서드 오버로딩은 하나의 클래스에서 같은 이름을 가졌지만 파라미터의 종류나 숫자가 다른 메서드를 구현하는 것입니다.
- 캡슐화란?
접근 제어자
- 접근제어자는 객체 지향 프로그래밍에서 클래스의 멤버 변수 또는 메서드에 설정하는 키워드로 접근 영역을 제한하는 데 사용합니다. public default protected private이 존재합니다
- 꼬리질문
- 접근제어자 범위 설명
- public
- 접근제한 X
- default
- 접근제어자 사용 X 같은 패키지내에서만 가능
- protected
- 같은 패키지내, 다른 패키지의 자식 클래스 내에서 접근
- private
- 같은 클래스 내에서만 접근가능
- public
- 접근제어자 범위 설명
- 꼬리질문
추상 클래스와 인터페이스
- 추상 클래스 (상속을 강제할떄 사용)
- 형태만 정의해 놓고 몸체는 없는 상태를 포함하고 있는 클래스를 의미한다. 클래스기에 extends키워드를 이용해 상속을 진행. 해당 추상클래스를 상속받은 자식 클래스에서는 반드시 추상메서드를 재정의해야함.
- 인터페이스(큰 프로젝트인 경우 다중 상속가능하기에)
- 추상 클래스보다 추상화 정보다 높은 상태를 정의하기 위해 사용한다. 멤버변수와 일반 메서드를 가질 수 없으며, 상수와 추상메서드만 선언가능합니다 ( 추상 클래스와 다른점)
- implements 키워드를 사용하여 상속을 진행하며(추상 클래스와 다른점), 자식 클래스에서 반드시 메서드는 재정의 해야한다.
- 다중 상속이 가능함 (추상 클래스와 다른점)
- 응집도 결합도프로그램의 한 요소가 해당 기능을 수행하기 위해 얼마만큼의 연관된 책임과 아이디어가 뭉쳐있는지를 나타내는 정도이다. 일반적으로 프로그램의 한 요소가 특정 목적을 위해 밀접하게 연관된 기능들이 모여서 구현되어 있고, 지나치게 많은 일을 하지 않으면 그것을 응집도가 높다고 표현한다. 응집도가 높으면 프로그램을 쉽게 이해할 수 있으므로 유지보수성이 높아진다.
- 이해하기 힘들고
- 따로 재사용하기 힘들며
- 유지보수하기 힘들고
- 다른 클래스의 변화에 민감하다.
- 이런 클래스는 대개 X and Y와 같은 식으로 이름을 붙인다. 한 클래스 안에 여러 기능 영역의 메소드가 들어 있어, 클래스가 한 가지 기능에 집중하지 못하는 일이 많다. 예를 들어, 이미지 처리하는 기능과 사운드 처리하는 기능을 같이 갖고 있으면 그 클래스는 응집도가 낮은 것이다.
- 같은 기능영역의 메소드로 구성되었지만 클래스내에 그들이 모두 구현된 경우로서 너무 많은 책임을 짊어지다 보니 클래스의 크기가 엄청나게 커진 경우이다. 다른 클래스가 해야 적당한 기능을 자신이 억지로 하려고 하니까 크기가 커진 것이다. 예를 들어, 돈의 지불(현금, 수표, 신용카드)과 관련된 모든 기능을 Payment(지불)라는 클래스에 넣으면 이 클래스는 응집도가 낮아진다. 이럴때는 현금, 수표, 신용카드의 공통된 결제 기능을 Payment 클래스에 정의하고, 각자 고유한 기능은 Cash, Check, CreditCard 등의 Payment를 상속받은 하위 클래스에 정의하는 것이 응집도를 높이는 방법이다.
- 클래스의 목적에 부합하는, 같은 기능영역( function area )의 메소드들로 구성되어 있다.
- 메소드의 개수가 상대적으로 작다. 그것은 오로지 자신만이 할 수 있는 책임을 부여 받았다는 뜻이다.
- 혼자 너무 많은 일을 하지 않는다. 다른 클래스와 협력한다.
- 한 모듈이 변경되기 위해서 다른 모듈의 변경을 요구하는 정도
좋은 설계란 높은 응집도를 가지고 결합도는 느슨해야 한다. 그 이유는 설계를 변경하기 쉽기 때문이다. - 의존성의 정도를 나타내며 다른 모듈에 대해 얼마나 많은 지식을 갖고 있는지를 나타내는 척도다. 어떤 모듈이 다른 모듈에 대해 너무 자세한 부분까지 알고 있다면 두 모듈은 높은 결합도를 가진다.
- 다른 기능 영역의 메소드들을 다수 포함한 클래스
- 응집도가 낮은 클래스의 문제점
- 응집도(Cohesion)
static 키워드의 쓰임새
- 클래스 내부의 메서드나 멤버 변수에 static 키워드를 사용하면 하나의 인스턴스에 속하지 않고 해당 클래스로부터 생성된 모든 인스턴스가 공통으로 공유하는 메서드와 변수로 변경됩니다
컬렉션 프레임워크에서 제네릭을 사용하는 이유
- 컴파일러가 특정 타입만 포함될 수 있도록 컬렉션을 제한합니다. 런타임시에 발생할 수 있는 잠재적인 모든 예외를 컴파일시에 잡아낼 수 있도록 도와주는 역할입니다.
- 런타임에서는 타입에 대한 제약 조건을 적용, 컴파일시 타입에 대한 정보를 소거하는 프로세스.
- 컴파일 시 발생하는 에러
- 컴파일러는 구문 오류로 프로그램을 컴파일 할 수 없다.
- 대체로 문법상의 에러
- 에러가 발생한 부분을 알려준다.
- 컴파일에러 예
- ’;’ 이 누락 된 문법 에러 (systax 오류)
- 괄호가 안 맞는 등 구문 에러
- classpath에 누락 된 클래스(컴파일시)
- 실행 시 발생하는 에러
- 프로그램이 컴파일 된 후 실행하면서 에러 발생
- 대체로 개발 시 설계 미숙(논리적)으로 발생하는 에러
- 에러 발생 시 프로그래머가 역추적해서 원인 확인해야함
- 런타임에러 예
- NullPointerException
- 무한루프
- 0으로 나누는 경우 등
- 컴파일타임 에러 (Compile-time Error)
컬렉션 프레임워크 대표 인터페이스
- 크게 list ,set , map 이 존재합니다
- list 는 순차적인 데이터를 저장하고, 중복을 허용합니다
- ArrayList , LinkedList , Stack ,vector 가 하위 클래스로 존재
- 주로 ArrayList는 검색이 많은 경우에 사용하고 LinkedList는 잦은 삽입/삭제 시 사용합니다.
- LinkedList > 왜 조회가 느린가?
- 첫 번쨰 값과 맨 뒤 값이 존재한다면..
- 첫번째부터 순차적으로 노드의 주소값을 찾아나간다.
- ArrayList
- n 속도
- 찾는 인덱스를 바로 찾아간다.
- set는 순서를 유지하지 않고 데이터의 중복만 허용하지 않는 자료구조
- hashset , treeset , LinkedHashSet > (특이)순서 O 중복 X
- hashset
- 해시 알고리즘으로 조회 > 조회가 빠름
- treeset
- 이진트리 방식 > heapq 에서 사용
- 범위 검색 > treeSet
- 일반 검색 > hashMap
- map 은 키와 값으로 이루저니 데이터를 순서 유지하지 않고 키의 중복만 허용하지 않는 자료구조
- hashmap treemap hashtable ...등이 하위 클래스
객체의 직렬화
- 객체에 저장되어 있는 데이터를 스트림(파일로 저장 혹은 네트워크를 이용하여 전송) 에 바로 쓰기 위하여 연속적인 데이터로 변환하는 과정
- 역직렬화
- 스트림으로부터 데이터를 읽어 객체로 변환하는 과정
- IO 패키지 내에서 Serializable 인터페이스를 상속받는 경우 직렬화가 가능한 클래스로 변경할 수 있음.
래퍼 클래스
- 기본 자료형으로 표현된 데이터를 참조 자료형으로 만들어야 할 경우 래퍼클래스 사용
- 특정 메서드에서 참조 자료형을 인자로 받거나,, 객체간의 비교가 필요한 경우 사용..
- 그리고 null 값을 래퍼 클래스를 받을 수 있기에.. 사용함
자바 쓰레드 구현하기 위한 방법 2가지
- lang 패키지내 > Thread 클래스 상속
- Runnable 인터페이스를 상속받아 run 메서드는 재정의해서 구현
- 하지만 자바에서는 다중 상속을 하용하지 않기 때문에, Thread 클래스를 확장하는 클래스는 다른 클래스를 상속받을 수 없습니다.
String에서 ==과 equals()는 어떤 차이가 있나요?
- ==은 참조형 변수의 값 자체, 즉 주소값을 비교하는 연산자이고 equals는 그 주소값이 가리키는 값을 비교하는 메소드.
StringPool에 대해서 설명해보세요.
- String의 값들이 저장되어있는 특별한 공간. 참조형 변수가 가리키고자 하는 String이 이미 String pool에 있다면 같은 주소값을 가지게 됨.
- new 생성자를 이용하여 String 값을 직접 heap에 저장했다면 String pool에 같은 String 값이 있더라도 메모리를 새로 할당 (리터럴은 StringPool 에서 들고옴)
- 리터럴만 StringPool
- 생성자 new >> Heap 영역에 할당 >>
쓰레드의 동기화와 데드락
- 스레드 동기화
- 2개 이상의 스레드가 하나의 공유 자원에 접근하여 값을 변경하려고 할때, 동기화를 적용하지 않으면 값이 올바르게 변경되지 않을 가능성이 있습니다. 그래서 synchorinized 키워드로 하나의 스레드가 공유 자원을 점유하는 경우 다른 스레드가 대기상태에 머물도록 할 수 있다.
- 데드락
- a 쓰레드가 foo 라는 공유변수에 락을 걸어둔 상태로 작업 진행. b 스레드가 bar 라는 공유변수에 락을 걸어둔 상태로 작업 진행
- a 스레드가 bar 공유변수에 접근 > b 스레드 bar 이미 점유중. >> a 스레드 대기상태 변경 >> 동시에 b 스레드에 foo 공유 변수가 필요 >> b 스레드 대기상태 변경
- 두 스레드 모두 대기 상태에 계속 머물게 되는 현상
String , StringBuffer , StringBuilder
- String
- 문자열 처리하는 래퍼 클래스
- 변경불가능한 성질을 가집니다.
- 문자열을 변형하는 경우가 많은 경우 매번 새로운 String 객체가 생성되기에 메모리나 속도 측면에서 비효율적
- StringBuffer , StringBuilder
- 새로운 객체를 생성하지 않고 기존의 문자열을 변경함
- StringBuilder
- 스레드 동기화 지원 X
- StringBuffer
- 스레드 동기화 지원
- 속도는 동기화를 지원하지 않는 StringBuilder 가 더 빠름. > 스레드 사용하지 않는 환경에는 StringBuilder 가 유리
JVM 메모리 구조,,, GC
- JVM 메모리의 구조
- class stack heap native메서드 pc레지스터로 나뉨
- class 영역
- 클래스 변수 메서드 상수 static 변수에 대한 정보가 저장
- stack
- 메서드 호출에 따른 메서드를 위한 공간인 프레임이 생성
- 메서드 안에서 필요한 각종 값이 임시 저장
- 메서드 수행이 끝나면 프레임별로 삭제가 진행
- heap
- new 연산자로 생성된 객체와 배열이 저장되는 공간
- permanent generation | new | old 영역으로 나뉨
- permanent
- 생성된 객체들의 주소값이 저장됨
- new
- 다시 eden | survivor 영역으로 나뉨
- eden
- 객체들이 최초로 생성되는 영역
- survivor
- eden 영역에서 참조되는 개체들이 저장되는 영역
- eden
- 다시 eden | survivor 영역으로 나뉨
- old
- new 영역에서 일정 시간 참조되고 있는 객체들이 저장
- permanent
- native 메서드
- 자바 이외의 다른 언어에서 제공되는 메서드가 저장됨
- pc register 영역
- 스레드가 생성될 때 생성되는 영역으로 스레드가 어떤 명령을 실행할지 저장
- GC
- minor , major 로 나뉩니다
- minor
- new 영역을 대상으로 실행됨.
- new 영역 안의 eden 영역이 가득 차면 survivor1 영역으로 이동하고 나머지 영역의 객체를 삭제
- eden 영역과 survivor1 영역이 기준치 이상으로 차면 참조가 실제로 되고 있는지 검사 후 참조되는 객체만 survivor2 영역에 복사한 후 나머지 영역의 객체를 삭제
- 마지막으로 일정시간 참조되고 있는 객체들을 old영역으로 이동
- major
- old 영역을 대상으로 실행됨
- minor에 비해 느리며. old 영역이 가득 차 프로세스가 정지될 가능성이 있는 경우 실행되며
- odl 영역에 있는 모든 객체를 검사하여 참조되지 않은 객체들을 한꺼번에 삭제함
call-by-value, call-by-reference
- call-by-value
- 값에 의한 호출
- 함수 호출 시 전달되는 변수 값을 복사해서 함수인자로 전달
- call-by-reference
- 참조에 의한 호출
- 함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달함
- 자바에서는 call-by-value 로 값을 넘깁니다. 참조자료형도 해당 객체의 주소값 자체를 들고오는 것이지 원본 객체 자체를 변경할 수는 없다.
자바의 형변환 규칙
- 크게 2가지가 존재합니다. 묵시적 형변환과 명시적 형변환입니다.
- 묵시적 형변환은 자바에서 작은 단위를 큰 단위로 변경하는 경우 지원합니다 (업캐스팅)
- 명시적 형변환은 자바에서 큰 단위를 작은 단위로 변경하는 경우 지원합니다(다운캐스팅)
자바의 클래스 멤버 변수 초기화 순서
- 멤버 변수는 클래스 변수와 인스턴스 변수로 나뉜다
- 클래스 변수는 클래스가 처음 로딩될 때 한번만 초기화된다
- 인스턴스 변수는 인스턴스가 생성될 때마다 인스턴스별로 초기화가 이루어진다.
class Car{
int instanceVariable = 1; // 인스턴스 변수
static int staticVariable =1 ; // 클래스 변수(static, 공유)
// 인스턴스 초기화 블럭
{ instanceVariable = 2; }
// 클래스 초기화 블럭, 앞에 static이 붙음.
static{ staticVariable = 2; }
// 생성자, 인스턴스 변수 초기화 과정이 들어있음.
Car(){
instanceVariable = 3;
}
}
- 기본값 → 명시적 초기화 → 초기화 블럭 → 생성자(인스턴스에만 해당)
- 클래스 변수 초기화
- 클래스 로딩시 staticVariable 0으로 기본값
- 명시적 초기화 : staticVariable 1
- 클래스 초기화 블럭 : staticVariable 2
- 인스턴스 변수 초기화
- 인스턴스 생성
- 기본값 instanceVariable 0
- 명시적 초기화 : 1
- 인스턴스 초기화 블럭 : 2
- 생성자 3
자바에서 메모리 누수가 발생하는 경우와 해결 방안에 대해서 설명하시오.
.class 와 .java 의 차이점
'자바 [JAVA]' 카테고리의 다른 글
[언어 공통] 면접 질문 사항 (추가중) (0) | 2022.03.24 |
---|---|
예제로 공부하는 Java 100 문제풀이 - Part.1[문1] - 문제쉬워서 그냥 넘어갈 예정. (0) | 2022.01.05 |
연속된 문자가 있는지 확인하는 방법 (0) | 2022.01.04 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- K번째수
- 2019 카카오 개발자 겨울 인턴십
- 10진수
- Git
- 백준
- 킹
- 2진수
- 인형뽑기
- 브루트포스
- 구현
- 알고리즘
- 코딩테스트
- 1063
- java
- 프로그래머스
- 크레인 인형뽑기 게임
- 자료구조
- 오
- 자료표현
- 프로그래머스 # 음양더하기
- stack
- ASCII코드
- solved.ac
- 카카오 코딩테스트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함