lunes, 21 de junio de 2010

Lenguaje de Programacion

Al desarrollarse las primeras computadoras electrónicas, se vio la necesidad de programarlas, es decir, de almacenar en memoria la información sobre la tarea que iban a ejecutar. Las primeras se usaban como calculadoras simples; se les indicaban los pasos de cálculo, uno por uno.
John Von Neumann desarrolló el modelo que lleva su nombre, para describir este concepto de "programa almacenado". En este modelo, se tiene una abstracción de la memoriacomo un conjunto de celdas, que almacenan simplemente números. Estos números pueden representar dos cosas: los datos, sobre los que va a trabajar el programa; o bien, el programa en sí.
¿Cómo es que describimos un programa como números? Se tenía el problema de representar las acciones que iba a realizar la computadora, y que la memoria, al estar compuesta por switches correspondientes al concepto de bit, solamente nos permitía almacenar números binarios.
La solución que se tomó fue la siguiente: a cada acciónque sea capaz de realizar nuestra computadora, asociarle un número, que será su código de operación (opcode) . Por ejemplo, una calculadora programable simple podría asignar los opcodes :
1 = SUMA, 2 = RESTA, 3 = MULTIPLICA, 4 = DIVIDE.
Supongamos que queremos realizar la operación 5 * 3 + 2, en la calculadora descrita arriba. En memoria, podríamos "escribir" el programa de la siguiente forma:
Localidad Opcode Significado Comentario 0 5 5 En esta localidad, tenemos el primer número de la fórmula 1 3 * En esta localidad, tenemos el opcode que representa la multiplicación. 2 3 3 En esta localidad, tenemos el segundo número de la fórmula 3 1 + En esta localidad, tenemos el opcode que representa la suma. 4 2 2 En esta localidad, tenemos el último número de la fórmula
Podemos ver que con esta representación, es simple expresar las operaciones de las que es capaz el hardware (en este caso, nuestra calculadora imaginaria), en la memoria.

La descripción y uso de los opcodes es lo que llamamos lenguaje de máquina . Es decir, la lista de códigos que la máquina va a interpretar como instrucciones, describe las capacidades de programación que tenemos de ella; es el lenguajemás primitivo, depende directamente del hardware, y requiere del programador que conozca el funcionamiento de la máquina al más bajo nivel.

Los lenguajes más primitivos fueron los lenguajes de máquina. Esto, ya que el hardware se desarrolló antes del software, y además cualquier software finalmente tiene que expresarse en el lenguaje que maneja el hardware.
La programación en esos momentos era sumamente tediosa, pues el programador tenía que "bajarse" al nivel de la máquina y decirle, paso a pasito, cada punto de la tarea que tenía que realizar. Además, debía expresarlo en forma numérica; y por supuesto, este proceso era propenso a errores, con lo que la productividad del programador era muy limitada. Sin embargo, hay que recordar que en estos momentos, simplemente aún no existía alternativa.

El primer gran avance que se dio, como ya se comentó, fue la abstracción dada por el Lenguaje Ensamblador, y con él, el nacimiento de las primeras herramientas automáticas para generar el código máquina. Esto redujo los errores triviales, como podía ser el número que correspondía a una operación, que son sumamente engorrosos y difíciles de detectar, pero fáciles de cometer. Sin embargo, aún aquí es fácil para el programador perderse y cometer errores de lógica, pues debe bajar al nivel de la forma en que trabaja el CPU, y entender bien todo lo que sucede dentro de él.
Con el desarrollo en los 50s y 60s de algoritmos de más elevado nivel, y el aumento de poder del hardware, empezaron a entrar al uso de computadoras científicos de otras ramas; ellos conocían mucho de Física, Química y otras ramas similares, pero no de Computación, y por supuesto, les era sumamente complicado trabajar con lenguaje Ensamblador en vez de fórmulas. Así, nació el concepto de Lenguaje de Alto Nivel, con el primer compilador de FORTRAN (FORmula TRANslation), que, como su nombre indica, inició como un "simple" esfuerzo de traducir un lenguaje de fórmulas, al lenguaje ensamblador y por consiguiente al lenguaje de máquina. A partir de FORTRAN, se han desarrollado innumerables lenguajes, que siguen el mismo concepto: buscar la mayor abstracción posible, y facilitar la vida al programador, aumentando la productividad, encargándose los compiladores o intérpretes de traducir el lenguaje de alto nivel, al lenguaje de computadora.

Hay que notar la existencia de lenguajes que combinan características de los de alto nivel y los de bajo nivel (es decir, Ensamblador). Mi ejemplo favorito es C: contiene estructuras de programación de alto nivel, y la facilidad de usar librerías que también son características de alto nivel; sin embargo, fue diseñado con muy pocas instrucciones, las cuales son sumamente sencillas, fáciles de traducir al lenguaje de la máquina; y requiere de un entendimiento apropiado de cómo funciona la máquina, el uso de la memoria, etcétera. Por ello, muchas personas consideramos a lenguajes como C (que fue diseñado para hacer sistemas operativos), lenguajes de nivel medio.

Java

El lenguaje de programación Java, fue diseñado por la compañía Sun Microsystems Inc, con el propósito de crear un lenguaje que pudiera funcionar en redes computacionales heterogéneas ( redes de computadoras formadas por más de un tipo de computadora, ya sean PC, MAC's, estaciones de trabajo, etc.),y que fuera independiente de la plataforma en la que se vaya a ejecutar. Esto significa que un programa de Java puede ejecutarse en cualquier máquina o plataforma. El lenguaje fue diseñado con las siguientes características en mente:

Simple. Elimina la complejidad de los lenguajes como "C" y da paso al contexto de los lenguajes modernos orientados a objetos. Orientado a Objetos. La filosofía de programación orientada a objetos es diferente a la programación convencional.

Familiar. Como la mayoría de los programadores están acostumbrados a programar en C o en C++, el sintaxis de Java es muy similar al de estos.

•Robusto. El sistema de Java maneja la memoria de la computadora por ti. No te tienes que preocupar por apuntadores, memoria que no se esté utilizando, etc. Java realiza todo esto sin necesidad de que uno se lo indique.

•Seguro. El sistema de Java tiene ciertas políticas que evitan se puedan codificar virus con este lenguaje. Existen muchas restricciones, especialmente para los applets, que limitan lo que se puede y no puede hacer con los recursos críticos de una computadora.

•Portable. Como el código compilado de Java (conocido como byte code) es interpretado, un programa compilado de Java puede ser utilizado por cualquier computadora que tenga implementado el interprete de Java.

•Independiente a la arquitectura. Al compilar un programa en Java, el código resultante un tipo de código binario conocido como byte code. Este códido es interpretado por diferentes computadoras de igual manera, solamente hay que implementar un intérprete para cada plataforma. De esa manera Java logra ser un lenguaje que no depende de una arquitectura computacional definida.

•Multithreaded. Un lenguaje que soporta múltiples threads es un lenguaje que puede ejecutar diferentes líneas de código al mismo tiempo.

•Interpretado. Java corre en máquina virtual, por lo tanto es interpretado.

•Dinámico. Java no requiere que compiles todas las clases de un programa para que este funcione. Si realizas una modificación a una clase Java se encarga de realizar un Dynamic Bynding o un Dynamic Loading para encontrar las clases.

Ejemplo de tutorial de Java:

En Java hay tres tipos de comentarios:

// comentarios para una sola línea

/* comentarios de una o

más líneas

*/

/** comentario de documentación, de una o más líneas

*/

Un programa en C

Generalizando, un programa en C consta de tres secciones. La primera sección es donde van todos los ``headers''. Estos ``headers'' son comúnmente los ``#define'' y los ``#include''. Como segunda sección se tienen las ``funciones''. Al igual que Pascal, en C todas las funciones que se van a ocupar en el programa deben ir antes que la función principal (main()). Declarando las funciones a ocupar al principio del programa, se logra que la función principal esté antes que el resto de las funciones. Ahora, solo se habla de funciones ya que en C no existen los procedimientos.

Y como última sección se tiene a la función principal, llamada main. Cuando se ejecuta el programa, lo primero que se ejecuta es esta función, y de ahí sigue el resto del programa.

Los símbolos { y } indican ``begin'' y ``end'' respectivamente. Si en una función o en un ciclo while, por ejemplo, su contenido es de solamente una línea, no es necesario usar ``llaves'' ({ }), en caso contrario es obligación usarlos.

Ejemplo de un programa en C

/*Programa ejemplo que despliega el contenido de "ROL" en pantalla*/

#include

#define ROL "9274002-1"

despliega_rol() {

printf("Mi rol es : \%s\n", ROL);

}

void main() {

despliega_rol();

}

/* Fin programa */


QBasic

Qbasic es un lenguaje de alto nivel, el cual consiste en instrucciones que los humanos pueden relacionar y entender. El compilador de Qbasic se encarga de traducir el mismo a lenguaje de máquina.

Un programa es una secuencia de instrucciones. El proceso de ejecutar esas instrucciones se llama correr el programa. Los programas contienen las funciones de entrada, procesamiento y salida. La persona que resuelve problemas mediante escribir programas en la computadora se conoce como programador. Después de analizar el problema y desarrollar un planpara solucionarlo, escribe y prueba el programa que instruye a la computadora como llevar a cabo el plan. El procedimiento que realiza el programador se define como "problem solving". Pero es necesario especificar que un programador y un usuario no son lo mismo. Un usuario es cualquier persona que use el programa.

Ejemplo de qbasic

para hacer una calculadora

DIM total AS DOUBLE

DIM number AS DOUBLE

DIM secondNumber AS DOUBLE

DIM more AS STRING

DIM moreNumbers AS STRING

DIM operation AS STRING

total = 0

more = "y"

moreNumbers = "c"

CLS

WHILE more = "y"

INPUT "Enter the first number"; number

total = number

WHILE moreNumbers = "c"

COLOR 14

PRINT "The total is:"; total

COLOR 7

PRINT "Select an operation"

COLOR 2

PRINT "(+)"

COLOR 5

PRINT "(-)"

COLOR 1

PRINT "(x)"

COLOR 4

INPUT "(/)"; operation

COLOR 7

CLS

IF operation = "+" THEN

REM where we do additions

PRINT "Enter the number to Add to"; total

INPUT secondNumber

total = secondNumber + total

COLOR 14

PRINT "The total is now:"; total

COLOR 7

ELSE

IF operation = "-" THEN

REM subtraction

PRINT "Enter the number to Subtract from"; total

INPUT secondNumber

total = total - secondNumber

COLOR 14

PRINT "The total is now:"; total

COLOR 7

ELSE

IF operation = "x" THEN

REM multiplication

PRINT "Enter the number to Multiply"; total; "by"

INPUT secondNumber

total = secondNumber * total

REM * is the multiplication sign in programs

COLOR 14

PRINT "The total is now:"; total

COLOR 7

ELSE

IF operation = "/" THEN

REM division

PRINT "Enter the number to Divide"; total; "by"

INPUT secondNumber

IF secondNumber = 0 THEN

COLOR 4

PRINT "You cannot divide by zero"

COLOR 7

ELSE

total = total / secondNumber

REM / is the division sign in programs

END IF

COLOR 14

PRINT "The total is now:"; total

COLOR 7

ELSE

PRINT "you must select an operation"

END IF

END IF

END IF

END IF

INPUT "Do you wish to continue (c) or start with new numbers

(n)";moreNumbers

CLS

WEND

COLOR 14

PRINT "The grand total is:"; total

COLOR 7

INPUT "Do you wish to make more calculations (y - n)"; more

moreNumbers = "c"

REM if we don't put "moreNumbers" back to y, it will always

REM come back to "Do you wish to make more calculations" and never REM ask

for numbers again

REM (try it)

total = 0

REM if we don't reset the total to 0, it will just

REM keep on adding to the total

WEND

END

Linux

Linux es una implementación del sistema operativo UNIX (uno más de entre los numerosos clónicos del histórico Unix), pero con la originalidad de ser gratuito y a la vez muy potente, que sale muy bien parado (no pocas veces victorioso) al compararlo con las versiones comerciales para sistemas de mayor envergadura y por tanto teóricamente superiores. Comenzó como proyecto personal del –entonces estudiante- Linus Torvalds, quien tomó como punto de partida otro viejo conocido, el Minix de Andy. S. Tanenbaum (profesor de sistemas operativos que creó su propio sistema operativo Unix en PCs XT para usarlo en su docencia). Actualmente Linus lo sigue desarrollando, pero a estas alturas el principal autor es la red Internet, desde donde una gigantesca familia de programadores y usuarios aportan diariamente su tiempo aumentando sus prestacionesy dando información y soporte técnico mútuo. La versión original -y aun predominante- comenzó para PCs compatibles (Intel 386 y superiores), existiendo también en desarrollo versiones para prácticamente todo tipo de plataformas:

PowerPC ,

Sparc ,

Alpha ,

Mips , etc.

De todas ellas la más reciente en este momento es la versión para PowerMac (el PowerPC de Apple) basada en el microkernel Mach 3.0 y de la que ya hay una distribuciónpara desarrolladores avalada directamente por Apple y OSF pero conservando el espíritu (gratuito, de libre distribución, etc) de la version original. Un servidor la acaba de probar hace unos días y se ha llevado una grata sorpresa (aún tendrá muuuchos fallos, pero para ser una primerísima versión y el poco tiempo que lleva en marcha, ha avanzado más de lo que me esperaba).

Ejemplo de linux:

Compilar el Kernel

Dado que un diskette sólo almacena 1.44 Megabytes (1440 Kilobytes) de datos, no puedes el mismo kernel que utilizas al diskette. Primero debes conseguir los fuentes del núcleo y descomprimirlos en /usr/src/linux. Luego ejecuta la siguiente orden desde el directorio

/usr/src/linux:

make config

Configura solamente aquello que realmente necesites. Yo, personalmente, sólo configuro el soporte para "ext2", soporte para la disquetera (floppy disk), y soporte para "PPP". Tus elecciones pueden se diferentes en función de lo que decidas incluir. Ahora introduce el siguiente comando:

make dep; make clean; make zImage

¡make zImage es muy importante! Comprime el kernel definitivo. Después de que termine la compilación, deberás buscar el nuevo núcleo en /usr/src/linux/arch/i386/boot bajo el

nombre de zImage.

El sistema de ficheros: No es solamente un conjunto de ficheros

Ahora hemos de crear el sistema de ficheros (en inglés: filesystem, fs) para el diskette. En vez de copiar los ficheros tal cual directamente al diskette, los comprimiremos antes de copiarlos. Esto nos hará un poco más difícil la faena de modificar todo permanentemente. Primero tecleamos el siguiente

comando:

dd if=/dev/zero of=[DEVICE] bs=1k count=3000

Donde [DEVICE] es "lugar" en el disco durodonde vas a guardar el sistema de ficheros descomprimido. Luego, introduce el siguiente comando y pulsa ENTER, sustituyendo [DEVICE] por el directorio en tu disco duro donde estás guardando el sistema de ficheros descomprimido:

mke2fs -m 0 [DEVICE]

Si make2fs te pregunta si realmente quieres hacer esto (Do you really want to do this?), acepta tecleando "y" (yes).

Después tenemos que montar este sistema de ficheros que hemos creado. Para ello, el núcleo que utilices tiene que permitir "montar ficheros", en otras palabras, ha de tener habilitada la posibilidad de "loopback devices". Para ello has de compilar el núcleo de tu máquina (no el núcleo que hemos creado, sino el de tu propia máquina) con la opción:

Loopback device support (CONFIG_BLK_DEV_LOOP) [M/n/y/?]

bien como módulo (M) o en el mismo núcleo (Y). Si lo compilas como módulo (lo más recomendable) luego tienes que insertar el módulo modprobe loop !No olvides rearrancar la máquina si has tenido que recompilar el núcleo!

mount -t ext2 DEVICE /mnt

Si se queja la orden mount puedes intentar con la siguiente orden:

mount -o loop -t ext2 DEVICE /mnt

Ahora debes copiar todos los ficheros que necesites en el nuevo sistema de ficheros. Primero, ponte en el directorio /mnt, (cd /mnt), y crea los siguientes directorios:

/dev

/pro

/etc

/bin

/lib

/mnt

/usr

Ahora crearemos el directorio /dev tecleando lo siguiente:

cp -dpR /dev /mnt/dev

Si se te acaban los i-nodos del diskette, puedes ir a /mnt/dev y borrar los archivos de dispositivo que no necesites. Cuando acabes de copiar los ficheros necesarios para /dev, ves a /etc. Para estar seguro copia todos los ficheros de /etc a /mnt/etc:

cp -dpR /etc /mnt/etc

Luego copia todo del directorio /lib en /mnt:

cp -dpR /lib /mnt/lib

Para el directorio /bin, copia sólo aquello que creas que necesitas en /mnt/bin.

Copiar todo a tu diskette

Ahora hemos de copiar todo en el/los diskette/s. Para hacer esto, debemos comprimir ahora el sistema de ficheros tecleando las siguientes ordenes:

cd /

umount /mnt

dd if=[DEVICE] bs=1k | gzip -9 > rootfs.gz

Ahora es importante comprobar el tamaño del núcleo. Ponte en /usr/src/linux/arch/i386/boot y teclea "ls -l". Luego divide el tamaño del núcleo entre 1024.

Por ejemplo, si el tamaño es de 250000 bytes, entonces son 245 KB. En adelante, reemplaza [ROOTBEGIN] en las ordenes que aparezca por el número total de kilobytes que has calculado. Ahora copia el kernel al diskette usando el siguiente comando:

dd if=zImage of=/dev/fd0

Este comando grabará el kernel en el diskette. Luego introduce el siguiente comando para que el kernel pueda encontrar la raíz del sistema de ficheros en el diskette.

rdev /dev/fd0 /dev/fd0

Ahora tendrás que hacer un pequeño cálculo en hexadecimal. Suma 4000 al equivalente en hexadecimal de [ROOTBEGIN] (que en nuestro ejemplo es F5). Convierte el resultado a decimal y teclea el siguiente comando, sustituyendo 16629 con el resultado que tú has obtenido:

rdev -r /dev/fd0 16629

Finalmente, teclea lo siguiente para copiar el sistema de ficheros al diskette:

dd if=/rootfs.gz of=/dev/fd0 bs=1k seek=[ROOTBEGIN]

El sistema de ficheros raíz será copiado al diskette justo después del kernel. ¡Ya lo tienes! Para el segundo diskette, el proceso es más fácil. Copia los ficheros que quieras en el diskette. No obstante, para poder usar los ficheros que hay en el segundo disco, tendrás que entrar lo siguiente después de arrancar con el diskette:

mount /dev/fd0 /usr

Procesamiento de Datos

Hasta el momento hemos supuesto que los datos que maneja una aplicación no son tan voluminosos y por lo tanto caben en memoria. Cuando recurrimos a archivos se debe a la necesidad de conservar datos después de que termina un programa, por ejemplo para apagar el computador.
Sin embargo, existen problemas en donde el volumen de datos es tan grande que es imposible mantenerlos en memoria. Entonces, los datos se almacenan en un conjunto de archivos, los que forman una base de datos. Una base de datos es por lo tanto un conjunto de archivos que almacenan, por ejemplo, datos con respecto al negocio de una empresa.
Cada archivo se forma en base a un conjunto de líneas y cada línea esta formada por campos de información. Todas las líneas de un mismo archivo tienen la misma estructura, es decir los mismos campos de información. Diferentes archivos poseen estructuras distintas, i.e. campos de información.
Por ejemplo, el archivo de postulantes post.dat, visto en capítulos anteriores, tiene la siguiente información:

•ci: carnet de identidad de la persona.
•nombre.

En lo que sigue supondremos que ambos archivos son lo suficientemente grandes como para que no quepan en la memoria del computador. A continuación resolveremos eficientemente el problema de generar un archivo con los tres campos de información, sin colocar previamente el contenido de un archivo en un arreglo.
Recolección de datos:

Provee un vínculo para obtener la información interoperacionales racional y las parametrizaciones.

Almacenamiento de datos

Las unidades de disco de la computadora y otros medios de almacenamiento externo permiten almacenar los datos a más largo plazo, manteniéndolos disponibles pero separados del circuito principal hasta que el microprocesador los necesita. Una computadora dispone también de otros tipos de almacenamiento.
La memoria de sólo lectura (ROM) es un medio permanente de almacenamiento de información básica, como las instrucciones de inicio y los procedimientos de entrada/salida. Asimismo, una computadora utiliza varios buffers (áreas reservadas de la memoria) como zonas de almacenamiento temporal de información específica, como por ejemplo los caracteres a enviar a la impresora o los caracteres leídos desde el teclado.

Procesamiento de datos:

a.El objetivo es graficar el Procesamiento de Datos, elaborando un Diagrama que permita identificar las Entradas, Archivos, Programas y Salidas de cada uno de los Procesos.
b.Su antecedente es el Diagrama de Flujo.
c.Los elementos claves son los Programas.
d.Se confecciona el Diagrama de Procesamiento de Datos
e.Este Diagrama no se podrá elaborar por completo desde un primer momento ya que depende del Flujo de Información.