CodeGym /Java Blog /무작위의 /Java 개발자 직위에 대한 취업 면접의 질문과 답변을 살펴보세요. 7부
John Squirrels
레벨 41
San Francisco

Java 개발자 직위에 대한 취업 면접의 질문과 답변을 살펴보세요. 7부

무작위의 그룹에 게시되었습니다
안녕 모두들! 프로그래밍에는 함정이 가득합니다. 그리고 당신을 비틀거리게 하고 발가락을 뭉개게 만들지 않을 단 하나의 주제도 거의 없습니다. 초보자에게는 특히 그렇습니다. 발가락을 보호하는 유일한 방법은 배우는 것입니다. 특히, 가장 근본적인 주제에 대해 깊이 파고들 필요가 있습니다. 오늘은 Java 개발자 인터뷰 중 가장 인기 있는 질문에 대한 검토를 계속하겠습니다. 이러한 인터뷰 질문은 기본적인 주제를 다루는 데 탁월한 역할을 합니다. 목록에는 일반적인 문제에 다르게 접근할 수 있는 표준적이지 않은 질문도 포함되어 있습니다. Java 개발자 직위에 대한 취업 면접의 질문과 답변을 살펴보세요.  파트 7 - 1

62. 스트링 풀이란 무엇이며, 왜 필요한가요?

Java 프로그램에서 사용할 수 있는 메모리의 일부를 힙(나중에 설명)이라고 하며 힙의 일부를 문자열 풀이 라고 합니다 . 문자열 값을 저장하기 위한 것입니다. 즉, 예를 들어 다음과 같이 큰따옴표를 사용하여 문자열을 생성할 때:
String str = "Hello world";
JVM은 문자열 풀에 이미 지정된 값이 있는지 확인합니다. 그렇다면 str 변수에는 풀의 해당 값에 대한 참조가 할당됩니다. 그렇지 않은 경우 풀에 새 값이 생성되고 해당 값에 대한 참조가 str 변수에 할당됩니다. 예를 생각해 봅시다:
String firstStr = "Hello world";
String secondStr = "Hello world";
System.out.println(firstStr == secondStr);
true가 화면에 표시됩니다. ==는 참조를 비교하며 이 두 변수는 문자열 풀에서 동일한 값을 가리킨다는 점을 기억하세요 . 이는 메모리에 동일한 String 개체가 많이 생성되는 것을 방지하는 데 도움이 됩니다. 기억하시겠지만 String 은 불변 클래스이므로 동일한 값에 대한 여러 참조를 갖는 데 아무런 문제가 없기 때문에 이를 수행할 수 있습니다. 이제 한 곳의 값을 변경하면 여러 다른 참조도 변경되는 상황이 발생하는 것은 불가능합니다. 그래도 new를 사용하여 문자열을 생성하면 다음과 같습니다 .
String str = new String("Hello world");
그런 다음 별도의 개체가 메모리에 생성되고 지정된 문자열 값을 저장합니다(해당 값이 이미 문자열 풀에 있는지는 중요하지 않습니다). 이 주장을 확인하려면 다음을 고려하십시오.
String firstStr = new String("Hello world");
String secondStr = "Hello world";
String thirdStr = new String("Hello world");
System.out.println(firstStr == secondStr);
System.out.println(firstStr == thirdStr);
false 를 나타내는 두 줄이 표시됩니다 . 이는 세 개의 별도 문자열이 있음을 의미합니다. 기본적으로 이것이 바로 큰따옴표를 사용하여 문자열을 생성해야 하는 이유입니다. 즉, new 키워드 를 사용하여 개체를 생성할 때에도 문자열 풀에 값을 추가(또는 참조 가져오기)하는 것이 가능합니다 . 이를 위해 String 클래스의 intern() 메소드를 사용합니다. 이 방법을 사용하면 문자열 풀에 값을 생성하거나 값이 이미 있는 경우 해당 값에 대한 참조를 얻을 수 있습니다. 예는 다음과 같습니다.
String firstStr = new String("Hello world").intern();
String secondStr = "Hello world";
String thirdStr = new String("Hello world").intern();
System.out.println(firstStr == secondStr);
System.out.println(firstStr == thirdStr);
System.out.println(secondStr == thirdStr);
이 코드는 콘솔에 true를 세 번 출력하며, 이는 세 변수 모두 메모리에서 동일한 문자열을 참조함을 알려줍니다.

63. 스트링 풀에는 어떤 GoF 디자인 패턴이 사용됩니까?

스트링 풀에서 GoF 디자인 패턴은 플라이급 패턴 입니다 . 여기에서 또 다른 디자인 패턴을 발견했다면 댓글로 공유해 주세요. 여기서는 플라이웨이트 디자인 패턴에 대해 이야기하겠습니다. 프로그램의 다른 위치에서 고유한 인스턴스로 자신을 나타내는 개체가 실제로 고유하지 않은 구조적 디자인 패턴입니다. 플라이웨이트는 각 개체에 동일한 데이터를 저장하는 대신 개체의 공유 상태를 저장하여 메모리를 절약합니다. 요점을 이해하려면 이 기본 예를 고려하십시오. Employee 인터페이스 가 있다고 가정해 보겠습니다 .
public interface Employee {
   void work();
}
그리고 Lawyer 클래스 와 같은 몇 가지 구현이 있습니다 .
public class Lawyer implements Employee {

   public Lawyer() {
       System.out.println("A lawyer was hired.");
   }

   @Override
   public void work() {
       System.out.println("Settling legal issues...");
   }
}
그리고 회계사 수업:
public class Accountant implements Employee {

   public Accountant() {
       System.out.println("An accountant was hired.");
   }

   @Override
   public void work() {
       System.out.println("Keeping accounting records...");
   }
}
메소드는 완전히 임의적입니다. 이 예에서는 메소드가 실행되고 있는지 확인하기만 하면 됩니다. 생성자에 대해서도 마찬가지입니다. 콘솔 출력은 새 개체가 생성된 시기를 알려줍니다. 또한 요청한 직원을 돌려보내는 업무를 담당하는 인사 부서도 있습니다. 해당 직원이 아직 직원이 아닌 경우 고용되고 HR 부서는 새 직원을 반환합니다.
public class HumanResourcesDepartment {
   private Map<String, Employee> currentEmployees = new HashMap<>();

   public Employee getEmployee(String type) throws Exception {
       Employee result;
       if (currentEmployees.containsKey(type)) {
           result = currentEmployees.get(type);
       } else {
           switch (type) {
               case "Accountant":
                   result = new Accountant();
                   currentEmployees.put(type, result);
                   break;
               case "Lawyer":
                   result = new Lawyer();
                   currentEmployees.put(type, result);
                   break;
               default:
                   throw new Exception("This employee is not on the staff!");
           }
       }
       return result;
   }
}
따라서 논리는 간단합니다. 원하는 객체가 존재하면 이를 반환하고, 그렇지 않으면 반환합니다. 그렇지 않은 경우 생성하여 저장소(캐시와 같은 것)에 넣은 다음 반환합니다. 이제 모든 것이 어떻게 작동하는지 살펴보겠습니다.
public static void main(String[] args) throws Exception {
   HumanResourcesDepartment humanResourcesDepartment = new HumanResourcesDepartment();
   Employee empl1 = humanResourcesDepartment.getEmployee("Lawyer");
   empl1.work();
   Employee empl2 = humanResourcesDepartment.getEmployee("Accountant");
   empl2.work();
   Employee empl3 = humanResourcesDepartment.getEmployee("Lawyer");
   empl1.work();
   Employee empl4 = humanResourcesDepartment.getEmployee("Accountant");
   empl2.work();
   Employee empl5 = humanResourcesDepartment.getEmployee("Lawyer");
   empl1.work();
   Employee empl6 = humanResourcesDepartment.getEmployee("Accountant");
   empl2.work();
   Employee empl7 = humanResourcesDepartment.getEmployee("Lawyer");
   empl1.work();
   Employee empl8 = humanResourcesDepartment.getEmployee("Accountant");
   empl2.work();
   Employee empl9 = humanResourcesDepartment.getEmployee("Lawyer");
   empl1.work();
   Employee empl10 = humanResourcesDepartment.getEmployee("Accountant");
   empl2.work();
}
콘솔에 표시되는 내용은 다음과 같습니다.
변호사가 고용되었습니다. 법적 문제 해결... 회계사가 고용되었습니다. 회계 기록 유지... 법적 문제 해결... 회계 기록 유지... 법적 문제 해결... 회계 기록 유지... 법적 문제 해결... 회계 기록 유지... 법적 문제 해결... 회계 유지 기록…
보시다시피 우리는 두 개의 개체만 만들고 여러 번 재사용했습니다. 이 예는 매우 간단하지만 이 디자인 패턴이 리소스를 어떻게 절약할 수 있는지 보여줍니다. 이미 눈치채셨겠지만, 이 패턴의 논리는 보험 풀의 논리와 매우 유사합니다. Java 개발자 직위에 대한 취업 면접의 질문과 답변을 살펴보세요.  파트 7 - 2

64. 문자열을 여러 부분으로 나누는 방법은 무엇입니까? 관련 코드의 예를 들어보세요.

분명히 이 질문은 분할 방법에 관한 것입니다. String 클래스 에는 이 메서드에 대한 두 가지 변형이 있습니다.
String split(String regex);
그리고
String split(String regex);
regex 매개변수는 구분 기호입니다. 예를 들어 문자열을 문자열 배열로 분할하는 데 사용되는 일부 정규식입니다 .
String str = "Hello, world it's Amigo!";
String[] arr = str.split("\\s");
for (String s : arr) {
  System.out.println(s);
}
콘솔에 다음이 표시됩니다.
안녕하세요, 세상 아미고입니다!
따라서 문자열은 공백을 구분 기호로 사용하여 문자열 배열로 분할되었습니다(정규 표현식 "\\s" 대신 일반 문자열 표현식 " " 을 사용할 수도 있음 ). 두 번째 오버로드된 변형에는 추가 제한 매개변수가 있습니다. Limit은 결과 배열의 최대 허용 크기입니다. 즉, 문자열이 허용되는 최대 하위 문자열 수로 분할되면 분할이 중지되고 마지막 요소에는 분할되지 않은 문자열의 "남은 부분"이 포함됩니다. 예:
String str = "Hello, world it's Amigo!";
String[] arr = str.split(" ", 2);
for (String s : arr) {
  System.out.println(s);
}
콘솔 출력:
안녕하세요, 세상 아미고입니다!
보시다시피, limit = 2 가 아닌 경우 배열의 마지막 요소는 세 개의 하위 문자열로 분할될 수 있습니다.

65. 비밀번호를 저장하는 데 문자열보다 문자 배열이 더 나은 이유는 무엇입니까?

비밀번호를 저장할 때 문자열보다 배열을 선호하는 데에는 몇 가지 이유가 있습니다.

1. 문자열 풀과 문자열 불변성.

배열( char[] )을 사용할 때 작업이 끝나면 데이터를 명시적으로 지울 수 있습니다. 또한 원하는 만큼 배열을 덮어쓸 수 있어 가비지 수집 이전에도 시스템에서 비밀번호를 제거할 수 있습니다(몇 개의 셀을 유효하지 않은 값으로 변경하는 것으로 충분합니다). 대조적으로, String은 불변 클래스입니다. 이는 String 개체 의 값을 변경하려는 경우 새 개체를 얻지만 이전 개체는 문자열 풀에 남아 있음을 의미합니다. 비밀번호가 포함된 문자열을 제거하려면 문자열 풀에서 해당 값을 제거하기 위해 가비지 수집기가 필요하지만 해당 문자열은 오랫동안 그곳에 남아 있을 가능성이 높기 때문에 복잡한 작업에 직면하게 됩니다 . 즉, 데이터를 안전하게 저장하는 데 있어서 String 은 char 배열 보다 열등합니다 .

2. 문자열 값을 콘솔(또는 로그)에 출력하면 다음을 얻습니다.

String password = "password";
System.out.println("Password - " + password);
콘솔 출력:
비밀번호 - 비밀번호
그리고 배열을 콘솔에 인쇄하는 경우:
char[] arr = new char[]{'p','a','s','s','w','o','r','d'};
System.out.println("Password - " + arr);
콘솔에는 이해할 수 없는 횡설수설이 표시됩니다.
비밀번호 - [C@7f31245a
사실, 그것은 횡설수설이 아닙니다. 표시되는 내용을 이해하는 방법은 다음과 같습니다. [C 는 클래스 이름 - 문자 배열, @ 는 구분 기호, 7f31245a 는 16진수 해시 코드입니다.

3. 공식 JCA(Java Cryptography Architecture) 참조 가이드에서는 String 대신 char[] 에 비밀번호를 저장하는 것을 명시적으로 언급합니다 .

" java.lang.String 유형의 객체에 비밀번호를 수집하고 저장하는 것이 논리적인 것처럼 보입니다 . 그러나 다음과 같은 주의 사항이 있습니다. String 유형의 객체는 변경할 수 없습니다. 즉, 변경(덮어쓰기)을 허용하는 메소드가 정의되어 있지 않습니다. 또는 사용 후 String 의 내용을 0으로 만듭니다 . 이 기능은 String 개체를 사용자 비밀번호와 같은 보안에 민감한 정보를 저장하는 데 적합하지 않게 만듭니다. 대신 항상 보안에 민감한 정보를 char 배열로 수집하고 저장해야 합니다." Java 개발자 직위에 대한 취업 면접의 질문과 답변을 살펴보세요.  파트 7 - 3

열거형

66. Java의 Enum에 대해 간략하게 설명해주세요

Enum 은 열거형의 줄임말로 공통 유형으로 통합된 문자열 상수 집합입니다. enum 키워드를 사용하여 선언합니다 . 다음은 enum : 일부 학교 캠퍼스에서 허용되는 역할 의 예입니다 .
public enum Role {
   STUDENT,
   TEACHER,
   DIRECTOR,
   SECURITY_GUARD
}
대문자로 쓰여진 단어는 열거형 상수이다. new 연산자 없이 단순화된 방식으로 선언됩니다 . 열거형을 사용하면 이름의 오류와 혼란을 방지할 수 있으므로 작업이 훨씬 쉬워집니다(목록은 유효한 값만 정의하므로). 나에게는 스위치 구성이 매우 편리합니다 .

67. Enum이 인터페이스를 구현할 수 있나요(implements 키워드 사용)?

예. 결국 열거형은 단순한 수동 집합(예: 학교 캠퍼스에서의 역할) 이상을 나타내야 합니다. Java에서는 더 복잡한 객체를 나타낼 수 있으므로 추가 기능을 추가해야 할 수도 있습니다. 또한 구현된 인터페이스 유형이 필요한 위치에 enum 값을 대체하여 다형성을 활용할 수 있습니다 .

68. Enum이 클래스를 확장할 수 있나요(extends 키워드 사용)?

아니요, 그럴 수 없습니다. 열거형은 기본 Enum<T> 클래스의 하위 클래스이기 때문입니다. 여기서 T 는 열거형 유형입니다. 이는 Java 언어의 모든 열거형 유형에 대한 공통 기본 클래스에 지나지 않습니다. 열거형 에서 클래스로의 변환은 컴파일 타임에 Java 컴파일러에 의해 수행됩니다. 확장자는 코드에 명시적으로 표시되지 않지만 항상 암시됩니다.

69. 객체의 인스턴스 없이 Enum을 생성하는 것이 가능합니까?

이 질문은 약간 혼란스러워서 제가 완전히 이해했는지 잘 모르겠습니다. 두 가지 해석이 있습니다. 1. 값 없이 열거형을 가질 수 있습니까? 예, 물론입니다. 하지만 빈 클래스와 같을 것입니다. 예를 들어 무의미합니다.
public enum Role {
}
그리고 우리가 전화하면 :
var s = Role.values();
System.out.println(s);
콘솔에서 다음을 얻습니다.
[Lflyweight.Role;@9f70c54
( Role 값 의 빈 배열 ) 2. new 연산자 없이 열거형을 생성할 수 있습니까 ? 물론이죠. 위에서 말했듯이 열거형 값은 정적 값이므로 new 연산자를 사용하지 않습니다.

70. Enum의 toString() 메서드를 재정의할 수 있나요?

예, 물론 toString 메서드가 호출될 때 열거 형을 표시하는 방법을 정의하기 위해 toString() 메서드를 재정의할 수 있습니다( 예를 들어 콘솔이나 로그에 출력하기 위해 열거형 을 일반 문자열로 변환하는 경우).
public enum Role {
   STUDENT,
   TEACHER,
   DIRECTOR,
   SECURITY_GUARD;

   @Override
   public String toString() {
       return "Selected role - " + super.toString();
   }
}
오늘은 그게 전부입니다. 다음 편까지!
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION