ให้คำตอบ
ฉันจะบอกว่าถ้าผู้สมัครไม่สนใจพอที่จะถามฉันจะไม่เสียลมหายใจ แต่ คำตอบ @Yannis_Rizosดีกว่ามาก
การสัมภาษณ์เป็นไปอย่างรวดเร็ว ฉันรู้ว่าฉันมักจะมองหาสิ่งต่าง ๆ หลังจากวันสัมภาษณ์
คนที่ไม่สามารถรหัส FizzBuzz Classic ได้
ฉันจินตนาการว่าจุดเกาะติดขนาดใหญ่กำลังตระหนักถึงตัวดำเนินการ% คุณหวังว่าจะมีคนคิดเปรียบเทียบกัน(myInt / 3) == (myDouble / 3.0)
แต่อาจจะมีความเครียดจากการสัมภาษณ์ ... ถึงกระนั้น FizzBuzz Classic บังคับให้มีวิธีการที่โหดร้ายวางไว้ในหมวดของปัญหาอัลกอริทึมที่ง่ายที่สุดในการแก้ปัญหา คุณลองขอให้ผู้คนเขียนโค้ดครึ่งหนึ่งเป็น "เครดิตครึ่งเครดิต" และอาจเพิ่ม "Buzz" ในภายหลังเพื่อเพิ่มประสิทธิภาพหรือไม่
ฉันคิดว่าคำตอบที่ดีที่สุดสำหรับคำถามของคุณคือมันยากมากที่จะหาผู้สมัครที่ดี
คำถามสัมภาษณ์ทั่วไป
ฉันมักจะพบว่าง่ายขึ้นและมีประสิทธิภาพมากขึ้นในการขอให้ผู้สมัครอธิบายโครงการเขียนโปรแกรมล่าสุดที่พวกเขาตื่นเต้น ฉันประสบความสำเร็จกับคำถามนี้ 100% ซึ่งหมายความว่าคนที่พูดอย่างมีชีวิตชีวาเกี่ยวกับโครงการเขียนโปรแกรมและสามารถตอบคำถามทางเทคนิคเกี่ยวกับเรื่องนี้ได้รับการว่าจ้างที่ดีและผู้ที่ไม่สามารถทำได้ไม่ใช่ สิ่งนี้มีผลข้างเคียงที่ดีของการทำให้ผู้สมัครมีความสะดวกและกระตุ้นให้เกิดการสนทนาปลายเปิด ด้วยคำถามนี้ผู้สมัครจะบอกคุณถึงสิ่งที่พวกเขาเหมาะสมที่สุด
อาจจะเป็นคำถามที่คิดว่าอัลกอริทึมของรถถังนั้นมีความจำเป็นเช่นกัน แต่ฉันก็ทิ้งมันไว้ในคำถาม "โปรเจ็กต์สุดโปรด"
ผลรวม (ลูกชาย) ของ FizzBuzz
คำถามสัมภาษณ์ของคุณไม่เทียบเท่ากับ FizzBuzz:
ถ้าเราแสดงจำนวนธรรมชาติทั้งหมดต่ำกว่า 10 ที่เป็นทวีคูณของ 3 หรือ 5 เราจะได้ 3, 5, 6 และ 9 ผลรวมของทวีคูณเหล่านี้คือ 23. เขียนฟังก์ชันที่ค้นหาผลรวมของทวีคูณทั้งหมดของ 3 หรือ 5 ต่ำกว่า 1,000
ที่ FizzBuzz Classic บังคับให้คุณผ่านการทำซ้ำn (เพื่อพิมพ์ทุกหมายเลขหรือ Fizz / Buzz) ปัญหาของคุณสามารถทำได้ในการทำซ้ำn / 5 + n / 3 + n / 15 หรือแม้กระทั่งไม่มีการทำซ้ำ - การแก้ไขโดยตรง - การคำนวณคะแนนเป็นไปได้ โปรแกรมต่อไปนี้เปรียบเทียบวิธีการทั้งสามนี้:
public static void main(String[] args) {
long n = Long.valueOf(args[0]).longValue();
long sum = 0;
long ms = System.currentTimeMillis();
// Brute force method Performance: cn
for (long i = 1; i <= n; i++) {
if ((i % 3) == 0) { sum += i;
} else if ((i % 5) == 0) { sum += i; }
}
System.out.print("Brute force sum: " + sum);
System.out.println(" time: " + (System.currentTimeMillis() - ms));
ms = System.currentTimeMillis();
// Second solution: iterate through only numbers we are
// interested in. Performance: c * (n/3 + n/5 + n/15)
// We counted multiples of 15 twice, so subtract one of them
sum = countSum(n, 3) + countSum(n, 5) - countSum(n, 15);
System.out.print("Only multiples sum: " + sum);
System.out.println(" time: " + (System.currentTimeMillis() - ms));
ms = System.currentTimeMillis();
// Third solution: Use high school algebra. Performance: c
sum = sumSeries(n, 3) + sumSeries(n, 5) - sumSeries(n, 15);
System.out.print("Sum of series: " + sum);
System.out.println(" time: " + (System.currentTimeMillis() - ms));
}
// Iteravely sum all multiples of skip
private static long countSum(long n, long skip) {
long skipTotal = skip;
long grandTotal = 0;
while (skipTotal <= n) {
grandTotal += skipTotal; skipTotal += skip;
}
return grandTotal;
}
// Thanks to @Caleb for pointing this out! High school algebra
// tells us that the sum of a series is: (n * (a1 + an)) / 2
// where a1 is the first term and an is the nth term. E.g. The
// sum of a series of 3 is: (n/3 * (3 + n - (n % 3))) / 2
// Since we are thinking about performance here, we'll shift
// right one instead of dividing by 2 for style points. ;-D
private static long sumSeries(long n, long skip) {
return (n/skip * (skip + n - (n % skip))) >> 1;
}
ผลลัพธ์ (ผลรวมของ FizzBuzz <1,000):
$JDK_HOME/bin/java FizzBuzzNot 999
Brute force sum: 233168 time: 0
Only multiples sum: 233168 time: 0
Sum of series: 233168 time: 0
ด้วย n ที่ใหญ่กว่าสำหรับการเปรียบเทียบประสิทธิภาพ:
$JDK_HOME/bin/java FizzBuzzNot 1000000000
Brute force sum: 233333334166666668 time: 4744
Only multiples sum: 233333334166666668 time: 818
Sum of series: 233333334166666668 time: 0
หมายเหตุสำหรับผู้ที่ลงคะแนนให้เป็นนอกหัวข้อ
จุดประสงค์ของการนำเสนอวิธีแก้ปัญหาสำหรับคำถามนี้คือการแสดงให้เห็นว่าในขณะที่วิธีการแก้ปัญหาแบบ brute force สำหรับ Sum of FizzBuzz นั้นคล้ายคลึงกับ FizzBuzz Classic แต่การแก้ปัญหาแบบ Sum นั้นมีปัญหาที่ดีกว่าทำให้เป็นปัญหาที่แตกต่างกัน ผลรวมของ FizzBuzz นั้นยากมากถ้าคุณจำสูตรที่ไม่เหมาะสมสำหรับผลรวมของอนุกรมหรือไม่ทราบว่ามันใช้กับการก้าวเป็น 3 หรือ 5
หากคุณได้รับสูตรซ้ำสำหรับผลรวมของอนุกรมโดยแบ่งอนุกรมออกเป็นครึ่งย้อนกลับครึ่งหนึ่งและจับคู่คุณจะได้รับ (n + 1) (n / 2) ซึ่งจะพาคุณไปสู่เส้นทางที่ยุ่งเหยิงจริงๆ ตราบใดที่มีการหารจำนวนเต็มและส่วนที่เหลือที่ถูกตัดทอน สูตรนี้ (n (a1 + an)) / 2 มีความสำคัญอย่างยิ่งสำหรับคำตอบง่ายๆสำหรับค่าทั้งหมดของ n