martes, 11 de febrero de 2014

Buen Programador


Tengo ya mucho tiempo programando y programando en equipos chicos y grandes. Y me he dado cuenta que casi todos los programadores son gente demasiado rara por lo que me di a la tarea de observarlos y entender que los hacia ser buenos programadores o malos programadores. 
Y primero diré que yo estoy lejos de mi ideal de buen programador, por lo que siempre he estado aprendiendo de cada uno que ha trabajado conmigo. 

Formación humana

Esto nos constituye como personas. Es importante como seres humanos formarnos a nosotros mismos, cualquiera sea el camino que elijamos. Esto nos hará un "buen programador", un "buen amigo", un "buen padre", etc. Los valores que cada uno posee son los que terminarán dando forma a su posterior actividad profesional. Conozco buenos programadores que son increíblemente soberbios, lo cual hace que poca gente quiera trabajar con ellos. Hay programadores que no son tan buenos técnicamente pero son grandes personas, lo que hace que otros programadores se acerquen y se sientan a gusto al compartir su tiempo y conocimiento, lo que termina siendo beneficioso para su vida profesional.

Más allá del tema de la persona y sus valores, tema que me excede notablemente, se encuentra la "disciplina" del programador. La programación es una profesion complicada. Tiene algo de ciencia y tiene algo de arte. El arte se manifiesta en esos momentos en que hay que hacer algo y uno no sabe por dónde arrancar. Se nos ocurren mil formas distintas de encararlo, pero todo es una experimentación. Sumado a eso, puede ser que esa particular tarea no nos agrade mucho. Y por si fuera poco, la mayoría de los programadores tenemos "horarios flexibles". No tenemos un jefe que nos diga "¿presentaste el formulario en tribunales?", "¿cuántos clientes visitaste?". En esos momentos es donde hay que hacerse fuerte y ponerse metas y objetivos, y terminar de alguna manera nuestro trabajo. Mucho se ha escrito acerca de esto. Incluso se han creado "técnicas" para optimizar el tiempo. Pero sigue siendo un problema recurrente. El buen programador conoce estas dificultades, conoce sus propias limitaciones y sabe cómo atacarlo.

 

Comunicación

Tener la capacidad de comunicarse con otros es fundamental. Y por comunicarse no digo: "convencer al otro programador que mi lenguaje es mejor o que mi editor es mejor" o "convencer al PM que tal o cuál feature quede fuera del release". Me refiero a lograr una profunda comunicación con el otro. Entender a las personas que nos rodean, conectar, lograr empatía.
La interacción social es la base del crecimiento de nuestra raza. No hay nadie que se haya desarrollado individualmente. Los programadores podemos tomar mucho de las otras personas. Afortunadamente hay muchos programadores que fomentan la comunicación. 

 

Matemáticas 

Programar consiste en resolver problemas. Para resolver problemas es fundamental la capacidad de abstracción. Si bien en el título dice "matemáticas", no estoy diciendo que le encajemos una Transformada de Laplace a un algoritmo de ordenamiento. La idea es desarrollar con el tiempo la capacidad de abstraerce y levantar el nivel de nuestro pensamiento. Lamentablemente esto es muy difícil de explicar. Los programadores con cierta experiencia van entender a lo que me refiero. Es una cuestión de práctica. Nuestro cerebro se acostumbra a los patrones.
Algunas cosas interesantes para desarrollar este punto pueden ser:
  • Problemas matemáticos en general.
  • Problemas de programación en general (Google: "programming puzzles". Los de Facebook están geniales.)

 

Conceptos técnicos básicos

Es fundamental aprender y entender las bases de la computación. Es irritante cuando un programador se jacta de saber "tal o cuál feature" o "conocer tal o cual lenguaje".
Es clave para un programador ir hacia el centro, hacia las bases de lo que hace. Uno no debe "aprender python". Debe aprender el concepto de objetos, de programación funcional, de concurrencia, etc. Eso es lo que diferencia a los buenos programadores. Los lenguajes pasan, las tecnologías pasan, las técnicas pasan. Las bases quedan. Es por eso que quienes aprenden las bases pueden transformarse a sí mismos hacia lo nuevo, evolucionar.
Cosas importantes para aprender que considero básicas:
  • Arquitectura de Hardware.
  • Sistemas operativos. Funcionamiento en general. "¿Qué pasa cuando ejecuto un proceso? De principio a fin."
  • Concurrencia. En general. (Fundamental en la nueva era multicore)
  • Redes Infraestructura y programación. Protocolos básicos.
  • Paradigmas: funcional, objetos, prototipos, etc.
  • Datos, datos y más datos! Almacenamiento, modificación, transformación. (Si no me creen pregúntenle a Linus)

 

Conceptos generales de programación

Si bien estos también podrían considerarse "conceptos básicos", quiero hacer una diferencia de los anteriores porque en este caso están directamente relacionados con la actividad de Programar. Con "Conceptos Generales" me refiero a cosas que uno hace a la hora de programar que son básicas y están más allá del lenguaje de programación o la plataforma usados. Tal vez la mejor manera de explicarlo es mediante ejemplos:
  • Manejo de colecciones: Cuál es la mejor forma de iterarlas, de modificarlas. Qué complejidad tiene cada tipo. Cuándo usar un tipo u otro, etc.
  • Algorítmica en general: Escribir programas simples, tratar de disminuír la complejidad.
  • Buen manejo de tipos de datos: Saber por qué un float no tiene la presición esperada, manejar dates y datetimes, conjuntos de caracteres, etc.
  • Escribir código legible y modular: Saber aprovechar de la mejor manera el paradigma que estemos usando en el momento.
  • Saber cuándo documentar y qué documentar.
  • Escribir buenos tests: Es decir, saber cuándo testear unitario, cuándo funcional, cuándo integración, etc.
Algo que es realmente útil para esto es poner tu código ante los ojos de otros programadores. Por ejemplo incorporar code reviews al proceso de desarrollo, escribir código y mandar PRs a proyectos open source (por más que no pasen, solamente para tener feedback), hacer pair programming, entre otras cosas.
A la hora de mejorar la programación en sí, una cosa que se puede hacer es aprender muchos lenguajes, y saber sacar lo mejor de cada uno. Además, aprender los fundacionales como Lisp o Smalltalk.

 

Lenguaje.

Por último un buen programador es aquel que conoce a fondo un lenguaje (o varios). Está muy bien aprender muchos lenguajes (cuantos más mejor) pero es importante conocer alguno a fondo. Esto es lo que nos permite, además de ser buenos programadores, escribir buenos programas. Si uno conoce los detalles (las cosas buenas, malas, oscuras) de un lenguaje puede escribir programas que exploten esas ventajas y con la menor cantidad de errores posibles.
La forma de conocer a fondo un lenguaje es usándolo mucho, leyendo código de gente que sabe más que nosotros y metiéndonos en la fuente del lenguaje. Tal vez leyendo el código, la arquitectura, papers publicados, etc.

viernes, 5 de julio de 2013

Servicios Web Axis2, JSF 2.0, PrimeFaces 3.5 en Tomcat 6.0.37 Parte I

Para la realización de este tutorial necesitaremos:
Axis2 es un contenedor de Web Services, soportando el protocolo SOAP y REST. Axis2 ofrece las siguientes características:
  • Velocidad - Axis2 usa su propio modelo de objetos y un análisis sintáctico basado en StAX (Streaming API para XML) para lograr una velocidad de proceso significativamente mayor que la de versiones anteriores de Apache Axis.
  • Uso reducido de memoria - Axis2 fue diseñado desde la base teniendo en cuenta el objetivo de una reducida demanda de memoria.
  • AXIOM - Axis2 viene con su propio y eficiente modelo de objetos, AXIOM, para el procesamiento de mensajes, modelo que es extensible, ha sido optimizado con miras a desempeño y rapidez, simplificando su uso por parte de los desarrolladores.
  • Despliegue instantáneo - Axis2 está equipado con la capacidad de desplegar servicios web y handlers con el sistema en pleno funcionamiento. En otras palabras, es posible agregar nuevos servicios al sistema sin tener que detener la ejecución del servidor. Basta con copiar simplemente los archivos requeridos de servicios web al directorio de servicios en el repositorio, y el modelo de despliegue automáticamente desplegará el servicio y lo pondrá a disposición para su uso.
  • Servicios web asincrónicos - Axis2 ahora soporta servicios web asincrónicos y la invocación asincrónica de servicios web por medio de clientes y transportes no bloqueantes.
  • Soporte de MEP - Axis2 ahora viene con la conveniente flexibilidad de soportar "patrones de intercambio de mensajes" (Message Exchange Patterns (MEPs)) con su soporte incorporado para los MEPs básicos definidos en WSDL 2.0.
  • Flexibilidad - La arquitectura de Axis2 le otorga al desarrollador completa libertad para insertar extensiones al motor para el procesamiento a la medida de encabezamientos (headers), administración del sistema, o cualquier otro aspecto imaginable.
  • Estabilidad - Axis2 define un conjunto de interfaces publicados que cambian con relativa lentitud, comparados con el resto de Axis.
  • Despliegue orientado a componentes - Se puede fácilmente definir redes reutilizables de handlers para implementar patrones comunes de procesamiento para determinadas aplicaciones o para distribuir estos elementos a las contrapartes.
  • Framework de transporte - Axis2 tiene una abstracción limpia y simple para la integración y el uso de diversos transportes (esto es, senders y listeners para SOAP por vía de diversos protocolos tales como SMTP, FTP, middleware orientada a mensajes, etc.), siendo el núcleo del motor completamente independiente de los mecanismos de transporte.
  • Soporte de WSDL - Axis2 soporta Web Services Description Language, versiones 1.1 y 2.0 , lo que facilita la construcción de stubs para el acceso a servicios remotos, como también automáticamente exportar de Axis2 descripciones legibles por máquinas de los servicios desplegados.
  • Agregados - Se han incorporado diversas especificaciones relativas de los servicios web, entre las que se incluyen WSS4J para securidad (Apache Rampart), Sandesha para mensajería confiable, Kandula que es un encapsulamiento de WS-Coordination, WS-AtomicTransaction and WS-BusinessActivity.
  • Composición y extensibilidad - Con el empleo de módulos y fases se mejoran las habilidades de composición y extensibilidad. Los módules de Axis2 soportan la facultat de composición y también pueden soportar nuevas especificaciones WS-* de manera más simple y limpia. Sin embargo no permiten su despliegue instantáneo, ya que alteran el comportamiento global del sistema.

Configuración del ambiente


  1. Primero se debe instalar el JDK de Java y tener establecida la variable de sistema JAVA_HOME:
    JAVA_HOME=”C:\Program Files\Java\jdk1.6.0_21″
  2. Deberemos tener también el servidor de aplicaciones Apache Tomcat correctamente instalado así como establecida la variable de entorno CATALINA_HOME a la ruta del mismo:
    CATALINA_HOME=C:\Program Files\Apache Software Foundation\Tomcat 6.0
  3. Descargar la versión binaria de Apache Axis2 y copiar la distribución War al directorio de aplicaciones de Apache Tomcat
    • Descomprimiremos la versión binaria de Axis2 en la carpeta C:\axis2-1.6.2 y estableremos la variable AXIS2_HOME=C:\axis2-1.6.2 y añadiremos a la variable PATH del sistema la siguiente rura: C:\axis2-1.6.2\bin
    • Copiaremos el fichero axis2.war a C:\apache-tomcat-6.0.37\webapps

Si ahora arrancasemos el servidor de aplicaciones Apache Tomcat  (CATALINA_HOME\bin\startup.bat) veriamos como se ha realizado el deploy de la aplicacion axis2.war:



Si accedemos ahora a la dirección URL http://localhost:8080/axis2 veremos que nuestra aplicación se encuentra instalada:





jueves, 27 de junio de 2013

¿Qué es un Objeto?

Antes de empezar con la programación orientada a objetos es necesario entender qué es un objeto.

El mundo esta hecho de objetos, basta con mirar a nuestro alrededor para encontrar cualquier cantidad de objetos, como por ejemplo: audifonos, llaves, lentes, mouse...


En el mundo real podríamos decir que todos los objetos tienen estados y comportamientos.

Por ejemplo:


Objeto Estado Comportamiento
Audífonos marca, peso, color, volumen actual sonar
Perro nombre, color, raza ladrando, buscando, moviendo la cola
Mouse color, marca, peso, tipo dar clic, desplazar, mover scroll
Radio marca, color, apagado, encendido sintonizar, ajustar volumen

Pero no se detiene esto aquí, también es posible observar que unos objetos son extensión de otros o que necesitan de otros objetos para realizar alguna función en especifico. Por ejemplo el radio puede conectar unos audífonos para tomar estos como la salida del audio y todo esto se puede reproducir en la programación orientada a objetos.

Los objetos software son similares a los objetos del mundo real: también consisten de estado y comportamiento. Un objeto almacena su estado en campos («variables») y muestra su comportamiento a través de métodos  («funciones»). Los métodos operan sobre el estado interno del objeto y sirven como el mecanismo principal para la comunicación entre objetos. La ocultación del estado interno y requerir que toda interacción se realice a través de los métodos de un objeto se conoce como encapsulación de datos — un principio fundamental de la programación orientada a objetos. Al agrupar código en objetos software individuales se obtienen ciertos beneficios:
  1. Modularidad: El código fuente de un objeto se puede escribir y mantener independientemente del código fuente de otros objetos. Una vez creado, un objeto se puede pasar fácilmente de un lado al otro del sistema.
  2. Ocultación de información: Al interactuar solamente con los métodos de un objeto los detalles de su implementación interna permanecen ocultas al mundo exterior.
  3. Reutilización de código: Si un objeto ya existe (quizás escrito por otro desarrollador de software), puede utilizar ese objeto en su programa. Esto permite que un especialista implemente/compruebe/depure objetos específicos para una tarea, en los que luego podrá confiar en su propio código.
  4. Conectividad y facilidad de depuración: Si un objeto en concreto resulta ser problemático podrá simplemente eliminarlo de su aplicación y «conectar» un objeto distinto para reemplazarlo. Esto es análogo a la reparación de problemas mecánicos en el mundo real. Si rompe un tornillo, reemplaza el tornillo, no la máquina entera.

domingo, 23 de junio de 2013

Configuar Axis2 en un Tomcat 7 en Windows

Vamos a configurar un Tomcat 7 con Axis2 para lo cual necesitamos lo siguiente:

  • Motor de servicios web: Axis2 (axis2-1.6.2-bin y axis2-1.6.2-war)
  • Apache Tomcat 7.0.42
  • JDK 5.x o superior
  • IDE: Netbeans 
Lo primero que debemos hacer es bajar el Apache Tomcat de la siguiente página http://tomcat.apache.org/, ahora se debe descomprimir el zip y ubucar el tomcat donde uno quiera y por creencias populares una ruta que no contegna espacias.

Ahora se debe bajar el Axis3 de la siguiente página http://ws.apache.org/axis2/, y debemos bajar:

  • La distribución Standard Binary Distribution | zip.
  • La distribución WAR (Web Archive Distribution) | zip.
Descomprimir ambas carpetas. De la distribución war, tomar el archivo axis2.war y ponerlo en la carpeta webapps del Tomcat que se configuró previamente. Y la distribución Binaria ubicarla en algún lugar de FileSystem (C:/Axis2-1.4.1, por ejemplo).

Una vez hecho estas dos cosas, hay que crear la variable de entorno AXIS2_HOME y apuntarla al directorio de axis2 binario, es decir:
AXIS2_HOME=C:/Axis2-1.4.1

Tambien se debe agregar al PATH lo siguiente:

JAVA_HOME=C:\Program Files\Java\jdk1.7.0_11
CATALINA_HOME=C:\apache-tomcat-7.0.41

Ahora en PATH, se debe agretar lo siguiente al final: 

;%JAVA_HOME%\bin;%CATALINA_HOME%\bin;%AXIS2_HOME%\bin;


Para comprobar si quedó bien instalado, ir a la carpeta bin del to mcat y levantarlo con el comando startup.bat, si quedó levantado bien, vamos a un explorador y ponemos la url: http://localhost:8080/axis2/ y nos debería aparecer una página con la bienvenida a Axis2.


Los archivos que yo he utilizado son los siguientes:
Nota:

Para crear una variable de entorno basta con hacer lo siguiente:
  1. Dar clic derecho en "Equipo" y dar clic en propiedades.
  2. Dar clic en "Configuración Avanzada del Sistema" y luego en la venta que se abre en "Variables de entorno"
  3. Luego abrira una ventana donde podremos ingresarlas, en la parte de "Variables de Sistema"

miércoles, 19 de junio de 2013

Lenguaje de bajo nivel, lenguaje ensamblador y lenguaje de alto nivel


Los principales tipos de lenguajes utilizados son tres:
  • Lenguaje Máquina.
  • Lenguaje de Bajo Nivel (ensamblador).
  • Lenguajes de Alto Nivel.

LENGUAJE MÁQUINA


Son aquéllos que están escritos en lenguajes directamente inteligibles para el humano pero para la máquina (computadora) si, ya que sus instrucciones son cadenas binarias (cadenas o series de caracteres de dígitos 0 y 1) que especifican una operación y las posiciones (dirección) de memoria implicadas en la operación se denominan instrucciones de máquina o código máquina. El código máquina es el conocido código binario.

Las instrucciones en lenguaje máquina dependen del hardware de la computadora y, por tanto, diferirán de una computadora a otra.

Ventajas del Lenguaje Máquina
  1. Posibilidad de cargar (tranferir un programa a la memoria) sin necesidad de traducción posterior, lo que supone una velocidad de ejecución superior a cualquier otro lenguaje de programación.
Desventajas del Lenguaje Máquina
  1. Dificultad y lentitud en la codificación.
  2. Poca fiabilidad.
  3. Gran dificultad para verificar y poner a punto los programas.
  4. Los programas solo son ejecutables en el mismo procesador (CPU).
En la actualidad, las desventajas superan a las ventajas, lo que hace prácticamente no recomendables a los lenguajes máquinas.


LENGUAJES DE BAJO NIVEL


Son más fáciles de utilizar que los lenguajes máquina, pero al igual que ellos, dependen de la máquina en particular. El lenguaje de bajo nivel por excelencia es el ensamblador. Las instrucciones en lenguaje ensamblador son instrucciones conocidas como nemotécnicos. Por ejemplo, nemotécnicos típicos de operaciones aritméticas son : en inglés : ADD, SUB, DIV, etc. ; en español : SUM, RES, DIV, etc.

Una instrucción típica de suma sería :

ADD M, N, P

Esta instrucción significa "sumar el contenido en la posición de memoria M al número almacenado en la posición de memoria N y situar el resultado en la posición de memoria P" . Evidentemente es más sencillo recordar la instrucción anterior con un nemotécnico que su equivalente en código máquina.

0110 1001 1010 1011

Un programa escrito en lenguaje ensamblador, requiere de una fase de traducción al lenguaje máquina para poder ser ejecutado directamente por la computadora.

El programa original escrito en lenguaje ensamblador se denomina programa fuente y el programa traducido en lenguaje máquina se conoce como programa objeto, el cual ya es directamente entendible por la computadora.

Ventajas del lenguaje ensamblador frente al lenguaje máquina
  1. Mayor facilidad de codificación y, en general, su velocidad de cálculo.
Desventajas del lenguaje ensamblador
  1. Dependencia total de la máquina lo que impide que  se pueda transportar  los programas o la posibilidad de ejecutar un programa en diferentes máquinas. El lenguaje ensamblador del PC es distinto del lenguaje ensamblador del Apple Machintosh.
  2. La formación de los programadores es más compleja que la correspondiente a los programadores de alto nivel, ya que exige no solo las técnicas de programación, sino también el conocimiento del interior de la máquina.
  3. Los lenguajes ensamblador tienen sus aplicaciones muy reducidas, se centran básicamente en aplicaciones de tiempo real, control de procesos y de dispositivos electrónicos.

LENGUAJES DE ALTO NIVEL


Estos lenguajes son los más utilizados por los programadores. Están diseñados para que las personas escriban y entiendan los programas de un modo mucho más fácil que los lenguajes máquina y ensambladores. Un programa escrito en lenguaje de alto nivel es independiente de la máquina (las instrucciones no dependen del diseño del hardware o de una computadora en particular), por lo que estos programas son portables o transportables. Los programas escritos en lenguaje de alto nivel pueden ser ejecutados con poca o ninguna modificación en diferentes tipos de computadoras.

Ventajas de los lenguajes de alto nivel
  1. El tiempo de formación de los programadores es relativamente corto comparado con otros lenguajes.
  2. La escritura de programas se basa en reglas sintácticas similares a los lenguajes humanos. Nombres de las instrucciones tales como READ, WRITE, PRINT, OPEN, etc.
  3. Las modificaciones y puestas a punto de los programas son más fáciles.
  4. Reducción del coste de los programas.
  5. Se pueden transportar de máquina a máquina.
Desventajas de los lenguajes de alto nivel
  1. Incremento del tiempo de puesta a punto al necesitarse diferentes traducciones del programa fuente para conseguir el programa definitivo.
  2. No se aprovechan los recursos internos de la máquina que se explotan mucho mejor en lenguajes máquina y ensambladores.
  3. Aumento de la ocupación de memoria.
  4. El tiempo de ejecución de los programas es mucho mayor.
 

martes, 18 de junio de 2013

¿Qué es una computadora?

Una definición rápida sería:

"¡Idiota Rápido!"

Ya que una computadora esta diseñada para realizar millones o miles de millones de cálculos por segundo, entonces todo se reduce en decirle (programar) que hacer a nuestro idiota rápida ya que el no tiene autonomía, simplemente se limita a realizar lo que nosotros le indicamos.

Una computadora se puede seccionar en:

Unidad de Entrada: 

Esta se ocupa de obtener datos tanto de programas como de dispositivos de entrada conectados a la computadora y es la encargada de pasar estos datos a las demás unidades. Algunos ejemplos de dispositivos de entrada serían: CD, DVD, Memorias USB, Teclado...

Unidad de Salida:

Esta se ocupa de arrojar los datos procesados por otras unidades a distintos dispositivos de salida como pueden ser: monitor, impresora, bocinas...

Unidad de Memoria:

Es la encargada de "guardar" la información que envía la unidad de entrada y también es la encargada de brindar esta información de manera "inmediata" a las distintas unidades como puede ser la unidad de salida. Esta información "guardada" es volátil por lo que una vez se apague deja de estar almacenada.

Unidad Aritmética y Lógica (ALU):

Es la encargada de realizar todos los cálculos con la información obtenida en otra unidad como pueden ser: suma, resta, multiplicación y división. Además contiene todos los mecanismos para realizar tomas de decisión como ver si dos elementos son distintos. En algunos casos la ALU esta contenida en la CPU.

Unidad Central de Procesamiento (CPU):

Es la encargada de controlar y gestionar a las demás unidades. Indica cuando se debe tomar la información de entrada, cuando debe ser arrojada la información de salida, cuando debe guardarse, cuando realizar los cálculos con la información obtenida. En la actualidad cuando se tienen un procesador de doble núcleo se tienen dos CPU.

Unidad de Almacenamiento Secundario:

Es la encargada de "guardar" información que no es requerida en ese preciso momento pero que se desearía recuperar, por ejemplo un disco duro, guardamos nuestras canciones pero no siempre las vamos a querer escuchar. Ademas esta información se "persiste" en el disco duro hasta que se indique lo contrario, borrando la información. El inconveniente respecto a la Unidad de Memoria es que esta información se procesa de una manera más "lenta".