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

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

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

2
. NET Framework ย้อนหลังเข้ากันได้คืออะไร?
เราพัฒนาแอปพลิเคชั่น windows ใน. NET 4 ด้วยฐานข้อมูล MySQL เมื่อเรากำลังจะปรับใช้แอปพลิเคชันนั้นเราจะติดตั้ง. NET Framework 4 ในไคลเอนต์ของเราจากนั้นเมื่อติดตั้ง. NET Connector for MySQL จะต้องใช้. NET Framework 3.5 แต่ติดตั้ง. NET 4 ไว้แล้ว . NET Framework ไม่รองรับการทำงานย้อนหลังหรือไม่ เราลงเอยด้วยการติดตั้ง. NET Framework สอง (3.5 และ 4) ซึ่งไม่เล็กในขนาดดิสก์ ความเข้ากันได้ย้อนหลังหมายถึงอะไร?

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

4
การจัดการงาน "ที่เกี่ยวข้อง" ภายในรายการงานที่คล่องตัวเพียงรายการเดียว
ฉันอยู่ในทีมโปรเจคที่มี 4 devs ฉันรวมอยู่ด้วย เราได้มีการพูดคุยกันอย่างยาวนานเกี่ยวกับวิธีจัดการกับงานพิเศษที่เกิดขึ้นในรายการงานชิ้นเดียว งานพิเศษนี้มักจะเป็นสิ่งที่เกี่ยวข้องกับงานเล็กน้อย แต่ไม่จำเป็นเสมอไปที่จะบรรลุเป้าหมายของรายการ (อาจเป็นความเห็น) ตัวอย่างรวมถึง แต่ไม่ จำกัด เฉพาะ: refactoring ของรหัสการเปลี่ยนแปลงโดยรายการงาน refactoring code ที่อยู่ใกล้เคียงรหัสที่ถูกเปลี่ยนแปลงโดยรายการ ออกแบบพื้นที่โค้ดขนาดใหญ่รอบตั๋วอีกครั้ง ตัวอย่างเช่นหากรายการที่คุณเปลี่ยนฟังก์ชั่นเดียวคุณรู้ว่าตอนนี้ทั้งคลาสสามารถทำซ้ำได้เพื่อให้รองรับการเปลี่ยนแปลงนี้ได้ดียิ่งขึ้น ปรับปรุง UI บนแบบฟอร์มที่คุณเพิ่งแก้ไข เมื่องานพิเศษนี้เล็กเราไม่รังเกียจ ปัญหาคือเมื่องานพิเศษนี้ทำให้ส่วนขยายของรายการเกินกว่าการประมาณจุดคุณลักษณะดั้งเดิม บางครั้งรายการ 5 คะแนนจะใช้เวลา 13 คะแนน ในกรณีหนึ่งเรามีรายการ 13 จุดที่ในการหวนกลับอาจมี 80 คะแนนหรือมากกว่า ในการสนทนาของเรามีสองทางเลือกสำหรับวิธีจัดการกับปัญหานี้ เราสามารถรับงานพิเศษในรายการงานเดียวกันและเขียนออกเป็นการประเมินที่ผิดพลาด อาร์กิวเมนต์สำหรับสิ่งนี้ได้รวม: เราวางแผนสำหรับ "การเติมเต็ม" ในตอนท้ายของการวิ่งเพื่ออธิบายสิ่งนี้ ปล่อยให้รหัสอยู่ในรูปที่ดีกว่าที่คุณพบเสมอ อย่าเช็คอินงานครึ่งทาง หากเราออกจากการปรับโครงสร้างใหม่ในภายหลังมันยากที่จะกำหนดเวลาและอาจไม่เสร็จสิ้น คุณอยู่ใน "บริบท" ทางจิตใจที่ดีที่สุดในการจัดการงานนี้ในขณะนี้เนื่องจากคุณอยู่ลึกเข้าไปในรหัสแล้ว ดีกว่าที่จะนำมันออกไปให้พ้นทางและมีประสิทธิภาพมากกว่าที่จะเสียบริบทนั้นไปเมื่อคุณกลับมาในภายหลัง เราวาดเส้นสำหรับไอเท็มงานปัจจุบันและบอกว่างานพิเศษเข้าสู่ตั๋วแยกต่างหาก ข้อโต้แย้งรวมถึง: การมีตั๋วแยกต่างหากช่วยให้การประเมินใหม่ดังนั้นเราจึงไม่โกหกตัวเองเกี่ยวกับจำนวนของสิ่งที่เป็นจริงหรือต้องยอมรับว่าการประเมินทั้งหมดของเรานั้นแย่มาก …

6
วิธีจัดทำเอกสารกฎเกณฑ์ทางธุรกิจ
ฉันสงสัยว่าอะไรจะเป็นวิธีที่เป็นทางการและเป็นวิธีที่ได้รับการฝึกฝนกันมากที่สุดในการทำเอกสารกฎเกณฑ์ทางธุรกิจ คุณจะทำเอกสารข้อกำหนดของ UI ของสิ่งประดิษฐ์เพื่อการพัฒนาได้อย่างไร (เช่นฟิลด์เอกสารแบบฟอร์มและวิธีการทำงานของปุ่มบนฟอร์มข้อความข้อมูล ฯลฯ )

3
ตรรกะทางธุรกิจที่ควรนั่งในสถาปัตยกรรมบริการไมโคร?
ยังคงพยายามคลุมหัวของฉันรอบ ๆ สถาปัตยกรรมไมโครบริการเนื่องจากฉันคุ้นเคยกับวิธีการแบบเสาหิน สมมติว่าเราพยายามสร้างระบบการจอง Uber ที่ง่ายมาก เพื่อลดความซับซ้อนของสิ่งที่เราสมมติว่าเรามี 3 บริการและ API ประตูสำหรับไคลเอนต์: Booking, Drivers, Notificationและเรามีขั้นตอนการทำงานต่อไปนี้: เมื่อสร้างการจองใหม่: ตรวจสอบว่าผู้ใช้ปัจจุบันมีการจองแล้ว รับรายการไดรเวอร์ที่มี ส่งการแจ้งเตือนไปยังผู้ขับขี่เพื่อรับการจอง คนขับรับการจอง สมมติว่าการส่งข้อความทั้งหมดทำได้ผ่านการโทร http แทนที่จะส่งข้อความบัสเช่นคาฟคาเพื่อให้ทุกอย่างง่ายขึ้น ดังนั้นในกรณีนี้ฉันคิดว่าBookingบริการสามารถทำการตรวจสอบการจองที่มีอยู่ แต่ใครจะได้รับรายชื่อของไดรเวอร์และการแจ้งเตือนที่มีอยู่ ฉันกำลังคิดที่จะทำในระดับเกตเวย์ แต่ตอนนี้ตรรกะแบ่งออกเป็นสองที่: Gateway - รับรายการไดรเวอร์ที่มีอยู่ + ส่งการแจ้งเตือน Booking - ตรวจสอบการจองที่มีอยู่ และฉันค่อนข้างแน่ใจว่าเกตเวย์ไม่ใช่สถานที่ที่เหมาะสมที่จะทำ แต่ฉันรู้สึกว่าถ้าเราทำในBookingบริการมันจะกลายเป็นคู่แน่น? เพื่อให้มันซับซ้อนยิ่งขึ้นจะเกิดอะไรขึ้นถ้าเรามีโครงการอื่นที่ต้องการนำระบบการจองกลับมาใช้ใหม่ แต่ด้วยตรรกะทางธุรกิจของมันเอง นั่นเป็นเหตุผลที่ฉันคิดว่าจะทำในระดับเกตเวย์เพื่อให้เกตเวย์โครงการใหม่สามารถมีตรรกะทางธุรกิจของตัวเองแยกต่างหากจากที่มีอยู่ อีกวิธีหนึ่งในการทำฉันคิดว่าแต่ละโครงการมีบริการจองของตัวเองที่จะพูดคุยกับบริการจองหลัก แต่ฉันไม่แน่ใจว่าวิธีที่ดีที่สุดที่นี่ :-)

5
ข้อผิดพลาดของการออกแบบโดเมนขับเคลื่อนด้วย Entity Framework
บทเรียนจำนวนมากเกี่ยวกับ DDD ที่ฉันศึกษาส่วนใหญ่จะครอบคลุมทฤษฎี พวกเขาทั้งหมดมีตัวอย่างรหัสพื้นฐาน (Pluralsight และคล้ายคลึงกัน) บางคนพยายามสร้างบทเรียนที่ครอบคลุม DDD ด้วย EF บนเว็บ หากคุณเริ่มศึกษาพวกเขาเพียงชั่วครู่ - คุณสังเกตได้อย่างรวดเร็วว่าพวกเขาแตกต่างกันมาก บางคนแนะนำให้แอพพลิเคชั่นมีน้อยที่สุดและเพื่อหลีกเลี่ยงการแนะนำเลเยอร์เพิ่มเติมเช่นที่เก็บข้อมูลด้านบนของ EFคนอื่น ๆ กำลังสร้างเลเยอร์เพิ่มเติมอย่างแน่นอนซึ่งมักจะละเมิด SRP ด้วยการฉีดDbContextเข้าไปใน Aggregate Roots ฉันขอโทษอย่างมากถ้าฉันถามคำถามตามความคิดเห็น แต่ ... เมื่อมาถึงการปฏิบัติ - Entity Framework เป็นหนึ่งใน ORMs ที่ทรงพลังและใช้กันอย่างแพร่หลาย คุณจะไม่พบหลักสูตรที่ครอบคลุมที่ครอบคลุม DDD ด้วยโชคไม่ดี ประเด็นสำคัญ: Entity Framework นำ UoW & Repository ( DbSet) ออกจากกล่อง รุ่นของคุณกับ EF มีคุณสมบัติการนำทาง กับ EF …

2
เหตุใดจึงใช้ `const foo = () => {}` แทนที่จะเป็น `function foo () {} '
ตัวอย่างเช่นในวิดีโอ Reduxนี้ผู้สอนมักใช้ไวยากรณ์เช่น const counter = (state=0, action) => { ... function body here } ฉันจะใช้ "ดั้งเดิม" แค่ไหน function counter(state=0, action) { ... function body here } ซึ่งสั้นกว่าจริงๆและ IMO จะชัดเจนขึ้น มันง่ายกว่าที่จะสแกนขอบซ้ายที่เป็นธรรมและมีโครงสร้างของหน้าสำหรับคำว่า "ฟังก์ชั่น" มากกว่าการสแกนขอบด้านขวาที่เป็นเศษเล็กเศษน้อยสำหรับขนาดเล็ก "=>" นอกเหนือจากthisและพยายามที่จะมีวัตถุประสงค์ไม่ใช่ความเห็นมีความแตกต่างหรือประโยชน์ที่เป็นประโยชน์ต่อไวยากรณ์ newfangled หรือไม่

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

4
บริการ MVC และ RESTful API
MVC ค่อนข้างตรงไปตรงมา มีรูปแบบตัวควบคุมและมุมมอง เมื่อเราสร้างเว็บไซต์มันทั้งหมดมารวมกันเป็น ' ไคลเอนต์ส่งคำขอคำหลัก REST ไปยังเซิร์ฟเวอร์ -> เซิร์ฟเวอร์ตรงกับ URL ที่ร้องขอไปยังการดำเนินการควบคุม -> ซึ่งจากนั้นเรียกรูปแบบ (s) สำหรับการรวบรวมข้อมูล / การประมวลผลได้รับผล -> และส่งคืนผลลัพธ์กลับไปยังลูกค้าเป็นหน้า HTML (ดู) ' ถ้าเรากำลังพูดถึง RESTful API เว็บเซอร์วิสอย่างแท้จริง จากนั้นโฟลว์ที่มีลักษณะคล้าย ' ไคลเอนต์จะส่งคำขอคำหลัก REST ไปยังเซิร์ฟเวอร์ -> เซิร์ฟเวอร์จับคู่ URL ที่ร้องขอไปยังแอ็คชั่นคอนโทรลเลอร์ -> ซึ่งจะเรียกโมเดลเพื่อรวบรวม / ประมวลผลข้อมูลรับผลลัพธ์ -> และส่งกลับ ผลลัพธ์กลับไปยังไคลเอ็นต์ใน JSON ' เหมือนเมื่อก่อน แต่ไม่มี 'มุมมอง' ... หรือมากกว่านั้น …

1
ฉันขอรวมบางส่วนของรหัสลิขสิทธิ์ MIT ไว้ในโครงการโอเพ่นซอร์สของฉันได้ไหม
นี่อาจเป็นคำตอบใช่ / ไม่ใช่ง่ายๆ แต่ฉันขอคำอธิบายอย่างละเอียด สถานการณ์ ฉันถูกขอให้ขยายระบบแหล่งข้อมูลปิดที่งานของฉันซึ่งไม่ได้รับการเผยแพร่อย่างเป็นทางการภายใต้ใบอนุญาตใด ๆ ฉันคิดว่าฉันเรียนรู้ครั้งหนึ่งซึ่งหมายความว่าสิทธิ์ทั้งหมดสงวนไว้โดยค่าเริ่มต้น แต่ฉันไม่สามารถหาแหล่งที่มาได้ในตอนนี้ดังนั้นโปรดแก้ไขให้ฉันถ้าฉันผิด ฉันได้พบโครงการ Github ที่ออกภายใต้ที่ใบอนุญาตเอ็มไอที มันมีชั้นเรียนที่ฉันสนใจที่จะใช้เพื่อให้บรรลุส่วนต่าง ๆ ของฟังก์ชั่นที่ร้องขอ ถ้ามันสร้างความแตกต่างแอพพลิเคชั่นที่ฉันได้รับการขอให้ทำงานนั้นยังไม่ได้วางจำหน่ายในปัจจุบัน มันใช้ภายในเพื่ออำนวยความสะดวกในการดำเนินงานมีการปรับแต่งสูงและไม่มีมูลค่าตลาด เหตุผลเดียวที่แท้จริงของแหล่งข้อมูลปิดคือเนื่องจากมีจุดปลายทางที่เปิดเผยต่ออินเทอร์เน็ตที่มีการจัดการที่เกี่ยวข้องอาจถูกเอารัดเอาเปรียบหากพบช่องโหว่ในรหัสโอเพนซอร์ส ความเข้าใจของฉัน คำตอบนี้ข้อควรระวังฉันไปตรวจสอบหาลิขบทบัญญัติซึ่งผมค่อนข้างมั่นใจไม่รวมอยู่ในใบอนุญาต MIT ดังนั้นอีกครั้งโปรดฉันที่ถูกต้องหากฉันผิด ใบอนุญาต MIT ระบุอย่างชัดเจน ... ประกาศเกี่ยวกับลิขสิทธิ์ข้างต้นและประกาศการอนุญาตนี้จะรวมอยู่ในสำเนาทั้งหมดหรือบางส่วนที่สำคัญของซอฟต์แวร์ ... ดังนั้นฉันจึงเข้าใจว่าใบอนุญาตจะต้องมีคำต่อคำภายในโครงการของฉัน แต่ฉันกังวลว่าสิ่งนี้จะมีผลต่อการเผยแพร่โครงการทั้งหมดภายใต้ใบอนุญาต MIT - ซึ่งฉันไม่มีสิทธิ์ทำ คำตอบนี้แนะนำให้กักรหัสโครงการ Github ซึ่งฉันรู้ว่าสามารถทำได้อย่างหมดจดในฐานะทรีย่อยของคอมไพล์ แต่ฉันกังวลว่าสถานการณ์นี้จะแตกต่างกันเนื่องจากเกี่ยวข้องกับใบอนุญาตโอเพนซอร์สที่คล้ายกันสองใบ คำถาม มันโอเคไหมที่จะมีไลเซนส์ในรูทซุปเปอร์โปรเจ็กต์ของฉันซึ่งมีอยู่ในบรรทัดเหล่านี้: ลิขสิทธิ์สำหรับส่วนของโครงการฟูถือโดย [ผู้เขียนต้นฉบับ MIT ปี] เป็นส่วนหนึ่งของ Project Bar และอยู่ภายใต้ลิขสิทธิ์ MIT ลิขสิทธิ์อื่น ๆ …

3
ตัวโหลดบาลานซ์จะส่งคืนอะไร
เมื่อผู้ใช้เยี่ยมชม load balancer และ load balancer กำหนดว่าเว็บเซิร์ฟเวอร์ใดที่จะส่งต่อไปจะเกิดอะไรขึ้นต่อไป ตัวโหลดบาลานซ์ส่งต่อคำร้องขอและข้อมูลทั้งหมดไปยังเว็บเซิร์ฟเวอร์รับการตอบกลับของเว็บเซิร์ฟเวอร์และส่งคืนนั้นกลับไปยังผู้ใช้หรือไม่? หรือเป็นเหมือนการเปลี่ยนเส้นทางที่ load balancer แท้จริงเพียงแค่ส่งคืนที่อยู่ IP ของเซิร์ฟเวอร์ที่เลือกกลับไปที่เบราว์เซอร์และเบราว์เซอร์จะต้องเปิดการเชื่อมต่อใหม่กับเซิร์ฟเวอร์ที่กำหนดหรือไม่ สัญชาตญาณของฉันบอกว่ามันจะไม่เป็นแบบหลังเพราะนั่นหมายถึงที่อยู่ IP ของเว็บเซิร์ฟเวอร์ทั้งหมดจะเป็นสาธารณะและฉันคิดว่าด้วยเหตุผลด้านความปลอดภัยจะเป็นการดีที่สุดที่จะเปิดเผยที่อยู่ของ load balancer ต่อสาธารณะเท่านั้น แต่อีกครั้งฉันไม่แน่ใจเพราะถ้าคุณเปิดใช้งานSSL terminationที่ load balancer SSL ไม่จำเป็นต้องถูกสร้างใหม่อีกครั้งด้วยเซิร์ฟเวอร์ที่เปลี่ยนเส้นทางหรือไม่

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

3
การทำลายรายการใหญ่จะล้นสแต็กของฉันหรือไม่
พิจารณาการใช้งานรายการที่เชื่อมโยงโดยลำพังดังต่อไปนี้: struct node { std::unique_ptr<node> next; ComplicatedDestructorClass data; } ทีนี้สมมติว่าฉันหยุดใช้std::unique_ptr<node> headอินสแตนซ์ที่เกินขอบเขตแล้วทำให้ destructor ของมันถูกเรียก สิ่งนี้จะทำให้สแตกของฉันสำหรับรายการขนาดใหญ่เพียงพอหรือไม่ มันยุติธรรมที่จะคิดว่าคอมไพเลอร์จะทำเพิ่มประสิทธิภาพซับซ้อนสวย (อินไลน์unique_ptr's destructor เข้าnode' s แล้วใช้ recursion หาง) ซึ่งได้รับยากมากถ้าผมทำต่อไปนี้ (ตั้งแต่datadestructor จะทำให้งงงวยnext's ทำให้มันยาก เพื่อให้คอมไพเลอร์สังเกตเห็นโอกาสการเรียงลำดับใหม่และโอกาสในการโทรหาง): struct node { std::shared_ptr<node> next; ComplicatedDestructorClass data; } ถ้าdataอย่างใดมีตัวชี้ไปnodeแล้วก็อาจเป็นไปไม่ได้สำหรับการเรียกซ้ำหาง (แม้ว่าแน่นอนเราควรพยายามหลีกเลี่ยงการละเมิด encapsulation ดังกล่าว) โดยทั่วไปแล้วเราจะทำลายรายการนี้ได้อย่างไร? เราไม่สามารถข้ามผ่านรายการและลบโหนด "ปัจจุบัน" เนื่องจากตัวชี้ที่ใช้ร่วมกันไม่มีrelease! วิธีเดียวคือกับตัวกำหนดเองซึ่งส่งกลิ่นให้ฉันจริงๆ

3
เมื่อใดที่จะใช้ REST เพื่อจัดการคำขอเทียบกับการใช้ AJAX เพื่อจัดการกับคำขอ [ปิด]
ปิด คำถามนี้ต้องการรายละเอียดหรือความคมชัด ไม่ยอมรับคำตอบในขณะนี้ ต้องการปรับปรุงคำถามนี้หรือไม่ เพิ่มรายละเอียดและชี้แจงปัญหาโดยแก้ไขโพสต์นี้ ปิดให้บริการใน6 ปีที่ผ่านมา บนหน้าเว็บของฉันหากฉันต้องการแสดงรายการแบบเลื่อนลงแบบไดนามิก (เช่นชื่อเมืองตามประเทศที่เลือก) ฉันสามารถทำได้โดยใช้ AJAX แต่ฉันสามารถทำได้โดยใช้การเรียกใช้ REST ฉันควรใช้อันไหนดี? ปัญหาของฉันคือฉันไม่ได้รับความแตกต่างระหว่างส่วนที่เหลือกับคำขอเบราว์เซอร์ HTTP อื่น ๆ (หรือที่เรียกว่าแบบฟอร์มส่ง) ฉันดูคำจำกัดความที่เป็นทางการของ REST และดูเหมือนว่าจะเป็นคำขอ HTTP REST แตกต่างจาก AJAX อย่างไร?
12 rest  ajax 

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