JavaRush /Java Blog /Random-KO /자바 문자열. 인터뷰 질문과 답변, 2부
Andrey
레벨 26

자바 문자열. 인터뷰 질문과 답변, 2부

Random-KO 그룹에 게시되었습니다
안타깝게도 기사가 하나의 조각에 맞지 않아서 두 부분으로 나누어야 했습니다. 여기에서 시작 부분을 확인하세요 자바 문자열.  면접 질문과 답변, 2부 - 1

12. 주어진 문자열에서 가장 긴 회문을 찾는 함수를 작성하세요.

문자열은 회문 문자열을 포함할 수 있으며 가장 긴 회문을 찾는 것은 프로그래밍의 문제입니다. 여기서 중요한 점은 회문의 중앙에서 한 문자씩 오른쪽과 왼쪽으로 이동하면 항상 같은 문자가 된다는 것입니다. 예를 들어 12321, 가운데는 3이고 현재 위치에서 양방향으로 계속 이동하면 2를 얻은 다음 1을 얻습니다. 우리는 가장 긴 회문을 찾기 위해 Java 프로그램에서 유사한 논리를 사용합니다. 그러나 회문의 길이가 짝수이면 가운데의 길이도 짝수이므로 이것이 우리 프로그램에서도 제공되는지 확인해야 합니다. 예를 들어 12333321, 중간은 33이고 계속 이동하면 양방향으로 우리는 3, 2, 1을 얻게 될 것입니다. 우리 프로그램에서는 결과 문자열의 중간부터 먼저 살펴보고 왼쪽과 오른쪽 문자를 확인합니다. 또한 회문의 초기 위치를 저장하는 두 개의 전역 변수가 있습니다. 또한 주어진 문자열에서 여러 개의 회문을 찾을 수 있으므로 이미 발견된 더 긴 회문이 있는지 확인해야 합니다. 다음은 모든 경우에 잘 작동하는 예제 프로그램입니다. while 루프를 별도의 메서드로 이동하여 위 코드를 개선할 수 있지만 해당 부분은 여러분을 위해 남겨 두겠습니다. 더 나은 구현 방법이 있거나 프로그램이 어떤 방식으로든 실패하는 경우 알려주시기 바랍니다.
package com.journaldev.util;

public class LongestPalindromeFinder {

    public static void main(String[] args) {
        System.out.println(longestPalindromeString("1234"));
        System.out.println(longestPalindromeString("12321"));
        System.out.println(longestPalindromeString("9912321456"));
        System.out.println(longestPalindromeString("9912333321456"));
        System.out.println(longestPalindromeString("12145445499"));
    }

    public static String longestPalindromeString(String in) {
        char[] input = in.toCharArray();
        int longestPalindromeStart = 0;
        int longestPalindromeEnd = 0;

        for (int mid = 0; mid < input.length; mid++) {
            // для случая нечетного палиндрома How 12321, 3 будет серединой
            int left = mid-1;
            int right = mid+1;
            // нам необходимо двигаться влево и вправо на 1 позицию до конца
            while (left >= 0 && right < input.length) {
                // ниже проверка, является ли это палиндромом
                if (input[left] == input[right]) {
                    // обновление глобальных позиций, только если палиндром длиннее имеющегося
                    if (right - left > longestPalindromeEnd
                            - longestPalindromeStart) {
                        longestPalindromeStart = left;
                        longestPalindromeEnd = right;
                    }
                }
                left--;
                right++;
            }
            // для четного палиндрома у нас должна быть подобная логика с размером середины 2
            // для этого мы начнем на одну позицию правее
            left = mid-1;
            right = mid + 2;// к примеру, для 12333321 мы выбрали 33 в качестве середины
            while (left >= 0 && right < input.length)
            {
                if (input[left] == input[right]) {
                    if (right - left > longestPalindromeEnd
                            - longestPalindromeStart) {
                        longestPalindromeStart = left;
                        longestPalindromeEnd = right;
                    }
                }
                left--;
                right++;
            }
        }
        // теперь у нас есть позиции для самого длинного палиндрома
        return in.substring(longestPalindromeStart, longestPalindromeEnd + 1);
    }
}
프로그램은 다음을 출력합니다:
1
12321
12321
12333321
454454

13. String, StringBuffer 및 StringBuilder의 차이점은 무엇입니까?

문자열은 Java에서 불변이고 완료되므로 모든 문자열 조작은 항상 새 문자열을 생성합니다. 문자열 조작은 리소스 집약적이므로 Java는 문자열 조작을 위한 두 가지 유용한 클래스인 StringBuffer및 를 제공합니다 StringBuilder. 변경 가능한 클래스입니다 StringBuffer. StringBuilder를 사용한 작업은 StringBuffer스레드로부터 안전하고 동기화되지만 메서드는 StringBuilder스레드로부터 안전하지 않습니다. 따라서 여러 스레드가 동일한 문자열에 대해 작업하는 경우 를 사용해야 StringBuffer하지만 단일 스레드 환경에서는 을 사용해야 합니다 StringBuilder. 동기화에 대한 부담이 없기 때문에 StringBuilder더 생산적입니다 .StringBuffer

14. Java에서 문자열이 불변이고 종료되는 이유는 무엇입니까?

문자열 불변성에는 몇 가지 장점이 있습니다.
  1. 문자열 풀링은 Java에서 문자열이 불변이기 때문에 가능합니다. 따라서 가상 머신은 다양한 문자열 변수가 풀의 동일한 변수를 가리키므로 많은 힙 공간을 절약합니다. 문자열이 변경 불가능하지 않은 경우 문자열 인터닝은 불가능합니다. 변수가 값을 변경하면 해당 문자열을 참조하는 다른 변수도 영향을 받기 때문입니다.

  2. 문자열이 변경 가능하면 애플리케이션에 심각한 보안 위험이 됩니다. 예를 들어, 데이터베이스 사용자 이름과 비밀번호는 데이터베이스에 대한 연결을 얻기 위해 문자열로 전달되고 소켓 프로그래밍에서는 호스트 및 포트 세부 정보가 문자열로 전달됩니다. 문자열은 변경할 수 없으므로 해당 값을 변경할 수 없습니다. 그렇지 않으면 해커가 링크 값을 변경하여 애플리케이션 보안에 문제를 일으킬 수 있습니다.

  3. 문자열은 변경할 수 없으므로 스레드로부터 안전하며 문자열의 한 인스턴스를 다른 스레드 간에 공유할 수 있습니다. 이렇게 하면 스레드 안전을 위한 동기화가 방지되며 문자열은 완전히 스레드로부터 안전합니다.

  4. 문자열은 Java에서 사용되며 classloader불변성은 클래스가 Classloader. 예를 들어, 클래스를 로드하려고 시도했지만 참조 값이 데이터베이스에 원치 않는 작업을 수행할 수 있는 클래스 java.sql.Connection로 변경된 경우 클래스 인스턴스를 생각해 보세요.myhacked.Connection

  5. 문자열은 변경할 수 없으므로 hashcode생성 시 캐시되며 다시 계산할 필요가 없습니다. 이렇게 하면 문자열이 키 입력에 탁월한 후보가 되며 Map해당 문자열의 처리 속도는 다른 키보다 빠릅니다 HashMap. 이것이 string이 키로 사용되는 가장 일반적으로 사용되는 객체인 이유입니다 HashMap.

15. 문자열을 여러 부분으로 나누는 방법은 무엇입니까?

split(String regex)정규식을 구분 기호로 사용하여 문자열을 문자열 배열로 분할하는 메서드를 사용할 수 있습니다 .
import java.util.Arrays;

public class JavaSplitString {
    public static void main(String[] args) {
        String line = "I am a java developer";
        String[] words = line.split(" ");
        String[] twoWords = line.split(" ", 2);
        System.out.println("String split with delimiter: "+Arrays.toString(words));
        System.out.println("String split into two: "+Arrays.toString(twoWords));
        //split string delimited with special characters
        String wordsWithNumbers = "I|am|a|java|developer";
        String[] numbers = wordsWithNumbers.split("\\|");
        System.out.println("String split with special character: "+Arrays.toString(numbers));
    }
}
이 메서드는 split(String regex, int numOfStrings)문자열을 지정된 수의 줄로 분할하기 위한 오버로드된 메서드입니다. 백슬래시를 사용하여 정규식 특수 문자를 일반 문자로 사용할 수 있습니다. 프로그램은 다음을 출력합니다:
String split with delimiter: [I, am, a, java, developer]
String split into two: [I, am a java developer]
String split with special character: [I, am, a, java, developer]

16. 비밀번호를 저장하는 데 문자열보다 문자열 배열을 선호하는 이유는 무엇입니까?

문자열은 Java에서 변경할 수 없으며 문자열 풀에 저장됩니다. 일단 생성되면 가비지 수집될 때까지 풀에 남아 있으므로 비밀번호 사용이 끝났다고 생각하면 잠시 동안 메모리에 사용 가능한 상태로 유지되며 이를 피할 수 있는 방법이 없습니다. 메모리 덤프에 액세스할 수 있는 사람은 누구나 일반 텍스트로 비밀번호를 찾을 수 있으므로 이는 보안상 위험합니다. 문자 배열을 사용하여 비밀번호를 저장하는 경우 비밀번호 작업을 마친 후에 비밀번호를 지울 수 있습니다. 이렇게 하면 문자열에 내재된 보안 위험을 피하면서 문자열이 메모리에 머무르는 기간을 제어할 수 있습니다.

17. Java에서 두 문자열의 유사성을 어떻게 확인합니까?

두 문자열이 동일한지 확인하는 방법에는 " ==" 연산자를 사용하거나 equals. “ ” 연산자를 사용하면 ==문자열의 값을 참조로 확인하지만, 프로그래밍에서는 대부분 값에 대해서만 문자열 동등성을 확인합니다. 따라서 두 문자열이 같은지 테스트하려면 equals 메서드를 사용해야 합니다. equalsIgnoreCase대소문자를 무시하는 데 사용할 수 있는 방법도 있습니다 .
String s1 = "abc";
String s2 = "abc";
String s3= new String("abc");
System.out.println("s1 == s2 ? "+(s1==s2)); //true
System.out.println("s1 == s3 ? "+(s1==s3)); //false
System.out.println("s1 equals s3 ? "+(s1.equals(s3))); //true

18. 스트링 풀이란 무엇입니까?

이름에서 알 수 있듯이 문자열 풀은 Java 힙에 저장된 문자열 모음입니다. 우리는 이것이 Java의 특수 클래스라는 것을 알고 String있으며 큰따옴표로 묶인 문자열 값을 제공하여 객체를 생성할 수 있는 것처럼 new 연산자를 사용하여 이 클래스의 객체를 생성할 수 있습니다. 아래 다이어그램은 문자열 풀이 Java 힙에 할당되는 방법과 문자열을 생성하기 위해 다양한 방법을 사용할 때 어떤 일이 발생하는지 설명합니다. 자바 문자열.  면접 질문과 답변, 2부 - 2부문자열 풀링은 Java의 문자열 불변성과 문자열 인터닝 아이디어 구현 덕분에 가능합니다. 스트링 풀도 플라이급 패턴의 한 예입니다. 문자열 풀은 많은 메모리를 절약하는 데 도움이 되지만, 행을 생성하는 데는 시간이 더 걸립니다. 문자열을 생성하기 위해 큰따옴표를 사용하면 먼저 풀에서 동일한 값을 가진 문자열을 찾고, 발견되면 단순히 참조를 반환하고, 그렇지 않으면 풀에서 새 문자열이 생성된 다음 참조를 반환합니다. 그러나 new 연산자를 사용하면 클래스가 String새 문자열 개체를 생성하도록 강제한 다음 메서드를 사용하여 intern()문자열을 풀에 넣거나 풀에서 String동일한 값을 가진 다른 개체에 대한 참조를 가져올 수 있습니다. 다음은 문자열 풀의 작동 방식을 보여주는 예입니다.
public class StringPool {
    public static void main(String[] args) {
        String s1 = "Cat";
        String s2 = "Cat";
        String s3 = new String("Cat");

        System.out.println("s1 == s2 :"+(s1==s2));
        System.out.println("s1 == s3 :"+(s1==s3));
    }
}
프로그램은 다음을 출력합니다:
s1 == s2 :true
s1 == s3 :false

19. intern() 메소드는 무엇을 합니까?

메소드가 intern()호출될 때 메소드에 의해 확인된 대로 문자열 풀에 객체와 동일한 문자열이 이미 포함되어 있는 경우 equals(Object)풀의 문자열에 대한 참조가 반환됩니다. 그렇지 않으면 문자열 개체가 풀에 추가되고 해당 개체에 대한 참조가 반환됩니다. 이 메서드는 항상 현재 문자열과 동일한 값을 갖는 문자열을 반환하지만 해당 문자열이 고유 문자열 풀의 문자열임을 보장합니다. 다음은 이 방법이 어떻게 작동하는지에 대한 예입니다 intern().
public class StringPool {
    public static void main(String[] args) {
        String a = "string a";
        String b = new String("string a");
        String c = b.intern();

        System.out.println(a == b);
        System.out.println(b == c);
        System.out.println(a == c);
    }
}
Программа выведет следующее:false
false
true

20. Java에서 문자열은 스레드로부터 안전합니까?

문자열은 변경할 수 없으므로 프로그램에서 해당 값을 변경할 수 없습니다. 따라서 스레드로부터 안전하며 다중 스레드 환경에서도 안전하게 사용할 수 있습니다.

21. Java의 HashMap에서 String이 널리 사용되는 키인 이유는 무엇입니까?

문자열은 변경할 수 없으므로 해당 해시 코드는 생성 시 캐시되며 재계산이 필요하지 않습니다. 이로 인해 문자열은 키에 대한 탁월한 후보가 되며 Map다른 키 개체보다 빠르게 처리됩니다 HashMap. 이것이 문자열이 주로 키로 사용되는 이유입니다 HashMap. 이 기사에 나열된 질문이 인터뷰에 도움이 되기를 바랍니다. 제가 놓친 내용이 있으면 알려 주시기 바랍니다. 원본 기사 링크 작성자: Pankaj Kumar
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION