Description of Course Goals and Curriculum
Introduction to programming systems, including modular programming, advanced program design, programming style, test, debugging and performance tuning; machine languages and assembly language; and use of system call services.
COS-217, Introduction to Programming Systems, is a course designed to introduce major and non-major students to the fundamentals of “lower-level” programming and program development. It is a course required for COS major and certificate students, and knowledge learned in this course lays the groundwork for more advanced computer science classes in the department. The class covers a broad set of topics, from general development advice (e.g. how to test and debug a program) to specific details of programming (e.g. how memory is allocated in a symbol table), and intends to equip students with knowledge and tools that will be beneficial in a wide variety of fields in computer science, such as programming languages, algorithms, compilers, software development, and others.
In regards to the topics covered, the course “is divided into three major parts: machine organization and assembly language programming, program design and development, and software tools” (COS-217, Fall 2014, General Information). More specifically speaking, the course will teach students programming in the C and Assembly languages, which are low-level programming languages (“low-level” refers to languages closer to computer architecture instructions, which are generally more difficult to learn); general program construction, development, and refinement; memory allocation and implementation in data structures; and process management. In addition, the course introduces students to terminal programming and useful programming tools such as Gprof, GDB, and MemInfo.
This is one of the three introductory COS course, with a class prerequisite of COS-126, General Computer Science, or equivalent in programming experience. The Java programming experience gained in COS-126 was useful as a high-level object-oriented programming language. The professor may mention core concepts or structures taught in COS-126. Most of the material taught is new for a majority of the class, and builds on top of knowledge from previous weeks, as opposed to building on top of knowledge from COS-126 or COS-226.
Out of the three COS introductory courses, COS-126, COS-226 (Algorithms and Data Structures), and COS-217, students may wonder which class, COS-226 or COS-217, is more appropriate to take after COS-126. While students may find taking COS-226 easier, since it (like COS-126) is taught with Java, the topics of COS-226 and COS-217 are essentially independent. Certain algorithms from COS-226 may be referenced in COS-217, but these references are nonspecific and used in demonstration. COS-217 focuses on certain data structures that are are studied in COS-226, but a sufficient introduction to these data structures is given in class.
Note about technologies used:
It is recommended to program in emacs, a text editor that can be launched within the terminal. It can be daunting to start terminal programming. However, the first precept will review setting up your computer environment appropriately. If there are additional problems, asking a preceptor in office hours or on Piazza can be helpful. If you would like to program in another text editor (like vim or Sublime Text), be aware that the professor provides an emacs config file that allows you to format your coding file correctly within emacs, and these configurations will not be copied over to another text editor.
It is helpful to develop a cheat sheet of relevant terminal commands over the semester, especially those for tools such as Valgrind and Meminfo.
Learning From Classroom Instruction
The course has lectures and precepts, both of which meet twice a week. Outside of these, there are office hours and lab TA hours offered. As with many COS classes, there is a Piazza discussion/Q&A forum. As such, there is a wide variety of help offered throughout the semester.
In the semester I took this class, the professor (Robert Dondero) requested that students not use laptops in lecture. A helpful alternative to laptop notes was printing out the slides before class and writing notes next to the relevant slide. In general, the professor closely followed the slides, but also interjected with useful information: for example, noting where a particular topic might be helpful for a later programming assignment. Printing out the slides beforehand made it easy to follow along and write notes when the professor added comments.
Broadly speaking, lectures cover the new material of the class at a higher level (like different types of memory management or ways to debug your program), while precepts go over the core concepts and are more directly applicable to programming assignments. Both are important to learning the material and performing well on programming assignments, so attending all lectures and precept is highly recommended. Precept handouts are especially helpful as references for programming assignments and exams, since they specify the core “how-to’s”: how to reference a pointer, how a heap manager is implemented, etc.
The required reading is helpful as a reference, although a very close reading is probably unnecessary unless a student does not follow the lecture. The most important information is covered in lecture. One exception is the required Bryant & O’Hallaron reading related to the Unix Shell programming assignment; there is a fair amount of useful information for the assignment in that reading. If a student is new to C Programming or studying for the exam, keeping the King C Programming book close is recommended. The course recommended reading is relevant and interesting, but not critical to success in the class.
Learning For and From Assignments
Program development is a task that requires both a sense of the overall structure of the program and attention to the minute details. Even a simple ‘one-off’ error can result in a common COS-217 bug called a “seg fault,” which can cause hours of searching. Precision and order is emphasized in assignments, so sloppy code may cost as many points as nonfunctional code.
As for assignments, start early. It is not uncommon for COS-217 programming assignments to take hours longer to complete than anticipated. Starting early will not only give you time to go to office hours, but you will also miss the crowd of students at office hours the day before the deadline. One way to approach assignments is to first gather all relevant materials for that assignment: the assignment itself, all related precept handouts, and all related lecture notes. Then, review and understand the core concept behind the programming assignment (e.g. registers or Assembly with the Assembly assignment). Precept handouts often directly relate to assignments. If anything is unclear, Piazza is a helpful resource for general questions related to the assignment.
If you get stuck during an assignment, it may take hours to identify the problem and fix the bug. One crucial tool for debugging is GDB, the GNU Debugger, which allows you to step line-by-line through your code. Memory errors (like seg faults) do not show the particular line at which it crashed, so stepping through your program line-by-line is one of the fastest and easiest ways to locate the bug. GDB is a tool automatically accessible in the terminal, if your environment is set up according to the first precept’s instructions. If you have been stuck for hours, it is highly recommended to go to office hours and ask the preceptor or professor for help, since they usually know the solution to the assignment and have experience with the common errors that students encounter. Lab TAs can similarly be useful in these cases. In these assignments, getting another pair of eyes to look at your code can save hours of time.
Before submitting your assignment, be sure it passes the style check tests (splint and critTer). As stated before, you may lose points for sloppy coding. Commenting code is essential to writing good code, so you also may lose points if your code is not commented adequately.
As for exam preparation, past exams and solutions are made available beforehand. It can be difficult to predict what types of questions will appear on the exam, so taking practice exams will let you work through many different types of questions. Take as many as you can, and review all of the solutions. Review the slides and precept handouts as well, since they will cover core concepts that are sure to be on the exam (for example, process management). If a solution is unclear, asking on Piazza is helpful, and answers often appear within the same day.
During the exam, be sure to pay attention to details. You may be required to trace through code, in which case a one-off error will cause a wrong answer. Be careful of getting stuck on a problem in the middle of the exam; easier problems should be tackled first before the harder problems, which can take longer than anticipated.
All of the knowledge necessary to the course is included in either lectures, precepts, or readings, and the information is often conveyed clearly. If one concept is particularly difficult to understand, it may be useful to search online for tutorials or videos explaining it.
What Students Should Know About This Course For Purposes Of Course Selection
COS-217 is a substantial programming class. Assignments can take many, many hours to complete, depending on how quickly you resolve bugs. In low-level programming, errors are particularly difficult to find, so it is easy to let an assignment eat hours of your time. Despite this, the concepts taught in COS-217 are fundamental to the study of computer science and useful even for the student who does not want to focus on programming systems.
Personally, taking this class confirmed to me that I really wanted to be a computer science major. Even though the class is difficult, the assignments are awesome — for example, after programming in the shell for a semester, you actually get to code a Unix shell in C. COS-217 gives you insight into how computers work at a very low level, which is useful in software development. Furthermore, it equips you with tools necessary to become a better programmer in general. It’s a difficult class, but the gains are worth the effort.