المقدمة
إذا كنت تخوض مقابلة للحصول على وظيفة في برمجة جافا، فإن مهارات البرمجة الخاصة بك ستخضع على الأرجح للاختبار. سواء كنت مبتدءًا في جافا أو مبرمجًا خبيرًا، يقدم هذا المقال بعض الأسئلة الشائعة في مقابلات الجافا وإجاباتها لمساعدتك في التحضير.
1. كيف يمكنك عكس سلسلة نصية في جافا؟
لا يوجد طريقة فورية لعكس النص (reverse()
) في فئة السلسلة (String
). ومع ذلك، يمكنك إنشاء مصفوفة حرفية من السلسلة ثم تكرارها من النهاية إلى البداية. يمكنك إلحاق الأحرف ببناء النص وأخيرًا إرجاع السلسلة المقلوبة.
يوضح الكود المثال التالي طريقة لعكس سلسلة نصية:
public class StringPrograms {
public static void main(String[] args) {
String str = "123";
System.out.println(reverse(str));
}
public static String reverse(String in) {
if (in == null)
throw new IllegalArgumentException("Null is not valid input");
StringBuilder out = new StringBuilder();
char[] chars = in.toCharArray();
for (int i = chars.length - 1; i >= 0; i--)
out.append(chars[i]);
return out.toString();
}
}
يحصل من يقوم بإضافة فحص null
في الطريقة واستخدام StringBuilder
لإلحاق الأحرف على نقاط إضافية. لاحظ أن الترقيم في جافا يبدأ من 0، لذلك تحتاج إلى البدء من chars.length - 1
في حلقة for
.
2. كيف يمكنك تبديل قيمتين دون استخدام متغير ثالث في جافا؟
تبديل الأرقام دون استخدام متغير ثالث هو عملية تتألف من ثلاث خطوات ويتم تصويرها بشكل أفضل في الكود:
b = b + a; // now b is sum of both the numbers
a = b - a; // b - a = (b + a) - a = b (a is swapped)
b = b - a; // (b + a) - b = a (b is swapped)
الكود المثال التالي يوضح طريقة لتنفيذ طريقة تبديل الأرقام:
public class SwapNumbers {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("a is " + a + " and b is " + b);
a = a + b;
b = a - b;
a = a - b;
System.out.println("After swapping, a is " + a + " and b is " + b);
}
}
الناتج يظهر أن قيم الأعداد الصحيحة تم تبديلها:
Outputa is 10 and b is 20
After swapping, a is 20 and b is 10
3. اكتب برنامج جافا للتحقق مما إذا كانت هناك حرف علة موجودة في سلسلة.
الكود المثال التالي يوضح كيفية استخدام تعبير عادي للتحقق مما إذا كانت السلسلة تحتوي على حروف علة:
public class StringContainsVowels {
public static void main(String[] args) {
System.out.println(stringContainsVowels("Hello")); // صحيح
System.out.println(stringContainsVowels("TV")); // خاطئ
}
public static boolean stringContainsVowels(String input) {
return input.toLowerCase().matches(".*[aeiou].*");
}
}
4. اكتب برنامج جافا للتحقق مما إذا كان الرقم المعطى هو عدد أولي.
يمكنك كتابة برنامج لتقسيم العدد المعطى n
على عدد من 2 إلى n
/2 وفحص الباقي. إذا كان الباقي يساوي 0، فإنه ليس عددًا أوليًا. يوضح الكود المثال التالي طريقة واحدة للتحقق مما إذا كان العدد المعطى عددًا أوليًا:
public class PrimeNumberCheck {
public static void main(String[] args) {
System.out.println(isPrime(19)); // صحيح
System.out.println(isPrime(49)); // خطأ
}
public static boolean isPrime(int n) {
if (n == 0 || n == 1) {
return false;
}
if (n == 2) {
return true;
}
for (int i = 2; i <= n / 2; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
}
على الرغم من أن هذا البرنامج يعمل، إلا أنه ليس فعالًا من حيث استهلاك الذاكرة والوقت. اعتبر أنه، لعدد معطى N
، إذا كان هناك عدد أولي M
بين 2
و √N
(جذر N) يقسمه بالتساوي، فإن N
ليس عددًا أوليًا.
5. اكتب برنامج Java لطباعة سلسلة Fibonacci باستخدام التكرار.
A Fibonacci sequence is one in which each number is the sum of the two previous numbers. In this example, the sequence begins with 0
and 1
. The following example code shows how to use a for
loop to print a Fibonacci sequence:
public class PrintFibonacci {
public static void printFibonacciSequence(int count) {
int a = 0;
int b = 1;
int c = 1;
for (int i = 1; i <= count; i++) {
System.out.print(a + ", ");
a = b;
b = c;
c = a + b;
}
}
public static void main(String[] args) {
printFibonacciSequence(10);
}
}
Output0, 1, 1, 2, 3, 5, 8, 13, 21, 34,
يمكنك أيضًا استخدام التكرار لطباعة سلسلة Fibonacci، لأن عدد Fibonacci يتم إنشاؤه عن طريق إضافة الرقمين السابقين في السلسلة:
F(N) = F(N-1) + F(N-2)
الفصل المثال التالي يوضح كيفية استخدام التكرار لحساب سلسلة Fibonacci التي تحتوي على 10 أرقام:
public class PrintFibonacciRecursive {
public static int fibonacci(int count) {
if (count <= 1)
return count;
return fibonacci(count - 1) + fibonacci(count - 2);
}
public static void main(String args[]) {
int seqLength = 10;
System.out.print("A Fibonacci sequence of " + seqLength + " numbers: ");
for (int i = 0; i < seqLength; i++) {
System.out.print(fibonacci(i) + " ");
}
}
}
OutputA Fibonacci sequence of 10 numbers: 0 1 1 2 3 5 8 13 21 34
6. كيف تتحقق مما إذا كانت قائمة من الأعداد الصحيحة تحتوي فقط على الأعداد الفردية في جافا؟
يمكنك استخدام حلقة for
والتحقق مما إذا كان كل عنصر فرديًا:
public static boolean onlyOddNumbers(List<Integer> list) {
for (int i : list) {
if (i % 2 == 0)
return false;
}
return true;
}
إذا كانت القائمة كبيرة، يمكنك استخدام تيار متوازي لمعالجة أسرع، كما هو موضح في الكود المثال التالي:
public static boolean onlyOddNumbers(List<Integer> list) {
return list
.parallelStream() // تيار متوازي لمعالجة أسرع
.anyMatch(x -> x % 2 != 0); // العودة بمجرد مطابقة أي عناصر للشرط
}
لمعرفة المزيد حول الرياضيات وراء تحديد ما إذا كان العدد صحيحًا فرديًا، راجع عملية النسبة المئوية على ويكيبيديا هنا.
7. كيف تتحقق مما إذا كانت سلسلة نصية هي جملة متناظرة في جافا؟
A palindrome string is the same string backwards or forwards. To check for a palindrome, you can reverse the input string and check if the result is equal to the input. The following example code shows how to use the String charAt(int index)
method to check for palindrome strings:
boolean checkPalindromeString(String input) {
boolean result = true;
int length = input.length();
for (int i = 0; i < length/2; i++) {
if (input.charAt(i) != input.charAt(length - i - 1)) {
result = false;
break;
}
}
return result;
}
8. كيف تقوم بإزالة المسافات من سلسلة نصية في جافا؟
الشفرة المثالية التالية تُظهر طريقة واحدة لإزالة المسافات من سلسلة باستخدام الطريقة Character.isWhitespace()
:
String removeWhiteSpaces(String input) {
StringBuilder output = new StringBuilder();
char[] charArray = input.toCharArray();
for (char c : charArray) {
if (!Character.isWhitespace(c))
output.append(c);
}
return output.toString();
}
تعرف المزيد حول إزالة المسافات وغيرها من الأحرف من سلسلة في جافا.
9. كيف يمكنك إزالة المسافات الزائدة في بداية ونهاية سلسلة في جافا؟
تحتوي فئة String
على طريقتين لإزالة المسافات الزائدة في البداية والنهاية: trim()
و strip()
. تمت إضافة طريقة strip()
إلى فئة String
في جافا 11. تستخدم طريقة strip()
طريقة Character.isWhitespace()
للتحقق مما إذا كان الحرف هو فراغ. تستخدم هذه الطريقة نقاط الترميز اليونيكود، بينما تعتبر طريقة trim()
أي حرف له قيمة نقطة ترميز أقل من أو تساوي U+0020
كحرف فراغ.
الطريقة strip()
هي الطريقة الموصى بها لإزالة الفراغات لأنها تستخدم المعيار اليونيكود. الشفرة المثالية التالية تُظهر كيفية استخدام الطريقة strip()
لإزالة الفراغات:
String s = " abc def\t";
s = s.strip();
System.out.println(s);
نظرًا لأن فئة String
لا تتغير، يجب عليك تعيين ناتج strip()
إلى السلسلة.
10. كيف يمكنك فرز مصفوفة في جافا؟
فئة الأدوات Arrays
لديها العديد من طرق sort()
المتعددة المحملة لفرز المصفوفات الأساسية والكائنات. إذا كنت تقوم بفرز مصفوفة أساسية بالترتيب الطبيعي، فيمكنك استخدام طريقة Arrays.sort()
، كما هو موضح في المثال التالي:
int[] array = {1, 2, 3, -1, -2, 4};
Arrays.sort(array);
System.out.println(Arrays.toString(array));
ومع ذلك، إذا كنت ترغب في فرز مصفوفة من الكائنات، فيجب أن ينفذ الكائن واجهة Comparable
. إذا كنت ترغب في تحديد معايير الفرز، يمكنك تمرير Comparator
لمنطق الفرز. تعرف أكثر عن الواجهة Comparable وComparator في جافا.
11. كيف يمكنك إنشاء سيناريو انغلاق برمجيًا في جافا؟
الانغلاق هو سيناريو في بيئة جافا متعددة الخيوط حيث يتم حجب اثنين أو أكثر من الخيوط إلى الأبد. ينشأ سيناريو الانغلاق عندما تكون هناك خيوطان أو أكثر. ينشئ الكود المثالي التالي سيناريو انغلاق:
public class ThreadDeadlock {
public static void main(String[] args) throws InterruptedException {
Object obj1 = new Object();
Object obj2 = new Object();
Object obj3 = new Object();
Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");
Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");
Thread t3 = new Thread(new SyncThread(obj3, obj1), "t3");
t1.start();
Thread.sleep(5000);
t2.start();
Thread.sleep(5000);
t3.start();
}
}
class SyncThread implements Runnable {
private Object obj1;
private Object obj2;
public SyncThread(Object o1, Object o2) {
this.obj1 = o1;
this.obj2 = o2;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " acquiring lock on " + obj1);
synchronized (obj1) {
System.out.println(name + " acquired lock on " + obj1);
work();
System.out.println(name + " acquiring lock on " + obj2);
synchronized (obj2) {
System.out.println(name + " acquired lock on " + obj2);
work();
}
System.out.println(name + " released lock on " + obj2);
}
System.out.println(name + " released lock on " + obj1);
System.out.println(name + " finished execution.");
}
private void work() {
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
جميع الخيوط الثلاثة ستتمكن من الحصول على قفل على الكائن الأول. ومع ذلك، فهي تستخدم موارد مشتركة ويتم بدء تشغيلها بطريقة تجعلها تنتظر بشكل غير محدد للحصول على قفل على الكائن الثاني. يمكنك استخدام تفريغ الخيط في جافا لاكتشاف الانغلاقات. تعرف أكثر عن انغلاق في جافا.
12. كيف يمكنك العثور على عامل الضرب لعدد صحيح في جافا؟
يتم حساب عامل الضرب لعدد صحيح عن طريق ضرب جميع الأرقام من 1 إلى العدد المعطى:
F(n) = F(1)*F(2)...F(n-1)*F(n)
يوضح الكود المثال التالي كيفية استخدام التكرار للعثور على عامل الضرب لعدد صحيح بشكل متكرر:
public static long factorial(long n) {
if (n == 1)
return 1;
else
return (n * factorial(n - 1));
}
13. كيف يمكنك عكس قائمة متصلة في جافا؟
descendingIterator()
للقائمة المتصلة يعيد مُكرر يُكرر على العنصر بترتيب عكسي. يوضح الكود المثال التالي كيفية استخدام هذا المكرر لإنشاء قائمة متصلة جديدة بالعناصر مرتبة بترتيب عكسي:
LinkedList<Integer> ll = new LinkedList<>();
ll.add(1);
ll.add(2);
ll.add(3);
System.out.println(ll);
LinkedList<Integer> ll1 = new LinkedList<>();
ll.descendingIterator().forEachRemaining(ll1::add);
System.out.println(ll1);
تعلم المزيد حول عكس قائمة متصلة من منظور هياكل البيانات والخوارزميات.
14. كيفية تنفيذ بحث ثنائي في جافا؟
يجب أن تكون عناصر المصفوفة مرتبة لتنفيذ البحث الثنائي. يعتمد خوارزمية البحث الثنائي على الشروط التالية:
- إذا كانت المفتاح أقل من العنصر الأوسط، فعليك البحث الآن في النصف الأول من المصفوفة.
- إذا كان المفتاح أكبر من العنصر الأوسط، فعليك البحث في النصف الثاني من المصفوفة.
- إذا كان المفتاح يساوي العنصر الأوسط في المصفوفة، فإن البحث ينتهي.
- أخيرًا، إذا لم يتم العثور على المفتاح في todaالمصفوفة ، فيجب أن يعيد
-1
. وهذا يشير إلى أن العنصر غير موجود.
تقوم الشيفرة المثالية التالية بتنفيذ بحث ثنائي:
public static int binarySearch(int arr[], int low, int high, int key) {
int mid = (low + high) / 2;
while (low <= high) {
if (arr[mid] < key) {
low = mid + 1;
} else if (arr[mid] == key) {
return mid;
} else {
high = mid - 1;
}
mid = (low + high) / 2;
}
if (low > high) {
return -1;
}
return -1;
}
15. اكتب برنامج جافا يوضح فرز الدمج.
ترتيب الدمج هو أحد أكثر خوارزميات الفرز كفاءة. يعمل على مبدأ “التقسيم والفتح”. يستند إلى فكرة تقسيم قائمة إلى عدة قوائم فرعية حتى تتكون كل قائمة فرعية من عنصر واحد، ثم دمج تلك القوائم الفرعية بطريقة تؤدي إلى قائمة مرتبة. يعرض الكود المثال التالي طريقة لاستخدام ترتيب الدمج:
public class MergeSort {
public static void main(String[] args) {
int[] arr = { 70, 50, 30, 10, 20, 40, 60 };
int[] merged = mergeSort(arr, 0, arr.length - 1);
for (int val : merged) {
System.out.print(val + " ");
}
}
public static int[] mergeTwoSortedArrays(int[] one, int[] two) {
int[] sorted = new int[one.length + two.length];
int i = 0;
int j = 0;
int k = 0;
while (i < one.length && j < two.length) {
if (one[i] < two[j]) {
sorted[k] = one[i];
k++;
i++;
} else {
sorted[k] = two[j];
k++;
j++;
}
}
if (i == one.length) {
while (j < two.length) {
sorted[k] = two[j];
k++;
j++;
}
}
if (j == two.length) {
while (i < one.length) {
sorted[k] = one[i];
k++;
i++;
}
}
return sorted;
}
public static int[] mergeSort(int[] arr, int lo, int hi) {
if (lo == hi) {
int[] br = new int[1];
br[0] = arr[lo];
return br;
}
int mid = (lo + hi) / 2;
int[] fh = mergeSort(arr, lo, mid);
int[] sh = mergeSort(arr, mid + 1, hi);
int[] merged = mergeTwoSortedArrays(fh, sh);
return merged;
}
}
16. هل يمكنك إنشاء هرم من الأحرف في جافا؟
تعتبر برامج النمط نمطًا شائعًا جدًا في مقابلات العمل. يُستخدم هذا النوع من الأسئلة لفهم قدرات التفكير المنطقي للمقابلين. يرجى الرجوع إلى برامج نمط الهرم في جافا لمشاهدة أمثلة على طرق مختلفة لإنشاء أنماط هرمية.
17. اكتب برنامج جافا يتحقق مما إذا كانت اثنتان من الصفائف تحتوي على نفس العناصر.
للتحقق مما إذا كانت هناك عناصر متطابقة في مصفوفتين، تحتاج أولاً إلى إنشاء مجموعة من العناصر من كلتا المصفوفتين، ثم قارن بين العناصر في هاتين المجموعتين للعثور على عنصر غير موجود في كلتا المجموعتين. يظهر الكود المثال التالي كيفية التحقق مما إذا كانت المصفوفتان تحتويان فقط على عناصر مشتركة:
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class ArraySameElements {
public static void main(String[] args) {
Integer[] a1 = {1,2,3,2,1};
Integer[] a2 = {1,2,3};
Integer[] a3 = {1,2,3,4};
System.out.println(sameElements(a1, a2));
System.out.println(sameElements(a1, a3));
}
static boolean sameElements(Object[] array1, Object[] array2) {
Set<Object> uniqueElements1 = new HashSet<>(Arrays.asList(array1));
Set<Object> uniqueElements2 = new HashSet<>(Arrays.asList(array2));
// إذا كانت الأحجام مختلفة، يعني وجود عدم تطابق
if (uniqueElements1.size() != uniqueElements2.size()) return false;
for (Object obj : uniqueElements1) {
// العنصر غير موجود في كلتاهما؟
if (!uniqueElements2.contains(obj)) return false;
}
return true;
}
}
Outputtrue
false
18. كيف تحصل على مجموع جميع العناصر في مصفوفة من الأعداد الصحيحة في لغة الجافا؟
يمكنك استخدام حلقة `for` لتكرار عناصر المصفوفة وجمعها للحصول على المجموع النهائي:
int[] array = { 1, 2, 3, 4, 5 };
int sum = 0;
for (int i : array)
sum += i;
System.out.println(sum);
19. كيف تجد الرقم الثاني الأكبر في مصفوفة في لغة الجافا؟
هناك العديد من الطرق لحل هذه المشكلة. يمكنك فرز المصفوفة بترتيب تصاعدي طبيعي واختيار القيمة الثانية من الأخير. ومع ذلك، يعد الفرز عملية مكلفة. يمكنك أيضًا استخدام متغيرين للعثور على القيمة الثانية الأكبر في عملية واحدة، كما هو موضح في المثال التالي:
private static int findSecondHighest(int[] array) {
int highest = Integer.MIN_VALUE;
int secondHighest = Integer.MIN_VALUE;
for (int i : array) {
if (i > highest) {
secondHighest = highest;
highest = i;
} else if (i > secondHighest) {
secondHighest = i;
}
}
return secondHighest;
}
كيف يمكنك تقليب مصفوفة في جافا؟
الكود المثالي التالي يوضح كيفية استخدام فئة Random
لتوليد أرقام فهرس عشوائية وتقليب العناصر:
int[] array = { 1, 2, 3, 4, 5, 6, 7 };
Random rand = new Random();
for (int i = 0; i < array.length; i++) {
int randomIndexToSwap = rand.nextInt(array.length);
int temp = array[randomIndexToSwap];
array[randomIndexToSwap] = array[i];
array[i] = temp;
}
System.out.println(Arrays.toString(array));
يمكنك تشغيل كود التقليب داخل حلقة for
أخرى لتقليب جولات متعددة.
كيف يمكنك العثور على سلسلة نصية في ملف نصي في جافا؟
الكود المثالي التالي يوضح كيفية استخدام فئة Scanner
لقراءة محتويات الملف سطراً بسطر ومن ثم استخدام طريقة String contains()
للتحقق مما إذا كانت السلسلة موجودة في الملف:
boolean findStringInFile(String filePath, String str) throws FileNotFoundException {
File file = new File(filePath);
Scanner scanner = new Scanner(file);
// قراءة الملف سطراً بسطر
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.contains(str)) {
scanner.close();
return true;
}
}
scanner.close();
return false;
}
يرجى ملاحظة أن الكود المثالي يفترض أن السلسلة التي تبحث عنها في الملف لا تحتوي على أحرف جديدة.
كيف يمكنك طباعة تاريخ بتنسيق معين في جافا؟
الكود المثالي التالي يوضح كيفية استخدام فئة SimpleDateFormat
لتنسيق سلسلة التاريخ:
String pattern = "MM-dd-yyyy";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
String date = simpleDateFormat.format(new Date());
System.out.println(date); // 06-23-2020
تعرف أكثر على Java SimpleDateFormat.
23. كيف يمكنك دمج قائمتين في جافا؟
الكود المثالي التالي يوضح كيفية استخدام طريقة addAll()
لدمج قوائم متعددة في جافا:
List<String> list1 = new ArrayList<>();
list1.add("1");
List<String> list2 = new ArrayList<>();
list2.add("2");
List<String> mergedList = new ArrayList<>(list1);
mergedList.addAll(list2);
System.out.println(mergedList); // [1, 2]
24. اكتب برنامج جافا يقوم بفرز HashMap حسب القيمة.
HashMap
ليست مجموعة مرتبة. الكود المثالي التالي يوضح كيفية فرز الإدخالات استنادًا إلى القيمة وتخزينها في LinkedHashMap
، الذي يحتفظ بترتيب الإدراج:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class SortHashMapByValue {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
scores.put("David", 95);
scores.put("Jane", 80);
scores.put("Mary", 97);
scores.put("Lisa", 78);
scores.put("Dino", 65);
System.out.println(scores);
scores = sortByValue(scores);
System.out.println(scores);
}
private static Map<String, Integer> sortByValue(Map<String, Integer> scores) {
Map<String, Integer> sortedByValue = new LinkedHashMap<>();
// احصل على مجموعة الإدخال
Set<Entry<String, Integer>> entrySet = scores.entrySet();
System.out.println(entrySet);
// قم بإنشاء قائمة نظرًا لأن المجموعة غير مرتبة
List<Entry<String, Integer>> entryList = new ArrayList<>(entrySet);
System.out.println(entryList);
// قم بفرز القائمة حسب القيمة
entryList.sort((x, y) -> x.getValue().compareTo(y.getValue()));
System.out.println(entryList);
// املأ الخريطة التجريبية الجديدة
for (Entry<String, Integer> e : entryList)
sortedByValue.put(e.getKey(), e.getValue());
return sortedByValue;
}
}
25. كيف يمكنك إزالة جميع حالات الحرف المعطى من سلسلة الإدخال في جافا؟
ليس لفئة String
طريقة لإزالة الأحرف. يوضح الشفرة المثالية التالية كيفية استخدام طريقة replace()
لإنشاء سلسلة جديدة بدون الحرف المعطى:
String str1 = "abcdABCDabcdABCD";
str1 = str1.replace("a", "");
System.out.println(str1); // bcdABCDbcdABCD
السلسلة لا تتغير في جافا. جميع طرق تعديل السلسلة تعيد سلسلة جديدة، ولهذا السبب تحتاج إلى تخصيصها إلى متغير آخر. تعرف على المزيد حول إزالة الأحرف من سلسلة في جافا.
26. كيف يمكنك الحصول على الأحرف المميزة وعددها في سلسلة نصية في جافا؟
يمكنك إنشاء مصفوفة الأحرف من السلسلة النصية. ثم قم بالتكرار فوقها وإنشاء HashMap
مع الحرف كمفتاح وعددهم كقيمة. يوضح الشيفرة المثالية التالية كيفية استخراج وعد الأحرف في سلسلة نصية:
String str1 = "abcdABCDabcd";
char[] chars = str1.toCharArray();
Map<Character, Integer> charsCount = new HashMap<>();
for (char c : chars) {
if (charsCount.containsKey(c)) {
charsCount.put(c, charsCount.get(c) + 1);
} else
charsCount.put(c, 1);
}
System.out.println(charsCount); // {a=2, A=1, b=2, B=1, c=2, C=1, d=2, D=1}
27. هل يمكنك إثبات أن كائن الـString
في جافا غير قابل للتغيير برمجيًا؟
توضح الشيفرة المثالية التالية كيفية إثبات أن كائن الـString
غير قابل للتغيير وتوضح التعليقات في الشيفرة كل خطوة:
String s1 = "Java"; // تم إنشاء سلسلة "Java" في التجميعة وتم تعيين المرجع إلى s1
String s2 = s1; // s2 لديه أيضًا نفس المرجع إلى "Java" في التجميعة
System.out.println(s1 == s2); // دليل على أن s1 و s2 لديهم نفس المرجع
s1 = "Python";
// تم تغيير قيمة s1 أعلاه، لذلك كيف يكون String لا تتغير؟
// في الحالة أعلاه تم إنشاء سلسلة جديدة "Python" في التجميعة
// s1 الآن يشير إلى السلسلة الجديدة في التجميعة
// لكن، السلسلة الأصلية "Java" لا تزال دون تغيير وتبقى في التجميعة
// s2 لا يزال يشير إلى السلسلة الأصلية "Java" في التجميعة
// دليل على أن s1 و s2 لديهم مرجع مختلف
System.out.println(s1 == s2);
System.out.println(s2);
// يطبع "Java" دعمًا لحقيقة أن قيمة السلسلة الأصلية غير متغيرة، لذا String لا تتغير
28. هل يمكنك كتابة بعض الشفرة لعرض التوريث في جافا؟
الشيفرة المصدرية التالية توضح كيفية استخدام كلمة المفتاح extends
لإنشاء فصيلة فرعية من الفئة Animal
. الفئة الجديدة Cat
ترث المتغير من الفئة Animal
وتضيف المزيد من الشيفرة التي تنتمي فقط إلى الفئة Cat
.
class Animal {
String color;
}
class Cat extends Animal {
void meow() {
System.out.println("Meow");
}
}
29. كيف يمكنك عرض مشكلة الماسة مع التوريث المتعدد في لغة البرمجة جافا؟
تحدث مشكلة الماسة عندما ترث الفئة من عدة فئات وتحدث غموضًا عندما يكون غير واضح أي من الطرق يجب تنفيذها من أي فئة. لا تسمح جافا بتمديد عدة فئات لتجنب مشكلة الماسة، كما يوضح الشرح التالي:
interface I {
void foo();
}
class A implements I {
public void foo() {}
}
class B implements I {
public void foo() {}
}
class C extends A, B { // لن يتم تجميعه
public void bar() {
super.foo();
}
}
30. كيف يمكنك توضيح مثال try-catch في لغة البرمجة جافا؟
توضح الشيفرة المصدرية التالية مثالًا على استخدام try-catch:
try {
FileInputStream fis = new FileInputStream("test.txt");
} catch(FileNotFoundException e) {
e.printStackTrace();
}
ابتداءً من جافا 7 وما بعدها، يمكنك أيضًا التقاط استثناءات متعددة في كتلة catch واحدة، كما يظهر في المثال التالي. يكون ذلك مفيدًا عندما يكون لديك نفس الشيفرة في جميع كتل الcatch.
public static void foo(int x) throws IllegalArgumentException, NullPointerException {
// بعض الشيفرة
}
public static void main(String[] args) {
try {
foo(10);
} catch (IllegalArgumentException | NullPointerException e) {
System.out.println(e.getMessage());
}
}
٣١. أكتب برنامج Java لعرض استثناء NullPointerException
.
إذا كنت تقوم باستدعاء دالة على null
، سيتم رمي استثناء NullPointerException
، كما هو موضح في الشيفرة التالية:
public static void main(String[] args) {
printString(null, 3);
}
static void printString(String s, int count) {
for (int i = 0; i < count; i++) {
System.out.println(s.toUpperCase()); // Exception in thread "main" java.lang.NullPointerException
}
}
يجب أن تقوم بفحص القيمة الخالية مبكرًا كإجراء تحقق، كما هو موضح في الشيفرة التالية:
static void printString(String s, int count) {
if (s == null) return;
for (int i = 0; i < count; i++) {
System.out.println(s.toUpperCase());
}
}
يمكنك أيضًا رمي استثناء IllegalArgumentException
استنادًا إلى متطلبات المشروع.
٣٢. كيف يمكنك إنشاء سجل في Java؟
تمت إضافة السجلات كميزة قياسية في Java 16. تتيح لك السجلات إنشاء فئة POJO بكود أدنى. تقوم السجلات تلقائيًا بتوليد الشيفرة لأساليب hashCode()
، equals()
، والحصول، والشيفرة لطريقة toString()
للفئة. السجلات هي نهائية وتمتد ضمنيًا من فئة java.lang.Record
. توضح الشيفرة التالية طريقة لإنشاء سجل:
import java.util.Map;
public record EmpRecord(int id, String name, long salary, Map<String, String> addresses) {
}
تعرّف أكثر على السجلات في جافا. للحصول على تفاصيل حول POJO، راجع Plain old Java object على ويكيبيديا.
33. كيفية إنشاء كتل نصية في جافا؟
أضافت جافا 15 ميزة الكتل النصية. يمكنك إنشاء سلاسل نصية متعددة الأسطر باستخدام الكتل النصية. يجب كتابة السلسلة متعددة الأسطر داخل زوج من علامات الاقتباس الثلاثة المزدوجة، كما هو موضح في المثال التالي:
String textBlock = """
Hi
Hello
Yes""";
إنها نفس الطريقة المستخدمة في إنشاء سلسلة، مثل Hi\\nHello\\nYes
.
34. أظهر مثالًا على تعبيرات التبديل وبيانات الحالة متعددة العلامات في جافا.
تمت إضافة تعبيرات التبديل كميزة قياسية في جافا 14. توضح الأمثلة التالية تعبيرات التبديل وكذلك بيانات الحالة متعددة العلامات:
int choice = 2;
int x = switch (choice) {
case 1, 2, 3:
yield choice;
default:
yield -1;
};
System.out.println("x = " + x); // x = 2
يمكنك أيضًا استخدام تعبيرات لامبدا في تعبيرات التبديل.
String day = "TH";
String result = switch (day) {
case "M", "W", "F" -> "MWF";
case "T", "TH", "S" -> "TTS";
default -> {
if (day.isEmpty())
yield "Please insert a valid day.";
else
yield "Looks like a Sunday.";
}
};
System.out.println(result); // TTH
35. كيف يمكنك تجميع وتشغيل فئة Java من سطر الأوامر؟
يشير هذا المثال إلى الملف الJava التالي:
public class Test {
public static void main(String args[]) {
System.out.println("Hi");
}
}
يمكنك تجميعه باستخدام الأمر التالي في الطرفية الخاصة بك:
- javac Test.java
لتشغيل الفئة، استخدم الأمر التالي في الطرفية الخاصة بك:
- java Test
بالنسبة للإصدارات الحديثة، سيقوم الأمر java
أيضًا بتجميع البرنامج إذا لم يكن ملف الفئة موجودًا. إذا كانت الفئة في حزمة، مثل com.example
، فيجب أن تكون داخل المجلد com/example
. الأمر للتجميع والتشغيل هو:
- java com/example/Test.java
إذا كانت فئتك تتطلب بعض ملفات JAR الإضافية للتجميع والتشغيل، يمكنك استخدام الخيار java -cp
. على سبيل المثال:
- java -cp .:~/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar com/example/Test.java
36. كيف تنشئ تعدادًا في جافا؟
يوضح الكود المثالي التالي كيفية إنشاء تعداد أساسي:
public enum ThreadStates {
START,
RUNNING,
WAITING,
DEAD;
}
ThreadStates
هو التعداد الذي يحتوي على حقول ثابتة هي START
، RUNNING
، WAITING
، و DEAD
. يمتد التعدادات ضمنيًا من الفئة java.lang.Enum
وتنفذ واجهتي Serializable
و Comparable
. يمكن أن يحتوي التعداد على أيضًا على طرق. تعرف على المزيد حول التعدادات في جافا.
37. كيفية استخدام طريقة forEach()
في جافا؟
توفر طريقة forEach()
اختصارًا لأداء إجراء على جميع عناصر المجموعة. يوضح الكود المثال التالي كيفية التكرار على عناصر القائمة وطباعتها:
List<String> list = new ArrayList<>();
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
يمكنك استخدام طريقة forEach()
مع تعبير لامبدا لتقليل حجم الكود، كما هو موضح في الكود المثال التالي:
List<String> list = new ArrayList<>();
list.forEach(System.out::print);
38. كيفية كتابة واجهة بطريقة تحتوي على طريقة default
و static
؟
تقدم Java 8 الطرق الافتراضية والثابتة في الواجهات. هذا يسد الفجوة بين الواجهات والفئات المجردة. يُظهر الكود المثال التالي طريقة واحدة لكتابة واجهة مع الطريقة default
وstatic
:
public interface Interface1 {
// الطريقة المجردة العادية
void method1(String str);
default void log(String str) {
System.out.println("I1 logging::" + str);
}
static boolean isNull(String str) {
System.out.println("Interface Null Check");
return str == null ? true : "".equals(str) ? true : false;
}
}
تعرف أكثر عن طرق default
وstatic
في الواجهات في تغييرات واجهة Java 8.
39. كيف تنشئ واجهة وظيفية؟
الواجهة التي تحتوي بالضبط على طريقة مجردة واحدة تُسمى واجهة وظيفية. الفائدة الرئيسية للواجهات الوظيفية هي أنه يمكنك استخدام تعبيرات لامبدا لت實فظلها وتجنب استخدام تنفيذ فئة مجهول ضخمة. تشير التعليقة @FunctionalInterface
إلى واجهة وظيفية، كما هو موضح في الكود المثال التالي:
@FunctionalInterface
interface Foo {
void test();
}
40. عرض مثال على استخدام تعبيرات لامبدا في Java.
Runnable
هو مثال ممتاز على واجهة وظيفية. يمكنك استخدام تعبيرات لامبدا لإنشاء مهمة قابلة للتشغيل، كما هو موضح في الشفرة المثالية التالية:
Runnable r1 = () -> System.out.println("My Runnable");
41. أظهر أمثلة على التحميل الزائد والتجاوز في جافا.
عندما تحتوي الفئة على اثنين أو أكثر من الأساليب بنفس الاسم، يتم استدعاء هذه الأساليب باسم “الأساليب المحملة”. الشفرة المثالية التالية تُظهر كيف يُستدعى الأسلوب المحمل بالاسم print
:
class Foo {
void print(String s) {
System.out.println(s);
}
void print(String s, int count) {
while (count > 0) {
System.out.println(s);
count--;
}
}
}
عندما يتم تنفيذ أسلوب في الفئة الأساسية ويتم تنفيذه أيضًا في الفئة الفرعية، يُسمى ذلك “التجاوز”. الشفرة المثالية التالية تُظهر كيفية تعليق أسلوب printname()
الذي يتم تنفيذه في كلتا الفئتين:
class Base {
void printName() {
System.out.println("Base Class");
}
}
class Child extends Base {
@Override
void printName() {
System.out.println("Child Class");
}
}
تعرف أكثر حول التجاوز والتحميل الزائد في جافا.
42.-49. حدد الناتج
امتحن نفسك عن طريق تخمين الناتج للكود الموجود أدناه.
String s1 = "abc";
String s2 = "abc";
System.out.println("s1 == s2 is:" + s1 == s2);
Output
false
الناتج للبيان المعطى هو false
لأن عامل الجمع +
له أولوية أعلى من عامل المساواة ==
. لذا، يُقيم التعبير المعطى إلى “s1 == s2 is:abc” == “abc”
، والذي يعود بقيمة false
.
String s3 = "JournalDev";
int start = 1;
char end = 5;
System.out.println(s3.substring(start, end));
Output
ourn
إخراج البيان المعطى هو ourn
. يتم تحويل الحرف الأول تلقائيًا إلى int
. ثم، نظرًا لأن فهرس الحرف الأول هو 0، سيبدأ من o
ويقوم بالطباعة حتى n
. يرجى ملاحظة أن طريقة String substring
تنشئ سلسلة فرعية تبدأ من الفهرس start
وتمتد إلى الحرف في الفهرس end - 1
.
HashSet shortSet = new HashSet();
for (short i = 0; i < 100; i++) {
shortSet.add(i);
shortSet.remove(i - 1);
}
System.out.println(shortSet.size());
Output
100
حجم shortSet
هو 100
. ميزة التحويل التلقائي في جافا تعني أن التعبير i
، الذي يحتوي على نوع بدائي short
، يتحول إلى كائن Short
. بالمثل، يحتوي التعبير i - 1
على نوع بدائي int
ويتم تحويله تلقائيًا إلى كائن Integer
. نظرًا لعدم وجود كائن Integer
في HashSet
، لا يتم إزالة شيء والحجم هو 100
.
try {
if (flag) {
while (true) {
}
} else {
System.exit(1);
}
} finally {
System.out.println("In Finally");
}
Output
لا إخراج. يؤدي هذا الكود إلى حلقة لانهائية إذا كانت العلمية هي true
ويتم الخروج من البرنامج إذا كانت العلمية هي false
. لن يتم الوصول أبدًا إلى كتلة finally
.
String str = null;
String str1="abc";
System.out.println(str1.equals("abc") | str.equals(null));
Output
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "<local1>" is null
سيؤدي البيان المعطى إلى رمي استثناء java.lang.NullPointerException
لأن المشغل المنطقي OR
يقيم كل من القيم قبل إرجاع النتيجة. نظرًا لأن str
هو null
، فإن طريقة .equals()
ستقوم بإلقاء استثناء. من النصح دائمًا باستخدام المشغلات المنطقية ذات الدوائر القصيرة، مثل ||
و &&
، التي تقيم القيم الأدنى من اليمين إلى اليسار. في هذه الحالة، نظرًا لأن القيمة الأولى ستعيد true
، فإنها ستتجاوز تقييم القيمة الثانية.
String x = "abc";
String y = "abc";
x.concat(y);
System.out.print(x);
Output
abc
x.concat(y)
ينشئ سلسلة جديدة ولكن لا يتم تعيينها لـ x
، لذلك قيمة x
لا تتغير.
public class MathTest {
public void main(String[] args) {
int x = 10 * 10 - 10;
System.out.println(x);
}
}
Output
Error: Main method is not static in class MathTest, please define the main method as:
public static void main(String[] args)
على الرغم من أنه قد يبدو أن هذا السؤال يتعلق بترتيب تنفيذ عمليات الرياضيات ، إلا أن السؤال يتعلق حقًا بملاحظة أنه لم يتم تعريف طريقة main كـ static
.
public class Test {
public static void main(String[] args) {
try {
throw new IOException("Hello");
} catch(IOException | Exception e) {
System.out.println(e.getMessage());
}
}
}
Output
Test.java:5: error: cannot find symbol
throw new IOException("Hello");
^
symbol: class IOException
location: class Test
Test.java:6: error: cannot find symbol
}catch(IOException | Exception e) {
^
symbol: class IOException
location: class Test
2 errors
يؤدي هذا الكود إلى وقوع خطأ في وقت الترجمة. يتم التقاط الاستثناء IOException
بالفعل بواسطة البديل Exception
.
50. ابحث عن 5 أخطاء في مقطع الشفرة التالي.
package com.digitalocean.programming-interviews;
public class String Programs {
static void main(String[10] args) {
String s = "abc"
System.out.println(s);
}
}
Answers
- لا يمكن أن يحتوي اسم الحزمة على شرطات.
- لا يمكن أن يحتوي اسم الفئة على مسافات.
- طريقة main ليست
public
، لذلك لن تتم تشغيلها. - لا يجب أن يحدد الوسيط الرئيسي حجمًا.
- فاصلة منقوطة مفقودة في تعريف السلسلة.
الاستنتاج
تتضمن هذه المجموعة من 50 سؤالًا لمقابلة برمجة Java أسئلة من المستوى المبتدئ إلى المستوى الخبير ، لمساعدتك في التحضير لمقابلتك.
القراءة الموصى بها:
Source:
https://www.digitalocean.com/community/tutorials/java-programming-interview-questions