My preference for teaching is to offer courses that mix theory with practice. Computer Science is nothing if not of practical value in today's technical, information-oriented society, and I am as confused as students are when I see Computer Science material presented without a clear indication of why the material "matters". When I teach a course, I like to first show the students what the important abstractions are, how they can be manipulated, what problems they solve, and then have the students work in a hands-on fashion with realizations of those abstractions and solutions.
For example, in 1994 I developed the course material for our COMP 204 core graduate class in software design and development, including formal methods. Over the course of a semeseter, students learn several different methods for specifying program behavior mathematically, and they learn mathematical methods for proving that programs adhere to these specifications. Though the content has evolved over the decade, the mix of theory and practice has not. In earlier years we had the students actually specify, develop, and verify significantly sized systems using the techniques they study. In more recent years, as methods change, we have them implement tools for doing the analyses they study, such as model checking. This is well beyond the normal back-of-the-text-book problems classes often rely on. Building the tools reinforces their understanding of the algorithms. The students demonstrate their final systems before the class when done, and present (and defend) their design rationale.
I use this same approach at UNC in COMP 145 (team software engineering), and have used it in COMP 217 and 213 (File and Databases, Languages), as well as in compiler classes I have taught at other universities. It is very effective at involving the students' imagination and enthusiasm in the class. Convincing a student to try something is far more important than convincing a student to listen to you tell them about something.
Most recently I applied this approach in teaching COMP 144 (programming languages) here at UNC. A portion of most every class meeting is spent actually running language tools (compilers, interpreters, IDEs) to demonstrate live the systems and languages under discussion. I especially like to have the students write program fragments collectively in class, as part of the discussion. I think this helps solidify the concepts they are hearing and forces them to begin internalizing the material right there, in class, at first or second exposure.
I also prefer collaborative work when possible and practical. I think working in small groups helps bring all students along rather than letting weaker ones fade. With some variations, I have the students work in groups of two or three on projects and programs. They present their results in class, to strengthen their presentation and speaking skills and to spur class discussions during the design critiques. Especially in software engineering classes, group work reinforces the reality of development outside the university, where accomplishments are usually team efforts rather than individual.
I try to work proven research results into teaching practice as they are developed. Before the Web existed, I had already used two different hypertext systems for notes presentation and communication with and among students in my classes. I wrote a paper entitled "Hypermedia Support for Learning Complex Intellectual Tasks," which documents an informal multi-year experiment of mine in using hypermedia notes to teach program verification. The dynamic nature of hypermedia browsing allowed me to provide notes to my students that guide them step-by-step through complex, process-oriented tasks that are traditionally difficult to learn. I observed three classes of students supported by this technology (two here at UNC, one at the Univ. of Florida), and compared students' learning success with classes I taught at the Univ. of Maryland before the technology was available. The UNC students were learning the material better, using the hypermedia support. Of course, the Web has now made this easy and popular to do, and this approach is now mostly expected in classes.
My "lectures" are guided discussions. Questions are welcomed at any time. I elicit student participation with many questions of my own. I try not to let anyone get through the class uninvolved. I expect reading to be done ahead of class so the students will be prepared to participate in the discussion.
On the first day of a class, I show the students what my goals are for a
course. I lay out what I expect they will learn and accomplish by the end
of the semester. I ask them to track their individual progress towards
these goals throughout the semeseter, to make sure each student is getting
there. If I have to make changes to a class as we go along, I revisit
the syllabus to discuss which class goals will be affected.
When all the circumstances conspire, I find teaching to be very rewarding, which keeps my enthusiasm high. I don't expect students to be interested in a subject if I am not; I use this guideline to gauge what techniques will work to keep a class lively and productive.