CodeGym /จาวาบล็อก /สุ่ม /สำรวจคำถามและคำตอบจากการสัมภาษณ์งานสำหรับตำแหน่ง Java Dev...
John Squirrels
ระดับ
San Francisco

สำรวจคำถามและคำตอบจากการสัมภาษณ์งานสำหรับตำแหน่ง Java Developer ตอนที่ 4

เผยแพร่ในกลุ่ม
สวัสดีทุกคน! วันนี้ฉันจะทบทวนคำถามสัมภาษณ์นักพัฒนา Java ต่อไป สำรวจคำถามและคำตอบจากการสัมภาษณ์งานสำหรับตำแหน่ง Java Developer  ตอนที่ 4 - 1

29. สามารถใช้ return ในตัวสร้างได้หรือไม่?

ใช่ แต่ไม่มีค่าทางด้านขวาของคีย์เวิร์ด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;
}
แต่หากเรากำลังพูดถึงค่าที่เป็นรูปธรรม คีย์เวิร์ด returnจะไม่สามารถส่งคืนค่าที่เจาะจงได้เนื่องจาก:
  • เมื่อคุณประกาศ Constructor คุณจะไม่มีอะไรที่เหมือนกับประเภทการคืนสินค้า
  • ตามกฎแล้วตัวสร้างจะถูกเรียกโดยปริยายในระหว่างการสร้างอินสแตนซ์
  • Constructor ไม่ใช่วิธีการ แต่เป็นกลไกที่แยกจากกันซึ่งมีวัตถุประสงค์เพียงอย่างเดียวคือการเริ่มต้นตัวแปรอินสแตนซ์ กล่าวคือ เราใช้ตัว ดำเนินการ ใหม่เพื่อสร้างวัตถุ
สำรวจคำถามและคำตอบจากการสัมภาษณ์งานสำหรับตำแหน่ง Java Developer  ตอนที่ 4 - 2

30. สามารถโยนข้อยกเว้นจากตัวสร้างได้หรือไม่?

ตัวสร้างทำงานกับข้อยกเว้นในลักษณะเดียวกับที่วิธีการทำ วิธีการอนุญาตให้เราโยนข้อยกเว้นโดยการเขียน<ExceptionType>ในส่วนหัวของวิธีการ และคอนสตรัคเตอร์ก็ยอมให้เราทำเช่นเดียวกัน เมื่อเราสืบทอดและกำหนดคอนสตรัคเตอร์ของคลาสลูก เราสามารถขยายประเภทข้อยกเว้นให้กว้างขึ้นได้ ตัวอย่างเช่น IOException -> Exception (แต่ไม่ใช่ในทางกลับกัน) ลองใช้ Constructor ของ คลาส Catเป็นตัวอย่างของ Constructor ที่สร้างข้อยกเว้น สมมติว่าเมื่อเราสร้างวัตถุ เราต้องการป้อนชื่อและอายุจากคอนโซล:

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} — มีเพียงpublicและdefault access modifiers เท่านั้นที่พร้อมใช้งานสำหรับ ระดับ. {static} — ตัวแก้ไข แบบคงที่บ่งชี้ว่าคลาสนี้เป็นแบบคงที่ มันใช้กับคลาสภายในเท่านั้น (คลาสภายในคลาสอื่น) {final} — นี่คือ ตัวแก้ไข ขั้นสุดท้ายซึ่งทำให้คลาสไม่สามารถสืบทอดได้ (ตัวอย่างนอกกรอบคือString ) {abstract} — ตัวแก้ไข นามธรรมซึ่งบ่งชี้ว่าคลาสอาจมีเมธอดที่ไม่ได้นำไปใช้ ตัวแก้ไขนี้ขัดแย้งกับตัวแก้ไขสุดท้าย ส่วนหัวของคลาสสามารถมีได้เพียงอันเดียวเท่านั้น เนื่องจาก ตัวแก้ไข นามธรรมหมายความว่าคลาสจะได้รับการสืบทอดและองค์ประกอบนามธรรมจะถูกนำไปใช้ แต่สุดท้ายบ่งชี้ว่านี่คือเวอร์ชันสุดท้ายของคลาส และไม่สามารถสืบทอดได้ จริงๆ แล้ว การใช้ตัวดัดแปลงทั้งสองพร้อมกันคงเป็นเรื่องไร้สาระ คอมไพเลอร์จะไม่ยอมให้เราทำเช่นนี้ <class>เป็นคีย์เวิร์ดบังคับที่ระบุการประกาศคลาส <ชื่อคลาส>เป็นชื่อคลาสธรรมดาที่จะกลายเป็นตัวระบุของคลาส Java เฉพาะ ชื่อคลาสแบบเต็มประกอบด้วยชื่อแพ็กเกจที่ผ่านการรับรองบวก '.' บวกกับชื่อคลาสที่เรียบง่าย {inheritance of the Parent class}เป็นการบ่งชี้ถึงคลาสพาเรนต์ (ถ้ามี) โดยใช้คีย์เวิร์ดขยาย ตัวอย่างเช่น ... ขยาย ParentClass {implementation of interfaces} — รายการอินเทอร์เฟซที่คลาสนี้นำไปใช้ (ถ้ามี) โดยใช้คีย์เวิร์ดImplements ตัวอย่างเช่น: ... ใช้ FirstInterface, SecondInterface ... ตามตัวอย่าง ให้พิจารณาส่วนหัวของคลาสของ คลาส Lionซึ่งสืบทอดCatและใช้ อินเทอร์เฟซ WildAnimal :

public final class Lion extends Cat implements WildAnimal
สำรวจคำถามและคำตอบจากการสัมภาษณ์งานสำหรับตำแหน่ง Java Developer  ตอนที่ 4 - 3

32. องค์ประกอบของส่วนหัวของวิธีการมีอะไรบ้าง? เขียนตัวอย่าง

เมื่อพิจารณาองค์ประกอบที่ประกอบเป็นส่วนหัวของวิธีการ ลองพิจารณาสคีมาเล็กๆ อีกครั้ง:
  • องค์ประกอบบังคับปรากฏในวงเล็บ <>
  • องค์ประกอบเสริมอยู่ใน {}
{access modifier}{static}{abstract}{final}{synchronized} {native} <return value><method name> <(>{method parameter}<}>{throwข้อยกเว้น} {access modifier} — ตัวดัดแปลงการเข้าถึง ทั้งหมดคือ ใช้ได้สำหรับวิธีการ — public , protected , default , private . {static} — ตัวแก้ไข แบบคงที่ซึ่งบ่งชี้ว่าวิธีการนั้นเป็นแบบคงที่และดังนั้นจึงเชื่อมโยงกับคลาส ไม่ใช่วัตถุ {abstract} — ตัวแก้ไข นามธรรมซึ่งบ่งชี้ว่า เมธอดไม่มีการใช้งาน (เนื้อหา) เพื่อให้ทำงานได้อย่างถูกต้อง คลาสที่ประกาศเมธอดจะต้องมี abstract modifier ด้วย เช่นเดียวกับในส่วนหัวของคลาส modifier นี้ขัดแย้งกับ modifier สุดท้ายและยังขัดแย้งกับstatic modifier เนื่องจาก วิธีนามธรรมหมายถึงการแทนที่วิธีการในลูกหลานและวิธีการแบบคงที่ไม่สามารถเขียนทับได้ {finale} - ตัวแก้ไข สุดท้ายซึ่งบ่งชี้ว่าวิธีนี้ไม่สามารถเขียนทับได้ {synchronized} - ตัวแก้ไข แบบซิงโค รไนซ์ ซึ่งหมายความว่าวิธีการนั้นได้รับการปกป้องจาก เข้าถึงได้จากเธรดต่างๆ หากวิธีการไม่คงที่ ดังนั้นจะถูกปิดสำหรับ mutex นี้ของอ็อบเจ็กต์ หากวิธีการเป็นแบบคงที่ วิธีการนั้นจะถูกปิดสำหรับ mutex ของคลาสปัจจุบัน {native} — ตัวดัดแปลง ดั้งเดิมระบุว่าวิธีการนี้เขียนในภาษาการเขียนโปรแกรมอื่น <ประเภทการส่งคืน> — ประเภทของค่าที่เมธอดต้องส่งคืน หากวิธีการไม่ส่งคืนสิ่งใดๆ จะเป็น void <ชื่อวิธีการ> — ชื่อของชื่อวิธีการ เช่น ตัวระบุในระบบ {method parameter} — พารามิเตอร์ที่ method ยอมรับ: จำเป็นต่อการใช้งานฟังก์ชั่นของมัน {thrown ข้อยกเว้น} - โยน <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);
   }
}
สำรวจคำถามและคำตอบจากการสัมภาษณ์งานสำหรับตำแหน่ง Java Developer  ส่วนที่ 4 - 4

34. คำสำคัญนี้ใช้เมื่อใด?

ในภาษา Java สิ่งนี้มีสองความหมายที่แตกต่างกัน 1. เป็นการอ้างอิงถึงวัตถุปัจจุบัน เช่นthis.age = 9 นั่นคือสิ่งนี้หมายถึงวัตถุที่ใช้งานและรหัสที่อ้างอิงถึงนี้ วัตถุประสงค์หลักคือเพื่อปรับปรุงความสามารถในการอ่านโค้ดและหลีกเลี่ยงความคลุมเครือ ตัวอย่างเช่น หากฟิลด์อินสแตนซ์และอาร์กิวเมนต์เมธอดมีชื่อเหมือนกัน:

public void setName(String name) {
   this.name = name;
}
นั่นคือthis.nameคือฟิลด์ของอ็อบเจ็กต์ ในขณะที่nameคือพารามิเตอร์ method ไม่สามารถใช้การอ้างอิงนี้ในวิธีการคงที่ 2. ในตัวสร้างสิ่งนี้สามารถเรียกได้เหมือนกับวิธีการ เช่นthis(value) ในกรณีนี้ มันจะเป็นการเรียกไปยัง Constructor อื่นในคลาสเดียวกัน โดยพื้นฐานแล้ว คุณสามารถเรียกคอนสตรัคเตอร์สองตัวได้ในระหว่างกระบวนการสร้างอ็อบเจ็กต์:

public Cat(int age, String name) {
   this(name);
   this.age = age;
}
 
public Cat(String name) {
   this.name = name;
}
เมื่อเรียกตัวสร้างตัวแรกเพื่อสร้าง วัตถุ Catทั้งสองฟิลด์อินสแตนซ์จะเริ่มต้นได้สำเร็จ มีความแตกต่างสองสามประการที่นี่:
  1. this()ใช้งานได้ในตัวสร้างเท่านั้น
  2. การอ้างอิงถึงตัวสร้างอื่นจะต้องอยู่ในบรรทัดแรกของบล็อกตัวสร้าง (เนื้อหา) ซึ่งหมายความว่า Constructor ไม่สามารถเรียก Constructor ของคลาสได้มากกว่าหนึ่ง (อื่นๆ)
สำรวจคำถามและคำตอบจากการสัมภาษณ์งานสำหรับตำแหน่ง Java Developer  ตอนที่ 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 ) ในบล็อกแบบคงที่ สำรวจคำถามและคำตอบจากการสัมภาษณ์งานสำหรับตำแหน่ง Java Developer  ตอนที่ 4 - 6ตอนนี้เราสามารถดูลำดับของการเริ่มต้นคลาส (ร่วมกับคลาสพาเรนต์) เพื่อให้เข้าใจได้ดีขึ้นว่าเมื่อใดที่บล็อกการเริ่มต้นถูกเรียกใช้

36. เมื่อกำหนดคลาส Child สาธารณะที่ขยาย Parent ให้เขียนลำดับการเริ่มต้นของอ็อบเจ็กต์

เมื่อโหลด คลาส Childลำดับการเริ่มต้นจะเป็นดังนี้:
  1. ฟิลด์คลาสคงที่ของคลาสParent
  2. บล็อกการเริ่มต้นแบบคงที่ของคลาสParent
  3. ฟิลด์คงที่ของคลาสСchild
  4. บล็อกการเริ่มต้นแบบคงที่ของคลาสย่อย
  5. ฟิลด์ที่ไม่คงที่ของคลาสParent
  6. บล็อกการเริ่มต้นแบบไม่คงที่ของคลาสParent
  7. ตัวสร้างคลาสผู้ปกครอง
  8. ฟิลด์ที่ไม่คงที่ของคลาสСchild
  9. บล็อกการเริ่มต้นแบบไม่คงที่ของคลาสСchild
  10. ตัวสร้างคลาสСchild
สำรวจคำถามและคำตอบจากการสัมภาษณ์งานสำหรับตำแหน่ง Java Developer  ตอนที่ 4 - 7

37. คุณรู้ความสัมพันธ์ประเภทใดระหว่างคลาส (วัตถุ)?

มีตัวแปรสองประเภทใน Java: ประเภทดั้งเดิมและการอ้างอิงไปยังอ็อบเจ็กต์ที่มีคุณสมบัติครบถ้วน
  • ความสัมพันธ์แบบ IS-A
หลักการ IS-A ของ OOP ขึ้นอยู่กับการสืบทอดคลาสหรือการใช้งานอินเทอร์เฟซ ตัวอย่างเช่น หาก คลาส LionสืบทอดCatเราจะบอกว่าLion is a Cat :

Lion IS-A Cat
(แต่ไม่ใช่ทุกCat is a Lion ) มีสถานการณ์เดียวกันนี้กับอินเทอร์เฟซ หาก คลาส Lionใช้ อินเทอร์เฟซ WildAnimalแสดงว่าพวกมันยังอยู่ในความสัมพันธ์ด้วย:

Lion IS-A WildAnimal
  • มี ความสัมพันธ์แบบมี-เอ
ความสัมพันธ์ประเภทนี้เป็นที่ที่คลาสหนึ่งใช้คลาสอื่น เรียกอีกอย่างว่า "การเชื่อมโยง" การเชื่อมโยงคือคลาสหนึ่งที่อ้างถึงคลาสอื่น (หรือการอ้างอิงซึ่งกันและกัน) ตัวอย่างเช่น คลาส Carสามารถอ้างอิง คลาส Passengerซึ่งจะประกอบขึ้นเป็นความสัมพันธ์ต่อไปนี้:

Car HAS-A Passenger
และในทางกลับกัน: หากPassengerมีการอ้างอิงถึงCarสิ่งนี้จะเป็นความสัมพันธ์:

Passenger HAS-A Car

38. คุณรู้ความสัมพันธ์เชิงวัตถุอะไรบ้าง?

การรวมกลุ่มและการจัดองค์ประกอบไม่ใช่อะไรมากไปกว่าการรวมกลุ่มกรณีพิเศษ การรวมกลุ่มคือความสัมพันธ์ที่วัตถุหนึ่งเป็นส่วนหนึ่งของอีกวัตถุหนึ่ง ตัวอย่างเช่น ผู้โดยสารอาจอยู่ในรถ ยิ่งไปกว่านั้น อาจมีผู้โดยสารหลายคนหรือไม่มีเลย (และหากเรากำลังพูดถึง Tesla ก็อาจไม่มีคนขับเลย) ตัวอย่างเช่น:

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();
   }
}
กล่าวอีกนัยหนึ่ง จำนวนผู้โดยสาร (จำนวนเท่าใดก็ได้) ไม่สำคัญสำหรับเรา: ฟังก์ชันการทำงานของคลาส Carไม่ได้ขึ้นอยู่กับสิ่งนี้ การรวมกลุ่มยังบอกเป็นนัยว่าเมื่อวัตถุอื่นใช้วัตถุหนึ่ง วัตถุแรกสามารถถูกใช้โดยวัตถุอื่นได้ ตัวอย่างเช่น นักเรียนคนเดียวกันอาจอยู่ในชมรมถักนิตติ้งและวงดนตรีร็อคและเข้าเรียนภาษาสเปนไปพร้อมๆ กัน ดังที่คุณสามารถจินตนาการได้ การรวมกลุ่มคือความสัมพันธ์ที่เชื่อมโยงระหว่างชั้นเรียนที่หลวมกว่า องค์ประกอบคือความสัมพันธ์ที่แน่นแฟ้นยิ่งขึ้น โดยที่วัตถุไม่ได้เป็นเพียงส่วนหนึ่งของวัตถุอื่นเท่านั้น แต่งานของวัตถุชิ้นหนึ่งยังขึ้นอยู่กับอีกวัตถุหนึ่งอีกด้วย เช่น รถยนต์มีเครื่องยนต์ เครื่องยนต์อาจดำรงอยู่ได้หากไม่มีรถยนต์ แต่ภายนอกรถยนต์ก็ไม่มีประโยชน์ และรถยนต์ไม่สามารถทำงานได้หากไม่มีเครื่องยนต์:

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