Software Systems Design (FIRST DRAFT)

Version 0.1

About this book

What is a system?

A system is generally considered to be a collection of interacting components. Software-based systems are ubiquitous today, as even inexpensive devices include embedded microcontrollers. Most of the systems we will examine in this course include human users. Their role in shaping the overall behavior of a system is crucial. For our purposes, a software-based system is one made of hardware components, software components, and “external” components (e.g. humans, rocket engines, cameras) where the software plays a major role in determining the behavior of the system as a whole.

The first chapter is a brief overview of design. Software-based systems, like almost everything in the built environment, are designed – they are planned, implemented, and deployed for a particular purpose.

Design is a practice that cuts across many different disciplines. Some computer science courses are about programming, in other words, designing programs. In this class, we look at the bigger picture, at how entire software-based systems are designed. A key aspect of any discussion about design is how to evaluate a design, and we’ll address that as well.

Software executes in a context

Software cannot execute in isolation. There is always a context. At the very least, there is something executing the software, perhaps a CPU or VM. But neither a CPU nor a VM exists in isolation. They are connected to other things.

Hardware, software, users, networks, and storage are ubiquitous. Light bulbs have upgradable firmware and internet addresses. Washing machines send their owners text alerts and emails. Cars are now (networks of several) computers that can also drive on the roads.

The network of networks is global, though access is certainly not uniformly distributed. Large tech companies deploy services that are used worldwide. Geopolitical factors affect the design and availability of all manner of products, including software-based services.

Undergraduates rarely get to see the big picture

Where in the typical undergraduate computer science curriculum do we discuss systems? In HCI courses (and others), we look at human-computer interaction through a design lens. In distributed systems courses, we look at computing systems that include a network. In courses on privacy and security, we focus on certain properties of data, in motion and at rest. I could go on.

The standard courses reduce, of necessity, the scope of analysis. An HCI course may not consider the EU’s GDPR regulation, or the implications of a distributed server system hosting an application. A distributed systems course, by turn, may not be able to address hot standby designs and other approaches to service resilience. Privacy and security courses may not examine challenges related to a system scaled up to serve many users in many countries.

In 2023, I piloted a course at NCSU aimed at upper level computer science students that tries to take a broad view. I built the course on a series of (informal) case studies, each of which is a system worthy of study.

Naturally, with a broad agenda, we can only go so deep. When we are lucky, our case studies situate concepts that students have seen elsewhere, such as in other courses. At other times, all we can do is build awareness of system design issues. For example, a student should leave this course aware of queuing theory, though we may discuss only the most basic ideas from that field.

As working engineers, we aim to produce useful systems. Some requirements, such as those related to performance or scale or resilience, may be quite challenging to address in our designs. Our success may depend on knowing what we don’t know!

We may design a system with a request queue, for example, but be frustrated trying to size the queue or the server components to meet demand. Just knowing that queueing theory exists gives us options. We can open a book (or maybe watch some videos) and learn what we need to know. Or we can consult an expert.

The only bad choice, perhaps, is to endure endless frustration trying to make a system work, because we don’t know what we don’t know.

This book is not a (traditional) textbook

This book is largely a collection of pointers to other material. Our case studies are formed by required readings and viewings of material not hosted here. The discussion questions and topics for additional study likewise resemble an annotated bibliography.

The material contained here represents my own view of key issues in the design of software-based systems, but there have been many contributors. In Spring 2023, when the course was first offered, my students voluntarily contributed and edited a set of course notes. They generously gave me permission to use those notes to supplement my own in drafting this book.

Because there were so many note-takers and editors, it is difficult to make precise attributions. Instead, I list below those that have contributed their notes or their efforts in editing and organizing notes. I am grateful to these (now former) students, and to all the students in this course.

Contributors

To be listed

Last updated on 29 Jan 2024
 Edit on GitLab