I just came across a very strange Mysql-Behaviour, which i want to discuss with the community.

In the following example there is a table with existing records. After altering the table and appending a DATE-Field, this field is NOT writeable in already existing records. The following error message occurs on every write to the field:

1267 Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_general_ci,IMPLICIT) for operation ’=’

 

The connection is utf8, the Table was created with utf8 (except the ENUM-Fields), indeed the whole database was created with utf8.

In Detail:

This is the table (i renamed the table for security purposes):

CREATE TABLE `test1` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT(10) UNSIGNED NOT NULL,
`location_id` BIGINT(20) UNSIGNED DEFAULT NULL,
`for_time` datetime NOT NULL,
`value` DECIMAL(5,1) UNSIGNED NOT NULL,
`unit` enum('mg_dl','mmol_l') CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
`value_mgdl` DECIMAL(7,3) NOT NULL DEFAULT '0.000',
`value_mmoll` DECIMAL(7,3) NOT NULL DEFAULT '0.000',
`source` enum('import','test','user','support') CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT 'user',
`comment` VARCHAR(255) NOT NULL,
`created` datetime NOT NULL,
`updated` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `fk_copd_location_id` (`location_id`),
KEY `for_time` (`for_time`),
KEY `value` (`value`,`unit`),
KEY `value_mgdl` (`value_mgdl`),
KEY `value_mmoll` (`value_mmoll`),
KEY `source` (`source`),
CONSTRAINT `fk_test1_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
SHOW TABLE STATUS like 'test1':
 
Name        Engine  Version Row_format  Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time         Update_time  Check_time Collation       Checksum	Create_options	Comment
bloodsugar	InnoDB  10      Compact     8    2048           16384       0               114688       611319808 14             2011-05-29 20:28:54 NULL         NULL	      utf8_general_ci NULL
mysql> show variables like '%colla%';
+----------------------+-----------------+
| Variable_name        | Value           |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database   | utf8_general_ci |
| collation_server     | utf8_general_ci |
+----------------------+-----------------+
3 rows in set (0.00 sec)
 
mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

This table contains some records, and has an overhead of 500 MB (i deleted a lot of records some days ago).

Then i entered the following statement:

ALTER TABLE  `test1` ADD  `test` DATE NULL DEFAULT NULL ;

Everything works fine right now.

But each of the following statements gives the error described above:

UPDATE test1 SET test=NULL;

or

UPDATE test1 SET test=DATE(for_time);

or

UPDATE test1 SET test='2011-01-01';

and so on….

Result:

1267 Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_general_ci,IMPLICIT) for operation ’=’

Setting up a new table with all the steps described above works fine on some machines and not on others. At least with data in it on every machine the same errors occure.

But altering the existing table  gives this annoying error.
My main Problem is: on the production database there are a lot of records collected in  the last 6 months. So i am looking for the underlying cause for such an error.

The MySQL-Version is “Ver 14.14 Distrib 5.1.56″ running an Debian Lenny 64bit.

Can anyone give me some hints or explain this issue?

Thanks in advance!

Dieser Artikel dient als Ergänzung zu diesen Artikeln.

Wie mir heute von einem Leser bekannt gegeben wurde, hat das Manipulieren der Inhalte von Websites durch die Mobilfunkprovider während der Übertragung via UMTS weitere eklatante Fehler!

Der Leser setzt für einen Kunden als CMS ein Produkt namens “CMSimple” ein. Nachdem sein Kunde, für den die mit CMSimple erstellte Homepage gedacht ist, über eine UMTS-Verbindung über Vodafone die Artikel überarbeitet hat, wurden die URL’s zu den Bild-Dateien ebenfalls umgebogen. Und zwar zu “http://1.1.1.1/bmi/www.brunsandalusier.de/images/brand.JPG”. An der IP-Adresse erkenne ich direkt den UMTS-Proxy von Vodafone. Der von der Telekom lautet in meinen untersuchten Fällen “1.2.3.*”, wobei das Sternchen für eine beliebige Zahl steht.

Diese URL ist NUR in einem UMTS-Umfeld gültig, wenn der Surfer das UMTS-Netz von Vodafone nutzt. Das heisst, Besucher der Website, die über DSL z.B. ins Internet gehen, sehen eine “kaputte” Seite, ohne Bild.

Was wird hier passiert sein?

Hierzu muss man wissen, wie das CMS arbeitet. Genauere Darstellungen kann ich erst später liefern. Es scheint aber folgendes abgelaufen zu sein:

  1. Der User bearbeitet einen Artikel und bindet Fotos ein, die er zuvor hochgeladen hat.
  2. Wie in diesem Artikel beschrieben, biegt Vodafone die Bild-URL auf eine gecachte Variante um.
  3. Der somit manipulierte HTML-Code wird durch das Speichern im CMS an den Server zurück übertragen
  4. Und ist somit futsch!

Hinzu kommt folgendes: der umgeänderte Link auf die Bilddatei wird auch noch falsch zusammen gebastelt:

Er beginnt mit “http://1.1.1.1/bmi/1.1.1.1/bmi” (diese Wiederholung ist kein Tippfehler)

Das kann entweder an Vodafone liegen oder an dem CMS. Möglicherweise an beiden. Der Teil “1.1.1.1/bmi” stammt von Vodafone. Diese Wiederholung auch? Ich kann es derzeit nicht nachprüfen.

An dieser Stelle muss ich auf folgendes hinweisen:

Meine o.g. Artikel sind nach reinem Gewissen recherchiert und enthalten ausschließlich Kenntnisse, die ich selbst erforscht und nachgewiesen habe.

Diese Nachforschung fehlt mir hier in diesem Aspekt des Lesers, da ich über keine Lizenz zu diesem CMS verfüge, um das Problem nachzustellen. Der Quelltext der Website, um die es geht, enthällt allerdings zweifelsohne die umgebogene IP-Adresse, und zwar ab Server, auch via DSL, ohne UMTS. Es steht außer Frage, das so eine URL (1.1.1.1/bmi) nur via UMTS-Verbindungen zustande kommt.

Außerdem bin ich der Meinung, das jetzt mal Vodafone selbst nachforschen kann. Ich habe schon genug Zeit und Geld für diese Geschichte geopfert.

Update

Mit dem Speedmanager kann man das Verhalten zumindest bei T-Mobile einstellen. Schade, das es nicht explizit kommuniziert wird.

http://www.t-mobile.de/speedmanager/0,20641,24080-_,00.html

Der Speedmanager muss laut T-Mobile über die UMTS-Verbindung aufgerufen werden, dann kann man aus 3 verschiedenen Optionen auswählen.

T-Mobile und Vodafone schummeln Zusatzdaten während der Übertragung von Websites über UMTS ein und bewirken damit, das Sie doppelt und dreifache/s Volumen und Zeit benötigen, als dies notwendig wäre!

Zu Ihrem(!) Nachteil werden viel mehr Daten übertragen als nötig!

(Bitte beachten Sie auch die Updates am Ende des Artikels mit Neuigkeiten zum Thema)

Bei dem Vorgehen werden übrigens nicht die ungeliebten viel-verbrauchenden Youtube-Benutzer abgestraft, sondern der Zeitungsleser, der Wikipedia-Surfer, der Spiegel-Leser!

Da mein ursprünglicher Artikel sehr technisch und vor allem auch sehr lang geworden ist – schließlich beinhaltet er die komplette Beweislage -, möchte ich hiermit den Versuch starten, den Sachverhalt kurz und bündig dem Nicht-Techniker verständlich zu machen.

Worum geht es?

Jeder, der via T-Mobile oder via Vodafone über UMTS surft, verbraucht vielmehr an Datenübertragung als es tatsächlich nötig wäre. Volumentarife erreichen dadurch viel eher ihr Limit. Und Flatrates werden viel früher “gedrosselt” (also auf “extrem langsam” geschaltet), als es unbedingt notwendig gewesen wäre.

Als UMTS-Kunde werden Sie von Ihrem Provider bei jedem Seitenaufruf mit deutlich mehr Daten “versorgt”, also bombadiert, als es mit DSL passiert wäre!

Das wird dadurch erreicht, da T-Mobile und Vodafone die abgerufenen Internetseiten während des Übertragens manipulieren und mit (quasi unsichtbaren) Daten anreichern, die nicht immer benötigt werden (bzw. nur beim ersten Laden einer Webseite).

Warum?

Hier muss ich etwas ausführlicher werden. Internet-Seiten enthalten neben dem darzustellenden Text, den Überschriften und den Bildern auch Design-Vorgaben bzw. Layouts, die dafür zuständig sind, das eine Internet-Seite so aussieht, wie sie nun mal aussieht. Nebenher gibt es weitere “Programmdateien”, die der Seite eine erweiterte Funktionalität zur Verfügung stellen. Alle drei Bereiche, also

  1. der tatsächliche Inhalt
  2. das Design
  3. erweiterter “Programmcode” (i.d.R. Javascript)

werden normalerweise – und nach Stand aktueller Technik – in separate Dateien ausgeliefert. Der Grund hierfür liegt darin, Bandbreite zu sparen, also Ladezeit und Ladeaufwand. Denn sowohl die Design-Information als auch der Programmcode verändern sich relativ selten. Demzufolge lädt Ihr Webbrowser solche Dateien nur beim allerersten Mal vollständig und speichert sie anschließend auf dem Computer (sog. Cache).

Wenn Sie also z.B. die Seite von Spiegel Online zum ersten Mal aufrufen, werden zwar noch alle 3 Dateien geladen (oder auch mehr), aber diese werden anschließend dem Zwischenspeicher übergeben. Wenn Sie dann auf eine Überschrift klicken, oder später die aktuelle Seite erneut laden, um neue Schlagzeilen zu erhalten, muss der Browser nur noch den geänderten bzw. neuen Inhalt (also Texte, Bilder und Videos) übertragen, aber nicht mehr die Designinformation.

Nicht selten ist es so, das das Laden der Designinformation sogar noch länger dauert als das Laden der Texte, weil die Daten dafür sehr umfangreich sind.

Damit kommen wir zum eigentlichen Problem!

Mit UMTS ist alles etwas anders

T-Online und Vodafone verwenden für UMTS die Software von einer Firma namens ByteMobile. Diese Software sorgt dafür, das die Design-Information und der Programmcode bei jedem Seitenaufruf, also auch dann, wenn Sie die aktuelle Seite nur aktualisieren wollen, oder bei Spiegel Online und Co. auf eine Überschrift klicken, jedesmal erneut übertragen wird!

Dies führt unweigerlich dazu, das sie bei jedem Seitenaufruf nicht selten doppelt bzw. dreimal so viele Daten übertragen, als es notwendig wäre! Sie könnten viel eleganter, schneller und kostensparender mit Ihren UMTS-Sticks oder Ihren Smartphones surfen, wenn unsere großen Mobil-Provider von diesem Unsinn Abstand nehmen würden.

Letztendlich zerstören die Provider damit auch jeden Versuch der Inhalte-Anbieter, die Daten kostengünstig und schnell an den Endkunden zu liefern.

Eine genaue Analyse habe ich hier in diesem Blog an dieser Stelle zur Verfügung gestellt.

Warum machen die das?

Ursprünglich ging es wohl darum, eine Software einzusetzen, welche die Ladezeit von Bildern verkleinert, wenn diese auf ein Mobiltelefon via UMTS geladen werden. Damit lässt sich Netzkapazität sparen und der Kunde freut sich, wenn er nicht mehr 30 Sekunden warten muß, bis ein Bild geladen wurde.

Warum dann aber dieser technische und vor allem auch technologisch-ökonomische Unsinn betrieben wird, den ich weiter oben beschrieben habe, kann ich mir nicht erklären und alle meine Kollegen, Freunde und Chefs aus dem Informatik-Bereich ebenfalls nicht.

Wir schütteln allesamt mit dem Kopf! Natürlich kann dem Kunden somit viel mehr Volumen an Datenübertragung in Rechnung gestellt werden. Tatsächlich wird dieses Volumen aber auch geliefert! Das UMTS-Netz wird also zusätzlich belastet.

Alle Errungenschaften, die in der Web-Entwicklung während der letzten Jahre gefeiert wurden, um das Netz schlanker und schneller zu machen (wie z.B. Caching, Komprimierung etc), gelten für das deutsche UMTS-Netz scheinbar nicht. Und inzwischen sind bei mir Hinweise eingetroffen, das wohl alle deutschen UMTS-Anbieter die gleiche Software verwenden, die die übertragenen Daten verdoppelt. Ob das wirklich zutrifft, kann ich aktuell nicht bezeugen. Lediglich bei T-Mobile/Telekom und Vodafone habe ich es persönlich nachgewiesen!

Update

Die Auswirkungen für einzelne CMS-Systeme sind anscheinend viel gravierender:

http://blog.sky-bizz.com/2011/01/14/der-umts-wahnsinn-hat-noch-schlimmere-auswirkungen/

Update 2

Inzwischen konnte ich mit Technikern der Deutschen Telekom über dieses Thema telefonieren. Und zwar richtige Techniker, keine Callcenter-Leute! Die Gespräche waren sehr aufschlußreich, auch wenn wir nicht immer die gleichen Ansichten vertreten haben. Das gehört aber bei Technikern dazu. Innerhalb der nächsten Tage werde ich darüber berichten.

Update II

Mit dem Speedmanager kann man das Verhalten zumindest bei T-Mobile einstellen. Schade, das es nicht explizit kommuniziert wird.

http://www.t-mobile.de/speedmanager/0,20641,24080-_,00.html

Der Speedmanager muss laut T-Mobile über die UMTS-Verbindung aufgerufen werden, dann kann man aus 3 verschiedenen Optionen auswählen.

T-Mobile (Update: und Vodafone) manipuliert offensichtlich die Inhalte von Websites während der Übertragung, wenn diese via UMTS stattfindet. Zum Nachteil des Kunden werden mit jeder Anfrage viel mehr Daten übertragen, als dies notwendig wäre, und zwar zwischen 2x und 3x so viel als nötig (gemessen anhand von HTML, CSS und Javascript, bewußt ohne Bilder) ! Update: Inzwischen habe ich Seiten ausfindig gemacht, wo eine versechsfachung stattfindet!

(Update: bitte beachtet die neuen Updates, einfach nach fett geschriebenem Update suchen)

Nachfolgend zeige ich Beispiele für populäre Websites wie heise.de und spiegel.de (weiter unten). Ein Kommentator analysierte die vorliegenden Kenntnisse anhand von der Online-Ausgabe der  Welt (welt.de, siehe Kommentare). Auf eine Kundenanfrage vom 26.12.2010 mit Verweis auf diesen Block hat T-Mobile übrigens bis heute nicht reagiert. Update: seit dem 17.01.2010 besteht Kontakt, darüber mehr in den kommenden Tagen.

Dabei sollte man doch eigentlich eher vom Gegenteil ausgehen? Wer mobil surft, mag schlanke Websites, bei denen nur wenige Daten übertragen werden müssen, um in den Genuß der Information zu kommen. T-Mobile zerstört damit sogar die Mühe von verantwortungsbewußten Webmastern und Entwicklern, die Menge der übertragenen Daten zu reduzieren, um das Surf-Feeling gerade für schmalbrüstige Anbindungen wie UMTS smarter zu gestalten.

Was passiert bei T-Mobile UMTS? Statische Inhalte, die normalerweise im Cache landen, werden bei jedem Aufruf erneut übertragen. Caching-Systeme von Browsern werden somit umgangen. Beschleunigungs-Techniken wie der Einsatz von Amazon CloudFront und Content Delivery Networks (CDN) werden umgangen.

Einige Entwickler berichten über Darstellungsfehler und Anzeigefehler, die durch diese Umstrukturierung des Seiten-Quellcodes zustande kommen.

Alle deutschen Mobilfunker setzen für UMTS die Technologie von ByteMobile ein. Diese schalten einen sog. Proxy dazwischen, um Inhalte auf dem Endgerät komprimiert zu empfangen. Das dies in den vorliegenden populären Beispielen gründlich in die Hose geht, zeigt dieser Artikel.

Konkret: detaillierte Beschreibung

Ich habe herausgefunden, das Inhalte von CSS-Dateien und JavaScript-Dateien bei der Übertragung via UMTS von T-Mobile direkt in den HTML-Code der abgerufenen Website integriert werden und somit bei jedem (!) Request der Seite erneut übertragen werden. Statische Inhalte wie CSS-Code und Javascript können somit nicht mehr im Browser-Cache zwischengespeichert werden, um die Übertragung beim nächsten Seitenaufruf zu sparen. Es ist ein altbewährtes Mittel, Design-Informationen von Websites in eine separate, statische Datei auszulagern, um schlanke Übertragungswege zu gewährleisten. T-Mobile torpediert diese Vorgehensweise geradezu dramatisch! Außerdem werden – gemäss den Design-Guidelines von Yahoo – solche Inhalte gerne auf Content Delivery Networks ausgelagert (CDN), die darauf spezialisiert sind, derartige Inhalte schnellst möglich auszuliefern, möglicherweise auch unter Berücksichtigung des kürzesten Weges (sog. Edge Locations).

Tatsächlich klammert T-Mobile die Verwendung von CDN’s in meinen Untersuchungen (siehe unten) fast komplett aus! Ich habe nur wenige externe StyleSheet-Anbindungen und JavaScript-Files-Includes gefunden, die nicht im HTML-Body eingebettet wurden, sondern als externe Einbindung belassen wurden (was ja auch im Sinne der Entwicklers wäre).

Außerdem werden URLs für Bild-Dateien von “http://static.domain.de/bild.jpg” als “http://1.2.3.11/bmi/static.domain.de/bild.jpg” im HTML-Quellcode geliefert. Aber darauf konzentrieren wir uns erst später.

Oben drein sei gesagt, das sich der eine oder andere Web-Entwickler darüber wundert, das der UMTS-Proxy auch noch eine Javascript-Datei namens “bmi.js” einschleust! Aber das ist ein anderes, und mittlerweise auch bekanntes Thema.

Die Auswirkung in Zahlen

Folgendes konnte ich aber soeben feststellen:

Beispiel heise.de

Wenn heise.de aufgerufen wird via DSL oder von meinem Webserver aus über eine direkte Rechenzentrum-Anbindung, umfängt die reine HTML-Datei 69.362 Bytes. Dazu kommen zwar noch CSS-Files, aber die werden nur beim ersten Aufruf geladen und landen unmittelbar im Cache, sie werden also zwischengespeichert. Folglich müssen beim kommenden Aufruf normalerweise lediglich knappe 70 KBytes Daten übertragen werden.

Der gleiche Aufruf via T-Mobile UMTS liefert eine HTML-Datei mit einem Umfang von 171.702 Bytes! Und zwar kontinuierlich! Da der seitens heise.de ausgelagerte CSS-Code von T-Mobile jedesmal im HTML-Code erneut eingebettet wird, werden folglich bei jedem weiteren Seitenaufruf immer noch diese 170 KB übertragen (Abweichungen pro Artikelfülle), während via DSL nur 70 KB geliefert worden wären. Das ist eine knappe Verzweieinhalbfachung(!) der übertragenen Daten. Bei Volumentarifen kann somit das Limit viel schneller erreicht werden. Da selbst Flatrates oftmals bei 5 GB zumindest gedrosselt werden, betrifft dieser Umstand auch solche Kunden mit einer UMTS-Flatrate.

Interessant ist, das ein Aufruf via “wget” über UMTS den Original-Quellcode liefert. Lediglich der Aufruf via WebBrowser wird also von T-Mobile verändert. Dies werte ich als Hinweis darauf, das die Browser-Kennung (UserAgent) abgefragt wird.

Anbei zeige ich Screenshots vom Quelltext von heise.de einmal via WGET und einmal via Safari “geholt”:

In der Original-Version werden alle CSS- und JS-Dateien separat eingebunden und auch ausgeliefert:

Und jetzt der Original-Quelltext von heise.de, der die separaten Dateien auch als “externe” einbindet:

Dieses Bild ändert sich dramatisch, wenn der Seitenabruf via Safari oder Firefox von der gleichen Maschine via UMTS stattfindet.

Anbei der Quellcode von heise.de via UMTS:

Ein Unding aus technologischer und ökonomischer Sicht zugleich, und vor allem eine Backpfeife für die UMTS-Kunden: der gesamte CSS-Code wird direkt in die HTML-Seite eingebettet.

Es geht aber noch weiter: der Javascript-Code von Heise wird ebenfalls eingebettet. Allerdings ist T-Mobile hier geringfügig gnädig: die jQuery-Bibliothek wird weiterhin extern eingebettet und somit aus dem Cache bedient. Aber jeglicher Javascript-Code darüber hinaus wird schön sauber in den HTML-Code eingebettet:

Beispiel spiegel.de:

Viel interessanter wird es beim ehemaligen Nachrichten-Magazin:

Der Spiegel überträgt via DSL eine index.html in der Größe von aktuell 148.076 Bytes, zzgl. einer CCS-Datei mit einem Umfang von 171.454 Bytes und einer Javascript-Datei von 58.103 Bytes.  Letztere werden im Cache des Browsers abgelegt und beim zweiten Aufruf nicht erneut übertragen.

Dumm für den UMTS-Nutzer: dieser bekommt sowohl die CSS-Datei als auch die Javascript-Datei stets in der index.html eingebettet mitgeliefert, mit jedem Aufruf! Folglich werden auch beim zweiten und dritten Aufruf 293.000 Bytes übertragen, während der DSL-User mit 148 KB beliefert wird. Die ca. 140 KB große CSS-Datei wird bei jedem weiteren Seitenaufruf auf den Seiten von spiegel.de stets eingebettet mitgeliefert und kann somit nicht aus dem Browsercache bedient werden! Gleiches betrifft die Javascript-Datei! Dies bedeutet ein doppelt so hohes Volumenaufkommen beim Surfen auf spiegel.de via UMTS! Da wird eine komplette jQuery-Bibliothek mal eben in den HTML-Code eingebettet und jedesmal übertragen!

Anbei die Screenshots:

Dies ist der Original-Quellcode von Spiegel-Online (Startseite). CSS- und Javascript-Seiten gemäß alter Schule als separate Dateien includiert. Dadurch können Sie aus dem Browser-Cache bedient werden. Dies spart Übertragungsvolumen!

Nun die Variante, wie sie von T-Mobile über eine UMTS-Verbindung gesendet werden (Auszug):

Das obige Bild zeigt den Quelltext von Spiegel-Online, wenn dieser über eine UMTS-Leitung von T-Mobile übertragen wird! Der rot markierte Code wurde via T-Mobile in die HTML-Seite eingebettet. Normalerweise würde dieser Code über einen kleinen Verweis aus dem Browser-Cache bedient werden (siehe vorheriges Bild).

Opulentes Beispiel: jegliche Optimierung dank UMTS-Proxy zunichte gemacht

Wirklich sehr dramatisch wird es bei hinsichtlich der Übertragungsrate hochoptimierten Seiten! Ein sehr eindrucksvolles Beispiel ist qnopr.com.

Bei der Entwicklung habe ich darauf geachtet, die Seite so schlank wie  nur möglich zu machen.

Die eigentliche HTML-Seite für die Startseite benötigt nur 7 KB! Das (zugebenermasse sehr umfangreiche CSS) liegt auf einem CDN in Amazon CloudFront als eine ebenfalls 7.4 KB große gezippte CSS-Datei vor. Der Browser lädt also beim ersten Mal nur 14.4 KB, bei jedem weiteren Aufruf 7 KB.

Und bei UMTS via T-Mobile? 46 KB! Jedesmal! Der gezippte CSS-Code wird stets zum Nachteil aller Beteiligten in die HTML-Datei eingepackt, mit seinen gesamten unkomprimierten 36 KB!

Die von mir gewählte Variante, das CSS gezippt auf den Server zu laden, wird spätestens seit den Jahren mit dem Internet Explorer 5.5 bzw 6.0 von ausnahmslos allen verbreiteten Browsern inklusive Linux und Max bedient. Durch die Ummodellierung von T-Mobile werden die Style Sheets von qnopr.com  aber nicht mehr im stromsparenden gezippten Modus übertragen, sondern entkomprimiert in voller Länge! Das ist ein Skandal!

Jeder Aufruf von Qnopr oder ähnlich optimierter Seiten erfährt via UMTS eine verSECHSfachung der zu übertragenden Daten!

Eklatante Fehler bei UTF-8-Inhalten mit Byte Order Mark

Ein zusätzliches Problem konnte ich vor einiger Zeit mit CSS-Dateien feststellen, die auf Windows-7-Rechnern mit neuwertigen Editoren (lt. Angaben des Designers handelte es sich hierbei um Microsoft Expression Web) erstellt wurden. Diese schreiben das sogenannte BOM, das Byte Order Mark, an den Beginn der CSS-Datei, um den Zeichensatz “UTF-8″ bzw. UTF-16 anzukündigen. Der Proxy von T-Mobile (bzw. ByteMobile), der die CSS-Dateien in den Quelltext einfügen möchte, hörte zumindest noch in den Sommermonaten 2010 an dieser Stelle auf und lieferte die CSS-Inhalte gar nicht mehr aus! Ein technologisches Unding, das der Webmaster nicht verifizieren kann, solange er via DSL/LAN sonstwas ans Netz angebunden ist. Dumm, wenn dann ein Kunde anruft, sich über den schlechten Zustand seiner Website erkundigt, und dies nicht nachempfungen werden kann, solange man nicht selbst via UMTS prüft. Beweise hierfür liegen sowohl dem Autor als auch einem weiteren Web-Entwickler aus jeweils eigener Forschung vor und können auf Nachfrage ausgehändigt werden.

Update: an die mitlesenden Ingenieure der Deutschen Telekom: dieses Phänomen lässt sich auch heute noch nachweisen. Es folgen heute noch die Screenshots von einem Beispielprojekt. Korrektur: dank DSL-Problemen kann ich das erst in den kommenden Tagen nachreichen

Einer der Techniker, der mit mir zu dieser Thematik telefonierte und sich interessiert über die Bloginhalte erkundigte, reagierte auf dieses Beispiel (BOM im CSS-File) mit folgendem Satz: “Wenn man schon kaputte Dateien hochlädt, muss man sich nicht wundern, das da dann was schief geht.” Prinzipiell hat er Recht und ich stimme zu! Aber es handelte sich hierbei nicht um kaputte Dateien. Es ist scheinbar heutzutage nun einmal so, das die Windows-Welt gerne ein BOM an den Anfang der Datei packt. Dies habe ich ihm auch erklärt. Und tue dies hiermit auf schriftlichem Wege erneut.

Bilder

Bilder werden für UMTS-Anwender ebenfalls als gespiegelte Kopie aus dem Netzwerk von T-Online ausgeliefert. Hierzu wird der Quelltext entsprechend angepasst:

Beispiel auf spiegel.de:

Original-Code für die Einbettung eines Bildes:

<img width=”520″ height=”250″ border=”0″ align=”center” title=”Wachstum 2011: Ökonomen machen Deutschland Mut” alt=”Wachstum 2011: Ökonomen machen Deutschland Mut” src=”/images/image-141047-panoV9free-ymsi.jpg”>

Quellcode via UMTS:

<img width=”520″ height=”250″ border=”0″ align=”center” title=”Wachstum 2011: Ökonomen machen Deutschland Mut” alt=”Wachstum 2011: Ökonomen machen Deutschland Mut” src=”http://1.2.3.13/bmi/www.spiegel.de/images/image-141047-panoV9free-ymsi.jpg“>

Ich habe beide Bilddateien untersucht und konnte keine Unterschiede feststellen. Möglichweise liefert T-Online Bilddateien aus dem eigenen Netzwerk deutlich schneller an das Gerät als der herkömmliche Weg. Sinn würde es jetzt noch machen, die Bilddateien für das Web zu optimieren, wie es Yahoo mittels SmushIt! möglich macht. Bzgl. von Bilddaten konnte ich bisher weder eine Verbesserung noch eine Verschlechterung ausfindig machen. Zwar gibt es Hinweise aus der Community darauf, das der ursprüngliche Zweck des Proxies wohl tatsächlich die Verkleinerung von Bilddaten war. Möglicherweise liefert Spiegel die Bilder aber schon selbst optimiert genug aus. Diesen Faktor “Umbiegen von Bild-URLs” können wir also geflissentlich ausblenden. Aber der Schaden für CSS- und JS-Code ist in meinen Augen bereits enorm.

Update: nach Telefonaten mit Technikern der Deutschen Telekom weiß ich jetzt, das man das einstellen kann. Im Speedmanager von T-Mobile lässt sich u.a. die Bildkomprimierung ein- und ausschalten. Für meine SIM-Karte war die Komprimierung voreingestellt deaktiviert. Daher behielten die Bilddateien auch die gleiche Größe wie bei DSL. Aber um Bilddateien geht es hier auch nicht, sondern darum, wie mit externen CSS- und JS-Dateien umgegangen wird. Auf den Speedmanager komme ich innerhalb der kommenden Tage zurück.

Folgen

Die Folgen sind für den User teilweise dramatisch und erklären mir inzwischen einzelne Phänomene, die von UMTS-Kunden oft berichtet werden, die mit schlechtem Empfang zu tun haben: Seitenabbrüche, Übertragungsabbrüche etc. Dazu gleich mehr.

Viel schlimmer dürfte die Auswirkung auf Kunden mit Volumentarife sein. Die 250 MB bspw. sind somit – je Surfverhalten – viel schneller erreicht, als sie erreicht werden dürften. Auch Flatrate-Kunden tragen Schaden: schließlich sind die meisten (oder gar alle?) UMTS-Flatrates ab einem gewissen Volumen gedeckelt (sehr häufig bei 1 bzw. 5 GB), sprich: sie werden gedrosselt und mit einer Übertragungsrate bedient, die an die 90er Jahre erinnert.

UMTS-Kunden in Gebieten mit schlechtem Empfang werden ebenfalls mit der oben beschriebenen Taktik äußerst benachteiligt!

Wenn jedesmal der CSS- und Javascript-Code als erstes übertragen wird, und erst dann der eigentliche Text, also die Information, der Website, so können keine Inhalte dargestellt werden, wenn “unterwegs” die Übertragung abbricht. CSS und JS wurden zwar geladen, aber keine “Texte”.

Würde T-Mobile die Finger von den Daten lassen und sie neutral, also 1:1 so übertragen, wie es sich die jeweiligen Entwickler von Content Management Systemen und Blogsystemen etc. ausgedacht haben, so würde beim zweiten Seitenaufruf der CSS-Code bereits geladen sein. Folglich würden die eigentlich darzustellenden Inhalte direkt als erstes im Stream geliefert werden. Ein möglicher Erfolg bei schlechter Verbindung besitzt so eine viel höhere Wahrscheinlichkeit, als wenn zu Beginn des Streams immer nur Balast geliefert wird (welcher noch dazu ab 2. Aufruf überflüssig ist).

Außerdem konnte ich feststellen, das Änderungen an den grundlegenden CSS-Dateien nicht nur den Browser-Cache renewen müssen, sondern auch noch den UMTS-Cache von T-Mobile passieren (IP-Adresse via UMTS 1.2.3.X). Somit wirken sich Änderungen laut meiner Erfahrung an diesen Dateien erst verzögert aus. Der einzige Umweg ist hier vermutlich, die CSS-Datei umzubennen oder eine parametrisierte Versionskennung anzuhängen (ungetestet).

Größere Probleme gibt es mit der Byte Order Mark (siehe weiter oben). Hier ergeben plötzlich frühere Anrufe von Kunden einen Sinn, die ein total zerrissenes Abbild der Website erhalten, die der Webdesigner mit seiner DSL-Leitung nicht verifizieren kann.

Update: Kolateralschaden auf breiter Fläche bei modernem Webdesign

Spätestens seit Kalifornien und Web 2.0 hilft folgendes Muster den hochfrequentierten Websites, ihren Traffic zu minimieren: die Style Sheets werden zunächst via CSS-Komprimierer zusammengefasst und gekürzt. Anschließend werden sie, bei jedem Deployment, gezippt und mit dem Encoding-Type “gzip” auf ein CDN geladen. Alle modernen Browser können damit umgehen und CSS sowie Javascript auch als gezippte Datei laden! Damit verringert sich das Übertragungsvolumen nicht selten um den Faktor 6 bis 8!

Um diesen Komfort zu erhalten und an die Kunden weiterzugeben, sind Deployment-Verfahren notwendig, die über das übliche “Datei hochladen” weit hinausgehen.

T-Mobile’s UMTS-Proxy verdirbt diesen Aufwand konsequent und erstklassig! Anstatt nur die 10 KB beispielsweise zu laden, die die Entwickler diverser Sites vorbereitet haben, werden jedesmal 70-80 KB übertragen, unkromprimiert im Klartext. Hier sind bereits zwei Greueltaten benannt: “jedesmal” und “entkomprimiert”.

Je weiter sich aber diese Technologien verbreiten – und das wachsende Web hat keine andere Möglichkeit zur Zeit – umso dramatischer wird es sich hier auswirken, wie T-Mobiles UMTS dem Fortschritt entgegen wirkt!

Für die mitlesenden Techniker der Deutschen Telekom möchte ich folgende Beispiel-Seite benennen: http://www.qnopr.com

Update: der User Agent entscheidet tatsächlich!

Wer UMTS-Bandbreite sparen will, sollte via Firefox surfen und sich das Plugin “User-Agent Switcher” installieren. Wenn man dort dann z.B. einen User-Agent einstellt, den T-Mobile nicht kennt (Googlebot genügt, oder WGET), der erhällt die Daten 1:1 so übertragen, wie der Webserver die Inhalte normalerweise auch ausliefert.

Wichtig ist dies für Webdesigner, die via UMTS mit Firebug nach Styles schauen wollen, um diese ggf. zu editieren. Da T-Mobile den CSS-Code komplett neu arrangiert in die HTML-Datei einbettet, gibt es natürlich keine genauen Angaben mehr, welcher Style aktuell pro Element wirkt und aus welcher Ursprungs-Datei dieser kommt.

Das Ändern des User-Agents hat natürlich unter Umständen eine Nebenwirkung: der Webserver als solcher könnte entsprechend konfiguriert worden sein, das er dann selbstätig andere Inhalte liefert. Außerdem gibt es Konfigurationen, die “ungültige” Browser-Kennungen – also solche, die nicht bekannt sind – abgewiesen werden. Daher ist dieser Vorschlag aktuell nur eine Notlösung, die nicht allumfassend gilt!

Abhilfe

Twitterer “Rokory” weisst darauf hin, das sich der o.g. Proxy mittels APN “noproxy” deaktivieren lässt. Genauere Hilfen hierzu findet man auf dieser Seite.

Update: unter der Adresse speedmanager.t-mobile.de lässt sich einstellen, ob eine Optimierung stattfinden soll oder nicht, und wenn ja, welche. Ich werde darauf genauer eingehen während der nächsten Tage

Frohe Weihnachten wünscht Hagen

Update:

Ich verweise auf diesen Artikel, wo vor allem Content Management Systeme davon betroffen sind: http://blog.sky-bizz.com/2011/01/14/der-umts-wahnsinn-hat-noch-schlimmere-auswirkungen/

Update:

Techniker der Deutschen Telekom haben mich auf den Speedmanager von T-Mobile aufmerksam gemacht: T-Mobile Speedmanager.

Dort kann man als Kunde einstellen, ob man mit dieser “Optimierung” seitens der Provider arbeiten möchte oder nicht. Da es sich laut meinen Experimenten aber um keine Optimierung handelt, habe ich sie deaktiviert. Dann werden Websites auch wieder nativ übertragen, wie es sich die Webseitenbetreiber gedacht haben.

Schade nur, das niemand den Speedmanager kennt. Alle Mitwirkenden an dieser Artikelreihe waren ganz verblüfft, als wir vom Speedmanager seitens Telekom erfuhren. Diese Information wurde mir übrigens nicht an der Hotline zu teil, sondern mit einem Telefonat mit “richtigen” Technikern der Telekom.

Reaktionen

Als erster UMTS-Anbieter reagierte Vodafone über deren Facebook-Seite. Ehrlich gesagt, überraschte es mich auch nicht. Wer so öffentlich gefragt wird, muss reagieren. Bei T-Mobile bzw. Telekom durchläuft man da erstmal alle Instanzen des Kundensupports.

Siehe hier:

Das kam heute von der Telekom:

> vielen Dank für Ihre E-Mail.
>
> Wir möchten schnell für Sie tätig werden, brauchen hierfür
> allerdings noch einige Informationen. Bitte ergänzen Sie in
> dieser E-Mail folgende Angaben und senden diese an uns
> zurück.
>
> Vorname Name (Anschlussinhaber/in):
> Telefonnummer mit Vorwahl:
> Kundennummer:

Anschließend wurden noch Hinweise aufgeführt, wo ich die Kundennummer finden würde.

Danke Telekom! Ihr habt den Text also gelesen. Ganz bestimmt!

Vodafone reagierte wie folgt:

Hallo Hagen,

vielen Dank für diesen wirklich aufschlussreichen Artikel. Wir werden das beschriebene Problem genau prüfen lassen. Letztlich würden wir ja unser Netz dadurch mit viel unnötigem Traffic blockieren, was defintiv nicht gewollt ist….

Dein Vodafone Deutschland Team

Das nenne ich mal Support! Um das einmal klarzustellen: ich bin weder Vodafone-Kunde, -Aktionär, -Mitarbeiter etc. Ich war mal lange Vodafone-Kunde und wollte keiner mehr sein, und brauchte leider auch etliche Jahre, um keiner mehr zu sein (das ist eine andere Geschichte). Aber als Telekom-Kunde muss ich sagen: bei Vodafone arbeiten entweder schlauere Leute an der Stelle, wo man Kundenbeschwerden aufnimmt, oder hat modernere Strukturen. So ein Rückläufer wie von der Telekom “Bitte nennen Sie uns ihre Kundennummer” ist ja wohl in solchen globalen Angelegenheiten absoluter Nonsens!

Meine Antwort lautet:

Sehr geehrte Damen und Herren

ich habe sehr viel Zeit und Mühe aufgebracht, um ein “globales” Problem bei der von Ihnen eingesetzten UMTS-Proxy-Software zu analysieren. Hin und wieder kamen mir Zweifel darüber auf, warum nicht Ihre Ingenieure bereits hinter dieses Problem gestiegen sind!

Viel schlimmer aber ist: Sie haben sich entweder nicht die Mühe gemacht, mein Anliegen sorgfälltig zu lesen bzw. an adäquate Stelle weiterzuleiten, oder haben den Sachverhalt nicht verstanden.

Es handelt sich hierbei NICHT um ein lokales Kundenproblem, das von der Kundenhotline bearbeitet werden kann. Demzufolge benötigen Sie weder eine Kundennummer noch meinen Namen (der übrigens in der Email stand und weltweit eindeutig ist). Es betrifft JEDEN Telekom-Kunden, der UMTS nutzt! Und es betrifft auch jeden Vodafone-Kunden. Dies ist in meinem Artikel ausführlich belegt.

Ihr Konkurrent Vodafone hat auf der hauseigenen Facebook-Seite angekündigt, dem Problem auf die Spur zu gehen, ohne nach Kundennummer etc. zu fragen. Dort hat man meinen Text gelesen und ihn entsprechend zur Kenntnis genommen. Und zwar wie folgt:
“Vielen Dank für diesen wirklich aufschlussreichen Artikel. Wir werden das beschriebene Problem genau prüfen lassen.”

Also: leiten Sie meine untenstehende Anfrage bitte an Ihre Ingenieure weiter.

Ihre Ingenieure dürfen mich für Fragen gerne telefonisch kontaktieren:****-******** .

Mit freundlichen Grüßen

Mal schauen, was draus wird. Vielleicht kann sich ein Callcenter-Mitarbeiter bei der Telekom doch dazu überwinden, meine Email direkt nach intern weiterzuleiten ohne erstmal die üblichen 20 Callcenter-Fragebögen auszufüllen….

Update

Mit dem Speedmanager kann man das Verhalten zumindest bei T-Mobile einstellen. Schade, das es nicht explizit kommuniziert wird.

http://www.t-mobile.de/speedmanager/0,20641,24080-_,00.html

Der Speedmanager muss laut T-Mobile über die UMTS-Verbindung aufgerufen werden, dann kann man aus 3 verschiedenen Optionen auswählen.

Das Has-Pattern

Möglicherweise hat dieses Pattern bereits einen anderen Namen, oder es ist gar nicht erwähnenswert genug, um einen Namen zu erhalten.
Dennoch werde ich immer mehr ein Freund davon.

Als HasPattern verstehe ich Functions oder Properties, die eine Abfrage der Form “sind Elemente der Form X verfügbar” darstellen. Der Name des Patterns leitet sich aus dem Präfix der Methoden ab, den sich alle diese teilen: “HasItems”, “HasClients”, “HasListItems” etc.

Beispiel:

Gegeben ist ein Objekt “Employer” (Arbeitgeber), das eine Auflistung von Angestellten enthält:

C#:

public class Employer {
    public IEnumerable Employees() {
        return …;
    }
}

PHP:

class Employer {
    public function Employees() {
        return $this->employees;
    }
}

Nun besteht oftmals nicht nur die “Herausforderung”, alle Angestellten des Arbeitgebers zu durchsuchen, oder die Anzahl der Angestellten auszugeben. Nicht selten will ein Entwickler einfach nur wissen: “HAT dieser Arbeitgeber überhaupt Angestellte?”

Viel zu häufig bin ich über Code gestolpert, der einfach die Anzahl der Elemente in einer Auflistung auswertet. Ist count > 0, hat der Arbeitgeber offensichtlich angestellte:

C#:

Employer emp = …;
if(emp.Employee.Count() > 0) {
    // dieser Arbeitgeber hat Angestellte
} else {
    // dieser Arbeitgeber hat keine Angestellte
}

PHP:

$emp = $this->getEmployerById(42);
if( count($emp->Employees()) {
    // dieser Arbeitgeber hat Angestellte
} else {
    // dieser Arbeitgeber hat keine Angestellte
}

Dieser Weg ist so unelegant wie nur möglich. Letztendlich werden alle Elemente durchgezählt, nur um herauszufinden, ob mindestens ein Element vorhanden ist. Richtig?
Tatsächlich kann das Zählen aller Elemente einer Auflistung richtig teuer sein! Natürlich, die List-Klasse vom .NET-Framework oder PHP’s Arrays wissen, wie viele Elemente sie aktuell verwalten. Bei abstrakteren Datenhaltungsstrukturen sollte davon aber nie ausgegangen werden!

Die LINQ-Extensions von .NET z.B. bieten zwar die tolle Methode Count() als Erweiterung zu allen IEnumerables. Diese zählt aber tatsächlich alle Elemente einzeln durch, in dem es via GetEnumerator() den zugehörigen Enumerator holt und dort mit MoveNext() durch alle Elemente iteriert und dabei eine Variable hochzählt. Diese enthält das Ergebnis von Count().

Richtig gefährlich werden kann es bei OR-Mappern: wenn hier dank Lazyloading erst noch Elemente nachgeladen werden – und zwar ALLE -, bekommen die Entwickler nach der Markteinführung richtig Freude.

Natürlich ist es ein schlechter OR-Mapper, der erstmal alle Datensätze lädt, um diese zu zählen. Aber als Konsument derartiger Strukturen wollen wir uns nicht auf die Implementierung selbiger verlassen, sondern ganz smart mit der Schnittstelle kommunizieren.

Darüberhinaus, rein vom sprachlichen und dokumentatorischen her, bietet es sich in meinen Augen an, einer solchen Auflistungs-Methode gleich noch eine Has-Methode zu spendieren:

C#:

public class Employer {
    public IEnumerable Employees() {
        return …;
    }

    public bool HasEmployees() {
    return … // true/false/Employees.Any() etc.;
    }

}

PHP:

class Employer {

    public function getEmployees() {
        … ///
    }

    public function hasEmployees() {
    }

}

WIE die Methode “hasEmployees” nachher implementiert ist, spielt keine Rolle und ist uns als Konsument dieser Klasse egal. Tatsächlich gegen wir davon aus, das die Entwickler der Klasse Employer den besten und performantesten Weg kannten und entsprechend implementiert haben.

Wie ließt sich denn der daraus folgende Code?

Ließt sich
     “if($employer->hasEmployees) echo “(*)”;”

nicht auch besser als

    ”if( count($employer->getEmployees()) > 0) echo “(*)”" ?

In ersterem Fall wissen wir direkt, was der Entwickler wirklich wissen will. Und was er nicht wirklich wissen will. Er muss nicht die tatsächliche Anzahl der Employees wissen. Er will nur wissen: ist mindestens einer vorhanden?

Der aufmerksame Leser wird zumindest im .NET-Bereich an die Linq-Methode “Any()” erinnern wollen. Sie ist relativ stromsparend implementiert, in etwa so:

public bool Any(this IEnumerable items) {
    foreach(var item in items) {
        return true;
    }
    return false;
}

Aber auch hier setzen wir wieder auf eine “fremde” Implementierung von “außen”, die das Konstrukt, das sich hinter “items” befindet, nicht kennt. Es wird der Enumerator zu items erzeugt, falls noch nicht vorhanden, und wir verwenden diesen nicht zum enumerieren, sondern zum Auswerten.
Auch hier finde ich es charmanter, direkt auf eine “hasItems”-Methode zurückgreifen zu können, die eventuell sogar intern performanter ausgewertet werden kann, z.B. durch die Zurückgabe einer boolschen Variable, die zu einem Zeitpunkt gesetzt wird, an dem das Objekt definitiv weiss, ob es entsprechende Unterlemente bzw. Detailobjekte enthält oder nicht.

If you need to convert all tables of a database from MyISAM (or somewhat else) to InnoDB, you can use the following Shell-Skript (Download-Link ):

#!/bin/sh

for tbl in `cat tables`
do
echo “ALTER TABLE \`$tbl\`  ENGINE = InnoDB ”
done

Please take care! Backup your database first!

Now we want to create a list containing all Tables of a specified database. At shell prompt, execute the following line:

mysql -uUSER -pPASSWD -D DATABASE_NAME -e ‘SHOW TABLES’ > tables

To process all tables, type in the following command into shell prompt:

mysql -uuser -ppasswd -D database < `convert_to_innodb.sh`

Thats all.

ShareThis.com – ein Bug nach dem anderen

Sharethis.com – den Button kennt ja inzwischen fast jeder. Ein Klick, und man postet die aktuelle URL des Browsers direkt in einen der hunderten Web-2.0-Dienste.

Heute wollte ich für eine Site mal wieder einen Sharethis.com-Button erstellen. Geht nicht! Ein Bug nach dem anderen!
Continue reading…

Native Typ-Erweiterung in C#

Seit C# 3.0 können DotNets eingebaute native ValueTypes wie int, string und double um neue Methoden erweitert werden, ohne die Definition der zugrundeliegenden Klassen ändern zu müssen. Diese sogenannten Extension-Methoden können so aufgerufen werden, als währen sie Member-Methoden der Klasse. Ähnliche Konzepte sind mir mal bei Ruby über den Weg gelaufen. Natürlich kann dieses Verfahren auch auf eigene Typen angewandt werden. Extension Methods sind nicht auf eingebaute Typen beschränkt.

Beispiel:

Wir wollen den eingebauten Typ “Integer” um eine Methode “sqr” erweitern, die das Quadrat des Wertes ermittelt und zurück gibt. Die Notwendigkeit dieses Beispiels sei einfach mal dahin gestellt. Es ist lediglich ein Beispiel:

public static class IntErweiterung
{
public static int sqr(this int i)
{
return i * i;
}
}

Mit dieser statischen Klasse wird folgendes möglich:

Console.WriteLine(20.sqr()); //  400
int x = 5;
int y = x.sqr();
Console.WriteLine(y); // 25

Hier stellt sich mir die Frage, warum es dann das Schlüsselwort sealed gibt, mit dem man eine Klasse versiegeln kann, um zu verhindern, das sie überschrieben wird. Vermutlich liegt der Unterschied zwischen der Verberung von Klassen und der Erweiterung via Extension Methods darin, das Extension Methods nur auf öffentliche Member zugreifen können. Damit wäre dann der Sinn einer versiegelten Klasse auch wieder hergestellt.

Probieren wir es einfach mal aus:

public class test
{
int m_i;
public test(int i)
{
m_i = i;
}
 
}
 
public static class testExtension
{
public static int getI(this test i)
{
return i.m_i;
}
}

Wir versuchen hier, die Klasse test um die fehlende öffentliche Methode “getI” zu erweitern, die den privaten Member “m_i” zurück geben soll.

Der Compiler sagt: “Der Zugriff auf “linqtest.test.m_i” ist aufgrund der Sicherheitsebene nicht möglich.

Na dann ist die Weltordnung wieder hergestellt. Extension Methods können die Architektur einer Software zumindest dann ein wenig vereinfachen, wenn ein Wrapper oder ein Adapter geschrieben werden müsste, um eine bestehende nicht-vererbbare Klasse um neue Methoden zu erweitern.

Die Privacy bzw. die Integriät einer Klasse bleibt also gewährleistet. Extension Methods können nur auf öffentliche Member zugreifen und können u.a. dazu benötigt werden, DesignPatterns wie Adapter wieder aufzulösen (wenn man dies denn möchte).

Lambda und LINQ

Eine der großartigen Neuerungen im Sprachumfang von C# bzw. .NET 3.5 sind Lambda und LINQ.

Lambda erinnert mich einerseits an DEFINES von Ansi C, und andererseits an die sog. “Functors” von C++ und wurden hier vermutlich auch abgeguckt. Dennoch wurde Lambda integrativer gelöst, da ein Lambda-Ausdruck direkt innerhalb des Codes erfolgen kann, wo er benötigt wird. C++ – Functors wurden bzw werden i.d.R. als separate Klassenrümpfe mit einem überladenen operator() definiert.

Ein Lamda-Ausdruck sieht zum Beispiel so aus:

Func<int , int> sqr = x => x * x;
Console.WriteLine(sqr(10)); // Result: 100
</int>

LINQ (Abkürzung für Language INtegrated Query) ist eine Komponente von Microsofts .NET-Framework, mit der SQL-, XLink- und XQuery-Anfragen direkt in .NET-Programmiersprachen wie C# 3.0 oder VB.Net 9.0 als Code statt als String eingebunden werden können. LINQ wurde federführend von Turbo-Pascal- und C#-Autor Anders Hejlsberg entwickelt.

LINQ erweitert C# u.a. um direkte Selektion von Datenmengen innerhalb des Codes. Es wird keine Query in String-Form abgesetzt, sondern unmittelbar in dem Code integriert.

Am besten erklärt sich LINQ ein einem kleinen, konkreten Beispiel:

string[] names = { "Faust", "Peter", "Tom", "Fred", "August" };
var foundNamesAsQuery = from s in names
                        where s[0] == 'F'
                        select s;
foreach (string name in foundNamesAsQuery) Console.WriteLine(name);
// Result: Faust, Fred

Wenn LINQ schon in einer SQL-Syntax Datenmengen selektieren und filtern kann, unterstützt es dann auch Sortierungen à la “ORDER BY”? Mal gucken:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace linqtest
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] names = { "Faust", "Peter", "Tom", "Fred", "August" };
            var foundNamesAsQuery = from s in names
                                    where s[0] == 'F'
                                    orderby s descending
                                    select s;
            foreach (string name in foundNamesAsQuery) Console.WriteLine(name);
            Console.ReadLine();
 
        }
 
    }
}

.NET-Betrachtungen

Nach Jahren aktiv gelebter Windows-Ignoranz habe ich mich in den letzten Wochen wieder verstärkt mit Microsofts Windows .NET beschäftigt. Re-Angefixt wurde ich vor allem durch Mono 2.0 , der platformunabhängigen Implementierung von GNOME-Mitbegründer Miguel de Icaza, welche vor kurzem veröffentlicht wurde.

Ich muss ganz ehrlich zugeben, das ich ziemlich erstaunt war über die Weiterentwicklung von .NET. Zu “meiner Zeit” schrieb man die Version 1.1. bzw 2.0.  Inzwischen sind die Jungs bei 3.5 angekommen. Man möge mich jetzt steinigen (Anm.d.Red.:ich werde auch vorläufig nicht mein Linux von der Notebook-Platte putzen),
Continue reading…