วิศวกรรมซอฟต์แวร์

ถาม - ตอบสำหรับมืออาชีพนักวิชาการและนักเรียนที่ทำงานในวงจรการพัฒนาระบบ

7
เหตุใดคู่มือการแย่งชิงจึงไม่บอกผู้ทดสอบ
ฉันได้อ่านคู่มือการแย่งชิงกันจาก scrum.org และมันบอกว่า: ทีมพัฒนาไม่ได้มีทีมย่อยสำหรับโดเมนเฉพาะเช่นการทดสอบหรือการวิเคราะห์ธุรกิจ ในการแปลตามตัวอักษรนี่หมายความว่าไม่มีผู้ทดสอบที่ทำให้เกิดความสับสน พวกเขาจะแนะนำสิ่งนี้ได้อย่างไร
14 scrum 

3
ฉันควรใช้อินเตอร์เฟสโดยตรงหรือให้ซูเปอร์คลาสทำหรือไม่
มีความแตกต่างระหว่าง public class A extends AbstractB implements C {...} เมื่อเทียบกับ ... public class A extends AbstractB {...} abstract class AbstractB implements C {...} ฉันเข้าใจว่าในทั้งสองกรณีคลาส A จะจบลงที่สอดคล้องกับส่วนต่อประสาน ในกรณีที่สองสามารถให้การดำเนินงานสำหรับวิธีการในอินเตอร์เฟซAbstractB Cนั่นคือความแตกต่างเท่านั้น? ถ้าฉันไม่ต้องการที่จะให้การดำเนินการใด ๆ ของวิธีการอินเตอร์เฟซใน AbstractB , รูปแบบที่ฉันควรจะใช้ ? การใช้รายการใดรายการหนึ่งมีวัตถุประสงค์ 'เอกสาร' ที่ซ่อนอยู่หรือไม่

3
ข้อเสียของการนำ singleton ไปใช้กับ enum ของ Java คืออะไร
ตามเนื้อผ้ามักจะใช้เป็นซิงเกิล public class Foo1 { private static final Foo1 INSTANCE = new Foo1(); public static Foo1 getInstance(){ return INSTANCE; } private Foo1(){} public void doo(){ ... } } ด้วย enum ของ Java เราสามารถใช้ singleton เป็น public enum Foo2 { INSTANCE; public void doo(){ ... } } น่ากลัวเหมือนรุ่นที่ 2 คือมีข้อเสียหรือไม่ (ฉันให้ความคิดกับฉันและฉันจะตอบคำถามของฉันเองหวังว่าคุณจะได้คำตอบที่ดีกว่า)
14 java  singleton  enum 

1
ฉันจะให้สิทธิ์ใช้งานไลบรารี่ที่อยู่ภายใต้ใบอนุญาต MIT ได้อย่างถูกต้องได้อย่างไร?
ฉันจะให้สิทธิ์ใช้งานไลบรารี่ที่อยู่ภายใต้ใบอนุญาต MIT ได้อย่างถูกต้องได้อย่างไร ฉันกำลังใช้และขยายไลบรารี ใบอนุญาต MIT ระบุว่าฉันมีอิสระในการอนุญาตให้ใช้สิทธิ์กับห้องสมุดย่อย ฉันขอพูดง่ายๆ: <Software library> is copyright <original author> and licensed under the MIT license. <orignal license> Extensions to <Software library> are copyright <me> and licensed under the GPL license, or commercial license if applicable. <GPL, or commercial license>

8
มีตัวอย่างของวิธีการที่ไม่ใช่ CRUD หรือไม่?
ฉันเป็นโปรแกรมเมอร์ แต่ยังทำงานเป็นนักเก็บเอกสารด้วย ในฐานะที่เป็นผู้เก็บเอกสารสำคัญเป็นเรื่องเกี่ยวกับการเก็บข้อมูล ฉันมักจะมีข้อโต้แย้งกับเพื่อนร่วมงานเมื่อมันมาถึงการดำเนินการกับข้อมูล ฉันไม่ชอบ U และ D ใน CRUD มากเกินไป จากนั้นอัปเดตระเบียนฉันต้องการเพิ่มระเบียนใหม่และมีการอ้างอิงไปยังระเบียนเก่า วิธีที่คุณสร้างประวัติการเปลี่ยนแปลง ฉันไม่ชอบลบบันทึก แต่ทำเครื่องหมายว่าไม่ใช้งาน มีคำสำหรับสิ่งนี้หรือไม่? โดยพื้นฐานการสร้างและอ่านข้อมูลเท่านั้น? มีตัวอย่างของวิธีการนี้หรือไม่?

1
เหตุใดส่วนรหัสจึงเรียกว่าส่วนข้อความ
ส่วนของปฏิบัติการที่มีรหัสบางครั้งเรียกว่า.textส่วน ในสถาปัตยกรรมหน่วยความจำที่แบ่งกลุ่มบางส่วนที่แมปเป็นรหัสบางครั้งเรียกว่าส่วนข้อความ ข้อความแสดงข้อผิดพลาด unix“ ไฟล์ข้อความไม่ว่าง” ( ETXTBSY) หมายถึง“ ไฟล์นี้เป็นโปรแกรมที่กำลังดำเนินการ” ไม่ว่าข้อความมาหมายถึงการปฏิบัติการ (เครื่อง) รหัส ? คำตอบในอุดมคติ: อธิบายการเชื่อมต่อระหว่างคำและความหมายของคำนั้น ให้การอ้างอิงสำหรับแหล่งกำเนิดหรืออย่างน้อยประวัติศาสตร์ของคำนั้น ให้แนวคิดเกี่ยวกับชุมชนที่ใช้

5
การมีชั้นเรียน 'Util' เป็นสาเหตุของความกังวลหรือไม่ [ปิด]
ตามที่เป็นอยู่ในปัจจุบันคำถามนี้ไม่เหมาะสำหรับรูปแบบคำถาม & คำตอบของเรา เราคาดหวังว่าคำตอบจะได้รับการสนับสนุนจากข้อเท็จจริงการอ้างอิงหรือความเชี่ยวชาญ แต่คำถามนี้อาจเรียกร้องให้มีการอภิปรายโต้แย้งโต้แย้งหรือการอภิปรายเพิ่มเติม หากคุณรู้สึกว่าคำถามนี้สามารถปรับปรุงและเปิดใหม่ได้โปรดไปที่ศูนย์ช่วยเหลือเพื่อขอคำแนะนำ ปิดให้บริการใน7 ปีที่ผ่านมา บางครั้งฉันสร้างคลาส 'Util' ซึ่งส่วนใหญ่ใช้เพื่อเก็บวิธีการและค่านิยมที่ไม่ได้อยู่ในที่อื่น แต่ทุกครั้งที่ฉันสร้างหนึ่งในชั้นเรียนเหล่านี้ฉันคิดว่า "เอ่อ - โอ้ฉันจะเสียใจในภายหลัง ... " เพราะฉันอ่านที่ไหนสักแห่งที่มันไม่ดี แต่ในทางกลับกันดูเหมือนจะมีสองกรณี (อย่างน้อยสำหรับฉัน) ที่น่าสนใจสำหรับพวกเขา: ความลับการนำไปใช้งานที่ใช้ในหลายคลาสภายในแพ็กเกจ นำเสนอฟังก์ชั่นที่มีประโยชน์เพื่อเพิ่มคลาสโดยไม่ทำให้หน้าจอของคุณยุ่ง ฉันกำลังจะไปสู่ความพินาศหรือไม่? คุณพูดอะไร !! ฉันควร refactor หรือไม่

4
รวมวิธีการแม่แบบกับกลยุทธ์
การมอบหมายในวิชาวิศวกรรมซอฟต์แวร์ของฉันคือการออกแบบแอพพลิเคชั่นที่สามารถเล่นเกมในรูปแบบที่แตกต่างกันได้ เกมดังกล่าวคือ Mancala เกมเหล่านี้บางเกมเรียกว่า Wari หรือ Kalah เกมเหล่านี้แตกต่างกันไปในบางแง่มุม แต่สำหรับคำถามของฉันเป็นสิ่งสำคัญที่ต้องรู้ว่าเกมดังกล่าวอาจแตกต่างกันดังต่อไปนี้: วิธีการจัดการผลลัพธ์ของการย้าย วิธีการกำหนดจุดสิ้นสุดของเกม วิธีการตัดสินผู้ชนะ สิ่งแรกที่ฉันนึกถึงในการออกแบบสิ่งนี้คือการใช้รูปแบบกลยุทธ์ฉันมีการเปลี่ยนแปลงในอัลกอริทึม (กฎที่แท้จริงของเกม) การออกแบบอาจมีลักษณะเช่นนี้: จากนั้นฉันก็คิดกับตัวเองว่าในเกมของ Mancala และ Wari วิธีที่ผู้ชนะได้รับการตัดสินนั้นเหมือนกันและรหัสจะซ้ำกัน ฉันไม่คิดว่านี่เป็นคำจำกัดความที่ละเมิดหลักการ 'หนึ่งกฎที่เดียว' หรือหลักการของ DRY ที่เห็นว่าเป็นการเปลี่ยนแปลงในกฎสำหรับ Mancala ไม่ได้หมายความว่าจะต้องเปลี่ยนกฎใน Wari โดยอัตโนมัติเช่นกัน อย่างไรก็ตามจากข้อเสนอแนะที่ฉันได้รับจากอาจารย์ของฉันฉันได้รับความประทับใจในการค้นหาการออกแบบที่แตกต่าง ฉันมากับสิ่งนี้: แต่ละเกม (Mancala, Wari, Kalah, ... ) จะมีคุณลักษณะของประเภทของส่วนต่อประสานของกฏแต่ละตัวเช่นWinnerDeterminerหากมีรุ่น Mancala 2.0 ซึ่งเหมือนกับ Mancala 1.0 ยกเว้นว่าผู้ชนะจะตัดสินได้อย่างไร ใช้รุ่น Mancala ฉันคิดว่าการใช้กฎเหล่านี้เป็นรูปแบบกลยุทธ์นั้นใช้ได้อย่างแน่นอน แต่ปัญหาที่แท้จริงเกิดขึ้นเมื่อฉันต้องการออกแบบเพิ่มเติม ในการอ่านเกี่ยวกับรูปแบบวิธีการของแม่แบบฉันคิดได้ทันทีว่าสามารถนำไปใช้กับปัญหานี้ได้ การกระทำที่ทำเมื่อผู้ใช้ทำการย้ายจะเหมือนกันเสมอและในลำดับเดียวกันคือ: …

9
ฉันควรให้คำตอบสำหรับแบบฝึกหัดการสัมภาษณ์ที่ล้มเหลวหรือไม่? [ปิด]
ปิด. คำถามนี้เป็นคำถามปิดหัวข้อ ไม่ยอมรับคำตอบในขณะนี้ ต้องการปรับปรุงคำถามนี้หรือไม่ อัปเดตคำถามเพื่อให้เป็นหัวข้อสำหรับ Software Engineering Stack Exchange ปิดให้บริการใน4 ปีที่แล้ว เรามีระดับผู้สมัครสัมภาษณ์อาวุโสล้มเหลวแตกต่างกันนิดหน่อยของที่คำถาม FizzBuzz 1 2 ฉันหมายถึงคำถามที่แท้จริงไม่ได้คำถามทั้งหมด - แม้แต่ใกล้ชิด ฉันยังเป็นโค้ชเขาผ่านการคิดเกี่ยวกับการใช้ห่วงและที่3และ5ก็จริงๆมีมูลค่าการพิจารณาเป็นกรณีพิเศษ เขาเป่ามัน เพียงเพื่อจุดประสงค์ในการประกันคุณภาพฉันให้คำถามที่เหมือนกันกับเพื่อนร่วมทีมสามคน ให้พวกเขา 5 นาที จากนั้นกลับมาเพื่อรวบรวมรหัสหลอกของพวกเขา พวกเขาทั้งหมดถูกจับและไม่เคยเห็นคำถามมาก่อน ทั้งสองถามว่าเคล็ดลับคืออะไร ... ในแบบฝึกหัดลอจิกที่แตกต่างกันผู้สมัครแสดงความเข้าใจเกี่ยวกับคุณสมบัติบางอย่างที่มีในภาษาที่เขาเลือกใช้ (C #) ดังนั้นจึงไม่เหมือนกับว่าเขาไม่เคยเขียนโค้ดเลย แต่ตรรกะของเขายังคงแข็งทื่อ คำถามของฉันคือฉันควรให้คำตอบสำหรับคำถามเชิงตรรกะหรือไม่ เขารู้ว่าเขาเป่าพวกเขาและยอมรับในภายหลังในการสัมภาษณ์ ในทางตรงกันข้ามเขาไม่เคยขอคำตอบหรือสิ่งที่ฉันคาดหวังที่จะเห็น ฉันรู้ว่าแบบฝึกหัดการเขียนโปรแกรมสามารถใช้ในการตั้งค่าผู้สมัครสำหรับความล้มเหลว (อีกครั้งดูลิงค์ที่สองจากด้านบน) และฉันพยายามช่วยเขากลับบ้านในการตอบคำถามหลักของคำถาม แต่นี่เป็นผู้สมัครระดับสูงและ Fizz-Buzz เป็นคนตรงไปตรงมาขันได้ง่ายแม้หลังจากการบัญชีสำหรับการสัมภาษณ์กระวนกระวายใจ ฉันรู้สึกเหมือนฉันควรจะแสดงให้เขาเห็นวิธีการแก้ปัญหาเพื่อให้เขาสามารถเรียนรู้จากประสบการณ์อย่างน้อย แต่อีกครั้งเขาไม่ถาม วิธีที่ถูกต้องในการจัดการกับสถานการณ์นั้นคืออะไร? 1 โอเคนั่นไม่ใช่ลิงก์ไปยังคำถาม FizzBuzz จริง ๆ …
14 interview 

2
จับคู่ตรรกะการเขียนโปรแกรมทางธุรกิจกับบุคคลที่ไม่ใช่ด้านไอที [ปิด]
ปิด คำถามนี้จะต้องมีมากขึ้นมุ่งเน้น ไม่ยอมรับคำตอบในขณะนี้ ต้องการปรับปรุงคำถามนี้หรือไม่ อัปเดตคำถามเพื่อให้มุ่งเน้นที่ปัญหาเดียวโดยแก้ไขโพสต์นี้ ปิดให้บริการใน4 ปีที่แล้ว คุณเคยมีประสบการณ์เกี่ยวกับบุคคลที่ไม่ได้ทำงานกับโปรแกรมเมอร์ในระหว่างกระบวนการเข้ารหัสหรือไม่? มันเหมือนกับการเขียนโปรแกรมคู่ แต่บุคคลหนึ่งเป็นบุคคลที่ไม่ใช่ด้านไอทีที่รู้เรื่องธุรกิจเป็นอย่างมากอาจเป็นวิศวกรกระบวนการที่มีพื้นฐานทางคณิตศาสตร์ที่รู้วิธีคำนวณสิ่งต่าง ๆ และสามารถเข้าใจโค้ดที่ไม่ใช้สำนวนได้ ฉันพบว่าบางภาษาเฉพาะโดเมนเช่น PL / SQL นั้นค่อนข้างเข้าใจได้ง่ายโดยวิศวกรที่ไม่ใช่ไอที บุคคลเหล่านี้เป็นผู้เขียนรหัสและรับประกันความถูกต้องของสูตรปัจจัย ฯลฯ ฉันพบว่าการเขียนโปรแกรมคู่ชนิดนี้มีประสิทธิภาพมากผู้ใช้ประเภทวิศวกรรมรู้สึกว่าพวกเขายังเป็น "เจ้าของ" และ "ผู้เขียน" ของรหัสและช่วยลดความเข้าใจผิดในกระบวนการสื่อสาร พวกเขายังช่วยออกแบบกรณีทดสอบ การปฏิบัตินี้เป็นเรื่องปกติหรือไม่ มันมีชื่อหรือไม่? คุณเคยมีประสบการณ์คล้าย ๆ กันบ้างไหม?

5
วิธีในการรับรองอินสแตนซ์ที่ไม่เหมือนใครของชั้นเรียนหรือไม่?
ต้องการปรับปรุงโพสต์นี้หรือไม่? ให้คำตอบโดยละเอียดสำหรับคำถามนี้รวมถึงการอ้างอิงและคำอธิบายว่าทำไมคำตอบของคุณถึงถูกต้อง คำตอบที่ไม่มีรายละเอียดเพียงพออาจแก้ไขหรือลบออกได้ ฉันกำลังมองหาวิธีที่แตกต่างเพื่อให้แน่ใจว่าแต่ละอินสแตนซ์ของคลาสที่กำหนดนั้นเป็นอินสแตนซ์ที่ระบุตัวตนไม่ซ้ำกัน ตัวอย่างเช่นผมมีเรียนกับสนามName nameเมื่อฉันมีNameวัตถุที่nameเริ่มต้นให้กับ John Smith ฉันไม่ต้องการที่จะสามารถสร้างอินสแตนซ์ของNameวัตถุที่แตกต่างด้วยชื่อเป็น John Smith หรือถ้าการสร้างอินสแตนซ์เกิดขึ้นฉันต้องการให้มีการอ้างอิงไปยังวัตถุเดิม กว่าวัตถุใหม่ ฉันทราบว่าวิธีหนึ่งในการทำเช่นนี้คือการมีโรงงานแบบคงที่ที่มีMapวัตถุชื่อปัจจุบันทั้งหมดและโรงงานตรวจสอบว่าวัตถุที่มี John Smith เป็นชื่อที่ไม่มีอยู่ก่อนส่งกลับการอ้างอิงไปยังNameวัตถุ. วิธีที่ฉันสามารถคิดออกด้านบนของหัวของฉันก็คือการมีแผนที่แบบคงที่ในNameระดับและเมื่อสร้างเรียกว่าการขว้างปายกเว้นถ้าค่าที่ส่งไปในnameที่มีอยู่แล้วในการใช้งานในวัตถุอื่น แต่ผมทราบข้อยกเว้นการขว้างปา ในตัวสร้างโดยทั่วไปความคิดที่ดี มีวิธีอื่นในการบรรลุเป้าหมายนี้หรือไม่?

4
แนวปฏิบัติที่ดีที่สุดสำหรับโปรแกรมทดสอบที่มีพฤติกรรมสุ่มคืออะไร
เมื่อทำงานวิจัยและพัฒนาฉันมักพบว่าตัวเองกำลังเขียนโปรแกรมที่มีการสุ่มในระดับสูงในพฤติกรรมของพวกเขา ตัวอย่างเช่นเมื่อฉันทำงานในการเขียนโปรแกรมทางพันธุกรรมฉันมักจะเขียนโปรแกรมที่สร้างและรันซอร์สโค้ดแบบสุ่มโดยพลการ ปัญหาเกี่ยวกับการทดสอบรหัสดังกล่าวคือข้อผิดพลาดมักจะเป็นระยะ ๆ และอาจเป็นเรื่องยากที่จะทำซ้ำ สิ่งนี้นอกเหนือไปจากการตั้งค่าเมล็ดพันธุ์แบบสุ่มเป็นค่าเดียวกันและเริ่มต้นการดำเนินการ ตัวอย่างเช่นโค้ดอาจอ่านข้อความจาก kernal ring buffer จากนั้นทำการข้ามแบบมีเงื่อนไขกับเนื้อหาข้อความ ตามปกติสถานะของบัฟเฟอร์บัฟเฟอร์จะเปลี่ยนไปเมื่อพยายามทำซ้ำอีกครั้งในภายหลัง แม้ว่าพฤติกรรมนี้เป็นคุณสมบัติที่สามารถเรียกใช้รหัสอื่นในวิธีที่ไม่คาดคิดและมักจะพบข้อบกพร่องที่หน่วยทดสอบ (หรือผู้ทดสอบมนุษย์) ไม่พบ มีการกำหนดแนวปฏิบัติที่ดีที่สุดสำหรับระบบทดสอบประเภทนี้หรือไม่? ถ้าเป็นเช่นนั้นการอ้างอิงบางอย่างจะมีประโยชน์มาก ถ้าไม่คำแนะนำอื่น ๆ ยินดีต้อนรับ!

1
วิธีการตรวจสอบหลักการทดแทน Liskov ในลำดับชั้นการสืบทอด?
แรงบันดาลใจจากคำตอบนี้ : หลักการทดแทน Liskov ต้องการ สิ่งนั้น เงื่อนไขเบื้องต้นไม่สามารถเสริมความแข็งแกร่งในประเภทย่อย Postconditions ไม่สามารถลดลงในประเภทย่อย ค่าคงที่ของซูเปอร์ไทป์จะต้องเก็บรักษาไว้ในประเภทย่อย ข้อ จำกัด ประวัติ ("กฎประวัติศาสตร์") วัตถุนั้นได้รับการยกย่องว่าสามารถปรับเปลี่ยนได้ด้วยวิธีการของพวกเขาเท่านั้น (encapsulation) เนื่องจากชนิดย่อยอาจแนะนำวิธีการที่ไม่ปรากฏใน supertype การแนะนำวิธีการเหล่านี้อาจอนุญาตให้มีการเปลี่ยนแปลงสถานะในชนิดย่อยที่ไม่อนุญาตใน supertype ข้อ จำกัด ประวัติห้ามสิ่งนี้ ฉันหวังว่าถ้ามีคนจะโพสต์ลำดับชั้นของชั้นเรียนที่ละเมิด 4 คะแนนและจะแก้ไขได้อย่างไร ฉันกำลังมองหาคำอธิบายอย่างละเอียดเพื่อจุดประสงค์ด้านการศึกษาเกี่ยวกับวิธีระบุแต่ละจุดในลำดับชั้นและวิธีที่ดีที่สุดในการแก้ไข หมายเหตุ: ฉันหวังว่าจะโพสต์ตัวอย่างโค้ดเพื่อให้คนทำงาน แต่คำถามนั้นเกี่ยวกับวิธีระบุลำดับชั้นผิดพลาด :)

2
เหตุใด UUID / GUID จึงอยู่ในรูปแบบ
Globally Unique Identifiers (GUID) เป็นสตริงที่จัดกลุ่มด้วยรูปแบบเฉพาะซึ่งฉันถือว่ามีเหตุผลด้านความปลอดภัย GUID ถูกเขียนโดยทั่วไปในข้อความเป็นลำดับเลขฐานสิบหกที่แยกออกเป็นห้ากลุ่มเช่น: 3F2504E0-4F89-11D3-9A0C-0305E82C3301 เหตุใดสตริง GUID / UUID จึงไม่เพียงแค่เข้ารหัสแบบสุ่มโดยใช้เลขฐานสิบหกของความยาว X สัญลักษณ์ข้อความนี้มีฟิลด์ต่อไปนี้คั่นด้วยเครื่องหมายขีดคั่น: | Hex digits | Description |------------------------- | 8 | Data1 | 4 | Data2 | 4 | Data3 | 4 | Initial two bytes from Data4 | 12 | Remaining six bytes from Data4 นอกจากนี้ยังมีหลายรุ่นมาตรฐาน …
14 uuid 

6
เซสชันฝั่งเซิร์ฟเวอร์ละเมิด REST หรือไม่
ตามรอยฟีลดิง (หนึ่งในผู้เขียนหลักของสเปค HTTP) ในรูปแบบสถาปัตยกรรมวิทยานิพนธ์ของเขาเมื่อพูดถึงส่วนที่เหลือเขากล่าวถึง: [E] การร้องขอจากลูกค้าไปยังเซิร์ฟเวอร์ต้องมีข้อมูลทั้งหมดที่จำเป็นเพื่อทำความเข้าใจคำขอและไม่สามารถใช้ประโยชน์จากบริบทที่จัดเก็บไว้บนเซิร์ฟเวอร์ โดย "บริบทที่เก็บไว้" เขาอ้างถึงสถานะแอปพลิเคชันเช่นหมายเลขหน้าของหน้าถัดไปคือเทียบกับสถานะของทรัพยากรเช่นแหล่งข้อมูลใด ๆ รูปภาพ ฯลฯ - ซึ่งเป็นจุดรวมของ REST มันยุติธรรมหรือไม่ที่จะบอกว่าความพยายามส่วนใหญ่ในการพักผ่อนที่บริสุทธิ์ (ต่อไปนี้เป็นการนำไปปฏิบัติซึ่งสอดคล้องกับวิทยานิพนธ์ข้างต้น) ต้องล้มเหลวเนื่องจากการพึ่งพาการจัดเก็บข้อมูลเซสชันบนเซิร์ฟเวอร์ (ถาวรหรืออย่างอื่น)? แนวคิดของเซสชั่นเป็นเรื่องปกติ - โดยเฉพาะอย่างยิ่งสำหรับนักพัฒนาเว็บ - แต่มันสงบตามข้อกำหนดข้างต้นหรือไม่
14 rest 

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.