sábado, 29 de marzo de 2008

¿Porqué fallan los proyectos informáticos?

La gran cantidad de proyectos cancelados todos los años nos dice que algo funciona muy mal en la ingeniería informática. ¿Qué es?

Según una encuesta del 2004, el 71 por ciento de los proyectos de sistemas terminan fracasando. ¿Cuál es el problema con el IT y cómo resolverlo?

En 1985 un grupo de profesionales de West Yarmouth, Massachussets creó el Standish Group con una visión: obtener información de los proyectos fallidos de IT. El objetivo: encontrar (y combatir) las causas de los fracasos.

Con el tiempo, la seriedad y el profesionalismo del Standish Group lo convirtieron en un referente mundial sobre los factores que inciden en el éxito o fracaso de los proyectos de IT. Sus análisis apuntan fundamentalmente a los proyectos de software y se aplican tanto a los desarrollos como a la implementación de paquetes (SAP, Oracle, Microsoft, etc.)

A lo largo del tiempo, el Standish Group relevó 50.000 proyectos fallidos. Así, sus conclusiones nos brindan interesantes pistas sobre dónde poner el foco para mejorarlos. Veamos lo que ocurrió en la última década...

En 1994, el 31 por ciento de los proyectos fueron cancelados. El 53 por ciento registró enormes desvíos en presupuesto y en cronograma. Sólo el 16 por ciento se completó en tiempo y dentro de los costos presupuestados (apenas nueve por ciento en el caso de grandes empresas). Para colmo, de la funcionalidad comprometida sólo se cumplió, en promedio, con el 61 por ciento (42 por ciento en grandes empresas).En vista de estos fracasos, durante los últimos diez años, la industria invirtió varios miles de millones de dólares en el desarrollo y perfeccionamiento de metodologías y tecnologías (CMMI, ITIL, SOA, etc.) destinadas a mejorar la administración y productividad de los proyectos de software. ¿Sirvieron estas inversiones? Veamos los resultados de la encuesta del 2004...

La buena noticia: los proyectos exitosos crecieron al 29 por ciento. La mala noticia: los proyectos fracasados representan el 71 por ciento.

¿No es aterrador? Siete de cada diez proyectos se cancelaron o registraron desvíos del 45 por ciento sobre lo presupuestado en costos y del 63 por ciento de lo previsto en tiempos. Por otro lado, apenas se cumplió con el 67 por ciento de la funcionalidad comprometida.

Según el informe de Standish las diez principales causas de los fracasos son las siguientes (por orden de importancia):

1) Escasa participación de los usuarios finales (12,8%): El usuario es quien finalmente evaluará y aprobará o desaprobará el proyecto terminado. Por eso siempre se debe siempre de involucrar al usuario en la definición del proyecto y en los subsiguientes pasos. Se deben establecer canales y vías de comunicación constante con el usuario para poder brindarle la mayor información posible del avance del proyecto, para que éste pueda valorarlo y dar su feedback, que es la base para hacer los reajustes sin algo no estuviese del todo bien.

2) Requerimientos y especificaciones incompletas (12,3%): La ingeniería de requerimientos cumple un papel primordial en el proceso de producción de software, ya que enfoca un área fundamental: la definición de lo que se desea producir. Su principal tarea consiste en la generación de especificaciones correctas que describan con claridad, sin ambigüedades, en forma consistente y compacta, el comportamiento del sistema; de esta manera, se pretende minimizar los problemas relacionados al desarrollo de sistemas.

La ambigüedad ayuda a generar falsas expectativas y provoca enormes pérdidas de tiempo cuando lo que se implementa es la solución equivocada.

3) Cambios frecuentes en los requerimientos y especificaciones (11,8%): Durante el proceso de construcción de un sistema de información es común encontrarse con usuarios ávidos en añadirles nuevas funcionalidades o características al mismo. Esto se constituye en un factor peligroso ya que el equipo de desarrollo podría perder días, semanas y hasta meses valiosos haciendo algo que al usuario inicialmente no especificó. Los requerimientos de los usuarios tienen contienen generalmente muchas ambigüedades, malos entendidos, inconsistencias y omisiones.

4) Falta de soporte ejecutivo (7,5%): Todo proceso de cambio tecnológico genera cierto grado de oposición en las organizaciones. En este sentido los funcionarios de mayor rango deben estar comprometidos con este proceso y este compromiso debe ser transmitido a los demás miembros de la organización.

5) Incompetencia tecnológica (7,0%): La incompetencia tecnológica proviene de la resistencia, psicológica o cultural, de los usuarios para modernizar sus procedimientos de trabajo, roles y obligaciones organizacionales.

6) Falta o recorte de recursos (6,4%): La asignación de recursos humanos y materiales suele ser, en la práctica, uno de los aspectos que mas complicaciones produce en un proyecto. La definición y asignación de recursos implica de hecho prever tres elementos:

  • Qué tipo de recursos se van a usar
  • En qué cantidad
  • Durante cuanto tiempo

La mayoría de proyectos grandes que fracasan lo hacen porque se reducen sutilmente todos los recursos necesarios para llevarlos a cabo. Cualquier albañil sabe que hay una proporción correcta entre cal y cemento y que no se puede quitar un 5% de hierro a un edificio porque los precios del acero se hayan disparado. En informática, en cambio, es normal contratar un profesional de 3 años en experiencia en el puesto de uno de 5. No importa convertir 9 meses en 8 o US$100.000 del presupuesto en US$90.000. Se van metiendo pequeños recortes por todas partes, un poco de cada lado hasta que se arruina cualquier posibilidad de éxito

7) Expectativas no realistas (5,9%): Comparta toda la información posible con sus clientes, evitando el uso de la jerga técnica, y ayude a los clientes en la descripción de sus necesidades.

Aclare las percepciones de sus clientes y explicite las limitaciones de manera frontal y honesta.

8) Objetivos poco claros (5,3%): Un principio básico en la gestión de proyectos es que los objetivos estén definidos a priori y con un grado de suficiente de claridad y precisión. Los objetivos generalmente son: el resultado , el costo y el plazo del proyecto. Estos tres objetivos son inseparables y forman un sistema en el que cada modificación de cada una de las partes afecta a las restantes. Dado que la maximización individual de los tres criterios básicos no es posible, es necesario maximizar una cierta combinación entre ellos.

9) Cronogramas irreales (4,3%): Se deben estimar plazos realistas para cada una de las etapas del proyecto teniendo en cuenta los recursos disponibles. Es frecuente que los plazos se definan sin criterios técnicos

10) Nuevas tecnologías (3,7%):

Observemos que de los diez factores mencionados, siete están referidos a factores humanos (1 a 4 y 7 a 9). Si bien algunas de las metodologías cubren temas de comunicación, manejo de conflictos y negociación, en su abordaje se pone mucho más énfasis en los elementos hard (duros) que en los suaves (soft). Así, muchas metodologías cometen el error de prestigiar el contenido procedimental por encima del conceptual. Es decir, se apunta más al COMO que al QUE.

En este marco, para incrementar los resultados de los proyectos de IT, es fundamental reformar la educación en sistemas, adoptando un enfoque original y desafiante que comprenda no sólo la difusión de metodologías, técnicas y experiencias sino también el replanteo de varios paradigmas incorporando nuevos marcos conceptuales.

viernes, 21 de marzo de 2008

¿Qué son los IDE de Programación?

A la hora de crear arte hecho código fuente, muchas veces necesitamos un buen editor para escribir nuestro codigo, un compilador a mano o interprete según corresponda a nuestro lenguaje de programación, una conección a su base de datos facil y rapida si es que utilizamos. En fin muchas veces necesitamos escoger para nuestro lenguaje un Entorno de Desarrollo Integrado (IDE).

Un entorno de desarrollo integrado o en inglés Integrated Development Environment (IDE) es un programa compuesto por un conjunto de herramientas para un programador.

Los IDEs proveen un marco de trabajo amigable para la mayoría de los lenguajes de programación.

Los componentes que deben tener los IDEs son:

* Un editor de texto.
* Un compilador.
* Un intérprete.
* Herramientas de automatización.
* Un depurador.
* Posibilidad de ofrecer un sistema de control de versiones.
* Factibilidad para ayudar en la construcción de interfaces gráficas de usuarios.

Clasificación de los lenguajes de programación

Los lenguajes de programacion se determinan según el nivel de abstracción, Según la forma de ejecución y según el paradigma de programación que poseen cada uno de ellos y esos pueden ser:

Lenguajes de Bajo Nivel
Los lenguajes de bajo nivel son lenguajes de programación que se acercan al funcionamiento de una computadora. El lenguaje de más bajo nivel es, por excelencia, el código máquina. A éste le sigue el lenguaje ensamblador, ya que al programar en ensamblador se trabajan con los registros de memoria de la computadora de forma directa.


Lenguajes de Medio Nivel
Hay lenguajes de programación que son considerados por algunos expertos como lenguajes de medio nivel (como es el caso del lenguaje C) al tener ciertas características que los acercan a los lenguajes de bajo nivel pero teniendo, al mismo tiempo, ciertas cualidades que lo hacen un lenguaje más cercano al humano y, por tanto, de alto nivel.


Lenguajes de Alto Nivel
Los lenguajes de alto nivel son normalmente fáciles de aprender porque están formados por elementos de lenguajes naturales, como el inglés. En BASIC, el lenguaje de alto nivel más conocido, los comandos como "IF CONTADOR = 10 THEN STOP" pueden utilizarse para pedir a la computadora que pare si CONTADOR es igual a 10. Por desgracia para muchas personas esta forma de trabajar es un poco frustrante, dado que a pesar de que las computadoras parecen comprender un lenguaje natural, lo hacen en realidad de una forma rígida y sistemática.

Lenguajes compilados e interpretados

Este es un concepto muy claro que marca muchas veces diferencia entre los lenguajes de programación que normalmente utilizamos y es un punto clave a la hora de elegir uno para llevar a cabo nuestras aplicaciones. Como corresponde en este blog probaremos tanto lenguajes compilados como también lenguajes interpretados ...

Lenguajes compilados
Naturalmente, un programa que se escribe en un lenguaje de alto nivel también tiene que traducirse a un código que pueda utilizar la máquina (lenguaje de máquina). Los programas traductores que pueden realizar esta operación se llaman compiladores. Éstos, como los programas ensambladores avanzados, pueden generar muchas líneas de código de máquina por cada proposición del programa fuente. Se requiere una corrida de compilación antes de procesar los datos de un problema.

Los compiladores son aquellos cuya función es traducir un programa escrito en un determinado lenguaje a un idioma que la computadora entienda (lenguaje máquina con código binario).

Al usar un lenguaje compilado (como lo son los lenguajes del popular Visual Studio de Microsoft), el programa desarrollado nunca se ejecuta mientras haya errores, sino hasta que luego de haber compilado el programa, ya no aparecen errores en el código.

Lenguajes Interpretados
Se puede también utilizar una alternativa diferente de los compiladores para traducir lenguajes de alto nivel. En vez de traducir el programa fuente y grabar en forma permanente el código objeto que se produce durante la corrida de compilación para utilizarlo en una corrida de producción futura, el programador sólo carga el programa fuente en la computadora junto con los datos que se van a procesar. A continuación, un programa intérprete, almacenado en el sistema operativo del disco, o incluido de manera permanente dentro de la máquina, convierte cada proposición del programa fuente en lenguaje de máquina conforme vaya siendo necesario durante el proceso de los datos. No se graba el código objeto para utilizarlo posteriormente.

La siguiente vez que se utilice una instrucción, se le debe interpretar otra vez y traducir a lenguaje máquina. Por ejemplo, durante el procesamiento repetitivo de los pasos de un ciclo, cada instrucción del ciclo tendrá que volver a ser interpretado cada vez que se ejecute el ciclo, lo cual hace que el programa sea más lento en tiempo de ejecución (porque se va revisando el código fuente en tiempo de ejecución) pero más rápido en tiempo de diseño (porque no se tiene que estar compilando a cada momento el código completo). El intérprete elimina la necesidad de realizar una corrida de compilación después de cada modificación del programa cuando se quiere agregar funciones o corregir errores; pero es obvio que un programa objeto compilado con antelación deberá ejecutarse con mucha mayor rapidez que uno que se debe interpretar a cada paso durante una corrida de producción.

Base de datos

Uno de los conceptos básicos en el mundo de la informática de hoy es el de las Bases de datos. Este concepto es muy importante a la hora de la construcción de aplicaciones, es tan importante como la elección del lenguaje de programación y muchas cuestiones relacionadas con el mismo.

Una base de datos o banco de datos es un conjunto de datos que pertenecen al mismo contexto almacenados sistemáticamente para su posterior uso. En este sentido, una biblioteca puede considerarse una base de datos compuesta en su mayoría por documentos y textos impresos en papel e indexados para su consulta. En la actualidad, y debido al desarrollo tecnológico de campos como la informática y la electrónica, la mayoría de las bases de datos tienen formato electrónico, que ofrece un amplio rango de soluciones al problema de almacenar datos.

En informática existen los sistemas gestores de bases de datos (SGBD), que permiten almacenar y posteriormente acceder a los datos de forma rápida y estructurada. Las propiedades de los sistemas gestores de bases de datos se estudian en informática.

Las aplicaciones más usuales son para la gestión de empresas e instituciones públicas. También son ampliamente utilizadas en entornos cientí­ficos con el objeto de almacenar la información experimental.

Aunque las bases de datos pueden contener muchos tipos de datos, algunos de ellos se encuentran protegidos por las leyes de varios paí­ses.

Al igual que contamos con leguajes de programación de código libre o privativos con la adquisición de su licencia, también contamos con sistemas gestores de bases de datos, tanto libres como así­ también privativas.

¿Qué es SQL?

El Lenguaje de Consulta Estructurado (Structured Query Language o SQL) es un lenguaje declarativo de acceso a bases de datos relacionales que permite especificar diversos tipos de operaciones sobre las mismas. Una de sus características es el manejo del álgebra y el cálculo relacional permitiendo lanzar consultas con el fin de recuperar información de interés de una base de datos, de una forma sencilla. Es un lenguaje de cuarta generación (4GL).

Con respecto a las caracteristicas podemos decir que el SQL es un lenguaje de acceso a bases de datos que explota la flexibilidad y potencia de los sistemas relacionales permitiendo gran variedad de operaciones sobre los mismos. Es un lenguaje declarativo de alto nivel o de no procedimiento, que gracias a su fuerte base teórica y su orientación al manejo de conjuntos de registros, y no a registros individuales, permite una alta productividad en codificación. De esta forma una sola sentencia puede equivaler a uno o más programas que utilizasen un lenguaje de bajo nivel orientado a registro.

Optimización de código

En informática, la optimización de código es el proceso de modificar un sistema para hacer que algún aspecto de su trabajo sea más eficiente o se utilicen menos recursos. Por ejemplo, un programa de computador puede ser optimizado de modo que este se ejecute más rápidamente, o que sea capaz de operar con menos memoria de almacenamiento u otros recursos.

Aunque la palabra optimización comparte la misma raíz que la palabra óptimo, es raro que en un proceso de optimización se obtenga un sistema verdaderamente óptimo. Típicamente, el sistema optimizado solo será óptimo en una aplicación o en un cierto ámbito. Uno podría reducir la cantidad de tiempo que un programa toma para ejecutar cierta tarea pero el precio de hacerlo consume más memoria.

Frecuentemente no hay "un tamaño que se ajusta para todo" esto es, un diseño que trabaje en todos los casos. Así los ingenieros hacen trade-offs para optimizar los atributos de mayor interés. Adicionalmente, el esfuerzo requerido para hacer una pieza de software completamente óptimo - incapaz de alguna mejora adicional - es casi siempre más razonable para los beneficios que serán logrados; así el proceso de optimización podría ser detenido antes que una solución óptima completa haya sido alcanzado. Afortunadamente, es frecuente el caso de que las más grandes mejoras vienen rápido en el proceso.

La optimización puede ocurrir en un número de niveles. En el más alto nivel, el diseño puede ser optimizado para hacer mejor uso de los recursos disponibles. La implementación de este diseño se beneficiará del uso de algoritmos eficientes y la implementación de estos algoritmos beneficiará con la escritura de código de buena calidad.

Trade-off
La optimización generalmente se enfocará en mejorar solo uno o dos aspectos de la performance: tiempo de ejecución, uso de memoria, espacio en disco, ancho de banda, potencia de consumo o algún otro recurso. Esto usualmente requerirá un trade-off: donde un factor es optimizado en expensas de otros. Por ejemplo, incrementando el tamaño del caché mejora la performance en tiempo de ejecución, pero también incrementa el consumo de memoria. Otros comunes trade-offs incluye código claro y conciso.

Cuellos de botella
La optimización requiere determinar un cuello de botella: la parte crítica del código es el consumidor primario de los recursos necesarios. Como una regla de oro, la mejora de un 20% del código es responsable del 80% de los resultados (Principio de Pareto).

El principio de Pareto (también conocido como la regla 80-20) dice que para muchos fenómenos, el 80% de las consecuencias se derivan de un 20% de las causas.

En ciencia del computador, el Principio de Pareto puede ser aplicado para optimización de recursos observando que el 80% de los recursos son típicamente usados por el 20% de las operaciones. En ingeniería de software, es frecuente una mejor aproximación que el 90% del tiempo de ejecución de un programa de computadora es gastado ejecutando el 10% del código (conocida como la ley 90/10 en este contexto).

El diseño de la arquitectura de un sistema abrumadoramente afecta a su rendimiento. La elección del algoritmo afecta la eficiencia más que cualquier otro ítem de diseño. Algoritmos más complejos y estructuras de datos se ejecutan bien con muchos ítems, mientras que algoritmos más simples son más convenientes para pequeñas cantidades de datos.

En algunos casos, añadir más memoria puede ayudar a hacer un programa más rápido.

¿Cuando optimizar?
La optimización puede reducir la legibilidad del código fuente (facilidad con que se puede comprender el propósito, flujo y la operación de una sección de código fuente) que es usado para mejorar la performance. Esto puede complicar programas o sistemas haciéndolos más duros de mantener o debuggear. Como resultado de esto, la optimización o afinamiento de performance es frecuentemente ejecutado al final de la etapa de desarrollo.

Automatización manual y automatizada
La optimización de un sistema completo es usualmente realizado por humanos porque el sistema es demasiado complejo para optimizaciones automáticas. En esta técnica, los programadores o administradores del sistema cambian explícitamente código de modo tal que el sistema mejora. Aunque esto podría conducir a una mejor eficiencia, este es más caro que las optimizaciones automáticas.

Primero que todo, es extremadamente importante usar una herramienta de análisis de performance (profiler) para encontrar la secciones del programa que están tomando la mayor parte de los recursos (el cuello de botella). Los programadores usualmente piensan que ellos tienen una idea clara de donde esta el cuello de botella, pero la intuición falla frecuentemente. Optimizando una pieza insignificante de código típicamente hará poco para ayudar a la performance total.

Cuando el cuello de botella es localizado, la optimización usualmente se inicia rediseñando el algoritmo utilizado en el programa: la mayoría de las veces, un algoritmo particular puede ser adaptado específicamente a un problema particular, produciendo un mejor rendimiento que un algoritmo genérico. Por ejemplo, la tarea de ordenar una enorme lista de ítems se realiza habitualmente con un algoritmo quicksort, que es uno de los algoritmos genéricos más eficientes. Pero si algunos de las características de los ítems son aprovechables (si por ejemplo, ellos ya están ordenados en algún orden particular), un método diferente puede ser usado, o incluso una rutina de ordenamiento hecho a la medida.

Después que se está razonablemente seguro que el mejor algoritmo es seleccionado, la optimización de código puede comenzar: bucles pueden ser desenrollados (para disminuir la sobrecarga del bucle, aunque a menudo esto puede conducir a disminuir la velocidad si esto sobrecarga el caché del CPU), tipos de dato tan pequeños como sea posible usar, aritmética de enteros puede ser usado en lugar de punto-flotante, y así sucesivamente.

Los cuellos de botella de performance pueden ser debidos a limitaciones del lenguaje de programción antes que algoritmos o estructuras de datos usadas en el programa. A veces, una parte crítica del programa puede ser re-escrita en un lenguaje diferente que da acceso más directo a la máquina subyacente. Por ejemplo, es común para lenguajes de muy alto nivel como Pitón tener módulos escritos en C para mayor velocidad. Programas ya escritos en C pueden tener módulos escritos en ensamblador.

La reescritura vale la pena debido a una regla general conocida como la ley 90/10, que dice que el 90% del tiempo es gastado en el 10% del código, y solo el 10% del tiempo en el restante 90% del código. Así poniendo esfuerzo intelectual en optimizar solo una parte pequeña del programa puede tener un enorme efecto en la velocidad total si la parte(s) correcta(s) puede(n) ser localizada(s).

Tiempo tomado para la optimización
En algunos casos, el tiempo tomado para la optimización en si mismo puede ser un problema.

En un proyecto de software, la optimización de código usualmente no añade un nuevas características, y peor aún, esto podría romper ciertas funcionalidades. Debido a que código optimizado tiene menos legibilidad que un código sencillo, la optimización puede bien afectar la legibilidad del programa. En resumen, la optimización se convierte en un costo y es importante estar seguro que la inversión vale la pena.