This text reviews several important technologies for software development with a particular focus on Web applications. In reviewing these technologies I put emphasis on underlying principles and basic concepts, rather than meticulousness and completeness. In design and documentation, if conflict arises, clarity should be preferred to accuracy because, as will be seen below, the key problem of software development is having a functioning communication between the interested human parties. Solving a problem by an effective abstraction and representation is a recurring theme of software engineering. The particular technologies evolve or become obsolete, but the underlying principles and concepts will likely resurface in new technologies. This text provides a background understanding, making it easier follow complete and detailed expositions of these technologies that can be found elsewhere.

This text is designed for upper-division undergraduate and graduate courses in software engineering. This book intended primarily for learning, rather than reference. I also believe that the book’s focus on core concepts should be appealing to practitioners who are interested in the “whys” behind the software engineering tools and techniques that are commonly encountered. I assume that the readers will have some familiarity with programming languages and do not cover any programming language in particular. Basic knowledge of discrete mathematics and statistics is desirable for some advanced topics, particularly in Chapters 3 and 4. Most concepts do not require mathematical sophistication beyond a first undergraduate course.

The text is intended to accompany a semester-long hands-on team project in software engineering. In the spirit of agile methods, the project consists of two iterations, both focused around the same software product. The first iteration is exploratory and represents the first attempt at developing the proposed software product. This usually means developing some key functions and sizing the effort to set more realistic goals in the second iteration. In the second iteration the students should perform the necessary adjustments, based on what they learned in the first iteration. I tried to make every chapter self-contained, so that entire chapters can be skipped if necessary.