71. จะเกิดอะไรขึ้นถ้าเราไม่แทนที่เมธอด toString() สำหรับ Enum
สมมติว่าเรามีenum ต่อไปนี้ :public enum Role {
STUDENT,
TEACHER,
DIRECTOR,
SECURITY_GUARD;
}
มาแสดงนักเรียนในคอนโซลโดยเรียก toString() กับเขา:
System.out.println(Role.STUDENT.toString());
ผลลัพธ์ในคอนโซล:
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การเปรียบเทียบทั้งผ่าน==และเท่ากับนั้นถูกต้อง
74. วิธีลำดับ () ทำอะไรใน Enum?
เมื่อเรียกใช้เมธอดint ordinal()บนอิ ลิเมนต์ enumเราจะได้เลขลำดับจากศูนย์ของค่านี้ในชุดการแจงนับทั่วไป ลองใช้วิธีนี้กับองค์ประกอบหนึ่งจากenum ก่อนหน้านี้ที่กล่าวถึง - Role :System.out.println(Role.DIRECTOR.ordinal());
ดังนั้นคอนโซลจะแสดง:
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);
และคอนโซลจะแสดง:
76. วิธีการเรียงลำดับ () และ comparisonTo () เกี่ยวข้องกันใน Enum อย่างไร
ตามที่ระบุไว้ก่อนหน้านี้ordinal()ส่งคืนเลขลำดับของค่าในรายการแจงนับทั่วไป นอกจากนี้ ในการวิเคราะห์คำถาม ก่อนหน้านี้ คุณเห็นว่าองค์ประกอบของการแจงนับ ตัวอย่างเช่น ใน ชุด TreeSet (ชุดที่เรียงลำดับ) ใช้ลำดับที่ประกาศไว้ในenum และดังที่เราทราบTreeSetและTreeMapเรียงลำดับองค์ประกอบโดยการเรียกเมธอดcomparisonTo () ของ Comparable interface จากนี้เราสามารถสรุปได้ว่า คลาส Enumใช้งานComparable interface โดยนำไปใช้ใน เมธอด comparisonTo()ซึ่งภายในordinal() ใช้ เพื่อกำหนดลำดับการจัดเรียง เมื่อเข้าสู่ คลาส Enumเราจะเห็นการยืนยันสิ่งนี้: และเนื้อความของวิธีการนั้นเอง: ไม่ได้เรียกเมธอดordinal() ที่นี่ แต่ จะใช้ตัวแปร ลำดับ แทน - เลขลำดับขององค์ประกอบในการแจงนับ เมธอด ordinal()นั้นไม่มีอะไรมากไปกว่า 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เป็นวิธีการใหม่ในการโต้ตอบกับสตรีมข้อมูล ซึ่งจะช่วยให้คุณประมวลผลข้อมูลขนาดใหญ่ได้สะดวกและกะทัดรัดยิ่งขึ้น ตลอดจนทำการประมวลผลข้อมูลแบบขนานระหว่างเธรดจำนวนหนึ่ง ซึ่งสามารถเพิ่มประสิทธิภาพในการใช้งานได้ ฟังก์ชั่น หัวข้อนี้ไม่สามารถพูดคุยอย่างลึกซึ้งโดยสรุปได้ ดังนั้นฉันจะทิ้งลิงก์ไปยังบทความที่สามารถช่วยให้คุณเจาะลึกในหัวข้อนี้ได้81. คุณสมบัติหลักของธุรกรรมมีอะไรบ้าง?
หัวข้อนี้เรียกว่า Stream API แต่คำถามเกี่ยวกับธุรกรรม อืม... ก่อนอื่น เรามาดูกันว่าธุรกรรมคืออะไร ธุรกรรมคือกลุ่มของการดำเนินการฐานข้อมูลตามลำดับซึ่งแสดงถึงหน่วยลอจิคัลของการทำงานกับข้อมูล ธุรกรรมสามารถดำเนินการให้เสร็จสมบูรณ์อย่างสมบูรณ์และสำเร็จได้ โดยรักษาความสมบูรณ์ของข้อมูลและเป็นอิสระจากธุรกรรมอื่น ๆ ที่ทำงานแบบคู่ขนาน หรือไม่สามารถดำเนินการให้เสร็จสิ้นได้เลย ซึ่งในกรณีนี้จะไม่มีผลกระทบใดๆ ดังนั้นธุรกรรมจึงมีคุณสมบัติหลักสี่ประการ ซึ่งเรียกสั้น ๆ ว่า ACID มาดูกันว่าแต่ละตัวอักษรของตัวย่อนี้ย่อมาจากอะไร: A - Atomicity - atomicity - คุณสมบัตินี้รับประกันว่าจะไม่มีการบันทึกธุรกรรมบางส่วนในระบบ การดำเนินการย่อยทั้งหมดจะดำเนินการหรือไม่ดำเนินการเลย ( ทั้งหมดหรือไม่มีเลย ) C - ความสม่ำเสมอ - ความสอดคล้องเป็นคุณสมบัติที่ช่วยให้มั่นใจได้ว่าธุรกรรมที่ประสบความสำเร็จแต่ละรายการจะบันทึกเฉพาะผลลัพธ์ที่ถูกต้องเท่านั้น นั่นคือเป็นการรับประกันว่าในกรณีที่การทำธุรกรรมสำเร็จจะเป็นไปตามกฎและข้อจำกัดทั้งหมดที่ระบบกำหนดกับข้อมูลเฉพาะ มิฉะนั้นธุรกรรมจะไม่เสร็จสมบูรณ์และข้อมูลในระบบจะกลับสู่สถานะเดิม สถานะ. I - Isolation - การแยกเป็นคุณสมบัติที่บอกว่าในระหว่างการทำธุรกรรม ธุรกรรมแบบขนานไม่ควรส่งผลกระทบต่อผลลัพธ์ คุณสมบัตินี้ใช้ทรัพยากรมาก ดังนั้นจึงมักนำมาใช้ในบางส่วนโดยอนุญาตให้ใช้ฉนวนในระดับหนึ่งซึ่งช่วยแก้ปัญหาฉนวนบางอย่างได้ เราจะพูดถึงเรื่องนี้โดยละเอียดในคำถามถัดไป D - Durability -คุณสมบัตินี้ช่วยให้มั่นใจได้ว่าหากผู้ใช้ได้รับการยืนยันจากระบบว่าธุรกรรมเสร็จสมบูรณ์ เขาสามารถมั่นใจได้ว่าการเปลี่ยนแปลงที่ทำไว้จะไม่ถูกยกเลิกเนื่องจากความล้มเหลวบางประการ นั่นคือคุณสามารถมั่นใจได้ว่าความล้มเหลวของระบบปฏิบัติการบางประเภทจะไม่ทำอะไรกับข้อมูลของคุณหากคุณได้รับการยืนยันว่าธุรกรรมของคุณเสร็จสมบูรณ์แล้ว82. ระดับการแยกธุรกรรมมีอะไรบ้าง?
ดังที่ผมได้กล่าวไว้ก่อนหน้านี้ การแยกกรดเป็นกระบวนการที่ต้องใช้ทรัพยากรมาก ดังนั้นทรัพย์สินนี้จึงได้รับความพึงพอใจบางส่วน มีระดับการแยกตัวที่แตกต่างกัน และยิ่งระดับสูงเท่าใด ผลกระทบต่อผลผลิตก็จะยิ่งมากขึ้นเท่านั้น ก่อนที่จะก้าวไปสู่ระดับการแยกธุรกรรม เราต้องพิจารณาปัญหาต่าง ๆ ของการแยกธุรกรรมที่ไม่เพียงพอ :-
การอ่าน Phantom - เมื่อมีการเรียกตัวอย่างเดียวกัน (แบบสอบถามเดียวกัน) ซ้ำ ๆ ภายในธุรกรรมเดียวกัน ข้อมูลที่ได้รับจะแตกต่างกัน ซึ่งเกิดขึ้นเนื่องจากการแทรกข้อมูลโดยธุรกรรมอื่น
-
การอ่านแบบไม่ซ้ำ - เมื่อตัวอย่างเดียวกัน (แบบสอบถามเดียวกัน) ถูกเรียกซ้ำ ๆ ภายในธุรกรรมเดียวกัน ข้อมูลที่ได้รับจะแตกต่างกันซึ่งเกิดขึ้นเนื่องจากการเปลี่ยนแปลง (อัปเดต) และการลบข้อมูลโดยธุรกรรมอื่น
-
การอ่านสกปรก - กระบวนการอ่านข้อมูลที่เพิ่มหรือเปลี่ยนแปลงโดยธุรกรรมที่ไม่ได้รับการยืนยันในภายหลัง (ย้อนกลับ) เช่น การอ่านข้อมูลที่ไม่ถูกต้อง
-
สูญเสียการอัปเดต - เมื่อธุรกรรมที่แตกต่างกันเปลี่ยนข้อมูลเดียวกันในเวลาเดียวกัน การเปลี่ยนแปลงทั้งหมดยกเว้นรายการสุดท้ายจะหายไป (ชวนให้นึกถึงปัญหา "สภาพการแข่งขัน" ในสภาพแวดล้อมแบบมัลติเธรด)
ระดับการแยก | การอ่านแบบผี | การอ่านแบบไม่ซ้ำซาก | การอ่านสกปรก | การอัปเดตที่หายไป |
---|---|---|---|---|
เรียงลำดับได้ | + | + | + | + |
อ่านซ้ำได้ | - - | + | + | + |
อ่านมุ่งมั่น | - - | - - | + | + |
อ่านอย่างไม่มีข้อผูกมัด | - - | - - | - - | + |
ไม่มี | - - | - - | - - | - - |
83. คำชี้แจงและคำชี้แจงที่เตรียมไว้แตกต่างกันอย่างไร?
และที่นี่การเปลี่ยนไปใช้คุณสมบัติของ เทคโนโลยี JDBC ไม่ค่อยราบรื่น นัก ก่อนอื่น เรามาทำความเข้าใจก่อนว่าStatement คือ อะไร นี่คือวัตถุที่ใช้ในการสร้างแบบสอบถาม SQL JDBC ใช้สามประเภท - Statement , PreparationStatementและCallableStatement เราจะไม่ดูCallableStatement วันนี้: มาพูดถึงความแตกต่างระหว่าง StatementและReadyStatement กันดี กว่า-
คำสั่งใช้เพื่อดำเนินการสืบค้น SQL แบบง่าย ๆ โดยไม่ต้องแทรกพารามิเตอร์ขาเข้าแบบไดนามิก PreparStatementใช้กับความสามารถในการแทรกพารามิเตอร์อินพุตแบบไดนามิก
-
ในการตั้งค่าพารามิเตอร์ในPreparedStatementพารามิเตอร์อินพุตในคำขอจะถูกเขียนเป็นเครื่องหมายคำถาม เพื่อที่จะแทรกค่าบางส่วนแทนค่าเหล่านั้นโดยใช้ตัวตั้งค่าต่างๆ เช่นsetDouble() , setFloat() , setInt() , setTime() .. .. ด้วยเหตุนี้ คุณจะไม่แทรกข้อมูลผิดประเภทลงในแบบสอบถามของคุณ
-
ReadyStatementได้รับการ "คอมไพล์ล่วงหน้า" และใช้การแคช ดังนั้นการดำเนินการจึงเร็วกว่าการสืบค้นจาก ออบเจ็ ก ต์ Statement เล็กน้อย ผลก็คือ การสืบค้น SQL ที่ถูกดำเนินการบ่อยครั้งจะถูกเขียนเป็น อ็อบเจ็กต์ ReadyStatementเพื่อ ปรับปรุงประสิทธิภาพ
-
คำสั่งมีความเสี่ยงต่อการถูกแทรก SQL ในขณะที่PreparedStatementป้องกันไว้ อ่านเพิ่มเติมเกี่ยวกับการกำจัดการแทรก SQL และแนวทางปฏิบัติที่ดีที่สุดอื่นๆ ในการรักษาความปลอดภัย Java ในบทความนี้
GO TO FULL VERSION