پوشش دقیق دامنههای آزمون
ویژگیهای اصلی زبان جاوا (۲۵٪)
مباحث:انواع دادههای اولیه، لیترالها و عملگرها؛ دستورات کنترل جریان و مدیریت استثناها؛ کلاسها، اینترفیسها، enumها و recordها؛ بهبودهای زبانی Java SE 11 و ویژگیهای پیشنمایش.
برنامهنویسی و طراحی شیءگرا (۲۵٪)
مباحث:کپسولهسازی، ارثبری و چندریختی؛ اصول طراحی (SOLID) و الگوهای رایج طراحی؛ اصلاحکنندههای دسترسی، کلاسهای داخلی و تو در تو؛ تصمیمگیری بین ترکیب (Composition) در مقابل ارثبری.
برنامهنویسی تابعی و استریمها (۲۵٪)
مباحث:عبارتهای لامبدا و ارجاعات متد؛ رابطهای تابعی و متدهای پیشفرض؛ عملیات خط لوله استریم (filter, map, reduce, collect)؛ APIهای Optional و مدیریت مقادیر null.
همروندی، internals JVM و عملکرد (۲۵٪)
مباحث:چرخه حیات Thread، رابطهای Runnable، Callable و Executorها؛ همگامسازی (Synchronization)، قفلها و مجموعههای همزمان؛ الگوریتمهای Garbage Collection و تنظیمات آن؛ بارگذاری کلاسها، سیستم ماژولار و گزینههای JVM.
دریافت گواهینامه Oracle Certified Professional (OCP) Java SE 11 یکی از معتبرترین راهها برای اثبات تخصص شما در مهندسی بکاند است. با این حال، قبولی در این آزمون نیازمند چیزی فراتر از درک کلی سینتکس است. این آزمون به دلیل تست کردن موارد بسیار خاص، رفتارهای غیرمنتظره کامپایلر و جزئیات پیچیده API که توسعهدهندگان به ندرت در کدنویسی روزمره به آنها فکر میکنند، شهرت دارد.
من این بانک سوالات آزمایشی را طراحی کردم تا فاصله بین «دانستن جاوا» و «قبولی در آزمون OCP» را پر کنم. به جای ارائه تعاریف ساده، این سوالات پیچیدگی محیط واقعی آزمون را شبیهسازی میکنند. شما یاد خواهید گرفت که تلههای ظریف در سوالات مربوط به استنتاج نوع متغیرها، ترتیب اجرای استریمها و شرایط رقابتی در محیطهای چندرشتهای را شناسایی کنید. هر سوال دارای یک تحلیل جامع است تا دقیقاً متوجه شوید چرا یک گزینه درست و سایر گزینهها غلط هستند.
پیشنمایش سوالات تمرینی
سوال ۱: ویژگیهای اصلی زبان جاوا
نتیجه تلاش برای کامپایل و اجرای قطعه کد زیر چیست؟
Java
public class LambdaVar {
public static void main(String[] args) {
java.util.function.BinaryOperator<String> bo = (var s1, String s2) -> s1 +s2; // Line 1
var dynamicList = new java.util.ArrayList<>(); // Line 2
dynamicList.add(10);
var item = dynamicList.get(0); // Line 3
System.out.println(item.getClass().getName());
}
}
A) بدون مشکل کامپایل شده و java.lang.Integer را چاپ میکند.
B) خط ۱ باعث خطای کامپایل میشود زیرا var نمیتواند با انواع صریح در پارامترهای لامبدا ترکیب شود.
C) خط ۲ باعث خطای کامپایل میشود زیرا عملگر diamond نمیتواند با var بدون زمینه نوع صریح استفاده شود.
D) خط ۳ باعث خطای کامپایل میشود زیرا dynamicList به صورت پیشفرض یک ArrayList از نوع Object است و نمیتواند getClass() را تحلیل کند.
E) هر دو خط ۱ و ۲ باعث خطای کامپایل میشوند.
F) کد با موفقیت کامپایل میشود اما در زمان اجرا ClassCastException پرتاب میکند.
پاسخها و توضیحات:
پاسخ صحیح: B
تحلیل گزینهها:
چرا B درست است:جاوا ۱۱ اجازه استفاده از var در پارامترهای لامبدا را میدهد، اما قانون سازگاری سختگیرانهای را اعمال میکند. شما باید یا برای تمام پارامترها از var استفاده کنید، یا برای همه انواع صریح، یا برای همه انواع ضمنی. ترکیب (var s1, String s2) غیرقانونی است و باعث خطای کامپایل میشود.
چرا A غلط است:کد هرگز اجرا نمیشود تا چیزی را چاپ کند زیرا خط ۱ قوانین کامپایل را نقض کرده است.
چرا C غلط است:خط ۲ کاملاً معتبر است. وقتی var با عملگر diamond خالی <> ترکیب شود، جاوا نوع را به عنوان ArrayList از Object استنتاج میکند.
چرا D غلط است:خط ۳ بدون مشکل کامپایل میشود. از آنجایی که dynamicList یک ArrayList<Object> است، متد get(0) یک ارجاع Object برمیگرداند. متد getClass() مستقیماً در کلاس Object تعریف شده است، بنابراین کاملاً در دسترس است.
چرا E غلط است:فقط خط ۱ باعث شکست کامپایل میشود؛ سینتکس خط ۲ قانونی است.
چرا F غلط است:کد در مرحله کامپایل شکست میخورد، به این معنی که هیچ استثنای زمان اجرای رخ نمیدهد.
سوال ۲: برنامهنویسی تابعی و استریمها
کد برنامه زیر را در نظر بگیرید. هنگام اجرای این کد چه چیزی در کنسول نمایش داده میشود؟
Java
import java.util.List;
import java.util.Optional;
public class StreamQuery {
public static void main(String[] args) {
List<String> data = List.of("apple", "banana", "apricot", "cherry");
Optional<String> result = data. stream()
.filter(s -> s.startsWith("a"))
.map(s -> {
System.out.print(s +"");
return s.toUpperCase();
})
.sorted()
.findFirst();
}
}
A) apple apricot
B) apple
C) هیچ چیزی چاپ نمیشود زیرا خط لوله استریم lazy است و findFirst() عملیات میانی را تحریک نمیکند.
D) apple apricot banana cherry
E) خطای کامپایل رخ میدهد زیرا sorted() نمیتواند بلافاصله بعد از یک عملیات mapping که رشته برمیگرداند فراخوانی شود.
F) در زمان اجرا NullPointerException پرتاب میشود زیرا عناصر List.of به صورت متوالی بررسی میشوند.
پاسخها و توضیحات:
پاسخ صحیح: A
تحلیل گزینهها:
چرا A درست است:استریمها عموماً lazy هستند، اما برخی عملیاتهای میانی مانند sorted() به عنوان یک سد (barrier) عمل میکنند. برای مرتبسازی عناصر، استریم باید ابتدا تمام عناصر upstream منطبق را ارزیابی کند. فیلتر مقادیر "apple"و "apricot"را به مرحله map میفرستد که هر دو رشته را قبل از اینکه عملیات sorted() بتواند آنها را سازماندهی کرده و اولین مورد را به findFirst() تحویل دهد، چاپ میکند.
چرا B غلط است:اگر sorted() نبود، منطق short-circuiting در findFirst() تنها "apple"را پردازش میکرد. اما سد مرتبسازی، ارزیابی هر دو عنصر منطبق را اجبار میکند.
چرا C غلط است:متد findFirst() یک عملیات نهایی (terminal operation) است، به این معنی که فعالانه خط لوله استریم را اجرا میکند.
چرا D غلط است:عناصری مانند "banana"و "cherry"در مرحله فیلتر حذف میشوند، بنابراین هرگز وارد بلوک map برای چاپ نمیشوند.
چرا E غلط است:عملیات map با موفقیت یک Stream<String> تولید میکند. کلاس String اینترفیس Comparable را پیادهسازی کرده است، بنابراین برای متد sorted() بدون آرگومان کاملاً مناسب است.
چرا F غلط است:متد List.of یک مجموعه معتبر و غیر null ایجاد میکند و هیچ پردازش عنصری باعث بروز null pointer نمیشود.
سوال ۳: همروندی، internals JVM و عملکرد
رفتار برنامه چندرشتهای زیر چیست؟
Java
import java.util.concurrent.*;
public class ConcurrencyTest {
public static void main(String[] args) throws Exception {
ExecutorService service = Executors.newFixedThreadPool(2);
Future<String> f1 = service.submit(() -> "Task 1");
Future<?> f2 = service.submit(() -> { System.out.print("Task 2 "); });
System.out.print(f1.get() +"");
System.out.print(f2.get() +"");
service.shutdown();
}
}
A) چاپ میکند Task 2 Task 1 null (یا Task 1 Task 2 null بسته به زمانبندی رشتهها).
B) باعث خطای کامپایل میشود زیرا submit() نمیتواند یک عبارت لامبدا را بدون کست صریح به رابط تابعی بپذیرد.
C) چاپ میکند Task 1 Task 2 و سپس یک NullPointerException در زمان اجرا در f2.get() رخ میدهد.
D) کد با موفقیت کامپایل میشود اما برای همیشه متوقف (hang) میشود زیرا service.shutdown() خیلی دیر فراخوانی شده است.
E) باعث خطای کامپایل میشود زیرا Future<?> نمیتواند مقدار بازگشتی یک عبارت لامبدا از نوع Runnable را دریافت کند.
F) چاپ میکند Task 1 و سپس یک InterruptedException پرتاب میکند.
پاسخها و توضیحات:
پاسخ صحیح: A
تحلیل گزینهها:
چرا A درست است:اولین تسک هدفش Callable<String> است و "Task 1"را برمیگرداند. تسک دوم با Runnable مطابقت دارد زیرا شکل بازگشتی آن void است. وقتی get() را روی یک Future که توسط Runnable پشتیبانی میشود فراخوانی میکنید، تا پایان اجرا منتظر میماند و سپس مقدار null برمیگرداند. بسته به اولویتبندی رشتهها، "Task 2 "ممکن است قبل یا بعد از چاپ نتایج get() توسط رشته اصلی چاپ شود.
چرا B غلط است:کامپایلر عبارات تابعی را به راحتی با نسخههای اورلود شده submit(Callable) و submit(Runnable) مطابقت میدهد.
چرا C غلط است:فراخوانی get() روی یک تسک Runnable تکمیل شده، به سادگی مقدار null را برمیگرداند و هیچ استثنایی پرتاب نمیکند.
چرا D غلط است:کد به طور طبیعی پایان مییابد. متدهای get() تا پایان تسکها مسدود میشوند و تضمین میکنند که shutdown() بلافاصله بعد از آن با ایمنی فراخوانی شود.
چرا E غلط است:Future<?> از یک الگوی wildcard استفاده میکند که به راحتی نتیجه null بازگشتی یک توالی Runnable را میپذیرد.
چرا F غلط است:هیچ حلقه اجرایی مختل یا متوقف نمیشود، به این معنی که هیچ InterruptedException پرتاب نخواهد شد.
به آکادمی آزمونهای شبیهسازی شده خوش آمدید تا شما را برای آزمونهای Oracle Certified Professional: Java SE 11 Developer آماده کنیم.
شما میتوانید آزمونها را هر چند بار که بخواهید تکرار کنید.
این یک بانک سوالات عظیم و اورجینال است.
در صورت داشتن هرگونه سوال، از پشتیبانی مدرسان بهرهمند میشوید.
هر سوال دارای یک توضیح دقیق و تشریحی است.
با اپلیکیشن Udemy کاملاً سازگار با موبایل است.
امیدوارم تا اینجا متقاعد شده باشید! سوالات بسیار بیشتری در داخل دوره وجود دارد.
Mock Exam Practice Test Academy
مدرس در Udemy
نمایش نظرات