El tipo de datos GUID existe, y es una opción a la hora de crear un campo, en sistemas gestores de bases de datos como SQL Server, pero, cosas de la ignorancia, nunca había pensado que pudieran ser una opción razonable para identificar una fila en una tabla.
Sin embargo, recientemente me he topado con una aplicación en la que, observando su base de datos, se utilizaban como identificadores únicos de registro valores de tipo GUID, lo cual me ha llamado la atención y me ha llevado a profundizar un poco en el tema.
Pero, ¿qué es un GUID? Según su definición formal, se trata de una implementación del estándar UUID (Universally Unique Identifier, Identificador Unico Universal), promovido por la OSF (Open Software Foundation), que propone un método de identificación única ideal para entornos distribuidos en los que no existe un coordinador central. En otras palabras, permite que nodos dispersos puedan establecer identificadores de forma única a entidades o unidades de información de forma que se pueda asegurar razonablemente que no van a existir duplicidades en los mismos, y todo ello sin necesidad de crear un punto común de comprobaciones.
A efectos prácticos, un GUID es un número de 16 bytes, o 128 bits, escrito habitualmente en forma de chorizo hexadecimal del tipo "550e8400-e29b-41d4-a716-446655440000", generado utilizando algoritmos pseudoaleatorios.
Pero diréis que un algoritmo pseudoaleatorio no garantiza su unicidad, y es cierto. Sin embargo, 16 bytes ofrecen un universo de 2128 valores posibles (del orden de 3·1038), lo que hace prácticamente imposible que dos GUID se repitan.
Esto los hace especialmente atractivos como identificadores únicos: registros en bases de datos, identificación de componentes (como COM o DCOM), registro de documentos, artículos, posts y un largo etcétera.
Publicado por José M. Aguilar a las 2:10 p. m.
Etiquetas: bases de datos, microsoft, programación, tecnología
List<Algocomplejo> listaDeCosas =
new List<Algocomplejo>();
Bueno, no pasa nada. Aunque la clase sea genérica, clase es. Esto implica que podemos hacer uso de la herencia para aclarar un poco el código:
public class ListaCompleja: List<Algocomplejo>
{
}
A partir de este momento, la instanciación quedaría más limpia:
ListaCompleja lista = new ListaCompleja();
A todos los efectos, este truco tan simple hace que podamos trabajar con clases genéricas con un código fuente similar al de siempre, sin "<" ni ">" que, por lo menos a mí, despistan tanto.
Esto puede resultar extremadamente útil a la hora de programar clases genéricas, capaces de implementar un tipado fuerte sin necesidad de conocer a priori los tipos para los que serán utilizadas. ¿Confuso? Mejor lo vemos con un ejemplo.
Sabemos que un ArrayList es un magnífico contenedor de elementos y que, por suerte o por desgracia, según se vea, trabaja con el tipo base object. Esto hace que sea posible almacenar en él referencias a cualquier tipo de objeto descendiente de este tipo (o sea, todos), aunque esta ventaja se torna inconveniente cuando se trata de controlar los tipos de objeto permitidos. En otras palabras, nada impide lo siguiente:
al.Add("Siete caballos vienen de Bonanza...");
al.Add(7);
al.Add(new String('*', 25)); // 25 asteriscos
Esto puede provocar errores a la hora de recuperar los elementos de la lista, sobre todo si asumimos que los elementos deben ser de un determinado tipo. Y claro, el problema es que el error ocurriría en tiempo de ejecución, cuando muchas veces es demasiado tarde:
foreach (string s in al)
{
System.Console.WriteLine(s);
}
Efectivamente, se lanza una excepción indicando que "No se puede convertir un objeto de tipo 'System.Int32' al tipo 'System.String'". Lógico.
Algunos de los que hayáis sido capaces de superar el test FizzBuzz en menos de media hora ;-) podríais decir que eso se puede solucionar fácilmente, que existen al menos dos maneras de hacerlo: crear nuestra propia colección partiendo de CollectionBase o similares y mostrar métodos de acceso a los elementos con tipado fuerte, o bien, usando delegación, crear una clase de cero que implemente interfaces como IEnumerable en cuyo interior exista una colección que es la que realmente realiza el trabajo.
En cualquier caso, es un trabajazo. Por cada clase que queramos contemplar deberíamos crear un engendro como el descrito en el párrafo anterior.
Y aquí es donde los generics entran en escena. El siguiente código declara una lista de elementos de tipo AlgoComplejo:
List<AlgoComplejo> listaDeCosas =
new List<AlgoComplejo>();
listaDeCosas.Add(new AlgoComplejo());
listaDeCosas.Add("blah"); // Error en compilación
Con esta declaración, no será posible añadir a la lista objetos que no sean de la clase indicada, ni tampoco será necesario realizar un cast al obtener los elementos, pues serán directamente de ese tipo.
Es interesante ver la gran cantidad de clases genéricas para el tratamiento de colecciones que incorpora el Framework 2.0 en el namespace System.Collections.Generic.
¿Y si queremos nosotros crear una clase genérica? Pues muy sencillo. Vamos a desarrollar un ejemplo completo donde podamos ver las particularidades sintácticas y detalles a tener en cuenta. Crearemos la clase CustodiadorDeObjetos, cuya misión es almacenar un objeto genérico y permitirnos recuperarlo en cualquier momento. Básicamente, construiremos una clase con una variable de instancia y un getter y setter para acceder a la misma, pero usaremos los generics para asegurar que valga para cualquier tipo y que el objeto introducido sea siempre del mismo tipo que el que se extrae.
public class CustodiadorDeObjetos<Tipo>
{
private Tipo objeto;
public Tipo Objeto
{
get { return objeto; }
set { this.objeto = value; }
}
}
El siguiente código muestra la utilización de nuestra nueva clase:
CustodiadorDeObjetos<string> cs = new CustodiadorDeObjetos<string>();
cs.Objeto = "Hola"; // Asignamos directamente
string s = cs.Objeto; // No hace falta un cast,
// objeto es de tipo string
// en esta clase.
cs.Objeto = 12; // Error en compilación,
// no es string
Pero no sólo es eso, los generics dan mucho más de sí, pero de esto seguiremos hablando otro día, que ya es tarde.
Habitualmente se trata de personas con titulaciones medias o superiores, cierta experiencia previa y un conocimiento de tecnologías de programación, al menos en teoría, relativamente alto, perfectamente capaces de mantener una conversación sin soltar barbaridades destacables.
Y lo más increíble de todo es una de las técnicas que usan para "filtrar" el personal en las entrevistas de selección: el "test FizzBuzz". La prueba consiste en solicitar a los candidatos:
Escribir un programa que imprima los números del 1 al 100. Sin embargo, hacer que en los múltiplos de tres se imprima la palabra "Fizz" en vez del propio número, y en los múltiplos de cinco se imprima "Buzz". Para aquellos números múltiplos de tres y cinco simultáneamente, se debe imprimir "FizzBuzz".
Si piensas que esta prueba es una chorrada, atento a las conclusiones que sacan los que la han puesto en práctica. La mayoría de los graduados, ingenieros, diplomados en informática no pueden hacerlo. Incluso muchos auto-proclamados programadores expertos tardan más de diez minutos en escribir una solución.
No sé si se trata de una exageración, pero en realidad se toca un tema muy espinoso y cierto como la vida misma: la falta de preparación de los futuros (y algunos actuales) programadores.
Y está claro que una de las medidas a tomar, desde el punto de vista de una empresa, es reforzar las pruebas y criterios de selección de su personal. No sé si el "FizzBuzz" es la solución, pero sin duda es un buen ejemplo: intentar conocer al candidato, sus habilidades y limitaciones básicas puede ayudar a descartar tarugos que pululan por el ciberespacio y han anidado masivamente en sitios web de ofertas de empleo. De esta forma, se evitará que entren en casa.
Pero el origen del problema es anterior a todo esto. ¿Qué se está enseñando en los centros de formación? ¿Qué nivel se exige a los estudiantes? ¿Existe todavía vocación en esta profesión?
Preocupante, ¿no?
Recordemos que los contenidos textuales se presentan en las imágenes mezclados con figuras y fondos que complican enormemente su detección automática. Si a la dificultad de detectar texto en esta maraña binaria se une que el mensaje está troceado en varias imágenes, las cuales se maquetan y posicionan después para que la lectura tenga sentido, esto se convierte en una labor prácticamente imposible.
Observad este ejemplo. El mensaje"Viagra" ha sido dividido en 6 imágenes, que se maquetan de forma consecutiva; prácticamente ninguna de ellas contiene texto que pudiera ser detectado por un OCR, y sin embargo se puede leer perfectamente.
Es posible que la solución a este problema sea intentar renderizar (¡uuf, vaya verbo, menos mal que la Wikipedia lo incluye!) el contenido de los mensajes, incluyendo sus imágenes, y someter el resultado a un OCR, de forma que si existen textos queden al descubierto. Sin embargo, además de la tremenda potencia de cálculo que hace falta para procesar en tiempo real esta información, sería fácil esquivarlo incluyendo secuencias animadas, como ya se comentó en un post anterior.
Si encuentro alguna solución brillante al problema, os la cuento. ;-)
Sí, y no estoy hablando de incluir personajes de la Warner en los mensajes. Se trata de enviar a los destinatarios mensajes con archivos gráficos (normalmente gifs) que contienen varios frames que, siendo visualizados de forma consecutiva, dan la sensación de movimiento, como si se tratase de una película.
Habitualmente, los primeros frames van en blanco, o con elementos de ruido para despistar a las herramientas OCR, que, parece ser, en un principio asumían que el archivo a rastrear sólo contenía una imagen. Los frames siguientes van componiendo el mensaje de forma sucesiva, a veces entremezclando los textos con píxeles y líneas de ruido.
También escuché hace tiempo que esto mismo se utilizaba para enviar spam con mensajes subliminales, que se servían de GIFs animados para mostrar durante un lapso de tiempo prácticamente imperceptible el texto describiendo el producto a vender... Esto, a diferencia del resto de técnicas que comento en los posts, no lo he visto nunca con mis propios ojos; no sé si es porque soy demasiado lento y mi subconsciente es incapaz de asimilar estos mensajes, o bien debido a que nunca he recibido un mensaje de este tipo.