Categoría: Técnico

Compartí un Post con mis compañeros de trabajo, y quedé como el malo

 

Y no es la primera vez que ocurre. Mi papá siempre dice que nací para llevarle la contraria al mundo, y cuando dice mundo se refiere a él y a sus absurdas aseveraciones o normas sin fundamento.

De manera natural en casa se fué formando en mí esa necesidad de no aceptar las cosas tal cual son o que tratan de imponer sin una explicación objetiva, o al menos una evaluación crítica. “Eres demasiado terco”, “Es lo que tu dices y yá”, “Eres demasiado necio”, “Eres demasiado imbécil”, “Te encanta el caos”, entre otras frases de ‘defensa’ cuando no logran mi aceptación… al que le importe mi aceptación.

Este post describe un fenómeno que me encanta. El autor llama una nueva tendencia de desarrollo de software basado en la ‘moda’. Yo lo traduzco como desarrollo basado en emociones. En general, los desarrollos basados en emociones son aquellos cuando tomas X tecnología nueva porque has visto muchos posts en twitter o blogs referente a ella, la mencionan en conferencias, o Facebook o Netflix estan haciendo uso de ellas, y entonces decides emplearla para tu siguiente proyecto en el trabajo o startup, solo por eso, porque es lo nuevo y cool.

Chévere, pero luego ocurre lo siguiente:

  • La tecnología no es sencilla de entender porque es todo un paradigma nuevo, tu proyecto se retrasa, se retrasan las entregas, y se frustra el equipo.
  • Estas en medio del proyecto y ya existe una nueva versión que depreca cerca del 80% de lo que ya has hecho pero era un cambio necesario para madurar el nuevo framework del que todos hablan. Toca hacer todo de nuevo.
  • Diseñaste toda una solución basado en premisas y documentación y la hora de implementar las promesas de funcionalidades, velocidad y estabilidad que tanto presumían en realidad no están ahí.

Personalmente me encanta siempre probar nuevas cosas, de manera crítica, y comparando contra lo que ya conozco. En el trabajo he introducido tecnologías de integración que hoy sustentan gran parte de la automatización de la cadena de valor del negocio. Y cuando lo hice, fue porque previo a eso ya había probado otras alternativas, y empleando un análisis de características. Otro compañero de equipo probó varias soluciones para el desarrollo de aplicaciones móviles antes de elegir el enfoque que la nueva generación ha heredado. Pero esto solo lo saben mi antiguo jefe, compañeros de trabajo y yo.

Hoy por hoy, de mi grupo inicial de trabajo quedamos solo tres, y hay cerca de 30 personas mas jóvenes, igual de emocionados y enérgicos en probar nuevas cosas.

Recientemente se eligió emplear dos tecnologías emergentes para dos nuevos desarrollos, se han hecho mesas de trabajo alrededor y se ha empleado mucho tiempo realizando pruebas y prototipos. Todo muy bien salvo por eso último, mucho tiempo empleando pruebas y prototipos y cuando pregunté cuál es la opción B contra la que van a comparar sobre qué van a decidir usar obtuve esto: “Bueno, creemos que no hará falta una opción B”

Wrong, really Wrong

Compartí entonces el artículo que les menciono al inicio con el siguiente mensaje en el asunto del correo “Leamos de manera crítica y revisemos nuestras recientes decisiones”.

A la mañana siguiente: “Por qué eres así?”, “Estas creando caos”, “Solo porque no fue tu idea…”.

Recibí muchas acusaciones que solo confirmaban que los acusadores no habían leído el artículo por completo. El mismo, al final, detalla varias estrategias para que los desarrollos basados en emociones salgan exitosos y saber bien que esperar antes de realizar un plan de trabajo y propuesta de producto.

Me decepcionó horrible los juicios levantados contra mi intención de ayudar, pero me reconfortó que algunos si leyeron por completo el post y los vi estableciendo nuevas tareas que se desprenden de esas estrategias dentro de la programación del proyecto.

Mi mantra como desarrollador, evangelizador de tecnologías y gerente de proyectos de software es muy sencilla: no hay que reinventar la rueda, ya todo esta hecho, solo hay que descubrirlo, probarlo y usarlo.

Anuncios

Cómo configurar la conexión a SQLServer mediante JDBC (NetBeans, Java 8, SQLServer Express 2016, Windows 10…)

Nunca antes, luego de haber aprendido cómo conectarme a distintas bases de datos mediante JDBC, me había costado tanto una como lo fue con SQLServer (casi 15 minutos). Gracias a Google, Stack Overflow y conocimiento previo salió medianamente rápido, pero vamos, que a esta gente le gusta complicar a veces las cosas.

Archivo de propiedades de conexión (config.properties)

Ya sabemos que es de muy mala educación, y prohibido además, hard-codear valores o atributos que pueden cambiar en el tiempo de una computadora, una red, etc… a otra; entre ellos las propiedades de conexión a una base de datos. Es por eso, que lo ideal es colocarlo en un archivo de propiedades como los que estamos acostumbrados a hacer:

#Ubicado en src\res\config.properties
db.url=jdbc:sqlserver://servidor\\SQLEXPRESS;databaseName=nombre_bd;integratedSecurity=true
db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
db.user=usuario
db.password=clave

Respecto a los valores db.url y db.driver, recordemos que cada manejador de base datos  (o DBMS, como quieran llamarlo) tiene su forma de establecer estos valores, los que les indico funcionan con SQLServer Express 2016; acá mucha mas información respecto a cómo formar la url.

Y una clase en Java sencilla que lo lea:

package th.control.db;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

/**
 *
 * @author jescobar
 */
public final class DBConnection {
 static InputStream inputStream;
 static Connection conn;
 
 public static void connect() throws Exception {
 inputStream = Class.forName("th.control.db.DBConnection").getClassLoader().getResourceAsStream("config.properties");
 
 Properties prop = new Properties();
 
 prop.load(inputStream);
 
 
 Class.forName(prop.getProperty("db.driver"));
 conn = DriverManager.getConnection(
 prop.getProperty("db.url"), 
 prop.getProperty("db.user"), 
 prop.getProperty("db.password"));
 
 System.out.println("Me conecté!!!");
 }
}

Todo bien, compila al pelo, pero al ejecutar un indeseado java.lang.NullPointerException te aparece en la línea donde intentas cargar el archivo de propiedades mediante el método prop.load(inputStream).

run:
Exception in thread "main" java.lang.NullPointerException
 at java.util.Properties$LineReader.readLine(Properties.java:434)
 at java.util.Properties.load0(Properties.java:353)
 at java.util.Properties.load(Properties.java:341)
 at th.control.db.DBConnection.connect(DBConnection.java:26)

El punto es que ni NetBeans ni Eclipse te van a decir dónde colocar el archivo para que sea leído, debes especificar en cada IDE que rutas incluir en el classpath. En NetBeans una solución sencilla es moverlo al directorio src.

#Ubicado en src
db.url=jdbc:sqlserver://servidor\\SQLEXPRESS;databaseName=nombre_bd;integratedSecurity=true
db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
db.user=usuario
db.password=clave

Ahora tu problema va a ser otro…

Continue reading “Cómo configurar la conexión a SQLServer mediante JDBC (NetBeans, Java 8, SQLServer Express 2016, Windows 10…)”

Éxito de Visibilidad Web de acuerdo a Web.com

Cómo les comenté en el reciente post, tuve la oportunidad de asistir a un seminario dictado por la gente (en realidad no recuerdo el nombre del expositor, sorry) de Web.com, empresa la cual según Wikipedia, tiene mas de 3 millones de clientes a quienes ofrece asesoría de posicionamiento Web, entre otros servicios.

Visibilidad o posicionamiento Web, en pocas palabras, es hacer que los buscadores coloquen tu portal dentro de los primeros resultados ante una búsqueda. Existe una rama de la informática dedicada a esto y muchos factores influyen en el mejoramiento del ranking de tu portal.

En la sesión explicaron un conjunto de premisas que pueden llevar a mejorar la visibilidad Web de tu negocio si las cumples. El target principal eran pequeños y medianos comerciantes; Durante la sesión, pocos tenían ya un portal Web, la mayoría estaban interesados en tener uno.

Algunas de estas premisas parecen triviales, otras no tanto. A continuación las menciono dando mi aporte crítico de cada una:

  1. Información de contacto de rápido acceso. Sin navegar mucho por el portal, el cliente debe ser capaz de identificar teléfonos de contacto, dirección y horas de trabajo. Hacer esto permite que los buscadores Web que ofrecen esta información en sus resultados de búsquedas indexen con mas rapidez el portal. Muchos portales lo ofrecen al pie de página (ej. https://airandspace.si.edu/), otros requieren entrar en una ficha de horario o contacto. En mi opinión la posición ideal es que esté dentro del área principal de visualización. Si tienes sucursales, una sección de Tiendas o Stores es ideal (ej. http://www.epa.biz/ve/tiendas/).
  2. El contenido no debe estar amontonado. Nada molesta mas que mucha información mal presentada, el exceso puede frustrar al visitante y también al motor de indexado de los buscadores. El espaciado es importante y el contenido debe ser de fácil lectura, claro y conciso. El contenido es el Rey… Repetirse siempre lo último.
  3. El contenido debe ser relevante. No tiene sentido hablar de noticias locales en el portal de tu súper mercado. Tiene mas sentido presentar recetas o información sobre festivales gastronómicos. Un ejemplo de alguien que lo esta haciendo mal… http://www.kromimarket.com. Playlists musicales en el área de noticias?!  Alguien que lo hace bien… http://www.ecomarket.com.ve. De nuevo, el contenido es el Rey.
  4. Tu portal debe ser ‘responsive’. Es decir, debe visualizarse bien en cualquier dispositivo o tamaño de pantalla. Por ejemplo, abre este blog que estas leyendo en un smartphone, luego en una tablet y luego en una PC. La forma de presentación se adapta para una mejor visualización. Google te mostrará portales que se ven bien en smartphones si la búsqueda la realizas desde uno.
  5. Tu portal debe estar optimizado. Flash, videos incrustados, imágenes de alta resolución, a todo esto NO. Un portal optimizado solo contiene texto, un arte hecho a base de CCS y HTML5 e imágenes optimizadas para la Web. El 72% de los usuarios acceden a la Web desde su móvil para realizar búsquedas; por lo que este punto y el anterior son importantes para ahorrarles datos y visualizar de manera rápida lo que a través de tu portal quieres ofrecer.
  6. La experiencia del usuario es importante. Imágenes de fondo que se deslizan, presentación presentada en tarjetas o secciones que se expanden al posicionarse sobre ellas, todas estas interacciones, bien usadas, llaman la atención y tienen un propósito.
  7. Buena organización. Tópicos, categorías, departamentos. La organización del portal debe guiar al visitante quien es un cliente potencial.
  8. Si quieres visibilidad mas rápida, paga por ello. Contrata servicios de publicidad Pay per Clic.

Si quieres saber mas de visibilidad Web, una rápida búsqueda del término ‘SEO’ en Google en conjunto con otras palabras (curso, tutorial, entre otros), te llevarán a contenido mas específico, y hasta diplomados y cursos universitarios de ello.

 

 

Problemas de desempeño mas comunes en Java… Y en cuáles he caído desarrollando en plataformas móviles: El N+1

Recientemente me hice con un entretenido e-book de AppDynamics donde se presentan un conjunto de 1o problemas con los cuales estoy seguro todos nos hemos enfrentado cuando estamos realizando estas maravillosas y extensas aplicaciones en Java que nos toma meses construir y las mismas una vez que las ‘inauguramos’ empiezan a caer, colgarse y molestar a nuestros usuarios.

¡Javier, esto es muy lento! Dime de una vez si me regreso a mi formulario en papel…

Mi mayor experiencia en Java empezó refactorizando una aplicación de ventas que se ejecuta sobre la máquina virtual de Java de IBM (J9) en la plataforma Windows Mobile. Para aquella entonces, los dispositivos basados en procesadores de 600 Mhz y apenas 256 MB de Ram de los AS400 que empleábamos daban la batalla en durabilidad para las manos pesadas y descuidos a los que estaban sometidos por la fuerza de venta; sin embargo, debido a sus limitados recursos, el código tenía que ser mas que eficiente en uso de memoria y el tiempo de respuesta de la aplicación era crítico para perder o ganar una venta.

Posterior a eso, la era de Android. Equipos doble núcleo, gigas de memoria, ¡mucho poder! Pero en un mercado emergente y socialmente peligroso como en el cual se desenvuelve nuestra fuerza de ventas, el vendedor no puede andar si quiera con un Galaxy S5 sin estar expuesto a un asalto y tampoco es viable para la empresa equipar a mas de 900 ‘asesores comerciales’ con un smartphone cada mes por situaciones como estas.

La aplicación debe ser rápida y ejecutarse en cualquier ‘aparatico’ que no pase de 70USD

Muchos de los problemas de desempeño a veces los solucionamos empleando sentido común, pero no descarto también golpes de suerte probando eso o aquello conseguido en Internet.

El e-book que les comparto distribuye en cuatro categorías los problemas de desempeño en desarrollos basados en Java: base de datos, memoria, concurrencia, y ‘descuido’. Este último no se llama así como tal, pero lo he tropicalizado. Los mismos están medidos por la magnitud del impacto que pueden causar en el desempeño de la aplicación, muestra patrones que permiten identificarlos y lineamentos para resolverlos. Son muchos como para estar en un solo post así que habrá mas de una publicación de este tema en este blog.

Problema ‘Muerte por 1000 Cortes’. El problema N+1 de Base de datos

Confieso que el nombre me llamó la atención y lo que leí en Wikipedia me dejó un mal sabor del café que me tomaba mientras les redactaba esto.

Ocurre cuando nuestra aplicación se vuelve lenta por el uso excesivo de la base de datos a través de accesos individuales. Es mas común en procesos transaccionales y tiene lugar cuando utilizas un número elevado de consultas cuando lo mismo lo puedes hacer con solo dos.

Por ejemplo, el vendedor con su dispositivo puede atender alrededor de 60 clientes al mes que tiene asignado. Un vendedor puede tomar en promedio al día cerca de 10 pedidos de unas 25 líneas a clientes distintos. En un mes puede hacer en promedio 5.000 líneas de pedido; y en total, los 900 vendedores de la empresa pueden hacer 4.500.000 líneas al mes.

Obtener las ventas realizadas a un cliente entonces, durante toda su vida pudiese hacerse ‘de mal manera’ así:

select id_pedido from pedido where id_cliente = $el_cliente

select * from pedido_detalle where id_pedido = 1

select * from pedido_detalle where id_pedido = 2

...

select * from pedido_detalle where id_pedido = n

La solución a este problema es sencilla, de hecho, seguramente la mayoría de quienes lean esto preguntarán ¿por qué no se hace así?:

select id_pedido from pedido where id_cliente = $el_cliente

select * from pedido_detalle where id_pedido in (1, 2, ..., n)

¿Cómo identifico que esto está sucediendo?

  • La aplicación responde lentamente obteniendo información.
  • Si cuentas el número de consultas que haces a la base de datos y lo comparas con el número de ítems del negocio siendo procesados, encontrarás una relación cercana de 1 a 1.

¿Qué me pasó a mi?

Cuando desarrollas para plataformas móviles, siempre debes tener en cuenta también algo: memoria.

Hice que la aplicación que carga lentamente los pedidos muestre un mensaje de “Espere por favor”para que el usuario’pierda un poco menos’ la paciencia mientras se analizaba el problema. El problema N+1 estaba en el código obteniendo todos los pedidos con una consulta a la base de datos pero instanciando las líneas de cada pedido con una consulta a la vez. Se solucionó la lentitud con una sola consulta, Join de pedidos y detalle de pedidos, la respuesta era inmediata pero mas temprano que tarde un java.lang.OutOfMemoryError aparecía de vez en cuando.

Esto no lo entendía puesto que la forma anterior debería ocasionar el mismo problema. Esto no era así porque en otra sección del código, luego de recuperar el pedido deseado, los detalles no utilizados eran descartados (se liberaba memoria) pero vueltos a cargar al volver a la pantalla anterior (lentitud de nuevo… pero funciona).

Cuando trabajas con poca memoria se debe analizar el impacto de la solución. La selección de únicamente los id del pedido que se necesitaban para instanciar los detalles y la consulta de únicamente las columnas necesarias para la instanciación de los detalles solucionó el problema. Eso, y por supuesto, no descartar las líneas de los demás salvo cuando se cambie de cliente.

El problema recién descrito parece ser trivial, pero no se asombren de si de vez en cuando pecan de hacerlo porque fue la solución rápida, la máquina donde se ejecuta tiene el poder para eso, o simplemente llevamos días sin dormir y el trabajo tenía que terminarse como fuese.

En un próximo post seguimos con dos problemas mas de desempeño relacionados con bases de datos  y Java.