JavaRush /จาวาบล็อก /Random-TH /การวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java ตอนท...
Константин
ระดับ

การวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java ตอนที่ 8

เผยแพร่ในกลุ่ม
การปฏิบัติหรือทฤษฎี? อะไรสำคัญกว่ากัน? หลายๆ คนจะบอกว่าแน่นอนว่าการฝึกฝนมีความสำคัญมากกว่า ชอบฝึกฝนให้หนักที่สุดเท่าที่จะทำได้แล้วคุณจะมีความสุข ฉันกล้าที่จะไม่เห็นด้วยกับสิ่งนี้ การวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 8 - 1ในระหว่างการสัมภาษณ์ จะไม่มีใครรู้ว่าคุณฝึกซ้อมเก่งแค่ไหน คุณจะถูกถามเต็มความยาวอย่างแม่นยำตามทฤษฎี และเมื่อคุณผ่านการสัมภาษณ์ทุกรอบและเข้าสู่โครงการ คุณจะใช้ทักษะการปฏิบัติของคุณ คุณอาจคัดค้าน: บางครั้งพวกเขาจะให้การทดสอบแก่คุณและยังต้องมีการฝึกฝนอีกด้วย ฉันไม่เถียง บางครั้งพวกเขาก็ให้ แต่ความจริงของเรื่องนี้ก็คือบางครั้ง แต่การสัมภาษณ์เชิงทฤษฎีมักจะเกิดขึ้นเสมอ คุณรู้สึกถึงความแตกต่างหรือไม่? ดังนั้นคุณต้องมีรากฐานทางทฤษฎีที่มั่นคงอยู่ใต้ฝ่าเท้าของคุณ ซึ่งเราจะเสริมสร้างความเข้มแข็งต่อไปในวันนี้ กล่าวคือ เราจะวิเคราะห์คำถามที่มักถูกถามบ่อยในระหว่างการสัมภาษณ์ต่อไป

71. จะเกิดอะไรขึ้นถ้าเราไม่แทนที่เมธอด toString() สำหรับ Enum

สมมติว่าเรามีenum ต่อไปนี้ :
public enum Role {
   STUDENT,
   TEACHER,
   DIRECTOR,
   SECURITY_GUARD;
}
มาแสดงนักเรียนในคอนโซลโดยเรียก toString() กับเขา:
System.out.println(Role.STUDENT.toString());
ผลลัพธ์ในคอนโซล:
นักเรียน
นั่นคือตามค่าเริ่มต้นtoString()สำหรับenumคือชื่อของค่าคงที่นั้นเอง

72. เป็นไปได้ไหมที่จะระบุ Constructor ภายใน Enum?

แน่นอน. ผ่านตัวสร้างที่ตั้งค่าของตัวแปรแจงนับภายใน ตามตัวอย่างให้เพิ่มสองฟิลด์ ใน การแจงนับ ก่อนหน้า - ageFromและageTo - เพื่อระบุช่วงอายุสำหรับแต่ละบทบาท:
public enum Role {
   STUDENT(5,18),
   TEACHER(20,60),
   DIRECTOR(40,70),
   SECURITY_GUARD(18,50);

   int ageFrom;
   int ageTo;

   Role(int ageFrom, int ageTo) {
       this.ageFrom = ageFrom;
       this.ageTo = ageTo;
   }
}

73. == และเท่ากับ() แตกต่างกันอย่างไร?

นี่เป็นหนึ่งในคำถามสัมภาษณ์นักพัฒนา Java ที่พบบ่อยที่สุด เริ่มต้นด้วยความจริงที่ว่าเมื่อเราเปรียบเทียบค่าง่าย ๆ ( int , char , double ... ) เราทำโดยใช้==เนื่องจากตัวแปรมีค่าเฉพาะและเราสามารถเปรียบเทียบได้ และตัวแปรดั้งเดิมไม่ใช่วัตถุที่มีคุณสมบัติครบถ้วน - พวกมันไม่ได้สืบทอดมาจากObject และไม่มีเมธอดเท่ากับ() เมื่อเราพูดถึงการเปรียบเทียบตัวแปรที่อ้างถึงวัตถุ==จะเปรียบเทียบเฉพาะค่าของการอ้างอิง - ไม่ว่าตัวแปรจะอ้างอิงถึงวัตถุเดียวกันหรือไม่ก็ตาม และแม้ว่าวัตถุหนึ่งจะเหมือนกันกับอีกวัตถุหนึ่ง การเปรียบเทียบผ่าน==จะให้ผลลัพธ์ที่เป็นลบ ( false ) เพราะนี่คือวัตถุอื่น ตามที่คุณเข้าใจ วิธีการเท่ากับ ( ) ใช้เพื่อเปรียบเทียบตัวแปรอ้างอิง นี่เป็นหนึ่งในวิธีการมาตรฐานของ คลาส Objectซึ่งจำเป็นสำหรับการเปรียบเทียบออบเจ็กต์โดยสมบูรณ์ แต่มันก็คุ้มค่าที่จะอธิบายให้ชัดเจนทันที: เพื่อให้วิธีนี้ทำงานได้อย่างถูกต้อง จำเป็นต้องนิยามใหม่โดยเขียนให้ชัดเจนว่าควรเปรียบเทียบอ็อบเจ็กต์ของคลาสนี้อย่างไร เว้นแต่คุณจะแทนที่วิธีการนั้น โดยค่าเริ่มต้น มันจะเปรียบเทียบวัตถุด้วย== ในIntelliJ IDEAคุณสามารถแทนที่มันได้โดยอัตโนมัติ (โดยใช้เครื่องมือ IDEA) -> alt + insertในหน้าต่างที่ปรากฏขึ้น เลือกเท่ากับ() และ hashCode() -> เลือกว่าฟิลด์คลาสใดควรเข้าร่วม -> และ voila การใช้งานอัตโนมัติของ วิธีการต่างๆ เสร็จสิ้นแล้ว นี่คือตัวอย่างของ วิธีการ เท่ากับ ที่สร้างขึ้นโดยอัตโนมัติสำหรับคลาส Catธรรมดาที่มีสองฟิลด์ - int ageและString name :
@Override
public boolean equals(final Object o) {
   if (this == o) return true;
   if (o == null || this.getClass() != o.getClass()) return false;
   final Cat cat = (Cat) o;
   return this.age == cat.age &&
           Objects.equals(this.name, cat.name);
}
ถ้าเราพูดถึงความแตกต่างระหว่าง== และเท่ากับ enums ก็ยังมีไม่มาก ท้ายที่สุดแล้วenumจะเก็บค่าคงที่และแม้กระทั่งเมื่อเปรียบเทียบค่าที่คล้ายกันโดยใช้==เราจะได้รับtrueเนื่องจากการอ้างอิงจะอยู่ที่วัตถุเดียวกันเสมอ เมื่อใช้เท่ากับเราจะทำงานอย่างถูกต้องโดยเฉพาะอย่างยิ่งหากคุณเข้าไปในเนื้อความของ วิธีการ เท่ากับสำหรับenumคุณจะเห็นว่าใน คลาส Enumการใช้งานวิธีการจะเป็นดังนี้: นั่นคือ ข้างใน - การเปรียบเทียบแบบเก่าที่ดีโดยการอ้างอิง! เพื่อสรุป: สำหรับenumการเปรียบเทียบทั้งผ่าน==และเท่ากับนั้นถูกต้องการวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 8 - 2การวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 8 - 3การวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 8 - 4

74. วิธีลำดับ () ทำอะไรใน Enum?

เมื่อเรียกใช้เมธอดint ordinal()บนอิ ลิเมนต์ enumเราจะได้เลขลำดับจากศูนย์ของค่านี้ในชุดการแจงนับทั่วไป ลองใช้วิธีนี้กับองค์ประกอบหนึ่งจากenum ก่อนหน้านี้ที่กล่าวถึง - Role :
System.out.println(Role.DIRECTOR.ordinal());
ดังนั้นคอนโซลจะแสดง:
2

75. เป็นไปได้ไหมที่จะใช้ Enum กับ TreeSet หรือ TreeMap ใน Java?

สามารถ ใช้ ประเภท enumในTreeSetและTreeMapได้ และเราสามารถเขียนได้:
TreeSet<Role> treeSet = new TreeSet<>();
treeSet.add(Role.SECURITY_GUARD);
treeSet.add(Role.DIRECTOR);
treeSet.add(Role.TEACHER);
treeSet.add(Role.STUDENT);
treeSet.forEach(System.out::println);
และคอนโซลจะแสดง:
ผู้อำนวยการฝ่ายรักษาความปลอดภัย_ครูนักเรียน
เราได้รับผลลัพธ์ที่ไม่เรียงตามตัวอักษร ประเด็นก็คือหากเราใช้ องค์ประกอบ enumสำหรับ ค่า TreeSetหรือเป็นคีย์สำหรับTreeMapองค์ประกอบจะถูกจัดเรียงตามลำดับธรรมชาติ (ลำดับที่ระบุไว้ในenum ) การทำความเข้าใจคุณสมบัติเหล่านี้ช่วยให้เราเขียนโค้ดได้ดีขึ้นการวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 8 - 5

76. วิธีการเรียงลำดับ () และ comparisonTo () เกี่ยวข้องกันใน Enum อย่างไร

ตามที่ระบุไว้ก่อนหน้านี้ordinal()ส่งคืนเลขลำดับของค่าในรายการแจงนับทั่วไป นอกจากนี้ ในการวิเคราะห์คำถาม ก่อนหน้านี้ คุณเห็นว่าองค์ประกอบของการแจงนับ ตัวอย่างเช่น ใน ชุด TreeSet (ชุดที่เรียงลำดับ) ใช้ลำดับที่ประกาศไว้ในenum และดังที่เราทราบTreeSetและTreeMapเรียงลำดับองค์ประกอบโดยการเรียกเมธอดcomparisonTo () ของ Comparable interface จากนี้เราสามารถสรุปได้ว่า คลาส Enumใช้งานComparable interface โดยนำไปใช้ใน เมธอด comparisonTo()ซึ่งภายในordinal() ใช้ เพื่อกำหนดลำดับการจัดเรียง เมื่อเข้าสู่ คลาส Enumเราจะเห็นการยืนยันสิ่งนี้: การวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 8 - 6และเนื้อความของวิธีการนั้นเอง: ไม่ได้เรียกการวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 8 - 7เมธอดordinal() ที่นี่ แต่ จะใช้ตัวแปร ลำดับ แทน - เลขลำดับขององค์ประกอบในการแจงนับ เมธอด ordinal()นั้นไม่มีการวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 8 - 8อะไรมากไปกว่า getter สำหรับตัวแปรลำดับ

77. เขียนตัวอย่าง EnumM

ในคำถามที่กล่าวถึงข้างต้น ฉันได้ยกตัวอย่างenums แล้ว และฉันไม่เห็นประเด็นในการทำซ้ำโค้ด (เช่น คำถามข้อ 72 เกี่ยวกับ Constructor ใน enum)

78. เป็นไปได้ไหมที่จะใช้ Enum ในกรณีสวิตช์?

เป็นไปได้และจำเป็น! เมื่อมองย้อนกลับไปที่การปฏิบัติของฉัน ฉันสังเกตว่าหนึ่งในตำแหน่งที่ใช้บ่อยที่สุดในการใช้enumคือโครงสร้างเชิงตรรกะเช่นswitch ในกรณีนี้ คุณสามารถระบุรูปแบบที่เป็นไปได้ทั้งหมดcaseและหลังจากเขียนตรรกะสำหรับ ค่า แจงนับ ทั้งหมด - และ อาจไม่จำเป็นต้อง ใช้ ตัวดำเนินการเริ่มต้น ด้วยซ้ำ! ท้ายที่สุด หากคุณใช้สตริงหรือค่าตัวเลข เช่น ประเภทintคุณอาจได้รับค่าที่ไม่คาดคิด ซึ่งไม่สามารถใช้enumได้ สวิตช์จะมีลักษณะอย่างไรสำหรับตัวอย่างที่กล่าวถึงก่อนหน้านี้:
public void doSomething(Role role) {
   switch (role) {
       case STUDENT:
           // некая логика для STUDENT
           break;
       case TEACHER:
           // некая логика для TEACHER
           break;
       case DIRECTOR:
           // некая логика для DIRECTOR
           break;
       case SECURITY_GUARD:
           // некая логика для SECURITY_GUARD
           break;
   }
}

79. จะรับค่าที่มีอยู่ทั้งหมดในอินสแตนซ์ Enum ได้อย่างไร

หากคุณต้องการรับอินสแตนซ์ทั้งหมดของการแจงนับจะมีเมธอดค่า ()ที่ส่งคืนอาร์เรย์ของค่าที่มีอยู่ทั้งหมดของแจง นับเฉพาะ ตามลำดับธรรมชาติ (ตามลำดับที่ระบุไว้ในแจงนับ ) ตัวอย่าง:
Role[] roles = Role.values();
for (Role role : roles) {
   System.out.println(role);
}
คอนโซลจะแสดงผลลัพธ์ต่อไปนี้:
ผู้อำนวยการฝ่ายรักษาความปลอดภัย_ครูนักเรียน

สตรีม API

80.สตรีมใน Java คืออะไร?

Java Streamเป็นวิธีการใหม่ในการโต้ตอบกับสตรีมข้อมูล ซึ่งจะช่วยให้คุณประมวลผลข้อมูลขนาดใหญ่ได้สะดวกและกะทัดรัดยิ่งขึ้น ตลอดจนทำการประมวลผลข้อมูลแบบขนานระหว่างเธรดจำนวนหนึ่ง ซึ่งสามารถเพิ่มประสิทธิภาพในการใช้งานได้ ฟังก์ชั่น หัวข้อนี้ไม่สามารถพูดคุยอย่างลึกซึ้งโดยสรุปได้ ดังนั้นฉันจะทิ้งลิงก์ไปยังบทความที่สามารถช่วยให้คุณเจาะลึกในหัวข้อนี้ได้การวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 8 - 9

81. คุณสมบัติหลักของธุรกรรมมีอะไรบ้าง?

หัวข้อนี้เรียกว่า Stream API แต่คำถามเกี่ยวกับธุรกรรม อืม... ก่อนอื่น เรามาดูกันว่าธุรกรรมคืออะไร ธุรกรรมคือกลุ่มของการดำเนินการฐานข้อมูลตามลำดับซึ่งแสดงถึงหน่วยลอจิคัลของการทำงานกับข้อมูล ธุรกรรมสามารถดำเนินการให้เสร็จสมบูรณ์อย่างสมบูรณ์และสำเร็จได้ โดยรักษาความสมบูรณ์ของข้อมูลและเป็นอิสระจากธุรกรรมอื่น ๆ ที่ทำงานแบบคู่ขนาน หรือไม่สามารถดำเนินการให้เสร็จสิ้นได้เลย ซึ่งในกรณีนี้จะไม่มีผลกระทบใดๆ ดังนั้นธุรกรรมจึงมีคุณสมบัติหลักสี่ประการ ซึ่งเรียกสั้น ๆ ว่า ACID มาดูกันว่าแต่ละตัวอักษรของตัวย่อนี้ย่อมาจากอะไร: A - Atomicity - atomicity - คุณสมบัตินี้รับประกันว่าจะไม่มีการบันทึกธุรกรรมบางส่วนในระบบ การดำเนินการย่อยทั้งหมดจะดำเนินการหรือไม่ดำเนินการเลย ( ทั้งหมดหรือไม่มีเลย ) C - ความสม่ำเสมอ - ความสอดคล้องเป็นคุณสมบัติที่ช่วยให้มั่นใจได้ว่าธุรกรรมที่ประสบความสำเร็จแต่ละรายการจะบันทึกเฉพาะผลลัพธ์ที่ถูกต้องเท่านั้น นั่นคือเป็นการรับประกันว่าในกรณีที่การทำธุรกรรมสำเร็จจะเป็นไปตามกฎและข้อจำกัดทั้งหมดที่ระบบกำหนดกับข้อมูลเฉพาะ มิฉะนั้นธุรกรรมจะไม่เสร็จสมบูรณ์และข้อมูลในระบบจะกลับสู่สถานะเดิม สถานะ. I - Isolation - การแยกเป็นคุณสมบัติที่บอกว่าในระหว่างการทำธุรกรรม ธุรกรรมแบบขนานไม่ควรส่งผลกระทบต่อผลลัพธ์ คุณสมบัตินี้ใช้ทรัพยากรมาก ดังนั้นจึงมักนำมาใช้ในบางส่วนโดยอนุญาตให้ใช้ฉนวนในระดับหนึ่งซึ่งช่วยแก้ปัญหาฉนวนบางอย่างได้ เราจะพูดถึงเรื่องนี้โดยละเอียดในคำถามถัดไป การวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 8 - 10D - Durability -คุณสมบัตินี้ช่วยให้มั่นใจได้ว่าหากผู้ใช้ได้รับการยืนยันจากระบบว่าธุรกรรมเสร็จสมบูรณ์ เขาสามารถมั่นใจได้ว่าการเปลี่ยนแปลงที่ทำไว้จะไม่ถูกยกเลิกเนื่องจากความล้มเหลวบางประการ นั่นคือคุณสามารถมั่นใจได้ว่าความล้มเหลวของระบบปฏิบัติการบางประเภทจะไม่ทำอะไรกับข้อมูลของคุณหากคุณได้รับการยืนยันว่าธุรกรรมของคุณเสร็จสมบูรณ์แล้ว

82. ระดับการแยกธุรกรรมมีอะไรบ้าง?

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

  • การอ่านแบบไม่ซ้ำ - เมื่อตัวอย่างเดียวกัน (แบบสอบถามเดียวกัน) ถูกเรียกซ้ำ ๆ ภายในธุรกรรมเดียวกัน ข้อมูลที่ได้รับจะแตกต่างกันซึ่งเกิดขึ้นเนื่องจากการเปลี่ยนแปลง (อัปเดต) และการลบข้อมูลโดยธุรกรรมอื่น

  • การอ่านสกปรก - กระบวนการอ่านข้อมูลที่เพิ่มหรือเปลี่ยนแปลงโดยธุรกรรมที่ไม่ได้รับการยืนยันในภายหลัง (ย้อนกลับ) เช่น การอ่านข้อมูลที่ไม่ถูกต้อง

  • สูญเสียการอัปเดต - เมื่อธุรกรรมที่แตกต่างกันเปลี่ยนข้อมูลเดียวกันในเวลาเดียวกัน การเปลี่ยนแปลงทั้งหมดยกเว้นรายการสุดท้ายจะหายไป (ชวนให้นึกถึงปัญหา "สภาพการแข่งขัน" ในสภาพแวดล้อมแบบมัลติเธรด)

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

83. คำชี้แจงและคำชี้แจงที่เตรียมไว้แตกต่างกันอย่างไร?

และที่นี่การเปลี่ยนไปใช้คุณสมบัติของ เทคโนโลยี JDBC ไม่ค่อยราบรื่น นัก ก่อนอื่น เรามาทำความเข้าใจก่อนว่าStatement คือ อะไร นี่คือวัตถุที่ใช้ในการสร้างแบบสอบถาม SQL JDBC ใช้สามประเภท - Statement , PreparationStatementและCallableStatement เราจะไม่ดูCallableStatement วันนี้: มาพูดถึงความแตกต่างระหว่าง StatementและReadyStatement กันดี กว่า
  1. คำสั่งใช้เพื่อดำเนินการสืบค้น SQL แบบง่าย ๆ โดยไม่ต้องแทรกพารามิเตอร์ขาเข้าแบบไดนามิก PreparStatementใช้กับความสามารถในการแทรกพารามิเตอร์อินพุตแบบไดนามิก

  2. ในการตั้งค่าพารามิเตอร์ในPreparedStatementพารามิเตอร์อินพุตในคำขอจะถูกเขียนเป็นเครื่องหมายคำถาม เพื่อที่จะแทรกค่าบางส่วนแทนค่าเหล่านั้นโดยใช้ตัวตั้งค่าต่างๆ เช่นsetDouble() , setFloat() , setInt() , setTime() .. .. ด้วยเหตุนี้ คุณจะไม่แทรกข้อมูลผิดประเภทลงในแบบสอบถามของคุณ

  3. ReadyStatementได้รับการ "คอมไพล์ล่วงหน้า" และใช้การแคช ดังนั้นการดำเนินการจึงเร็วกว่าการสืบค้นจาก ออบเจ็ ก ต์ Statement เล็กน้อย ผลก็คือ การสืบค้น SQL ที่ถูกดำเนินการบ่อยครั้งจะถูกเขียนเป็น อ็อบเจ็กต์ ReadyStatementเพื่อ ปรับปรุงประสิทธิภาพ

  4. คำสั่งมีความเสี่ยงต่อการถูกแทรก SQL ในขณะที่PreparedStatementป้องกันไว้ อ่านเพิ่มเติมเกี่ยวกับการกำจัดการแทรก SQL และแนวทางปฏิบัติที่ดีที่สุดอื่นๆ ในการรักษาความปลอดภัย Java ในบทความนี้

หากคุณกำลังเริ่มศึกษาเทคโนโลยีในการเชื่อมต่อแอปพลิเคชัน Java กับฐานข้อมูล - JDBC ฉันแนะนำให้คุณเริ่มด้วยบทความนี้ . ณ จุดนี้เราจะหยุดในวันนี้Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 8 - 11
วัสดุอื่นๆ ในชุด:
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION