Computer systems programming involves developing software to connect the low-level computer hardware to high-level, user-facing application software and usually requires careful consideration of performance and resource constraints. Examples of computer systems software include compilers, operating systems, databases, numerical libraries, and embedded controllers. This course aims to provide a strong foundation in the art, principles, and practices of computer systems programming using C and C++, the languages of choice for system-level programmers.

The course lectures are structured into four parts. In the first part, students will use C to explore procedural programming (e.g., functions, conditional statements, iteration statements, recursion, types, pointers, arrays, dynamic allocation). In the second part, students will apply their knowledge of C to explore basic data structures and algorithms (e.g., lists and vectors, complexity analysis, sorting algorithms, abstract data types). In the third part, students will transition from C to C++ and then use C++ to explore four programming paradigms: object-oriented programming (e.g., C++ classes and inheritance for dynamic polymorphism), generic programming (e.g., C++ templates for static polymorphism), functional programming (e.g., C++ functors and lambdas), and concurrent programming (e.g., C++ threads and atomics). In the fourth part, students will apply their knowledge of multi-paradigm C++ to explore more algorithms and data structures involving trees (e.g., binary search trees, binary heaps), tables (e.g., lookup tables, hash tables), and graphs (e.g., depth-first search, breadth-first search, shortest path, minimum spanning trees).

The course includes hands-on discussion sections and a series of five programming assignments for students to put the principles they have learned into practice. Students will gain experience with UNIX software development including command line development tools, distributed version control, unit testing frameworks, continuous integration, debugging tools, and performance optimization. In the final two programming assignments, students will work in pairs to design, implement, test, and evaluate a high-performance handwriting recognition system to automatically classify handwritten letters.