سوالات مصاحبه برنامه نویسی جاوا — راهنمای استخدام
زبان جاوا (Java) یک زبان پرطرفدار و دائمی در حوزه برنامه نویسی و توسعه نرم افزار به حساب میآید. یادگیری مهارتهای استفاده از زبان برنامه نویسی جاوا میتواند به پیشرفت علمی و شغلی هر فردی بینجامد. در این مقاله تعدادی از سوالات مورد توجه و مهم زبان برنامه نویسی جاوا به همراه پاسخ آنها برای کسب آمادگی لازم جهت شرکت در مصاحبه برنامه نویس جاوا ارائه شده است. در مقاله «سوالات مصاحبه برنامه نویسی جاوا» سوالات بر اساس درجه سختی از سطح مبتدی تا پیشرفته ستهبندی شدهاند. در ابتدای این مطلب به سوالاتی پرداخته میشود که نیاز است برنامه نویسان مبتدی و تازهکار آنها را بدانند.
سوالات مصاحبه برنامه نویسی جاوا برای افراد تازهکار
در این مقاله، ابتدا به سوالات مصاحبه برنامه نویسی جاوا برای افراد تازهکار و مبتدی پرداخته شده است. اشخاص مبتدی در حوزه برنامه نویسی میتوانند به وسیله آشنایی با این سوالات سطح مهارتهای خود را در این حوزه افزایش دهند.
اگر شخصی در زمینه برنامه نویسی جاوا در ابتدای مسیر است و قصد استخدام شدن به عنوان یک برنامه نویس تازهکار را دارد، میتواند از سوالات مصاحبه برنامه نویسی جاوا این بخش جهت آمادگی لازم برای شرکت در جلسه مصاحبه استفاده کند. سوالات مصاحبه برنامه نویسی جاوا در این بخش از ابتداییترین موضوع شروع و به مرور پیشرفتهتر میشوند.
زبان برنامه نویسی جاوا چیست؟
جاوا یک زبان همه منظوره مبتنی بر کلاس و برنامه نویسی شی گرا (Object Oriented Programming | OOP) است. زبان جاوا یکی از محبوبترین زبانهای برنامه نویسی در میان برنامه نویسان جهان به شمار میرود.
چطور میتوان جاوا را نصب کرد؟
جاوا روشهای نصب گوناگونی دارد که در این بخش به بررسی آنها پرداخته شده است:
- جاوا را میتوان با استفاده از خط فرمان (Command Prompt) نصب کرد. همچنین به وسیله نصب جاوا از طریق خط فرمان، جاوا میتواند فایلهای ثبت وقایع (لاگها) را برای تسهیل عیبیابی ایجاد کند.
- میتوان با استفاده از وب سایت رسمی جاوا [+] به صورت رایگان این برنامه را دانلود و نصب کرد که مراحل انجام آن به این صورت است:
- پس از دانلود نرم افزار جاوا از سایت معرفی شده، روی دکمه «save» کلیک و این نرم افزار در سیستم شخص ذخیره میشود.
- در این مرحله باید خط فرمان «cmd» را باز شود و با باز کردن به شاخه دانلود جاوا، باید فایل نصب را اجرا و دستورالعملها را دنبال کرد تا فرآیند نصب تکمیل شود.
چرا جاوا زبانی مستقل از پلتفرم است؟
زبان برنامه نویسی جاوا به گونهای توسعه داده شده است که به هیچ سخت افزار یا نرم افزار خاصی وابسته نیست. دلیلش این است که کامپایلر کدهای جاوا را کامپایل (همگردانی) و سپس آنها را به کدهای بایتی (Bytecode) مستقل از پلتفرم تبدیل میکند تا امکان پیادهسازی کدها روی سیستمهای متعدد فراهم شود.
تنها شرطی که برای اجرای کدهای بایتی وجود دارد این است که حتما «محیط زمان اجرای جاوا» (Java Runtime Environment | JRE) روی سیستم نصب باشد.
متد در جاوا چیست؟
متُد (Method) در جاوا بلوکی از کدها است و فقط زمانی پیادهسازی میشود که فراخوانی شود. میتوان دادههایی را به عنوان پارامتر به متد ارجاع داد. متدها برای اجرای عملکردهای مختلف به کار میروند. معمولاً دو اصطلاح متد و تابع به جای یکدیگر استفاده میشوند.
thread در جاوا چیست؟
Thread یا نخ در جاوا مسیری است که در زمان اجرای برنامه دنبال میشود. به وسیله مفهوم نخ در جاوا امکان اجرای موازی وظایف برنامه برای برنامه نویس فراهم میشود. از Threadها میتوان جهت پیادهسازی کدهای برنامههای پیچیدهتر در پس زمینه برنامه بدون ایجاد هیچ وقفهای در برنامه اصلی استفاده کرد. آنها به وسیله کلاس Thread و رونویسی (Override) کردن متد «()run» پیادهسازی میشوند.
شی گرایی در جاوا چیست ؟
شی گرایی در جاوا، مفهومی جهت بهبود خوانایی (Readability) و قابلیت استفاده مجدد (Reusability) از کدها به وسیله تعریف کارآمد برنامه به حساب میآید. اصول اساسی شی گرایی در این زبان برنامه نویسی نیز مانند سایر زبانها، خصیصههای تجرید یا انتزاع (Abstraction)، کپسوله سازی (Encapsulation)، وراثت یا ارث بری (Inheritance)، چند ریختی یا پلی مورفیسم (Polymorphism) در جاوا و سایر موارد را شامل میشوند. هدف از تبیین این اصول، پیادهسازی موجودیتهای دنیای واقعی در برنامهها است.
چرا جاوا یک زبان شی گرای خالص نیست؟
زبان جاوا انواع دادههای اولیه را پشتیبانی میکند و به همین دلیل یک زبان شی گرای خاص به حساب نمیآید. انواع دادههای اولیه شامل موارد زیر است:
- Integer
- Short
- Char
- Boolean
- نوع داده Double
- Long
- Float
- Byte
کلاس در جاوا چیست؟
کلاس بلوک اصلی زبانهای شی گرا مانند جاوا به حساب میآید. در یک کلاس، دادهها و رفتارهای مرتبط با نمونههای کلاس (یعنی همان اشیا) توصیف میشوند. هنگامی که در کلاسی نمونهای ایجاد میشود، شی جدید ایجاد شده شبیه به نمونههای دیگر همان کلاس است. دادههای مرتبط با یک کلاس یا شی در متغیرها ذخیره میشوند. رفتار مرتبط با یک کلاس یا شی به وسیله متدها پیادهسازی شده است. کلاسها قالبهایی برای ساخت اشیا هستند. برای درک بهتر مفهوم کلاس در برنامه نویسی، مطالعه مقاله زیر پیشنهاد میشود:
اشاره گرها که در زبان برنامه نویسی C و ++C استفاده میشوند، چرا در جاوا استفادهای ندارند؟
اشاره گر (Pointer) مفهومی است که امنیت پایینی دارد و برای استفاده برنامه نویسان تازهکار کمی پیچیده است. جاوا به دنبال سادگی در برنامه نویسی است و برخلاف این هدف زبان جاوا، اشاره گرها در برنامه نویسی چالش ایجاد میکنند. استفاده از اشاره گر پتانسیل بالایی برای بروز خطا دارد. علاوه بر این، به دلیل اینکه استفاده از اشاره گرها موجب ایجاد دسترسی مستقیم کاربران به حافظه میشود، امنیت برنامه به خطر میافتد.
بدین ترتیب، سطح معینی از انتزاع با درج نکردن اشاره گرها در جاوا ایجاد میشود. استفاده از اشاره گرها میتواند روند بازیافت حافظه (Garbage Collection) را تا حد زیادی کُند و دچار اختلال کند. جاوا از ارجاعات (Reference) استفاده میکند زیرا برخلاف اشاره گرها نمیتوان آنها را دستکاری کرد.
Bytecode در جاوا چیست؟
بایتکد یا همان «Bytecode» فرمت کامپایل شده برای برنامههای جاوا به حساب میآید. زمانی که یک برنامه جاوا به Bytecode تبدیل میشود، میتوان آن را به یک شبکه انتقال داد و توسط ماشین مجازی جاوا (Java Virtual Machine | JVM) اجرا کرد. فایلهای Bytecode معمولاً دارای پسوند «class.» هستند.
منظور از ماشین مجازی جاوا چیست؟
ماشین مجازی جاوا (JVM) یک ماشین مجازی است که به کامپیوتر این امکان را میدهد تا برنامههای زبان جاوا و همچنین برنامههای نوشته شده با زبانهای دیگر را اجرا کند. در زبانهای دیگر اگر برنامهها در بایتکد جاوا کامپایل شده باشند، امکان اجرای آنها توسط «JVM» وجود دارد.
متغیر در جاوا چیست؟
متغیر در برنامه نویسی جاوا قطعهای از حافظه است که میتواند حاوی یک مقدار داده با نوع خاصی باشد. بنابراین متغیرها میتوانند دارای انواع داده مانند «Integer» ،«Float» ،«String» و سایر موارد باشند. متغیرها معمولاً برای ذخیره اطلاعاتی مورد استفاده قرار میگیرند که برنامه جاوا برای اجرای وظایف به آنها نیاز دارد.
متغیر نمونه و متغیر محلی چیست؟
متغیرهای نمونه (Instance Variable) نوعی از متغیرها به حساب میآیند که در دسترس همه متدهای کلاس قرار دارند. این متغیرها خارج از متدها و در داخل کلاسها اعلان (تعریف) میشوند. این متغیرها خصلتهای (خصوصیتهای| Property) اشیا را توصیف میکنند و همیشه به اشیا وابسته میمانند.
همه اشیا کلاس کپی متغیرهای خود را دارند. اگر هر گونه تغییری روی این متغیرها انجام شود، تنها همان نمونه تحت تأثیر این تغییرات قرار میگیرد و دیگر نمونههای کلاس همچنان بیتأثیر باقی میمانند. برای درک بهتر این موضوع در ادامه مثالی ارائه شده است. در این مثال، athleteName ،athleteSpeed و athleteAge متغیرهای نمونه هستند.
1class Athlete {
2public String athleteName;
3public double athleteSpeed;
4public int athleteAge;
5}
متغیرهای محلی (Local Variable)، متغیرهایی هستند که در بلوکها، توابع یا سازندهها وجود دارند و فقط در داخل محدوده این بلوکها دسترسی به متغیرهای محلی امکانپذیر است. زمانی که یک متغیر محلی در داخل متدی تعریف میشود، متدهای دیگر کلاس هیچ اطلاعی از آن متغیر ندارند. در مثال زیر athleteName ،athleteSpeed و athleteAge به صورت متغیرهای محلی تعریف شدهاند:
1public void athlete() {
2String athleteName;
3double athleteSpeed;
4int athleteAge;
5}
روش دریافت ورودیها در جاوا چگونه است؟
در زبان برنامه نویسی جاوا با استفاده از روش زیر میتوان ورودیها را تعریف کرد:
1Scanner in = new Scanner(System.in);
2 System.out.print(""Please enter hour 1: "");
3 int hour1 = in.nextInt();
4 System.out.print(""Please enter hour 2: "");
5 int hour2 = in.nextInt();
6 System.out.print(""Please enter minute 1: "");
7 int min1 = in.nextInt();
8 System.out.print(""Please enter minute 2: "");
9 int min2 = in.nextInt();
شمارش در جاوا چیست؟
شمارش (Enumeration) در جاوا به صورت فهرستی تعریف میشود که با شیوه ثابتی نامگذاری شده است. Enumeration یا همان Enum نوع کلاسها را تعریف میکند و میتواند دارای سازندهها، متدها و متغیرهای نمونه باشد. این مفهوم با استفاده از کلمه کلیدی «enum» مورد استفاده قرار می گیرد.
هر Enumeration به صورت پیشفرض دارای حالت عمومی (Public)، استاتیک (Static) یا نهایی (Final) است. اگر روش شمارش نوعی کلاس را تعریف کند که دارای سازنده است، enum به وسیله کلمه «new» نمونهسازی (Instantiate) نمیشود. متغیرهای Enumeration تقریباً به همان روشی که یک متغیر ابتدایی اعلان شده است، استفاده و اعلان میشوند.
وراثت یا ارث بری در جاوا چیست؟
فرآیندی که به وسیله آن کلاسی ویژگیها (همان اعضای داده) و عملکردهای (همان متدهای) کلاس دیگر را به دست میآورد، وراثت یا ارث بری (Inheritance) نامیده میشود. هدف وراثت در زبان برنامه نویسی جاوا این است که قابلیت استفاده مجدد (Reusability) از کدها افزایش پیدا کند.
به طوری که یک کلاس فقط میتواند ویژگیهای (Feature) خاص خود را ایجاد کند و بقیه ویژگیها و قابلیتهای عملکردی (Functionality) مشترک را از کلاسهای قبل از خود به دست میآورد و به اصطلاح میتوان گفت که به ارث میبرد. این موضوع یکی از مفاهیم مهم شی گرایی در جاوا به حساب میآید. در ادامه دو نوع از کلاسهای این مفهوم تعریف شدهاند:
کلاس فرزند
کلاسی که ویژگیهای یک کلاس دیگر را استفاده میکند به عنوان کلاس فرزند (Child Class)، زیر کلاس (Sub Class) یا کلاس مشتق شده (Derived Class) شناخته میشود.
کلاس والد
کلاسی که ویژگیها و عملکردهای آن توسط کلاس دیگری استفاده میشود (به ارث میرسد.). به این نوع از کلاسها، کلاس والد (Parent Class)، سوپر کلاس (Super Class) یا کلاس پایه (Base Class) میگویند.
چرا وراثت چندگانه در جاوا پشتیبانی نمیشود؟
زبان برنامه نویسی جاوا وراثت چندگانه (Multiple Inheritance) را فقط توسط واسطها پشتیبانی میکند. یک کلاس میتواند هر تعداد واسط را پیادهسازی کند، اما تنها یک کلاس را گسترش (Extend) میدهد. وراثت چندگانه به این دلیل پشتیبانی نمیشود که منجر به اختلال در روند اجرای برنامههای جاوا میشود.
انتزاع در جاوا چیست؟
اشیا بلوکهای سازنده برنامه نویسی شی گرا در جاوا به حساب میآیند. آنها شامل برخی از ویژگیها و متدها هستند. میتوان این اشیا را به وسیله تغییر دهندههای دسترسی (Access Modifier) از دسترس دنیای بیرون از کلاس پنهان کرد. انتزاع (Abstraction) فقط به توابع و ویژگیهای مورد نیاز از برنامههای دیگر در برنامه مورد نظر امکان دسترسی میدهد.
کلاس انتزاعی در جاوا چیست؟
کلاسی که از کلمه «abstract» در تعریف آن استفاده شده باشد، یک کلاس انتزاعی (Abstract Class) به حساب میآید. این کلاس میتواند دارای متدهای انتزاعی (Abstract Method) یعنی متدهایی که بدنه ندارند و همچنین متدهای عینی یعنی متدهای عادی با بدنه باشد. کلاسهای عادی، نمیتوانند از متدهای انتزاعی استفاده کنند.
چرا در جاوا واسط یا اینترفیس استفاده میشود؟
واسط (Interface)، جهت دستیابی و پیادهسازی انتزاع در شی گرایی مورد استفاده قرار میگیرد. از آن جایی که در زبان جاوا از وراثت چندگانه در کلاسها پشتیبانی نمیشود، با استفاده از واسطها میتوان از وراثت چندگانه استفاده کرد. معمولاً واسطها برای اتصال سست (Loose Coupling) در جاوا استفاده میشوند.
کپسوله سازی داده در جاوا به چه معنی است؟
کپسوله سازی (Encapsulation) دادهها یکی از مفاهیم برنامه نویسی شی گرا به حساب میآید. کپسوله سازی در جاوا مفهومی است که کدها و دادهها (متغیرها) و عملیاتی که روی دادهها انجام میشوند (متدها) به صورت واحدی در کنار هم قرار میگیرند. در کپسوله سازی، متغیرهای یک کلاس از کلاسهای دیگر پنهان میشوند و فقط از طریق متدهای کلاس فعلی دسترسی به آنها وجود دارد. این مفهوم باعث افزایش امنیت دادهها در کلاسها میشود. کپسوله سازی به توسعه دهندگان جهت توسعه نرم افزار به صورت پیمانهای (Modular) و اطمینان از استقلال هر شی از اشیا دیگر به وسیله متدها، ویژگیها (Attribute) و عملکردهای خود کمک میکند. ایده استفاده از کپسوله سازی در جهت پنهان کردن ویژگیها و رفتارهای (Behavior) دادهها از کاربرها است.
اگر عضو داده، خصوصی (Private) باشد، یعنی فقط در همان کلاسی که در آن تعریف شده قابل دسترسی است. هیچ کلاس خارجی نمیتواند به عضو دادههای خصوصی (متغیرها) کلاس دیگر دسترسی داشته باشد. به اطلاعاتی که در یک بستهبندی قرار دارند و کلاس دیگری نمیتواند به آنها دسترسی داشته باشد، کپسوله شده گفته میشود. با این حال، کلاسهای خارجی میتوانند با استفاده از متدهای عمومی «Setter» و «Getter» به فیلدهای داده خصوصی دسترسی پیدا کنند.
پلی مورفیسم در جاوا چیست؟
پُلی مورفیسم (چند ریختی | چند شکلی | Polymorphism) به وجود شکلهای (فُرمهای) بسیار در برنامه گفته میشود. یا میتوان گفت پلی مورفیسم پردازشی به حساب میآید که یک عمل واحد را به روشهای گوناگونی انجام میدهد. پلی مورفیسم در جاوا برای افزایش خوانایی و استفاده مجدد از دادهها به کار گرفته میشود.
API در جاوا چیست؟
واسط برنامه نویسی اپلیکیشن (Application Programming Interface) در جاوا یا به اختصار «API»، فهرستی از تمام کلاسهایی است که بخشی از کیت توسعه جاوا (Java development kit | JKD) هستند. API شامل همه بستههای جاوا (Java Package)، کلاسها و واسطها (Interface) به همراه متدها، فیلدها و سازندههای آنها است. این کلاسهای از پیش نوشته شده (Pre-Written Class)، قابلیتهای فوق العادهای را در اختیار یک برنامه نویس قرار میدهند.
آرایه در جاوا چیست؟
آرایه در جاوا یک شی از نوع «Container» (ظرف) است که تعداد ثابتی از مقادیر یک نوع واحد را در خود نگه میدارد. با ایجاد آرایه طول آن نیز مشخص و پس از ایجاد طول، ثابت میشود. برای مثال اگر آرایهای دارای 10 محل نگهداری عنصر باشد، این مکانها از صفر تا 9 شمارهگذاری میشوند و اندیس (Index) شماره صفر اولین عنصر آرایه را نشان میدهد. مقدار هر بخش از آرایه یک عنصر نامیده میشود و با استفاده از اندیسها میتوان به این عناصر دسترسی داشت. در ادامه این بخش از مقاله «سوالات مصاحبه برنامه نویسی جاوا» دو سوال دیگر مرتبط با آرایه در جاوا ارائه شده است.
چطور میتوان آرایهها را در جاوا تعریف کرد؟
در کدهای زیر مثالی برای تعریف دو متغیر با نوع دادهای گوناگون ارائه شده است.
1int[] arr = new int[5];
2String[] cars = {""Volvo"", ""BMW"", ""Ford"", ""Mazda""};
در خط اول کدها، آرایه در جاوا با نوع دادهای «Integer» یا همان عدد صحیح و اندازه 5 تعریف میشود و در خط دوم دستورات فوق، آرایهای با نوع دادهای «String» یا رشتهای تعریف شده است.
چطور یک آرایه در جاوا مرتب میشود؟
برای مرتبسازی دادهها در جاوا از متد sort() به صورت زیر استفاده میشود:
1import java. util. Arrays;
2Arrays. sort(array);
عضو استاتیک در جاوا چیست؟
در جاوا، عضو ایستا (Static Member) عضوی از کلاس است که با نمونههای (Instance) کلاس ارتباطی ندارد. در عوض این عضو متعلق به خود کلاس است. میتوان بدون ایجاد نمونه کلاس به عضو ثابت آن دسترسی داشت.
بسته در جاوا چیست؟
بسته (Package) در جاوا جهت گروهبندی کلاسهای مرتبط به هم استفاده میشود. این مفهوم به عنوان یک پوشه در فایل دایرکتوری در نظر گرفته شده است. از بستهها برای جلوگیری از تداخل نام کلاسها و بهبود نوشتن کد با قابلیت نگهداری (Maintainability) مورد استفاده قرار میگیرد. بستهها به دو نوع زیر تقسیم میشوند:
- بستههای ساخته شده (Built-in Package): بستههایی که در API جاوا وجود دارند.
- بستههای تعریف شده توسط کاربر (User-defined Package): بستههایی هستند که توسط برنامه نویس ایجاد و استفاده میشوند.
استثنا در جاوا چیست؟
استثنا (Exception) رویدادی است که در حین اجرای برنامه رخ میدهد و جریان عادی دستورالعملهای برنامه را مختل میکند. هنگامی که خطایی (Error) در متد به وجود میآید، متد یک شی را ایجاد میکند و آن را در زمان اجرا به سیستم تحویل میدهد. این شی استثنا نامیده میشود و حاوی اطلاعاتی در مورد خطا، از جمله نوع آن و وضعیت برنامه در هنگام وقوع خطا است. ایجاد شی استثنا و تحویل آن به سیستم زمان اجرا کنترل استثنا (Throwing an Exception) نامیده میشود.
پس از کنترل و ارسال استثنا در متد، سیستم زمان اجرا تلاش میکند روشی برای مدیریت استثنا پیدا کند. مجموعهای از «چیزهای» ممکن برای رسیدگی به استثنا و حل کردن آن، در فهرستی از متدها موجود هستند که برای رسیدن به متدی که خطا در آن رخ داده فراخوانی میشوند. فهرست متدها به عنوان پشته فراخوانی (Call Stack) شناخته میشوند.
کلاس Singleton در جاوا چیست؟
الگوی طراحی «Singleton» جهت محدود کردن نمونهسازی کلاس استفاده میشود و فقط وجود یک نمونه از کلاس را در ماشین مجازی جاوا تضمین میکند. به عبارت دیگر، کلاس Singleton کلاسی است که میتواند تنها یک شی (نمونهای از کلاس) در یک زمان برای هر نمونه «JVM» داشته باشد.
منظور از فریمورک در جاوا چیست؟
فریمورکها بدنههای بزرگی (معمولاً کلاسهای زیادی) از کدهای از پیش نوشته شده هستند که برنامه نویس برای حل یک مسئله در دامنهای خاص، کدهای خود را به آن اضافه میکند. برنامه نویس یک فریمورک را جهت فراخوانی متدها، ارث بری و پیادهسازیهای دیگر مورد استفاده قرار میدهد.
کامپایلر JIT چیست؟
«JIT» سرنامی برای عبارت «Just In Time» به معنی سیستم تولید به موقع یا «کامپایلر درجا» است و جهت افزایش کارایی در زمان اجرا مورد استفاده قرار میگیرد. این کامپایلر، وظیفه کامپایل بخشی از بایتکد با عملکرد مشابه در یک زمان را دارد و در نتیجه مقدار زمان کامپایل برای اجرای کدها را کاهش میدهد.
کامپایلر مترجمی برای تبدیل کدهای منبع به کدهای قابل اجرا توسط ماشین به حساب میآید. اما کامپایلر JIT دارای ویژگیهای خاصی است که باعث محبوبیت و کارایی بیشتر آن شده و در ادامه به بررسی این ویژگیها پرداخته میشود:
- ابتدا، کدهای منبع جاوا (java.) با کمک کامپایلر «javac» به بایتکد (class.) تبدیل میشوند.
- در این مرحله، فایلهای «class.» در زمان اجرا به وسیله JVM بارگذاری و به کمک یک مفسر (Interpreter) به کدهای قابل درک برای ماشین تبدیل میشوند.
- کامپایلر JIT بخشی از JVM به حساب میآید. زمانی که این کامپایلر غیر فعال است، JVM فراخوانی متدهای داخل فایلهای «class.» را تجزیه و تحلیل میکند و برای به دست آوردن کارایی بیشتر و کدهای «Native» (بومی) آنها را کامپایل میکند. همچنین اطمینان حاصل میکند که فراخوانی متدهای اولویتبندی شده، بهینه هستند.
- زمانی که مرحله فوق انجام شد و به پایان رسید، JVM به جای تفسیر دوباره کدها، کدهای بهینهسازی شده را به طور مستقیم اجرا میکند. این روش، کارایی و سرعت پیادهسازی را افزایش میدهد.
- مقاله پیشنهادی: آموزش طراحی کامپایلر — مجموعه مقالات جامع وبلاگ فرادرس
تفاوت بین متد ()equals و عمگر == در جاوا چیست؟
دو تفاوت عمده متد «()equals» و عمگر «==» به این صورت است که:
- «()equals» یک متد برای تعریف شی در کلاس است و عملگر «==»، عملگری باینری در جاوا به حساب میآید.
- متد «()equals» جهت بررسی برابر بودن محتوای دو شی بر اساس منطقی استفاده میشود که برای آنها مشخص شده است، اما عملگر «==» برای مقایسه آدرسها یا ارجاعات مورد استفاده قرار میگیرد، این موضوع به این معنی است که فقط زمانی دو شی بررسی و مقایسه میشوند که دقیقاً به یک مکان در حافظه اشاره داشته باشند.
در این سوال باید به دو نکته زیر نیز توجه داشت:
- در مواردی که متد ()equals در کلاس رونویسی نشده باشد، کلاس از پیادهسازیهای پیشفرض این متد استفاده میکند که به کلاس والد نزدیکتر هستند.
- کلاس شی به عنوان کلاس والد همه کلاسهای جاوا در نظر گرفته میشود. در پیادهسازی متد ()equals در کلاس شی از عملگر == جهت مقایسه دو شی استفاده شده است. این پیادهسازی پیشفرض میتواند به صورت منطقی رونویسی شود.
یک حلقه بینهایت در جاوا چگونه اعلان میشود؟
حلقههای بینهایت (Infinite Loop) بدون قطع شرط حلقه به صورت پی در پی و بینهایت اجرا میشوند.
این حلقهها فقط با دستورات قطع حلقه متوقف خواهند شد. میتوان با سه روش این حلقهها را تعریف کرد که در ادامه این بخش مشاهده میشوند.
- ایجاد Infinite Loop با استفاده از حلقه «for» جاوا:
1for (;;)
2{
3 // دستورات حلقه
4 // دستورات قطع حلقه
5}
- ایجاد Infinite Loop با استفاده از حلقه «while» در جاوا:
1while(true){
2 // دستورات حلقه
3 // دستورات قطع حلقه
4}
- ایجاد حلقه بینهایت با استفاده از حلقه «do-while» در جاوا:
1do{
2 // دستورات حلقه
3 // دستورات قطع حلقه
4}while(true);
به طور مختصر مفهوم Constructor Overloading چیست؟
«Constructor Overloading» یا همان سازنده اضافه بار فرآیندی جهت ایجاد سازندههای چندگانه (Multiple Constructor) در کلاسی یکسان به همراه تفاوت در پارامترهای سازنده است.
این مفهوم به تعداد پارامترها و انواع آنها بستگی دارد، تشخیص انواع گوناگون سازندهها توسط کامپایلر انجام میگیرد.
1class Hospital {
2int variable1, variable2;
3double variable3;
4public Hospital(int doctors, int nurses) {
5 variable1 = doctors;
6 variable2 = nurses;
7}
8public Hospital(int doctors) {
9 variable1 = doctors;
10}
11public Hospital(double salaries) {
12 variable3 = salaries
13}
14}
در کدهای فوق سه سازنده تعریف شدهاند که نوع و تعداد پارامترهای آنها با هم تفاوت دارند.
منظور از روش Overloading و Overriding در جاوا چیست؟
در زبان برنامه نویسی جاوا، روش «Overloading» به وسیله معرفی متدهای گوناگون در کلاسی مشابه با نام یکسان تعریف میشود. تفاوت این متدها در تعداد و نوع پارامترهایشان است.
وقتی همه این متدها در داخل کلاس قرار میگیرند، قابلیت خوانایی برنامه افزایش پیدا میکند. تنها تفاوت در ساخت این روش در نوع بازگشتی آن است. کدهای زیر مثالی برای روش Overloading در جاوا به حساب میآیند.
1class OverloadingHelp {
2 public int findarea (int l, int b) {
3 int var1;
4 var1 = l * b;
5 return var1;
6 }
7 public int findarea (int l, int b, int h) {
8 int var2;
9 var2 = l * b * h;
10 return var2;
11 }
12}
در کدهای فوق، هر دو متد از یک نام استفاده کردهاند اما تعداد آرگومانهای آنها متفاوت است. متد اول مساحت مستطیل و متد دوم مساحت مکعب را محاسبه میکند.
روش «Overriding» یا همان رونویسی کردن مفهومی است که در آن دو متد دارای یک امضا (کدهای شناسایی | Signature) متد یکسان در دو کلاس متفاوت وجود دارند. این متدها با هم در ارتباط وراثتی هستند. متد خاص پیادهسازی شده (اکنون در کلاس پایه وجود دارد.) برای استفاده به صورت روش Overriding در کلاس مشتق شده یا همان کلاس فرزند وجود دارد. مثال زیر روش Overriding را توصیف میکند.
1class HumanBeing {
2 public int walk (int distance, int time) {
3 int speed = distance / time;
4 return speed;
5 }
6}
7class Athlete extends HumanBeing {
8 public int walk(int distance, int time) {
9 int speed = distance / time;
10 speed = speed * 2;
11 return speed;
12 }
13}
نام هر دو متد در هر دو کلاس «walk» است و دارای پارامترهای یکسان «distance» و «time» هستند. اگر کلاس مشتق شده فراخوانی شود، متد کلاس پایه walk با کلاس مشتق شده رونویسی میشود؛ یعنی کلاس فرزند از کلاس والد ارث بری میکند.
کلمه کلیدی final چگونه در متغیرها، متدها و کلاسها مورد استفاده قرار میگیرد؟
در زبان برنامه نویسی جاوا، کلمه کلیدی «final» جهت تعریف چیزی استفاده میشود که ثابت و نهایی باشد و همچنین نشان دهنده دسترسی نداشتن به تغییرات است.
در ادامه این بخش به ویژگیهای استفاده از متغیرها، متدها و کلاسها به صورت نهایی پرداخته شده است:
- متغیرهای final: زمانی یک متغیر به صورت نهایی در زبان جاوا اعلان میشود که پس از تخصیص مقدار به متغیر نتوان آن را تغییر داد. اگر هیچ مقداری به متغیر تخصیص داده نشده بود، فقط توسط سازنده کلاس به آن مقدار داده میشود.
- متد final: متدی که به صورت نهایی تعریف شده باشد، نمیتواند با کلاسهای فرزندانش رونویسی شود. همچنین، نمیتوان سازنده را به صورت نهایی تعریف کرد. زیرا زمانی که یک کلاس چیزی به ارث برده است، سازنده چیزی به ارث نمیبرد. از این رو، حالت نهایی برای سازندهها وجود ندارد. در این حالت خطای کامپایلی به صورت «modifier final not allowed here» به معنی «اصلاح کننده نهایی در اینجا مجاز نیست» نشان داده میشود.
- کلاس final: هیچ کلاسی از کلاسی که به صورت نهایی اعلان شده است، چیزی نمیتواند به ارث ببرد. اما کلاس نهایی میتواند کلاسهای دیگر را برای استفاده خود گسترش بدهد.
- مقاله پیشنهادی: کلمات کلیدی final و static در جاوا
در این بخش از مقاله «سوالات مصاحبه برنامه نویسی جاوا» به بررسی برخی از کلیدیترین پرسشهای مقدماتی برنامه نویسی با جاوا پرداخته شد. اکنون در ادامه پیش از پرداختن به سایر سوالات مصاحبه برنامه نویسی جاوا ، تعدادی از دورههای آموزش برنامه نویسی جاوا فرادرس معرفی شدهاند.
چه زمانی از کلمه کلیدی super استفاده میشود؟
به صورت کلی کلمه کلیدی «super» جهت دسترسی به فیلدهای پنهان شده و متدهای رونویسی شده یا ویژگیهای (Attribute) کلاس والد مورد استفاده قرار میگیرد.
در ادامه موارد اصلی استفاده از این کلمه کلیدی ارائه شده است:
- جهت دسترسی به عضو دادههای کلاس والد زمانی که نام عضوهای کلاس و زیر کلاسهای فرزند آنها یکسان است، از کلمه کلیدی «super» استفاده میشود.
- برای فراخوانی سازندههای پیشفرض و دارای پارامتر کلاس والد در داخل کلاس فرزند، از کلمه کلیدی «super» استفاده میشود.
- از کلمه کلیدی «super»، برای دسترسی به متدهای والد زمانی استفاده میشود که کلاسهای فرزند آنها را رونویسی کردهاند.
کدهای زیر برای درک بهتر روشهای استفاده از کلمه کلیدی «super» ارائه شدهاند.
1public class Parent{
2 protected int num = 1;
3
4 Parent(){
5 System.out.println("Parent class default constructor.");
6 }
7
8 Parent(String x){
9 System.out.println("Parent class parameterised constructor.");
10 }
11
12 public void foo(){
13 System.out.println("Parent class foo!");
14 }
15 }
16
17 public class Child extends Parent{
18 private int num = 2;
19
20 Child(){
21 System.out.println("Child class default Constructor");
22
23 super(); // فراخوانی سازنده والد پیشفرض
24 super("Call Parent"); // فراخوانی سازنده پارامتری
25 }
26
27 void printNum(){
28 System.out.println(num);
29 System.out.println(super.num); // کلاس والد num چاپ مقدار
30 }
31
32 @Override
33 public void foo(){
34 System.out.println("Parent class foo!");
35 super.foo(); // کلاس والد در رونویسی همین متد از کلاس فرزند foo فراخوانی متد
36 }
37 }
آیا در متدهای استاتیک میتواند روش Overload انجام گیرد؟
بله؛ به دلیل اینکه در زبان برنامه نویسی جاوا دو یا چند متد استاتیک میتوانند در یک کلاس با نام یکسان و پارامترهای ورودی گوناگون وجود داشته باشند، روش «Overload» نیز انجام میگیرد.
آیا در متدهای استاتیک میتواند روش «Overridde» انجام گیرد؟
خیر؛ اعلان متدهای استاتیک دارای کدهای شناسایی یا «Signature» یکسانی است که در زیر کلاس انجام میگیرد. روش «Override» یا پلی مورفیسم پویا در زمان اجرا اتفاق میافتد، اما متدهای استاتیک در زمان کامپایل به صورت ایستا بارگذاری میشوند. به همین دلیل این روش در متدهای استاتیک قابل اجرا نیست.
تفاوت بین زبان برنامه نویسی جاوا و جاوا اسکریپت چیست؟
جاوا و جاوا اسکریپت (JavaScript) دو زبان برنامه نویسی متفاوت هستند که در این بخش به عنوان یکی از سوالات مهم مصاحبه برنامه نویسی جاوا به تفاوتهای اصلی آنها پرداخته شده است. در ادامه مقاله، این تفاوتها در پنج بخش ارائه میشوند.
- زبان جاوا اسکریپت برای توسعه فرانتاند (Front End) مورد استفاده قرار میگیرد، در حالی که جاوا جهت توسعه بکاند (Back End) استفاده میشود. به عبارت دیگر، جاوا اسکریپت مسئول رفتار پویا (Dynamic Behaviour) یک صفحه وب است یعنی رویدادها (Events)، کوکیها (Cookie)، «جاوا اسکریپت و XML غیرهمزمان» (Asynchronous JavaScript and XML | AJAX) و سایر موارد را در یک وب سایت مدیریت میکند. جاوا اسکریپت مسئله اصلی واسط کاربری پویا (Dynamic User Interface) صفحات وب به حساب میآید، در حالی که جاوا بهترین زبان برنامه نویسی برای مهندسان نرم افزار است و میتواند با صفحات سرور جاوا (Java Server pages | JSP) جهت مدیریت بکاند استفاده شود.
- در جاوا اسکریپت کدها به صورت پویا و در زبان جاوا کدها به صورت استاتیک نوشته میشوند. این موضوع به این معنی است که در جاوا اسکریپت میتوان نوع داده متغیرها را تغییر داد. اما در جاوا نمیتوان تغییری در نوع داده متغیر ایجاد کرد و این تغییر باعث خطا در جاوا خواهد شد. در ادامه مثالهایی برای درک بهتر این مفاهیم ارائه شده است:
1// مثالی جهت تغییر نوع داده متغیر در جاوا اسکریپت
2var string = “hello world”;
3string = 4;
4document.write(string); // .خروجی عدد 4 است
5document.write( ) will now print ‘4′ on the browser.
1// مثالی جهت تغییر نوع داده متغیر در جاوا
2int number = 45;
3number = “hello world”; // .تغییر متغیر در این خط باعث بروز خطا شده است
- جاوا اسکریپت یک زبان اسکریپت نویسی است، در حالی که جاوا یک زبان برنامه نویسی به حساب میآید. مانند زبانهای برنامه نویسی دیگر جاوا به یک کامپایلر جهت ساخت و اجرای برنامههایش احتیاج دارد، اما کدهای جاوا اسکریپت به وسیله مرورگرها خوانده و ویرایش میشوند.
- جاوا و جاوا اسکریپت در نحو ساختاری و نوشتاری (Syntax) تفاوتهای بسیاری دارند. این تفاوتها در دو مثال زیر ارائه شدهاند:
1// در جاوا «Hello World» مثالی جهت چاپ
2public class hello
3{
4 public static void main(String[] args)
5 {
6 System.out.println("Hello World");
7 }
8}
1// در جاوا اسکریپت «Hello World» مثالی جهت چاپ
2<script>
3 document.write("Hello World");
4</script>
- هر دو این زبانها شی گرا هستند، ولی جاوا اسکریپت یک زبان شی گرای جزئی (Partial Object Oriented Language) است، در حالی که جاوا یک زبان کاملأ شی گرا به حساب میآید. جاوا اسکریپت میتواند با اشیا و یا بدون آنها مورد استفاده قرار بگیرد، اما امکان استفاده از زبان جاوا بدون کلاس وجود ندارد.
Public Static Void main در جاوا چیست؟
تعریف «Public Static Void main» روش کنترل دسترسی (Access Modifier) به متد اصلی (main) در جاوا به حساب میآید. این روش دسترسی باید به صورت عمومی (Public) باشد تا در زمان اجرای (Runtime) جاوا بتواند متد را پیادهسازی کند. باید به این نکته توجه داشت که اگر متدی به صورت غیر عمومی ایجاد شود، امکان اجرای آن با هر برنامهای وجود ندارد و محدودیتهای دسترسی اعمال خواهد شد. بنابراین متد main باید حتما به صورت عمومی ایجاد شود.
در زمان اجرای برنامه در جاوا، هیچ کدام از اشیا کلاسها وجود ندارند. به همین دلیل است که متد main باید ثابت (استاتیک) باشد تا JVM بتواند کلاس را در حافظه بارگذاری و متد main را فراخوانی کند. اگر متد main ثابت نباشد، JVM نمیتواند آن را فراخوانی کند زیرا هیچ شیئی از کلاس وجود ندارد.
برنامه نویسی جاوا ملزم به این است که هر متدی دارای نوع بازگشتی (Return Type) باشد. متد main جاوا چیزی را بر نمیگرداند، به همین دلیل است که نوع بازگشتی آن «void» به معنی خالی به حساب میآید. این کار برای ساده نگه داشتن کارها انجام شده است زیرا پس از اتمام اجرای متد main، برنامه جاوا خاتمه مییابد. اگر قصد برگرداندن چیزی از متد main وجود داشته باشد، خطای کامپایل به عنوان مقدار برگشتی غیر منتظره (Unexpected Return Value) ایجاد میشود.
هدف از توالی در جاوا چیست؟
توالی شی (Object Serialization) در جاوا فرآیندی به حساب میآید که تبدیل حالت (State) یک شی به دنبالهای از بایتها را انجام میدهد. این دنبالهها میتوانند در دیسک یا فایلها باقی بمانند یا به وسیله شبکه به هر ماشین مجازی در حال اجرا جاوا دیگر ارسال شوند. فرآیندی که برای معکوس کردن توالی شی و تبدیل دنبالهای از بایتها به حالت استفاده میشود را «Deserialization» مینامند.
- مقاله پیشنهادی: دنباله سازی (Serialization) – به زبان ساده
تفاوت بین throw و throws در جاوا چیست؟
«Throw» کلمه کلیدی است که جهت کنترل یک استثنا صریح برنامه در داخل یک تابع یا بلوکی از کدها استفاده میشود. «Throws» کلمه کلیدی متفاوت دیگری به حساب میآید که در متد «Signature» جهت اعلان استثناهایی مورد استفاده قرار میگیرد که امکان دارند هنگام اجرای کدها توسط تابع ایجاد و ارسال شوند.
هدف اصلی بازیافت حافظه در زبان برنامه نویسی جاوا چیست؟
هدف اصلی از فرآیند بازیافت حافظه در جاوا آزاد کردن فضای حافظهای است که به وسیله حذف اشیا غیر ضروری و غیر قابل دسترسی در حین اجرای برنامه جاوا به دست میآیند. این فرآیند تضمین میکند که منابع به صورت کارآمد در حال استفاده هستند، اما ضمانت نمیکند که به طور قطع فضای کافی جهت اجرای برنامه جاوا وجود خواهد داشت. بازیافت حافظه در جاوا یک فرآیند خودکار به حساب میآید. در ادامه سوال کوتاه دیگری در رابطه با فرآیند بازیافت حافظه به عنوان آخرین سوال بخش سوالات مصاحبه برنامه نویسی جاوا مبتدی ارائه شده است.
کدام بخش از حافظه در فرآیند بازیافت حافظه پاک و آزاد میشود؟ (Stack یا Heap)
در فرآیند بازیافت حافظه در بخش «Heap» آزادسازی حافظه انجام میگیرد و «Stack» یا «پشته» نقشی در این فرآیند ندارد. در این بخش از مقاله «سوالات مصاحبه برنامه نویسی جاوا» سعی شد به بررسی اکثر سوالات مصاحبه جهت آمادگی برای شرکت در مصاحبه مبتدی و افراد تازهکار پرداخته شود. در ادامه این بخش به بررسی سوالات مصاحبه برنامه نویسی جاوا در سطح متوسط پرداخته شده است.
- مقاله پیشنهادی: پشته (Stack)، صف (Queue) و تجزیه عبارت — ساختار داده و الگوریتم ها
- مقاله پیشنهادی: ساختمان هیپ در درخت های دودویی — به زبان ساده
سوالات مصاحبه برنامه نویسی جاوا در سطح متوسط
در این بخش از مقاله «سوالات مصاحبه برنامه نویسی جاوا» به سوالات در سطح معمولی و متوسط این زبان برنامه نویسی پرداخته میشود. این سوالات جهت شرکت در مصاحبه شغلی برنامه نویسی جاوا و بالا بردن اطلاعات در زمینه زبان جاوا مورد استفاده قرار میگیرند.
همگام سازی در جاوا چیست؟
همگام سازی (Synchronization) پردازشی جهت رسیدگی به دسترسیهای منابع با استفاده از Threadهای چندگانه است. هدف اصلی همگام سازی جلوگیری از تداخل در Threadها به حساب میآید. زمانی که بیشتر از یک Thread سعی میکنند تا به منبعی مشترک دسترسی داشته باشند، باید اطمینان حاصل کرد که منبع تنها توسط یک Thread در زمانی مشترک مورد استفاده قرار میگیرد. فرآیندی که برای به دست آمدن این امر انجام میشود را همگام سازی مینامند. جهت ایجاد بلوکی از کدها برای همگام سازی از کلمه کلیدی «synchronization» استفاده میشود.
دلایل تغییر ناپذیری رشتهها در جاوا چیست؟ (به جز جنبههای امنیتی)
یک رشته به دلایل زیر به صورت تغییر ناپذیر (Immutable) تعریف میشود:
- مخزن رشته (String Pool): معمولاً نوع داده رشته به دفعات زیادی توسط برنامه نویسان و توسعه دهندگان جاوا استفاده میشود. بنابراین، آنها ایده استفاده از «String Pool» (مخزن ذخیرهسازی در Heap جاوا) را برای ذخیره کلمات String مطرح کردند. برنامه نویسان قصد داشتند به وسیله اشتراکگذاری، اشیا رشتهای موقت (Temporary String Object) را کاهش دهند. همچنین کلاسهای تغییر ناپذیری نیز جهت تسهیل کار اشتراکگذاری نیاز هستند. اشتراکگذاری ساختارهای قابل تغییر بین دو طرف درگیر ناشناخته غیر ممکن است. از این رو، رشتههای غیر قابل تغییر جاوا به اجرای مفهوم مخزن رشته کمک میکنند.
- چند نخی (Multithreading): امنیت نخها با توجه به اشیا رشتهها، یک جنبه مهم در زبان جاوا به حساب میآید. اگر اشیا رشتهها تغییر ناپذیر باشند، هیچ همگام سازی خارجی نیاز نیست. بنابراین، کدهای تمیزی میتوانند جهت اشتراکگذاری اشیا رشتهها مابین نخهای گوناگون نوشته شوند. در نهایت میتوان گفت که فرایند پیچیده همزمانی با این روش آسان میشود.
- کلکسیونها (Collection): در موضوع «Hashtable» و «HashMap»، کلید اشیا رشتهها هستند. اگر اشیا رشتهها تغییر ناپذیر نباشند، میتوانند در طول دورهای که در HashMapها قرار دارند، اصلاح شوند. در نتیجه، بازیابی دادههای مورد نظر امکانپذیر نیست. چنین حالتهایی که در حال تغییر هستند، خطرات زیادی را به همراه دارند. از این رو، ایجاد رشتهها به صورت تغییر ناپذیر کاملاً امن است.
کلکسیون در جاوا چیست؟
کلکسیونها در جاوا مانند ظرفهایی (Container) هستند که چندین مورد را در واحدی گروهبندی میکنند. به عنوان مثال، یک شیشه شکلات، لیست اسامی و سایر موارد را میتوان به عنوان نمونههایی از کلکسیون یا همان مجموعه در نظر گرفت. کلکسیونها در همه زبانهای برنامه نویسی استفاده میشوند. به عنوان نمونههایی از کلکسیونها در زبان جاوا میتوان کلاس، آرایه (Array)، بردار (Vector)، پشته (Stack) و «Hashtable» را نام برد.
چگونه hashmap به صورت داخلی در جاوا کار میکند؟
«HashMap» در جاوا بر اساس اصول هش کار میکند. این مفهوم یک ساختمان داده (Data Structure) است که امکان ذخیره شی و بازیابی آن را به شرط دانستن کلید در زمان O(1) میدهد. در هش کردن، از توابع هش برای پیوند (Link) کلید و مقدار در HashMap استفاده میشود.
StringBuffer ،String و StringBuilder چه تفاوتهایی با هم دارند؟
جهت پاسخ به این سوال در چند بخش گوناگون تفاوتهای «StringBuffer» ،«String» و «StringBuilder» مورد بررسی قرار میگیرند، در ادامه به بررسی و تعریف این بخشها پرداخته شده است.
- فضای ذخیرهسازی (Storage Area): در String، مخزن رشته به عنوان فضای ذخیرهسازی عمل میکند. در StringBuffer و StringBuilder حافظه «Heap» به عنوان فضای ذخیرهسازی به حساب میآید.
- تغییرپذیری (Mutability): Stringها تغییر ناپذیر هستند، اما StringBuffer و StringBuilder تغییر پذیرند.
- بهرهوری (Efficiency): این قابلیت در Stringها مقداری کُند عمل میکند و StringBuilder سریعترین نوع داده برای این عملکرد به حساب میآید. سرعت StringBuffer از String بیشتر و از StringBuilder کمتر است. برای مثال، اضافه کردن یک مقدار کاراکتر در StringBuilder سرعت بالایی و در نوع داده String سرعت بسیار پایینی دارد، زیرا مکان حافظه جدیدی جهت اضافه کردن کاراکتر جدید String نیاز است.
- «Thread Safe»: در محیطهای نخی (Threaded Environment)، از نوع داده StringBuffer و StringBuilder استفاده میشود ولی String اصلا در این محیطها کاربردی ندارد. با این حال، StringBuilder در محیطهای دارای یک نخ یا همان Thread مورد استفاده قرار میگیرد و StringBuffer در محیطهای چند نخی (Multiple Thread) استفاده میشود.
نحوه ساختاری و نوشتاری این سه نوع داده در کدهای زیر مشخص شده است:
1// String
2String first = "InterviewBit";
3String second = new String("InterviewBit");
4// StringBuffer
5StringBuffer third = new StringBuffer("InterviewBit");
6// StringBuilder
7StringBuilder fourth = new StringBuilder("InterviewBit");
- مقالات پیشنهادی:
چه چیزی HashSet را از TreeSet متمایز میکند؟
اگرچه هم «HashSet» و «TreeSet» هر دو همگام نیستند و وظیفه آنها اطمینان حاصل کردن از عدم وجود داده تکراری در فهرست است، ویژگیهای خاصی وجود دارند که HashSet را از TreeSet متمایز میکنند.
در ادامه برخی از این ویژگیها ارائه شدهاند.
- پیادهسازی: در HashSet، جدول هش برای ذخیرهسازی عناصر به صورت نامرتب استفاده میشود. با این حال، TreeSet از روش درخت سرخ-سیاره (Red-Black Tree) جهت ذخیره عناصر به گونهای مرتب استفاده میکند.
- پیچیدگی و کارایی: برای افزودن، بازیابی و حذف عناصر، پیچیدگی زمانی عملیات جاوا روی ساختمان داده برای HashSet مقدار O(1) به حساب میآید. پیچیدگی زمانی جهت انجام همان عملیات برای TreeSet مقداری بیشتر و برابر با O(log n) است. به طور کلی، کارایی HashSet در مقایسه با TreeSet سریعتر در نظر گرفته میشود.
- متدها: «()hashCode» و «()quals» متدهایی هستند که توسط HashSet برای مقایسه اشیا استفاده میشوند. برعکس، متدهای «()compareTo» و «()compare» توسط TreeSet برای کمک به مقایسه اشیا مورد استفاده قرار میگیرند.
- نوع اشیا: اشیا ناهمگن (Heterogeneous) و تهی (Null) را میتوان با کمک HashSet ذخیره کرد. اما در TreeSet هنگام درج اشیا ناهمگن یا تهی استثنای زمان اجرا رخ میدهد.
چرا آرایههای کاراکتری درج شده روی رشتهها جهت ذخیره اطلاعات محرمانه در جاوا ترجیح داده میشوند؟
در زبان برنامه نویسی جاوا رشتهها همیشه تغییر ناپذیر هستند و امکان تغییر و ویرایش آنها وجود ندارد. پس از اعلان یک رشته، تا زمانی که به صورت زباله از بین نرود، در مخزن رشته وجود خواهد داشت. به عبارت دیگر، رشتهها پس از پردازش و استفاده در اجرای یک برنامه، برای زمانی غیر قابل تنظیم و نامشخصی در بخش حافظه Heap میمانند.
در نتیجه، هکرها اگر به طور غیر قانونی به حافظه زباله دسترسی پیدا کنند، اطلاعات حیاتی را به دست میآورند. چنین خطراتی را میتوان به وسیله اشیا قابل تغییر یا ساختارهایی مانند آرایههای کاراکتری برای ذخیره هر شی کاهش داد. در نهایت میتوان گفت، این روشها به صرفهجویی در حافظه Heap کمک میکنند و همچنین به هکرها هیچ فرصتی برای استخراج دادههای حیاتی نمیدهند.
تفاوتهای بین JVM ،JRE و JDK در جاوا چیست؟
جهت پاسخ به این پرسش که JVM ،JRE و JDK چه تفاوتهایی با هم دارند، در این بخش به صورت خلاصه مفهوم و هدف «JVM» ،«JRE» و «JDK» مورد بررسی قرار میگیرند.
- «JDK» که سرنامی برای عبارت «Java Development Kit» به حساب میآید، یک کیت نرم افزاری توسعه کامل برای توسعه اپلیکیشنهای جاوا است. این کیت شامل کامپایلر «JRE» ،«JavaDoc» و اشکالیابها (Debugger) و سایر موارد میشود.
- «JRE» سرنامی برای عبارت «Java Runtime Environment» به معنی «محیط زمان اجرا جاوا» است. این محیط، بسته نرم افزاری به حساب میآید که کتابخانههای کلاس جاوا، «JVM» و همه مؤلفههای مورد نیاز جهت اجرای برنامههای جاوا را فراهم میکند.
- «JVM» که مخفف عبارت «Java Virtual Machine» است، یک ماشین انتزاعی وابسته به پلتفرم همراه با سه ویژگی به حساب میآید. این ویژگیها شامل «سندی که الزامات پیادهسازی JVM را توصیف میکنند»، «برنامه کامپیوتری که الزامات JVM را برآورده میکند و شی نمونه جهت اجرای بایتکد جاوا» و «فراهم کردن محیط زمان اجرا برای پیادهسازی برنامهها» میشود.
- هدف اصلی JDK به طور عمده استفاده از آن جهت توسعه و اجرای کدها است. JRE معمولا برای ایجاد محیطی جهت اجرای کدها استفاده میشود و JVM مشخصات همه پیادهسازیها را در JRE ارائه میدهد.
- JDK ابزارهایی مانند کامپایلر، اشکالیاب و سایر موارد را برای توسعه کدها و همچنین JRE به وسیله JVM کتابخانهها و کلاسهای مورد نیاز را جهت پیادهسازی برنامه در جاوا فراهم میکنند. JVM شامل هیچ ابزاری نمیشود اما در عوض، مشخصاتی را برای پیادهسازی کدها ارائه میدهد.
- مقاله پیشنهادی: چگونه بدون JRE برنامههای جاوا را روی سیستم اجرا کنیم؟
تفاوت بین کلاس HashMap و HashTable در جاوا چیست؟
در پاسخ به این سوال تفاوتهای «HashMap» و «HashTable» به طور خلاصه ارائه شدهاند.
- کلاس HashMap همگام نیست و در نتیجه از آن بیشتر در برنامههای غیر نخی استفاده میشود. کلاس HashTable همگام سازی شده است و از این رو برای برنامههای دارای thread مناسب به حساب میآید.
- کلاس HashMap دارای فقط یک کلید تهی است اما میتواند مقادیر تهی زیادی دریافت کند. کلاس HashTable اجازه استفاده از تهی را به عنوان کلید و مقادیرش ندارد.
- ضمانتی برای درج با ترتیب در کلاس HashTable وجود ندارد. اما کلاس HashMap با استفاده از زیر کلاس «LinkedHashMap»، از ترتیب درج پشتیبانی میکند.
چه مواردی از بازتابی در جاوا اهمیت بالایی دارند؟
اصطلاح بازتابی (Reflection) جهت بازرسی کدهایی از برنامه و تاثیر آن بر روی کدهای دیگر خود و اصلاح کدها در طول زمان اجرا استفاده میشود. برای مثال، اگر شئی از نوع دادهای ناشناخته در نظر گرفته شود، متدی مانند «()fooBar» نیز در برنامه وجود داشته باشد که باید برای شی مورد نظر فراخوانی شود. سیستم تایپ ایستا جاوا (Static Typing System of Java) اجازه فراخوانی این متد را نمیدهد مگر اینکه نوع شی از قبل مشخص باشد.
این نوع از برنامهها را میتوان با استفاده از «Reflection» پیادهسازی کرد. روش بازتابی به کدها این امکان را میدهد تا شی اسکن شود و تشخیص دهند که آیا متدی به نام ()fooBar در جاوا وجود دارد یا خیر و در نهایت تنها در صورت نیاز متد را فراخوانی میکند. کدهای زیر نشان دهنده این مثال هستند.
1Method methodOfFoo = fooObject.getClass().getMethod("fooBar", null);
2methodOfFoo.invoke(fooObject, null);
استفاده از بازتابی معایبی نیز دارد که در ادامه به بررسی آنها پرداخته شده است:
- فراخوانی متدها با استفاده از روش بازتاب تقریباً سه برابر کندتر از فراخوانی روش به صورت مستقیم است.
- هنگامی که یک متد با استفاده از مرجع خود به اشتباه با استفاده از روش بازتابی فراخوانی میشود، فراخوانی در زمان اجرا با شکست مواجه خواهد شد زیرا در زمان کامپایل یا بارگذاری، متد شناسایی نمیشود.
- هر زمان که روش بازتابی با خطا مواجه شود، یافتن ریشه اصلی این خطا به دلیل وجود یک پشته بزرگ بسیار دشوار است. برای شناسایی ریشه اصلی خطا بازتابی باید در لاگهای متد «()invoke» و «()proxy» بررسی عمیقی انجام گیرد.
بدین ترتیب، توصیه میشود راهحلهایی دنبال شوند که مستلزم تأمل نیستند و استفاده از این روش به عنوان آخرین راهحل، مناسب است.
تفاوت بین سازنده و متد در کلاسهای جاوا چیست؟
برای پاسخ به این سوال، در ادامه به تفاوتهای سازندهها و متدها در کلاس پرداخته میشود.
- سازنده برای مقداردهی اولیه نوع شی مورد استفاده قرار میگیرد و از متدها جهت نمایش رفتار شی استفاده میشود.
- سازنده نوع بازگشتی ندارد. متد باید یک نوع بازگشتی داشته باشد، حتی اگر چیزی را برنگرداند، دارای نوع بازگشتی «void» است.
- سازندهها به طور ضمنی فراخوانی میشوند. اما متدها باید با صراحت روی شی فراخوانی شوند.
- اگر سازندهای برای برنامه جاوا تعریف نشده باشد، یک سازنده پیشفرض توسط کامپایلر جاوا استفاده میشود. اگر متدی تعریف نشده باشد، کامپایلر آن را فراهم نمیکند.
- نام سازنده باید با نام کلاس برابر باشد. نام متد میتواند هر نامی و حتی مانند نام کلاس باشد.
- یک سازنده نمیتواند به عنوان نوع نهایی کننده در نظر گرفته شود، زیرا هر زمان که از کلاسی ارث بری شود، سازندهها به ارث برده نمیشوند. از این رو، در نظر گرفتن آن به صورت نهایی منطقی نیست. در این حالت جاوا خطای کامپایل «modifier final not allowed here» را به معنی «اصلاح کننده نهایی در اینجا مجاز نیست» میدهد. متدها را میتوان به صورت نهایی تعریف کرد، اما نمیتوان آنها را در زیر کلاس رونویسی کرد.
- استفاده از نوع نهایی برای متغیرهای نمونه در داخل سازندهها امکان پذیر است و این موضوع برای کل کلاس و اشیا آن میتواند اعمال شود. متغیر نهایی اگر در داخل یک متد مقداردهی اولیه شود، تضمین میکند که متغیر فقط در محدوده همان متد تغییر نمیکند.
جاوا به صورت «pass by value» یا «pass by reference» کار میکند؟
زبان جاوا همیشه به صورت «Pass by Value» به معنی «ارسال به وسیله مقدار» عمل میکند و هیچ چیزی به نام «Pass by Reference» به معنی «ارسال به وسیله مرجع» در جاوا وجود ندارد. با این حال زمانی که شی به متد ارسال میشود، به دلیل نوع مدیریت شی (Object Handling) در جاوا، آدرس مقدار شی ارسال شده است. زمان ارسال شی، یک کپی از مرجع نیز توسط جاوا ایجاد و به متد ارسال میشود.
اشیا به محل ذخیره خود در حافظه اشاره میکنند. امکان بروز دو مورد مهم در متد وجود دارد:
- زمانی که شی به یک مکان دیگر اشاره میکند: در این حالت، تغییرات ایجاد شده در آن شی، قبل از ارسال آن به متد به عنوان مرجع و انتقال به مکان دیگر، تاثیری روی شی اصلی ندارد. برای مثال کدهای زیر ارائه شدهاند.
1class InterviewBitTest{
2 int num;
3 InterviewBitTest(int x){
4 num = x;
5 }
6 InterviewBitTest(){
7 num = 0;
8 }
9}
10class Driver {
11 public static void main(String[] args)
12 {
13 // ایجاد مرجع
14 InterviewBitTest ibTestObj = new InterviewBitTest(20);
15 // updateObject ارسال مرجع به متد
16 updateObject(ibTestObj);
17 // updateObject پس از اجرای متد
18 // .در شی بررسی میشود num مقدار
19 System.out.println(ibTestObj.num);
20 }
21 public static void updateObject(InterviewBitTest ibObj)
22 {
23 // .شی به مرجع جدید اشاره میکند
24 ibObj = new InterviewBitTest();
25 // .مقدار شی بروز رسانی میشود
26 ibObj.num = 50;
27 }
28}
29Output:
3020
- وقتی ارجاعات شی اصلاح نمیشوند: در این حالت، تا زمانی که یک کپی از مرجع شی اصلی وجود داشته باشد و به مکان یکسانی از حافظه اشاره کند، هر تغییری روی محتوای این شی، روی شی اصلی تاثیر میگذارد. کدهای زیر جهت درک بهتر این موضوع ارائه شدهاند.
1class InterviewBitTest{
2 int num;
3 InterviewBitTest(int x){
4 num = x;
5 }
6 InterviewBitTest(){
7 num = 0;
8 }
9}
10class Driver{
11 public static void main(String[] args)
12 {
13 // ایجاد مرجع
14 InterviewBitTest ibTestObj = new InterviewBitTest(20);
15 // updateObject ارسال مرجع به متد
16 updateObject(ibTestObj);
17 // updateObject پس از اجرای متد
18 // .در شی بررسی میشود num مقدار
19 System.out.println(ibTestObj.num);
20 }
21 public static void updateObject(InterviewBitTest ibObj)
22 {
23 // .در مکان جدید ایجاد نمی شود ibObj هیچ تغییری برای اشاره به
24 // .بروز رسانی میشود num مقدار شی
25 ibObj.num = 50;
26 }
27}
28Output:
2950
زمانی که نیاز است بروز رسانیهای زیادی در دادهها انجام شود، بین نوع داده String و String Buffer کدام ترجیح داده میشود؟
نوع داده «StringBuffer» به صورت پیشفرض تغییر پذیر و پویا است و «String» همانطور که در بخشهای قبلی نیز مورد بررسی قرار گرفت، نوع دادهای تغییر ناپذیر به حساب میآید. هر به روز رسانی و تغییر در String، باعث ایجاد String جدیدی میشود و در نتیجه مخزن رشتهها با اشیا غیر ضروری پر شده است. از این رو، اگر تعداد بروز رسانیها در برنامهای زیاد باشد، معمولاً ترجیح داده میشود که از StringBuffer استفاده شود. این نوع داده، سربار (Overhead) ایجاد شده توسط چندین String در مخزن رشته را کاهش میدهد.
چطور از توالی ویژگیهای کلاس در جاوا جلوگیری کرد؟
برای جلوگیری از توالی ویژگیهای کلاس در جاوا میتوان از کلمه کلیدی «transient» استفاده کرد. در کدهای زیر روش استفاده از این کلمه کلیدی نشان داده شده است.
1public class InterviewBitExample {
2
3 private transient String someInfo;
4 private String name;
5 private int id;
6 // :
7 // متدهای تنظیم کننده و گیرنده
8 // :
9}
در مثال فوق، همه فیلدها به جز «someInfo» از توالی ویژگیهای کلاس در جاوا پیروی میکنند.
اگر تغییر دهنده ایستا در کدهای شناسایی متد اصلی جاوا ایجاد نشود، احتمال وقوع چه اتفاقی وجود دارد؟
در صورتی که تغییر دهنده ایستا (Static Modifier) در کدهای شناسایی (Signature) متد اصلی جاوا وجود نداشته باشد، هیچ خطای کامپایلی وجود نخواهد داشت. اما هنگامی که برنامه اجرا میشود، تا زمانی که «JVM» نتواند به کدهای شناسایی متد اصلی دسترسی پیدا کند، کدها خطای «NoSuchMethodError» را در زمان اجرا نشان میدهند.
اگر چندین متد اصلی در یک کلاس وجود داشته باشند، چه اتفاقی رخ میدهد؟
اگر در یک کلاس جاوا چندین متد اصلی یا همان «main» تعریف شود، برنامه کامپایل نمیشود. در این حالت کامپایلر اعلام میکند که این متد قبلا در داخل کلاس تعریف شده است.
شبیهسازی شی در جاوا چیست و چطور انجام میشود؟
به فرآیندی که در جاوا کپی دقیقی از شی را ایجاد میکند، شبیهسازی شی در جاوا (Object Cloning) گفته میشود. برای انجام این منظور، کلاس جاوا واسط «Cloneable» از بسته «java.lang» را پیادهسازی میکند. همچنین، متد «()clone» که با استفاده از شی کلاس ایجاد شده رونویسی میشود. در کدهای این روش نمایش داده شده است.
1protected Object clone() throws CloneNotSupportedException{
2 return (Object)super.clone();
3}
در صورتی که واسط «Cloneable» پیادهسازی نشود، فقط متد رونویسی شود. در نتیجه «CloneNotSupportedException» در جاوا نمایش داده میشود.
چگونه یک استثنا در کدهای جاوا ایجاد میشود؟
زمانی که در برنامه جاوا استثنا رخ میدهد، ابتدا روند جستجویی جهت یافتن یک بلوک «Catch» در جاوا ایجاد میشود. اگر بلوک Catch در مکانی درست وجود داشته باشد، این بلوک اجرا خواهد شد. در غیر این صورت، استثنا به وسیله پشته فراخوانی متد ایجاد و از بالا به پایین به متدهای فراخوانی شدهای ارسال میشود که در آنها فرآیند تطبیق بلوک Catch وجود داشته باشد.
روند تکثیر استثنا تا زمانی انجام میگیرد که بلوک Catch برای انطباق پیدا شود. اگر این بلوک پیدا نشود، فرآیند در متد اصلی خاتمه مییابد.
آیا اجباری برای وجود یک بلوک Catch بعد از بلوک Try در جاوا وجود دارد؟
خیر؛ اجباری جهت وجود یک بلوک Catch پس از بلوک Try در جاوا وجود ندارد. بلوک Try نیاز است که بعد از یک بلوک Catch یا بلوک نهایی (Finally) ایجاد شود. در نهایت، اگر احتمال استثنا در برنامه جاوا زیاد باشد، باید با استفاده از شرط کنترل استثنا متدها اعلان شوند.
آیا زمانی که عبارت Return در انتهای بلوک Try و بلوک Catch مانند کدهای زیر نوشته میشود، بلوک نهایی اجرا خواهد شد؟
1public int someMethod(int i){
2 try{
3 // دستورات برنامه
4 return 1;
5 }catch(Exception e){
6 // دستورات برنامه
7 return 999;
8 }finally{
9 // دستورات بلوک نهایی
10 }
11}
بلوک نهایی، در هر صورت و با وجود و یا عدم وجود استثنا اجرا خواهد شد. تنها زمانی که بلوک نهایی اجرا نمیشود در مواجهه با متد «()System.exit» در بلوکهای Catch و Try است.
آیا میتوان یک سازنده از کلاس را در داخل سازنده دیگری فراخوانی کرد؟
بله؛ یک سازنده از کلاس را در داخل سازنده دیگری میتوان فراخوانی کرد و به این مفهوم زنجیرهسازی سازنده (Constructor Chaining) گفته میشود. زنجیرهسازی سازنده با استفاده از متد «()this» انجام میگیرد، در تصویر کدهای زیر نمونهای از این روش ارائه شده است.
چرا مکانهای حافظه پیوسته معمولاً برای ذخیره مقادیر واقعی در آرایهها استفاده میشوند و در لیست آرایه قرار نمیگیرند؟
در «Array List» یا همان لیست آرایه، ذخیره دادهها در نوع دادههای اولیه مانند integer ،Float و سایر موارد امکانپذیر نیست. اعضا یا اشیا دادههای موجود در لیست آرایه دارای ارجاعات به اشیایی هستند که در محلهای مختلف حافظه قرار دارند.
بدین ترتیب، ذخیره اشیا واقعی با نوع داده غیر اولیه مانند Double و سایر موارد در مکانهای مختلف و غیر پیوسته حافظه رخ میدهد. در تصویر زیر نوع ذخیره اشیا در لیست آرایه مشاهده میشود.
با این حال، روش عملکرد آرایهها متفاوت است و به صورت دیگری اعضا داده در آن قرار میگیرند. اشیا یا انواع داده از نوع اولیه میتوانند در مکانهای آرایه به صورت پیوسته ذخیره شوند، بنابراین هیچ عنصری نیازی به ارجاع به عنصر بعدی ندارد. در تصویر زیر نوع ذخیرهسازی دادهها در آرایه نشان داده شده است.
در این بخش از مقاله «سوالات مصاحبه برنامه نویسی جاوا» به بررسی سوالات مصاحبه جهت آمادگی برای شرکت در مصاحبه افرادی پرداخته شد که با زبان جاوا در سطح متوسط آشنا هستند. در ادامه این مقاله به بررسی سوالات مصاحبه برنامه نویسی جاوا در سطح پیشرفته پرداخته میشود.
سوالات مصاحبه برنامه نویسی جاوا در سطح پیشرفته
در این بخش از مقاله «سوالات مصاحبه برنامه نویسی جاوا» به سوالات مصاحبه جاوا در سطح پیشرفته برای افراد با تجربه پرداخته میشود.
چرا با اینکه وراثت مفهوم محبوبی در برنامه نویسی شی گرا به حساب میآید، مزایای کمتری نسبت به مفهوم Composition در جاوا دارد؟
با توجه به دلایل زیر «Composition» نسبت به ارث بری بهتر عمل میکند و از ارث بری پیشی گرفته است:
- وراثت چندگانه در زبان جاوا پشتیبانی نمیشود و امکانپذیر نیست. کلاسها فقط با استفاده از یک سوپر کلاس میتوانند گسترش یابند. بنابراین، گاهی زمانی که چندین قابلیت نیاز است مانند خواندن و نوشتن اطلاعات در یک فایل، الگوی «Composition» ترجیح داده میشود. با در نظر گرفتن عملکردها به عنوان اعضای خصوصی، عملکرد نوشتن به خوبی خواندن در Composition انجام میگیرد.
- مفهوم Composition به داشتن انعطاف بالا در برنامه و جلوگیری از شکست کپسوله سازی کمک میکند.
- انجام تست واحد (Unit Test) در روش Composition امکانپذیر است و در وراثت این امکان وجود ندارد. در روش Composition زمانی که توسعهدهندهای قصد دارد کلاسی که از کلاس دیگری تشکیل شده است را تست کند، یک شی ساختگی (Mock Object) برای نشان دادن کلاس ترکیبی و تسهیل در تست استفاده میشود. این روشها به دلیل اینکه کلاس مشتق شده را در روش وراثت بدون کمک سوپر کلاس خود نمیتوان تست کرد، امکانپذیر نیستند.
- مفهوم اتصال سست (Loosely Coupled) در Composition نسبت به اتصال سخت ( Tightly Coupled) در وراثت ارجحیت دارد.
در ادامه مثالی در رابطه با مفهوم وراثت و Composition ارائه شده است:
1package comparison;
2public class Top {
3public int start() {
4 return 0;
5}
6}
7class Bottom extends Top {
8 public int stop() {
9 return 0;
10 }
11}
در کدهای فوق، وراثت انجام گرفته است. در مثال زیر تغییراتی روی کدهای کلاس «Top» صورت میپذیرد:
1public class Top {
2 public int start() {
3 return 0;
4 }
5 public void stop() {
6 }
7}
در پیادهسازی جدید کلاس «Top» در کدهای فوق یک خطای زمان اجرا در کلاس «Bottom» اتفاق میافتد و همچنین نوع بازگشتی ناسازگاری برای تابع «()Top.stop» وجود دارد. برای به وجود آمدن سازگاری، این تغییرات باید روی هر دو کلاس Top و Bottom انجام گیرند. با این حال، جهت برطرف شدن این مشکل از روش Composition نیز به صورت زیر میتوان استفاده کرد.
1class Bottom {
2 Top par = new Top();
3 public int stop() {
4 par.start();
5 par.stop();
6 return 0;
7 }
8}
ایجاد یک رشته در زبان جاوا با استفاده از ()new چه تفاوتی با ایجاد رشته از طریق لیترال دارد؟
زمانی که یک رشته به شکل لیترال (Literal) به کمک عملگرهای تخصیصی (Assignment Operator) ایجاد میشود، راه خود را به مخزن ثابت رشته باز میکند تا «ورود رشته» (String Interning) انجام گیرد. در روش لیترال، اگر محتوایی برای دو رشته یکسان باشد، این شی مشابه در «Heap» توسط یک رشته متفاوت ارجاع داده میشود.
مثال زیر روش استفاده از لیترال را نشان میدهد.
1public bool checking() {
2String first = "FaraDars";
3String second = "FaraDars";
4if (first == second)
5 return true;
6else
7 return false;
8}
در کدهای فوق، تابع «()checking» کلمه «True» را برمیگرداند، زیرا یک محتوا یکسان توسط دو متغیر ارجاع داده شده است. در تصویر زیر روش ایجاد رشته توسط لیترال ارائه میشود.
برعکس، وقتی ایجاد رشته به وسیله عملگر «()new» انجام میشود، «ورود رشته» انجام نمیگیرد. در این حالت حتی اگر شئی با همان محتوا در حافظه Heap وجود داشته باشد، باز هم شی جدید در این حافظه ایجاد خواهد شد. کدهای زیر مثال مرتبط با این مسئله را نشان میدهند.
1public bool checking() {
2String first = new String("FaraDars");
3String second = new String("FaraDars");
4if (first == second)
5 return true;
6else
7 return false;
8}
در مثال فوق، تابع «()checking» کلمه «False» را برمیگرداند، زیرا محتوای یکسان توسط هر دو متغیر ارجاع داده نشده است.
آیا محدودیت حافظه در یک برنامه، حتی با وجود روش بازیافت حافظه، امکانپذیر است؟
بله؛ امکان پر شدن حافظه حتی با وجود روش بازیافت حافظه وجود دارد. بازیافت حافظه به شناسایی و حذف اشیایی کمک میکند که دیگر در برنامه جاوا مورد استفاده قرار نمیگیرند، با این رویکرد جایی که این اشیا اشغال کردهاند مجددا به عنوان فضای قابل استفاده برنامه آزاد میشود.
در برنامه اگر شئی غیر قابل دسترس باشد، روش بازیافت حافظه برای از بین بردن آن شی انجام میگیرد. همچنین اگر در برنامه، مقدار حافظه مورد نظر برای ایجاد یک شی جدید وجود نداشته باشد، روش بازیافت حافظه اشیایی را که دیگر مورد استفاده قرار نمیگیرند جهت آزادسازی حافظه برای ایجاد شی جدید حذف میکند. هنگامی محدودیت حافظه در برنامه رخ میدهد که فضای حافظه ایجاد شده به وسیله بازیافت حافظه برای ایجاد شی جدید کافی نباشد.
علاوه بر این، اگر اشیا به گونهای ایجاد شوند که در حافظه باقی بمانند و آن را مصرف کنند. حافظه Heap به مرور زمان دچار فرسودگی میشود. برنامه نویس باید از قطع ارجاع شی پس از اتمام کار اطمینان حاصل کند. اگرچه رویکرد بازیافت حافظه همیشه سعی بر این دارد تا حافظه را تا حد امکان بازیابی و فضاهای موجود را آزاد کند، اما همچنان امکان ایجاد محدودیتهای حافظه وجود دارد. مثال زیر جهت نشان دادن این موضوع ارائه شده است:
1List<String> example = new LinkedList<String>();
2while(true){
3example.add(new String("Memory Limit Exceeded"));
4}
دلیل ضرورت همگام سازی چیست؟ (با مثال توضیح داده شود.)
اجرای همزمان فرآیندهای مختلف به وسیله همگام سازی در برنامه نویسی جاوا امکانپذیر است. زمانی که یک منبع خاص بین چندین Thread به اشتراک گذاشته میشود، امکان ایجاد شرایطی وجود دارد که در آن چندین Thread به یک منبع مشترک نیاز دارند.
در این شرایط همگام سازی به حل این مسئله کمک میکند و منبع در هر زمان توسط یک Thread به اشتراک گذاشته میشود. برای مثال، نیاز است که تعداد درخواستهای ارسالی به یک نشانی وب (Uniform Resource Locator | URL) محاسبه شوند، در این حالت دو درخواست همزمان میتواند محاسبه شمارش را نامنظم کند. کدهای این مثال که تا به این بخش بدون همگام سازی هستند در ادامه ارائه شدهاند:
1package anonymous;
2public class Counting {
3 private int increase_counter;
4 public int increase() {
5 increase_counter = increase_counter + 1;
6 return increase_counter;
7 }
8}
زمانی که «Thread T1» مقدار ۱۰ را نشان میدهد، به این معنی است که مقدار شمارش از یک تا ۱۱ افزایش خواهد داشت. به طور همزمان، اگر «Thread T2» نیز مقدار ۱۰ را نشان دهد، مقدار شمارش این Thread نیز بین یک تا ۱۱ افزایش داشته است. بدین ترتیب، ناهماهنگی در تعداد مقادیر ایجاد میشود زیرا مقدار نهایی مورد انتظار برنامه 12 است اما مقدار نهایی واقعی 11 خواهد بود. اکنون، در مثال بعدی تابع «()increase» به صورت همگام سازی شده ایجاد میشود بنابراین، دسترسی همزمان در این مثال امکانپذیر نیست.
1package anonymous;
2public class Counting {
3 private int increase_counter;
4 public synchronized int increase() {
5 increase_counter = increase_counter + 1;
6 return increase_counter;
7 }
8}
اگر در مثال فوق، «Thread T1» مقدار ۱۰ را نشان دهد، به این معنی است که مقدار شمارش از یک تا ۱۱ افزایش خواهد داشت. سپس، «Thread T2» مقدار ۱۱ را نشان میدهد، یعنی مقدار شمارش از یک تا ۱۲ افزایش مییابد. بنابراین ثبات در مقادیر ایجاد میشود.
آیا میتوان چرخه حیات Thread در جاوا را توضیح داد؟
چرخه حیات نخ یا همان «Thread» در جاوا (Java Thread Life Cycle) دارای مراحلی است که در ادامه بررسی شدهاند:
- جدید (New): وقتی که نمونهای از Thread ایجاد میشود و متد «()start» فراخوانی نشده است. Thread به صورت زنده و در حالت «جدید» یا همان «NEW» در نظر گرفته میشود.
- قابل اجرا (Runnable): قبل از فراخوانی متد «()run» توسط ماشین مجازی جاوا، زمانی که متد «()start» فراخوانی میشود، Thread در حالت قابل اجرا (آماده برای اجرا) قرار میگیرد. همچنین یک Thread میتواند از حالت انتظار (Waiting) یا خواب (Sleeping) وارد این حالت شود.
- در حال اجرا (Running): زمانی که متد «()run» فراخوانی میشود و Thread شروع به اجرا میکند، Thread در حالت اجرا قرار میگیرد.
- غیر قابل اجرا (Non-Runnable): زمانی یک Thread غیر قابل اجرا در نظر گرفته میشود که در حالت مسدود شده (Blocked) یا انتظار قرار داشته باشد. اگر Thread با جود داشتن حالت زنده، باز هم قادر به اجرا نباشد یعنی این Thread در حالت غیر قابل اجرا قرار گرفته است. در وضعیت ایدهآل پس از مدتی با قرار گرفتن در حالت زنده، Thread به حالت قابل اجرا تغییر حالت میدهد. در ادامه به دو حالتی پرداخته شده است که در این بخش ایجاد میشوند.
- اگر یک Thread قصد ورود به یک برنامه همگام سازی شده را داشته باشد، اما انجام این کار به دلیل وجود یک Thread دیگر در بلوک همگام سازی شده همان شی امکانپذیر نباشد، به اصطلاح گفته میشود که Thread در حالت «مسدود شده» قرار گرفته است. Thread اول جهت پیادهسازی، تا زمانی که اجرای Thread دوم موجود در بلوک همگام سازی شده خاتمه نیافته است باید صبر کند.
- اگر Threadی منتظر سیگنالی از طرف یک Thread دیگر جهت پیادهسازی باشد یعنی برای شروع کار منتظر دریافت سیگنالی است و در این موقعیت به اصطلاح گفته میشود که Thread در حالت «انتظار» قرار گرفته است.
- خاتمه یافته (Terminated): زمانی که متد «()run» به طور کامل پیادهسازی میشود، Thread وارد مرحله «خاتمه یافته» شده است و وارد حالت غیر زنده میشود.
فلوچارت زیر به صورت کاملاً واضح چرخه حیات Thread در جاوا را توضیح و نشان میدهد.
تفاوت استفاده از آرایه نامرتب و آرایه مرتب در چه چیزی میتواند باشد؟
مزیت اصلی استفاده از آرایه مرتب در جاوا این است که پیچیدگی زمانی جستجو را به «(log n)O» کاهش میدهد، با اینکه پیچیدگی زمانی هنگام استفاده از آرایههای نامرتب «(n)O» است. مشکل اصلی آرایههای مرتب در جاوا افزایش زمان درج با پیچیدگی زمانی «O(n)» به حساب میآید.
زیرا عنصرهای آرایه جهت ایجاد ترتیب در آرایه در حین درج، باید مرتب شوند. این درحالی است که پیچیدگی زمانی در آرایههای نامرتب «O(1)» است. استفاده این مواردی که درباره آرایهها ارائه شدند، به نیاز برنامه نویس و انتخاب نوع ساختمان داده برای پیادهسازی کدها بستگی دارد.
آیا امکان وارد کردن مجدد یک کلاس یا بسته مشابه در جاوا برای بار دوم وجود دارد؟ اگر این کار انجام شود، چه اتفاقی میافتد؟
این امکان وجود دارد که کلاس یا بسته (پکیج) برای چندمین بار وارد یک برنامه شوند. با این حال، انجام این کار بیهوده و اضافی است زیرا ماشین مجازی جاوا فقط یک بار کلاس یا پکیج را در برنامه بارگذاری میکند.
واسط نشانگر در جاوا چیست؟
واسطهای نشانگر یا همان «Marker Interface» به عنوان واسطهای برچسبگذاری (Tagging Interface) نیز شناخته میشوند و واسطهایی هستند که هیچ متد و مقدار ثابتی در آنها تعریف نشده است. این واسطها برای کمک به کامپایلر و ماشین مجازی جاوا جهت دریافت اطلاعات زمان اجرا با توجه به اشیا مورد استفاده قرار میگیرند.
چطور یک کلاس تغییر ناپذیر در جاوا میتوان ایجاد کرد؟
برای ایجاد یک کلاس تغییر ناپذیر (Immutable Class) در زبان برنامه نویسی جاوا، مراحل زیر طی میشوند:
- کلاس به عنوان کلاس نهایی کننده (Final) تعریف میشود تا امکان گسترش دادن آن وجود نداشته باشد.
- همه فیلدها به صورت خصوصی ایجاد میشوند، بنابراین دسترسی مستقیم به آنها وجود ندارد.
- متد تنظیم کننده (Setter) برای متغیرها فراهم نمیشود.
- همه فیلدهای قابل تغییر به حالت Final تبدیل میشوند تا مقدار آنها فقط یک بار تخصیص داده شود.
- تمام فیلدها به وسیله سازندهای مقداردهی اولیه میشوند که کپی عمیق (Deep Copy) را انجام میدهد.
- ایجاد شبیهساز (Clone) از اشیا در متد گیرنده (Getter)، برای اینکه یک کپی به جای مرجع واقعی شی برگردانده شود.
Classloader در جاوا چیست؟
«Classloader» یا همان کلاس لودر یک زیر سیستم (Subsystem) برای «JVM» است که جهت بارگذاری فایلهای کلاس مورد استفاده قرار میگیرد. در زمان اجرای یک برنامه در جاوا، ابتدا برنامه با استفاده از Classloader بارگذاری میشود.
سه نوع Classloader پیشساخته در زبان برنامه نویسی جاوا وجود دارد که در ادامه به بررسی آنها پرداخته شده است.
- Bootstrap ClassLoader: کلاس لودرها ساختاری سلسله مراتبی دارند و کلاس لودر «Bootstrap» اولین کلاس لودر و سوپر کلاس «Extension Classloader» به حساب میآید. این لودر فایل «rt.jar» را بارگذاری میکند که شامل همه کلاسهای نسخه استاندارد جاوا (Java Standard Edition) از جمله کلاسهای بسته java.lang ،java.net ،java.util ،java.io ،java.sql و سایر موارد میشوند.
- Extension ClassLoader: این کلاس لودر فرزند کلاس لودر Bootstrap است و والد کلاس لودر سیستم یا اپلیکیشن به حساب میآید. کلاس لودر «Extension» فایلهای «jar» واقعی را مانند دایرکتوریهای JAVA_HOME ،jre ،lib ،ext و سایر موارد بارگذاری میکند.
- ClassLoader سیستم یا عملکرد: این کلاس لودر فرزند «Extension ClassLoader» است. کلاس لودر سیستم یا عملکرد فایلهای کلاس «Classpath» را بارگذاری میکند. به صورت پیشفرض، Classpath روی فهرست فعلی تنظیم شده است و میتوان آن را با استفاده از «cp-» یا «classpath-» تغییر داد. به همین دلیل به این کلاس لودر، کلاس لودر عملکرد نیز گفته میشود.
تفاوت بین استثنا بررسی شده و بررسی نشده در جاوا چیست؟
استثنا بررسی شده (Checked Exception) توسط کامپایلر در زمان کامپایل بررسی میشود. در یک متد کنترل استثناهای «Checked» قرار دادن آنها در بخش اسثناهای کنترل شده اجباری است. استثناهای بررسی شده، جزئی از زیر کلاس استثنا هستند اما به وسیله استثنا زمان اجرا (Runtime Exception) ایجاد نمیشوند. استثناهای بررسی نشده (Unchecked Exception) فرزند استثنای زمان اجرا به حساب میآیند و در زمان کامپایل توسط کامپایلر بررسی نمیشود. این سوال یکی از سوالهایی به شمار میرود که دارای محبوبیت کمتری نسبت به دیگر سوالها است.
به این ترتیب، در این مقاله سعی شد تا حد امکان به طور جامع سوالات مصاحبه برنامه نویسی جاوا از سطوح مبتدی تا پیشرفته مورد بررسی قرار گیرند.
جمعبندی
جاوا یکی از زبانهای برنامه نویسی سطح بالا و ساده به حساب میآید که ابزارهای قدرتمندی را فراهم میکند و استانداردهای چشمگیر مورد نیاز برای توسعه برنامهها را دارا است. این زبان یکی از اولین زبانهایی است که از Threadها جهت مقابله با مشکلات همزمانی (Concurrency Based Problem) پشتیبانی میکند. ساختار نوشتاری ساده و ویژگیهای از پیش ساخته شده در جاوا باعث ایجاد ثباتی میشوند که دلیل اصلی استفاده روز افزون از این زبان برنامه نویسی هستند.
با توجه به بازار کار امروزی، مشخص است که برنامه نویسی جاوا یکی از مشاغل محبوب در دنیای برنامه نویسی به حساب میآید. در این مقاله، به تعدادی از مهمترین سوالات مصاحبه برنامه نویسی جاوا پرداخته شد. این سوالات به طور اختصاصی برای برنامه نویسان جاوا در سطوح مختلف مبتدی، متوسط و پیشرفته دستهبندی شدهاند. با مطالعه این مقاله آشنایی لازم با سوالات مصاحبه برنامه نویسی جاوا حاصل میشود و میتوان میتوان آمادگی لازم را برای حضور در مصاحبههای کاری به دست آورد و احتمال پذیرفته شدن در موقعیتهای شغلی مناسب برنامه نویسی جاوا حاصل خواهد شد. از این رو، این مقاله به عنوان یک راهنمای کاربردی به منظور آمادگی و ورود هر چه سریعتر به بازار کار برنامه نویسی جاوا به حساب میآید.