Unite al grupo

Grupos de Google
Suscribirte a webandbeer
Correo electrónico:
Consultar este grupo

lunes, 14 de julio de 2008

WebAndBeer version 3

Ya tiene fecha y lugar el proximo WebAndBeer.

En esta version del evento, vamos a cambiar de lugar y forma del evento.

Invitamos a todos a participar del evento, que sera el dia miercoles 23 de julio a las 19:00hs en el CicloBar, Guatemala 5800 (esq. Carranza), Buenos Aires, Argentina.

Todos los que quieran llevar camaras y demas para registrar el evento haganlo, ya que como siempre nos colgamos y jamas queda nada registrado.

Por otro lado, estamos buscando sponsors, recuerden que el cambio es CV de los inscriptos a cambio de cervezas, asi que espero colaboren.

Hay que registrarse, pues es por cuestion de control y organizacion.



Promo_btn13

Arquitectura y escalabilidad de YouTube

Dando vueltas por esto de la internet y la blogosfera en la mañana de ayer, encontré un par de videos bastante interesantes a cargo de Cuong Do, uno de los ingenieros que estuvo en el desarrollo de youtube desde el comienzo y ahora es manager del grupo de ingeniería del core del producto.

La verdad hasta el momento solamente vi entero el primer video, en el cual Do habla sobre la arquitectura de youtube y cuenta algunos problemas que tuvieron. Entre ellos destaca uno con la forma de almacenar los thumbnails directamente en disco en una estructura "plana" de directorios y que les generó en determinado momento un conflicto en el file system que no entendí exactamente cuál fue, pero lo terminaron resolviendo con una estructura jerárquica de directorios. Luego también habla de otro problema con MySQL y unas placas que tenían que generaban unos problemas de voltage y les daban unos quilombos con un checksum (muy loco).

En cuanto a la arquitectura habla de que tienen una serie de servidores de balanceo que envian los requests a los web servers, e internamente como ya sabemos los recibe Apache para el contenido dinámico y el contenido estático se sirve con lighthttpd. Y luego tienen los servidores de memcache y los de bases de datos. También habla de unos servidores que creo que son de Google que los usan para tener como "más a mano" los videos más vistos.

En cuanto a tecnologías repite un poco lo que ya se sabe: Servidores Linux (SuSE), Apache y Lighthttpd, MySQL 5.0.X, el 99% del código en Python y usan toda la serie de recursos de Google a las que accedieron luego de la compra (el motor de búsqueda, el file system, y todas esas cosas locas para procesamiento distribuido que tiene Google).

Este es el video:



Fuente: Gigaom.


Luego, viendo los comentarios del post vi que uno indicaba que en esta otra conferencia Do habría hablado de lo mismo, así que la dejo también porque es más larga (52 minutos).






Link a Google Video

viernes, 4 de julio de 2008

El modelo de Drupal

El otro día estaba leyendo un post en un blog de un personaje conocido en el mundo de PHP, criticando a un framework, y me llamo la atención los puntos que marco como deficientes.

Que seria lo correcto o incorrecto ?

La realidad indica que lo funcional es lo correcto, pero es tan asi?

Nosotros sabemos que al mundo lo rigen ciertas reglas, de cosas que deberían ser, y realmente en PHP se hace lo que se quiere sin respetar estas reglas, y es muy difícil destacarse en este ambiente, tan mal visto por verdaderos gurus de la programacion. Al manejar muchos pseudo lenguajes (js, html, css, xml, json, etc), se complica un poco la organizacion, y si además a eso le agregamos que PHP es un hibrido que permite estructurado y POO. Y que hasta estos días no se conoce un estándar de código, mas allá de lo que tenemos en la documentacion de Zend, y que no somos muchos los que lo implementamos. Esto se traduce ha mucho código programado y pensado en muchas variedades diferentes.

Hace unos días empecé a trabajar con Drupal, para el frontend de un portal, y su código podría ser catalogado como incorrecto, pero la funcionalidad y la potencia de este CMS, lo hacen único. Su flexibilidad, su extensionalidad, y lo fácil que resulta lo hacen un gran CMS, sino el mejor. Pero la mayoría de su código son funciones, ni siquiera PHP4 solo funciones, bien estructurado, muchas de esas funciones nos devuelven HTML puro, así es HTML en una función, y generamos las distintas partes de un themes a través de esto.

Y para seguir hablando de lo poco correcto del código, tengo que decirles otra cosa mas (lo que va a leer ahora puede ser nocivo para la salud), usa variables globales!.

Sin embargo Drupal es el CMS mas popular, eficiente, fácil, y extensible del mercado.

Así y todo yo apoyo 100% el uso POO en PHP, creo que PHP5 es uno de los grandes avances que tuvimos, y es la forma en que la gente de Zend nos dice, "Estamos evolucionando, sigan con nosotros", no solo PHP5, sino los magníficos Frameworks que tenemos hoy en el mercado como symfony y Zend Framework, entre otros, que día a día siguen extendiendo funcionalidades, de la mejor forma posible usando POO.

Posibles soluciones: que en las próximas versiones la gente de Zend, elimine la programacion estructurada de su código, y obliga al mejor ejemplo java a usar solo POO, pero esto tiene mas de una contra, va a perder popularidad, el costo de aprendizaje va a ser mayor. Pero vamos a ser mas respetados como programador, los que sigamos con PHP, vamos a tener un camino definido bajo estándares de código, y siguiendo una linea. Sin embargo no creo que sea lo mejor.

En definitiva, creo que lo mejor es que tomemos el tren que mejor nos quede.

Ustedes que piensan?

Enlaces:
Drupal
Zend Framework
Symfony
Estandar de código

martes, 1 de julio de 2008

Web Services - Introduccion

¿Que son?
Un web service es un conjunto de estándar y protocolo que sirve para intercambiar información entre distintos sistemas. Un sistema desarrollado con cierta tecnología, por ejemplo Java, puede comunicarse con un sistema en PHP a través de un Web Services, esta es la funcionalidad principal, pero no necesariamente tienen que ser de diferentes plataformas, los sistemas pueden estar realizados en un mismo lenguaje, por Ejemplo comunicar dos sistemas realizados en PHP a través de un web service.

Esto se consigue gracias al uso de estándar abiertos que son regulados por la W3C y OASIS encargados de dicha tarea.


Los estándar que se manejan en un web Service, son Web Services Protocol Stack, XML, SOAP, XML-RCP, HTTP, FTP, SMTP, WSDL, UDDI, y WS-Security

Un ejemplo de utilizacion de un web Service.

La cadena de Hoteles OneTravel, se asocia con la agencia de viajes EcoSpace.

Cada empresa tiene un sistema particular para cada empresa, pero surge la necesidad de reservar una habitación desde el sistema de EcoSpace que repercuta en OneTravel, para saber si tiene disponibilidad para cierta fecha, durante ciertos días. Esta comunicacion la podemos hacer a través de un Web Service.

OneTravel, tiene un WebService (desde ahora WS), en el cual nosotros podemos conseguir.

- El listado de los hoteles asociados a OneTravel.
- Interfaz para reservar una habitación
- Interfaz para liberar una reserva
- Interfaz para saber los detalles de los servicios.


EcoSpace al poder interactuar con OneTravel de forma remota y en linea, se puede reservar una habitación desde el sistema de EcoSpace de forma automatizada y que impacte en el sistema de OneTravel, sin la necesidad de correos electrónicos, o llamadas por teléfono para confirmar, de esta forma nosotros impactamos directamente sobre el sistema de OneTravel.

Los Web Service no solo nos sirven para hacer reservas en un hotel desde una agencia de viajes, sino para cualquier tipo de comunicacion a través de sistemas diferentes. A nuestros WS le podemos dar la cantidad de funcionalidades que necesitemos.



Ventajas de un web Services
Los WS tienen muchas ventajas.
Son puentes de comunicacion a través de aplicaciones desarrolladas en diferentes plataformas independientemente de sus propiedades o plataforma en la que se instale. Una aplicacion desarrollada en Linux, se puede comunicar tranquilamente con una aplicacion desarrollada para Windows.

Se puede dar que una aplicacion solo englobe a un conjunto de WS. Por ejemplo un home Banking. Nosotros autenticamos nuestros datos a un servidor especial que Corre una aplicacion en C que corre sobre un Debian, también tenemos la conexión, con las diferentes empresas de tarjeta de créditos (American Express, Visa, Master, Cabal, etc), esta comunicacion se hace a través de un WS que es administrado por cada empresa. Ademas tenemos el WS de pagomiscuentas.com, que a su vez se conecta con los WS de otras empresas y a su vez con mas WS, permitiendo al usuario pagar la cuenta de teléfono de su casa, a través de su Home Banking, sin la necesidad de ir a los cajeros de esta empresas.


Desventajas
El problema principal que tiene un WS es el rendimiento, al ser un estándar basado en texto, resulta ser mas pesado que con otros estándar de comunicacion.
Al ser procesado por el puerto de HTTP, algunas reglas de los firewall pueden ser violadas.


¿Por que crear un WS?
Los WS son fácil de implementar, tanto para la creación de un WS, como para la implementación y uso de este. A medida que pasa el tiempo mas aplicaciones usan los WS para comunicarse, y esto hace que se genere mas información, y sea mas común hablar de WS. Es comun encontrar en grandes organizaciones uno o mas sistemas internos desarrollados en algún lenguaje para crear aplicaciones de escritorio, y con el crecimiento y auge de Internet, el uso de aplicaciones vía web crece dia a dia. Lenguajes como PHP pueden comunicarse muy facilmente con estos sistemas para brindar informacion o interactuar con un usuario via web.


Referencias
OASIS http://www.oasis-open.org
W3C http://www.w3c.es/Consorcio/

lunes, 30 de junio de 2008

Oracle/PHP for starters: Ponele bindings a esa query!

¿Qué son los bindings?

Oracle tiene una facilidad de fundamental importancia que a veces suele llamarse variable binding, pero que es más comunmente conocido (también en otros DBMS como MySQL, SQL Server o Postgre) como prepared statements o "sentencias preparadas", por la forma en que se utiliza esto a nivel código.

Lo explicaré desde el punto de vista de Oracle, que por lo que conozco es bastante más completo (y me es más familiar) y luego comentaré brevemente cómo se puede implementar en otros sistemas como MySQL.

¿A qué llamamos prepared statements?
Un prepared statement es básicamente una consulta SQL que se define en forma genérica con el fin de ser reutilizado varias veces a lo largo de la ejecusión de un mismo programa. Como generalmente una query suele tener filtros por determinados campos, donde comparamos el valor de uno o más campos contra uno o más valores variables, lo que utilizamos al definir el prepared statement es definir variables dentro de la query.

Optimización de consultas

Veamos esto con un ejemplo.

Supongamos que tenemos una consulta para obtener los datos de un usuario a partir de su ID:

$sSql = "SELECT user_name, user_password, user_birthdate FROM user WHERE user_id = " . $iUserId;

Dejaremos de lado por un momento los problemas de seguridad de esta query para ver qué sucede cuando se ejecuta en Oracle. Al ejecutarse esa query, por ejemplo cuando la variable $iUserId es igual a 5, se enviará a Oracle la siguiente consulta:

SELECT user_name, user_password, user_birthdate FROM user WHERE user_id = 5

Oracle tomará la consulta, elaborará un plan de ejecusión (dependiendo de muchas variables como índices, claves primarias y foráneas, estadísticas específicas de la base de datos, etc.), ejecutará la query y devolverá los resultados. Adicionalmente, esta query será almacenada en una suerte de cache que tiene Oracle con las últimas queries ejecutadas (no recuerdo el número exacto de consultas que se cachean, pero por decir algo digamos que son 100), junto con su plan de ejecusión. De esta manera, cuando una misma query se ejecuta varias veces seguidas, Oracle no debe estar armando el plan de ejecusión cada vez.

Supongamos que, seguidamente, ingresa otro usuario al sistema y se ejecuta la query para obtener los datos del usuario con ID = 6. Se ejecutaría la siguiente consulta:

SELECT user_name, user_password, user_birthdate FROM user WHERE user_id = 6

Oracle repetiría los pasos que describimos recién: plan de ejecusión, ejecusión, devolución de los resultados. ¿Por qué no utiliza el cache del que hablabamos?, porque evidentemente para Oracle las dos queries son diferentes: una tiene un 5 y la otra un 6. El query string, digamos, es diferente por lo tanto Oracle no tiene por qué pensar que el plan de ejecusión va a ser el mismo.

¿Cómo hacemos para que Oracle sepa que la query es la misma? Definimos ese $iUserId que usamos en PHP como una variable que pueda reconocer Oracle. Para ello, de la misma forma que en cualquier lenguaje, deberemos definir un nombre para la variable, ubicarla dentro de la query y luego asignarle un valor a esa variable. Dentro de la consulta SQL, las variables se identifican porque comienzan con dos puntos ":". La consulta que teníamos quedaría así:

$sSql = "SELECT user_name, user_password, user_birthdate FROM user WHERE user_id = :iUserId";

Luego, asignamos el valor a la variable en un array.

$aBindings = array ("iUserId" => $iUserId);

Por último, ejecutamos la query con nuestra clase de base de datos:

$aResult = $oDB->sql_query($sSql, $aBindings);

En pruebas en producción, con queries sobre tablas con cientos de miles de registros, creanmé que las diferencias de preformance son notables.

Consultas más seguras

Pero esto tiene otra ventaja adicional, en relación a un problema cotidiano de cualquier desarrollador, y sobre todo de cualquier desarrollador web: el escapado de las variables. Muchos freaks recordarán la famosa viñeta de xkcd al respecto.

El iUserId (o cualquier otra variable que usemos para filtrar), en muchos casos vendrá de un dato introducido por el usuario y debemos asegurarnos de validar esa información correctamente para evitar riesgos de SQL Inyection, es decir que en esa variable se introduzca código SQL que pueda modificar (en algunos casos muy perjudicialmente, HolaCine, cof, cof) el comportamiento esperado de la consulta. Ahora bien, yendo a la lógica más naif: ¿Si $iUserId es una variable que utilizo para filtrar, por qué le voy a meter SQL? Claro, hasta hace un rato Oracle no tenía ni idea que iUserId era una variable porque a él le llegaba el string de SQL entero y el ejecutaba.

Con los bindings Oracle sabe que :iUserId es una variable (de hecho, al momento de bindear con el statement se le puede indicar de qué tipo de dato es esa variable), por lo tanto no hay ninguna razón para evaluarlo como SQL. Nosotros podríamos tener:

$sSql = "SELECT user_name, user_password, user_birthdate FROM user WHERE user_id = :iUserId";
$aBindings = array ("iUserId" => '"" OR 1 = 1; DROP TABLE user;');
$aResult = $oDB->sql_query($sSql, $aBindings);

Y no vamos a tener ningún problema de inyection. Ojo, en ese caso en particular lo que sí vamos a tener es un error de Oracle diciendo que el valor que le pusimos a iUserId no es del tipo de dato adecuado (a menos que seamos tan nardos de poner un ID en un campo char/varchar).

Además, con los bindings no necesitamos preocuparnos por andar escapando comillas, porque el SQL statement y los valores viajan por canales separados y no como un string concatenado.

Cómo implementar prepared statements

Hasta ahora, a lo largo del artículo, utilicé siempre una ficticia clase de base de datos pero no dije cómo funcionaba internamente. Creo que no tiene sentido que reproduzca aquí la clase que uso, porque no es mía, tiene algunos problemas y seguramente ustedes podrán hacer alguna mejor. Voy a reproducir un pequeño ejemplo de cómo hacer una query con bindings usando la librería Oci8. Luego también está la alternativa con PDO que en todo caso veré para la próxima si armo algún ejemplo.


// Este sería el valor con el que vamos a filtrar
$mValue = 'some value';

// El prefetch define la cantidad de registros para la cual la librería alocará
// memoria inicialmente, en cada "ida" a buscar información.
// 200 suele ser un número recomendable cuando la query retornará varios
// registros.
$iPreFetch = 200;

// El array donde guardaremos la respuesta
$aResponse = array();

// Nos conectamos
$rConn = ocilogon($sDbUsername, $sDbPassword, $sDbName);

if ($rConn) {
    // Armamos la query
    $sSql = "SELECT field_1, field_2 FROM table WHERE field_3 = :value";

    // Definimos el array de bindings
    $aBindings = array (
                   'value' => $mValue
                 );

    // Generamos el statement
    $oStmt = ociparse($rConn, $sSql);

    // Asociamos los bindings
    foreach ($aBindings as $sWildcard => $sValue) {
       
@ocibindbyname($oStmt, ":" . $sWildcard, $sValue, -1);
    }
   
      // Vemos si hubo algun error al generar el statement
    $err = ocierror($oStmt);
    if(!$err) {
        // Seteamos el prefetch
        ocisetprefetch($oStmt, $iPreFetch);

        // Ejecutamos el statement
        $bOk = ociexecute($oStmt, OCI_DEFAULT);

        // Vemos si hubo algún error en la ejecusión
        $err = ocierror($oStmt);

        // Si estuvo todo bien armamos el record set
        if ($bOk) {
            while(ocifetchinto($oStmt, $aRow, OCI_ASSOC+OCI_RETURN_NULLS+OCI

_RETURN_LOBS+OCI_NUM)) {
                $aResponse[] = $aRow;
            }
            print_r($aResponse);
        } else {
            die("SQL error");
        }
       
        // Liberamos la memoria del statement
        ocifreestatement($oStmt);
    }
}
?>

En otros DBMS

Otros DBMS como MySQL o SQL Server también soportan queries con bindings. Actualmente, la mejor forma que he visto es con PDO porque lo maneja de la misma forma que con Oracle. Para MySQL desde PHP también puede hacerse con la clase Mysqli, el problema es que en vez de poner nombres de variables en la query uno debe usar signos de pregunta "?", lo cual trae varios problemas: si una variable se usa más de una vez en una query se debe enviar repetidas veces; los valores de las variables deben ser enviados en orden; la comprensibilidad de la query en sí resulta más complicada.

Al implementarlo de la misma forma que en Oracle, con PDO se resuelve este problema.

Estructuras de datos en C y manejo de memoria I

Nota: Este texto supone que se sabe que es una estructura de datos recursivas (nodos de listas, colas, pilas, árboles, etc.) y como se la programa en C e intenta darle una vuelta de rosca a ese conocimiento.

El lenguaje C es uno de los lenguajes de más bajo nivel (relativo) que existe. En este lenguaje la memoria se estructura de manera plana, que es en definitiva lo que es la memoria, un espacio plano de almacenamiento temporal.

Así entonces un nodo de estructura dinámica como el siguiente:

struct empleado{
int idEmpleado;
char* nombre;
char codigoPostal[6];
int idDepto;
struct empleado* sgte;
}

No es una estructura dimensional, sino un manojo de bytes ordenados:

(
Suponiendo arquitectura intel x86 32bits
int = >4 bytes
Dirección de memoria => 4bytes
char x 6 => 6 bytes
)

id nombre Codigo depto siguiente
[][][][] [][][][] [][][][][][] [][][][] [][][][]

Los cuales son interpretados cada uno como entero, puntero a caracter, entero, entero, entero.
En otras palabras, puede ser claramente un vector de bytes, donde a cada subconjunto de bytes se los interpreta como un tipo de datos nativo según la información de la definición de la estructura.

Bien, ahora supongamos que tenemos esta otra estructura bastante distinta:

struct empresa{
char* idEmpresa;
char* razonSocial;
long int cuit;
char* direccion;
char codigoPostal[6];
struct empresa* sgte;
};

Cuando hacemos funciones de acceso a cola (por ejemplo) siempre tenemos la maldita sensación de estar haciendo las mismas cosas miles de veces, puesto que si bien no es lo mismo un empleado y una empresa,
¡¡Las colas son todas iguales!!
¡¡El mecanismo si es el mismo, agrego al final, saco del principio!!

¿Cómo hacer para separar el “¿Qué?” del “¿Cómo?”?

Con el conocimiento que tenemos ahora de la memoria y la estructuración en memoria de las estructuras, existe al menos una forma de hacerlo.

¿Qué tienen en común todos los nodos de una estructura de datos dinámica / recursiva?
Rta.: El puntero al siguiente nodo.

¿Qué tienen en común todos los punteros en una misma arquitectura hardware / sistema operativo?
Rta.: El puntero es un tipo de datos, no importa lo que apunte, siempre pesa lo mismo.

Si planteamos la siguiente estructura:

Struct Nodo {
Struct Nodo* sgte;
};

Tenemos una estructura que el primer valor es un puntero un siguiente nodo, no tenemos variable “contenedor”, y no la necesitamos, puesto que ahora no nos importa el contenido de información, sino el puntero siguiente.

Un programa hecho en C, interpreta los datos según el tipo del mismo en el instante de ejecución dado.

Si yo modificase las estructuras anteriores y pusiese el elemento siguiente primero en la lista, quedaría esto:

struct empleado{
struct empleado* sgte;
int idEmpleado;
char* nombre;
char codigoPostal[6];
int idDepto;
}

struct empresa{
struct empresa* sgte;
char* idEmpresa;
char* razonSocial;
long int cuit;
char* direccion;
char codigoPostal[6];
};

Ahora, la última pregunta a hacernos es:
¿Qué tienen en común nuestras tres estructuras?
Rta.: Las tres empiezan con un puntero conceptualmente igual, el puntero al siguiente elemento.

Como se dan todas estas relaciones, entonces, gracias a la existencia del “casteo”, que hace que el programa interprete un dato como otro, sin afectarlo en el proceso, entonces, podemos definir todas las funciones para manejo de Colas para la estructura mas chica.

#define null NULL
#include
#include

typedef struct Nodo {
struct Nodo* sgte;
}Nodo;

typedef struct Cola {
Nodo* head;
Nodo* tail;
}Cola;

typedef struct Empleado{
struct Empleado* sgte;
int idEmpleado;
char* nombre;
char codigoPostal[6];
int idDepto;
} Empleado;

void inicializarCola (Cola* unaCola) {
unaCola->head = null;
unaCola->tail = null;
}

void agregarNodo (Cola* unaCola, Nodo* unNodo){
unNodo->sgte = null;

if ( unaCola->tail != null) {
unaCola->tail->sgte = unNodo;
}
unaCola->tail = unNodo;

if (unaCola->head == null) {
unaCola->head = unNodo;
}

}

Nodo* obtenerNodo (Cola* unaCola) {
Nodo* retorno;
retorno = unaCola->head;
if ( unaCola->head != null ) {
unaCola->head = unaCola->head->sgte;
}
return retorno;
}

int main (void) {

Cola unaCola;
Empleado* unEmpleado;
int i;
inicializarCola(&unaCola);

for (i = 0; i codigoPostal), ”, 6);
unEmpleado->idDepto = i;
unEmpleado->idEmpleado = i * 2;
unEmpleado->nombre = null;
agregarNodo(&unaCola, (Nodo*)unEmpleado);

}

while ((unEmpleado = (Empleado*) obtenerNodo(&unaCola)) != null) {
printf (” Id Empleado: %d \tId Depto: %d \n”, unEmpleado->idEmpleado, unEmpleado->idDepto);
}

return 0;
}

/*
Nota: Ejemplo probado con GCC y MinGW. No incluye el manejo de cadenas y la creación de empleados por una función dedicada por cuestiones de tiempo.
*/

Y con esto, tenemos el algoritmo de inserción y obtención de colas para cualquier nodo que tenga como primer dato de estructura el puntero al siguiente valor.

Como se puede ver a simple vista, esto de poder usar la misma función para distintos tipos de datos en los parámetros tiene cierto potencial.
Esta posibilidad de, por medio de casteo a estructuras menores de igual forma es una forma de emular el llamado Polimorfismo paramétrico (que no es el polimorfismo de objetos, sino, el de funcional)

Este articulo fue escrito por el flameante editor de Zend Hispano Santiago Bragagnolo en su blog

Artituculo original

domingo, 29 de junio de 2008

Entrevista a Richard Stallman

La gente de tecnologicas libres consiguio una entrevista con Richard Stallman.

Este es la version publicada por ellos.


richardstallmanvu1.jpg

¿Hola, como estás :)?

Tengo un calor insoportable aquí.

¿Cuando viajaras de nuevo a Chile?

No tengo un plan de volver a Chile, pero me gustaría ir, cuando haya
una invitación con fondos para los costes, y un hueco en mi agenda.

Como lo prefieres ¿”Free Software” o “Software Libre”?

“Software libre” es más claro, porque no se toma por “software
gratuito”. El software libre es el software que respeta la libertad
del usuario y la solidaridad social de su comunidad. No es asunto de
precio. Por lo tanto, en español no digas nunca “free software”, sino
siempre “software libre”. Incluso en inglés digo a veces “libre”.

Peor aun es decir “open source”. Ese término fue inventado para hacer
caso omiso de los asuntos éticos. Si comparas la palabra de los
activistas de software libre, como yo, y los promovidores de open
source, verás una gran diferencia al nivel el más profundo, el de
los valores.

¿Que Sistema Operativo estas usando?

Uso el sistema GNU con Linux. Básicamente es el sistema operativo
GNU, cuyo desarrollo lanc é en 1984, combinado con el kernel Linux,
lanzado en 1991 por el Sr. Torvalds.

Pero no uso su versión de Linux, porque contiene programas privativos.
Son los “blobs” de firmware que son presientes en los archivos
“fuente” de varias pilotas, en la forma de largas listas de números.
Es decir, estos archivos no realmente son de código fuente; no
obstante, los desarrolladores de Linux los ponen en sus archivos.

Ahora tenemos que mantener otra versión de Linux, llamada Linux Libre,
para usar en las versiones libres del sistema GNU/Linux.

Esto nos demuestra que ser libres hoy no garantiza que seremos libres
en un año. Mantener la libertad exige defenderla, en todos los
aspectos de la vida, incluso la informática.

Cuentanos ¿Como es un día promedio de Richard Stallman, desde que te levantas hasta que te duermes?

No me gusta tener rutinas, por lo tanto cada día es diferente en los
detalles. Lo que puedo decir es que paso mucho tiempo leyendo y
contestando mis correos. Mi trabajo se hace usualmente en
comunicación, y usualmente por correo. A parte esto, leo mucho
excepto el trabajo no me deja tiempo.

¿Estas desarrollando algún proyecto que nos puedas contar?

Mi trabajo de hoy en día no es programar, es difundir la filosofía
ética de software libre. Por lo tanto, mayormente no tiene la forma
de proyectos.

¿Has pensado en tener hijos?

La idea de unirse con otro en amor para crear una mezcla es muy
romántica, pero las consecuencias son muchas molestias. Por ejemplo,
las peleas arruinan el mismo amor, y hay que dedicar la vida al ganar
dinero.

El crecimiento de población es también muy malo para el mundo. La
población actual parece más que la tierra puede soportar. Estamos
estropeando nuestro mundo. El no tener hijos es un acto muy importante
para protegerlo.

¿Deseas agregar algo más?

La libertad no se defiende sola; tú tienes que defenderla.

Si aprecias el trabajo del movimiento de software libre, y del
Proyecto GNU, la mejor manera de agradecernos es contribuir.
Programar no es la única manera de contribuir: gnu.org/help sugiere
muchas más.

Para defender tu libertad, tienes que organizar. Si tu país propone
firmar un tratado de comercio con los EEUU, casi seguro que es
injusto. Organiza para que no se firme, o si ya se firmó, para
anularlo. (El Presidente Correa de Ecuador ha rechazado firmar un
tratado; es un muy buen ejemplo.)

Últimamente tienes que resistir la tentación de ceder tu libertad.
Por lo tanto, nunca compres ningún producto que implemente la Gestión
Digital de Restricciones (es decir, DRM) sin tener acceso personal a
las medidas necesarias para superarla.

Esto fue la entrevista que le realice al señor Stallman, por favor si quieres incluirla en tu website
asegúrese de que también incluya estos 3 links:

http://gnu.org/help
http://www.tecnologiaslibres.net
http://www.tecnologiaslibres.net/2008/06/29/entrevista-a-richard-stallman-desde-chile/