Sabias que Java posee una clase Void

Hacía mas de 2 años que quería hacer este post, porque me parece algo bastante curioso. De hecho fue en el 2012 que me enteré de la existencia de la clase java.lang.Void pero lo verdaderamente interesante es que esta clase existe desde la versión 1.1 del jdk.

De acuerdo a la documentación de la API “La clase Void es un comodín para almacenar una referencia a objetos de clases representando la palabra clave void.”

A continuación un ejemplo que muestran el uso de la clase Void. La primera parte es con Generics (que de hecho fue así como me enteré de su existencia), lo que me resulta curioso es que quizás ahora este sea su uso mas extendido aun cuando Generics apareció en la versión 5 de Java. La segunda parte es con reflection el cual creo que fue el primer caso de uso de esta clase Void.

Tablas en memoria en MySQL

Algunas semanas atrás en el trabajo nos topamos con un problema, realizábamos una consulta que consistía en hacer un join entre una tabla muy grande contra un par de tablas pequeñas que contenían únicamente descripciones. Como ustedes ha de imaginarse teníamos nuestra base de datos normalizada y para exportar los datos con el conjunto de descripciones era necesario realizar este cruce.

Para que la consulta fuese bien (que no arrojase un timeout en el mejor de los casos) habíamos agregado índices a las tablas secundarias (aquellas que contenían las descripciones) y la consulta de lograr ejecutarse llegó a tardar unos 25 segundos. Estas tablas eran de tipo InnoDB y los índices eran de tipo B-Tree (es el único tipo de índice para las tablas de tipo InnoDB). La consulta llegaba a tardar en el mejor de los casos (que no devolviese un timeout) 25 segundos. Es por esta razón que buscando una alternativa abordamos las tablas en memoria.

Las tablas en memoria son almacenadas en la memoria HEAP razón por la cual son tablas temporales ya que una vez se haya reiniciado o apagado la máquina estas perderán los datos, es decir se mantiene la estructura de la tabla mas no su contenido. Las tablas en memoria en MySQL pueden tener 2 tipos de índices B-Tree o Hash.

¿Cuando utilizar cada tipo de índice?

El índice B-Tree puede utilizarse con operadores del tipo =, >, >=, <, <= o BETWEEN, de igual manera puede ser usado con el operador LIKE, mientras que el índice Hash es usado únicamente para comparaciones de igualdad como =, >= o <=. Así que de realizar comparaciones de igualdad es recomendable utilizar el índice Hash ya que es muy rápido mientras que cuando se realicen comparaciones del tipo >, <, LIKE, BETWEEN u optimizar operaciones de ORDER BY la opción es utilizar B-Tree.

En nuestro caso únicamente realizábamos operaciones de igualdad ya que comparábamos en base a un código así que utilizamos índices de tipo Hash, obteniendo excelentes resultados, tanto es así que nunca llegamos a obtener un timeout y el tiempo de respuesta de nuestras consultas se redujeron a 5 segundos.

¿Cómo crear una tabla en memoria?

La creación de una tabla en memoria es muy sencilla, es igual a la creación de cualquier otra tabla del tipo InnoDB, lo único es sencillamente cambiar el tipo de “engine” e indicar “MEMORY”, por ejemplo:

Por último ¿Como hacer para que se carguen los datos de la tabla en memoria al arrancar?

Por muy tonto que parezca para nosotros esto era importante ya que nos asegurábamos de que de reiniciarse el ordenador (era windows :-s ) estando o no nosotros, las tablas en memoria estarían creadas y cualquier consulta que se efectuase no daría error. Para que la tabla en memoria se llene de datos al arrancar el servidor MySQL es bastante sencillo, lo único que debemos hacer es editar el fichero my.ini o my.cnf y debajo de donde dice [mysqld] agregar la siguiente linea

Donde script.sql tendrá las sentencias sql de inserción por ejemplo

Espero que esto les pueda servir para optimizar el consultas en base de datos o sencillamente resolver cualquier inconveniente.

¿Has trabajado antes con tablas en memoria? Compartirías con nosotros tu experiencia.

Web scraping con Java

Actualmente me encuentro desarrollando mi proyecto final de máster, el cual consiste en crear un modelo de aprendizaje automático que arroje predicciones acerca de partidos de futbol de la liga de primera división española. Para ello he necesitado entre otras cosas tener los resultados de todas las jornadas de las ultimas ligas. Aunque recientemente conseguí un paquete de R (enlace) que contenía los resultados desde 1929, este no me proporcionaba toda la información que yo buscaba, así que me decidí por obtener yo mismo esa información sacándola de las paginas deportivas y es lo que quiero compartir con ustedes.

En un principio pense en hacerlo en python con la biblioteca lxml, pero haciendo una búsqueda rápida por Internet encontré un proyecto en Java llamado Jsoup y debo decir que este si me simplifico la tarea.

Primero como todos saben es necesario que demos un repaso a la estructura del documento que vamos a scrapear y confirmar que hay un patron.

estructura documento html

Como pueden ver en la imagen, podemos detallar que todas las filas de las tablas de las jornadas comparten el atributo itemtype=”http://schema.org/SportEvent”, así que este fue el que utilicé para obtener todas las filas y a partir de allí obtener los nombres de los equipos, el resultado y el enlace para ir al detalle del partido.

Par de cosas que quisiera comentar con respecto al código:

  • Podemos aplicar expresiones sobre elementos de antemano obtenidos, por ejemplo como se hizo para obtener los equipos que intervienen en el partido.
  • Existe otra forma además de la anteriormente explicada (usando expresiones) para obtener elementos del árbol DOM de la página Web, si damos un vistazo a la API de la biblioteca del partido, existe un método getElementsByAttributeValue, entonces para obtener el elemento score, este se pudo haber obtenido también de la siguiente manera

    Elements score = match.getElementsByAttributeValue(“class”, “resultado resul_post”)

  • Por último si quisiéramos obtener mas datos por ejemplo del detalle del partido (ya que logramos obtener el url), esta biblioteca nos permite seguir navegando (haciendo conexiones), y sería cuestión de realizar otra conexión y de nuevo empezar a extraer elementos.
    Document detalleDelPartido = Jsoup.connect(statsLink).get()

Aquí les dejo el enlace al repositorio GitHub y espero que les pueda ser de utilidad.

Estadística simple con Spark

Hace unos 20 días lei un articulo titulado “Simple Data Analysis Using Spark” (no publico el enlace ya que el mismo desapareció de dzone de la zona de Big Data y el mismo blog ya no existe, corroborarlo buscando por Internet), lo interesante de este articulo es que el autor hacía cálculos de estadística simple, es decir, calculaba, media, máximo y mínimo, y fue casualidad que justo en ese momento acaba de leer acerca de las operaciones numéricas de los RDD, es esta la razón que me movió a querer hacer un ejercicio similar, con estadística simple pero quería hacerlo con una información que yo considerara valiosa.

Fue entonces que me decidí a buscar alguna fuente de open data española, ya que quería arrojar u obtener datos reales, o no se quizás quería sencillamente obtener algo significativo que se acercara a una tarea real, fue así que llegue al Portal de datos abiertos de la comunidad de Madrid y después de revisar el catalogo me decidí por el padrón municipal, un fichero csv de 22 MB.

He aquí el código:

Hay una cosa que quiero resaltar, Lo simple y corto del código en Scala, tanto para la definición de la clase Padron como en las transformaciones hechas en los RDD, ya Scala esta en mi lista de cosas por aprender porque se que con Java hubiese sido el doble de código.

Por último les dejo parte de la información obtenida, la lista ordenada de población por distrito:

BARAJAS: 46166
VICALVARO: 69709
MORATALAZ: 94785
VILLA DE VALLECAS: 101011
MONCLOA-ARAVACA: 116581
RETIRO: 118390
CENTRO: 131805
USERA: 133579
CHAMBERI: 137454
VILLAVERDE: 141457
CHAMARTIN: 142334
SALAMANCA: 143123
ARGANZUELA: 151061
TETUAN: 152142
SAN BLAS-CANILLEJAS: 153303
HORTALEZA: 176320
CIUDAD LINEAL: 212626
PUENTE DE VALLECAS: 227183
LATINA: 234842
FUENCARRAL-EL PARDO: 234883
CARABANCHEL: 242032

¿Te ha parecido interesante? ¿Qué le agregarías o quitarías al código?

Si quieres acceder al GitHub donde he colgado el código pincha aquí

Primer ejemplo con apache spark

Hace algunas semanas atrás que empezamos a trabajar con apache spark en el máster, brevemente les contare mis impresiones desde mi punto de vista como principiante.

Apache spark me gusto, ¿por qué? porque se puede programar en Scala (además de Python y Java),  la API de Scala lo simplifica mucho y la cantidad de código a teclear es (considerablemente) menor a la necesaria para hacer la misma tarea en Java, aunque aquí debo hacer un paréntesis, ya que con la entrada de Java 8 y las lambda expresión la cantidad de código será menor pero insisto la API de Scala a mi modo de ver lo hace mas sencillo.

Nos permite hacer operaciones con mucha data (quizás no Big Data, es decir no hablamos de TeraBytes) sin necesidad de usar Hadoop, me gustaría hacer hincapié en esto ya que muchos piensan que Big Data es Hadoop y NO, no es así, mi concepto de Big Data es un poco mas amplio y contempla mas cosas, aquí me refiero específicamente a la API MapReduce de Hadoop la cual es mas complicada de usar que la de Spark, no obstante si necesitamos trabajar con una cantidad de datos considerable que requiera del uso de HDFS, podemos desde Spark acceder a este sistema de archivo u algún otro como por ejemplo Amazon S3.

Por último decirles que Spark es mas rapido, esto se debe a su arquitectura, ya que este trabaja en memoria (todo en memoria si tiene la capacidad de cargar todos los datos por completo) y pues si llegamos a hacer varias tareas (lo que técnicamente sería reutilizar los RDD ya guardados en memoria) con los datos en memoria es cuando mas jugo se le sacará a Spark.

Sinceramente si alguien discrepa de mi o coincide me entusiasmaría mucho que comparta su opinión ya que todo este mundo que envuelve el Big Data me tiene super enganchado.

 Ahora bien vamos con los ejemplos, estas formaban parte de la primera tarea de Spark que tuvimos que realizar, y consiste en 2 ejemplos:

  1. Dado un fichero de texto en formato csv con información de medallistas olímpicos, obtener el numero de medallas por edad.
  2. Dado el mismo fichero de texto anterior, y un esquema de puntuación por tipo de medalla obtener un ranking de medallistas olímpicos.

He aqui el código:

 

Una última cosa que es bueno saber para aquellos que como yo están empezando con Spark y sus RDD, Los RDD tienen 2 tipos de operaciones: transformaciones y acciones, las primeras son operaciones que como resultado nos devuelven otro RDD y las acciones son aquellas que hacen “algo” sobre los datos como por ejemplo el foreach de mi código,  utilizado para mostrar por pantalla los valores finales, además los RDD (como hasta ahora lo entiendo) son las instrucciones a realizar sobre los datos, mas no almacenan la información, además estás instrucciones no se realizan de inmediato, sino que al contrario estos tienen un funcionamiento lazy, esto significa que se ejecutan cada vez que se realiza una operación de tipo acción.

Otra sugerencia, no duden en cacharrear con la consola de spark, de hecho el primer ejercicio lo llegue a hacer por la consola (sin los JavaBeans) y el practicar por aquí si que ayuda a conocer los operaciones a utilizar sobre los RDD.

Aquellos interesados en descargar el código, les dejo la dirección del ejercicio en mi repositorio github

El esqueleto del ejercicio esta en el repositorio del que fue nuestro profesor y pueden acceder a el haciendo clic aquí.

Cualquier material, idea o contenido que quieres compartir, no dudes en hacerlo, ya que bien recibido será. Ahora si para cerrar les dejo el enlace a un libro que hasta ahora me esta pareciendo muy bueno para aprender Spark (además con ejemplos elaborados en Java, Scala y Python).