ในการพัฒนาความรู้การเขียนโปรแกรมลึก


136

บางครั้งฉันเห็นคำถามเกี่ยวกับคดีขอบและความแปลกประหลาดอื่น ๆ ใน Stack Overflow ที่ตอบได้ง่ายจาก Jon Skeet และ Eric Lippert แสดงให้เห็นถึงความรู้อย่างลึกซึ้งเกี่ยวกับภาษาและความซับซ้อนมากมาย เช่นนี้:

คุณอาจจะคิดว่าในการที่จะใช้foreachห่วงคอลเลกชันที่คุณกำลังทำซ้ำมากกว่านั้นจำเป็นต้องใช้หรือIEnumerable IEnumerable<T>แต่มันกลับกลายเป็นว่านั่นไม่ใช่ข้อกำหนดจริงๆ สิ่งที่จะต้องเป็นว่าประเภทของคอลเลกชันจะต้องมีวิธีการที่เรียกว่าประชาชนGetEnumeratorและที่จะต้องกลับบางชนิดที่มีความทะเยอทะยานทรัพย์สินของประชาชนที่เรียกว่าCurrentและวิธีการที่ประชาชนที่ส่งกลับMoveNext boolหากคอมไพเลอร์สามารถพิจารณาได้ว่าข้อกำหนดทั้งหมดนั้นเป็นไปตามนั้นรหัสนั้นจะถูกสร้างขึ้นเพื่อใช้วิธีการเหล่านั้น เฉพาะในกรณีที่ความต้องการเหล่านั้นจะไม่พบเราจะตรวจสอบเพื่อดูว่าวัตถุที่นำไปปฏิบัติหรือIEnumerableIEnumerable<T>

นั่นเป็นเรื่องที่ควรรู้ ฉันเข้าใจได้ว่าทำไม Eric ถึงรู้เรื่องนี้ เขาอยู่ในทีมคอมไพเลอร์ดังนั้นเขาต้องรู้ แต่สิ่งที่เกี่ยวกับผู้ที่แสดงให้เห็นถึงความรู้ลึก ๆ ที่ไม่ได้อยู่ภายใน

ปุถุชนเพียง (ที่ไม่ได้อยู่ในทีมคอมไพเลอร์ C #) หาข้อมูลเกี่ยวกับสิ่งนี้ได้อย่างไร

โดยเฉพาะมีวิธีการที่คนเหล่านี้ใช้เพื่อรูทความรู้ดังกล่าวสำรวจและทำให้เป็นระบบ (ทำให้เป็นของตัวเอง) หรือไม่


10
ฉันคิดว่านี่เป็นสิ่งที่ซอฟท์แวร์โอเพนซอร์สส่องสว่าง ยินดีที่ได้ก้าวเข้าสู่เฟรมเวิร์ก / ระบบ / ไลบรารีจนสุด ฉันเคยมีความเข้าใจในกรอบการทำงานภายในเมื่อฉันทำงานกับ Qt ดีกว่าเมื่อฉันทำงานกับ WinForms
Vitor Py

2
เมื่อใดที่คุณจะต้องรู้ตัวอย่างนี้โดยเฉพาะนอกเหนือจากการไม่มองหน้าคนพิเศษ พวกเขาพิสูจน์ตัวเองงี่เง่านี้ นอกจากนั้นชุด C # ที่มีประสิทธิภาพ, Java, C ++ ฯลฯ อาจมีสิ่งดีๆอยู่ในนั้น บล็อกของ Eric Lippert ก็เป็นแหล่งข้อมูลที่ดีเช่นกัน โดยทั่วไปแล้วเรามักจะไม่รู้ว่าไม่รู้อะไรดังนั้นเมื่อพวกเขาพูดว่า "มีชีวิต 100 ปีเรียนรู้เป็นเวลา 100 ปีและตายเป็นคนโง่"
งาน

26
มันคุ้มค่ากับความพยายามหรือไม่? ฉันพูดได้สองภาษาและพยายามที่จะเรียนรู้ภาษาพูดอีกสองสามภาษา ฉันเรียนคณิตศาสตร์บางวิชา แต่ยังไม่เพียงพอ ฉันต้องการเรียนรู้วิธีการเล่นเทนนิสครึ่งทางและเรียนรู้การว่ายน้ำโดยใช้จังหวะผีเสื้อ ฉันต้องการท่องเที่ยวเพิ่มเติม ฉันต้องการเรียนรู้ Clojure สิ่งที่ฉันไม่ต้องการคือการเป็นผู้เชี่ยวชาญในภาษาเดียวมีปริญญาเอกในวิชาคณิตศาสตร์ใช้เวลา 30 ชั่วโมงต่อสัปดาห์ในสระว่ายน้ำเช่น Michael Phelps เป็นต้นความรู้ของ Lippert และ Skeet นั้นเกิดจากการที่พวกเขาใช้เวลามาก ความพยายามในสิ่งหนึ่ง (หรือสองสาม) ในขณะที่พลาดประสบการณ์อื่น ๆ อาจจะเปลี่ยนงานหรือไม่
งาน

10
"ฉันเข้าใจได้ว่าทำไมเอริครู้เรื่องนี้เขาอยู่ในทีมคอมไพเลอร์ดังนั้นเขาต้องรู้" - โอกาสที่เขารู้เรื่องนี้เพราะเขาคิดว่ามันขึ้นมาในสถานที่แรก ผมสงสัยว่าเขาจะต้อง 'หา' ว่ามันทำงานเช่นนี้ :)
อเล็กซ์บริงค์สิบ

10
@Alex: ฉันใช้งาน C # ได้จริงเท่านั้นเนื่องจากเราเริ่มสร้างการใช้งาน C # 3 ข้อกำหนด "foreach" นั้นเขียนขึ้นเมื่อหกปีก่อน ฉันยังค้นหาสิ่งที่เกี่ยวกับประวัติศาสตร์ที่บ้าคลั่งเกี่ยวกับภาษาทุกวัน ตัวอย่างเช่นฉันได้เรียนรู้วันนี้ว่าสำหรับผู้ได้รับมอบหมาย ((A + B) + C) - (A + C) = A + B + C แต่ ((A + B) + C) - (B + C) = A แปลก!
Eric Lippert

คำตอบ:


167

ก่อนอื่นขอบคุณสำหรับคำใจดี

หากคุณต้องการความรู้อย่างลึกซึ้งเกี่ยวกับ C # มันเป็นข้อได้เปรียบอย่างแน่นอนในการมีข้อกำหนดภาษาการออกแบบโน้ตสิบปีซอร์สโค้ดฐานข้อมูลข้อผิดพลาดและ Anders, Mads, Scott และ Peter เพียงลงมาที่ห้องโถง ฉันโชคดีอย่างแน่นอนไม่มีคำถามเกี่ยวกับเรื่องนี้

อย่างไรก็ตามแม้จะไม่มีข้อดีเหล่านั้นก็ยังคงเป็นไปได้ที่จะได้รับความรู้ลึกของเรื่อง

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

เห็นได้ชัดว่า StackOverflow และฟอรัม Q & A สาธารณะอื่น ๆ เป็นเหมือนการดื่มจากไฟสำหรับสิ่งนั้น ย้อนกลับไปฉันอ่าน comp.lang.javascript และฟอรัม "ผู้ใช้ JS" ภายใน Microsoft อย่างเคร่งครัดและปฏิบัติตามคำแนะนำของผู้จัดการของฉัน: เมื่อฉันเห็นคำถามเกี่ยวกับความหมายของภาษาที่ฉันไม่ทราบคำตอบ ธุรกิจของฉันเพื่อค้นหา

หากคุณต้องการทำ "การดำน้ำลึก" เช่นนั้นคุณต้องเลือกอย่างระมัดระวัง ฉันมาจนถึงทุกวันนี้อย่างไม่รู้ลืมว่ารูปแบบวัตถุของเบราว์เซอร์ทำงานอย่างไร ตั้งแต่ฉันได้จดจ่อกับการเป็นผู้เชี่ยวชาญภาษา C # เมื่อหลายปีที่ผ่านมาฉันไม่รู้อย่างชัดเจนว่าคลาสต่างๆในไลบรารีคลาสพื้นฐานทำงานอย่างไร ฉันโชคดีที่ฉันมีงานที่ได้รับรางวัลความรู้ลึกที่เฉพาะเจาะจง หากงานของคุณหรือพรสวรรค์ของคุณสอดคล้องกับการเป็นคนทั่ว ๆ ไปการลงลึกอาจไม่เหมาะกับคุณ

การเขียนบล็อกมีประโยชน์อย่างมาก โดยกำหนดให้ฉันต้องอธิบายหัวข้อที่ซับซ้อนให้ผู้อื่นฉันถูกบังคับให้เผชิญหน้ากับความเข้าใจที่ไม่เพียงพอของหัวข้อต่าง ๆ ตลอดเวลา


14
ไม่ต้องลากออกนอกหัวข้อ แต่หลังจากอ่านคำตอบนี้ฉันอยากรู้ว่าทำไมคุณไม่ถามคำถามใด ๆ ที่นี่หรือใน Stack Overflow ณ จุดนี้เพื่อนร่วมงานบล็อกและอื่น ๆ ของคุณเพียงพอหรือไม่ มีทรัพยากรที่ดีไปกว่าที่เราควรรู้หรือไม่?
Matthew อ่าน

6
บางทีคุณอาจเข้าใจผิดในสิ่งที่เขาพูด ตอบโต้โดยสัญชาตญาณเขาไม่ได้ถามคำถามเพื่อเรียนรู้สิ่งต่าง ๆ เขาตอบคำถาม
jhocking

65

เมื่ออยู่ด้าน "กูรู" ของการสนทนาครั้งเดียวหรือสองครั้งฉันสามารถบอกคุณได้ว่าหลายครั้งที่คุณเห็นว่า "ความรู้ลึก" ของภาษาโปรแกรมหรือระบบมักเป็นผลมาจาก "กูรู" ที่ดิ้นรนเพื่อ เดือนเพื่อแก้ไขปัญหาเดียวกันแน่นอน โดยเฉพาะอย่างยิ่งในฟอรัมที่ผู้คนสามารถเลือกคำถามที่พวกเขาจะตอบ แม้แต่ไลค์ของ Jon Skeet และ Eric Lippert ก็ต้องเรียนรู้โลกสวัสดีในจุดเดียว พวกเขาเลือกความรู้ครั้งละหนึ่งแนวคิดเหมือนกับคนอื่น ๆ


1
เป็นจุดที่ดีมาก ฉันมักจะพบเมื่อเริ่มต้นการวิจัยเป็นระยะเวลานานซึ่งฉันพบคำถามที่ฉันสามารถตอบได้เนื่องจากสิ่งที่ฉันเรียนรู้มาก่อนหน้านี้ในวันนั้น
Matthew อ่าน

47

การถอดความโยคีบาฮาน:

"ถ้าคุณต้องการที่จะเรียนรู้บางอย่างอ่านเกี่ยวกับมันถ้าคุณต้องการที่จะเข้าใจบางสิ่งบางอย่างเขียนเกี่ยวกับมัน; ถ้าคุณต้องการที่จะโทสิ่งที่ โปรแกรมมัน"

การเขียนโปรแกรมเป็นเหมือนการสอนที่ท้าทายที่สุด การสอนคอมพิวเตอร์ต้องทำบางสิ่งบางอย่างเพื่อให้คุณรู้ว่าสิ่งของของคุณดีมาก - หรือคุณจะเรียนรู้ที่จะเชี่ยวชาญ

ตัวอย่างเช่นหากคุณต้องการเรียนรู้วิชาฟิสิกส์ให้เขียนกลไกทางฟิสิกส์ หากคุณต้องการเรียนรู้หมากรุกให้ตั้งโปรแกรมเกมหมากรุก ถ้าคุณต้องการเรียนรู้อย่างลึกซึ้ง C # ให้เขียนคอมไพเลอร์ C # (หรือเครื่องมืออื่น ๆ )


2
การเขียนโปรแกรมยังเป็นความพยายามในการเขียนเล็ก ๆ น้อย ๆ (แน่นอนว่าคนอ่าน) ในลักษณะที่ชัดเจนที่สุด
vpit3833

4
คำพูดนั้นฟังลึกมากจนกระทั่งฉันอ่านตัวอย่างหมากรุก น่าเสียดายที่การเขียนโปรแกรมหมากรุก AI จะไม่ทำให้คุณเป็นผู้เล่นหมากรุกที่ดีกว่า (โดยพื้นฐานแล้วเป็นการค้นหาในทรี Min-Max) ยัง +1
bughi

1
@bughi บางทีคุณสามารถควบคุมกฎได้: D
Julio Rodrigues

@bughi 'program it' เป็นคำที่กว้างมากไม่เกี่ยวข้องกับการเขียนโค้ดเสมอไป !! แค่คิดนอกกรอบนิดหน่อย
Nitesh Verma

25

เท่าที่ฉันรู้วิธีการเรียนรู้นี้คือ:

  • อ่านเกี่ยวกับเรื่องนี้จากคนอย่าง Eric Lippert
  • สัมผัสประสบการณ์แล้วแก้ไขปัญหาด้วยตนเองโดยตรง

วิธีที่สองอาจใช้เวลานานกว่ามาก แต่อาจส่งผลให้เกิดความเข้าใจที่ลึกซึ้งขึ้น (แต่ไม่เสมอไป)


17
หรือทั้งคู่. [15 chars]
Michael K

23

ฉันจะบอกว่าทำต่อไปนี้:

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

อาสาสมัครสำหรับงานที่ซับซ้อนมากขึ้นงานที่ทำให้คุณต้องเจาะลึกเพื่อแก้ปัญหา หากไม่มีที่ทำงานให้มองหางานโอเพ่นซอร์สที่ต้องทำหรือเริ่มทำงานในโครงการส่วนบุคคลที่จะทำให้คุณต้องลงลึก หากงานของคุณไม่มีปัญหาที่น่าสนใจลองมองหางานที่ท้าทายมากขึ้น

อ่านหนังสือขั้นสูงในหนึ่งภาษา (สำหรับ SQl Server เช่นนี้จะรวมถึงการอ่านเกี่ยวกับการปรับแต่งประสิทธิภาพและฐานข้อมูลภายใน) แทนการเรียนรู้ X ในประเภทหนังสือ 30 วัน

อ่านคำถามที่น่าสนใจที่นี่และสถานที่อื่น ๆ ที่พวกเขาถูกถามและพยายามแก้ปัญหาด้วยตัวคุณเอง หากคุณต้องการเรียนรู้พยายามแก้ปัญหาโดยไม่อ่านคำตอบอื่นก่อน แม้ว่าคำถามจะได้รับคำตอบแล้วคุณจะเรียนรู้เพิ่มเติมถ้าคุณพบคำตอบด้วยตัวเอง คุณอาจพบคำตอบที่ดีกว่าคำถามที่มี

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

ค้นหาบล็อกทางเทคนิคที่ดีจากผู้เชี่ยวชาญที่มีชื่อเสียงในฟิลด์และอ่าน

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


คำตอบที่ดี แต่ฉันก็สงสัยว่าฉันจะรักษาความรู้และเชื่อมต่อจุดต่าง ๆ ได้ดีขึ้นอย่างไร

ฉันขอแนะนำให้คุณจดบันทึกสิ่งที่คุณเรียนรู้ ฉันเริ่มทำสิ่งนี้ใน Evernote ของฉันและในอีกไม่กี่ปีที่ผ่านมาฉันพบว่าฉันสามารถใช้ชีวิตโน้ตของฉันได้ ช้าฉันก็มาถึงจุดที่บันทึกของฉันสามารถทำการนำเสนอซึ่งฉันพร้อมที่จะนำเสนอในช่วงเวลาที่แจ้งให้ทราบล่วงหน้า
Shivasubramanian A

9

คุณสามารถเริ่มต้นด้วยการศึกษาคุณสมบัติทางภาษาของสิ่งที่คุณต้องการจะเป็นผู้เชี่ยวชาญอย่างลึกซึ้ง ตัวอย่างเช่น:


3
คำตอบที่ดี - ตัวอย่างเช่นส่วนที่ 15.8.4 ของข้อกำหนด C # ที่เชื่อมโยงครอบคลุมการดำเนินการforeachและอธิบายพฤติกรรมที่อธิบายไว้ในโพสต์บล็อกที่ยกมาจาก Eric Lippert หากใครเคยพบว่าตัวเองกำลังคิดอะไรบางอย่างเช่น "ฉันสงสัยว่า foreach ใช้งานได้จริงอย่างไร" นี่จะเป็นจุดเริ่มต้นที่ดีในการมองหา
Carson63000

6

รับReflectorหรือ decompiler อื่น ๆ (เพราะมันจ่ายตอนนี้) และเริ่มเปิดไลบรารี. NET ที่ใช้มากที่สุดเพื่อเรียนรู้วิธีการทำงานของ internals เมื่อรวมกับหนังสืออย่างCLR ผ่านทาง C #คุณจะได้รับข้อมูลที่ค่อนข้างลึก (ยิ่งลึกกว่าพวกเราส่วนใหญ่จะไปทำงานประจำ)


5
ฉันทำสิ่งนี้จริงกับBitConverterคลาสและค้นหาIsLittleEndianค่าสถานะระบบเฉพาะ
Robert Harvey

ฮ่า ๆ. +1 สำหรับ isLittleEndian
Rudy

4

ฉันพัฒนาความรู้ประเภทนั้นใน C ++ โดยการออกไปเที่ยวcomp.lang.c++.moderatedเป็นเวลาสองปีแม้ว่าฉันจะไม่ได้ทำงานหนักในการเขียนโค้ดในตอนนั้น ฉันไม่แน่ใจว่าปราชญ์ฉันสามารถพูดได้ว่าฉันเป็นอย่างไร

ฉันคิดว่ามีความรู้สองประเภทที่สามารถเลือกได้เกี่ยวกับภาษาการเขียนโปรแกรม:

  1. รู้เรื่องไม่สำคัญเกี่ยวกับภาษาและรู้วิธีหลีกเลี่ยงข้อผิดพลาด
  2. รู้วิธีแก้ปัญหาอย่างมีประสิทธิภาพ

หมายเลข 2 สามารถทำได้โดยการเขียนโปรแกรมในภาษาและดูรหัสของคนอื่น แต่หมายเลข 1 สามารถทำได้โดยการใช้เวลามากมายในการอ่านเกี่ยวกับภาษาในฟอรัมการสนทนาของพวกเขาเห็นคำถามประเภทที่ผู้คนถามและสิ่งที่ คำตอบคือ StackOverflow เป็นสถานที่ที่ดีเช่นกัน


4

ความรู้เชิงลึกและความเชี่ยวชาญด้านการเขียนโปรแกรมหมายถึงความสะดวกสบายในทุกระดับ กล่าวคือ

  • ไลบรารีและ API
  • ความหมายของภาษา
  • การเพิ่มประสิทธิภาพของคอมไพเลอร์
  • คอมไพเลอร์ภายในและการสร้างรหัส
  • ลักษณะการทำงานของรันไทม์และตัวรวบรวมขยะ
  • ปัญหาเกี่ยวกับสถาปัตยกรรมและชุดคำสั่ง

ทุกสิ่งที่ฉันเห็นใน 15 ปีที่ผ่านมาแสดงให้เห็นว่าถ้าคุณสามารถเข้าสู่คอมไพเลอร์และรันไทม์จริงๆคุณมีโอกาสที่จะมีความเชี่ยวชาญอย่างลึกซึ้ง คุณอาจต้องบังคับตัวเองให้ทำตามขั้นตอนและเริ่มใช้เหตุผล (และการสร้าง) ซอฟต์แวร์ในระดับต่อไปของนามธรรมที่ต่ำกว่าในสแต็ก แต่เป็นวิธีเดียวที่จะเชี่ยวชาญ

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


3

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

อย่างไรก็ตามนี่ไม่ใช่ความคิดของฉันสำหรับความรู้ลึก มันเป็นเพียงรายละเอียดการติดตั้งที่ไม่น่าสนใจ มันอาจจะน่าสนใจมากขึ้นถ้าผู้ออกแบบอธิบายว่าทำไมมันถึงเกิดขึ้นในแบบไดนามิกมากกว่านี้แทนที่จะตรวจสอบว่าวัตถุนั้นใช้ Iterable ได้


1
ฉันไม่คิดว่าจะมีอะไรเช่น "skimming" ข้อกำหนดภาษา C #
Robert Harvey

@RobertHarvey: คุณสามารถอ่านภาษาทางการส่วนใหญ่ซึ่งครอบคลุมสิ่งที่คุณรู้อยู่แล้วเช่นความสำคัญของผู้ดำเนินการและไวยากรณ์การประกาศและมุ่งเน้นไปที่รายละเอียดที่ไม่คาดคิด แต่มีประโยชน์เช่นพฤติกรรมที่แน่นอนของ C # foreach หรือ Java enum constructors
วินไคลน์

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