لسوء الحظ، لم يكن المقال مناسبًا لجزء واحد، واضطررت إلى تقسيمه إلى جزأين. شاهد البداية هنا سلسلة جافا.  أسئلة وأجوبة المقابلة، الجزء 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. هذا هو السبب في أن السلسلة هي الكائن الأكثر استخدامًا كمفتاح 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. عندما نستخدم ==العامل " "، فإنه يتحقق من قيمة السلسلة كمرجع، ولكن في البرمجة معظم الوقت نتحقق من تكافؤ السلسلة من أجل القيمة فقط. لذلك، يجب علينا استخدام طريقة يساوي لاختبار ما إذا كانت سلسلتين متكافئتين. هناك أيضًا طريقة 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. نحن نعلم أن Stringهذه فئة خاصة في Java ويمكننا إنشاء كائنات من هذه الفئة باستخدام عامل التشغيل الجديد تمامًا مثلما يمكننا إنشاء كائنات من خلال توفير قيمة سلسلة بين علامات اقتباس مزدوجة. يشرح الرسم البياني أدناه كيفية تخصيص تجمع السلاسل في كومة Java وما يحدث عندما نستخدم طرقًا مختلفة لإنشاء السلاسل. سلسلة جافا.  أسئلة وأجوبة المقابلة، الجزء 2 - 2يعد تجميع السلاسل ممكنًا فقط بسبب ثبات السلاسل في Java وتنفيذ فكرة تدريب السلاسل. يعد تجمع السلسلة أيضًا مثالاً على نمط وزن الذبابة. يساعد تجمع السلاسل على توفير الكثير من الذاكرة، ولكن من ناحية أخرى، يستغرق إنشاء صف وقتًا أطول. عندما نستخدم علامات الاقتباس المزدوجة لإنشاء سلسلة، فإنها تبحث أولاً عن سلسلة في التجمع بنفس القيمة، إذا تم العثور عليها، فإنها تقوم ببساطة بإرجاع مرجع، وإلا فسيتم إنشاء سلسلة جديدة في التجمع ثم تقوم بإرجاع مرجع. ومع ذلك، عندما نستخدم عامل التشغيل الجديد، فإننا نجبر الفصل 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()، إذا كان تجمع السلسلة يحتوي بالفعل على سلسلة مكافئة لكائننا، كما تم التحقق منه بواسطة الطريقة 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. هل السلاسل النصية آمنة في جافا؟

السلاسل النصية غير قابلة للتغيير، لذا لا يمكننا تغيير قيمتها في البرنامج. ولذلك فهي آمنة للخيوط ويمكن استخدامها بأمان في بيئة متعددة الخيوط.

21. لماذا تعتبر String مفتاحًا شائعًا في HashMap في Java؟

نظرًا لأن السلاسل غير قابلة للتغيير، فسيتم تخزين كود التجزئة الخاص بها مؤقتًا في وقت الإنشاء ولا يتطلب إعادة الحساب. وهذا يجعل السلاسل مرشحًا ممتازًا للمفتاح Map، وتتم معالجتها بشكل أسرع من الكائنات الرئيسية الأخرى HashMap. ولهذا السبب يتم استخدام السلاسل في الغالب كمفاتيح HashMap. آمل أن تساعدك الأسئلة الواردة في هذه المقالة في مقابلاتك، واسمحوا لي أن أعرف إذا فاتني أي شيء. رابط إلى المقال الأصلي الكاتب: بانكاج كومار