Tabla de Contenidos
Fundamentos de Desarrollo de Software
La labor de desarrollo de software es realizada por un programador, o un equipo de programación. El desarrollador de software puede contribuir en la visión general del proyecto más a nivel de aplicación que a nivel de componentes, así como a las tareas de programación individuales. También puede realizar la función de analista o de programador, arquitecto de la aplicación, etc.
El concepto de desarrollo de software incluye:
- Trabajo en equipo: los proyectos en la mayor parte de los casos parte de la colaboración entre diferentes desarrolladores, y también de otros tipos de colaboradores, comerciales (definen junto al cliente la finalidad y necesidades del producto), diseñadores gráficos (definen el aspecto de la interfaz gráfica, GUI, de la aplicación). En muchos casos los roles de el equipo pueden ser llevados a cabo por desarrolladores.
- Concepción o diseño a partir de unas condiciones, especificaciones o requisitos.
- Pruebas: investigaciones y técnicas cuyo objetivo es proporcionar información objetiva e independiente sobre la calidad del producto, siendo una actividad más en el control de calidad.
- Mantenimiento: abarca la corrección de errores o modificaciones después de que haya comenzado el uso comercial del programa informático.
Lenguajes de Programación
Según su nivel de abstracción
Se entiende como la separación de un elemento de su contexto, o del resto de elementos que lo acompañan. La abstracción se centra en el ¿Qué hace? más que en el ¿Cómo lo hace?.
- Lenguajes de Alto Nivel
Los lenguajes de alto nivel son aquellos que expresan sus algoritmos de forma comprensible por la capacidad humana, en lugar de la capacidad de las máquinas. Cuando hay un gran nivel de abstracción tratamos con variables, matrices, objetos, aritmética, funciones, en lugar de con registros del procesador, direcciones de memoria, o las pilas de llamadas. Generan un código más sencillo y comprensible, permitiendo que en algunos casos pueda ser para diferentes máquinas o sistemas operativos. Permiten utilizar diferentes paradigmas de programación. Ejemplos: Java, Ada, Visual BASIC, VB .NET, C#, FORTRAN, Lisp, Pascal, Python, Perl, PHP, Ruby, SQL
- Lenguajes de Nivel Medio
Tienen características que los acercan a los lenguajes de bajo nivel, pero a la vez también tiene características de los lenguajes de alto nivel. Se suelen utilizar para la aplicaciónes como la creación de sistemas operativos (p.e. Unix en C) Ejemplos: C, C++
- Lenguajes de Bajo Nivel
El bajo nivel de abstracción se centra en lenguajes próximos a los que entiende la máquina, código máquina. Ejercen un control directo sobre el hardware (memoria, cpu) y dependen de la estructura física de este. Es por esto que los programas escritos en lenguajes de bajo nivel no son portables entre distintos equipos. Apuntemos que el código máquina es el código nativo de cada procesador, está organizado en instrucciones y se ejecuta directamente. No es un código escrito por programadores. Ejemplos: código máquina, lenguaje ensamblador.
Según su forma de ejecución
- Lenguajes Compilados
Son aquellos que generan un código resultante que posteriormente será ejecutado. Esto puede darse, creando un archivo ejecutable con el código máquina, preparado para su ejecución directa por la máquina física. Pero algunos lenguajes actuales también permiten compilar su código fuente dando como resultado un código intermedio, almacenado en un fichero. Este fichero es interpretado posteriormente y ejecutado directamente paso a paso (convertido paso a paso a código máquina). Los programas compilados a código nativo en tiempo de compilación, suelen ser más rápidos que los traducidos en tiempo de ejecución. Generan el problema de que el código máquina creado es dependiente de la arquitectura de la plataforma en la que se compilan y para la que se ejecutan. Ejemplos: C, C++, Visual Basic, Fortran, Pascal
- Lenguajes Interpretados
Son lenguajes cuyas instrucciones se traducen para ser ejecutadas por la máquina hardware en el mismo momento de la ejecución, sin crear ningún código intermedio, ni guardar el resultado de dicha traducción. Son más lentos que los lenguajes compilados debido a la necesidad de traducir a código máquina el programa, instrucción a instrucción, mientras se ejecuta. Debido a esta ejecución en tiempo real, no se traduce la totalidad del conjunto de instrucciones, sino se va traduciendo a medida que se van ejecutando cada una de ellas. Permiten ofrecer al programa interpretado un entorno no dependiente de la máquina donde se ejecuta el interprete, sino del propio interprete. Ejemplos: Html, Php, Python, Ruby, Javascript
- Lenguaje Intermedio
Conocemos bajo este concepto el producto de la compilación de algunos lenguajes de alto nivel en un tipo de lenguaje (bytecode). Para mejorar el proceso de optimización o facilitar la portabilidad, algunas implementaciones de lenguajes de programación pueden compilar el código fuente original en una forma intermedia y después traducir (interpretar) ese al código máquina mediante una (máquina virtual). Esto ocurre con lenguajes como Java o C#.
Según su sistema de tipos
En una clasificación menos convencional y poco consensuada, pero también es una característica importante de los lenguajes de programación. Los tipos de datos de cada lenguaje, representan la naturaleza de los datos que un programa puede emplear. Por ejemplo: valores numéricos (números enteros, decimales, naturales, etc), valores lógicos (verdadero o falso), valores de texto (caracteres, cadenas fijas, cadenas variables), expresiones matemáticas, etc.
- Lenguajes fuertemente tipados (tipado estático): Un lenguaje de programación es fuertemente tipado si no se permiten violaciones de los tipos de datos, es decir, una vez definido el tipo de una variable, no se puede usar como si fuera de otro tipo distinto a menos que se haga una conversión. Cada tipo de datos tiene un dominio de valores (rango, valores permitidos) y su tipo de datos controla que no podamos salirnos de su dominio. Para convertir de unos tipos a otros debemos usar sentencias de conversión. Ejemplos: Java, C++, C, C#
- Lenguajes débilmente tipados (tipado dinámico): Los lenguajes de programación no tipados o débilmente tipados no controlan los tipos de las variables que declaran, de este modo, es posible usar valores de cualquier tipo en una misma variable. Por ejemplo, una función puede recibir indiferentemente como parámetro un valor entero, cadena de caracteres, número flotante, etc. Un lenguaje que no está tipado se refiere a que no está fuertemente tipado. Son lenguajes en los que no se define el tipo de una variable y puede almacenar distintos tipos de datos: números, caracteres, etc. Ejemplo: Javascript, Python
Construccion de un programa informático
Para ver nuestro programa en ejecución, debemos aplicar unos procesos intermedios mediante los cuales nuestro programa cambia de un estado a otro hasta que obtenemos una versión ejecutable. Este concepto se conoce como Build.
- Código Fuente: Es el código escrito por los programadores utilizando algún editor de texto o algun entorno de desarrollo. Este código no es directamente ejecutable por el ordenador.
- Código Objeto: Es el código resultante de compilar el código fuente. No es directamente ejecutable por el ordenador, pero tampoco es entendido por el ser humano. Es un código o representación intermedia de bajo nivel.
- Código Ejecutable: Es el resultado de enlazar el código objeto con una serie de rutinas y librerías, obteniendo el código que es directamente ejecutable por la máquina.
Proceso de compilación
La obtención de un programa ejecutable se lleva a cabo mediante dos programas: el compilador y el enlazador (linker). Aunque difiere dependiendo de la tecnología o plataforma de programación que usemos.
Aun así, la compilación se compone internamente de varias etapas:
- Análisis léxico: se lee secuencialmente todo el código fuente agrupándolo en unidades significativas de caracteres (tokens). Son secuencias de caracteres que tienen significado (int, =, void, …). Todos los espacios en blanco, lineas en blanco, comentarios, etc, se eliminan del programa fuente.
- Analizador sintáctico: recibe el código fuente en forma de tokens (componentes léxicos) y se agrupan jerárquicamente en frases gramaticales que el compilador utiliza para sintetizar la salida. Se comprueba si lo obtenido de la fase anterior es sintácticamente correcto (obedece a la gramática del lenguaje). Por lo general, las frases gramaticales del programa fuente se representan mediante un árbol de análisis sintáctico.El proceso es semejante al análisis gramatical de una frase en lenguaje natural.
- Analizador semántico: se comprueban que las declaraciones son correctas, se verifican los tipos de todas las expresiones, si las operaciones se pueden realizar sobre esos tipos, si los arrays tienen el tamaño adecuado, etc. Esta información se añade al árbol de análisis sintáctico.
- Generación del código intermedio: después del análisis se genera una representación intermedia similar al código máquina con el fin de facilitar la tarea de traducir al código objeto.
En los lenguajes compilados completamente a codigo máquina, la fase de enlazado (linker) une todos los códigos objetos resultados de la compilación de todos los ficheros fuentes que forman parte de un programa. También se une el código de los métodos de las librerías usadas. Todos estos códigos objetos se traducen a código máquina creando un programa ejecutable (p.e. un fichero .exe).
Máquina virtual
En el caso de que nuestra plataforma use una máquina virtual para ejecutar nuestro código compilado, la máquina se inicia automáticamente cuando se lanza el programa que se desea ejecutar y se detiene cuando se finaliza. Este tipo de máquinas virtuales se conocen como máquinas virtuales de proceso, y son en sí un proceso normal más dentro del sistema operativo. Su objetivo es el de proporcionar un entorno de ejecución independiente de la plataforma de hardware y del sistema operativo. El ejemplo más conocido es la Java Virtual Machine.
La máquina virtual de java se encarga de cargar, verificar, enlazar e inicializar los ficheros .class obtenidos del proceso de compilación de los fuentes .java.
- El proceso de compilación del código fuente, es el mismo descrito en el punto anterior hasta obtener un código intermedio. A diferencia del anterior, la fase de enlazado se realiza cada vez que se ejecuta el programa.
- En el proceso de carga se buscan los ficheros binarios de las clases (ficheros .class) atendiendo a los identificadores y se crea la clase a partir de esos ficheros binarios.
- En la fase de verificación se comprueban que los bytecodes recibidos no contienen instrucciones que son obviamente dañinas para el sistema.
- Fase de enlace, es el momento en el que se cogen las clases o interfaces y se combinan en un estado de ejecución de la máquina virtual y se van traduciendo mediante el interprete (linea a linea) y el compilador JIT de Java (Just In Time, compila el fichero class completo) a código nativo. Este código es ejecutado.
A diferencia de los lenguajes compilados, en este tipo de funcionamiento el enlazado de las clases y las librerías y la traducción a código máquina se realiza cada vez que ejecutamos el programa, por lo que es más lento que otros lenguajes puramente compilados.
© 2024 Fernando Valdeón