JavaRush /Java Blog /Random-KO /번역: 스레드별 상위 50개 인터뷰 질문. 2 부.
KapChook
레벨 19
Volga

번역: 스레드별 상위 50개 인터뷰 질문. 2 부.

Random-KO 그룹에 게시되었습니다
신입생, 숙련된 프로그래머를 위한 상위 50가지 Java 스레드 인터뷰 질문 답변 원본 기사 번역의 두 번째 부분입니다 . 첫 번째 부분.
  1. 스레드가 잠금을 보유하고 있는지 확인하는 방법은 무엇입니까?

  2. 전화 인터뷰에서 이 질문을 접하기 전까지는 스레드가 현재 잠금을 유지하고 있는지 여부를 확인할 수 있다는 것을 전혀 몰랐습니다. java.lang.Thread에는holdLock() 메소드가 있으며, 현재 스레드가 특정 객체에 대한 모니터를 보유하고 있는 경우에만 true를 반환합니다.
  3. 스레드 덤프를 얻는 방법은 무엇입니까?

  4. 스레드 덤프를 사용하면 스레드가 현재 수행 중인 작업을 확인할 수 있습니다. 운영 체제에 따라 스레드 덤프를 얻는 방법에는 여러 가지가 있습니다. Windows에서는 ctrl + Break 조합을 사용할 수 있고, Linux에서는 kill -3 명령을 사용할 수 있습니다. jstack 유틸리티를 사용할 수도 있습니다. 이는 프로세스 ID에서 작동하며 다른 jps 유틸리티를 사용하여 확인할 수 있습니다.
  5. 스레드의 스택 크기를 제어하는 ​​데 사용되는 JVM 매개변수는 무엇입니까?

  6. 이는 Java에서 스레드 스택의 크기를 제어하는 ​​데 사용되는 간단한 -Xss 매개변수 중 하나입니다.
  7. 동기화와 ReentrantLock의 차이점은 무엇입니까?

  8. 상호 배제를 달성하는 유일한 방법은 동기화된 키워드를 통하는 것이었지만 메서드나 코드 블록 이상으로 잠금을 확장할 수 없는 등 몇 가지 단점이 있습니다. Java 5는 Lock 인터페이스를 통해 보다 세부적인 제어를 제공하여 이 문제를 해결합니다. ReentrantLock은 암시적 모니터와 동일한 기본 동작 및 의미 체계를 갖춘 잠금을 제공하는 일반적인 잠금 구현으로, 동기화된 메서드를 사용하여 달성되지만 향상된 기능을 제공합니다.
  9. 3개의 스레드 T1, T2 및 T3이 주어지면 어떻게 될까요? 시퀀스 T1, T2, T3을 구현하는 방법은 무엇입니까?

  10. 일관성은 여러 가지 방법으로 달성할 수 있지만 다른 스레드가 실행을 마쳤을 때 간단히 Join() 메서드를 사용하여 스레드를 시작할 수 있습니다. 주어진 시퀀스를 구현하려면 마지막 스레드를 먼저 시작한 다음 Join() 메서드를 역순으로 호출해야 합니다. 즉, T3는 T2.join을 호출하고 T2는 T1.join을 호출하므로 T1이 먼저 완료되고 T3이 마지막에 완료됩니다. .
  11. 항복 방법은 무엇을 합니까?

  12. 양보 방법은 다른 스레드가 실행될 수 있도록 스레드에 CPU를 포기하도록 요청하는 한 가지 방법입니다. 이는 정적 방법이며 현재 스레드가 프로세서를 포기하도록 보장할 뿐, 어느 스레드 실행으로 이동할지는 결정하지 않습니다.
  13. ConcurrentHashMap의 동시성 수준은 무엇입니까?

  14. ConcurrentHashMap은 실제 맵을 섹션으로 분할하여 확장성과 스레드 안전성을 달성합니다. 이러한 분리는 병렬성 수준을 사용하여 달성됩니다. 이는 ConcurrentHashMap 생성자의 선택적 매개변수이며 기본값은 16입니다.
  15. 세마포어란 무엇입니까?

  16. 세마포어는 새로운 유형의 동기화 장치입니다. 이것은 카운터가 있는 세마포어입니다. 개념적으로 세마포어는 일련의 권한을 제어합니다. 각 acquire()는 필요한 경우 권한을 사용할 수 있기 전에 차단한 다음 이를 획득합니다. 각 release()는 권한을 추가하여 잠재적으로 차단 획득자를 해제합니다. 그러나 이는 실제 권한 개체를 사용하지 않습니다. 세마포어는 단순히 사용 가능한 개수를 저장하고 그에 따라 작동합니다. 세마포어는 풀링된 데이터베이스에 대한 연결과 같이 제한된 수량으로 사용 가능한 값비싼 리소스를 보호하는 데 사용됩니다.
  17. 스레드 풀 대기열이 이미 가득 차서 작업을 제출하면 어떻게 되나요?

  18. 스레드 풀 대기열이 가득 차면 제출된 작업이 "거부"됩니다. ThreadPoolExecutor의 submit() 메소드는 RejectedExecutionException을 발생시킨 후 RejectedExecutionHandler가 호출됩니다.
  19. 스레드 풀에서 submit()과 excute() 메소드의 차이점은 무엇입니까?

  20. 두 방법 모두 스레드 풀에 작업을 제출하는 방법이지만 약간의 차이가 있습니다. Execute(Runnable 명령)는 Executor 인터페이스에 정의되어 있으며 앞으로 주어진 작업을 실행하지만 더 중요한 것은 아무것도 반환하지 않는다는 것입니다. 반면 submit()은 오버로드된 메서드로, Runnable 및 Callable 작업을 허용하고 실행을 취소하거나 계산 결과를 기다리는 데 사용할 수 있는 Future 객체를 반환할 수 있습니다. 이 메소드는 Executor 인터페이스를 상속하는 ExecutorService 인터페이스에 정의되어 있으며 ThreadPoolExecutor 또는 ScheduledThreadPoolExecutor와 같은 각 스레드 풀 클래스는 이러한 메소드를 상속합니다.
  21. 차단 방법이란 무엇입니까?

  22. 차단 메서드는 작업이 완료될 때까지 차단하는 메서드입니다. 예를 들어 ServerSocket accept() 메서드는 클라이언트가 연결되기를 기다리는 동안 차단합니다. 여기서 차단이란 작업이 완료될 때까지 제어가 호출 메서드로 반환되지 않음을 의미합니다. 반면에 작업이 완료되기 전에 완료되는 비동기식 또는 비차단 메서드가 있습니다.
  23. 스윙 스레드는 안전한가요?

  24. 간단히 말해서, Swing은 스레드로부터 안전하지 않습니다. 하지만 면접관이 묻지 않더라도 그것이 의미하는 바를 설명해야 합니다. Swing이 스레드로부터 안전하지 않다고 말할 때 일반적으로 Swing은 여러 스레드에 의해 수정될 수 없는 구성요소라는 사실을 참조합니다. GUI 구성요소에 대한 모든 변경은 AWT 스레드에서 이루어져야 하며 Swing은 그러한 변경을 예약하기 위한 동기식 및 비동기식 방법을 제공합니다.
  25. InvokeAndWait와 InvokeLater의 차이점은 무엇입니까?

  26. 이는 개발자가 이벤트 관리자 스레드가 아닌 스레드에서 GUI 구성 요소를 업데이트할 수 있도록 하는 두 가지 Swing API 방법입니다. InvokeAndWait()는 진행률 표시줄과 같은 GUI 구성 요소를 동기적으로 업데이트합니다. 진행률이 이루어질 때마다 변경 사항을 반영하도록 표시줄을 업데이트해야 합니다. 다른 스레드에서 진행 상황을 추적하는 경우 해당 구성 요소를 업데이트하기 위한 이벤트 디스패처 스레드를 할당하기 위해 InvokeAndWait()를 호출해야 합니다. 그리고 informaLater()는 구성 요소를 업데이트하기 위한 비동기 호출입니다.
  27. 스레드로부터 안전한 Swing API 메소드는 무엇입니까?

  28. 이 질문은 다시 Swing과 스레드 안전성에 관한 것입니다. Swing 구성 요소는 스레드로부터 안전하지 않지만 여러 스레드에서 안전하게 호출할 수 있는 메서드가 있습니다. repaint() 및 revalidate()가 스레드로부터 안전하다는 것을 알고 있지만 JTextComponent의 setText() 및 JTextArea의 insert() 및 Append() 메소드와 같은 다양한 Swing 구성요소에 다른 메소드가 있습니다.
  29. 불변 객체를 만드는 방법은 무엇입니까?

  30. 이 질문은 멀티스레딩 및 동시성과 관련이 없는 것처럼 보일 수 있지만 실제로는 그렇습니다. 불변성은 이미 복잡한 병렬 코드를 단순화하는 데 도움이 됩니다. 불변 객체는 동기화 없이 전파될 수 있기 때문에 개발자에게 매우 비용이 많이 듭니다. 불행하게도 Java에는 객체를 불변으로 만드는 @Immutable 주석이 없습니다. 개발자가 열심히 노력해야 하기 때문입니다. 불변 객체를 생성하려면 생성자 초기화, 설정자 없음, 참조 누출 없음, 변경 가능 객체의 별도 복사본 저장 등 기본 사항을 따라야 합니다.
  31. ReadWriteLock이란 무엇입니까?

  32. 일반적으로 ReadWriteLock은 병렬 애플리케이션의 성능을 향상시키기 위한 잠금 구문 분석 기술의 결과입니다. 이는 Java 5에 추가된 인터페이스입니다. 한 쌍의 관련 잠금(읽기 작업용, 쓰기 작업용)에서 작동합니다. 판독기 잠금은 작성자가 없을 때까지 여러 읽기 스레드에 의해 동시에 유지될 수 있습니다. 쓰기 잠금은 독점적입니다. 원하는 경우 규칙 세트로 인터페이스를 구현하거나 최대 65535개의 재귀 쓰기 잠금과 65535개의 읽기 잠금을 지원하는 ReentrantReadWriteLock을 사용할 수 있습니다.
  33. 비지 스핀이란 무엇입니까?

  34. Busy Spin은 프로그래머가 특정 조건에서 스레드를 강제로 대기시키는 데 사용하는 기술입니다. 프로세서 제어권을 양도하는 전통적인 방법인 wait(), sleep() 또는 Yield()와 달리 이 방법은 프로세서를 양도하지 않고 단순히 빈 루프를 실행합니다. 왜 이런 일을 하겠습니까? 프로세서 캐시를 저장합니다. 멀티 코어 시스템에서는 일시 중단된 스레드가 다른 코어에서 계속 실행될 수 있으며 이는 캐시 재구축을 의미합니다. 비용이 많이 드는 재구축을 피하기 위해 프로그래머는 바쁜 스핀을 사용하여 대기 시간을 줄이는 것을 선호합니다.
  35. 휘발성 변수와 원자 변수의 차이점은 무엇입니까?

  36. 이것은 매우 흥미로운 질문입니다. 처음에는 휘발성 및 원자 변수가 매우 유사해 보이지만 여전히 다릅니다. Volatile 변수는 후속 쓰기 전에 쓰기가 발생한다는 사전 발생 보장을 제공하지만 원자성을 보장하지는 않습니다. 예를 들어, count++ 연산은 단순히 count가 휘발성으로 선언되었기 때문에 원자성이 되지 않습니다. 반면에 AtomicInteger 클래스는 이러한 복잡한 작업을 원자적으로 수행하는 원자 메서드를 제공합니다. 예를 들어 getAndIncrement()는 증가 연산자를 원자적으로 대체하므로 현재 값을 원자적으로 1씩 증가시키는 데 사용할 수 있습니다. 다른 데이터 유형에 대한 원자 버전도 있습니다.
  37. 스레드가 동기화된 블록에서 예외를 발생시키면 어떻게 됩니까?

  38. 이것은 일반 Java 프로그래머를 위한 또 다른 트릭 질문입니다. 일반적으로 실행을 완료하거나 갑자기 예외를 발생시켜 동기화된 블록을 종료하는 방법에 관계없이 스레드는 동기화된 블록에 들어갈 때 획득한 잠금을 해제합니다. 이것이 일반적으로 finally 블록에서 잠금을 해제하여 잠금을 해제할 때 특별한 주의가 필요한 인터페이스보다 동기화된 잠금 블록을 선호하는 이유 중 하나입니다.
  39. 싱글톤의 이중 확인 잠금이란 무엇입니까?

  40. 이것은 가장 인기 있는 면접 질문 중 하나이지만, 인기에도 불구하고 후보자가 이에 답할 확률은 기껏해야 50%입니다. 절반의 시간은 코드 작성에 실패하고 나머지 절반은 Java 1.5에서 코드가 어떻게 손상되고 수정되었는지 설명하는 데 실패합니다. 이는 싱글톤 인스턴스가 처음 인스턴스화될 때만 차단하여 성능을 최적화하려고 시도하는 스레드로부터 안전한 싱글톤을 생성하는 오래된 방법이지만 JDK 1.4에서 손상되었다는 사실과 복잡성으로 인해 개인적으로 마음에 들지 않습니다. 그것. 그래도 이 접근 방식을 선호하지 않더라도 인터뷰 관점에서 알아두면 유용합니다.
  41. 스레드로부터 안전한 싱글톤을 만드는 방법은 무엇입니까?

  42. 이 질문은 이전 질문을 보완합니다. 이중 확인 잠금이 마음에 들지 않는다고 말하면 면접관은 스레드로부터 안전한 싱글톤을 만드는 다른 방법에 대해 질문해야 합니다. 그리고 클래스 로딩 및 정적 변수 초기화 기능을 활용하여 싱글톤을 인스턴스화하거나 강력한 열거형 유형을 활용할 수 있습니다.
  43. 병렬 프로그래밍에서 따르는 세 가지 관습을 나열해 보세요.

  44. 성능, 디버깅 및 지원에 도움이 되는 병렬 코드를 작성할 때 따라야 할 특정 규칙이 있다고 믿기 때문에 이것은 제가 가장 좋아하는 질문입니다. 다음은 모든 Java 프로그래머가 따라야 한다고 생각하는 3가지 최고의 규칙입니다.
    • 항상 스레드에 의미 있는 이름을 지정하세요.
    • 병렬 코드에서 버그를 찾거나 예외를 추적하는 것은 다소 어려운 작업입니다. OrderProcessor, QuoteProcessor 또는 TradeProcessor는 Thread-1보다 훨씬 낫습니다. 스레드-2 및 스레드-3. 이름은 스레드가 수행하는 작업을 반영해야 합니다. 모든 주요 프레임워크와 심지어 JDK도 이 규칙을 따릅니다.
    • 차단 방지 또는 동기화 범위 줄이기
    • 차단에는 비용이 많이 들고 컨텍스트 전환에는 훨씬 더 많은 비용이 듭니다. 가능한 한 동기화 및 차단을 피하려고 하면 중요한 섹션이 필요한 최소한으로 줄어듭니다. 이것이 내가 시간 제한 방법보다 시간 제한 방법을 선호하는 이유입니다. 차단 범위를 완벽하게 제어할 수 있기 때문입니다.
    • 동기화 장치와 대기 및 알림 사이에서 동기화 장치를 선택하세요
    • 첫째, CountDownLatch, Semaphore, CyclicBarrier 또는 Exchanger와 같은 동기화 장치는 코딩을 단순화합니다. 대기 및 알림을 사용하여 복잡한 제어 흐름을 구현하는 것은 매우 어렵습니다. 둘째, 이러한 클래스는 업계 최고의 전문가가 작성하고 유지 관리하며 향후 JDK 릴리스에서는 최적화되거나 더 나은 코드로 대체될 가능성이 높습니다. 고급 동기화 유틸리티를 사용하면 이러한 모든 이점을 자동으로 얻을 수 있습니다.
    • 동시수집과 동기화수집 중 동시수집 선택
    • 이것은 따르기 쉽고 혜택을 얻을 수 있는 또 다른 간단한 규칙입니다. 동시 컬렉션은 동기화된 컬렉션보다 확장성이 뛰어나므로 병렬 코드를 작성할 때 사용하는 것이 좋습니다. 따라서 다음에 지도가 필요할 때는 Hashtable을 생각하기 전에 ConcurrentHashMap을 생각해 보세요.
  45. 스레드를 강제로 시작하는 방법은 무엇입니까?

  46. 가비지 수집을 강제로 실행하는 방법에 대한 질문입니다. 간단히 말해서, 물론 System.gc()를 사용하여 쿼리를 만들 수는 있지만 아무 것도 보장하지는 않습니다. Java에서 스레드를 강제로 시작하는 방법은 전혀 없습니다. 이는 스레드 스케줄러에 의해 제어되며 Java는 이를 제어할 API를 제공하지 않습니다. Java의 이 부분은 여전히 ​​임의적입니다.
  47. Fork/Join 프레임워크란 무엇입니까?

  48. JDK 7에 도입된 Fork/Join 프레임워크는 개발자가 최신 서버의 다중 프로세서를 활용할 수 있게 해주는 강력한 유틸리티입니다. 이는 작은 입자로 반복적으로 분해될 수 있는 작업을 위해 설계되었습니다. 목표는 사용 가능한 모든 컴퓨팅 성능을 사용하여 애플리케이션의 성능을 높이는 것입니다. 이 프레임워크의 중요한 장점 중 하나는 작업 도용 알고리즘(작업 - 작업 및 도용 - 도용)을 사용한다는 것입니다. 작업이 부족한 작업자 스레드는 여전히 사용 중인 다른 스레드에서 작업을 훔칠 수 있습니다.
  49. wait() 호출과 sleep() 호출의 차이점은 무엇입니까?

  50. 대기 및 절전 모드는 모두 Java 애플리케이션에서 일종의 일시 중지를 나타내지만 서로 다른 요구 사항을 충족하는 장치입니다. 대기는 내부 스레드 통신에 사용되며, 대기 조건이 true이면 잠기고, 다른 스레드의 작업으로 인해 대기 조건이 false가 되면 알림을 기다립니다. 반면에 sleep() 메서드는 단순히 프로세서를 포기하거나 지정된 시간 동안 현재 스레드의 실행을 중지합니다. sleep()을 호출해도 현재 스레드가 보유한 잠금이 해제되지 않습니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION