이전 두 기사에서는 인터뷰에서 가장 자주 묻는 몇 가지 중요한 질문에 대해 논의했습니다. 이제 나머지 질문을 살펴보고 살펴보겠습니다.
깊은 복사와 얕은 복사
원본의 정확한 사본은 복제본입니다. Java에서 이는 원래 객체와 유사한 구조를 가진 객체를 생성할 수 있음을 의미합니다. 이 방법은clone()
이 기능을 제공합니다. 얕은 복사는 가능한 한 적은 정보를 복사합니다. 기본적으로 Java에서의 복제는 얕습니다. Object class
복사하는 클래스의 구조에 대해 모릅니다. 복제 시 JVM은 다음을 수행합니다.
- 클래스에 기본 유형의 멤버만 있는 경우 객체의 완전히 새로운 복사본이 생성되고 해당 객체에 대한 참조가 반환됩니다.
- 클래스에 기본 유형의 멤버뿐만 아니라 다른 클래스 유형의 멤버도 포함되어 있는 경우 해당 클래스의 객체에 대한 참조가 복사됩니다. 따라서 두 개체 모두 동일한 참조를 갖게 됩니다.
- 기본 데이터를 별도로 복사할 필요가 없습니다.
- 원래 클래스의 모든 멤버 클래스는 복제를 지원해야 합니다.
super.clone()
각 클래스 멤버에 대해 메서드가 재정의될 때 호출되어야 합니다clone()
. - 클래스의 멤버 중 복제를 지원하지 않는 멤버가 있으면 복제 메서드에서 해당 클래스의 새 인스턴스를 생성하고 모든 속성이 포함된 각 멤버를 새 클래스 객체에 한 번에 하나씩 복사해야 합니다.
동기화란 무엇입니까? 객체 수준 잠금과 클래스 수준 잠금?
동기화는 멀티스레딩을 의미합니다. 동기화된 코드 블록은 한 번에 하나의 스레드에서만 실행될 수 있습니다. Java를 사용하면 여러 스레드를 동시에 처리할 수 있습니다. 이로 인해 두 개 이상의 스레드가 동일한 필드에 액세스하려고 할 수 있습니다. 동기화는 메모리 리소스가 잘못 사용될 때 발생하는 메모리 오류를 방지하는 데 도움이 됩니다. 메소드가 동기화됨으로 선언되면 스레드는 모니터를 보유합니다. 이때 다른 스레드가 동기화된 메서드에 액세스하려고 하면 해당 스레드는 차단되고 모니터가 해제될 때까지 기다립니다. Java의 동기화는 특수한 동기화 키워드를 사용하여 수행됩니다 . 이런 방식으로 클래스의 개별 블록이나 메서드를 표시할 수 있습니다. 동기화 키워드는 클래스 변수 또는 속성과 함께 사용할 수 없습니다. 개체 수준 잠금은 하나의 스레드만 해당 클래스 인스턴스에서 코드 블록을 실행할 수 있도록 비정적 메서드나 비정적 코드 블록을 동기화하려는 경우에 사용되는 메커니즘입니다. 클래스 인스턴스 스레드를 안전하게 만들려면 항상 이 작업을 수행해야 합니다. 클래스 수준 잠금은 여러 스레드가 클래스의 사용 가능한 모든 인스턴스에 대해 동기화된 블록에 들어가는 것을 방지합니다. 예를 들어, DemoClass 클래스의 인스턴스가 100개라면 주어진 시간에 변수 중 하나를 사용하여 1개의 스레드만 decoMethod()를 실행할 수 있습니다. 이는 정적 스레드 안전성을 보장하기 위해 항상 수행되어야 합니다. 여기에서 동기화에 대해 자세히 알아보세요.sleep()과 wait()의 차이점은 무엇입니까?
Sleep()
몇 초 동안 프로세스를 지연시키는 데 사용되는 방법입니다. 의 경우 스레드는 or 메소드 wait()
를 호출할 때까지 대기 상태에 있습니다 . 가장 큰 차이점은 잠금을 해제하지 않고 모니터 잠금을 해제한다는 것입니다 . 다중 스레드 애플리케이션에 사용되며 단순히 스레드 실행을 일시 중지하는 데 사용됩니다. 현재 스레드를 특정 시간 동안 "실행 불가능" 상태로 둡니다. 스레드는 이 메서드가 호출되기 전의 모니터 상태를 저장합니다. 다른 스레드가 을 호출하면 "잠든" 스레드가 깨어납니다. 이는 정적 메서드이므로 항상 현재 스레드(메서드를 실행하는 스레드 )에 영향을 미칩니다. 일반적인 실수는 또 다른 스레드가 어디에 있는지 호출하는 것입니다. 메소드를 호출한 현재 스레드가 스레드가 아닌 경우에도 마찬가지입니다. 와 마찬가지로 현재 스레드를 잠시 동안 "실행 불가능" 상태로 보냅니다. 그러나 약간의 차이가 있습니다. 스레드가 아닌 객체에서 호출됩니다. 우리는 이 객체를 "잠금 객체"라고 부릅니다. 를 호출하기 전에 현재 스레드는 "잠금 개체"와 동기화되어야 합니다. 그런 다음 이 잠금을 해제하고 이 잠금과 관련된 "대기 목록"에 스레드를 추가합니다. 나중에 다른 스레드가 동일한 잠금 개체와 동기화하고 . 이 메소드는 아직 대기 중인 원래 스레드를 "깨우게" 됩니다. 원칙적으로 /는 / 와 비교될 수 있습니다 . 활성 스레드만 휴면 스레드에 대한 직접 포인터가 필요하지 않으며 공유 잠금 개체만 알면 됩니다. 여기에서 자세한 차이점을 읽어보세요.notify()
notifyAll()
wait()
sleep()
Wait()
sleep()
Thread.sleep()
t.interrupt()
sleep()
sleep()
t.sleep()
t
sleep()
t
Object.wait()
sleep()
Wait()
lock.wait()
wait()
lock.notify()
wait()
notify()
sleep()
interrupt()
참조 변수에 null을 할당할 수 있습니까?
아니 당신은 할 수 없습니다. Java에서는 할당 연산자의 왼쪽이 변수여야 합니다. "This"는 항상 클래스의 현재 인스턴스를 제공하는 특수 키워드입니다. 그것은 단순한 변수가 아닙니다. 마찬가지로, "super" 키워드나 기타 유사한 키워드를 사용하여 변수에 null을 할당할 수 없습니다.&&와 &의 차이점은 무엇인가요?
&
- 비트별 및 &&
- 논리적으로.
&
작업의 양면을 평가합니다.&&
작업의 왼쪽을 평가합니다. true인 경우 오른쪽을 계속 평가합니다.
equals() 및 hachCode() 메서드를 재정의하는 방법은 무엇입니까?
hashCode()
및 메소드는 Java 객체의 상위 클래스인 equals()
클래스에 정의됩니다 . Object
이러한 이유로 모든 Java 객체는 메소드에 대한 기본 구현을 상속합니다. 이 메소드는 hashCode()
주어진 객체에 대한 고유한 정수를 얻는 데 사용됩니다. 이 정수는 예를 들어 객체를 저장해야 할 때 객체의 위치를 결정하는 데 사용됩니다 HashTable
. 기본적으로 객체가 저장된 메모리 위치의 주소 표현을 hashCode()
반환합니다 . 이름에서 알 수 있듯이 integer
이 메서드는 두 개체가 동일한지 여부를 간단히 테스트하는 데 사용됩니다. equls()
기본 구현에서는 객체 참조를 검사하여 동일한지 확인합니다. 다음은 이러한 메서드를 다시 로드하기 위한 중요한 지침입니다.
hashCode()
및 를 생성할 때 항상 동일한 객체 속성을 사용하십시오equals()
.- 대칭. 저것들. 일부 객체에 대해 true를 반환
x
하면 true를 반환해야y
x.equals(y)
합니다y.equals(x)
. - 반사성. 모든 객체는
x
x.equals(x)
true를 반환해야 합니다. - 일관성. 모든 객체에 대해 비교에 사용된 정보가 변경되지 않으면 동일한 것을 반환합니다
x
.y
x.equals(y)
- 전이성. 모든 객체 및 에 대해
x
truey
를 반환하고z
true 를 반환하면 true를 반환해야 합니다.x.equals(y)
y.equals(z)
x.equals(z)
- 애플리케이션 실행 중 동일한 객체에 대해 메소드가 호출될 때마다 사용된 정보가 변경되지 않는 한 동일한 번호를 반환해야 합니다.
hashCode
서로 다른 애플리케이션 인스턴스에서 동일한 개체에 대해 서로 다른 값을 반환할 수 있습니다. - 에 따르면 두 객체가 동일하면 동일한 값을 반환해야 합니다
equals
.hashCode
- 반대 요구 사항은 선택 사항입니다. 두 개의 서로 다른 객체가 동일한 hashCode를 반환할 수 있습니다. 그러나 성능을 향상시키려면 서로 다른 개체가 서로 다른 코드를 반환하도록 하는 것이 좋습니다.
접근 수정자에 대해 알려주세요
Java 클래스, 필드, 생성자 및 메소드는 네 가지 액세스 한정자 중 하나를 가질 수 있습니다. private 메소드 또는 변수가 private 으로 표시된 경우 동일한 클래스 내의 코드만 변수에 액세스하거나 메소드를 호출할 수 있습니다. 서브클래스 내부의 코드는 변수나 메서드에 액세스할 수 없으며 다른 클래스에서도 액세스할 수 없습니다. 개인 액세스 수정자는 생성자, 메서드 및 변수에 가장 자주 사용됩니다. default 수정자가 전혀 지정되지 않은 경우 기본 액세스 수정자가 선언됩니다 . 이 수정자는 클래스 자체 내부의 코드, 동일한 패키지의 클래스 내부 코드를 통해 특정 클래스의 필드, 생성자 및 메서드에 대한 액세스를 얻을 수 있음을 의미합니다. 서브클래스가 슈퍼클래스 와 동일한 패키지에 있지 않는 한, 서브클래스가 default 로 선언된 경우 서브클래스는 슈퍼클래스의 메서드 및 멤버 변수에 액세스할 수 없습니다 . protected protected 한정자는 서브클래스가 슈퍼클래스의 protected 메소드 및 변수에 액세스할 수도 있다는 점을 제외하면 default 와 동일하게 작동합니다 . 이 설명은 하위 클래스가 상위 클래스와 동일한 패키지에 없는 경우에도 적용됩니다. public public 액세스 한정자는 해당 코드의 위치에 관계없이 모든 코드가 클래스, 해당 변수, 생성자 또는 메서드에 액세스할 수 있음을 의미합니다.가비지 수집기란 무엇입니까? 그 사람에게 전화해도 될까요?
가비지 수집은 Java 및 NET.Framework의 언어와 같은 많은 최신 프로그래밍 언어의 자동 메모리 관리 기능입니다. 가비지 컬렉션을 사용하는 언어는 JVM과 같은 가상 머신에서 가비지 컬렉션을 해석하는 경우가 많습니다. 가비지 수집에는 두 가지 목적이 있습니다. 사용되지 않은 메모리를 해제해야 하고, 프로그램이 계속 사용하는 경우 메모리를 해제해서는 안 됩니다. 가비지 수집을 수동으로 실행할 수 있나요? 아니요,System.gc()
가능한 한 많은 액세스 권한을 제공합니다. 가장 좋은 방법은 메서드를 호출하는 것입니다 System.gc()
. 이 메서드는 실행해야 하는 가비지 수집기에 대한 힌트를 제공합니다. 가비지 수집기는 비결정적이므로 즉시 실행할 수 있는 방법이 없습니다. 또한 설명서에 따르면 OutOfMemoryError
가상 머신이 전체 가비지 수집 후 메모리를 확보하지 못한 경우 전달되지 않습니다. 여기에서 가비지 수집기에 대해 자세히 알아보세요.
네이티브 키워드는 무엇을 의미하나요? 자세히 설명해주세요
기본 키워드는 메소드가 Java 파일이 아닌 프로그래밍 언어로 구현되었음을 나타내는 데 사용됩니다. 과거에는 기본 방법이 사용되었습니다. 현재 버전의 Java에서는 이 작업이 덜 자주 필요합니다. 현재 다음과 같은 경우 기본 메서드가 필요합니다.- 다른 언어로 작성된 Java에서 라이브러리를 호출해야 합니다.
- 다른 언어(일반적으로 C)를 통해서만 액세스할 수 있는 시스템 또는 하드웨어 리소스에 액세스해야 합니다. 실제로 실제 컴퓨터와 상호 작용하는 많은 시스템 기능(예: 디스크 또는 네트워크 데이터)은 기본 메서드로만 호출할 수 있습니다.
- JNI/JNA는 특히 복잡한 작업을 수행하려는 경우 JVM을 불안정하게 만들 수 있습니다. 기본 메소드가 잘못된 경우 JVM이 충돌할 가능성이 있습니다. 또한 네이티브 메서드가 여러 스레드에서 호출되면 나쁜 일이 발생할 수 있습니다. 등등.
- 네이티브 코드 로 프로그램을 디버깅하는 것이 더 어렵습니다 .
- 네이티브 코드에는 별도의 프레임워크 구성이 필요하므로 다른 플랫폼으로 포팅할 때 문제가 발생할 수 있습니다.
직렬화란 무엇입니까?
컴퓨터 과학에서 데이터 저장 및 전송과 관련하여 직렬화는 데이터 구조 또는 객체의 상태를 저장하고 나중에 다른 컴퓨팅 환경에서 검색할 수 있는 형식으로 변환하는 프로세스입니다. 일련의 비트를 수신한 후 직렬화 형식에 따라 다시 계산되며 원래 개체의 의미상 동일한 복제본을 만드는 데 사용할 수 있습니다. Java는 객체가 인터페이스를 구현하도록 요구하는 자동 직렬화를 제공합니다java.io.Serializable
. 인터페이스 구현은 클래스를 "직렬화 가능"으로 표시합니다. java.io.Serialized 인터페이스에는 직렬화 메서드가 없지만 직렬화 가능 클래스는 직렬화/역직렬화 프로세스의 일부로 호출될 메서드를 선택적으로 정의할 수 있습니다. 클래스를 변경할 때 직렬화와 호환되는 클래스와 호환되지 않는 클래스를 고려해야 합니다. 여기에서 전체 지침을 읽을 수 있습니다. 가장 중요한 사항을 알려 드리겠습니다. 호환되지 않는 변경 사항:
- 필드를 삭제합니다.
- 계층 구조에서 클래스를 위나 아래로 이동합니다.
- 비정적 필드를 정적으로 변경하거나 비일시적 필드를 일시적으로 변경합니다.
- 선언된 기본 데이터 유형 변경
- 기본적으로 더 이상 필드를 쓰거나 읽지 않도록 메서드를 변경합니다
WriteObject
.ReadObject
- 클래스를 클래스
Serializable
로 변경하거나Externalizable
그 반대로 변경합니다. - 열거형 클래스를 비열거형 으로 변경하거나 그 반대로 변경합니다.
- 제거
Serializable
또는Externalizable
; - 클래스에 메서드를
writeReplace
추가 합니다 .readResolve
- 필드 추가
- 수업 추가/제거
- 메소드 추가
WriteObject/ReadObject
[메소드defaultReadObject
또는defaultWriteObject
처음에 호출되어야 함]; - 제거 방법
WriteObject/ReadObject
; - 덧셈
java.io.Serializable
; - 현장 접근 변경
- 정적 필드를 비정적으로 또는 일시적에서 비일시적 으로 변경 합니다 .
GO TO FULL VERSION