A este blog, le llega bastante spam, pero gracias a akismet, nada de aquello sale publicado. Una vez a la semana tengo que eliminar los mensajes y todo bien.
Lo curioso de todo y que me gustaria saber son dos cosas:
1.- como trabajan/funcionan los robots que reparten spam.
2.- cual es el objetivo del spam que reparten. Esta pregunta que es algo obvia, para mi ni en ocasiones no lo es tanto, ya que ha veces en que hay texto sin sentido (y no, no son palabras en otro idioma) y lo más importante, es que no hay ninguna URL asociada.

Como curiosidad, hace unos días (bastantes ya) apareció este mensaje. ¿Curioso no?

Bill265025834?,’380636358billy@msn.com’,”,’132.76.181.170?,’2008-05-22 08:10:33?,’2008-05-22 08:10:33?,”,’0?,’lynx’,'comment’,'0?,’0?),(’0?, ”, ”, ”, ”, ‘2008-05-23 08:10:33?, ‘2008-05-23 08:10:33?, ”, ’spam’, ”, ‘comment’, ‘0?,’0? ) /* | None | IP: 124.217.227.127

None…

None…

Todo matrimonio debiera seguir este howto… para que no se te olvide nada. Casarse era más complicado de lo que creias…
Lee el resto de esta entrada »

Anoche necesitaba asegurarme de que mi notebook tirara sin problemas la señal de video por la salida de monitor. Pase unos cuantos minutos tratando de acordarme como iniciar la aplicación de ATI para controlar algunas cosas de la tarjeta de video… pero así y todo no funciona adecuadamente… me tuve que ir con el plan B bajo la manga para el trabajo hoy día.
Luego de un break me puse a revisar las opciones de aticonfig y ahí estaba lo que necesitaba:
aticonfig --enable-monitor=auto
Y lo hace mejor de lo que esperaba…. no es necesario reiniciar la X.
Curiosamente, hoy vi a jotape y le comentaba al Ati (no a la tarjeta… a un amigo), sobre esta mismo comando pero con otras opciones, en donde le especificaba las salidas a ocupar. Ambos destacamos la no necesidad de relevantar la X.
En mis narices y nunca lo revise con calma.
Mi equipo es un Acer Aspire 5050 y tiene Ubuntu 7.10, con una ATI Radeon XPress 1100 y el kernel 2.6.22-14-generic sin ninguna modificación.

Lee el resto de esta entrada »

El viernes 18 de julio, Jotape me llama a eso de las 12 del día y me dio la triste noticia que me dejo en bloqueado un par de horas… nuestro amigo Raúl Ortega (en internet conocido como Darth Debian y para nosotros Raulito) había fallecido en un accidente.
Conversando con mis compañeros, hablábamos de que a la “gente mala” no le pasaba estas cosas. El consuelo que me daba mi mamá era que él no era para este mundo y ayer el cura que daba la misa en el velatorio remataba con algo similar. Era algo así como que dios necesitaba de esta gente buena para convertirlos en ángeles y poder cuidar a los que quedábamos en la tierra.
Lo que es yo, te dejaré referenciado siempre en memoria.
La foto es de cuando nos fuimos a Talca al Encuentro Linux
Raul Ortega

En la aplicación que estoy haciendo en mi tema de memoria, me topé con un problema. Bueno, en realidad el problema me lo planteo mi profesor guía. Contextualizando un poco el asunto, estoy haciendo una aplicación en java y es de escritorio, por lo que también ocupo Swing para la interfaz gráfica.
El cuento es que necesitaba mostrar unos resultados de una consulta a una base de datos y al tener muchos registros como respuesta al mostrarlos en un JTable iba a ser algo costoso en cuanto al uso de memoria ram. Originalmente estaba ocupando un ArrayList el cual mostraba ocupando un JTable. Eso implicaba tener TODOS los registros de la consulta en memoria. Si calculamos a vuelo de pájaro que cada registro ocupaba 120 caracteres a un costo de 1 byte por carácter por unos miserables 500 registros, tenemos 60000 bytes, dividiento por 1024, tendríamos 58.59 mbkb (espero que el calculo este bien hechoestaba mal hecho :)) en el puro arreglo… lo que es bastante poco eficiente. Así que una de mis misiones era darle un vistazo a eso y encontrar alguna manera eficiente de hacerlo.
Obviamente no quise reinventar la rueda y me tope con un exelente articulo el cual incluye tambien unas clases.
La gracia de lo anterior, es que en vez de ocupar el modelo por defecto que por ejemplo nos ofrece NetBeans es setear nuestro propio modelo el cual se va cargando a medida que lo vamos necesitando (en la práctica, cada vez que pinchamos el scroll). Esta muy bien documentada la clase y tiene varios constructores. Un ejempo de uso de los anterior seria el siguiente extracto de código:

//Creamos nuestra conexión a la base de datos
Connection conexion = Utiles.ManejadorConexionSql.conectarBd();
//hacemos una llamada a la base de datos
String stringConsulta = "select * from algunaTabla";
//Seteamos el Statement como es requisito para nuestra clase que hace la magia
Statement consulta = conexion.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
//Obtenemos nuestro resultset.
ResultSet resultado = consulta.executeQuery(stringConsulta);
//Creamos la clase que nos dara nuestro modelo
ScrollableTableModel tablaModelo = new ScrollableTableModel(resultado);
//Le ajustamos el modelos a nuestra tabla
jTaableResultado.setModel(tablaModelo);

En el documento esta muy claro explicado como lo hace internamente para quien quiera destripar la clase.

Antes de empezar a hacer (tratar) cosas en serio, pensaba que la gente iba a responder en función de como uno la tratara. Por lo tanto, tener si había buena onda, la comunicación seria mucho más fluida.
Pero no. Lamentablemente hay personas cuadradas, que solo responden a ordenes e imposiciones y que solo de esa manera entienden. Y lo pero de eso, es cuando tienes un usuario de aquellos en tu equipo, al cual le tienes que extraer información.
Después de dos intentos fallidos de entablar una conversación de no más de 15 minutos, tendré que aplicar el método antiguo… “el palo con clavo”. Si no hay respuesta, palo. Si no hay intención de ayudar, palo. Si omites información, palo. Y un palo de despedida, para que aprendan, al igual que los animalitos, a comportarse.
¿Conclusión? A la gente subordinada, le gusta que la estén controlando, que estén con el látigo y el palo por si es que escapan o dejan de hacer su labor y que le den ordenes por todo. Y ahí esta el rol del jefe… el tratar bien a la gente no es buena consejera, ya que al rato se te subirán por el chorro, así que palo.

Desde ayer, que estoy en cama con fiebre y molestia de garganta. Me ha servido para trabajar y ver televisión. Me ha tocado ver todos los noticiarios y los programas con noteros. Y una cosa me ha llamado la atención:
Anoche (lunes) hubo algunos robos en la capital y se vio reflejado en todos los noticiarios como una “ola de asaltos en el sector oriente“. Bueno, esto no me llama tanto la atención…. (robos hay en todas partes, una cosa es que salgan en los medios y otra es que los denuncien) si no que el “plan de contención para estos”.
¿Que le parecen estas diferencias? ¿A mi? Una burla para todos los que no tenemos suficientes recursos para “comprar” esa seguridad. Es más, no entiendo el porque existen estas diferencias. La única respuesta que le encuentro a esto es que el plan cuadrante de “allá” es más organizado que los de los otros sectores…. ahora… ¿por qué pasa eso?

Trabajando en mi proyecto de título, me tope con un problema. Contextualizando un poco el problema:

  • una tabla con un campo serial (autogenerado).
  • una tabla que necesita como llave foranea, el campo serial anterior
  • para ingresar valores a las tablas anteriores, ambas se hacen a través de funciones de postgres.
  • jdbc de postgres
  • La interfaz de jdbc provee el método getGeneratedKeys() que debiera entregar un ResultSet, con todos las llaves que se crearon. Después de un (buen) rato viendo que porque no funcionaba y buscar el problema en mi código dí con las primeras luces de mi problema:

  • La versión que estoy ocupando del jdbc es la última a la fecha 8.3-603 no soporta este método y lamentablemente al ejecutarlo no tira una exception gritando acerca de esto, como al parecer lo hacia en versiones anteriores.
  • Obviamente muy empantanado y sin mucho tiempo de leer la documentación recurrí a la lista en español de postgresql donde me ayudaron a reescribir la función en cuestion, quedando de la siguiente manera:


    CREATE OR REPLACE function ingresarVoucherEntrada( _idEmpleado "int4", _idProveedor "int4", _fechaEmision"date", _documentoAsociado"int4")
    returns int as $$
    insert into voucherEntrada (idEmpleado, idProveedor, fechaEmision, docuementoasociado)
    values ($1, $2, $3,$4);
    select currval(‘voucherentrada_idvoucherentrada_seq’)::int;
    $$ LANGUAGE ’sql’ VOLATILE;

    La parte en negrita es lo que hace la magia. Devuelve un entero, que es el entero que tiene la llave que me interesa recuperar. Y ¿cómo la recupero? Seleccionando el “valor actual” de la secuencia del “voucherentrada_idvoucherentrada_seq”.
    Esta última secuencia (sequence) se genera automáticamente al definir un campo como serial.
    Luego, mi método que ocupa esta función, tiene que devolver el identificador del registro que se ha creado recientemente y se lo paso como parámetro al método que llena la tabla usando el identificador de la primera tabla.

    es importante en esta profesión centrarse en el problema y no irse por las ramas, si sabéis que algo soluciona vuestro problema, a por ello, no os pongáis a mirar y mirar y mirar, porque el tiempo se os va a ir y la fecha de entrega de un proyecto suele ser fija. Somos ingenieros y nos gusta aprender, pero no nos podemos pasar el día aprendiendo sin dar un resultado porque si no no seríamos ingenieros, seríamos científicos.

    Visto en un blog, mientras buscaba más soluciones para algo que ya tengo casi resuelto… y que aplica para muchas cosas… a menos que uno sea genio (el 99.999% de los casos).