CONTENIDOS TEÓRICOS

1. Orígenes y Concepto del Software

El término informática nace como un acrónimo derivado de la frase: INFORmación de forma autoMÁTICA.

Evolución Histórica

  • Charles Babbage (1791-1871): Precursor del concepto de software. Durante el diseño de su máquina diferencial, planteó el uso de series de instrucciones leídas desde la memoria principal del sistema, refiriéndose a ellas de forma primitiva como software.
  • Ada Lovelace (1815-1852): En 1843, tradujo y amplió de forma masiva las notas del ingeniero Luigi Menabrea sobre la máquina de Babbage. En su apéndice incluyó un algoritmo detallado para calcular los Números de Bernoulli, considerado de forma unánime como el primer programa informático de la historia y encumbrándola como la primera persona programadora.
  • Alan Turing (1912-1954): Matemático y criptógrafo clave en el desciframiento de los códigos de la máquina ENIGMA en la Segunda Guerra Mundial. Diseñó el modelo teórico de la Máquina de Turing y desarrolló la teoría de la computación fundamental para la ciencia de la computación moderna.
  • John Wilder Tukey (1915-2000): Empleó formalmente el término "computer software" por primera vez en un artículo publicado en 1958 en la revista American Mathematical Monthly. En él describió la capacidad de escribir conjuntos de instrucciones complejas que luego se traducirían para las máquinas, sentando las bases de los compiladores modernos. Adicionalmente, acuñó el término bit como contracción de binary digit.

Nota histórica

Parte del cerebro de Charles Babbage se encuentra conservado en formol en el Royal College of Surgeons de Londres.


2. Arquitectura del Ordenador y Ejecución de Programas

Datos e Instrucciones

Un programa consiste en una secuencia ordenada de instrucciones que permiten procesar datos de entrada con el fin de generar datos de salida útiles.

  • Los Datos: Valores independientes del soporte físico que cumplen requisitos para ser representados e interpretados. Su unidad atómica son los caracteres (letras, dígitos, signos de puntuación y caracteres de control).
  • Las Instrucciones: Acciones atómicas elementales con un significado concreto y una duración de ejecución limitada en el tiempo.
[ Entrada (Periféricos/Disco) ] ➔ [ Memoria RAM (Datos/Instrucciones) ] ➔ [ Procesador (CPU) ] ➔ [ Salida ]

Componentes Hardware Clave y su Relación con el Software

  1. El Procesador (CPU): Es el elemento ejecutor principal.
  2. Unidad de Control (CU): Lee las instrucciones de la memoria, las decodifica y dirige el flujo de ejecución.
  3. Unidad Aritmético-Lógica (ALU): Realiza las operaciones matemáticas y lógicas que dictan las instrucciones.
  4. Registros: Pequeñas celdas de memoria ultrarrápida dentro del procesador que contienen los datos inmediatos con los que trabaja la ALU (ej. Program Counter, Accumulator).
  5. Memoria Principal (RAM): Es el espacio de almacenamiento volátil y de alto acceso donde residen las instrucciones del programa y los datos activos durante la ejecución.
  6. Memoria Secundaria (Almacenamiento Persistente): Disco duro (SSD/HDD) donde el programa permanece guardado en forma de archivo ejecutable mientras no está en uso.
  7. Periféricos de Entrada/Salida (E/S): Dispositivos que permiten recibir datos externos (teclado, ratón, red) y devolver los resultados procesados (pantalla, archivos, impresora).
  8. Buses de Comunicación: Vías físicas que interconectan la CPU, la RAM y los dispositivos (Buses de Datos, Direcciones y Control).

Datos e Instrucciones: Codificación

  • Instrucción: Orden elemental traducida a código máquina con un significado concreto para la CPU.
  • Datos: Valores numéricos, alfanuméricos o lógicos procesados por las instrucciones.
  • Codificación de Caracteres: Para representar datos en binario se emplean tablas estándar como ASCII (7 bits), ISO-8859 (8 bits) o Unicode (esquemas como UTF-8 y UTF-16).

Codificación de Caracteres

Para que el hardware interprete los datos, los caracteres se transforman numéricamente mediante tablas de correspondencia. Para codificar un número N de símbolos distintos se requiere una cantidad x de bits, definida por la relación matemática:

2^{x-1} < N \le 2^x

  • ASCII: Codificación basada en 7 bits.
  • ISO-8859: Codificación basada en 8 bits.
  • Unicode: Codificación basada en 32 bits. Dispone de esquemas de codificación como UTF-8, UTF-16 y UTF-32.

Tipos de Software

  1. Sistema Operativo: Software base e indispensable que gestiona los recursos del hardware y hace de nexo con las aplicaciones (ej. Windows, Linux, macOS).
  2. Software de Programación: Herramientas especializadas concebidas para que los profesionales desarrollen nuevos programas informáticos (compiladores, editores).
  3. Aplicación Informática: Software en contacto directo con el usuario final para automatizar tareas específicas (procesadores de texto, hojas de cálculo, contabilidad).

El Firmware y la BIOS

La BIOS (Basic Input-Output System) es el software integrado en un chip de la placa base que chequea el hardware al encender el equipo y actúa de interfaz primaria entre el sistema operativo y los componentes. Este tipo de software con un alto acoplamiento físico se denomina firmware.


3. Ingeniería del Software y Ciclo de Vida (SDLC)

La Ingeniería del Software aplica metodologías estructuradas para asegurar la construcción de programas correctos, fiables y modulares que faciliten el trabajo colaborativo y la evolución del código sin introducir errores.

Fases del Desarrollo de Software

  1. Análisis / Factibilidad: Fase inicial donde se evalúa la viabilidad temporal y económica del proyecto. El desarrollo de un software es pertinente únicamente si automatiza tareas muy repetitivas o resuelve un proceso de altísima complejidad técnica.
  2. Planificación / Requisitos: Se definen formalmente las necesidades y funciones solicitadas por el usuario final. Esta fase concluye cuando el cliente valida y firma el documento de requisitos.
  3. Diseño: Los analistas definen la arquitectura técnica. Se generan dos tipos de especificaciones: el diseño genérico (visión global del sistema) y el diseño detallado (especificación de cada módulo).
  4. Desarrollo (Codificación): Escritura del código fuente del programa. Requiere la confección de documentación técnica interna exhaustiva (propósito, parámetros de entrada y salida de las funciones) para su posterior comprensión.
  5. Pruebas (Testing): Garantizan que la aplicación cumple las especificaciones.
  6. Funcionales: Verifican que las funciones del programa se ajusten a lo acordado con el cliente.
  7. Estructurales: Pruebas técnicas que someten la aplicación a estrés, carga y rendimiento bajo condiciones reales.
  8. Explotación: Instalación e implementación del software en el entorno operativo real (producción) para su uso cotidiano. Es la etapa más extensa del ciclo de vida.
  9. Mantenimiento: Proceso continuo de actualización, corrección de incidencias, parches de seguridad y adaptaciones evolutivas. Exige que cada cambio sea rigurosamente documentado y validado por personal distinto al programador.
  10. Evaluación: Revisión crítica del sistema orientada a la mejora continua, identificando actualizaciones o entrenamientos necesarios.
  11. Fin de Vida: Planificación del cese de la aplicación, abarcando la recuperación y preservación segura de datos esenciales junto al desmantelamiento físico de los activos.

Modelos de Proceso

  • Modelo en Cascada: Estructura estrictamente secuencial donde cada etapa se ejecuta de manera sucesiva tras finalizar y validar por completo la anterior (criterio "gate"). Carece de flexibilidad al desaconsejar la revisión de fases ya cerradas.
  • Modelo en Espiral: Diseñado por Barry Boehm en 1988. Su núcleo se fundamenta en la gestión y análisis de riesgos de forma periódica a lo largo de ciclos iterativos, ideal para sistemas complejos a gran escala.
  • Desarrollo Iterativo e Incremental: Construcción del software en secciones funcionales reducidas que crecen de forma progresiva. Facilita la detección temprana de errores arquitectónicos y ayuda a moldear los objetivos en clientes con necesidades ambiguas.

Metodologías Ágiles

  • Kanban: Flujo de trabajo visual ideado por Toyota. Divide las tareas en fracciones mínimas y las organiza en un tablero por estados (Pendiente, En Curso, Finalizado) para optimizar el valor del producto.
  • Scrum: Proceso incremental estructurado en bloques de tiempo cortos y fijos (de 2 a 4 semanas) denominados Sprints. Sigue un ciclo estricto: Sprint Planning, Sprint (Ejecución), Daily Meeting (Reunión diaria) y Sprint Review.
  • Lean: Centrado en la capacitación de equipos pequeños, la eliminación de procesos innecesarios (desperdicios), la reacción rápida y el aprendizaje continuo.
  • Programación Extrema (XP): Metodología focalizada en la calidad del código y las relaciones del equipo. Se rige por 12 pilares básicos, entre los que destacan el diseño sencillo, las pruebas constantes, la refactorización, la programación en parejas y la integración continua.

Herramientas CASE

Las herramientas CASE (Computer Aided Software Engineering) son aplicaciones informáticas orientadas a automatizar las tareas del ciclo de vida del desarrollo para reducir costes, tiempos y aumentar la fiabilidad. Se clasifican en:

  • U-CASE: Soporte en la planificación inicial y análisis de requisitos.
  • M-CASE: Soporte en las fases de análisis estructurado y diseño arquitectónico.
  • L-CASE: Soporte en la codificación, depuración, pruebas automáticas y generación de la documentación técnica del proyecto.

4. Obtención de Código Ejecutable

El proceso de transformación del software escrito por el desarrollador hasta ser comprendido por la máquina consta de tres etapas de abstracción de código:

Niveles de Código

  • Código Fuente: Instrucciones legibles de alto nivel escritas en editores o IDEs. Debe gestionarse bajo sistemas de control de versiones para evitar pérdidas accidentales y organizar el trabajo. Puede ser Abierto (disponible para modificación y estudio) o Cerrado (sin permisos de edición).
  • Código Objeto: Código intermedio en formato binario o bytecode generado tras la traducción del código fuente. Se distribuye en múltiples archivos libres de errores sintácticos y semánticos, pero aún no es directamente ejecutable por la CPU.
  • Código Ejecutable: El binario definitivo obtenido al enlazar todos los archivos de código objeto junto con las librerías nativas del sistema mediante un software enlazador (linker). Es directamente inteligible por la computadora.
[ Código Fuente (.java/.cpp) ]
│
▼ (Compilador)
[ Código Objeto (.o/.obj) ] ───┐
├─► (Enlazador / Linker) ──► [ Código Ejecutable (.exe/bin) ]
[ Librerías / Bibliotecas ] ────┘

Métodos de Traducción

Método Funcionamiento Ventajas / Desventajas
Compilación El compilador traduce la totalidad del código fuente de una sola vez, generando el archivo objeto independiente. Ofrece velocidades de ejecución nativas óptimas (ej. C, C++).
Interpretación El intérprete traduce y ejecuta el código fuente en tiempo real, línea a línea, sin generar código objeto intermedio. Es más lento en su ejecución, pero ofrece un detalle minucioso en la detección y depuración de errores.
Máquinas Virtuales El compilador traduce el código fuente a un lenguaje intermedio estándar conocido como bytecode. Una máquina virtual nativa lo interpreta o compila en la plataforma destino. Ofrece una portabilidad multiplataforma absoluta a cambio de una velocidad ligeramente inferior (ej. Java).

Generación de Código Intermedio y Máquinas Virtuales (CE d)

Determinados lenguajes no generan código máquina directo para una plataforma física concreta, sino un código intermedio (Bytecode).

  • Bytecode / Código Intermedio: Formato binario optimizado de bajo nivel pero independiente de la arquitectura del procesador.
  • Máquina Virtual (VM): Programa informático que simula un ordenador completo y actúa como capa intermedia entre el bytecode y el sistema operativo real (ej. Java Virtual Machine - JVM, .NET CLR).
  • Compilación JIT (Just-In-Time): Técnica de las máquinas virtuales modernas donde el bytecode se traduce a código máquina ejecutable en tiempo real durante la ejecución para mejorar el rendimiento.
  • Ventaja Principal: Portabilidad ("Write Once, Run Anywhere"). El mismo código intermedio se ejecuta sin cambios en cualquier sistema operativo que disponga de la máquina virtual correspondiente.

5. Clasificación de los Lenguajes de Programación

  1. Lenguaje Máquina: Instrucciones complejas e ininteligibles estructuradas puramente en cadenas de unos y ceros (0 y 1). Es el único lenguaje que el procesador entiende de forma directa sin traducción, pero carece de portabilidad al cambiar según el modelo de CPU.
  2. Lenguaje de Medio Nivel (Ensamblador): Sustituto directo del lenguaje máquina para facilitar la labor de desarrollo. Sigue ligado estrechamente al hardware, pero emplea instrucciones codificadas en términos mnemotécnicos (ej. abreviaciones legibles) y trabaja con los registros de la CPU. Requiere compilarse a código máquina.
  3. Lenguaje de Alto Nivel: Los lenguajes modernos mayoritarios. Presentan una sintaxis intuitiva cercana al lenguaje humano, manejan altos niveles de abstracción, encapsulamiento y orientación a objetos, e incorporan extensas librerías prediseñadas para agilizar la codificación.

5. CLASIFICACIÓN DE LOS LENGUAJES DE PROGRAMACIÓN

(Atiende al Criterio de Evaluación e)

Los lenguajes de programación se clasifican según diversos criterios de abstracción, paradigma y traducción:

1. Según el Nivel de Abstracción

  • Lenguajes de Bajo Nivel (Lenguaje Máquina): Cadenas de bits (0 y 1) entendidas directamente por el hardware. Máxima velocidad pero nula portabilidad y extrema dificultad de escritura.
  • Lenguajes de Medio Nivel (Ensamblador / Assembly): Sustituyen las secuencias binarias por instrucciones mnemotécnicas (ADD, MOV, PUSH). Sigue estrechamente ligado a la arquitectura del procesador.
  • Lenguajes de Alto Nivel (Java, Python, C++, C#): Utilizan palabras y estructuras sintácticas cercanas al lenguaje humano o matemático. Totalmente independientes del hardware del equipo.

2. Según el Método de Traducción

  • Lenguajes Compilados (C, C++, Rust): Un compilador analiza todo el programa fuente y genera de una sola vez un archivo ejecutable antes de la ejecución. Rendimiento y velocidad máximos.
  • Lenguajes Interpretados (Python, JavaScript, PHP): Un intérprete lee, traduce y ejecuta el código fuente línea a línea en tiempo de ejecución. Mayor facilidad para detectar errores en desarrollo, pero velocidad de ejecución inferior.
  • Lenguajes Híbridos / Mixtos (Java, C#): Se compilan a un código intermedio (Bytecode) y son ejecutados/interpretados por una Máquina Virtual.

3. Según el Paradigma de Programación

  • Imperativos / Procedimentales (C, Pascal): Se enfocan en cómo realizar la tarea mediante secuencias paso a paso de instrucciones y estados.
  • Orientados a Objetos - POO (Java, C++, Python): Organizan el código en torno a "objetos" que agrupan datos (atributos) y comportamientos (métodos).
  • Declarativos / Funcionales (SQL, Haskell): Se centran en qué resultado se desea obtener sin detallar el flujo paso a paso.

6. HERRAMIENTAS UTILIZADAS EN PROGRAMACIÓN

(Atiende al Criterio de Evaluación f)

Para desarrollar programas de manera eficiente se emplean diversos tipos de software especializado:

Tipos de Herramientas de Programación

  1. Editores de Código Fuente: Programas orientados a la edición de texto plano enriquecidos con resaltado sintáctico, autocompletado e indentación (ej. VS Code, Sublime Text, Vim).
  2. Compiladores e Intérpretes: Herramientas de traducción de código (ej. GCC, Clang, Javac, Python Interpreter).
  3. Depuradores (Debuggers): Permiten ejecutar un programa paso a paso, detener la ejecución en puntos de ruptura (breakpoints) e inspeccionar las variables en memoria para localizar errores sintácticos o lógicos.
  4. Entornos Integrados de Desarrollo (IDE): Aplicaciones integrales que combinan en un único entorno editor, compilador/intérprete, depulador, gestor de proyectos y control de versiones (ej. Eclipse, IntelliJ IDEA, NetBeans, Visual Studio).
  5. Herramientas CASE (Computer Aided Software Engineering): Software para automatizar y modelar las fases de diseño, análisis, generación de código y documentación (ej. StarUML, Draw.io).
  6. Sistemas de Control de Versiones (VCS): Herramientas que registran los cambios realizados en el código a lo largo del tiempo, facilitando el trabajo colaborativo (ej. Git).

7. ERRORES EN EL DESARROLLO Y REUTILIZACIÓN DE CÓDIGO

Tipos de Errores en Programación

  • Errores de Compilación (Sintácticos): Incumplimiento de las reglas gramaticales del lenguaje (ej. olvidar un punto y coma, variable no declarada). Imposibilitan generar el código objeto/ejecutable.
  • Errores de Ejecución (Runtime Errors): Ocurren mientras el programa se está ejecutando (ej. división por cero, acceso a un puntero nulo o fuera del rango de un array).
  • Errores Lógicos (Semánticos): El programa se ejecuta completamente sin fallar, pero devuelve un resultado incorrecto porque el algoritmo o la fórmula fue mal diseñada.

Errores de Gestión en Proyectos de Software

  • Fallos de Estimación: Mala planificación en tiempos y costes debido a falta de rigor.
  • Ley de Brooks: Añadir más programadores a un proyecto de software que ya va retrasado solo conseguirá retrasarlo más debido al incremento exponencial del coste de comunicación e integración.
  • Negligencia en QA: Reducir la fase de pruebas para acortar plazos provoca el despliegue de software inestable.

Importancia de la Reutilización de Código

La reutilización de código consiste en la práctica de emplear módulos, librerías, marcos de trabajo (frameworks) o diseños preexistentes para crear nuevos programas.

Ventajas:

  • Reducción de costes y tiempos: Evita "reinventar la rueda" en tareas comunes.
  • Aumento de la fiabilidad: Los componentes reutilizados suelen estar ampliamente probados y depurados por la comunidad o la industria.
  • Estandarización: Facilita el mantenimiento y la comprensión del código entre distintos equipos.
  • Indicadores Reales en la Industria:
  • Entre el 40% y el 60% de los componentes de una aplicación estándar son completamente reutilizables en otros sistemas.
  • Cerca del 75% de las funciones operativas analizadas en programas comerciales son comunes.
  • En promedio, solo el 15% del código escrito para una nueva aplicación representa una lógica totalmente única e innovadora.