CodeGym /وبلاگ جاوا /Random-FA /بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه...
John Squirrels
مرحله
San Francisco

بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه دهنده جاوا. قسمت 4

در گروه منتشر شد
سلام، همه! امروز به بررسی سوالات مصاحبه توسعه دهندگان جاوا ادامه می دهم. بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه دهنده جاوا.  قسمت 4 - 1

29. آیا می توان از بازگشت در یک سازنده استفاده کرد؟

بله، اما فقط بدون مقدار در سمت راست کلمه کلیدی بازگشتی . می توانید از بازگشت استفاده کنید. به عنوان یک دستور کمکی در سازنده برای خاتمه فوری (وقفه) اجرای کد بیشتر و پایان دادن به مقداردهی اولیه شی. به عنوان مثال، فرض کنید ما یک کلاس Cat داریم ، و اگر یک Cat بی‌خانمان باشد ( isHomeless = درست است ، پس می‌خواهیم مقداردهی اولیه را خاتمه دهیم و فیلدهای دیگر را پر نکنیم (در نهایت، آنها برای ما ناشناخته هستند، زیرا گربه بی‌خانمان است) :
public Cat(int age, String name, boolean isHomeless) {
   if (isHomeless){
       this.isHomeless = isHomeless;
       return;
   }
   this.isHomeless = isHomeless;
   this.age = age;
   this.name = name;
}
اما اگر در مورد مقادیر مشخص صحبت می کنیم، کلمه کلیدی بازگشت نمی تواند مقدار خاصی را برگرداند زیرا:
  • وقتی سازنده ای را اعلام می کنید، چیزی شبیه نوع بازگشتی نخواهید داشت.
  • به عنوان یک قاعده، سازنده به طور ضمنی در هنگام نمونه سازی فراخوانی می شود.
  • سازنده یک متد نیست: یک مکانیسم جداگانه است که تنها هدف آن مقداردهی اولیه متغیرهای نمونه است، به عنوان مثال، ما از عملگر جدید برای ایجاد یک شی استفاده می کنیم.
بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه دهنده جاوا.  قسمت 4 - 2

30. آیا می توان از سازنده یک استثنا انداخت؟

سازندگان با استثناها به همان روشی کار می کنند که متدها انجام می دهند. متدها به ما این امکان را می دهند که با نوشتن پرتاب <ExceptionType> در هدر متد، استثناها را پرتاب کنیم. و سازنده ها به ما اجازه می دهند همین کار را انجام دهیم. وقتی سازنده یک کلاس فرزند را به ارث می بریم و تعریف می کنیم، می توانیم نوع استثنا را گسترش دهیم - برای مثال، IOException -> Exception (اما نه برعکس). بیایید سازنده کلاس Cat را به عنوان مثالی از سازنده ای که یک استثنا پرتاب می کند استفاده کنیم. فرض کنید وقتی یک شی را ایجاد می کنیم، می خواهیم نام و سن را از کنسول وارد کنیم:
public Cat() throws IOException {
   BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
   this.name = reader.readLine();
   this.age = Integer.parseInt(reader.readLine());
}
از آنجایی که reader.readLine() یک IOException می اندازد، آن را در هدر به عنوان یک استثنای احتمالی می نویسیم.

31. عناصر سربرگ کلاس چیست؟ یک مثال بنویسید

برای نشان دادن عناصری که یک هدر کلاس را تشکیل می دهند، اجازه دهید به یک طرحواره کوچک نگاه کنیم:
  • عناصر اجباری در پرانتز <> ظاهر می شوند
  • عناصر اختیاری در {} هستند
{access modifier}{static}{final}{abstract}<class name>{inheritance of Parent class}{implementation of interfaces} بنابراین، آنچه داریم: { access modifier} — فقط اصلاح‌کننده‌های دسترسی عمومی و پیش‌فرض برای کلاس {static} - اصلاح کننده استاتیک نشان می دهد که این کلاس ثابت است. فقط برای کلاس های داخلی (کلاس های داخل کلاس های دیگر) کاربرد دارد. {final} — البته این اصلاح‌کننده نهایی است که کلاس را غیرقابل ارث می‌کند (یک مثال خارج از جعبه String است ). {abstract} - اصلاح کننده انتزاعی ، که نشان می دهد که کلاس ممکن است متدهای اجرا نشده داشته باشد. این اصلاح کننده با اصلاح کننده نهایی در تضاد است . هدر کلاس فقط می تواند یکی از آنها را داشته باشد زیرا اصلاح کننده انتزاعی به این معنی است که کلاس به ارث می رسد و عناصر انتزاعی آن پیاده سازی می شوند. اما final نشان می دهد که این نسخه نهایی کلاس است و نمی توان آن را به ارث برد. در واقع، استفاده همزمان از هر دو اصلاح کننده پوچ خواهد بود. کامپایلر به ما اجازه این کار را نمی دهد. <class> یک کلمه کلیدی اجباری است که بیانگر یک کلاس است. <class name> یک نام کلاس ساده است که به شناسه یک کلاس خاص جاوا تبدیل می شود. نام کلاس کاملا واجد شرایط شامل نام بسته واجد شرایط به اضافه '.' است. به علاوه نام ساده کلاس {inheritance of the Parent class} نشانی از کلاس والد (در صورت وجود) با استفاده از کلمه کلیدی extends است . به عنوان مثال، ... ParentClass را گسترش می دهد . {implementation of interfaces} — لیستی از واسط هایی که این کلاس (در صورت وجود) با استفاده از کلمه کلیدی implements پیاده سازی می کند . به عنوان مثال: ... اجراهای FirstInterface، SecondInterface ... به عنوان مثال، عنوان کلاس کلاس Lion را در نظر بگیرید که Cat را به ارث می برد و رابط WildAnimal را پیاده سازی می کند :
public final class Lion extends Cat implements WildAnimal
بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه دهنده جاوا.  قسمت 4 - 3

32. عناصر هدر متد چیست؟ یک مثال بنویسید

هنگام در نظر گرفتن عناصر تشکیل دهنده یک هدر متد، اجازه دهید دوباره یک طرح کوچک را در نظر بگیریم:
  • عناصر اجباری در پرانتز <> ظاهر می شوند
  • عناصر اختیاری در {} هستند
{access modifier}{static}{abstract}{final}{synchronized} {native} <Return value><method name> <(>{method parameters}<}>{trow استثناها} {access modifier} — همه اصلاح‌کننده‌های دسترسی هستند در دسترس برای متد — public , protected , default , private {static} — اصلاح کننده استاتیک که نشان می دهد که متد ثابت است و بنابراین با کلاس مرتبط است نه یک شی { abstract} — اصلاح کننده انتزاعی که نشان می دهد که متد پیاده سازی (بدنه) ندارد. برای درست کار کردن، کلاسی که متد را اعلام می کند باید اصلاح کننده انتزاعی نیز داشته باشد . همانطور که در سربرگ کلاس، این اصلاح کننده با اصلاح کننده نهایی در تضاد است و همچنین با اصلاح کننده استاتیک در تضاد است ، زیرا یک روش انتزاعی به معنای نادیده گرفتن روش در یک نسل است، و روش‌های ایستا نمی‌توانند نادیده گرفته شوند. {finale} - اصلاح‌کننده نهایی ، که نشان می‌دهد این روش نمی‌تواند لغو شود. {synchronized} - اصلاح‌کننده همگام‌سازی شده ، به این معنی که روش در برابر محافظت می‌شود. دسترسی همزمان به آن از موضوعات مختلف. اگر متد ثابت نباشد، برای این mutex شی بسته است. اگر متد ثابت باشد، برای mutex کلاس فعلی بسته می شود. {native} - اصلاح کننده بومی نشان می دهد که روش به زبان برنامه نویسی دیگری نوشته شده است. <return type> - نوع مقداری که متد باید برگرداند. اگر متد چیزی برنگرداند، void کنید . <نام روش> - نام نام متد، یعنی شناسه آن در سیستم. {پارامترهای روش} - پارامترهایی که روش می‌پذیرد: برای اجرای عملکرد آن ضروری هستند. {thrown exports}<ExceptionType> را پرتاب می کند — فهرستی از استثناهای علامت زده شده که این روش می تواند پرتاب کند. من موارد زیر را به عنوان نمونه ای از هدر متد ارائه می کنم:
public static void main(String[] args) throws IOException

33. یک سازنده پیش فرض در کلاس فرزند ایجاد کنید اگر قبلاً در کلاس پایه تعریف نشده است (اما سازنده دیگری تعریف شده است)

من مطمئن نیستم که سؤال را کاملاً درک کرده باشم، اما شاید به این معنی است که ما سازنده ای مانند این در کلاس والد داریم:
public Cat(int age, String name) {
   this.age = age;
   this.name = name;
}
در این صورت، در کلاس والد، قطعاً باید سازنده ای تعریف کنیم که والد را مقداردهی اولیه کند (یعنی سازنده والد را فراخوانی کند):
public class Lion extends Cat {

   public Lion(int age, String name) {
       super(age, name);
   }
}
بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه دهنده جاوا.  قسمت 4 - 4

34. چه زمانی از این کلمه کلیدی استفاده می شود؟

در جاوا این دو معنی متفاوت دارد. 1. ارجاع به شی فعلی است، به عنوان مثال this.age = 9 . یعنی این به شیئی که در آن استفاده شده و کد با این به آن اشاره دارد اشاره دارد. هدف اصلی بهبود خوانایی کد و جلوگیری از ابهام است. به عنوان مثال، اگر یک فیلد نمونه و یک آرگومان متد یک نام داشته باشند:
public void setName(String name) {
   this.name = name;
}
یعنی this.name فیلد شی است، در حالی که name پارامتر متد است. این مرجع را نمی توان در روش های استاتیک استفاده کرد. 2. در سازنده، این را می توان مانند یک متد نامید، به عنوان مثال this(value) . در این صورت فراخوانی به سازنده دیگری از همان کلاس خواهد بود. اساساً می‌توانید در طول فرآیند ایجاد یک شی، دو سازنده را فراخوانی کنید:
public Cat(int age, String name) {
   this(name);
   this.age = age;
}

public Cat(String name) {
   this.name = name;
}
هنگام فراخوانی اولین سازنده برای ایجاد یک شی Cat ، هر دو فیلد نمونه با موفقیت مقداردهی اولیه می شوند. در اینجا چند تفاوت وجود دارد:
  1. this() فقط در یک سازنده کار می کند.
  2. ارجاع به سازنده دیگری باید در خط اول بلوک سازنده (بدنه) باشد. این بدان معناست که یک سازنده نمی تواند بیش از یک سازنده (سایر) کلاس خود را فراخوانی کند.
بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه دهنده جاوا.  قسمت 4 - 5

35. مقداردهی اولیه چیست؟

تا جایی که من متوجه شدم، این سوال در مورد بلوک های اولیه و استاتیک اولیه است. بیایید ابتدا به یاد بیاوریم که مقداردهی اولیه چیست. اولیه سازی ایجاد، فعال سازی، آماده سازی و تعریف فیلدها است. آماده سازی یک برنامه یا جزء برای آماده شدن برای استفاده. به یاد می آورید که وقتی یک شی را ایجاد می کنید، یک متغیر کلاس می تواند بلافاصله پس از اعلان مقداردهی اولیه شود:
class Cat {
   private int age = 9;
   private String name = "Tom";
یا بعد از واقعیت از طریق سازنده تنظیم کنید:
class Cat {
   private int age;
   private String name;

   public Cat(int age, String name) {
       this.age = age;
       this.name = name;
   }
اما راه دیگری وجود دارد: می توانید یک متغیر نمونه را با استفاده از یک بلوک اولیه تنظیم کنید، که به شکل پرانتزهای مجعد {} در داخل یک کلاس، بدون نام (مانند یک متد یا سازنده بی نام) تنظیم می شود:
class Cat {
   private int age;
   private String name;

   {
       age = 10;
       name = "Tom";
   }
بلوک مقداردهی اولیه قطعه ای از کد است که هنگام ایجاد یک شی بارگذاری می شود. چنین بلوک‌هایی معمولاً برای انجام محاسبات پیچیده خاصی استفاده می‌شوند که هنگام بارگذاری یک کلاس مورد نیاز است. نتایج این محاسبات را می توان به عنوان مقادیر متغیرها تنظیم کرد. علاوه بر بلوک های اولیه اولیه، بلوک های ثابت نیز وجود دارد. آنها یکسان به نظر می رسند اما کلمه کلیدی ثابت را در جلوی بند باز می کنند:
class Cat {
   private static int age;
   private static String name;

   static{
       age = 10;
       name = "Tom";
   }
این بلوک مانند بلوک قبلی است. اما اگر حالت معمولی زمانی اجرا شود که هر شیء مقدار دهی اولیه می شود، آنگاه استاتیک تنها یک بار، زمانی که کلاس بارگذاری می شود، اجرا می شود. به عنوان یک قاعده، محاسبات پیچیده خاصی در یک بلوک استاتیک انجام می شود که برای مقداردهی اولیه متغیرهای کلاس ایستا استفاده می شود. همان محدودیت‌ها برای یک بلوک استاتیک که برای روش‌های استاتیک اعمال می‌شود اعمال می‌شود: شما نمی‌توانید از داده‌های غیراستاتیک، مانند ارجاع به شی فعلی ( this ) در یک بلوک استاتیک استفاده کنید. بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه دهنده جاوا.  قسمت 4 - 6اکنون می‌توانیم به ترتیب اولیه‌سازی کلاس (همراه با کلاس والد آن) نگاه کنیم تا درک بهتری داشته باشیم که دقیقاً چه زمانی بلوک‌های اولیه فراخوانی شده‌اند.

36. با توجه به یک کلاس Child عمومی که Parent را گسترش می دهد، ترتیب اولیه شی را بنویسید

هنگام بارگذاری کلاس Child ، ترتیب اولیه سازی به صورت زیر خواهد بود:
  1. فیلدهای کلاس ایستا از کلاس Parent .
  2. بلوک اولیه سازی استاتیک کلاس Parent .
  3. فیلدهای ثابت کلاس Сhild .
  4. بلوک اولیه سازی استاتیک کلاس Child .
  5. فیلدهای غیر استاتیک از کلاس Parent .
  6. بلوک مقداردهی اولیه غیراستاتیک کلاس Parent .
  7. سازنده کلاس والد .
  8. فیلدهای غیر استاتیک از کلاس Сhild .
  9. بلوک مقداردهی اولیه غیراستاتیک کلاس Сhild .
  10. سازنده کلاس Сhild .
بررسی پرسش ها و پاسخ های مصاحبه شغلی برای یک موقعیت توسعه دهنده جاوا.  قسمت 4 - 7

37. چه نوع روابط بین کلاس ها (اشیاء) را می شناسید؟

دو نوع متغیر در جاوا وجود دارد: انواع اولیه و ارجاع به اشیاء کامل.
  • روابط IS-A
اصل IS-A OOP بر اساس وراثت کلاس یا پیاده سازی رابط ها است. به عنوان مثال، اگر کلاس Lion Cat را به ارث ببرد ، می گوییم که Lion یک Cat است :
Lion IS-A Cat
(اما هر گربه شیر نیست ) همین وضعیت در رابط ها وجود دارد. اگر کلاس Lion واسط WildAnimal را پیاده سازی کند ، در این رابطه نیز وجود دارد:
Lion IS-A WildAnimal
  • رابطه دارد
این نوع رابطه جایی است که یک کلاس از کلاس‌های دیگر استفاده می‌کند که به آن «تداعی» نیز می‌گویند. یک انجمن کلاسی است که به کلاس دیگر (یا ارجاعات متقابل به یکدیگر) اشاره دارد. به عنوان مثال، کلاس Car می تواند به کلاس Passenger اشاره کند که رابطه زیر را تشکیل می دهد:
Car HAS-A Passenger
و بالعکس: اگر مسافر اشاره ای به خودرو داشته باشد ، این رابطه خواهد بود:
Passenger HAS-A Car

38. چه روابط شیء انجمنی را می شناسید؟

تجمیع و ترکیب چیزی جز موارد خاص تداعی نیست. تجمع رابطه ای است که در آن یک شی بخشی از شی دیگر است. به عنوان مثال، یک مسافر ممکن است در یک ماشین قرار داشته باشد. علاوه بر این، ممکن است چندین مسافر وجود داشته باشد یا اصلاً هیچ مسافری وجود نداشته باشد (و اگر در مورد تسلا صحبت می کنیم، ممکن است هیچ راننده ای وجود نداشته باشد). مثلا:
public class Car {
   private List passengers = new ArrayList<>();

 void setPassenger(Passenger passenger) {
     passengers.add(passenger);
 }

   void move() {
       for (Passenger passenger : passengers) {
           System.out.println("Transporting passenger - " + passenger.toString());
       }
       passengers.clear();
   }
}
به عبارت دیگر، تعداد مسافران (در هر کدام) برای ما مهم نیست: عملکرد کلاس خودرو به این بستگی ندارد. تجمیع همچنین به این معنی است که وقتی شی دیگری از یک شی استفاده می کند، اولین شی می تواند توسط اشیاء دیگر استفاده شود. به عنوان مثال، ممکن است همان دانش آموز هم در یک باشگاه بافتنی و هم در یک گروه راک باشد و همزمان در کلاس اسپانیایی شرکت کند. همانطور که می‌توانید تصور کنید، تجمیع یک رابطه تداعی ضعیف‌تر بین طبقات است. ترکیب یک رابطه حتی تنگ تر است که در آن یک شی نه تنها بخشی از یک شی دیگر است، بلکه کار یک شی بسیار به دیگری وابسته است. مثلا ماشینی موتور دارد. یک موتور ممکن است بدون ماشین وجود داشته باشد، اما در خارج از ماشین بی فایده است. و یک ماشین بدون موتور نمی تواند کار کند:
public class Car {
   private Engine engine;

   public Car(Engine engine) {
       this.engine = engine;
   }

   void startMoving() {
       engine.start();
           ...
   }
ترکیب همچنین به این معنی است که وقتی شی دیگری از یک شی استفاده می کند، اولین شی نمی تواند به هیچ شی دیگری تعلق داشته باشد. به مثال ما برگردیم، یک موتور فقط می تواند متعلق به یک خودرو باشد، نه دو یا چند خودرو همزمان. من فکر می کنم برای امروز کافی است، بنابراین ما در اینجا توقف می کنیم.
بیشتر بخوانید:
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION