Programmiersprachen
Java
C++
Perl
Visual Basic
Java
IO
ByteStreams Inputstream-Outptstream
Streams auf Byteebene; Alle Subklassen verarbeiten Byteströme;
Werden Bytestreams für Zeichenfolgen verwendet, dann muss ein Encoding eingestelllt werden.
Im Default wird das Plattformencoding verwendet.
Klassen wie Printstream zum Schreiben von Strings mittels Bytestreams sind veraltet.
CharacterStreams Reader-Writer
Reader und Writerklassen schreiben Unicode Character.
Diese Klassen sollten für Texte verwendet werden.
Dabei liegen intern unter den Readern- und Writerklassen wieder byteorientierte Streams.
Das Encoding wird aber vorher richtig angewendet. Dabei wird im Default aber das gleiche Encoding verwendet, wie bei den
ByteStreams (Windows = CodePage 1252). Bei den ByteStreams ist nicht immer sichergestellt, dass bei Unicodezeichen mit mehr als
8Byte nicht die oberen Bytes abgeschnitten werden.
Die Verarbeitung beider Klassen erfolgt byte- oder zeichenweise. Es wird also jedes Byte einzeln in eine Datei geschrieben oder gelesen.
Zum Beschleunigen dieses Vorgangs gibt es die „Buffered“ – Klassen. Diese Klassen schreiben Blöcken (Default 512 Byte) mit konfigurierbarer
Größe. Wenn also eine Buffered-Klasse vorhanden ist, sollte diese verwendet werden.
Für beide Gruppen gibt es Klassen zum Lesen/Schreiben auf spezifische Devices (z.B. FileWriter) und Klassen zum Lesen/Schreiben in
spezifische Speicherstrukturen (z.B. StringWriter). Beide Gruppen können kombiniert werden, um spezielle Speicherstrukturen auf
die entsprechenden Geräte zu schreiben.
public static void write2OOS(String fileName, Object obj) {
try {
FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(obj);
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static Object readFromOIS(String fileName) {
Object obj = null;
try {
FileInputStream fos = new FileInputStream(fileName);
ObjectInputStream oos = new ObjectInputStream(fos);
obj = oos.readObject();
oos.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return obj;
}
//use reader for stream
public static void readFromIS(InputStream is) {
String str = null;
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new ObjectInputStream(isr);
while(br.ready()) {
str = br.readLine();
//do something with str
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void write2BFW(String fileName, String value) {
try {
FileWriter fw = new FileWriter(fileName);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(value);
bw.newLine();
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static String readFromBFR(String fileName) {
String result = "";
try {
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);
while(br.ready()) {
result += br.readLine();
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
Prozess
Umgebungsvariablen
CLASSPATH - Semikolongetrennte Liste der JARs
JAVA_HOME - Pfad auf das JDK, z.B. "C:\Programme\sdk"
Starten eines Programms
java -classpath . pack.Hello - startet die Klasse: "Hello" mit der Mainfunktion aus dem Package: (= Unterverzeichnis) "pack" aus dem aktuellen Verzeichnis.
java -classpath c:/tmp pack.Hello - startet die Klasse: "Hello" mit der Mainfunktion aus dem Package: "pack" aus dem Verzeichnis: "c:/tmp/pack/".
java -jar test.jar - startet die im Manifest festgelegte Startklasse der Bibliothek: "test.jar"
Compiler
javac -d ..\bin test\Main.java - compiliert die Klasse Main.java aus dem Unterverzeichnis test und schreibt den ByteCode nach ..\bin.
d - Verzeichnis für die *.class files
Decompiler
javap -c -verbose Main - decompiliert die Klasse Main.java und gibt den ByteCode aus.
c = Disassemble
Core
Notation
ByteCode für: double x; x > 0 ist gleich x > 0.00d (Notation für double).
0.0 erzeugt automatisch einen double.
Parameter
Alle Methodenparameter können in Java nur per Value übergeben werden.
Instanzen der Wrapperklassen für die Grunddatentypen (Long, Boolean, …) sind unveränderlich und können nur einmal initialisiert werden
oder auf ein anderes Objekt zeigen. Die Wrapper ermöglichen also auch keine pseudo CallByReferenz Übergabe für Grunddatentypen.
Eine mögliche Variante wäre die Übergabe eines Array mit einem Element, welches dann innerhalb einer Funktion ausgetauscht
werden kann.
C++
Type Qualifier
extern
In einer hybriden Sprache wie C++ sind globale Variablen möglich, also Variablen, die nicht an eine Klasse gebunden sind. Wird in einem Headerfile eine Variable double x; deklariert, so kann sie in einem zugehörigen Sourcefile verwendet werden. Dabei wird aber durch den Headerfile nicht nur deklariert, sondern auch definiert, also Speicher für die Variable angelegt. Wird dieser Headerfile in einem zweiten Sourcefile verwendet, so wird der Compiler melden, daß eine Variable mit gleichem Namen erneut erzeugt wurde.
Damit globale Variablen trotzdem möglich sind wird die Variable mit dem Typequalifier extern versehen. Dadurch wird kein Speicherplatz angelegt, also nur deklariert. Danach muß in einem Sourcefile eine globale Wertzuweisung stattfinden (außerhalb einer Klassenmethode). Danach kann die Variable überall global genutzt werden. Die Variable wird dann beim Programmstart initialisiert, so wie statische Variablen. Aus diesem Grund sollten keine zeitlichen Abhängigkeiten zwischen globalen oder statischen Variablen bestehen, weil die Reihenfolge der Initialisierung unbestimmt ist (Compilerabhängig).
Der Einsatz von globalen Variablen sollte minimiert werden.
Externe Variablen eignen sich zum Beispiel für Stringtabellen. Die Variablen, die im Sourcefile A verwendet werden sollen, werden in einem eigenen Headerfile als extern deklariert und dann in einem Sourcefile B definiert und in A verwendet. Das hat den Vorteil, das eine Änderung des Textes lediglich einen Compile von Sourcefile B erfordert, nicht aber von A.
volatile (unbeständig)
Volatile ist ein Typequalifier der angibt, das ein Objekt jederzeit während des Programmablaufs vom Betriebssystem oder der Hardware oder einem gleichzeitig laufendem Thread verändert werden kann.
Bei Multithreading sollten alle Variablen, die von mehreren Threads gelesen werden, als volatile qualifiziert sein. Dadurch wird der Optimierer angewiesen keinen Code zu verändern, der diese Variable betrifft.
Beispiel:
Wenn in einem Programm zweimal eine Variable A an eine Variable B übergeben wird, ohne das durch den Code inzwischen eine Änderung an einer der beiden Variablen durchgeführt wird, so würde der Optimierer das zweite Lesen wegoptimieren, weil es überflüßig erscheint. Wurde aber die Adresse der Variable extern anderen Prozessen bekanntgegeben, so ist diese Optimierung vielleicht nicht erwünscht und wird durch volatile verhindert.
mutable (veränderlich)
Dieser Typequalifier kann nur auf nicht statische oder konstante Membervariablen angewandt werden. Wenn eine Membervariable als mutable deklariert ist, so ist es legal ihr einen Wert zu zuweisen innerhalb einer konstanten Methode der Klasse.
Beispiel:
Eine Klasse hat einen Zugriffszähler. Wenn dieser mutable deklariert ist, kann eine Instanz der Klasse als const gehalten werden, der Zähler wird aber trotzdem hochgezählt.
const
bei einer Funktion kann const für folgendes verwendet werden:
1. der Retrunwert - const int name();
2. die Parameter - void name(const int i);
3. das die Funktion keine Änderungen an Membern der Klasse durchführt oder andere nicht konstante Funktionen der Klasse aufruft - void name() const;
const wegcasten:
const int ci = 10;
int * ui = (int*) &ci; //Dereferenzieren und auf der Addresse
//den Pointer ohne const abbilden
*ui = 10;
static
Variablen oder Funktionen, die an eine Klasse und nicht an eine Instanz der Klasse gebunden sind.
Strings
Schnelle Stringfunktionen
strcpy - memcpy
memcpy ist schneller als strcpy,
strcpy kopiert Zeichen für Zeichen vom Quellstring in den Zielstring,
memcpy kopiert Speicherblöcke (Busgröße) also 4 Zeichen oder 8 Zeichen gleichzeitig,
Achtung (bliebter Fehler): Am Ende muß '\0' angehängt oder mitkopiert werden.
strcpy(Zielstring, Quellstring);
memcpy(Zielstring, Quellstring, Bytezahl);
Bytezahl = Anzahl der Zeichen im Normalfall.
strcat - zeitlich nicht effektiv
strcat funktioniert so: der Zielstring wird vom Anfang durchlaufen, bis das Ende '\0' erreicht wurde, dann beginnt das
Anhängen.
Bei langen Strings kann das Durchlaufen einige Zeit kosten.
Besser ist einen Pointer auf den Start des String setzen und den Pointer um die Länge des Strings erhöhen,
damit stehen wir mit dem Pointer am Ende des Zielstrings und können dort ein strcpy oder memcpy
durchführen.
Beispiel:
char *s = stringPointer;
s += strlen(stringPointer);
memcpy(s, newStringPointer, strlen(newStringPointer));
Timefunctions
Zeitmessung
Für die Zeitmessung im Microsekundenbereich gibt es eine alte Funktion:
#include <time.h>
struct timeval tp;
gettimeofday(&tp, NULL);
long sec = tp.tv_sec; //Sekunden seit 1970 blah blah
long micsec = tp.tv_usec; //Mikrosekunden pro aktuelle Sekunde
Die neue Funktion auf UNIX:
(void)clock_gettime(CLOCK_REALTIME, &ts);
Perl
Perlscripte - Beispiele
Suchen und Ersetzen (mehrzeilig, gezielt, rekursiv, regexp)
Download
Text in Dateien einfügen am Anfang und am Ende (rekursiv)
Download
Visual Basic
VB - Projekte und deren Properties
Component
In den Propertys eines Projektes wird unter Component die Compatibilität eingestellt.
Dabei geht es um die Kompatibilität von COM-Komponenten, d.h. die UID's müssen immer passen.
Ein Projekt wird völlig Standalone erzeugt = none.
Ein Projekt wird Projektkompatibel erzeugt, wenn mehrere Projekte in einer Projektgruppe zusammen
erstellt werden, dann ist das Projekt immer Kompatibel zu den anderen Projekten, d.h. die
Registrierung und Anpassung der UID's in den anderen Projekten wird vom VB-Runtime übernommen.
Die anderen Projekte müssen nur in ihren Referenzen die Referenz auf das vbp des Projektes
ankreuzen.
Ein Projekt wird binärkompatibel erzeugt, dann wird in einem anderen Verzeichnis eine Vergleichs-DLL
oder EXE abgelegt und geprüft, ob die Binärkompatibilität zu dieser verletzt wurde, d.h. ob sich
nur intern etwas geändert hat oder ob das Interface geändert wurde (public Funktionen andere
Parameter bekommen haben oder weggefallen sind). Solange die Binärkompatibilität nicht verletzt
wird gibt es auch keine Schwierigkeiten mit neuen DLL's.
Um soetwas zu machen, wird die DLL einmal unter Reiter Make auf Version 1.0.0 gesetzt und mit
None in einem extra Verzeichnis (z.B. \bincomp\*.dll) erstellt. Danach wird die Binärkompatibilität
eingestellt (Reiter Component) und im Feld darunter die DLL, die vorher mit none erstellt wurde,
eingegeben. Jetzt werden die DLL's binärkompatibel zu der DLL (im Verzeichnis bincomp) mit der
Version 1.0.0 erstellt.
Make
Im Make kann durch autoinkrement, eine automatische Versionsnummerierung eingestellt werden.
Diese sollte bei COM-DLL's immer eingeschaltet werden.
Mit Conditional Compilation Arguments können Projektkonstanten definiert werden.
|