The education of embedded systems software engineers: failures and fixes
Do the math
Mathematics lies at the foundation of much of Computer Science. Software-related examples include numeric analysis for floating point computation, queuing theory for operating system scheduling algorithms, and formal logic for proving properties of programs.
In other disciplines the mastery of such fundamentals would be a prerequisite for a degree; imagine a medical doctor graduating without having taken a course in gross anatomy.
However, Computer Science programs have no consistent policy when it comes to ensuring that the mathematical prerequisites are covered and, if anything, have de-emphasized mathematics to make room for more popular subjects.
Mathematics is sometimes called the language of science; with today’s curricula, many computer science graduates are in effect illiterate.
Real-life problems in software engineering involve very large systems, and indeed as the scale of problems being addressed increases, and as hardware capabilities continue to grow exponentially, yesterday’s very large systems seem small by comparison.
It is obviously infeasible to have students create very large systems during a one- or two-semester course. So how do teachers typically react?
Simple, by assigning exercises to build small programs instead. But this is an incomplete and misleading approach. Composing a small program and getting it to work has very little in common with designing and constructing very large systems; it doesn’t scale up.
Instead, Computer Science could learn from other disciplines, such as architecture, that have the similar challenge of teaching “the big picture”.
Architecture schools address this issue in two ways: by emphasizing extensive study of the great architectural achievements in the past, and by having students conduct the high level design of structures (buildings, bridges, etc) without filling in all the details.
This approach can be used in Computer Science curricula. Many large programs are available for study, particularly since the advent and success of the Free Software movement. Students can study these programs in detail, analyzing their strengths and weaknesses and learning the underlying design principles. And assigning high-level design for large systems will give students a good sense for such real-world issues as the interplay between system and software requirements.
“Proceed by process”
A typical regimen for a commercial software company is to issue periodic releases of its product(s), possibly on a variety of platforms, to incorporate new features, adapt to new versions of an underlying operating system or hardware processor, and repair defects.
The work requires a multi-person team who must be able to make changes and check in new versions without interfering with each other. When a problem is reported by a user, it must be possible to determine the exact source files and system build scripts that generated the executable. If a software update is required, then regression tests need to be run so that the solution does not introduce other bugs.
This section’s title quotation from Shakespeare’s Coriolanus aptly summarizes the basic issue in software production. To be successful, a development team must define and rigorously adhere to a carefully defined process, including source code version control, configuration management, and quality assurance. However, these essential process activities are not very exciting from an academic point of view and thus are not given high priority in Computer Science curricula.
“There’s no ‘I’ in ‘team’”
A fundamental issue in software engineering is people-related: team members have to work together effectively. Although this is of course required in most endeavors, software development seems special. As originally noted in Fred Brooks’ classic work , adding more people to a late project makes it later.
Since group software development is so important in the real world, one would hope that Computer Science programs would at least provide students with extensive practice in working in teams on larger projects. Unfortunately such hopes would remain unfulfilled, for two reasons.
First, a perhaps regrettable staple of the educational process is the need to assess a student’s progress through a grade, and a team project makes this difficult.
Second, setting up and monitoring group projects require a large amount of work, and teachers are already stretched too thin, or perhaps would find it more productive to devote their energies to research.
In practice what we find in a typical Computer Science curriculum is that students will do almost all their programming work in individual projects where cooperation is not only not encouraged, but actively discouraged as cheating.