PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wahl der "richtigen" Programmiersprache



blackberry
20.09.2011, 16:42
http://img6.imagebanana.com/img/ei5bwukb/programmieren_gross.jpeg
(entstanden in Zusammenarbeit mit Sawyer (http://free-hack.com/member.php?u=44795))


Worum geht es hier?

Da immer wieder die Frage aufkommt, welche Programmiersprache man lernen sollte sei hier jetzt mal eine kleine Übersicht zu einzelnen Programmiersprachen zusammengestellt.
Dass man diese Frage nicht einfach so pauschal beantworten kann sollte bereits darin genug begründet sein, dass sich bis heute mehrere hundert Programmiersprachen in allen möglichen Variationen entwickelt haben und nach wie vor durchaus einige davon täglich von vielen Programmieren genutzt werden.
Dieser Artikel richtet sich hierbei eher an Programmierneulinge, die noch keinerlei Erfahrung mit Programmierung gesammelt haben und Angst haben sich bei den ersten Schritten schon im Dschungel der verschiedenen Programmiersprachen zu verlaufen.
Wer hier seine Lieblingssprache nicht findet und Lust hat sie vorzustellen, der kann sich gerne melden. Auch wenn jemand das Gefühl hat, dass die eigene Lieblingssprache hier falsch oder missverständlich dargestellt wurde, der möge sich bitte melden. Bei einer doch meiner Auffassung nach relativ großen Zusammenfassung dieser Art mag es durchaus vorkommen, dass man sich stellenweise irrt, oder Aspekte vergisst. Wer ernste Kritik und Verbesserungsvorschläge äußern möchte ist herzlich dazu eingeladen.

Im Allgemeinen möchte ich allerdings hoffen, dass es mir gelungen ist alles objektiv und fair darzustellen und sich nicht zu viele Fehler eingeschlichen haben. Viel Spaß beim Lesen!

Was sind typische Vergleichsmerkmale von Programmiersprachen?

Hierbei geht es darum dem Leser einen Überblick zu verschaffen, was eine Programmiersprache charakterisiert.

Zum einen und vielleicht am offensichtlichsten wäre da die Syntax, also die Ansammlung an Regeln, die das Bilden von Ausdrücken in dieser Sprache formalisieren. Das heißt die Syntax einer Sprache setzt den Rahmen für die Kommunikation Mensch<->Maschine, die wir durch das Programmieren zu erreichen suchen. Da die Syntax aber eigentlich nur die Form der Kommunikation formalisiert und an sich nicht viel darüber aussagt, wie leistungsfähig die zugrundeliegende Sprache ist wenden wir uns auch sogleich anderen Themen zu.

Eine Programmiersprache kann ein imperatives, oder deklaratives Paradigma verfolgen (wobei das eine nicht zwangsweise das andere ausschließt). Bei imperativer Programmierung gibt man explizite Anweisungen, wie etwas gemacht werden soll (z.B. "Lege deine Hand auf die Klinke; Drücke die Klinke runter; Drücke die Tür an der Klinke von dir weg; ..."). Bei der deklarativen Programmierung beschreibt man was gemacht werden soll. Dabei stellt man das Problem (z.B. "Eine Tür soll geöffnet werden") und stellt Anforderungen an die Lösung, zeichnet also aus was eine Tätigkeit erfüllen muss, um als Lösung zu diesem Problem zu gelten (z.B. "Tür nicht eingetreten; Durchgang möglich; ..."). Dabei werden wir uns hier auf imperative Programmiersprachen konzentrieren, da diese in der Praxis eher etabliert sind (deklarative Programmierung ist eher von akademischem Interesse aus Sicht der theoretischen Informatik und Mathematik; weil die Wahl des Weges zur Lösungsfindung komplett dem Computer überlassen wird laufen solche Programme je nach Aufgabenstellung oft auch wesentlich länger als ihr Analogon in imperativer Form).

Imperative Programmiersprachen sind fast immer auch prozedual. D.h. sie erlauben das Untergliedern des Programms in kleinere Teilprogramme, also das Zusammenfassen von mehreren Anweisungen zu voneinander abgegrenzten Einheiten (z.B. wenn wir einzelne Muskeln in unserem Körper durch eine Programmiersprache steuern könnten und wir eine Tür öffnen wollten; möglichte Teilprogramme des Programms "Tür öffnen" wären dann etwa "Hand auf Klinke legen", "Klinke drücken", etc.).

Ein erweiterter Ansatz zur prozedualen Programmierung ist objektorientiertes Programmieren. Objektorientierte Sprachen erlauben die Gruppierung von Daten und Operationen auf diesen Daten zu einer nach außen hin scheinbaren Einheit. Dies erleichtert insbesondere das Arbeiten mit sehr komplexen Systemen, sowie das Arbeiten in Teams, da logisch zusammenhängende Teile eines solchen Systems wie ein zusammenhängendes ganzes betrachtet werden können und dabei auch verschiedene Teams unabhängig voneinander an unterschiedlichen logischen Einheiten eines komplexen Systems arbeiten können. Sagen wir mal wir wollten einen Simulation für Straßen schreiben. Ein Auto kann dabei von unserer künstlichen Intelligenz gefahren werden. Von außen her interessiert uns das Zusammenspiel der Mechanik und Elektronik in einem Auto recht wenig. Die KI muss nur das Auto starten, anfahren, fahren, lenken, anhalten, usw. Dass dabei Kraftstoff in den Motor eingespritzt werden muss ist für die KI nicht von Bedeutung. Man würde also die Technik im Auto vom Auto steuern lassen und das Auto von der KI. So bildet man sogenannte Klassen, also Gruppierungen von Daten (Tankfüllung, Stärke des Motors, momentane Geschwindigkeit, Position des Autos in unserer "Welt", usw.) und Operationen auf diesen Daten (Fahren, Beschleunigen, Lenken, ...). Instanzen einer Klasse heißen Objekte. Ein Objekt speichert tatsächlich Daten, die von der Klasse festgelegt wurden und arbeitet mit den Operationen der Klasse (Klassen sind also sozusagen Baupläne für Objekte).
Ohne jetzt hier Objektorientierung mit allen Feinheiten erklärt haben zu meinen, hoffe ich doch eine Vorstellung vermittelt zu haben, wieso vorhandene Objektorientierung in einer Programmiersprache nützlich sein kann.

Ein weiteres Augenmerk bei der Wahl einer Programmiersprache ist Plattformunabhängigkeit, oder im weiteren Sinne auch prinzipielle Verfügbarkeit der entsprechenden Programmiersprache auf einer speziellen Plattform. Hierbei sollte man sich fragen, ob sich Systemnähe und plattformübergreifende Verfügbarkeit in angemessener Weise aufwiegen. Wer beispielsweise Treiber für ein spezielles Betriebssystem programmieren will, der muss sich darüber im Klaren sein, dass diese Treiber auf anderen Betriebssystemen vielleicht nicht ohne Weiteres laufen werden, wobei eine Programmiersprache, die Plattformübergreifendes Programmieren im größeren Stil ermöglicht ("im größeren Stil" soll nicht einfach heißen, dass die Sprache auf verschiedenen Systemen prinzipiell verfügbar ist, sondern dass Programme, die in dieser Sprache geschrieben wurden, ohne, oder nur mit sehr kleinen Änderungen auf einem anderen System lauffähig sind), womöglich nicht die dafür benötigte Systemanbindung zur Verfügung stellen kann.
Man unterscheiden darum oft zwischen Highlevel- und Lowlevelsprachen, wobei die Lowlevelsprachen nah an der Arbeitsweise des Prozessors angelehnt sind, also wenig bis gar keine Abstraktion zwischen geschriebenem Code und tatsächlich ausgeführten Befehlen zwischenschalten. Als Lowlevelsprache im eigentlichen Sinn geht also (abgesehen vom direkten Schreiben der Befehle als Zahlenwerte) nur die Assemblersprache durch (dazu später mehr). Die andere Seite des Spektrums wird von den Highlevelsprachen besetzt. Diese charakterisieren sich durch die Zulässigkeit komplexe Ausdrücke zu formen (z.B. "berechne 2*4+1", anstatt "merke dir 2, multipliziere das Gemerkte mit 4 und merke dir dieses Ergebnis, addiere 1 zum gemerkten"), sowie den Programmablauf im höheren Sinne zu abstrahieren (die Fähigkeit objektorientiert zu Programmieren wäre u.a. ein solches Merkmal). Das äußert sich dann salopp gesagt auch dadurch, dass "eine Zeile im Programmcode" zu bis Weilen "sehr vielen Zeilen im eigentlichen Maschinencode" wird.

Interessant ist auch, ob eine Sprache statisch, oder dynamisch typisiert ist, d.h. ob die innerhalb der Sprache verwendeten Variablen nur eine vorher festgelegte Art von Daten speichern können (das wäre statisch; z.B. muss man festlegen ob eine Variable nun Zahlen, oder Zeichenketten speichern kann), oder sich dynamisch an die Art der Daten anpassen. Während statische Typisierung eine höhere Optimierung der Programme zulässt (weil sich der Computer dann nicht darum kümmern muss Variablen ständig anzupassen), ist eine dynamische Typisierung seitens des Programmierers natürlich komfortabler (kleines Beispiel für alle, die "Big Band Theory" mögen: Sheldon ist sehr statisch; er kann nur in seinem "Spot" sitzen; obwohl dieser, wie er häufig und gern erklärt aufgrund vieler Überlegungen als optimaler Sitzplatz ausgewählt wurde, hat er ein großes Problem, wenn sein Sitzplatz anderweitig besetzt ist; die, die sich überall hinsetzen können sind in der Hinsicht sicher freier).

Zuletzt sollte man natürlich auch immer das Aufgabenfeld im Hinterkopf behalten, dass die Entwickler einer Sprache bei deren Konzeption im Sinn hatten. Dabei gibt es sogenannte all-purpose-Sprachen (universell einsetzbar), deren Anwendungsspektrum sehr breit gefächert ist, sowie eher stark spezialisierte Sprachen, die jeweils eine eigene Nische haben, in der sie brillieren.
Für einen Programmieranfänger wäre es an dieser Stelle sicher ratsam eine universell einsetzbare Sprache zu wählen und je nach Bedarf später zu eher spezialisierteren Sprachen zu greifen.

Vorstellung einiger Programmiersprachen

Die folgende Zusammenstellung ist in keiner Weise vollständig und stellt auch keinen Anspruch an Vollständigkeit. Hierbei soll es eher darum gehen, die in Form einer Section auf Free-Hack vertretenen Sprachen kurz vorzustellen.

Wer an diese Stelle vielleicht auch ein Programm in der entsprechenden Sprache sehen will sei auf 99 Bottles of Beer (http://99-bottles-of-beer.net/) verwiesen. Auf dieser Seite findet man ein und dasselbe Programm in vielen verschiedenen Sprachen (zwar durchaus nicht immer auf die selbe Weise programmiert, da alles von verschiedenen Autoren stammt, aber das ganze sollte einem schon einen groben Überblick geben, wie so ein Programm in einer speziellen Sprache aussehen könnte).

C/C++

Siehe auch: C/C++ FAQ (http://free-hack.com/showthread.php?p=568674#post568674). C bzw. C++ ("C/C++" sei hier nur geschrieben um beide Sprachen zu referenzieren. Es soll nicht heißen, dass es hier um eine Sprache namens "C/C++" geht -- eine solche Sprache existiert nämlich gar nicht!) wurden als Kompromiss zwischen Highlevel- und Lowlevelprogrammierung konzipiert. Dabei wurde C ursprünglich konzipiert, um das Betriebssystem Unix auf einem neueren Rechner zu implementieren. Zwecks dieses Ziels teilt sich C zusammen mit Assembler z.B. die Fähigkeit direkt auf den Speicher zuzugreifen. Dabei ist C auch prozedual, unterstützt verschiedene Kontrollstrukturen (if, switch und Schleifen) und verfolgt ein eher minimalistisches Design (nach dem Motto "weniger ist mehr"). C ist streng statisch typisiert. Darauf aufbauend wurde später C++ entwickelt, das die Möglichkeit zur Lowlevelprogrammierung beibehält, aber die Möglichkeiten zur Highlevelprogrammierung konsequent durch Hinzufügen von Objektorientierung, Templates, Konstrukten zur Fehlerbehandlung, sowie der Möglichkeit zum Überladen von Funktionen ausbaut. Vor allem durch Polymorphismus (ein Konzept in der Objektorientierung) und Templates entschärft C++ auch etwas die Strenge, die C bei der statischen Typisierung einhält.
Wer C oder C++ lernt hat die Möglichkeit nah am Betriebssystem zu Programmieren (z.B. Treiberentwicklung), aber zugleich auch große Programme zu schreiben.
Ein Nachteil für Anfänger ist die sehr übersichtlich gehaltene Standardbibliothek, die zu C/C++ gehört und die so aufkommende Notwendigkeit oft auf 3rd Party Bibliotheken auszuweichen (weder C, noch C++ haben beispielsweise eine standardisierte Weise um eine grafische Benutzeroberfläche zu programmieren; das soll aber keines Falls heißen, dass dies per se nicht möglich ist -- das ist es nämlich sehr wohl). C/C++ an sich ist weiterhin auch plattformunabhängig (und das nicht nur auf "normalen" Betriebssystemen; viele Microcontroller lassen sich auch über C programmieren) und bleibt es auch, sofern man die richtige Bibliotheken wählt.
Wer sich also für C/C++ entscheidet bekommt ein mächtiges Werkzeug in die Hand gedrückt mit dem man, wenn man sich auskennt, wirklich fast alles machen kann (wobei das "fast alles" eben im Gegenteil zu vielen anderen universellen Sprachen auch Treiberprogrammierung mit einschließt). Der große Nachteil, wenn man C/C++ als erste Sprache lernen will ist allerdings der, dass zwar "fast alles" möglich ist, aber vieles von diesem "fast alles" nicht umbedingt kürzer machbar ist, als in anderen Sprachen.

VB.NET

Jeder der sich dem Thema Programmieren zuwenden will, wird früher oder später einmal dem Begriff "Visual Basic" begegnen. Der Name spricht hierbei für sich selbst, denn das Ziel war es damals eine einfache Programmiersprache zu schaffen, die stark an das Englische angelehnt war und somit auch leichter zu lernen sein sollte.
Hierbei ist es allerdings wichtig zu wissen, dass es heutzutage verschiedene Arten von Visual Basic gibt. Zu nennen wäre an dieser Stelle das klassische Visual Basic was man als "Visual Basic 6" oder als "Visual Basic classic" kennt. Da diese Variante unter den heutigen Technischen Maßstäben und Standards veraltet ist, werde ich an dieser Stelle nicht weiter darauf eingehen.
Primär geht es um die Sprache VB.NET und deren Kerntechnologie. Das .NET steht hierbei im Grunde für eine Technologie die sehr stark an Oracle’s Java erinnert. Das Programm wird in der jeweiligen Sprache geschrieben und zur Laufzeit in Maschinencode umgewandelt. Wie dies genau von statten läuft lässt sich hier (http://free-hack.com/showthread.php?t=47737) und hier (http://free-hack.com/showthread.php?t=40309) nachschlagen.
Syntaktisch hat sich nicht viel geändert, allerdings sind altbekannte Operatoren auch nach wie vor aus Kompatibilitätsgründen vorhanden. Die Sprache besitzt somit alle gängigen Techniken und ist wie alle modernen Programmiersprachen objektorientiert, im Gegensatz zu seinem Vorgänger. Die Sprache und seine Plattform wurden von Microsoft entwickelt und sind daher sehr gut für das hauseigene Betriebssystem abgestimmt. Durch diverse andere Projekte ist es möglich ein in VB.NET geschriebenes Programm auch unter anderen Systemen lauffähig zu machen.
Zu empfehlen ist die Sprache also für Personen die gerne eine Einfache Sprache lernen wollen, die sich gut für Anwendungsentwicklung im Desktop und Serverbereich eignet.

C#

Auch C# gehört zur Familie der .NET Sprachen. Aus diesem Grunde empfehle ich zuerst den Beitrag "Funktionsweise von Microsoft .NET (http://free-hack.com/showthread.php?t=40309)" als Basiserklärung zur Grundtechnologie. Anhand der Syntax lässt sich sehr deutlich feststellen, dass die Sprache selbst durch viele andere Sprachen inspiriert wurde. Die zwei stärksten wären hierbei Java und C++. Der große Unterschied zwischen VB.NET und C# besteht darin, dass es in C# möglich ist "unsicheren Code" zu verwenden. Das bedeutet es ist möglich in C# Techniken wie Pointer zu verwenden. Des Weiteren lässt sich in C# wesentlich kürzerer und kompakter Code schreiben als in VB.
C# wurde damals speziell für .NET entwickelt, wodurch sie eine wesentliche Rolle spielt wenn es um .NET geht. Letztendlich bleibt allerdings zu sagen dass sich im Grunde in beiden Sprachen die gleichen Dinge realisieren lassen, hier entscheidet letztendlich nur der persönliche Geschmack.
Zu empfehlen für Personen die eine moderne, objektorientierte und zugleich Syntaktisch Anspruchsvolle Programmiersprache mit dem Schwerpunkt auf Anwendungsentwicklung im Desktop/Server Bereich lernen wollen.

F#

Sie ist einer der neuesten Sprachen in der Familie der .NET Sprachen. Zuerst ist zu sagen das auch dank des .NET Frameworks hier dieselben Möglichkeiten gegeben sind, auch wenn dies bei der Begutachtung eines F# Programms zuerst nicht ersichtlich sein kann. Die Sprache selbst wurde in erster Linie für Personen Entwickelt, die in Berufsfeldern Tätig sind mit dem Schwerpunkt auf Mathematik. In dieser Sprache lassen sich mathematische Funktionen und Formeln leichter, kürzer und vor allem effizienter abbilden als dies in den anderen .Net Sprachen möglich wäre. Es war auch gedacht das mathematikintensive Teile eines .NET Programms in F# abgebildet werden, und dann als Klassenbibliothek in ein anderes Programm importiert werden.
Der wohl interessanteste Aspekt besteht darin, dass es in F# keine main Methode zu geben scheint. Die erste Zeile wird als Einstiegspunkt gewertet und dementsprechend abgearbeitet. In Wirklichkeit besitzt eine F# Assembly allerdings trotzdem die übliche Main Methode, wodurch sie im eigentlichen Ausführungsprozess genauso arbeitet wie die anderen .NET Sprachen.

Assembler

Obwohl für Anfänger im Prinzip komplett ungeeignet sei Assembler hier dennoch kurz vorgestellt. Assembler ist sozusagen eine für Menschen lesbare Form für die Grundlegenden Befehle, die ein Prozessor ausführen kann (also Befehle für CPU, ALU, FPU, ...).
Wer sich entscheidet Assembler zu lernen, der tut dies sicher aus einem der folgenden drei Gründe: (1) aus reinem Interesse daran, was ein Prozessor im Computer wirklich für Befehle ausführt und wie Programme auf dieser Ebene aussehen und (2) weil von den drei großen Zielen "Macht, Autos, Frauen" Assembler zumindest Macht bringt (okay, das sollte jetzt eher ein Scherz sein, aber das mit der Macht stimmt wirklich) (3) man möchte bereits in Maschinencode vorliegende Programme verstehen (und eventuell verändern; eine Anwendung wäre Reverse Engineering, was u.a. in der Malware-Analyse und beim Cracken von Programmen Anwendung findet -- darum vielleicht auch insbesondere für uns hier interessant). Beantworten wir also die Frage: "Was kann man mit Assembler machen?". Dies wird leicht deutlich, wenn man sich vor Augen führt, dass jedes Programm, das auf einem Computer läuft, letztlich in Form von Befehlen für den Prozessor vorliegt (Befehle für Grafikkarten etc. seinen mal außen vor; damit sind interpretierte Programme keines Wegs ausgeschlossen, da diese auch oft zuerst in eine Art Zwischencode übersetzt werden, der der Assemblersprache häufig sehr ähnlich ist und erst dann vom Interpreter ausgeführt werden; wem das noch nicht als Begründung wasserdicht genug erscheint, dem sollte aber auf jeden Fall klar sein, dass der Interpreter auch ein Programm ist, das ja letztlich die Arbeit macht -- und dieses Programm besteht dann letztlich eben aus den Befehlen, die die CPU ausführt; was ist mit "Interpretern, die einen Interpreter intepretieren, welcher dann den Code interpretiert?"... lassen wir das... in dem Fall wäre dann halt der letzte Interpreter ein richtigen Maschinenprogramm). Gibt es also ein Programm, das irgendwas macht, dann kann man dieses "irgendwas" auch mit einem Assemblerprogramm machen.
Wenn man sich also überlegt, dass salopp gesagt "alles" möglich ist, dann sollte auch gleich klar sein, dass man hierbei schwerwiegende Kompromisse eingehen muss (denn sonst würde ja jeder nur in Assembler programmieren). Obwohl es Assembler (die Programme, die einen Assembler-Quelltext in die tatsächlichen Maschinenbefehle übersetzen; weil Assemblerbefehle zu Maschinenbefehlen im Prinzip eine 1 zu 1 Repräsentation besitzen spricht man hier nicht von einem Compiler, sondern nur von einem Programm, dass die Befehle aus den geschriebenen Repräsentationen zusammensetzt [engl. "to assemble"]) für so ziemlich jede Plattform gibt, die Verfügbarkeit also gewährleistet ist, sind Assemblerprogramme dennoch fast immer inkompatibel zu anderen Plattformen.
Bei Microcontrollern kommt es dabei stark drauf an, welche Befehle der Prozessor kennt, dann gibt es auch viele verschiedene Dialekte (AT&T und Intel Syntax wären für den Desktop-Bereich vielleicht die häufigsten Kandidaten) und noch viel wichtiger:
Assembler als Sprache an sich hat keinerlei Anbindung an das zugrundeliegende Betriebssystem (wozu auch? Assembler wird ja vor allem auch überhaupt erst eingesetzt um ein Betriebssystem zu schreiben). Allein schon eine Textausgabe, die ja eine solche Interaktion erfordert sorgt dann schon dafür, dass das Programm nicht mehr kompatibel zu allen Systemen ist, obwohl die darin verwendeten Prozessorbefehle auf anderen Systemen vielleicht verfügbar wären.
Außerdem werden Assemblerprogramme schnell sehr groß (bezogen auf die Länge des Quelltextes; die fertigen Programme in ausführbarer Form sind hingegen extrem klein). Darum sind Quelltexte von Assemblerprogrammen oft nicht sehr gut wartbar und auch nicht leicht zu verstehen (gemeint ist hier zu verstehen "wozu dient dieser Abschnitt im Code"; die einzelnen Befehle für sich sind immer leicht verständlich).

(X)HTML / CSS / JavaScript

Hierbei handelt es sich wie einige sicher Anmerken würden nur bei JavaScript um eine Programmiersprache (genauer: um eine Skriptsprache). Diese sind hier aber dennoch alle drei aufgelistet und vor allem zusammen gruppiert, da diese oft nur in Kombination miteinander zu guten Ergebnissen führen.
HTML steht für "HyperText Markup Language" und ist Grundlage so ziemlich jeder Webseite. XHTML ist im Prinzip das selbe wie HTML, nur eben dass XHTML auf der Metasprache XML basiert und etwas strikter ist als HTML (dazu gleich mehr). Ich spreche ab hier jetzt eher von XHTML, da dieses eine konsequentere Syntax hat und HTML in nichts nachsteht.
XML steht für "eXtensible Markup Language", ist also eine erweiterbare Auszeichnungssprache (beschreibt Inhalt eines Dokuments). Erweiterbar soll hier heißen, dass man durch sogenannte Schemasprachen (beispielsweise DTD) weitere Sprachen auf XML-Basis definieren kann. Dies ist auch der Fall von XHTML.
XML-Basierte Auszeichnungssprachen liegen in Form einer Baumstruktur vor. Das heißt, dass jedes in so einer Auszeichnungssprache formatierte Dokument ein "Wurzel-Element" besitzt (im Fall von XHTML wäre dies das <html>-Tag) und jedes Element weitere Elemente enthalten kann. Solche Elemente (auch "Tags" genannt) können auch Attribute besitzen (Informationen über das Tag). Jedes Tag braucht ein End-Tag (<html> ... </html>; enthält ein Tag keinen Inhalt, wie z.B. <br>, welches in (X)HTML für einen Zeilenumbruch sorgt, so schreibt man in XHTML nicht </br> dahinter, sondern statt <br> einfach <br />. Dies ist übrigens auch der Grund, wieso ich XHTML als konsequenter als HTML bezeichnete -- die Regel "jedes Tag braucht ein End-Tag" -- gilt immer! <br /> ist sozusagen Tag und End-Tag in einem; in HTML ist dies nicht notwenig und man schreibt einfach <br> ohne irgendwo jemals ein </br> zu platzieren). XML stellt also die Rahmenbedingungen und eine entsprechende DTD (Schemasprache; siehe oben) definiert dann die Tags mit zugehörigen Attributen, wie man in XHTML verwenden kann/muss.
Während (X)HTML also für die logische Gruppierung und (stark) begrenzt auch für die Formatierung (Einbinden von Bildern, unterstreichen/fett drucken von Text, usw.) zuständig ist, gibt es CSS (Cascading Style Sheets; nicht der Ego-Shooter von Valve), welches zusätzliche Möglichkeiten zur Formatierung des Inhalts bietet (Hintergrundbilder, Positionieren von Elementen, Anpassen von Größen und Abständen, ...). Hierbei werden Elemente im XHTML-Dokument anhand von ihren Tags, oder ihren Klassen bzw. IDs (lassen sich über die Attribute "class" bzw. "id" für jedes Tag einzeln festlegen), oder mit neueren CSS-Features auch anhand ihrer Attributwerte usw. auswählen und individuell "stylen".
XHTML und CSS sind dabei wirklich sehr einfach durch stures Auswendiglernen der Tags und Properties (die Eigenschaften eines Tags, die man via CSS verändern kann) zu erlernen, da die zugrundeliegenden Formalismen (Syntax, Semantik) sehr einfach gehalten sind. Darum sind XHTML und CSS auch Sprachen, die man sich auch mal über ein Wochenende provisorisch aneignen kann (jetzt ohne Webdesign runterspielen zu wollen; das wirklich zu können ist auch eine Kunst an sich und bedarf viel Erfahrung, obwohl die zugrundeliegenden Kenntnisse nicht sehr umfassend sein zu brauchen).
Kurz noch zu JavaScript (hat mit Java übrigens rein gar nichts zu tun!): JavaScript bietet eine Möglichkeit zur Automatisierung gewisser Vorgänge auf Webseiten und sorgt damit für etwas "Dynamik" (am XHTML-Code bzw. CSS Style einer Webseite ändert sich ja nichts; diese sind darum eher statisch). JavaScript wird dabei von Seite des Browsers ausgeführt und kann zum Beispiel dafür sorgen, dass gewisse Daten von einem Webserver regelmäßig durch den Browser abgefragt werden (z.B. wichtig für eine Shoutbox) und im Browser angezeigt werden. Dabei hilft das Document Object Model (DOM), über welches man durch JavaScript auch bestehende XHTML Dokumente verändern kann (Clientseitig -- nicht auf Seiten des Servers!!) -- also eben z.B. das Anzeigen der von der Shoutbox angefragten Nachrichten innerhalb der Seite.
Wer JavaScript lernen möchte, der sollte allerdings im Hinterkopf behalten, dass das Haupteinsatzgebiet von JavaScript eben die Ausstattung von Webseiten mit dynamischen Elementen ist. Wer sich einen Crypter programmieren will ist hier definitiv falsch! (mal ganz davon abgesehen, dass die, die nur Programmieren lernen wollen, um einen Crypter zu schreiben in diesem ganzen Thread völlig falsch sind)
Bezogen auf die Tatsache, dass es in diesem Forum ja auch um Sicherheitsaspekte beim Programmieren geht wäre es sicher noch erwähnenswert, dass eben die Fähigkeit von JavaScript Aktionen auf einer Webseite zu automatisieren als Grundlage für verschiedene Angriffsmethoden dient (namentlich Cross-Site-Scripting [XSS] und Cross-Site-Request-Forgery [CSRF]), bei denen man eignen JavaScript Code in Webseiten einschleust (obwohl man für CSRF im weiteren Sinne oft nichtmal JS braucht, sondern wirklich nur den Browser des Benutzers dazu bringt eine gewisse Seite aufzurufen, die sofern der Benutzer die Rechte dazu hat dem Angreifer z.B. erhöhte Rechte auf der Webseite verleiht).

PHP

Wir bleiben in der Umgebung der Webprogrammierung und befassen uns nun ein wenig mit PHP. Ursprünglich als "Personal Home Page Tools" in Form von einigen Perl-Skripten erstellt, steht der Name PHP heute für das rekursive Akronym "PHP: Hypertext Preprocessor". Wie der heute Name nahelegt dient PHP zum Vorbereiten von Hypertext ((X)HTML).
Syntaktisch stark durch C/C++ und Perl beeinflusst dient PHP dazu Datenbankabfragen zu tätigen, Inhalte zu generieren und auch Inhalte zu speichern. Ein gutes Beispiel für den Einsatz von PHP ist auch schon dieses Forum -- es werden Daten aus einer Datenbank ausgelesen, verarbeitet und formatiert in XHTML an unseren Browser weitergeleitet. Beim Abschicken von Posts ist auch wieder PHP dafür zuständig die Daten richtig an die Datenbank weiterzugeben, usw.
Abgesehen von diesem Anwendungsfeld und dem für uns interessanten dadurch entstehenden Anwendungsfeld für Websicherheit (Motto: "Kenne deinen Feind / Kenne dein Ziel", wer Webseiten angreifen will, der tut eben gut daran deren Funktionsweise zu verstehen) ist PHP auch noch vielseitiger einsetzbar.
Durch eine große Funktionsvielfalt in Bereichen wie Textverarbeitung, Bildergenerierung, Kommunikation mit dem Internet über Sockets, ein umfangreiches CryptoAPI, der Möglichkeit mit großen Zahlen umzugehen (BCMath; in Form einer Erweiterung erhältlich), uvm. macht sich PHP sehr gut als universelle Programmiersprache, mit deren Hilfe man sich tägliche Aufgaben am Computer erleichtern kann.
PHP bietet Möglichkeiten zur objektorientierten Programmierung, ist dynamisch typisiert und plattformunabhängig (alles was man braucht ist eine Installation des PHP Interpreters auf dem Computer; der Interpreter selber ist für viele verschiedene Plattformen verfügbar).
Wer umbedingt will kann mit PHP sogar grafische Benutzeroberflächen programmieren (per Erweiterung; ist aber nicht so ganz ernst zu nehmen und die Entwicklung davon steht mehr oder weniger still; zu sagen man könnte es nicht wäre also falsch, aber so weit zu gehen es wirklich zu loben würde ich nicht) und mit Programmen wie bamcompile auch seine Skripten in ".exe"-Form ausliefern (das sollte man aber nicht in den falschen Hals bekommen -- das Skript selber wird von bamcompile nicht irgendwie übersetzt, sondern nur an eine Portable Version des PHP Interpreters gebunden... es ist also kein echtes Compilieren; Python kann das unter dem Namen "Frozen Binary" übrigens auch)
Wer PHP lernen will, bekommt also das Werkzeug schlechthin zum Programmieren von (serverseitig) dynamischen Webseiten und hat obendrein auch noch ein Schweizertaschenmesser für den Alltag in der Hand.

Perl

Hier will ich gar nicht so viel sagen, da vieles was PHP kann auch mit Perl geht und andersrum vieles was Perl kann auch mit PHP geht. Insbesondere kann man mit Perl auch via CGI Webseiten programmieren. Der eigentliche Reiz von Perl im Vergleich zu PHP ist Perls starke Orientierung an Textverarbeitung. Perl wurde damals von Larry Wall zum Auswerten von Logdateien konzipiert, als dieser als Systemadministrator tätig war. Besonders leistungsstark ist Perl also vor allem im Einsatz von Regulären Ausdrücken zum Erkennen von Mustern in Text, extrahieren von Informationen, ersetzen von bestimmten Textstellen usw.
Wer also viel Text verarbeiten möchte, oder sehr schnell Arbeit erledigt haben möchte, der kann auf Perl zurückgreifen. Vor allem das "sehr schnell" erreicht bei Perl neue Dimensionen, da Perl so ausgelegt wurde, dass man mit möglichst wenig Zeichen möglichst viel machen kann (Perl-Golf, anyone? :D).
Perl selber ist prozedual, dynamisch typisiert und auch begrenzt objektorientiert.
Wer jetzt nicht so auf Textverarbeitung steht, der kann mit Perl trotzdem glücklich werden, da Perl durch eine große Moduldatenbank (CPAN (http://www.cpan.org/)) viele vorgefertigte Module anbietet, die verschiedenste Funktionen erfüllen.

Java

Wer Objektorientierung richtig toll findet, der wird Java lieben (es sei denn einem kommt nach einer Weile dieser Kaffee doch zu den Ohren raus; weiß ich nicht). Im Gegensatz zu vielen anderen Sprachen, die objektorientiertes Programmieren erlauben ist Java wirklich durch und durch Objektorientiert (in anderen Sprachen hat man eigentlich immer die Wahl, ob man jetzt Klassen benutzt, oder ganz drauf verzichtet; bei Java muss man allein schon eine Klasse anlegen um ein lauffähiges Programm zu haben; sogar die Grunddatentypen sind in Java Objekte von Klassen).
Java orientiert sich hierbei stark an C++ und teilt mit C++ auch viel von seiner Syntax (ist ferner auch statisch typisiert). Dabei verzichtet Java aber bewusst auf freien Speicherzugriff für den Programmierer und nimmt im Gegenteil zu C++ auch das Freigeben von Speicher selbst in die Hand (was an sich ein sehr gutes Konzept ist). Java läuft standardmäßig in einer Virtuellen Maschine (VM), wird also interpretiert (obwohl Java-Code zuerst in sogenannten Byte-Code übersetzt wird, der dann erst von der VM ausgeführt wird; weiterhin sage ich "standardmäßig", da vor allem das GNU Projekt mit GCJ einen "echten" Java Compiler hervorgebracht hat, der tatsächlich Maschinencode erzeugt, wie ihn der Prozessor ausführt).
Dadurch kommt Java zu dem durchaus praktischen Konzept "Compile once, run anywhere". Das liegt daran, dass der fertige Bytecode, der in Form von .class Dateien, oder gepackt in .jar Archiven ausgeliefert wird unabhängig von dem zugrundeliegenden Betriebssystem von der Java VM ausgeführt werden kann. Man erreicht so also eine echte Plattformunabhängigkeit, wie man sie sonst nur bei Skriptsprachen sieht. Logischer Weise büßt man dadurch aber auch ein großes Maß an Systemnähe ein.
Interessant ist Java zur Entwicklung von Java Applets für Webseiten (obwohl diese eigentlich schon länger immer weiter an Bedeutung verlieren), auf dem Handy-Markt (wer für beispielsweise Android Programme schreiben will findet mit Java die richtige Sprache und kommt auch nicht daran vorbei) und natürlich auch für normale Anwendungsentwicklung.
Hierbei besticht Java vor allem durch einen großen Umfang sogenannter Packages, die als Klassenbibliotheken einen Großteil der Funktionalität von Java bereitstellen. Man muss im Gegensatz zu C/C++ also nicht ständig auf 3rd Party Bibliotheken zurückgreifen, sondern kann auch größere Programme ganz ohne extra Bibliotheken schreiben.

SQL

Hier gibt es eigentlich nicht viel zu sagen, da SQL keine Programmiersprache ist. Da man mit SQL jedoch in relationalen Datenbanken (was relational bedeutet gleich im Anschluss) Daten definieren, abfragen und ändern kann und das vor allem im Zusammenhang mit PHP häufig genutzt wird (aber auch in Programmen; das Datenbanksystem SQLite, welches SQL zur Kommunikation benutzt rühmt sich mit vielen wohlbekannten Benutzern -- siehe Liste (http://www.sqlite.org/famous.html)) sei SQL hier auch kurz erwähnt. Wer in Erwägung zieht SQL zu lernen, der wird also immer bereits eine Programmiersprache beherrschen, die die Interaktion mit Datenbanken unterstützt.
Relationale Datenbanken speichern ihre Daten in tabellarischer Form, wobei die Zeilen in einer solchen Tabelle als Datensätze bezeichnet werden und die Zellen in einem Datensatz als Attributwerte (die "Überschriften" zu der Spalte in der ein Attributwert steht heißen Attribute). Die "Relation" besteht nun darin einzelne Datensätze (nicht notwenig aus der selben Tabelle) miteinander zu verbinden.
SQL ist nun eine Sprache um solche Datensätze auszuwählen, einzufügen, abzuändern, oder überhaupt erst Tabellen zu erstellen. SQL ist nebenbei erwähnt ein Beispiel für eine deklarative Sprache, da man bei einer Abfrage angibt, welche Eigenschaften die auszuwählenden Datensätze haben sollen (oft anhand ihrer Attributwerte) und das Datenbanksystem sich dann damit beschäftigt diese zu finden, anstatt dass man selber angibst wie das Datenbanksystem diese zu finden habe.


Download als PDF

http://img7.imagebanana.com/img/9wx8p9k6/wahlprglangscreenshot.png
Wer sich lieber eine PDF durchliest, oder seinen neuen Drucker heiß laufen lassen möchte, der findet diesen ganzen Post auch als wunderschön geTeXte Variante zum Download bei Megaupload:
http://www.megaupload.com/?d=C2P3NK4E
Insgesamt 14 Seiten mit Inhaltsverzeichnis und provisorischem Index am Ende.
Viel Spaß damit!

TODO-Liste:

Delphi
PythonP.S.: Ja, dieser Artikel erfreut sich der Unterstützung mehrerer Liter Kaffee!