So kennen Sie den Computer

Jedes Kleinkind weiß heute, was ein Computer ist. Aber kein Kleinkind kann einen Computer so genau beschreiben, wie Sie das können:

Der Computer ist ganz einfach ein Rechner. Die Bezeichnung stammt aus dem Lateinischen: Computare = zusammenrechnen. Heute ist dieser Rechner oft schon ein Gerät, das wenig Platz erfordert. Es steht als Desktop auf oder unter dem Arbeitsplatz oder ist als Laptop schon kombiniert mit dem wichtigsten Ausgabegerät, dem Bildschirm. Der Rechner verarbeitet das, was ihm eingegeben wird. Dazu dient ihm sein Herz, die CPU (Central Processing Unit).

Das Ergebnis, das vom Computer erwartet wird, kommt nach dem EVA-Prinzip zu Stande:
EVA = Eingabe, Verarbeitung, Ausgabe

Daten und Befehle empfängt der Rechner über die Tatatur, die Maus, Scanner, Mikrofon und Bildschirm (Maus, Touch-Screen). Dazu gibt es Eingaben aus dem Zuladen von Speichermedien wie DVD, CD-ROM, USB-Memory-Sticks, Disketten und weiteren Speichermedien.

Die Verarbeitung erfolgt gemäß den ablaufenden Programmbefehlen in der CPU. Es wird verknüpft, verschoben, verändert, gelöscht etc. Damit das alles funktioniert, gibt es im Rechner ein Verkehrsmittel, den Bus. Er transportiert die Daten und Programmbefehle. Was zuerst erledigt werden soll, ist in den Registern der CPU geordnet. Was nachfolgt, befindet sich im Kurzzeitspeicher Cache. Die nächsten Daten und Befehle warten im Arbeitsspeicher. Und was dann noch erledigt werden soll, muss von der Festplatte des Rechners oder externen Speichermedien zugeladen werden.

Die Ausgabe erfolgt über Geräte, die das Ergebnis des Rechners so darstellen, dass der Benutzer damit etwas anfangen kann. Bildschirm, Drucker, Lautsprecher – das ist das Dreigestirn der Ausgabe.

Ohne Betriebssystem geht nichts

Damit Mensch und Rechner sich verstehen, ist ein Betriebssystem unerlässlich. Es garantiert, dass nach dem Einschalten binnen weniger Momente dem Nutzer eine Arbeitsfläche zur Verfügung steht, die er versteht. Das setzt voraus, dass der Rechner blitzschnell schon mal einige grundlegende Arbeitsschritte erledigt. Er rechnet einen Arbeitsplatz herbei, der natürlich nur so aussehen kann, wie er einmal programmiert ist. Er lädt Anwendungsprogramme, Ordner und Speicher, Verbindungen zu Eingabe- und Ausgabegeräten usw. Diese Vorarbeit des Rechners beim Hochfahren ist dafür verantwortlich, dass wir überhaupt mit dem Rechner kommunizieren können.

Im Zeitalter der DOS-Rechner sah das Betriebssystem so aus, das auf dem Bildschirm zunächst eine schier endlose Reihe von abgearbeiteten Befehlen erschien, bis dann das erlösende C:// erschien. Darauf musste man eingeben, auf welches Verzeichnis der Rechner zugreifen sollte. Dann kam Windows, und damit fing die Segenszeit der grafischen Benutzeroberflächen an. Heute ist es jeder gewohnt, einen Arbeitsplatz zu haben, der über Zeichen (Icons) und Ordner schnell zu dem führt, was man braucht.

Neben Windows sind als Betriebssysteme Linux und OS für die Apple-Computer gebräuchlich. Alle drei generieren unterschiedliche Arbeitsplätze und Benutzeroberflächen. Betriebssystem und Rechner werden in der Regel im Paket verkauft. Dies hat durchaus Sinn gemacht für die Jahre, in denen die großen Wettbewerber der PC-Industrie noch grundlegend unterschiedliche Chips einbauten. In den letzten Jahren hat eine Bewegung auf einen einheitlichen Standard eingesetzt. Vielleicht ist es in Kürze möglich, dass jeder auf der Hardware seiner Wahl das ihm passende Betriebssystem einsetzt.

Was den Anwender interessiert

Benutzer oder Anwender sind in der Regel Menschen, die mit dem Computer bestimmte Ergebnisse und Darstellungen erzielen wollen. Der Computer ist ihr Arbeits- oder Spielgerät. Sie verhalten sich zum Computer wie zu einem Auto. Grundsätzliche Anforderung: Er muss fahren, das heißt ganz einfach funktionieren. Den normalen Benutzer interessiert nicht, ob der Computer mit oben liegender Nockenwelle arbeitet oder dergleichen. Ihn interessiert kaum, wo der Motor sitzt. Sein Interesse gilt der Bequemlichkeit, der Optik und der sicheren Beförderung von A nach B. Dafür sorgen im Computer die Anwendungsprogramme. Schwer genug für den Nutzer, Sie zu lernen. Noch schwerer und bisweilen richtig ärgerlich ist die Manie der Softwareindustrie, alle 1-2 Jahre Updates der Programme zu liefern. Häufig bringen sie neben Verbesserungen auch Verschlechterungen und meist Änderungen in vielen Teilen der Benutzerführung. Ergebnis: Der Anwender muss neu lernen, findet die gewohnten Funktionen nicht mehr oder nicht dort, wo er sie immer gefunden hat.

Den Benutzer interessiert selten, wie ein Computer genau funktioniert. Es bewegt ihn auch nicht, was sein Betriebssystem kann und leistet. Sein Fachwissen und sein Bedürfnis nach Computerunterstützung fokussieren ihn auf das Anwendungsprogramm. Und das macht Sie als Programmierer/in zum wichtigsten Verbündeten des Benutzers. Sie sorgen dafür, dass Benutzer mit ihrem Computer auf Du und Du stehen und sich voll auf ihren leichten Weg zum besten Ergebnis verlassen können. Sie stehen in jedem Moment hinter dem Benutzer und fragen ihn: Was brauchst du noch in deinem Programm, was kann ich für dich besser machen? Wenn Sie nicht auf Tuchfühlung mit dem Anwender gehen, wenn Sie nicht fragen und gut zuhören, dann geht es schnell, dass Sie zu Anwenders bestem Feind werden.

Der Prozessor richtet es!

Die zentrale Recheneinheit eines Computers ist der Prozessor. Gemeinhin wird er auch als CPU (Central Processing Unit) bezeichnet. Sind, wie heute in den meisten PCs üblich, mehrere Prozessoren als eingebettetes System (embedded systems) eingebaut, so steuert die CPU alle anderen Prozessoren. Ein Hauptprozessor ist über seine einzelnen Bestandteile oder Funktionseinheiten der Manager aller Prozesse im Computer.

Das Verhalten des Prozessors bestimmen programmierte Einheiten, die Befehle und Daten im Maschinencode stellen. Hauptbestandteile des Prozessors sind:

Die Register
Als interne Speicher stellen Register schnelle Verbindungen zu anderen Prozessorbestandteilen bereit. Sie sind das Nahverkehrssystem mit der Geschwindigkeit eines Transrapid. Sie stellen die erste Stufe der gesamten Speicherhierarchie des Computers dar. Nur mit ihren Daten können direkt Operationen ausgeführt werden.

Die Arbeitsregister liefern Daten und, je nach Prozessortyp, auch Adressen.

Das Befehlszählregister nimmt immer die Adresse des Befehls auf, der als nächstes ausgeführt werden soll. Deshalb wird es oft auch als IP (Instruction Pointer) bezeichnet.

Das Befehlsregister nimmt Befehle in binärer Maschinensprache auf, die Grundlage der Rechenvorgänge sind.

Größe und Eigenschaften der Register sind ein Indiz für die Leistungsfähigkeit des Prozessors.

Rechenwerk
ALU (Arithmetic Logical Unit) – so heißt das Rechenwerk, das die elementaren Operationen eines Rechners ausführt. Es kann arithmetische Operationen wie die Addition ausführen oder logische Operationen wie etwa UND (AND) und ODER (OR).

Befehlsdecoder
Ein notwendiger Übersetzer, der aus binären Maschinenbefehlen mit Hilfe der Befehlstabelle (Instruction Table) die entsprechenden Anweisungen kreiert, die dann Schaltungen aktivieren, durch die ein Befehl erst ausgeführt wird.

Steuerwerk
Die Kontrollinstanz im Prozessor ist das Steuerwerk. Es checkt und setzt die Ausführung der Anweisungen in Gang. Es sorgt dafür, dass der Befehl im Befehlsregister vom Befehlsdecoder decodiert und vom Rechenwerk ausgeführt wird. Es lädt den bei der Adresse im Befehlszählerregister liegenden Befehl in das Befehlsregister und dann die nächste Adresse ins Befehlszählerregister. Fast schon wie beim Militär.

Speichermanager
Das Zentralorgan zur Verwaltung aller Speicher, genannt Memory Management Unit (MMU). Die MMU regelt den Zugriff auf Arbeitsspeicher und Hardware, indem sie virtuelle Adressen in physische Adressen übersetzt und dann auf den Adressbus setzt. Die MMU verfügt über spezielle Cache-Speicher, die Translation Lookaside Buffer, die jeweils die letzten Adressübersetzungen in Tabellen speichern. Daneben hat die MMU Speicherschutzfunktionen. Sie kann Speicher für bestimmte Codes sperren. Sie schottet Prozesse voneinander und vom Betriebssystem ab. Der Betrieb wird wesentlich sicherer, da die MMU verhindert, dass Fehler in einem Prozess zu einem direkten Zugriff auf Daten eines anderen Prozesses oder des Betriebssystems führen.

Caches
Caches sind die Zwischenspeicher. Sie enthalten die zuletzt verarbeiteten Daten und Befehle und stellen Sie bei Bedarf blitzschnell wieder zur Verfügung. Nach den Registern stellen sie die zweite Stufe der Speicherhierarchie dar. Bis zu drei Caches werden inzwischen in Computerprozessoren eingebaut:
Level-1-Cache: Dieser Cache läuft mit dem Prozessortakt. Er ist sehr klein, fasst nur etwa 4-256 KB. Dafür ist er aufgrund seiner Lage zentral im Prozessorkern ein richtig schneller.
Level-2-Cache: Auch dieser ist direkt in den Prozessor eingebaut, liegt jedoch nicht im Kern. Er fasst bereits zwischen 64 KB und 12 MB.
Level-3-Cache: Ein Cache, der meist in Mehrkernprozessoren eingebaut wird. Ihn müssen sich die Prozessoren teilen. Er ist der langsamste, aber auch der größte der drei Caches, bis zu 256 MB fasst er.

Datenleitungen
Für den Transport sind im Prozessor oder in der Prozessorenlandschaft Busse zuständig. Dieses Nahverkehrssystem ist streng reglementiert, nicht jeder darf zusteigen. Je nach Architektur des Prozessors sind ein oder zwei Datenbusse für den Transfer der Programmcodes und der normalen Daten zuständig. Über den Adressbus laufen die Speicheradressen. Und schließlich steuert der Prozessor mit dem Steuer- oder Kontrollbus die Peripherie-Anschlüsse, also Anschlüsse für die umgebenden Geräte (via USB, PCI etc.).

In den letzten Jahren werden immer mehr Funktionen, die früher nach einem separaten Chip verlangten, in die Prozessoren integriert. Darunter zum Beispiel

  • ein numerischer Coprozessor für schnellere Rechenoperationen;
  • Vektorarithmetikeinheiten für schnelle Grafikbearbeitung;
  • Chipsatz (oder Teile davon) zur Ansteuerung des RAMs;
  • Grafikchip zur Anzeigesteuerung etc.

So fing alles an

Vor dem Zweiten Weltkrieg bestand das Rechenwerk eines Computers aus Relais und mechanischen Bauelementen. Diese elektromechanischen Rechner waren langsam und sehr störanfällig. In den 40er Jahren des 20. Jahrhunderts begann man, Computer mit Hilfe von Röhren zu bauen. Diese Röhrenrechner wurden in den 50er Jahren dann „Massenprodukte“, die zwar in keinem Haushalt, aber doch schon in vielen Universitäten, Forschungseinrichtungen und einigen Unternehmen ihren Dienst taten. Um die Rechner erschwinglich zu machen, wurde die Anzahl der Röhren reduziert: Hauptspeicher und CPU-Register waren nun auf einer Magnettrommel untergebracht. Rechenoperationen wurden seriell ausgeführt, und die Ablaufsteuerung realisierte man mit Hilfe einer Diodenmatrix. In den frühen 60er Jahren begann dann die Neuzeit der Computertechnik. Röhren wurden durch Transistoren ersetzt und im Laufe der Jahre brachte man immer mehr Transistorfunktionen in integrierten Schaltkreisen unter. Der Weg zum modernen Chip war konzipiert.

Heute kann man wirtschaftlich erträglich bereits rund 1 Milliarde Transistorfunktionen auf einem einzigen Chip unterbringen.

RAM = Random Access Memory

Verdeutscht heißt das RAM soviel wie „Speicher mit wahlfreiem Zugriff“ oder „Direktzugriff“. RAMs werden in allen Arten von elektronischen Geräten eingesetzt, besonders aber als Arbeitsspeicher im Computer. Es sind Schreib-/Lesespeicher.

RAMs sind meist als integrierter Schaltkreis in Silizium-Halbleitertechnik umgesetzt. In Reihen und Spalten, einer Matrixform, sind die Speicherzellen auf dem Chip angeordnet. Eine Steuerleitung gibt dem Chip an, ob geschrieben oder gelesen wird. Zum RAM-Chip gehören natürlich auch Datenleitungen, die so genannten Pins. RAMs gibt es in einigen technischen Varianten, die sich vor allem dadurch unterscheiden, ob sie flüchtig (volatil) oder nicht flüchtig (non volatil) sind. Flüchtig meint dabei, dass Daten energieabhängig gespeichert werden. Sobald der Energiefluss unterbrochen wird, gehen die Daten verloren.

In Computern sind überwiegend volatile RAMs eingebaut. SRAMs (statisches RAM), die relativ groß und Energie fressend sind, als Cache-Speicher. DRAMs (dynamisches RAM) mit kleiner Kapazität, geringerem Stromverbrauch und hoher Geschwindigkeit als Arbeitsspeicher.

ROM = Read Only Memory

Ein Festspeicher, nicht volatil, der im normalen Betrieb nur gelesen, aber nicht beschrieben werden kann. In Computern ist das Basisprogramm BIOS (Basic Input/Output System) zum Starten des Betriebssystems zum Beispiel auf einem ROM programmiert. Inzwischen gibt es unterschiedliche Varianten von ROMs, vom nicht beschreibbaren über den unter bestimmten technischen Voraussetzungen beschreibbaren bis zum löschbaren und wieder beschreibbaren. Heute wird als Ersatz für das ROM schon häufig ein Flash-Speicher verbaut.

So funktioniert ein Prozessor

Prozessoren sind ganz einfache Soldaten. Sie gehorchen nur Befehlen, die für sie in eine besondere Sprache übersetzt werden – die Maschinensprache, binär ausgelegt. Das heißt, Soldat Prozessor versteht nur 0 und 1.

Jeden Befehl bearbeitet ein moderner Prozessor in ein- und derselben Weise. Er folgt dabei dem Von-Neumann-Zyklus. John von Neumann war ein kluger Kopf, der 1945 als einer der ersten eine Computer-Architektur beschrieb, die es möglich machte, von der Rechnerhardware-Programmbindung abzuweichen. Bis dahin wurden Rechner für bestimmte Programme gebaut oder umgekehrt. Von Neumann schuf die Architektur für den Universalcomputer, der mit verschiedenen Programmen unterschiedlicher Programmiersprachen zurechtkommt.

Der Von-Neumann-Zyklus sieht so aus:

1. FETCH
Aus dem Befehlszählregister wird die Adresse des nächsten Maschinenbefehls gelesen. Er wird aus dem Arbeitsspeicher in den Befehlsspeicher geladen.

2. DECODE
Der Befehlsdecoder decodiert den Befehl und aktiviert alle Schaltungen, die dafür sorgen, dass der Befehl ausgeführt wird.

3. FETCH OPERANDS
Von der Festplatte, aus dem Cache oder dem Arbeitsspeicher werden alle Werte und Parameter in die Register geladen, die Gegenstand des Befehls sind und die verändert werden sollen.

4. EXECUTE
Der Befehl wird ausgeführt. Das heißt, es werden Peripheriegeräte (Drucker etc.) angesteuert oder Operationen im Rechenwerk durchgeführt oder ein Sprung im Programm bewerkstelligt. Sprung im Programm bedeutet, dass das Befehlszählerregister verändert wird.

Jetzt kann der Zyklus wieder von vorne beginnen.

Und das läuft nebenbei auch noch.

Während decodiert wird und die Operanden hereingeholt werden, wird auch der Update Instruction Pointer aktiv. Das ist der Befehlszähler, der sich regelmäßig ändert. Wird in der Execute-Phase kein Sprungbefehl ausgeführt, steigt er jeweils um 1 Zähler.

Nach dem Execute-Vorgang gibt es normalerweise auch noch eine Rückschreibphase, in der angefallene Rechenergebnisse in bestimmte Register geschrieben werden.

Nebenbei kommen ab und zu so genannte Hardware Interrupts vor: Die Hardware des Computers kann Anfragen an den Prozessor richten. Diese werden bevorzugt und sofort bearbeitet. Der Prozessor prüft also regelmäßig, ob Hardware-Anfragen vorliegen und unterbricht seine Arbeit am Programm, wenn dies der Fall ist.

Prozessor ist nicht gleich Prozessor

Als Prozessorkern (engl. core) wird das eigentliche Rechenwerk des Prozessors bezeichnet. Um diesen herum sind die weiteren Komponenten wie Caches und die Memory Management Unit angeordnet. Inzwischen hat die Entwicklung der Halbleitertechnik dazu geführt, dass mehrere Prozessorkerne auf einen Mikrochip passen. Dadurch werden die Computer schneller, obwohl jeder einzelne Prozessorkern in der Geschwindigkeit klaren physikalischen Grenzen folgt. Die Leistung eines Prozessors bestimmt sich durch die Anzahl der verbauten Transistoren (aktuell bis zu 1,9 Milliarden möglich), durch die Wortbreite (im Normalfall bei PCs 64 Bit) und die Taktfrequenz.

Es gibt Prozessoren ganz unterschiedlicher Bauart: Asynchrone Prozessoren, Bit-Slice-Prozessoren, Mehrkernprozessoren, Mikrocontroller und Mikroprozessoren. Und es gibt eine ganze Reihe Prozessoren, die auf bestimmte Funktionen ausgerichtet sind:

  • Digitaler Signalprozessor (DSP): Er verarbeitet analoge Signale mit Hilfe digitaler Syteme. DSPs haben getrennte Bus-Systeme für Daten und Befehle
  • I/O-Prozessor: Er steuert sicher die Eingabe- und Ausgabegeräte.
  • Grafikprozessor (GPU = Graphics Processing Unit): Dieser dient dazu, Grafikdaten für die Bildschirmausgabe zu berechnen. Neuerdings nennt man diese Prozessoren öfter VPU = Visual oder Video Processing Unit, da sie eben auch bewegte Bilder auf den Bildschirm bringen.
  • Hauptprozessor (CPU = Central Processing Unit), der Prozessor schlechthin.
  • Mathematischer Koprozessor (FPU = Floating Point Unit), der lediglich dazu dient, Gleitkommazahlen zu verarbeiten.
  • Physikbeschleuniger (PPU = Physics Processing Unit): Ein Prozessor, der physikalische Effekte verarbeitet und berechnet.
  • Soundprozessor (Sound Processing Unit): Einer der ganz wichtigen Prozessoren heutzutage, sorgt er doch dafür, dass Klang korrekt verarbeitet und erzeugt wird.

In der Bauart unterscheidet man Prozessoren auch danach, wie ihre Architektur in Bezug auf die Größe des Befehlssatzes aufgebaut ist. Der Befehlssatz bezeichnet die Menge der Maschinenbefehle, die ein Prozessor beinhaltet, also versteht und umsetzen kann. Folgende Bauarten konkurrieren miteinander:

CISC (Complex Instruction Set Computing = Rechnen mit komplexem Befehlssatz). Diese Architektur versucht, immer mehr und immer komplexere Funktionen direkt in Maschinensprache auszudrücken. Die Anzahl der verfügbaren Maschinenbefehle liegt daher meist deutlich über 100, vielschrittige Operationen können direkt ausgeführt werden. Vorteil: Die erforderlichen Übersetzungsprogramme (Assembler, Compiler, Interpreter) für die Sprachen, in denen programmiert wird, sind relativ klein und ihrerseits einfach zu programmieren.

RISC (Reduced Instruction Set Computing = Rechnen mit reduziertem Befehlssatz). Diese neuere Architektur stellt möglichst wenige, deutlich unter 100 Befehle zur Verfügung, die einfach sind und schnell funktionieren. Vorteil: Befehle werden deutlich schneller ausgeführt, weniger Taktzahlen werden benötigt, auch die Decodierung ist schneller. Das Design von Prozessoren mit RISC-Architektur ist zudem einfacher.

So viel im Schnelldurchgang durch die Welt der Prozessoren. Wenn Sie mehr wissen möchten, fragen Sie nach oder forschen Sie selbst im Internet. Das Gute aber: Als zukünftige(r) Programmierer(in) müssen Sie gar nicht mal so tief in die Funktionsweise eines Computers einsteigen. Technisches Verständnis in der Tiefe brauchten nur die ersten Generationen der Programmierer. Sie sind zum Glück davon befreit und können es sich schenken, Computertechnik zu verstehen. Sie können loslegen.

Gratis-Informationen zum Programmieren lernen jetzt anfordern!

Was hat der Landwirt mit den ersten Computern zu tun?

Computermaschinen verstehen Maschinensprache. Und die ist binär aufgebaut. Sie besteht aus Bits (binary digits = Binärziffer), die jeweils nur 2 Zustände darstellen können, symbolisiert durch die Ziffern 0 und 1. Ein Bit ist vielleicht am einfachsten erklärt, wenn man ihn als Lichtschalter sieht: Ein oder Aus sind hier die Alternativen.

Ältere CPUs und Mikrocontroller verfügen häufig nur über wenige Register und einen eingeschränkten Befehlssatz. Die komplexesten Operationen sind oft Addition und Subtraktion. Zur Steuerung einfacher Maschinen reicht das aus. Denn auch Funktionen wie Multiplikation und Division lassen sich durch Verschieben und Addieren errechnen – man spricht dann im Computerdeutsch von bitweiser Verschiebung. Ein Verfahren, das uns seit der Einführung des Dezimalsystems mit 10 Ziffern merkwürdig vorkommt. Doch das war nicht immer so – und schon sind wir beim Landwirt – genauer gesagt, bei der russischen Bauernmultiplikation.

Russische Bauernmultiplikation

Das ist ein einfaches Verfahren zur Multiplikation natürlicher Zahlen, das ohne das Einmaleins auskommt. Im Prinzip ist es eine schriftliche Multiplikation im Binärsystem. Der Name rührt daher, dass dieses Verfahren bis weit in die Neuzeit unter russischen Bauern üblich war.

Und so geht´s:

  • Beide zu multiplizierende Zahlen nebeneinander schreiben, dazwischen einen senkrechten Strich ziehen.
  • Auf der linken Seite die Werte der Zahlen jeweils halbieren, Reste abrunden, und die Ergebnisse untereinander schreiben, bis die Zahl 1 erreicht ist.
  • Auf der rechten Seite die Werte der Zahlen verdoppeln und untereinander schreiben.
  • Die rechts stehenden Zahlen werden gestrichen, wenn die links daneben stehende Zahl gerade ist.
  • Die Summe der nicht gestrichenen rechts stehenden Zahlen ergibt den gesuchten Wert.

Beispiel:
39 x 67

39 | 67
19| 134
9 | 268
4 | 536
2 | 1072
1 | 2144
______
2613 = 39 x 67

Von Analyse bis Test

Programmierung ist nicht alles!

Diese Seite beschäftigt sich mit den Vor- und Nachwehen jeder Programmierung. Von der Analyse bis zu den Tests ist eine Menge rund um den Kernjob der Programmierung zu erledigen.

Analyse und Planung

Vor jeder Software-Entwicklung muss geklärt sein, worin die Aufgabe besteht: Was soll die Software enthalten, welche Ergebnisse soll sie bringen, welche Interaktionen müssen möglich sein, welche Zugriffe und Sicherheitsstufen sind notwendig usw. Wichtig sind dabei die Präzision, die Vollständigkeit und die Unmissverständlichkeit. Deshalb wird in großen betrieblichen Projekten sogar eine eigene Darstellungssprache benutzt, die UML (Unified Modeling Language = Vereinheitlichte Modellierungssprache). Folgende Dokumente sind für Softwareprojekte üblich, wenn es um die Festlegung der Aufgaben und Arbeitsschritte geht:

Das Lastenheft
Es beschreibt das Projekt aus der Sicht der Anwender, deren Anforderungen in deren Sprache: Was soll die Software leisten, welche Probleme soll sie lösen. Die Art der Realisierung spielt im Lastenheft keine Rolle.

Das Pflichtenheft
Es beschreibt technische Festlegungen, die aufgrund der im Lastenheft genannten Ziele und Vorgaben benötigt werden (Betriebssystem(e), Programmiersprache(n), Auslegung der Server, Organisation der Software bis zum detaillierten Aufbau von Bildschirmdialogen, Datenbanktabellen und benötigten Schnittstellen.

Die Analysediagramme
Sie beschreiben Begriffe und ihre Zusammenhänge aus Entwicklersicht. Das Lastenheft wird praktisch in der analytischen Sprache der Entwickler in Modellen und Diagrammen abgebildet. Das Dokument enthält idealerweise nur dann Freitext, wenn schwer formalisierbare Anforderungen zu formulieren sind. Wenn die Analysedokumente stimmig sind, wissen Entwickler, dass die Vorgaben aus dem Lastenheft im Sinne des Kunden umsetzbar sind.

Diese Dokumente beschreiben präzise die Anforderungen an die Software. Gerade in größeren Projekten kommt es häufig vor, dass Anforderungen vergessen oder erst nachträglich formuliert werden. Für Nicht-Programmierer ist es vollkommen unverständlich, wieso eine kleine Änderung in der Anforderung einen Rattenschwanz an Arbeit und damit Kosten nach sich ziehen kann. Deshalb ist es sinnvoll, eine Abnahmeerklärung unterzeichnen zu lassen, wenn die Arbeit an den Anforderungsdokumenten beendet ist. In der Abnahmeerklärung sollten alle Dokumente in ihrer letzten Version aufgeführt sein. Ist sie unterschrieben, gibt es für den Auftraggeber bei nachträglichen Änderungen keinen Grund, zusätzliche Kosten grundsätzlich in Frage zu stellen.

Die Anforderungsdokumente werden in der Regel ergänzt um

  • eine Aufwandsschätzung
  • ein Vorgehensmodell
  • ein Mock-up

Das Mock-up ist praktisch ein Fake der Software, das dem Auftraggeber in Grundzügen das Design der Nutzeroberfläche zeigt.

Erst aufgrund von Planung und Analyse kann ein Softwareprojekt seriös kalkuliert werden.

Auch bei kleineren Projekten und Arbeiten im Freundeskreis ist es allein schon aus Gründen der Arbeitsökonomie ratsam, vor Beginn der Programmierung alle Ziele und Wünsche zu klären. Erst mal anfangen und dann schauen, wie sich das Projekt entwickelt – das ist reine Zeitverschwendung.

Spezifikation und Entwurf

Die Spezifikation ist der erste Schritt in die Umsetzung des Anforderungsdokuments. In ihr legen die Programmierer dar, mit Hilfe welcher Programmiersprachen und Tools sie die Anforderungen erfüllen wollen. Neben den Funktionen der Software geht es dabei darum, wie Sicherheitsstandards erfüllt werden, wie Backups und Updates ausgeführt werden, für welche Browserversionen programmiert wird, wie Zugriffsrechte eingefügt werden etc. Und natürlich um Hardwarefragen. Wo und wie wird gespeichert, wie werden Anpassungen und Schnittstellen für das Backup-Office realisiert. Anhand einer guten Spezifikation lässt sich ein detaillierter Vergleich zwischen Soll- und Ist-Zustand vornehmen.

Im Entwurf geht es um die Softwarearchitektur. Dabei wird meist eines der drei folgenden Entwurfsprinzipien angewendet:

  • schrittweise Verfeinerung
  • Modularisierung
  • Strukturierung

Das erste Entwurfsprinzip ist für kleinere Projekte das brauchbarste, die beiden anderen zielen auf große bis sehr große Softwareprojekte ab. Im Verfahren der schrittweisen Verfeinerung entwirft man zunächst einen groben und relativ abstrakten Algorithmus. Dann wird Schritt für Schritt verfeinert, die Funktionen werden in zu programmierende Einheiten zerlegt. Dieses Verfahren nennt man auch Top-down-Entwurf – vom Allgemeinen zum Spezifischen.

In der Modularisierung wird in Einzelbausteinen entworfen, die dann zur Gesamtstruktur zusammengefügt werden. Und das Prinzip der Strukturierung schließlich geht von einer hierarchischen Anordnung der Systemkomponenten aus und beschreibt ihre Beziehungen untereinander.

Programmierung

Im engeren Sinn bedeutet Programmierung, den abstrakten Entwurf in Quellcode umzusetzen. Als Hilfsmittel dienen dazu die Werkzeuge, die Programmierer zur Verfügung haben:

  • Integrierte Entwicklungsumgebungen (DIE)
  • Editoren
  • Quellverwaltungssysteme
  • Übersetzer oder Compiler
  • Prüfsoftware
  • Testwerkzeuge

Validierung und Verifikation

Der letzte und entscheidende Schritt. Auf deutsch gesagt heißt das einfach: testen, testen, testen! Validierung oder Plausibilisierung, auf Englisch sehr schön Sanity Check genannt, verlangt die Kontrolle eines konkreten Wertes darauf, ob er zu einem bestimmten Datentyp gehört oder in einem vorgegebenen Wertebereich oder einer vorgegebenen Wertemenge liegt. Die meisten Programmfehler und Sicherheitsprobleme sind letztlich auf fehlende Plausibilisierung von Eingabewerten zurückzuführen.

Für die Validierung gilt die goldene Regel: never trust the user (traue niemals dem Benutzer) – wobei der „Benutzer“ in diesem Fall der Programmierer ist, der die fraglichen Funktionen und Module verwendet. Mit der Validierung von Werten sollte ein Programmierer schon im Entwicklungsprozess beginnen: Einzelne Funktionen und Module sollten regelmäßig Unit-Tests unterzogen werden, die den Quellcode flächendeckend (Code Coverage Analysis) auf korrektes Verhalten überprüfen. Auch bei der Übersetzung des Programmes können einige Arten der Validierung vom Compiler vorgenommen werden. Manche Programmiersprachen haben darüber hinaus ein Laufzeitsystem, das bestimmte Arten von Fehlern selbstständig erkennt, z.B. nicht vorhandene Objekte.

Unter Validierung fällt auch die Prüfung der Eignung beziehungsweise des Werts einer Software bezogen auf ihren Einsatzzweck. Grundlage ist das vorher aufgestellte Anforderungsdokument. Die Eignungsprüfung wird sowohl technisch als auch durch Benutzer ausgeführt. Es wird dadurch die Frage beantwortet: „Ist das richtige Produkt entwickelt worden?“. Der klassische Abnahmetest kann in allen Entwicklungsstufen verschiedene Methoden umfassen:

  • Reviews mit dem Kunden, um Unklarheiten und irrtümliche Annahmen aufzudecken.
  • Prototyping von Benutzeroberflächen als Kommunikationsgrundlage mit dem Anwender
  • Teilergebnisse der Entwicklung vorstellen. Dadurch sollen schnelles Kundenfeedback und zuwachsende Entwicklung erreicht werden.
  • Nutzerakzeptanztests

In der Verifikation wird dagegen überprüft, ob ein System seiner formalen Spezifikation genügt. Die Frage lautet: „Bauen wir das Produkt richtig?“. Es ist durchaus denkbar, dass eine Software ihre Spezifikation erfüllt, jedoch für den Kunden nur geringen Nutzen hat.

Methoden zur Verifikation sind:

  • Codereviews
  • formale Verifikation besonders sensibler Bereiche
  • Verfahren des Softwaretests

Algorithmus

Ein schwieriger, richtig mathematisch klingender Begriff, der etwas Einfaches meint und seinen Namen einer scherzhaften Umformung verdankt. Algorithmus ist eine genau definierte Handlungsvorschrift zur Lösung eines Problems oder einer bestimmten Art von Problemen in endlich vielen Schritten. Jedes Kochrezept ist also ein Algorithmus. Und jede Bauanleitung für ein zerlegt geliefertes Möbelstück (wenn sie denn funktioniert!).

Das Wort Algorithmus ist eine Verballhornung des Namens von Muhammed al-Chwarizmi, dessen arabisches Lehrbuch von 825 „Über das Rechnen mit indischen Ziffern“ in der lateinischen Übersetzung so begann: „Dixit Algorismi“ (Algorismi hat gesagt). Im Mittelalter wurde daraus lateinisch „algorismus“ oder „alchorismus“ oder „algoarismus“ für die Kunst des Rechnens mit arabischen Ziffern. Da man später die Wurzeln im Griechischen vermutete, wurde in der lateinischen Wissenschaftssprache aus dem „rismus“ ein „rithmus“.

Der Algorithmus spielt in der Informatik eine zentrale Rolle. Doch welche, darüber streiten die Gelehrten. Mal wird er definiert als das abstrakte Gegenstück zum konkret auf die Maschine zugeschnittenen Programm, mal als Maschinenprogramm für die ideale mathematische Maschine. Als gebrauchsfertige, notwendige und hinreichende Definition für Programmierer bleibt: Algorithmus ist eine genau definierte Handlungsvorschrift zur Lösung eines Problems oder einer bestimmten Art von Problemen in endlich vielen Schritten.

Grundlagen Programmierung

Programmieren – eine Leidenschaft, die sich schnell entwickelt!

Sieht man mal von den ersten revolutionären und streng mathematischen Bemühungen ab, Maschinen zu programmieren, fängt die Geschichte der Programmierung eigentlich erst nach dem Zweiten Weltkrieg an. Seitdem hat sich das Programmieren genau wie die Welt der Computer und elektronischen Steuerungen mit Riesenschritten entwickelt. Doch wie kam es dazu – war erst die Henne da oder erst das Ei?

Schon im Zeitalter der Manufakturen, im 18. und beginnenden 19. Jahrhundert waren Mathematiker und Ingenieure von dem Wusch besessen, Maschinen zu konstruieren, die nach einem Programmablauf verschiedene Aufgaben nacheinander erfüllen konnten. Auch mechanische Maschinen arbeiten ja nach Programm, nach einer kausalen Kette. Diese lässt sich jedoch nur ändern, wenn die Maschine umgebaut wird. Erst mit der Entwicklung von Steuerungen waren Maschinen möglich, die ohne Umbau im Rahmen ihrer Fähigkeiten unterschiedliche Aufgaben erfüllen konnten. In der ersten Hälfte der noch jungen Computergeschichte war das Erfinden neuer Programme und Programmstrukturen von der Entwicklung der Hardware getrieben. Mit dieser Entwicklung und dem Vordringen elektronischer Steuerungen und Datenverarbeitung in immer komplexere Anforderungen war auch Schluss mit dem einfachen Programmieren.

Vorbereitet von den Pionieren und hellsten Köpfen der Informatik, dankbar aufgenommen und schnell weiter entwickelt von den Computer-Begeisterten der Commodore- und Atari-Generation, nahm das Programmieren in der Dritten Generation der Programmiersprachen im Galopp eine Hürde nach der anderen und baute neue auf. Die Zahl der Programmiersprachen wuchs, neue Programmierparadigmen kamen ins Spiel, das Internet nahm die Bedeutung an, die ihm viele nicht zugetraut hätten und … schließlich teilten sich die Programmierer in ganz unterschiedliche Völker:

  • Die Informatiker und Intellektuellen
    Für sie war lange Zeit der Griff in die Tasten eine Aufgabe fürs niedere Volk der Programmierer, ein Rückschritt in die Steinzeit. Sie beschäftigen sich mit Sprachentwicklung, Analyse, Planung etc.
  • Die Maschinenprogrammierer
    Sie programmieren nach wie vor auch an der Wurzel, entwickeln maschinennahe Steuerungen, Übersetzungsprogramme, Entwicklungsumgebungen etc.
  • Die Anwendungsprogrammierer
    Sie arbeiten anwendernah, programmieren die Softwaretools, die den normalen Nutzer zum Ergebnis bringen. In ihrer Programmierung sind sie selber Anwender der vorbereiteten Codes in den Entwicklungsumgebungen.
  • Die Multimedia-Programmierer
    Die Visualisten unter den Programmierern. Für sie zählt der Effekt. Sie programmieren Software-Anwendungen im grafischen und auditiven Bereich, Filme und Animationen. Sie entwickeln virtuelle Charaktere, dialogartige, intelligente Interaktivität, Besuchererkennung und schreiben Autorensysteme. Daneben vereinfachen sie die Mensch-Maschine-Kommunikation, z. B. über Personen- und Spracherkennung. Sie spezialisieren sich auf Medizin- oder Medientechnik, für die Automobilindustrie oder Unterhaltungsbranche.

Die Welt der Programmierer ist vielfältiger und komplizierter geworden. Denn innerhalb der Völker gibt es soziale Gruppen, die einander fast schon ausschließen. Sie definieren sich über Vorliebe zu oder Ablehnung von bestimmten Programmiersprachen.

Die meisten Programmierer arbeiten heute als Anwendungsprogrammierer für PC Systeme auf der Basis von Windows.

Was zeichnet gute Programmierung aus?

Gut programmiert ist eine Software, wenn die Funktionen, die eine Entwicklungsumgebung zur Verfügung stellt, möglichst effizient genutzt werden. Bibliotheken und der Quellcode sollten übersichtlich und einfach zu warten sein. Das heißt, ein guter Programmierer schafft selbsterklärende Strukturen und fügt, wenn notwendig, Kommentare hinzu. Es gilt, redundante (sich wiederholende) Anweisungen und Daten zu vermeiden. Schlecht ist es, wenn Programmierer ein Gestrüpp an Strukturen und Modulen schaffen, an dem bei jedem Versionswechsel nacharbeitende Programmierer scheitern müssen.

Es ist heute nicht Aufgabe, die letzte Nanosekunde herauszukitzeln und kryptischen, aber schnellen Code zu schreiben. Gute Programmierer schreiben sauberen, leicht lesbaren und wartbaren Code. Sie erkennen die echten Anforderungen an das Programm: Das es das tut, was verlangt wird, in der zur Verfügung stehenden Zeit und zu dem gewünschten Preis.

Ada Lovelace

Die Mutter der Programmierer. Sie übersetzte 1843 die durch den italienischen Mathematiker Luigi Menebrea notierte Beschreibung der „Analytical Engine“ von Charles Babbage ins Englische. Ihre eigentliche Leistung dabei war, dass sie nicht nur übersetzte, sondern eigene Überlegungen zum Bau der geplanten mechanischen Rechenmaschine hinzufügte. Sie legte dem britischen Parlament einen genauen Plan vor, wie mit der Maschine Bernulli-Zahlen zu berechnen seien. Das brachte ihr den Ruhm ein, das erste Computerprogramm geschrieben zu haben. Die Rechenmaschine allerdings wurde nie gebaut, denn die Parlamentarier verstanden wohl die Dimension nicht – sie verweigerten die Gelder zur Entwicklung.

Ada King Byron, Countess of Lovelace – so ihr korrekter Name – wurde 1815 als Tochter des berühmten Dichters Lord Byron geboren. Sie lernte ihn nie kennen, da sich ihre Mutter, eine mathematisch und naturwissenschaftlich interessierte Frau, kurz nach der Geburt von Lord Byron trennte. Ada Lovelace heiratete mit 19 Jahren Baron King. Er war ihr bei der Beschaffung von Artikeln und Fachbüchern nützlich, denn Frauen war damals noch der Zutritt zu Bibliotheken und wissenschaftlichen Einrichtungen verwehrt. Ada bekam drei Kinder und beschwerte sich immer wieder, dass ihr durch die Kinderbetreuung zu wenig Zeit für die Mathematik und die Musik bliebe. Um sich für das durchaus langweilige häusliche Leben zu entschädigen, stürzte sich Ada in Gesellschaftsleben und hatte zahlreiche Affären. Die letzten Jahre ihres Lebens verbrachte sie aufgrund einer Krebserkrankung im Bett und starb im Alter von nur 36 Jahren.

Nach Ada Lovelace ist die Programmiersprache „Ada“ benannt.

Was, um Himmels willen, ist ein Paradigma?

Etwas sehr Einfaches. Ein Muster, ein Modell. Beim Programmieren ist es das Prinzip, nach dem eine Programmiersprache oder Programmiertechnik aufgebaut ist. Die Programmierparadigmen sorgen in jeder Programmiersprache mehr oder weniger dafür, dass die Basiskriterien Lesbarkeit des Codes, Redundanzfreiheit, Modularität und Nebenwirkungsfreiheit eingehalten werden. Sie schaffen dies dadurch, dass sie die Einhaltung der Regeln vereinfachen, nahe legen, fast erzwingen oder im besten Fall automatisch realisieren. In zwei Hauptrichtungen lassen sich die Paradigmen der Programmierung klassifizieren: Imperative Paradigmen und deklarative Paradigmen.

Imperative Programmierparadigmen

In allen imperativen Programmiersprachen versteht man ein Programm als lineare Folge von Befehlen, die der Rechner in der definierten Reihenfolge abarbeitet. Durch den Mikrocode wird auf der Prozessorebene angegeben, wie der Rechner mit welchen Daten verfahren soll. Dazu dienen die Befehle. Sie manipulieren den Zustand der Speicherbereiche, die Daten zur Verarbeitung oder Ausgabe vorhalten. Diese Daten sind meist in Variablen gespeichert, so dass sie sich im Programmablauf verändern können. Durch die Reihenfolge der Befehle ist die zeitliche Abfolge im Programm vorgegeben. Um reagierende Programme zu realisieren, gibt es Sprungbefehle, die jene einmal festgelegte Abfolge der Befehle dynamisch verändern.

Nach imperativem Paradigma wird ein Lösungsweg vorgegeben: Welche einzelnen Schritte müssen nacheinander ablaufen, wie sind Variablen zu verändern, damit am Ende das gewünschte Ergebnis herauskommt. Im Vordergrund steht also die Frage „Wie?“

Den imperativen Programmierparadigmen folgen wiederum unterschiedliche Programmsprachenformen:

  • Strukturierte Programmierung
    Ein Programmierparadigma, das sich etliche Programmiersprachen zu eigen gemacht haben. Strukturierte Programmierung verlangt, sich auf der untersten Ebene auf lediglich drei Kontrollstrukturen zu beschränken:

    • Sequenz = hintereinander auszuführende Programmanweisungen
    • Auswahl = Verzweigung
    • Wiederholung = Schleifen

    Strukturierte Programmierung beinhaltet den ersten Ansatz einer prozeduralen Programmierung, indem es eine baumartige Zerlegung in Teilprogramme oder Prozeduren verlangt. Als wesentliche Verbesserung gegenüber früheren imperativen Paradigmen gilt die Konsequenz, dass Sprunganweisungen vermieden oder eingeschränkt und standardisiert werden. Die muntere Fehlerquelle des „GOTO“ wird dadurch weitgehend umgangen.

    Der strukturierten Programmierung folgen diese Sprachen:
    – Ada
    – Algol
    – C
    – Pascal
    – Fortran (ab 77)
    Generative Programmierung, aspektorientierte und objektorientierte Programmierung bauen auf der strukturierten auf.

  • Prozedurale Programmierung
    Dahinter steckt das Prinzip, Programme in kleinere Teilaufgaben zu zerlegen und diese als eigenständige Prozeduren einzusetzen. Die prozedurale Programmierung zielt darauf ab, Quelltexte wieder verwendbar zu machen. Der Vorteil: universell einsetzbare Prozeduren müssen nur einmal programmiert werden, man kann sie komplett in weitere Programme einsetzen. Darüber hinaus bringt die Zerlegung, dass die so verkleinerten Probleme auch einfacher zu lösen sind.
    Typische Sprachen:
    – Fortran
    – COBOL
    – ALGOL
    – C
    – Pascal
  • Modulare Programmierung
    Der erste Versuch, der wachsenden Größe von Softwareprojekten Herr zu werden. In der modularen Programmierung wird der prozedurale Ansatz erweitert, indem Prozeduren zusammen mit Daten in logische Einheiten gefasst werden. Die Software wird also in größere funktionale Einheiten zerlegt, die für sich geplant, programmiert und getestet werden können. Derartige Unterprogramme nennen sich dann Module. Sie müssen schließlich nur noch logisch miteinander verknüpft werden, und schon ist die Software einsatzbereit. Typische Sprachen:
    – Ada
    – Component Pascal
    – Modula-2
    – Oberon
  • Objektorientierte Programmierung
    Grundidee dieses Programmierparadigmas ist, Daten und Funktionen möglichst eng in einem Objekt zusammen zu fassen und nach außen hin zu kapseln. Implementierungsdetails werden bewusst verborgen, so dass Methoden fremder Objekte diese Daten nicht versehentlich manipulieren können. Der Zugriff auf die interne Datenstruktur eines Objekts erfolgt über definierte Schnittstellen.Objektorientierte Programmierung ist heute das am weitesten verbreitete Prinzip. Die Objektorientierung wird in den einzelnen Programmiersprachen jedoch sehr unterschiedlich streng befolgt. Typische Sprachen:
    – Smalltalk
    – Ada 95
    – Java
    – C++
    – C#
    – Python
    – Perl
    – PHP
    – Ruby

Deklarative Programmierparadigmen

Deklarative Programmierung ist eine Idee der jüngeren Programmiergeschichte. Im Gegensatz zu den imperativen Programmierparadigmen fragt man in der deklarativen Programmierung nicht nach dem „Wie“, sondern nach dem „Was“, das berechnet werden soll. Nicht der Lösungsweg wird programmiert, sondern man gibt an, welches Ergebnis erzielt werden soll. Deshalb beruhen deklarative Paradigmen auf rechnerunabhängigen mathematischen Theorien.

Die Vorteile der deklarativen Programmierung:

  • Es gibt keine Nebeneffekte. Denn deklarative Programmierung ist referenziell transparent. Das heißt, der Wert eines Ausdrucks hängt nur von seiner Umgebung und nicht vom Zeitpunkt seiner Auswertung ab. In der Mathematik gilt, dass ein und dieselbe Variable an verschiedenen Stellen ihres Geltungsbereichs immer den gleichen Wert hat. Das gilt auch in der deklarativen Programmierung. Deshalb sind Programme auch in Teilen auswertbar und ermöglichen es, unendliche Datenstrukturen zu bearbeiten.
  • Beweise zur Korrektheit von Ergebnissen oder Programmeigenschaften sind uneingeschränkt durchführbar. Denn deklarative Programmierung arbeitet auf mathematischer Basis (Lambda-Kalkül)
  • Deklarative Programmierung zeigt keine Abhängigkeit von irgendeiner Rechnerarchitektur

Deklarative Programmiersprachen sind trotz dieser Vorteile nicht weit verbreitet. Ihre Akzeptanz leidet unter dem Vorbehalt „Akademikersprache“. Typische Sprachen:
– funktionale Sprachen wie LISP, ML, Miranda, Gofer, Haskell
– logische Sprachen wie Prolog
– funktional-logische Sprachen wie Babel, Escher, Curry, Oz
– mengen-orientierte Abfragesprachen wie SQL

First Class Citizens – FCC

Hier handelt es sich nicht um die oberen Zehntausend einer Großstadt. Im Kontext jeder einzelnen Programmiersprache ist der First Class Citizen die Einheit, die im Vergleich zu anderen Einheiten ohne Beschränkung direkt genutzt werden kann. Abhängig von der Programmiersprache müssen FCCs bestimmte Bedingungen erfüllen, zum Beispiel speicherbar in Variablen oder speicherbar außerhalb laufender Prozesse oder aufbauend in Laufzeit etc. So sind etwa in Java Objekte FCCs, in LISP ist jedes Stück Programm FCC, in Perl sind es Zeichenketten, Arrays und Hashes.

Softwareprinzipien

Von der Entwicklung bis zur Pflege – der Lebenszyklus einer Software

Beziehen sich die Paradigmen des Programmierens auf die grundsätzliche Technik des Programmierens und die Auswahl der Sprachen, so beschäftigt sich dieser Abschnitt mit den Prinzipien, die in jedem Projekt als Leitlinien dienen sollten. Denn die Anforderungen an die Programmierung von Software sind in den letzten Jahren eindeutig gestiegen. Vorbei sind die Zeiten, in denen ein Programmierer lustig drauf los programmierte und alle zufrieden waren, wenn am Stichtag X ein halbwegs fehlerfreies Produkt zum Laufen gebracht wurde.

Heute kommt es darauf an, dass Produkte geschaffen werden, die

  • ausbaubar und erweiterbar sind
  • änderbar sind
  • durch andere Programmierer zu bearbeiten sind
  • eine relativ lange Lebensdauer haben

Softwareprinzipien werden für den gesamten Lebenszyklus einer Software postuliert, von der Entwicklung bis zur Pflege.

Prinzipien der Softwareentwicklung

1. Das Abstraktionsprinzip
In der Programmierung einer Software sollte nicht allein die konkret eng gefasste Aufgabe leitend sein, sondern die Abstraktion dieser Aufgabe. Wenn verlangt wird, die Arbeitsstunden der Lagerarbeiter zu erfassen und den resultierenden Lohn daraus zu berechnen, so sollte die Programmierung auf eine Modelllösung ausgerichtet sein: Erfassung von Arbeitsstunden und Lohnberechnung aller Lohnarbeiter.

2. Das Hierarchisierungsprinzip
Jede Struktur eines komplexen Systems soll in ihrer gegenseitigen Abhängigkeit in jedem Programm in Form eines hierarchischen Aufbaus ablesbar sein.

3. Das Strukturierungsprinzip
Eine Gesamtaufgabe muss in nachvollziehbare Teilaufgaben gegliedert werden, ein Gesamtsystem in einzelne Strukturelemente.

4. Das Modularisierungsprinzip
In der Programmierung sollen funktionale und in sich geschlossene Subsysteme gebildet werden. Die Subsysteme müssen austauschbar sein. Schnittstellen zwischen den Subsystemen werden definiert.

5. Das Lokalitätsprinzip
Es wird erwartet, dass logisch zusammenhängende Informationen (Daten und Funktionen) am gleichen Ort komprimiert abgelegt werden.

6. Das Dokumentationsprinzip
Jeder Softwareabschnitt soll als Vorspann eine Dokumentation dessen erhalten, was der Programmteil ausführt und verlangt.

7. Das Standardisierungsprinzip
Zum Verständnis der Software trägt bei, dass bestimmte Lösungsreihenfolgen eingehalten werden: Modulname, Dokumentation, Variableninitialisierung, Kontrollstrukturen, Rückgabewert.

8. Das Mehrfachverwendungsprinzip
Einfügen einer allgemeinen Sortierroutine. Softwareteile sollen so ausgearbeitet und bereitgestellt werden, dass sie von anderen Entwicklern wieder verwendet werden können.

Prinzipien der Qualitätssicherung

1. Das operationale Qualitätseigenschaftsprinzip
Klingt kompliziert, ist aber einfach. Damit meint man, dass in einem Projekt von vornherein Qualitätsmerkmale einer Softwarefunktion festgelegt werden, die dann auch nachprüfbar sind. Im Beispiel der Stundenerfassung Lagerarbeiter sind das maximale Anzahl der Stunden und Wertebereiche der Löhne.

2. Das konstruktive Qualitätssicherungsprinzip
Vorausblickend sollen Maßnahmen ergriffen werden, um Fehlerquellen zu unterdrücken. Zum Beispiel sind Vektoren so zu dimensionieren, dass keine „core bus errors“ auftreten.

3. Das Fehlerfrüherkennungsprinzip
Als Fehler sind hier Abweichungen von den Benutzeranforderungen gemeint. Um diese zu erkennen, sollten Benutzeranforderungen vorab detailliert gegliedert werden.

4. Das akkompagnitive Qualitätssicherungsprinzip
Auch hier geht es einfach: Jeder Programmierer sollte Tests mit Testdaten und Ausgabe in den Entwicklungsprozess einzelner Module einbauen. Geschieht das nicht, wird die Fehlersuche in der fertig programmierten Software wesentlich aufwändiger.

Prinzipien des Softwaremanagements

1. Das organisatorische Modellierungsprinzip
Wichtig bei größeren Projekten: Vor Beginn der Arbeiten sollte ein organisatorischer Rahmen gebildet werden, in dem die Entwicklung durchgeführt wird. Dazu gehört die Einteilung in Entwicklerteams oder ein Phasenmodell für die Entwicklung.

2. Das Meilensteinprinzip
In der Programmierung von Software spielen Termine häufig eine der wichtigsten Rollen. Um Termintreue zu gewährleisten, ist es gut, für einzelne Programmierungsschritte Endzeitpunkte festzulegen. Das sind dann die Meilensteine.

3. Das Kommunikationsprinzip
Jede komplexere Programmierung erfordert Kommunikation unter den Beteiligten. Von vornherein soll festgelegt werden, wie und mit wem kommuniziert wird, wie Entwickler untereinander Informationen austauschen. Ein Ziel ist, den erforderlichen Kommunikationsaufwand zu reduzieren. Zum Beispiel, indem gleich die aufgabengerechte Zahl der Entwickler eingeplant wird, um nicht nachher neuen Mitarbeitern die gesamte Planung und Ausführung neu erklären zu müssen.

Wartung und Pflege

Werden diese Prinzipien eingehalten, dann lässt sich in der Wartung und Pflege der Software viel Zeit sparen. Einige gehen davon aus, dass in Softwareprojekten etwa 60% der Fehler im Entwurf liegen und 40% in der Programmierung. Schlimmer ist aber, dass etwa 50% der Fehler erst im Betriebseinsatz gefunden werden. Sind nur wenige der Softwareprinzipien eingehalten worden, dann kann man sich vorstellen, dass die Pflege bei laufendem Betrieb zum Horror und zur gigantischen Kostenfalle wird.

Integrierte Entwicklungsumgebung

Eine der besten Ideen: die IDE

Bis in die erste Hälfte der Achtziger Jahre des vergangenen Jahrhunderts war es üblich, für die einzelnen Programmiersprachen Editor, Compiler, Linker und Debugger als vier selbstständige Produkte anzubieten, die vom Benutzer über die Kommandozeile ausgeführt wurden.

Dann wurde die Idee umgesetzt, die aus Programmierern endgültig auch Benutzer (user) machte: die Integrierte Entwicklungsumgebung (IDE = integrated design Environment). IDEs sollten den Software-Entwicklern endlich hilfreiche Werkzeuge unter einer Benutzeroberfläche an die Hand geben, die ihnen häufig wiederkehrende Aufgaben abnahmen und den Zugriff auf wichtige Funktionen übersichtlicher und schneller machten.

Die erste DIE weltweit war Maestro I von Softlab. Sie wurde insgesamt 22.000 mal installiert, davon allein 6.000 mal in der Bundesrepublik Deutschland. Wesentlich erfolgreicher unter den ersten IDEs war das heute noch bekannte Turbo Pascal. In der Regel verfügen Integrierte Entwicklungsumgebungen über folgende Komponenten:

  • Texteditor
  • Compiler oder Interpreter
  • Linker
  • Debugger
  • Quelltextformatierer

Viele haben darüber hinaus Komponenten wie Versionsverwaltung, Projektmanagement, UML-Modellierung oder GUI=Graphical User Interface, mit dem grafische Benutzeroberflächen einfach erstellt werden können.

IDEs gibt es für nahezu alle Programmiersprachen und Plattformen, teilweise auch für mehrere Programmiersprachen unter einer Benutzeroberfläche. Sie sind entweder frei oder proprietär. Letzteres meint, dass eine IDE im Eigentum einer bestimmten Firma ist. Ihr Quelltext kann, auch wenn er öffentlich zugänglich ist, nicht verändert werden, die Lizenzbedingungen sind strikt.

Freie IDEs wiederum teilen sich in Freeware und in Software, die unter einer allgemeinen Lizenz wie der GPL=General Public License stehen. Diese beinhaltet im Wesentlichen:

  • Das Programm darf ohne Einschränkung für jeden Zweck genutzt werden (auch kommerziell).
  • Kopien des Programms dürfen kostenlos oder gegen Geld verteilt werden, wobei der Quellcode mitgeliefert werden muss. Lizenzgebühren sind dagegen nicht erlaubt.
  • Die Arbeitsweise des Programms darf den eigenen Bedürfnissen angepasst werden.
  • Veränderte Programme dürfen auch nur kostenlos oder gegen Geld, jedoch nicht gegen Lizenzgebühren verteilt werden.

Diese Art der Lizenz nannten die Erfinder des Systems auch im Gegensatz zum Copyright das „Copyleft“. Das Betriebssystem Linux ist eines der bekanntesten „Open Source“-Projekte unter freier Lizenz, an dem weltweit Tausende Entwickler freiwillig und kostenlos arbeiten.

Editor

Der Editor ist das Programm, in dem Programmierer ihre Daten erstellen. Die Daten werden in flüchtigen Speichern so lange vorrätig gehalten, bis der Bearbeiter ausdrücklich die Speicherung veranlasst. Bei den meisten Editoren wird durch eine „Undo“-Funktion ermöglicht, Eingaben ohne Schäden und Einschränkungen zurückzunehmen. Besonders gute Editoren schaffen es dabei auch, mit den zu löschenden Eingaben verbundene Daten zu löschen. Geschieht dies nämlich nicht, können vollkommen unsinnige Informationen und Anweisungen übrig bleiben.

Editoren gibt es nicht nur für Textdateien, sondern auch für Web-Text, HTML, XML und Script. Auch Audioeditoren, Leveleditoren für Spieleprogrammierung, Hex-Editoren für Binärdateien, Pixeleditoren für Rastergrafik und Grafikeditoren für z.B. Computer Aided Design (CAD) werden gebraucht.

Compiler

Compiler (engl. von to compile = zusammenführen) ist angesichts der aktuellen Fähigkeiten solcher Programme eine glatte Fehlbezeichnung. Ursprünglich waren Compiler die Programme, die Unterprogramme zusammenfügten. Heute sind es Übersetzer, die ein im Quelltext geschriebenes Programm in eine Zielsprache übersetzen, in Assemblersprache, Bytecode oder Maschinensprache.

Dabei gehen Compiler so vor: Zunächst werden im Frontend oder der Analysephase lexikalische Analyse, syntaktische Analyse und semantische Analyse vorgenommen. Dann wird im Backend der Zwischencode oder der Programmcode erzeugt. Es gibt ganz unterschiedliche Arten von Compilern.

Verwandt mit dem Compiler ist der Interpreter. Er übersetzt nicht, sondern lässt die Vorgaben des Quelltextes Schritt für Schritt direkt ausführen. Er ist also so eine Art Simultanübersetzer mit Handlungsvollmacht.

Linker

Linker ist in der Programmierung keine weltanschauliche oder politische Bezeichnung. Linker ist ein höchst nützliches Programm, das einzelne Programmmodule zu einem ausführbaren Programm zusammenstellt und verbindet.

Linker sorgen auch dafür, dass Programmmodule in anderen Programmen genutzt werden können. Dazu werden die symbolischen Adressen der Funktionen und Variablen in Speicheradressen umgewandelt. Der Linkvorgang erfolgt nach der Kompilierung und ist der letzte Schritt in der Programmierung. Man unterscheidet zwischen zwei Methoden:
Statisch gelinkt wird meist in der Fertigung eines Programms. Aufgrund des Statischen Linkens erhält der Nutzer ein fertiges, sofort ausführbares Programm. Im Gegensatz dazu erfolgt im Dynamischen Linken das Auflösen der Funktions- und Variablen-Namen erst während das Programm ausgeführt wird. Der Vorteil ist, dass Bibliotheken nachträglich leicht ausgetauscht werden können und die Programme kleiner werden. Denn Programmmodule können sich aus ein- und derselben Bibliothek bedienen, der „dynamically linked library“(DLL) oder „shared library“. Da mehrere Programme die gleiche Bibliothek nutzen, wird weniger Speicherplatz benötigt.

Debugger

Ein Debugger ist die Prüfanstalt des Programmierers. Seine Werkzeuge dienen dazu, Programmfehler zu diagnostizieren, aufzufinden und zu beheben. Dafür steuert der Debugger zunächst den Programmablauf durch Haltepunkte und Einzelschrittverarbeitung von Befehlen. Währenddessen inspiziert er Daten in den Registern, im Programmcode und in den Speichern. Er modifiziert Speicher, Register des Prozessorkerns und die Ein-/Ausgabezustände.

In unterschiedlicher Weise sind Debugger in der Lage, Rückmeldungen zu Fehlern und Fehlerquellen zu geben und Fehler selbstständig zu beheben. Wichtig ist oft die finale Version des Debugging. Bei der Ausnahmeunterbrechung von Programmen, die durch einen Fehler erzwungen wurde, kommt der Post-Mortem-Debugger zum Einsatz.

Quelltextformatierer

Eine nützliche kleine Funktion, die in den meisten Integrierten Entwicklungsumgebungen enthalten ist. Sie erledigt die Putz- oder Kosmetikarbeit, wird daher im Englischen teilweise auch „beautyfyer“ genannt. Quelltextformatierer können in bestimmten Grenzen nachlässig geschriebenen Quelltext selbstständig umformatieren. Sie korrigieren Fehler im Programmierstil (code convention), vereinheitlichen das Quelltextlayout, erhöhen die Lesbarkeit und sorgen dafür, dass der Quellcode leichter zu warten ist.

Natürlich gehen sie dabei formal vor. Ein Formatierer ist nicht in der Lage, die Bedeutung eines Quelltextes zu erfassen. Es gibt Textsequenzen, die ein Programmierer bewusst abweichend von der code convention schreibt, um das Verständnis für den Code zu erhöhen. Das wiederum kann ein Formatierer nicht verstehen.

 

Programmierung

Programmieren leicht gemacht. Der Bedarf an Programmen und Programm-Verbesserungen steigt, Programmierer sind gesucht.

Anbieter:

 

 

Nach oben scrollen