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

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

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

89. ArrayList แตกต่างจาก LinkedList อย่างไร

นี่เป็นหนึ่งในคำถามยอดนิยมพร้อมกับคำถามเกี่ยวกับโครงสร้างภายในของ HashMap การสัมภาษณ์เพียงครั้งเดียวจะไม่สมบูรณ์หากไม่มีการสัมภาษณ์ ดังนั้น คำตอบของการสัมภาษณ์จึงควร "ทำให้คุณหลุดออกจากฟัน" นอกจากชื่อที่ชัดเจนแล้ว - ชื่อที่แตกต่างกัน - โครงสร้างภายในยังแตกต่างกัน ก่อนหน้านี้ เราได้ตรวจสอบโครงสร้างภายในของทั้งArrayListและLinkedListแล้ว ดังนั้นฉันจะไม่ลงรายละเอียดเกี่ยวกับการนำไปใช้งาน ฉันขอเตือนคุณว่าArrayListถูกนำมาใช้โดยยึดตามอาร์เรย์ภายใน ซึ่งจะเพิ่มขึ้นตามความจำเป็นตามสูตร:
<размерТекущегоМассива> * 3 / 2  + 1
ในเวลาเดียวกันLinkedListจะถูกนำไปใช้ตามรายการที่เชื่อมโยงแบบทวีคูณภายใน นั่นคือแต่ละองค์ประกอบมีลิงก์ไปยังรายการก่อนหน้าและถัดไป โดยไม่รวมค่าที่เป็นจุดเริ่มต้น/จุดสิ้นสุดของรายการ ผู้คนชอบถามคำถามนี้ในรูปแบบ: “อันไหนดีกว่า - ArrayListหรือLinkedList ?” หวังว่าจะจับคุณได้ ท้ายที่สุดแล้ว หากคุณชี้ไปที่คำตอบใดข้อหนึ่ง มันจะเป็นคำตอบที่ผิด การวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 10 - 2คุณควรชี้แจงให้ชัดเจนว่าคุณกำลังพูดถึงสถานการณ์ใด - การเข้าถึงดัชนีหรือการแทรกลงในรายการ คุณจะสามารถอธิบายตัวเลือกของคุณได้ ทั้งนี้ขึ้นอยู่กับคำตอบ ก่อนหน้านี้ฉันได้อธิบายไปแล้วว่าArrayListและLinkedList ทำงานอย่างไร ในสถานการณ์ใดสถานการณ์หนึ่ง ลองสรุปสิ่งนี้โดยวางไว้ในหน้าเดียวกันเพื่อเปรียบเทียบ: การเพิ่มองค์ประกอบ (เพิ่ม)
  1. Добавление нового element без указания индекса How местоположения будет происходить автоматически в конец обоих списков. В LinkedList новый элемент станет новым хвостом (происходит только перезаписывание пары ссылок — алгоритмическая сложность O(1)).

    В ArrayList будет добавлен новый элемент в последнюю пустую ячейку массива — O(1).

  2. Добавление element по индексу How правило подразумевает вставку примерно в середину списка. В LinkedList сперва будет вестись поиск нужного места с помощью перебора элементов с “хвоста” и “головы” — O(n/2), а после — вставка значения путем переопределения ссылок элементов, между которыми вставляется новый — O(1). Суммарная алгоритмическая сложность данного действия будет O(n/2).

    ArrayList в данной ситуации по индексу находит элемент — O(1), и все элементы справа (включая элемент, который уже хранится по данному индексу) двигаются на одну единицу вправо (при этом возможно понадобится создание нового списка и копирование элементов в него) — O(n/2). Суммарная сложность — O(n/2).

  3. Добавление element в начало списка в LinkedList будет ситуация схожая с добавлением в конец: новый элемент станет новой “головой” — O(1), в то же время когда ArrayList-у нужно будет двигать все элементы вправо — O(n).

บรรทัดล่าง: ในLinkedListความซับซ้อนของอัลกอริทึมจะมีตั้งแต่O(1)ถึงO(n/2 ) กล่าวคือ ยิ่งการแทรกอยู่ใกล้จุดสิ้นสุดหรือจุดเริ่มต้นของรายการมากเท่าใด การแทรกก็จะยิ่งเร็วขึ้นเท่านั้น ในเวลาเดียวกัน สำหรับArrayListจะมีช่วงตั้งแต่O(1)ถึงO(n) : ยิ่งการแทรกอยู่ใกล้จุดสิ้นสุดของรายการมากเท่าใด ก็จะยิ่งเร็วขึ้นเท่านั้น การตั้งค่าองค์ประกอบ (ชุด) การดำเนินการนี้จะเขียนองค์ประกอบไปยังตำแหน่งที่ระบุในรายการ โดยเขียนทับองค์ประกอบก่อนหน้า ถ้ามี ในLinkedListการดำเนินการนี้จะคล้ายกับการเพิ่ม เนื่องจาก ความยากที่ใหญ่ที่สุดที่นี่คือการค้นหาองค์ประกอบ การเขียนองค์ประกอบใหม่จะเกิดขึ้นโดยการเขียนคู่ลิงก์ใหม่ ดังนั้นความซับซ้อนของอัลกอริทึมก็จะอยู่ในช่วงตั้งแต่O(1)ถึงO(n/2)ขึ้นอยู่กับระยะห่างของตำแหน่งจากจุดสิ้นสุดหรือจุดเริ่มต้นของรายการ ในเวลานั้น เซลล์ที่ต้องการจะอยู่ในArrayListสำหรับการดำเนินการดัชนีนี้ และองค์ประกอบใหม่จะถูกเขียนลงไป การค้นหาดัชนี เช่นเดียวกับการดำเนินการนี้ มีความซับซ้อนของอัลกอริธึมO(1 ) รับองค์ประกอบตามดัชนี (รับ) ในLinkedListการรับองค์ประกอบจะเกิดขึ้นตามหลักการเดียวกันกับการค้นหาการดำเนินการอื่น ๆ - ขึ้นอยู่กับระยะห่างจากจุดสิ้นสุดหรือจุดเริ่มต้นเช่น จากO(1)ถึงO(n/2) . ในArrayListอย่างที่ฉันพูดไปก่อนหน้านี้ การค้นหาองค์ประกอบในอาร์เรย์ด้วยดัชนีมี ความซับซ้อน O(1 ) ลบองค์ประกอบตามดัชนี (ลบ) สำหรับLinkedListหลักการทำงานของมันยังใช้งานได้ที่นี่: ก่อนอื่นจะพบองค์ประกอบจากนั้นลิงก์จะถูกเขียนทับ - เพื่อนบ้านขององค์ประกอบเริ่มอ้างอิงถึงกันและกันโดยสูญเสียการอ้างอิงถึงองค์ประกอบนี้ซึ่ง จะถูกลบโดยตัวรวบรวมขยะในภายหลัง นั่นคือความซับซ้อนของอัลกอริทึมยังคงเหมือนเดิม - จากO(1)ถึงO(n/2 ) สำหรับArrayListการดำเนินการนี้จะคล้ายกับการดำเนินการเพิ่มองค์ประกอบใหม่ (เพิ่ม) ขั้นแรกให้ค้นหาองค์ประกอบที่ต้องการ - O(1)จากนั้นจะถูกลบออกและองค์ประกอบทั้งหมดที่อยู่ทางด้านขวาจะถูกย้ายไปทางซ้ายหนึ่งหน่วยเพื่อปิดช่องว่างที่เกิดขึ้น การดำเนินการลบจะมีความซับซ้อนของอัลกอริทึมเช่นเดียวกับการดำเนินการเพิ่ม - ตั้งแต่O(1)ถึงO(n ) ยิ่งการลบอยู่ใกล้จุดสิ้นสุดของรายการมากเท่าใด ความซับซ้อนของอัลกอริทึมก็จะน้อยลงเท่านั้น จริงๆ แล้วสิ่งเหล่านี้ล้วนเป็นปฏิบัติการหลักทั้งสิ้น ฉันขอเตือนคุณ: เมื่อเปรียบเทียบทั้งสองรายการนี้ คุณต้องชี้แจงว่าเรากำลังพูดถึงสถานการณ์ใดโดยเฉพาะ จากนั้นคุณก็สามารถตอบคำถามที่ตั้งไว้ได้อย่างไม่คลุมเครือ

90. ArrayList แตกต่างจาก HashSet อย่างไร

หาก สามารถเปรียบเทียบ ArrayListและLinkedListในแง่ของการดำเนินการ - ซึ่งดีกว่า - การเปรียบเทียบ ArrayListกับHashSet นั้น ไม่ใช่เรื่องง่าย เพราะสิ่งเหล่านี้เป็นคอลเลกชันที่แตกต่างกันโดยสิ้นเชิง คุณสามารถเปรียบเทียบอาหารจานหวานจานหนึ่งกับอีกจานหนึ่งได้ แต่จานเนื้อจะได้ผล - มันแตกต่างกันเกินไป อย่างไรก็ตาม ฉันจะพยายามให้ความแตกต่างระหว่างพวกเขา:
  • ArrayListใช้ อินเทอร์เฟซ รายการในขณะที่HashSetใช้ อินเทอร์เฟ ซ Set ;

  • ในArrayListการเข้าถึงสามารถทำได้ด้วยดัชนีองค์ประกอบ: การดำเนินการ getมีความซับซ้อนของอัลกอริธึมO(1)และในHashSetองค์ประกอบที่ต้องการสามารถรับได้โดยใช้กำลังเดรัจฉานเท่านั้น และนี่คือจากO(1)ถึงO(n) ;

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

  • ArrayList ถูกนำไปใช้ โดยใช้อาร์เรย์ภายใน และHashSet ถูกนำไปใช้โดยใช้ HashMapภายใน

  • ArrayListรักษาลำดับการแทรกขององค์ประกอบ ในขณะที่HashSetเป็นชุดที่ไม่เรียงลำดับและไม่รักษาลำดับขององค์ประกอบ

  • ArrayListอนุญาตให้มีค่าว่างจำนวนเท่าใดก็ได้ (null) สามารถแทรกค่า null ได้เพียงค่าเดียวลงในHashSet (หลังจากนั้นคือเอกลักษณ์ขององค์ประกอบ)

91. เหตุใดจึงมีการใช้งานอาร์เรย์แบบไดนามิกที่หลากหลายใน Java?

การวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 10 - 3นี่เป็นคำถามเชิงปรัชญามากกว่า ทำไมพวกเขาถึงเกิดเทคโนโลยีใหม่ที่แตกต่างกันมากมาย? เพื่อความสะดวกสบาย จริงๆ แล้ว มันก็เหมือนกันกับการใช้งานอาร์เรย์แบบไดนามิกจำนวนมาก ไม่มีใครสามารถเรียกได้ว่าดีที่สุดหรืออุดมคติ แต่ละคนมีข้อได้เปรียบในสถานการณ์เฉพาะบางอย่าง และหน้าที่ของเราคือการรู้ความแตกต่าง จุดแข็ง/จุดอ่อน เพื่อให้สามารถใช้สิ่งที่เหมาะสมที่สุดในสถานการณ์ที่เหมาะสมได้

92. เหตุใดจึงมีการใช้งานหน่วยเก็บข้อมูลคีย์-ค่าที่หลากหลายใน Java?

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

93. จะเรียงลำดับคอลเลกชันขององค์ประกอบได้อย่างไร?

สิ่งแรกที่ต้องพูดคือคลาสองค์ประกอบคอลเลกชันต้องใช้ อินเทอร์เฟซ ที่เปรียบเทียบได้และวิธี การ เปรียบเทียบTo หรือคุณต้องการคลาสที่ใช้Comapratorด้วยวิธีcomparator คุณสามารถอ่านเพิ่มเติมเกี่ยวกับพวกเขาได้ในโพสต์นี้ ทั้งสองวิธีระบุวิธีการเปรียบเทียบวัตถุประเภทที่กำหนด เมื่อทำการเรียงลำดับ สิ่งนี้มีความสำคัญอย่างยิ่ง เนื่องจากคุณต้องเข้าใจหลักการที่สามารถเปรียบเทียบองค์ประกอบต่างๆ ได้ วิธีหลักในการทำเช่นนี้คือการใช้Comparableซึ่งนำไปใช้โดยตรงในคลาสที่คุณต้องการเรียงลำดับ ในขณะเดียวกัน การใช้Comparatorก็ไม่ค่อยพบบ่อยนัก สมมติว่าคุณกำลังใช้คลาสจากไลบรารีบางแห่งที่ไม่มีComparable Implement แต่คุณจะต้องจัดเรียงมันด้วยวิธีใดวิธีหนึ่ง โดยไม่ต้องเปลี่ยนโค้ดของคลาสนี้ (ยกเว้นการขยาย) คุณสามารถเขียนการใช้งานComparatorซึ่งคุณระบุหลักการที่คุณต้องการเปรียบเทียบอ็อบเจ็กต์ของคลาสนี้ และอีกตัวอย่างหนึ่ง สมมติว่าคุณต้องการหลักการที่แตกต่างกันในการเรียงลำดับวัตถุประเภทเดียวกัน ดังนั้นคุณจึงเขียนตัวเปรียบเทียบ หลายตัว ที่คุณใช้ในสถานการณ์ที่แตกต่างกัน ตามกฎแล้ว คลาสจำนวนมากนอกกรอบได้ใช้ อินเทอร์เฟซ ที่เปรียบเทียบได้ - String เดียวกันอยู่ แล้ว จริงๆ แล้วเวลาใช้ก็ไม่ต้องกังวลว่าจะเปรียบเทียบยังไง คุณเพียงแค่พาพวกเขาและใช้พวกเขา วิธี แรกและชัดเจนที่สุดคือการใช้คอลเลกชันเช่นTreeSetหรือTreeMapซึ่งจัดเก็บองค์ประกอบตามลำดับที่เรียงลำดับแล้วตามตัวเปรียบเทียบคลาสองค์ประกอบ โปรดจำไว้ว่าTreeMapเรียงลำดับคีย์ แต่ไม่ใช่ค่า หากคุณใช้ComparatorแทนComparableคุณจะต้องส่งอ็อบเจ็กต์ของมันไปยังตัวสร้างคอลเลกชันเมื่อสร้าง:
TreeSet treeSet = new TreeSet(customComparator);
แต่ถ้าคุณมีคอลเลกชันประเภทอื่นล่ะ? จะเรียงลำดับอย่างไร? ในกรณีนี้ วิธี ที่สองของ คลาสยูทิลิตี้ Collections มีความเหมาะสม - วิธีsort() มันเป็นค่าคงที่ ดังนั้นสิ่งที่คุณต้องมีคือชื่อของคลาสและวิธีการที่จะส่งรายการที่ต้องการไป ตัวอย่างเช่น:
Collections.sort(someList);
หากคุณไม่ได้ใช้Comparableแต่เป็นการใช้งานComparatorคุณจะต้องส่งผ่านเป็นพารามิเตอร์ตัวที่สอง:
Collections.sort(someList, customComparator);
เป็นผลให้ลำดับภายในขององค์ประกอบของรายการที่ส่งผ่านจะเปลี่ยนไป: จะถูกจัดเรียงตามตัวเปรียบเทียบองค์ประกอบ ฉันทราบว่ารายการองค์ประกอบที่ถ่ายโอนจะต้องไม่แน่นอน เช่น ไม่แน่นอน มิฉะนั้นวิธีการจะไม่ทำงานและUnsupportedOperationException จะถูกส่งออก ไป วิธีที่ 3คุณสามารถใช้การดำเนินการStream sortซึ่งจะเรียงลำดับองค์ประกอบของคอลเลกชันหาก ใช้ Comparable Implementation :
someList = someList.stream().sorted().collect(Collectors.toList());
ถ้าตัวเปรียบเทียบ :
someList = someList.stream().sorted(customComparator).collect(Collectors.toList());
คุณสามารถอ่าน เพิ่มเติมเกี่ยวกับสตรีมได้ใน บทความนี้ วิธี ที่สี่คือการใช้การเรียงลำดับด้วยตนเอง เช่นการเรียงลำดับแบบฟองหรือการ เรียงลำดับแบบผสาน

ClassObject. เท่ากับและ HashCode

94. ให้คำอธิบายโดยย่อเกี่ยวกับคลาสอ็อบเจ็กต์ใน Java

ในส่วนที่สองของการวิเคราะห์ เราได้พูดถึงวิธีการของ คลาส Object แล้ว และฉันจะเตือนคุณว่า คลาส Objectนั้นเป็นต้นกำเนิดของคลาสทั้งหมดใน Java มี 11 วิธีซึ่งสืบทอดมาจากทุกคลาส การวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 10 - 4ข้อมูลเกี่ยวกับทั้ง 11 วิธีสามารถพบได้ในส่วนที่สองของการสนทนา

95. Equals และ HashCode ใช้สำหรับอะไรใน Java?

hashCode()เป็นวิธีการของ คลาส Objectที่สืบทอดมาจากคลาสทั้งหมด หน้าที่ของมันคือการสร้างตัวเลขที่แสดงถึงวัตถุเฉพาะ ตัวอย่างของการใช้วิธีการนี้คือการใช้งานในHashMapบนออบเจ็กต์หลักเพื่อกำหนดรหัสแฮชในเครื่องเพิ่มเติม ซึ่งจะกำหนดเซลล์ของอาร์เรย์ภายใน (ที่เก็บข้อมูล) ที่จะจัดเก็บคู่ดังกล่าว เราได้พูดคุยโดยละเอียดเกี่ยวกับงานของHashMap ในส่วนที่ 9 ของการวิเคราะห์ดังนั้นเราจะไม่จมอยู่กับเรื่องนี้มากเกินไป การวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 10 - 5นอกจากนี้ ตามกฎแล้ว วิธีการนี้ใช้ใน วิธี เท่ากับ()ซึ่งเป็นหนึ่งในเครื่องมือหลักในการกำหนดเอกลักษณ์ของวัตถุ เท่ากับ()เป็นวิธีการของ คลาส Objectซึ่งมีหน้าที่ในการเปรียบเทียบวัตถุและพิจารณาว่าวัตถุนั้นเท่ากันหรือไม่ วิธีการนี้ใช้ทุกที่ที่เราต้องการเปรียบเทียบวัตถุ เนื่องจากการเปรียบเทียบตามปกติโดยใช้==ไม่เหมาะกับวัตถุ เนื่องจาก เปรียบเทียบเฉพาะลิงก์กับพวกเขา

96. บอกเราเกี่ยวกับสัญญาระหว่าง Equals และ HashCode ใน Java หน่อยได้ไหม

สิ่งแรกที่ฉันจะพูดคือเพื่อให้เมธอดเท่ากับ ()และhashCode() ทำงานได้อย่างถูกต้อง พวกเขาจำเป็นต้องเขียนทับอย่างถูกต้อง หลังจากนี้พวกเขาจะต้องปฏิบัติตามกฎ:
  • วัตถุที่เหมือนกันซึ่งการเปรียบเทียบผ่านผลตอบแทน ที่ เท่ากันจะต้องมีรหัสแฮชที่เหมือนกัน
  • ออบเจ็กต์ที่มีรหัสแฮชเดียวกัน อาจ ไม่เท่ากัน เสมอไป
ณ จุดนี้ เราจะหยุดชั่วคราวจนกว่าจะถึงส่วนถัดไปของการวิเคราะห์!การวิเคราะห์คำถามและคำตอบจากการสัมภาษณ์นักพัฒนา Java  ตอนที่ 10 - 6
วัสดุอื่นๆ ในชุด:
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION