Záludný komparátor
Řečeno s Freudem: Kdo tvrdí, že nikdy nevytvořil SortedSet s Comparatorem, který byl nekonzistentní s equals metodou porovnávaných objektů, ten je tvoří dodnes.
A já pořád, kde se mi ty objekty ztrácejí…
Social engineering ve velkém
Zdá se, že legrační phishingové maily a podvržené stránky stránky vydávající se za komunikační kanály České spořitelny jsou součástí sofistikované akce, jak ukolébat ostražitost klientů a vsugerovat jim, že nebezpečné maily se poznají leda podle oslovení “Drahoušek Zákazník” a dotazu na “Skonání Datle”.
Tomu odpovídá poslední výkřik módy — zcela nevinně působící a k ničemu nevyzývající e-mail může mít jediný záměr: nahlodat ostražitost uživatelů a přivyknout je dojmu, že nevyžádané e-maily od jejich banky jsou něčím zcea normálním.
Skutečně umíme měřit, jak dlouho lidé setrvají na webových stránkách
Daniel Dočekal klade řečnickou otázku, a jak to u řečnických otázkách bývá, rovnou připojuje negativní odpověď — cituji: "jediné co totiž [Navrcholu] ví, je že někdo někam přišel. A pak už nikam neodešel".
Navrcholu to možná neumí (proč?), technicky lze tuto dobu velmi dobře aproximovat za předpokladu, že při čtení stránky uživatel tu a tam zaroluje či pohne myší (schválně si to vyzkoušejte na sobě).
Třeba takto:
/**
* a simple reading time tracking utility
*
* @author Pavel Kolesnikov
*/
var Tracker = function(cfg) {
var TIMEOUT = 3000; // 3 seconds
var config = cfg ? cfg : {};
var mouseLogging = 1;
var keyboardLogging = 1;
var lastActivity;
var total = 0;
var saveMessage = config.saveMessage;
function logActivity() {
var now = new Date();
var sinceLastActivity = now.getTime() - lastActivity.getTime();
if (sinceLastActivity > TIMEOUT) {
sinceLastActivity = TIMEOUT;
}
total += sinceLastActivity;
lastActivity = now;
}
function logActivityMouse() {
if (mouseLogging) {
logActivity();
}
}
function logActivityKeyboard() {
if (keyboardLogging) {
logActivity();
}
}
this.stopMouseLogging = function() {
mouseLogging = 0;
};
this.startMouseLogging = function() {
mouseLogging = 1;
};
this.stopKeyboardLogging = function() {
keyboardLogging = 0;
};
this.startKeyboardLogging = function() {
keyboardLogging = 1;
};
function createXMLHttpRequest() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else if (window.ActiveXObject) {
return new ActiveXObject('Microsoft.XMLHTTP'
} else {
return null;
}
}
function postLog(params) {
var ajax = createXMLHttpRequest();
if (ajax) {
ajax.onreadystatechange = function() {};
}
ajax.open('POST', config.o, true);
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
ajax.setRequestHeader("Content-length", params.length);
ajax.setRequestHeader("Connection", "close");
ajax.send(params);
}
function write() {
var params = "u=" + config.u + "&i=" + config.i + "&t=" + total
+ "&r=" + document.referrer;
postLog(params);
}
this.write = write;
lastActivity = new Date();
document.onmousemove = logActivityMouse;
document.onkeypress = logActivityKeyboard;
window.onunload = write;
}