miércoles, 30 de septiembre de 2015

Los diagramas de flujo son una manera de representar visualmente el flujo de datos a travéz de sistemas de tratamiento de información. Los diagramas de flujo describen que operaciónes y en que secuencia se requieren para solucionar un problema dado.
Un diagrama de flujo u organigrama es una representación diagramática que ilustra la secuencia de las operaciones que se realizarán para conseguir la solución de un problema. Los diagramas de flujo se dibujan generalmente antes de comenzar a programar el código frente a la computadora. Los diagramas de flujo facilitan la comunicación entre los programadores y la gente del negocio. Estos diagramas de flujo desempeñan un papel vital en la programación de un problema y facilitan la comprensión de problemas complicados y sobre todo muy largos. Una vez que se dibuja el diagrama de flujo, llega a ser fácil escribír el programa en cualquier idióma de alto nivel. Vemos a menudo cómo los diagramas de flujo nos dan ventaja al momento de explicar el programa a otros. Por lo tanto, está correcto decir que un diagrama de flujo es una necesidad para la documentación mejor de un programa complejo.
Reglas para dibujar un diagramas de flujo.
Los Diagramas de flujo se dibujan generalmente usando algunos símbolos estándares; sin embargo, algunos símbolos especiales pueden también ser desarrollados cuando séan requeridos. Algunos símbolos estándares, que se requieren con frecuencia para diagramar programas de computadora se muestran a continuación:
Inicio o fin del programa
Pasos, procesos o líneas de instruccion de programa de computo
Operaciones de entrada y salida
Toma de desiciónes y Ramificación
Conector para unir el flujo a otra parte del diagrama
Cinta magnética
Disco magnético
Conector de pagina
Líneas de flujo
Anotación
Display, para mostrar datos
Envía datos a la impresora
Observación: Para obtener la correcta elaboración de los símbolos, existen plantillas. Las puedes conseguir en Papelerías.
Simbolos gráficos
Dentro de los simbolos fundamentales para la creaación de diagramas de flujo, los símbolos gráficos son utilizádos especificamente para para operaciónes aritméticas y relaciónes condicionales. La siguiente es una lista de los símbolos más comunmente utilizados:
+ Sumar
- Menos
* Multiplicación
/ División
± Mas o menos
= Equivalente a
> Mayor que
< Menor que
³ Mayor o igual que
£ Menor o igual que
¹ o <>
Diferente de
  Si
  No
  True
  False
Reglas para la creacion de Diagramas
  1. Los Diagramas de flujo deben escribirse de arriba hacia abajo, y/o de izquierda a derecha.
  2. Los símbolos se unen con líneas, las cuales tienen en la punta una flecha que indica la dirección que fluye la información procesos, se deben de utilizar solamente líneas de flujo horizontal o verticales (nunca diagonales).
  3. Se debe evitar el cruce de líneas, para lo cual se quisiera separar el flujo del diagrama a un sitio distinto, se pudiera realizar utilizando los conectores. Se debe tener en cuenta que solo se vana utilizar conectores cuando sea estrictamente necesario.
  4. No deben quedar líneas de flujo sin conectar
  5. Todo texto escrito dentro de un símbolo debe ser legible, preciso, evitando el uso de muchas palabras.
  6. Todos los símbolos pueden tener más de una línea de entrada, a excepción del símbolo final.
  7. Solo los símbolos de decisión pueden y deben tener mas de una línea de flujo de salida.
Ejemplos de diagramas de flujo
Diagrama de flujo que encuentra la suma de los primeros 50 numeros naturales

Bueno, y ahora la descripción del diagrama anterior

Suma, es la variable a la que se le va agregando la valor de cada número natural. N, es el contador. Éste recorrerá lo números hasta llegar al 50.
  • El primer bloque indica el inicio del Diagrama de flujo Inicio del Diagrama de flujo
  • El segundo bloque, es un Símbolo de procesos Bloque de proceso En este bloque se asume que las variables suma y N han sido declaradas previamente y las inicializa en 0 para comenzar a el conteo y la suma de valores (Para declararlas existe el bloque Tarjeta perforada).
  • El tercer bloque, es también un Símbolo de procesos Bloque de procesos En éste paso se incrementa en 1 la variable N (N = N + 1). Por lo que, en la primera pasada esta N valdrá 1, ya que estaba inicializada en 0.
  • El cuarto bloque es exactamente lo mismo que el anterior Bloque de procesos Pero en éste, ya se le agrega el valor de N a la variable que contendrá la suma (En el primer caso contendrá 1, ya que N = 1).
  • El quinto bloque es uno Símbolo de Toma de decisiones y Ramificación Lo que hay dentro del bloque es una pregunta que se le hace a los valores que actualmente influyen en el proceso 
  • Símbolo de toma de desiciónes y Ramificación  
  • ¿Es N=50?, Obviamente la respuesta es no, ya que N todavía es 1. por lo que el flujo de nuestro programa se dirigirá hacía la parte en donde se observa la palabra no: Tercer Bloque, éste le sumará 1 (N=N+1) y vuelve a llegar a éste bloque, donde preguntará ¿Es N=50?... ¡No!, todavía es 2. Ha pues, regresa al Tercer bloque y vuelve hacer lo mismo. Y así hasta llegar a 50, obteniendo así la suma de los primeros 50 primeros números naturales.
  • Por último indicamos que el resultado será mostrado en la impresora (Este lo puedes cambiarlo por el display para mostrar datos). Bloque de Display
  • Fin del programa (o diagrama) Fin del diagrama

martes, 29 de septiembre de 2015

¿”Java es lento”?
Java tuvo sus inicios en 1991, y Sun Microsystems lo liberó al público en 1995. Aunque el lenguaje heredó mucha de sus sintaxis de C/C++, los objetivos de Java en aquél entonces pueden resumirse en los siguientes principios:
• Simple, orientado a objetos y familiar.

• Robusto y seguro.

• Arquitectónicamente neutro y portable.

• Ejecutándose en “alto desempeño”.

• Interpretado, con soporte a paralelismo y dinámico.
El compilador de Java convierte el código fuente en archivos bytecode, que posteriormente son interpretados por la Máquina Virtual de Java o JVM, en un modelo de ejecución en pila o stack. Las primeras versiones de Java – previas a la 1.2 – no realizaban optimizaciones en el bytecode y debido a que las diferentes versiones de JVM eran más bien genéricas, la ejecución tenía un desempeño pobre.
A partir de la versión 1.2 (Diciembre de 1998), Java incluyó un compilador Just-In-Time o JIT, que optimizaba el bytecode en tiempo real de acuerdo a la carga de trabajo sobre el programa. Como contraste, un modelo de compilación estática como C/C++ “adivina” dónde se encuentran los cuellos de botella y se enfoca en esa parte del código para realizar la optimización, pero en el caso de ambientes dinámicos como las aplicaciones web, el compilador JIT mantiene una relativa ventaja. Por otro lado, con cada nueva versión de Java, el lenguaje ha ido mejorando su desempeño, ya sea por optimización en la JVM, el recolector de basura o el compilador JIT. De acuerdo a este artículo, podemos ver la comparación en desempeño entre C++ y Java en algunas funciones relativamente sencillas. Lo sorprendente es lo malo que se desempeña C++ si durante la secuencia de compilación y enlace (linking) se deshabilitan todas las banderas de optimización de código. Adicionalmente, de la versión 6 a la 7, Java mejora su desempeño en alrededor de un 33%:
Función Ejemplo Java SE 6 (2010) Java SE 7 (2012) C++ (optimizado) C++ (sin optimizar)
Aritmética entera int Y = rand(X) * 2 25 16 0.001427 70
Aritmética de punto flotante double Y = rand(X) * 2.0 47 28 0.001477 85
Comparación de enteros if A == B then X = B else X = B 50 33 0.001971 56
Acceso a memoria indexada for i = 0 to N: int X = array[n] 53 25 11 136
Asignación de memoria – tipo primitivo for i = 0 to N: int array[n] = X 12,994 7,589 3,661 8,567
Asignación de memoria – objetos for i = 0 to N: Object array[n] = X 710,788 191,581 29,348 70,436

Tiempos de ejecución en milisegundos (excepto la asignación de memoria, dada en nanosegundos) para algunas funciones en C++ y Java. La ejecución de J2SE 7 se realizó el 10/12/2012. Fuente: developer.com
Podemos deducir que el problema de desempeño no reside en el lenguaje mismo, sino en el compilador y en su caso, la JVM. De hecho, existen dos ejemplos de esta dependencia:
• Es bien sabido por muchos que JRockit, la JVM construida por BEA Systems (ahora Oracle) y publicada en 2002, es mucho más escalable en ambientes con una fuerte demanda de recursos que HotSpot, la JVM originalmente concebida por Sun Microsystems. Tanto así que la próxima Java SE 8, por liberar en Septiembre de 2013, tendrá integrado el core de JRockit.
• Por el contrario, algunas versiones de C++ para Linux sobre Intel pueden tener un nivel de optimización tan mediocre (por ejemplo, G++ [gcc] 3.3.1), que incluso con código escrito por el mejor programador, pueden tener un desempeño equivalente o más lento que el de Java, con lo que muchos fans de éste lenguaje justifican la afirmación de que “Java es más rápido que C++” (idea que por cierto, también es errónea).
Finalmente, debemos considerar la manera en que se está usando el lenguaje cuando hablamos de desempeño. En el caso de Java, tenemos el clásico ejemplo de Vector vs. ArrayList: mientras un Vector es una colección de datos “segura” para implementar hilos de ejecución y paralelismo, ésta genera un fuerte golpe al desempeño debido a que controla el acceso concurrente sobre los elementos que ésta almacena. Por ello, tampoco es sano realizar nuestras comparaciones sin primero verificar que el código fuente está optimizado, ya que en algunos casos la programación es tan mala que el tiempo de ejecución se incrementará enormemente.
Java vs. C++: una comparación histórica
¿Cómo se comparan Java y C++ en términos de programas “de la vida real”? Actualmente abundan muchos microbenchmarks como el arriba mostrado, donde se verifican funciones muy simples, como manipulación de arreglos o acceso a memoria. Sin embargo, la mayoría de los casos de prueba son demasiado básicos como para ser un indicador confiable del desempeño. En la actualidad, existe un estudio comparativo formal: desarrollado por J. P. Lewis y Ulrich Neumann, investigadores de la Universidad del Sur de California (USC), el estudio se basa en 5 pruebas con diferentes versiones de Java y C++. Sus resultados, en términos generales, fueron los siguientes:
• Al comparar algoritmos numéricos como FFT, factorización de matrices o SOR en diferentes arquitecturas y compiladores, los investigadores encontraron que el desempeño de Java en plataformas Intel es razonablemente cercano al de C++ y que Java era más rápido que al menos un compilador en C (KAI sobre Linux Red Hat 5.0). En hardware con Intel Pentium, especialmente con Linux, la diferencia en desempeño es lo suficientemente pequeña como para carecer de importancia.
• Al utilizar el benchmark SciMark2 en una plataforma Intel, ellos encontraron que el IBM JDK 1.3.0 generaba un poder de procesamiento de 84.5 MFlops, mientras que el compilador de linux2.2 gcc (2.9x) era marginalmente mejor con 87.1 MFlops. Es decir, Java era tan sólo 3% más lento que C++.
• Utilizando implementaciones de métodos numéricos mediante objetos, ellos encontraron que Java se aproximaba bastante a los tiempos que tardaba C++ en ejecutarse. Por ejemplo, para generar el Triángulo de Pascal, Java tardaba 9 milisegundos mientras C++ tardaba 1.1 segundos. Para una Factorización LU, Java tardaba 1 segundo en resolver el problema mientras C++ tardaba hasta 3.9 segundos.
• Implementando microbenchmarks con y sin cache, los investigadores encontraron que Java se encuentra justo a la mitad entre los mejores y los peores compiladores de C++. Es decir, Java 3 es mejor que gcc 3.2, pero nunca le ganará a un gcc 4.1.0.
El problema que tengo con este estudio es que fue desarrollado hace ya algún tiempo – en aquél entonces, Lewis y Neumann compararon Java 2 o 3 contra las versiones de C++ disponibles entre 2003 y 2004 – por lo que si bien podemos darnos una mejor idea de que la velocidad de los programas definitivamente depende del compilador, hoy por hoy tendríamos que correr todas estas pruebas en plataformas multi-core, con la última versión de software disponible para darnos cuenta cuál es el estatus actual de esta “carrera armamentista”.
Java 7 vs. C++ (gcc) 4.6.3
Afortunadamente, los amigos de Debian han hecho su tarea de forma magnífica. Mediante crowdsourcing, ellos han estado comparando no sólo Java y C++, sino también implementaciones de otros lenguajes como Fortran, Ruby o Perl. Incluyendo árboles binarios, fractales de Mandelbrot o el cálculo de Pi (π), los resultados son bastante coherentes. Aunque las pruebas se desarrollaron en diferentes plataformas, para este caso nos enfocaremos en los resultados de correr estos programas en Intel Q6600 (Quad Core) con Ubuntu 5.10 x64:
Prueba Java SE 7 C++ 4.6.3 Mejor de su tipo (factor = 1.0)
N-Body 2.1 1.0 C++
Fannkuch-redux 1.9 1.4 ADA 2005 GNAT
Meteor-contest 15.0 1.0 C++
Fasta 3.4 1.7 C
Spectral-norm 2.3 1.0 Fortran Intel, ADA 2005 GNAT, C++ (empate)
Reverse-complement 1.9 1.0 C++
Mandelbrot 1.9 1.7 Fortran Intel
K-nucleotide 1.1 1.0 C++
Regex-dna 5.3 1.7 C
Pidigits 2.4 1.2 ATS
Chameneos-redux 7.8 1.1 ADA 2005 GNAT, C (empate)
Thread-ring 41.0 21.0 Haskell GHC
Binary-trees 1.6 1.6 C

Factor de desempeño en Java y C++ para diversos algoritmos matemáticos. El factor se mide como 1.0 = tiempo con el mejor desempeño. En la tabla se muestra que para el programa Fannkuch-redux, Java tardó 1.9 veces el mejor tiempo, mientras que C++ tardó 1.4 veces el mejor tiempo. En este ejemplo, el mejor tiempo se lo llevó el lenguaje ADA 2005 GNAT. Fuente: debian.org
Obteniendo la media, mejores y peores tiempos, también incluidos en el estudio, nos damos cuenta que Java no está lejos de alcanzar la velocidad de C++, aunque todavía permanece por debajo del desempeño logrado por éste lenguaje y sus optimizaciones:
Lenguaje Mejor Tiempo Peor Tiempo Media
C++ 1.00 1.69 1.21
Java 7 1.13 3.46 1.95

Comparación de desempeño para todas las pruebas en Java y C++. Fuente: debian.org
De hecho, si sólo tomamos los valores de la media, nos daremos cuenta que el factor de desempeño de Java es de 3.46/1.69 = 2.06 contra el de C++. Es decir, una relativamente amplia variedad de programas escritos en Java tardarían aproximadamente el doble de lo que tardarían si fueran escritos en C++. Esto es un precio a pagar muy pequeño si tomamos en cuenta los otros beneficios de Java, como portabilidad, facilidad de uso, o impedir que los programadores administren la memoria directamente (apuntadores, ¿alguien?).
Conclusiones
Aunque todavía le falta camino por recorrer, durante los últimos años Java ha disminuido su factor de desempeño contra C++ hasta alrededor del doble en plataformas Linux-Intel. Por lo que es necesario “iluminar a los no iniciados” para que se den cuenta que la “lentitud de Java” es una leyenda urbana que ha perdurado por más de 15 años sin un verdadero análisis que lo respalde. Por otro lado, es importante reconocer que ningún lenguaje es la “bala de plata”, por lo que Java o C++ deben implementarse de acuerdo al problema que queremos resolver: para acceder a recursos de bajo nivel como drivers, rutinas matemáticas o código embebido de alto desempeño, la respuesta la encontramos en C++. Para programas orientados a negocios o web que requieran facilidad de modificación, portabilidad o simplemente, cuyos problemas de desempeño puedan ser “matados a billetazos” (es decir, pagando por agregar hardware más potente), Java es una buena opción. Para finalizar, esto no debería ser una competencia para ver “quién es el mejor”, sino encontrar la manera de complementar ambos lenguajes. Después de todo, ambos son los más populares entre los programadores. En nuestro caso particular, una opción interesante será tener el procesamiento geoespacial en C++, mientras dejamos todo lo demás en Java y sus múltiples frameworks de desarrollo.
Lo principal a la hora de decidirnos por un lenguaje de programación u otro es saber qué es lo que queremos construir, qué tipo de programa o aplicación queremos desarrollar. En ese sentido, la web Dev/Code/Hack nos ofrece esta clasificación de los distintos idiomas según sus funcionalidades:
  • Webs/Front-end: HTML, CSS y Javascript. Para desarrollar la parte “visible” es necesario que el desarrollarlo tenga también experiencia en diseño.
  • Servidores/Back-end: Python, Ruby, PHP, Java o .Net. En estos casos se requieren además conocimientos de bases de datos y de administración de sistemas.
  • Aplicaciones Móviles: Objective C (iOS) y Java (Android). HTTML / CSS para sitios web móviles.
  • Videojuegos y apps 3D: C/C++ y OpenGL. Su programador debe ser además experto en diseño y tener un toque artístico.
  • Aplicaciones de alto rendimiento: C/ C++ y Java, acompañados de un experto en matemáticas y análisis cuantitativo.

Python, el más sencillo de aprender

Aunque todos los lenguajes se asemejan y el aprendizaje de uno sirve como background a la hora de introducirnos en el siguiente, sí es cierto que hay lenguajes que son más sencillos de aprender que otros. Python es considerado habitualmente como el lenguaje más sencillo y recomendado para los desarrolladores más noveles. Python es un lenguaje de programación interpretado que tiene como principal particularidad su extrema simplicidad en su sintaxis: no hace falta ser exacto ni tremendamente precisos al escribir el código ya que el sistema reconocerá esos detalles que nos falten.
Java, el lenguaje de programación desarrollado por Sun Microsystems e impulsado ahora por Oracle, que adquirió la anterior empresa en 2009, también es muy sencillo de comprender, más aún gracias a la enorme comunidad de usuarios que existe a escala global y los miles de tutoriales que recorren la red. Es un lenguaje limitado en cuanto a sus capacidades que sus competidores, pero a cambio se trata de uno de los más atractivos de la actualidad gracias a su presencia no sólo en PC sino también en los millones de smartphones Android, cuyas aplicaciones utilizan este lenguaje como base para su desarrollo. java-logo Esta es la norma general, pero ya sabemos que la mente de cada cual funciona de forma particular, con lo que al final la sencillez de un lenguaje u otro dependerá mucho de la afinidad y la capacidad del programador.

 ¿Cuál es el más demandado?

Junto a Java, el lenguaje de programación más popular es C. Este idioma, con su brevísimo nombre, es el padre de todos los demás lenguajes (Java, de hecho, deriva de él aunque tiene menos utilidades de bajo nivel) y, además, es uno de los más completos y que permite un mayor control sobre todo el proceso de desarrollo. En este mismo campo, existe otro lenguaje conocido como C++ y cuya diferencia con C radica en que se convierte en un idioma multiparadigma, al incorporar la programación genérica, programación estructurada y la programación orientada a objetos.
Javascript es otro de los más utilizados a diario. Todos los que accedemos a Internet estamos, aunque no lo sepamos, ejecutando procesos escritos en este lenguaje. Aunque su nombre haga referencia a Java, su relación es más simbólica que real (en sus orígenes Netscape quiso asociarlo al Java de su partner Sun Microsystems), ya que Javascript es un idioma construido sobre C++ con algunos componentes de Java y que es utilizado por todos los navegadores web para ejecutar códigos más complejos de los que permite el HTML. microsoft2
En el ámbito empresarial hemos de destacar también a .NET, el framework de desarrollo de Microsoft. Aunque no se trate literalmente de un lenguaje de programación (de hecho permite integrar textos escritos en C++, C# o Visual Basic), lo cierto es que .NET acaba convirtiendo todos estos idiomas a un código intermedio, conocido como CIL (Common Intermediate Language), muy usado en aplicaciones de negocio y sistemas desarrollados para Windows.