ในยุคที่เทคโนโลยีมีบทบาทสำคัญอย่างยิ่งในสังคมสมัยใหม่ ซอฟต์แวร์ถูกนำมาใช้ในการพัฒนาในด้านต่างๆมากมายเพื่อเปลี่ยนแปลงโลกให้ดีขึ้น แต่กว่าที่แนวคิดต่างๆจะถูกสร้างขึ้นมาเป็นระบบซอฟต์แวร์ขนาดใหญ่นั้นต้องผ่านอุปสรรคและความล้มเหลวมามากมาย วิศวกรรมซอฟต์แวร์ (software engineer) เป็นเทคนิกในการพัฒนาโครงการซอฟต์แวร์ที่ถูกรวบรวมมาจากการลองผิดลองถูกมาเป็นเวลานาน แต่ก็ไม่ใช่ว่าทุกเทคนิกจะถูกนำมาใช้กับทุกโครงการพัฒนาซอฟต์แวร์ การเลือกเทคนิก แนวทาง หรือกระบวนการแบบใดที่ควรนำมาใช้จะขึ้นอยู่กับประสบการณ์ของผู้ทำงาน
วิศวกรรมซอฟต์แวร์ครอบคลุมองค์ความรู้ที่หลากหลาย ตั้งแต่ที่เราเริ่มมีแนวคิดที่จะพัฒนาอะไรสักอย่าง การรวบรวมความต้องการ การออกแบบตามความต้องการที่รวบรวมมา การออกแบบในภาพรวม (high level design) การออกแบบในรายละเอียด (low level design) กิจกรรมต่างๆที่ต้องทำเพื่อให้แน่ใจว่าซอฟต์แวร์ที่พัฒนาขึ้นมาทำงานได้ตามต้องการ การติดตั้งใช้งาน การบำรุงรักษา การแก้ไขข้อผิดพลาดต่างๆที่พบ การปรับปรุงและพัฒนาเพิ่มเติมความสามารถใหม่ๆ จนถึงจุดหนึ่งที่เราอาจจะต้องกลับมาสร้างระบบใหม่ขึ้นมาทดแทนระบบเดิมที่อาจจะไม่สามารถพัฒนาให้ตอบโจทย์ได้อีกต่อไปหรืออาจจะไม่คุ้มกับค่าใช้จ่ายในการพัฒนาต่อ
หลักการของวิศวกรรมซอฟต์แวร์จะครอบคลุมตั้งแต่การวางแผน (plan) ออกแบบ (design) พัฒนา (implement) ทดสอบ (test) ปรับปรุงหรือเพิ่มเติมความสามารถให้ดีขึ้น (evolve) ซึ่งหลักการต่างๆเหล่านี้จะช่วยลดอุปสรรคและความเสี่ยงในความล้มเหลวของการพัฒนา การเรียนรู้เรื่องวิศวกรรมซอฟต์แวร์จะแบ่งออกเป็นส่วนๆคือ
(1) เรียนรู้เกี่ยวกับกระบวนการในการพัฒนาซอฟต์แวร์ซึ่งเป็นขั้นตอนต่างๆตั้งแต่เริ่มมีแนวคิดไปจนถึงการสร้างและการติดตั้งซอฟต์แวร์ซึ่งกระบวนการมีทั้งแบบดั้งเดิม เช่น กระบวนการแบบ Water Fall และกระบวนการแบบ Spiral และวิธีการแบบอไจล์ (Agile) ซึ่งใช้กระบวนการสมัยใหม่ เช่น กระบวนการแบบ Extreme Programming (XP), กระบวนการแบบ Test Driven Development (TDD) และกระบวนการแบบ Scrum รวมถึงการกำหนดว่าใครบ้างที่เกี่ยวข้องในกระบวนการ เอกสารที่ต้องใช้ และข้อดี/ข้อเสียของแต่ละกระบวนการ
(2) เรียนรู้เกี่ยงกับกระบวนการในการรวบรวม (gathering) และประเมินคุณค่า (validating) ของความต้องการ (requirement) การทำความเข้าใจประสบการณ์ที่ผู้ใช้งานต้องการ (user stories) การกำหนดรายละเอียด (specification) ของซอฟแวร์ที่จะพัฒนา(ซึ่งต่อไปจะเรียกว่าสเปค) ทั้งหมดนี้จะเป็นเครื่องมือที่ช่วยให้เกิดการสื่อสารกันระหว่างผู้พัฒนาและลูกค้า/ผู้ใช้งาน (ซึ่งต่อไปจะเรียกว่าผู้ใช้งาน)
(3) เรียนรู้เกี่ยงกับการทดสอบเพื่อให้แน่ใจว่าซอฟต์แวร์ที่พัฒนาขึ้นมาสามารถใช้งานได้ตรงตามรายละเอียดที่ได้กำหนดไว้ โดยจะทำความเข้าใจเทคนิกต่างๆในการทดสอบ เช่น การทดสอบโดยยึดตามเนื้อหาของโปรแกรม (coding) ตามที่เขียนไว้ ( white-box testing) การทดสอบโดยยึดตามวัตถุประสงค์ของการใช้งาน (black-box testing) การทดสอบโดยเปรียบเทียบกับผลลัพธ์ที่กำหนดไว้ล่วงหน้า (assertion test) และการออกแบบซอฟต์แวร์ที่เป็นมิตรกับการทดสอบ (testabillity)
(4) เรียนรู้เกี่ยวกับการออกแบบในภาพรวม จะเป็นการออกแบบที่ช่วยให้การปรับปรุงและการบำรุงรักษาซอฟต์แวร์สามารถทำได้อย่างมีประสิทธิภาพ โดยการใช้แนวคิดของการซ่อนรายละเอียด (abstraction) การแยกองค์ประกอบ (decomposition) การห่อหุ้ม (encapsulation) การซ่อนข้อมูล (information hiding) การนำเสนอ (representation) การใช้ API การใช้ REST การเชื่อมต่อและการทำงานร่วมกัน (couplings and cohesion) และการใช้หลักการ SOLID ในการออกแบบ รวมถึงการใช้ไดอะแกรมเพื่อตรวจสอบความผิดพลาดในการออกแบบ
(5) เรียนรู้เกี่ยวกับการออกแบบในรายละเอียด จะเป็นเรื่องแบบแผน (pattern) ต่างๆในการออกแบบซอฟต์แวร์ เช่น Singleton, Strategy, State, Facade, Decorator, MVC และ MVP (6) เรียนรู้เกี่ยวกับการสร้างซอฟต์แวร์โดยใช้เครื่องมือ เช่น non-structural properties, static analysis และ linters, automation, code smells และ refactoring เพื่อควบคุมคุณภาพของซอฟต์แวร์