JavaRush /وبلاگ جاوا /Random-FA /تجزیه و تحلیل پرسش و پاسخ از مصاحبه برای توسعه دهنده جاوا...

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

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

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

شما می توانید، اما بدون مقدار بازگشتی سمت راست بازگشت . یعنی می توانید از return استفاده کنید. به عنوان یک ساختار کمکی در طول محاسبات در سازنده به منظور پایان فوری (وقفه) اجرای کد بیشتر و تکمیل اولیه سازی شی. به عنوان مثال، ما یک کلاس Cat داریم و اگر Cat بی خانمان است - isHomeless = true ، باید مقداردهی اولیه را تمام کنیم و فیلدهای دیگر را پر نکنیم (در آخر، آنها برای ما ناشناخته هستند، زیرا گربه بی خانمان است):
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. سربرگ کلاس از چه عناصری تشکیل شده است؟ یک مثال بنویسید

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

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

دوباره، هنگام نگاه کردن به عناصر تشکیل دهنده یک هدر متد، یک نمودار کوچک را در نظر بگیرید که در آن:
  • اجزای اجباری در پرانتز <> هستند
  • اختیاری - در {}
{access modifier}{method static}{method abstraction}{method finality}{synchronization modifier} {native modifier}<return value><method name> <(> {method arguments} <)>{thrown استثناها} {access modifier } - همه اصلاح کننده های دسترسی برای روش موجود هستند: عمومی ، محافظت شده ، پیش فرض ، خصوصی . {method static} - static اصلاح‌کننده‌ای است که نشان می‌دهد این روش ثابت است، یعنی نه به یک شی، بلکه به یک کلاس متصل است. {method abstraction} اصلاح کننده انتزاعی است که نشان می‌دهد هیچ پیاده‌سازی (بدنه) روش وجود ندارد. برای عملکرد صحیح، شما همچنین به یک اصلاح کننده انتزاعی برای کلاسی که متد در آن ارائه شده است نیاز دارید. همانطور که در هدر کلاس، این اصلاح کننده با اصلاح کننده نهایی در تضاد است ، اما علاوه بر آن، با اصلاح کننده استاتیک نیز در تضاد است ، زیرا یک روش انتزاعی به معنای نادیده گرفتن روش در نسل است و روش های ایستا نادیده گرفته نمی شوند. {finality of the method} - final - یک اصلاح کننده که نشان می دهد این روش قابل لغو نیست. {synchronization modifier} - synchronized - یک اصلاح کننده به این معنی که این روش از دسترسی همزمان به آن از موضوعات مختلف محافظت می شود. اگر متد ثابت نباشد، روی این mutex شی بسته می شود. اگر متد ثابت باشد، روی mutex کلاس جاری بسته می شود. {native modifier} - native - این اصلاح کننده نشان می دهد که روش به زبان برنامه نویسی دیگری نوشته شده است. <return value> نوع مقداری است که متد باید برگرداند. اگر نباید چیزی را برگرداند، باطل است . <نام روش> نام متد، شناسه آن در سیستم است. {آگومان‌های روش} آرگومان‌هایی (پارامترهایی) هستند که متد می‌گیرد: آنها برای اجرای عملکرد آن ضروری هستند. {throughable استثناها} - throwsExceptionType - لیستی از استثناهای علامت گذاری شده که این روش می تواند پرتاب کند. و به عنوان مثالی از هدر متد، این را می‌دهم:
public static void main(String[] args) throws IOException

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

من خود سوال را به طور کامل درک نمی کنم، اما شاید به این معنی است که، به عنوان مثال، در والد ما یک سازنده سفارشی داریم:
public Cat(int age, String name) {
   this.age = age;
   this.name = name;
}
بنابراین، در کلاس ancestor، ما قطعاً نیاز به تعریف سازنده ای داریم که سازنده والد را پر کند ( فراخوانی کند:
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 یک فیلد از نام شی یک آرگومان متد است.این مرجع را نمی توان در متدهای ثابت استفاده کرد. 2. این را می توان در یک سازنده به شکل فراخوانی متد، مانند این (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 extends Parent، ترتیب مقداردهی اولیه شی را بنویسید.

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

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

دو نوع رابطه بین کلاس ها در جاوا وجود دارد:
  • رابطه IS-A
اصل IS-A در OOP بر پایه وراثت کلاس یا پیاده سازی رابط است. به عنوان مثال، اگر کلاس Lion از Cat به ارث برسد ، می گوییم که Lion Cat است :
Lion IS-A Cat
(اما هر گربه ای شیر نیست ) وضعیت دقیقاً در مورد رابط ها یکسان است. اگر کلاس Lion رابط WildAnimal را پیاده‌سازی کند ، آن‌ها نیز در یک رابطه هستند:
Lion IS-A WildAnimal
  • روابط دارد
این نوع رابطه مبتنی بر استفاده از کلاس ها توسط سایر طبقات است که به آن "Asociation" نیز می گویند. یک انجمن یک کلاس است که به کلاس دیگر (یا حتی به یکدیگر) ارجاع می دهد. به عنوان مثال، کلاس 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("Перевозка пассажира - " + passenger.toString());
       }
       passengers.clear();
   }
}
یعنی ما به تعداد مسافران اهمیتی نمی دهیم (یا اصلاً وجود دارد): عملکرد کلاس خودرو به این بستگی ندارد. تجمیع همچنین به این معنی است که وقتی یک شی توسط شی دیگری استفاده می شود، اولین مورد می تواند در اشیاء دیگر استفاده شود. مثلاً همین هنرجو می تواند هم عضو یک باشگاه بافتنی باشد و هم در یک گروه موسیقی راکرها و در عین حال به سراغ گروهی از زبان آموزان انگلیسی برود. همانطور که می‌دانید، تجمیع یک رابطه تداعی ضعیف‌تر بین کلاس‌ها است. تجزیه و تحلیل پرسش و پاسخ از مصاحبه برای توسعه دهنده جاوا.  قسمت 4 - 8ترکیب یک رابطه سفت و سخت تر است، زمانی که یک شی نه تنها بخشی از یک شی دیگر است، بلکه کار شی دیگر بسیار وابسته به اولی است. مثلا موتور ماشین. اگرچه ممکن است موتور بدون خودرو وجود داشته باشد، اما در خارج از آن بی فایده است. خوب، یک ماشین بدون موتور نمی تواند کار کند:
public class Car {
   private Engine engine;

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

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