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

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

เผยแพร่ในกลุ่ม
สวัสดี! ผู้คนมากมายมารวมตัวกันที่ JavaRush พวกเราบางคนแค่อยากจะเป็น Java Developer โดยทุ่มเวลาและความพยายามอย่างมากในการพัฒนา ในขณะที่คนอื่นๆ ก็เป็น Java Developer อยู่แล้ว ในกรณีใดกรณีหนึ่ง คุณจะต้องเตรียมพร้อมสำหรับการทดสอบ - การสัมภาษณ์ทางเทคนิค การทดสอบนี้ไม่ใช่เรื่องง่าย และนอกเหนือจากการเตรียมตัวทางศีลธรรมแล้ว ยังจำเป็นต้องมีการเตรียมทางเทคนิคอีกด้วย การวิเคราะห์คำถามและคำตอบในการสัมภาษณ์  ตอนที่ 1 - 1ฉันเพิ่งเจอ รายการ คำถามสัมภาษณ์นักพัฒนา Java จำนวนมากใน dou คำถามเหล่านี้แบ่งออกเป็นระดับต่างๆ - ระดับจูเนียร์ ระดับกลาง และระดับอาวุโส อย่าตกใจ: ไม่ใช่ทุกคำถามจะง่าย แต่คำถามที่มีเครื่องหมายดอกจันมักไม่ค่อยถูกถาม คำถามเป็นสิ่งที่ดี แต่ฉันอยากจะพยายามตอบส่วนใหญ่ เห็นได้ชัดว่าฉันจะไม่เข้าขอบเขตของบทความเดียวเพราะมีคำถามมากมายอยู่ที่นั่น ดังนั้นนี่จะเป็นบทความทั้งชุดที่ตอบคำถามดังกล่าว ฉันขอเน้นบางประเด็นทันที:
  1. มีบทความ ดีๆ พร้อมคำถามและคำตอบยอดนิยมสำหรับพวกเขา คำถามบางข้อทับซ้อนกับรายการที่นำเสนอข้างต้น (250+) ดังนั้นคำถามเหล่านี้จะถูกข้ามไปเพื่อไม่ให้ข้อมูลซ้ำอีกครั้ง

  2. คำถามจะถูกนำเสนอเป็นภาษายูเครน แต่เนื่องจากผู้เข้าร่วม JavaRush ส่วนใหญ่พูดภาษารัสเซีย (และฉันก็เช่นกัน) คำตอบจึงเป็นภาษารัสเซีย

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

เอาล่ะ มาเริ่มกันเลย

คำถามและคำตอบระดับจูเนียร์

การวิเคราะห์คำถามและคำตอบในการสัมภาษณ์  ส่วนที่ 1 - 2

ปัญหาทั่วไป

1. คุณรู้รูปแบบการออกแบบอะไรบ้าง? บอกเราเกี่ยวกับเทมเพลตทั้งสองที่คุณใช้ในการทำงานของคุณ

มีเทมเพลตมากมาย: คุณสามารถเริ่มทำความคุ้นเคยกับเทมเพลตเหล่านี้ได้จาก บทความ นี้และบทความนี้ สำหรับใครที่อยากทำความรู้จักแบบละเอียดๆ ผมแนะนำให้อ่านหนังสือ“Head First” ครับ รูปแบบการออกแบบ" . ด้วยความช่วยเหลือนี้ คุณสามารถศึกษารูปแบบการออกแบบขั้นพื้นฐานที่สุดได้อย่างละเอียดและง่ายดาย เมื่อพูดถึงรูปแบบการออกแบบที่คุณสามารถใช้เป็นตัวอย่างในการสัมภาษณ์ สิ่งที่นึกถึงได้แก่:
  • Builderเป็นเทมเพลตที่ใช้บ่อยซึ่งเป็นทางเลือกแทนการสร้างวัตถุแบบคลาสสิก
  • รูปแบบกลยุทธ์ซึ่งโดยเนื้อแท้แล้วแสดงถึงความหลากหลาย นั่นคือเรามีอินเทอร์เฟซเดียว แต่พฤติกรรมของโปรแกรมจะเปลี่ยนไปขึ้นอยู่กับการใช้งานเฉพาะของอินเทอร์เฟซนี้ที่ถูกถ่ายโอนไปยังฟังก์ชันการทำงาน (ตอนนี้กลยุทธ์นี้ใช้งานได้จริงทุกที่ในแอปพลิเคชัน Java)
หากนี่ยังไม่เพียงพอสำหรับคุณ ให้ใส่ใจกับSpring (หากคุณคุ้นเคยอยู่แล้ว) เพราะมันเป็นแพลตฟอร์มของเฟรมเวิร์กทั้งหมด ซึ่งในทางกลับกันจะเต็มไปด้วยรูปแบบขึ้นและลง นี่คือตัวอย่างบางส่วนของสิ่งที่ฉันกำลังพูดถึง:
  • โรงงาน - ใน ApplicationContext (หรือใน BeanFactory)
  • Singleton - ถั่วทั้งหมดเป็นซิงเกิลตันตามค่าเริ่มต้น
  • พร็อกซี - โดยพื้นฐานแล้วทุกสิ่งใน Spring ใช้รูปแบบนี้ไม่ทางใดก็ทางหนึ่ง เช่น AOP;
  • ห่วงโซ่ความรับผิดชอบเป็นรูปแบบตามแนวคิดที่ Spring Security ทำงาน
  • เทมเพลต - ใช้ใน Spring Jdbc

จาวาคอร์

การวิเคราะห์คำถามและคำตอบในการสัมภาษณ์  ส่วนที่ 1 - 3

2. Java มีข้อมูลประเภทใดบ้าง?

Java มีประเภทข้อมูลดั้งเดิม:
  • ไบต์ - จำนวนเต็มในช่วง -128 ถึง 127 มีน้ำหนัก 1 ไบต์
  • short — จำนวนเต็มในช่วง -32768 ถึง 32767 หนัก 2 ไบต์
  • int - จำนวนเต็ม -2147483648 ถึง 2147483647 มีน้ำหนัก 4 ไบต์
  • ยาว - จำนวนเต็มในช่วง 9223372036854775808 ถึง 9223372036854775807 มีน้ำหนัก 8 ไบต์
  • float — ตัวเลขทศนิยมในช่วง -3.4E+38 ถึง 3.4E+38 หนัก 4 ไบต์
  • double — ตัวเลขทศนิยมในช่วง -1.7E+308 ถึง 1.7E+308 หนัก 8 ไบต์
  • ถ่าน - อักขระเดี่ยวใน UTF-16 มีน้ำหนัก 2 ไบต์
  • ค่าบูลีนtrue/falseมีน้ำหนัก 1 ไบต์
และอ้างอิงชนิดข้อมูลซึ่งชี้ไปที่วัตถุบนฮีป

3. ออบเจ็กต์แตกต่างจากประเภทข้อมูลดั้งเดิมอย่างไร

ข้อแตกต่างประการแรก: จำนวนหน่วยความจำที่ถูกครอบครอง: primitives ใช้เวลาน้อยมาก เนื่องจากมีค่าของตัวเองเท่านั้น ในขณะที่ object สามารถมีค่าที่แตกต่างกันได้มากมาย: ทั้ง primitives และการอ้างอิงถึง object อื่น ๆ ข้อแตกต่างที่สอง: Java เป็นภาษาเชิงวัตถุ ดังนั้นทุกอย่างในนั้นทำงานผ่านการโต้ตอบระหว่างวัตถุ และภาษาพื้นฐานไม่เข้ากันเป็นอย่างดี (อันที่จริง นี่คือสาเหตุที่ Java ไม่ใช่ภาษาเชิงวัตถุ 100%) ประการที่สาม ต่อจากวินาที: เนื่องจาก Java มุ่งเน้นไปที่การโต้ตอบระหว่างอ็อบเจ็กต์ อ็อบเจ็กต์เหล่านี้จึงมีกลไกที่แตกต่างกันมากมายในการจัดการพวกมัน ตัวอย่างเช่น ตัวสร้าง วิธีการ ข้อยกเว้น (ซึ่งทำงานบนวัตถุเป็นหลัก) เป็นต้น ที่จริงแล้ว เพื่อให้ดั้งเดิมสามารถมีส่วนร่วม (งาน) ในสภาพแวดล้อมเชิงวัตถุนี้ wrappers ถูกประดิษฐ์ขึ้นสำหรับประเภทดั้งเดิม ( Integer , Character , Double , Boolean ...)

4. อะไรคือความแตกต่างระหว่างการส่งพารามิเตอร์โดยการอ้างอิงและตามค่า?

ฟิลด์ดั้งเดิมจะเก็บค่าของมัน: ตัวอย่างเช่น ถ้าเราตั้งค่าint i = 9; ฟิลด์iเก็บค่า9 เมื่อเรามีการอ้างอิงถึงวัตถุ นั่นหมายความว่าเรามีฟิลด์ที่มีการอ้างอิงถึงวัตถุ หรืออีกนัยหนึ่งคือ มีค่าของที่อยู่ของวัตถุในหน่วยความจำ
Cat cat = new Cat();
ปรากฎว่าฟิลด์ที่มีการอ้างอิงถึงวัตถุยังเก็บค่า ค่าที่อยู่หน่วยความจำ ด้วย นั่นคือcatเก็บค่าที่อยู่ของ วัตถุ Cat() ใหม่ไว้ในหน่วยความจำ เมื่อเราส่งพารามิเตอร์ไปยังวิธีการ ค่าของมันจะถูกคัดลอก ในกรณีของข้อมูลพื้นฐาน ค่าของข้อมูลพื้นฐานจะถูกคัดลอก ดังนั้นวิธีการนี้จะทำงานร่วมกับสำเนาซึ่งเปลี่ยนแปลงซึ่งจะไม่ส่งผลกระทบต่อต้นฉบับ ในกรณีของประเภทการอ้างอิง ค่าของที่อยู่หน่วยความจำจะถูกคัดลอก ตามลำดับ ที่อยู่จะเหมือนกับวัตถุที่ชี้ไป และถ้าเราเปลี่ยนออบเจ็กต์โดยใช้ลิงก์ใหม่นี้ มันก็จะเปลี่ยนไปสำหรับอันเก่า (ท้ายที่สุดแล้วทั้งคู่ก็ชี้ไปที่ออบเจ็กต์เดียวกัน)

5. JVM, JDK, JRE คืออะไร

JVM - Java Virtual Machineเป็นเครื่องเสมือนที่รัน Java bytecode ที่สร้างไว้ล่วงหน้าโดยคอมไพเลอร์ JRE - Java Runtime Environment - โดยพื้นฐานแล้วเป็นสภาพแวดล้อมสำหรับการรันแอปพลิเคชัน Java ซึ่งประกอบด้วยJVM , ไลบรารีมาตรฐาน และส่วนประกอบอื่นๆ สำหรับการรันแอปเพล็ตและแอปพลิเคชันที่เขียนด้วยภาษาการเขียนโปรแกรม Java กล่าวอีกนัยหนึ่งJREเป็นแพ็คเกจของทุกสิ่งที่จำเป็นในการรันโปรแกรม Java ที่คอมไพล์แล้ว แต่ไม่มีเครื่องมือและยูทิลิตี้เช่นคอมไพเลอร์หรือดีบักเกอร์สำหรับการพัฒนาแอปพลิเคชัน JDK - Java Development Kit - ชุดขยายของJREนั่นคือสภาพแวดล้อมที่ไม่เพียง แต่สำหรับการเปิดตัวเท่านั้น แต่ยังสำหรับการพัฒนาแอปพลิเคชัน Java ด้วย JDK มีทุกสิ่งที่อยู่ใน JRE รวมถึงเครื่องมือเพิ่มเติมต่างๆ - คอมไพเลอร์และดีบักเกอร์ที่จำเป็นในการสร้างแอปพลิเคชันใน Java (รวมถึงเอกสาร java ด้วย)การวิเคราะห์คำถามและคำตอบในการสัมภาษณ์  ส่วนที่ 1 - 4

6. ทำไมต้องใช้ JVM?

ตามที่กล่าวไว้ข้างต้น Java Virtual Machine เป็นเครื่องเสมือนที่รัน Java bytecode ที่สร้างไว้ล่วงหน้าโดยคอมไพเลอร์ นั่นคือ JVM ไม่เข้าใจซอร์สโค้ด Java ดังนั้น ขั้นแรก ไฟล์ .javaจะถูกคอมไพล์ซึ่งหลังจากการคอมไพล์มี นามสกุล .class อยู่แล้ว และแสดงในรูปแบบของโค้ดไบต์เดียวกันกับที่ JVM เข้าใจ แต่ละ OS มี JVM ของตัวเอง ดังนั้นเมื่อได้รับไฟล์ bytecode แล้ว JVM จะดำเนินการกับมัน โดยปรับให้เข้ากับ OS ที่มันเกิดขึ้น ที่จริงแล้ว เนื่องจาก JVM ที่แตกต่างกัน เวอร์ชัน JDK (หรือ JRE) จึงแตกต่างกันสำหรับ OS ที่แตกต่างกัน (แต่ละเวอร์ชันต้องใช้ JVM ของตัวเอง) เรามาจำไว้ว่าการพัฒนาทำงานอย่างไรในภาษาการเขียนโปรแกรมอื่นๆ คุณพัฒนาโปรแกรม จากนั้นโค้ดของโปรแกรมจะถูกคอมไพล์เป็นโค้ดเครื่องสำหรับระบบปฏิบัติการเฉพาะ จากนั้นคุณก็สามารถรันโปรแกรมได้ กล่าวอีกนัยหนึ่ง คุณต้องเขียนโปรแกรมเวอร์ชันที่แตกต่างกันสำหรับแต่ละระบบ ในขณะที่ใน Java ต้องขอบคุณการประมวลผลโค้ดคู่ (การคอมไพล์และการประมวลผลไบต์ของโค้ด JVM) คุณสามารถเพลิดเพลินกับคุณประโยชน์ของข้ามแพลตฟอร์มได้ ครั้งหนึ่งเราเคยสร้างโค้ด คอมไพล์ใหม่เป็นโค้ดไบต์ ถ่ายโอนไปยังระบบปฏิบัติการใดๆ และ JVM ภายในจะรันโค้ด นี่คือคุณสมบัติในตำนานของ Java - เขียนครั้งเดียวทำงานได้ทุกที่ การวิเคราะห์คำถามและคำตอบในการสัมภาษณ์  ส่วนที่ 1 - 5อ่านเพิ่มเติมเกี่ยวกับสิ่งนี้ในบทความ “ การคอมไพล์และรันแอปพลิเคชัน Java ภายใต้ประทุน

7. ไบต์โค้ดคืออะไร?

ดังที่ได้กล่าวไว้ข้างต้น คอมไพลเลอร์จะแปลงโค้ด Java เป็นโค้ดไบต์ ระดับกลาง (ไฟล์ที่มีนามสกุล .java เป็นไฟล์ที่มีนามสกุล .class) Bytecode มีความคล้ายคลึงกับรหัสเครื่องหลายประการ เพียงแต่ใช้ชุดคำสั่งที่ไม่ได้มาจากโปรเซสเซอร์จริง แต่มาจากชุดคำสั่งเสมือน นอกจากนี้ อาจรวมถึงส่วนที่เน้นไปที่การใช้คอมไพเลอร์ JIT ซึ่งปรับการดำเนินการคำสั่งให้เหมาะสมสำหรับโปรเซสเซอร์จริงที่โปรแกรมกำลังทำงานอยู่ การคอมไพล์ JIT หรือที่เรียกว่าการคอมไพล์แบบทันทีทันใดเป็นเทคโนโลยีที่เพิ่มประสิทธิภาพของโปรแกรมโดยใช้ bytecode โดยการคอมไพล์ bytecode ลงในเครื่องหรือรูปแบบอื่นในขณะที่โปรแกรมกำลังทำงาน ดังที่คุณอาจเดาได้ JVM ใช้คอมไพเลอร์ JIT เมื่อรัน bytecode มาดูตัวอย่าง bytecode กัน: การวิเคราะห์คำถามและคำตอบในการสัมภาษณ์  ส่วนที่ 1 - 6อ่านไม่ออกใช่ไหม? นี่ไม่ใช่คำสั่งสำหรับเรา แต่สำหรับ JVM นี่คือบทความที่จะช่วยให้คุณเข้าใจปัญหานี้ดีขึ้น

8. JavaBean มีคุณลักษณะอย่างไร?

JavaBeansเป็นคลาส Java ที่มีกฎบางอย่าง ต่อไปนี้เป็นกฎบางประการสำหรับการเขียนJavaBean :
  1. คลาสจะต้องมีตัวสร้างการเข้าถึงสาธารณะที่ว่างเปล่า (ไม่มีพารามิเตอร์) พร้อมด้วยตัว แก้ไขการเข้าถึง สาธารณะ ตัวสร้างนี้ทำให้สามารถสร้างอ็อบเจ็กต์ของคลาสนี้ได้โดยไม่มีปัญหาที่ไม่จำเป็น (เพื่อไม่ให้ยุ่งยากกับพารามิเตอร์โดยไม่จำเป็น)

  2. ฟิลด์ภายในของคลาสเข้าถึงได้ผ่าน เมธอด getและsetซึ่งควรเป็นมาตรฐาน ตัวอย่างเช่น หากฟิลด์คือ nameดังนั้นgetNameและsetNameเป็นต้น ซึ่งในทางกลับกัน จะทำให้เครื่องมือต่างๆ (เฟรมเวิร์ก) สามารถกำหนดและอัพเดตเนื้อหาของ bean โดยอัตโนมัติโดยไม่มีความยุ่งยาก

  3. คลาสจะต้องมีเวอร์ชันที่ถูกแทนที่ของเมธอดเท่ากับ() hashCode()และtoString()

  4. คลาสจะต้องทำให้เป็นอนุกรมได้ กล่าวคือ ต้องมีอินเทอร์เฟซมาร์กเกอร์ - ทำให้เป็นอนุกรมได้ หรือใช้ อินเทอร์เฟซ ภายนอกได้ นี่เป็นสิ่งจำเป็นเพื่อให้สามารถบันทึก จัดเก็บ และกู้คืนสถานะของถั่วได้อย่างน่าเชื่อถือ

การวิเคราะห์คำถามและคำตอบในการสัมภาษณ์  ตอนที่ 1 - 7คุณสามารถอ่านเกี่ยวกับประเภทของ JavaBeans ได้ในเนื้อหานี้

9. OutOfMemoryError คืออะไร

OutOfMemoryErrorเป็นหนึ่งในข้อผิดพลาดรันไทม์ที่สำคัญที่เกี่ยวข้องกับการทำงานของ Java Virtual Machine (JVM) เรียกว่าเมื่อ JVM ไม่สามารถจัดสรรอ็อบเจ็กต์ได้เนื่องจากมีหน่วยความจำไม่เพียงพอและตัวรวบรวมขยะไม่สามารถจัดสรรหน่วยความจำเพิ่มเติมได้ OutOfMemoryErrorบางประเภท:
  • OutOfMemoryError: พื้นที่ฮีป Java - ไม่สามารถจัดสรรออบเจ็กต์บนฮีป Java ได้เนื่องจากหน่วยความจำไม่เพียงพอ ข้อผิดพลาดอาจเกิดจากหน่วยความจำรั่วหรือเนื่องจากขนาดฮีปเริ่มต้นไม่ใหญ่พอสำหรับแอปพลิเคชันปัจจุบัน

  • OutOfMemoryError: เกินขีดจำกัดค่าโสหุ้ย GC - เนื่องจากปริมาณข้อมูลแทบจะไม่พอดีกับฮีป ตัวรวบรวมขยะทำงานตลอดเวลา และโปรแกรม Java ทำงานช้ามาก และด้วยเหตุนี้ ขีดจำกัดค่าโสหุ้ยของตัวรวบรวมขยะ เกินและแอปพลิเคชันขัดข้องด้วยข้อผิดพลาดนี้

  • OutOfMemoryError: ขนาดอาร์เรย์ที่ร้องขอเกินขีดจำกัด VM - บ่งชี้ว่าแอปพลิเคชันพยายามจัดสรรหน่วยความจำสำหรับอาร์เรย์ที่มีขนาดใหญ่กว่าขนาดฮีป ซึ่งอาจเกิดจากการจัดสรรหน่วยความจำเริ่มต้นไม่เพียงพออีกครั้ง

  • OutOfMemoryError: Metaspace — ฮีปมีพื้นที่ว่างที่จัดสรรสำหรับข้อมูลเมตาไม่เพียงพอ (ข้อมูลเมตาคือคำสั่งสำหรับคลาสและวิธีการ)

  • OutOfMemoryError: ร้องขอขนาดไบต์ด้วยเหตุผล พื้นที่สว็อปไม่เพียงพอ - ความล้มเหลวบางอย่างเกิดขึ้นเมื่อพยายามจัดสรรหน่วยความจำจากฮีป และเป็นผลให้ไม่มีหน่วยความจำในฮีป

10. การติดตามสแต็กคืออะไร? จะได้รับมันได้อย่างไร?

Stack Trace คือรายการคลาสและวิธีการที่ถูกเรียกจนถึงจุดนี้ในแอปพลิเคชัน คุณสามารถเรียกการติดตามสแต็ก ณ จุดใดจุดหนึ่งในแอปพลิเคชันได้ดังนี้:
StackTraceElement[] stackTraceElements =Thread.currentThread().getStackTrace();
วิธีนี้เราจะได้อาร์เรย์ขององค์ประกอบการติดตามสแต็กที่จัดเรียงตามลำดับ LIFO - Last In First Out การวิเคราะห์คำถามและคำตอบในการสัมภาษณ์  ส่วนที่ 1 - 8ตามกฎแล้วใน Java เมื่อเราพูดถึงการติดตามสแต็ก เราหมายถึงการติดตามสแต็กที่แสดงในคอนโซลเมื่อมีข้อผิดพลาด (หรือข้อยกเว้น) เกิดขึ้น คุณสามารถรับการติดตามสแต็กของข้อยกเว้นได้ดังนี้:
StackTraceElement[] stackTraceElements;
try{
                ...
} catch (Exception e) {
   stackTraceElements = e.getStackTrace();
}
ถ้าเรากำลังพูดถึงการส่งออกการติดตามสแต็กข้อยกเว้นในคอนโซล:
try{
                ...
} catch (Exception e) {
  e.printStackTrace();
}
นอกจากนี้ หากเรามีข้อผิดพลาด ข้อยกเว้น ที่ไม่ได้ตรวจสอบหรือข้อยกเว้นที่ตรวจสอบซึ่งเราจะไม่ดำเนินการ แต่จะส่งต่อเท่านั้น จากนั้นเมื่อแอปพลิเคชันขัดข้อง เราจะได้รับการติดตามสแต็กของข้อยกเว้นในคอนโซลโดยอัตโนมัติ ตัวอย่างเล็กๆ ของข้อยกเว้นการติดตามสแต็กในคอนโซล: การวิเคราะห์คำถามและคำตอบในการสัมภาษณ์  ส่วนที่ 1 - 9คุณสามารถอ่านเพิ่มเติมเกี่ยวกับ Stack Trace ได้ที่นี่ เราจะเน้นไปที่ปัญหานี้ในวันนี้...การวิเคราะห์คำถามและคำตอบในการสัมภาษณ์  ส่วนที่ 1 - 10
วัสดุอื่นๆ ในชุด:
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION