-
CS 스터디 - JavaCS 2023. 8. 31. 02:17
#1 ArrayList와 Linked List 차이점?
- ArrayList
- 배열과 유사하나 크기를 지정하지 않고 동적으로 값을 삽입하고 삭제할 수 있음
- 초기 용량이 다 차면 더 큰 ArrayList 생성 후 거기다 복사한다. 원소가 많다면 대략적인 용량을 처음에 설정하는 것이 성능상 좋다.
- 조회
- 각 데이터의 index 가지고 있고 index를 통해 해당 데이터에 바로 접근 가능
- 데이터 삽입, 삭제
- 가장 마지막 자리에 데이터를 삽입하거나 삭제한다면 빠른 속도가 가능하나, 중간에 데이터를 삽입하거나 삭제할 경우 빈 칸만큼 뒤의 원소를 앞으로 이동시켜야 한다. (위치를 맞춰줘야 함)
- 따라서 일반적으로 ArrayList 중간에 원소를 삽입하거나 삭제하는 경우가 많다면 비효율적
- 만약 원소를 맨 뒤에 원소부터 쭉 삭제하거나 삽입하게 된다면 오히려 Linked List보다 빠르다.
- Linked List
- 양방향 연결리스트로 구성되어 있어 참조하려는 원소에 따라 정방향 / 역순으로 순회가 가능하다.
- 순차적으로 접근해야 하므로 (물리적으로 메모리상에 붙어있지 않음) 데이터 조회시 연결된 데이터들을 다 검색해야 하므로 느리다
- 중간에 있는 데이터를 추가하거나 삭제할 경우 ArrayList보다 속도상 더 빠르다 (새롭게 원소를 앞으로 당겨올 필요 없이 주소값만 변경해주면 된다)
- 맨 뒤에 계속 데이터를 추가하거나 삭제한다면(순차적인 작업) 마지막 원소까지 탐색하는 시간이 걸리므로 오히려 ArrayList보다 성능이 떨어질 수 있음
#2 자바의 syncrohonized 키워드는 어떤 경우에 사용하나요?
synchronized는 여러 스레드가 하나의 자원을 사용하고자 할 때, 현재 데이터를 사용하고 있는 해당 스레드를 제외하고 나머지 스레드들은 데이터에 접근할 수 없도록 막는 키워드로 메서드에 붙이거나 메서드 내 블록 단위에 붙일 수 있습니다. 이때 lock을 걸어 다른 스레드의 접근을 막기 때문에 멀티 스레드 간 가시성 문제와 동시 접근 문제를 해결하여 thread-safe 하다는 장점이 있으나, synchronized를 남용하게 되면 스레드들이 lock 을 얻기 위해 대기해야하므로 성능 저하 문제가 발생할 수 있습니다.
* 가시성 문제 : 하나의 스레드에서 공유 자원 수정한 결과가 다른 스레드에게 보이지 않는 문제(타 스레드에서의 변경을 알아차리지 못하는 것)
* 동시 접근 문제 : 여러 스레드에서 공유자원 동시 접근 시 연산이 가장 늦게 끝난 결과값으로 덮어씌워지는 것
#3 static 키워드는 무엇이고, 사용 시 주의해야 할 점이 무엇인가요?
static 키워드는 하나의 인스턴스만 생성되어 여러 스레드가 공유할 수 있습니다. static 키워드를 잘 못 사용하면, 각 스레드간 동기화 문제가 발생하여 여러 스레드가 동시에 접근하거나 수행시 값이 가장 마지막 수행 결과로 덮어씌워지는 동시 접근 문제나 수정한 결과가 제대로 다른 스레드에 보여지지 않는 가시성 문제가 발생할 수 있습니다.
#4 JVM의 class loader에 대해 설명해주세요
- 자바의 .class(컴파일된)를 메모리로 올려주는 역할
- Loading - Linking - Initializing 단계를 진행
Loading
- 특정 이름을 가진 클래스 또는 인터페이스 찾고 메모리에 로드 / 동적으로 필요한 것들만 찾고 클래스 타입의 객체를 Heap에 만들어 둔다. (static 변수나 사용 안하는 건 이 단계에서는 로딩 안해둠)
Linking
- 클래스 파일을 읽어서 바이너리 데이터를 만들고 메서드 영역에 저장 / 클래스나 인터페이스를 가져와 실행될 수 있도록 Java Virtual Machine의 런타임 상태로 결합하는 프로세스
- Verifying : 읽은 클래스 파일이 정상적인지, 유효한지 검증 후 다음단계 수행
- Preserving : 필요한 것 메모리 공간에 할당
- Resolving : 동작 여부 결정 / 이 과정에서 심볼릭 메모리 레퍼런스를(이름에 의한 참조) 메소드 영역에 있는 실제 메모리 인스턴스에 대한 레퍼런스로 바꿔줌
Initializing
- Linking 단계에서 확보한 메모리 영역의 클래스 static 변수를 명시된 값으로 할당
#5 자바의 변수 종류 4가지와 생명 주기에 대해 설명해주세요
- 지역변수
- 중괄호 내에서 선언된 변수로 해당 괄호 내에서만 유효
- 매개변수
- 메소드에 넘겨주는 변수, 메소드 호출 시 생명이 시작되어 끝나면 소멸
- 인스턴스 변수
- 메소드 밖, 클래스 안에 선언된 변수로 앞에는 static 예약어 붙지 않는 변수 / 객체 생성시 생성되어 그 객체가 제거될 시 소멸됨 (unreachable하게 되어 GC 처리될 때 같이 소멸)
- 클래스 변수
- 인스턴스 변수처럼 메소드 밖, 클래스 안에 있되 앞에 static 예약어 붙어있음 / 모든 인스턴스들이 공통 값을 가짐 ~ 클래스 호출 시 생명 시작되어 자바 프로그램 끝날 때 소멸(class loader 의 초기화 단계에서 할당되므로)
public class Variable { int instanceVariable; // 인스턴스 변수 static int classVariable; // 클래스 변수 public void method(int parameter) { // parameter : 매개변수 int localVariable; // 지역변수 } }
#6 클래스와 인스턴스의 차이점?
- Class
- 객체를 생성하기 위한 일종의 설계도
- 속성(필드)와 동작(메소드)로 구성되어 있으며 속성과 동작을 0개 이상 가지고 있을 수 있다.
- Instance
- Class를 통해 new 키워드로 생성된 객체들을 인스턴스라고 하며, Heap 영역에 클래스를 기반으로 각각 새로운 인스턴스(객체)를 생성할 수 있다.
#7 자바의 GC 알고리즘 중 Garbage First에 대해 간단히 설명해주세요
Java 9+버전의 default GC
힙 메모리를 기존의 Linear하게 분할하던 GC들과 달리, 바둑판 모양의 여러 영역으로 구분하여 Eden - Survivor - Old - Reserved(큰 객체 담는 용) 으로 역할 구분
한 번에 스캔하는 것이 아닌, 영역 단위로 GC 수행해서 stop the world 타임 예측가능
#8 final 키워드에 대해 설명해주세요
- class에 붙은 경우
- 해당 클래스를 상속을 통해 더 이상 확장할 수 없게 만든다.
- 상속받아서 내용을 변경하면 안되는 클래스에 final 키워드 사용
- method에 붙은 경우
- 해당 메소드를 오버라이딩 하지 못하도록 막는다.
- 변수에 붙는 경우 : 값을 변경하지 못하도록 막는 의도
- 인스턴스, 클래스 변수인 경우
- 선언과 함께 무조건 값을 지정하여 초기화, 그 후 변경 불가능하다.
- 생성과 동시에 초기화
- 매개변수나 지역변수인 경우
- 선언 과 동시에 초기화할 필요는 없으나 한번 값이 지정되면 변경 불가능하다.
- 인스턴스, 클래스 변수인 경우
- 객체에 final 붙은 경우에도 새로 생성자 사용하거나 두 번 이상 값 할당 불가능 : 아래 코드는 오류가 난다.
public class FinalReferenceType { final MemberDto dto = new MemberDto(); public static void main(String[] args) { FinalReferenceType frt = new FinalReferenceType(); frt.checkDto(); } public void checkDto() { System.out.println(dto); dto - new MemberDto(); } }
단, dto 내부 변수가 final 이 아니라면 내부 변수들은 값 재할당이 가능하다. 해당 클래스가 final 이라고 해서 안에 있는 모든 인스턴스 / 클래스 변수가 final은 아님
#9 Primitive 타입과 Reference Type 차이점이 무엇인가요?
자바 Primitive Type -------------------------
정수형 : byte, short, int, long, char
소수형 : float, double
기타 : boolean
Primitive Type은 실제 데이터 값을 저장하는 타입으로, byte, short, int, long, char, float, double, boolean 총 8가지 타입이 존재하며, null 값을 담을 수 없으며, 제네릭 타입에 사용할 수 없습니다. 변수가 초기화되지 않았을 경우 기본 값으로 자동 초기화(Int : 0, boolean : false 등)
Reference Type은 객체의 주소를 저장하는 타입으로, Reference Type은 JVM의 Heap 메모리에 저장되고, 이 주소값을 Stack영역에 저장합니다. Primitive Type과 다르게 null 값을 담을 수 있고, 제네릭 타입에도 사용할 수 있습니다. 또한 값을 지정하지 않을 경우 null로 초기화됩니다.#10 StringBuffer와 StringBuilder 차이점이 무엇인가요?
StringBuffer와 StringBuilder는 둘 다 문자열을 처리하는 클래스로서, 문자열을 변경하거나 조작하는 작업을 수행하는 데 사용
동기화(Synchronization):
- StringBuffer: StringBuffer는 스레드 안전(thread-safe)하게 동작합니다. 여러 스레드에서 동시에 접근하더라도 안전하게 문자열을 수정할 수 있도록 동기화되어 있습니다. 이로 인해 스레드 간 동기화 오버헤드가 발생하며, 상호 배제 잠금(locks)을 사용합니다.
- 따라서 그만큼 성능 저하 존재!
- StringBuilder: StringBuilder는 StringBuffer와 달리 스레드 안전하지 않습니다. 따라서 단일 스레드 환경에서만 사용하는 것이 좋습니다. 스레드 간 동기화가 필요하지 않기 때문에, StringBuilder는 더 빠르게 작동할 수 있습니다.
멀티스레드 환경이라면 값 동기화 보장을 위해 StringBuffer를 사용하고, 단일스레드 환경이라면 StringBuilder를 사용하는 것이 좋다.
결론 )
StringBuffer는 스레드에 안전한 프로그램이 필요할 때나, 개발 중인 시스템의 부분이 스레드에 안전한지 모를 경우 사용하면 좋습니다.
StringBuilder는 스레드에 안전한지 여부가 전혀 관계 없는 프로그램을 개발할 때 사용하면 좋습니다.
'CS' 카테고리의 다른 글
CS 스터디 - 네트워크 Q&A (2) (0) 2023.09.20 CS 스터디 - 데이터베이스(2) (0) 2023.09.06 CS 스터디 - Java & Spring (0) 2023.08.15 CS 스터디 - 운영체제 Q&A(1) (0) 2023.08.10 CS 스터디 - 네트워크 Q&A (1) (0) 2023.08.03 - ArrayList