Probablemente un usuario novicio no sabrá cómo responder esta pregunta, pero si eres un usuario más avanzado me dirás que has revisado la barra de direcciones de tu navegador, que te has preocupado de no seguir un link que recibiste por email, o tuviste la precaución de escribir la dirección que te entregó tu banco, caracter a caracter, con mucho cuidado.
¡Es más! Te entregaron un aparatito, que te dijieron que está sincronizado con un super califragilistico mecanismo al que sólo accede un servidor de tu banco, y que asegura que, si alguien llegase a adivinar tu clave, el numerito mágico que este dispositivo te entrega impide que otro pueda ingresar al web del banco haciendose pasar por tí.
Estás tranquilo y seguro de que todo funciona, porque además tu proveedor de internet te ha prometido que se preocupa de tu seguridad, protegiendote para que no entren virus, bloqueando puertos que no vas a necesitar, y evita que te lleguen emails no solicitados, que podrían tratar de engañarte.
Pero tengo que decirte que todo eso es una falsa sensación de seguridad.
Porque intentar clonar un sitio web como el de tu banco es algo que un ladrón informático intentará hacer.
Me dirás que no pueden clonar la dirección web del banco, porque hay instituciones que se aseguran que funcione todo el sistema de nombres de dominio, para que nadie se adueñe de la dirección de otros.
Efectivamente, hay una enorme infraestructura montada sobre un servicio llamado DNS que permite que puedas llegar al servidor asociado a la dirección que ingresaste en tu navegador, y esas instituciones efectivamente se preocupan de que las direcciones sean entregadas a quienes corresponden.
Es un complejo servicio, que funciona muy bien, a una velocidad asombrosa y que permite que toda la web sea lo que es.
Pero esa maquinaria, tan compleja y maravillosa tenía (tiene) un fallo en su diseño original, un error tan grande que ha sido manejado en secreto, y de forma coordinada por importantes firmas y proveedores de internet en todas partes del mundo, para que sea reparado antes de que algún delincuente haga uso de esta vulnerabilidad.
Porque esta vulnerabilidad permitiría engañar a tu computador, a tu navegador, y cualquier otros programa que use direcciones basadas en nombres, enmascarando un servidor fraudulento, redirigiendo el tráfico a donde no corresponde.
Las consecuencias serían muy graves, por eso que se ha hecho esta coordinación a nivel mundial.
Pero lamentablemente, al menos en Chile, y al parecer en España también, nuestros proveedores de internet aún no han reparado el problema, a pesar de que tienen la solución desde hace semanas.
Algo que es tan urgente, aún no ha sido ejecutado, con la prontitud que esperaríamos, no sabemos las causas, pero creo que danlo mismo la razón de la demora, es obligación de los ISP brindar un servicio seguro que nos proteja de potenciales problemas como los descritos, o al menos si es cierto lo que ellos mismos dicen, de que toman medidas, que atentan a la neutralidad de la red, para protegernos, entonces con mayor razón deberían demostrarlo parchando sus servidores DNS vulnerables.
¿Quieres saber si tu proveedor de internet se ha preocupado de reparar sus servidores DNS? visita esta dirección, y presiona el botón que dice Check My DNS, esperemos que se pongan las pilas pronto nuestros proveedores de acceso, porque tenemos razones para sospechar que pronto se empezará a hacerse mal uso de esta vulnerabilidad.
"Aquellos que no entienden Unix están condenados a reinventarlo, pobremente"
(Those who do not understand Unix are condemned to reinvent it, poorly)
Henry Spencer, el geek que salvo Usenet, y autor, de regex y de Los 10 mandamientos de los programadores C.
(No, no es el padre de Shawn de Psych(Psych_character))
Aunque era una helada tarde en la comuna de Buin, disfrutamos de una cálida ceremonia de premiación a los ganadores de la Primera Olimpiada Nacional de Informática.
Allí estaban felices, los cuatros competidores que se presentaron finalmente a la final, en la que salió ganador Vicente Iglesias, del Colegio San Ignacio El Bosque.
Felicitaciones a él, y a los otros tres ganadores que conformarán el equipo que nos representará en Egipto.
En la fotografía vemos a los cuatro finalistas, y al equipo organizador, formado por los hermanos Cristobal e Israel Leiva, y Mauricio Iturriaga, ingeniero informático que los ha apoyado y que encabezará la delegación.
Pueden leer una nota en la edición del domingo en El Mercurio, uno de los pocos medios que cubrió este evento.
Este es un momento importante, estos chicos están haciendo historia, porque, aunque la IOI lleva 20 años realizándose, esta es la primera vez que nuestro país tendrá una representación oficial y elegida con un mecanismo transparente que involucra la participación a nivel nacional.
El proceso de preselección involucró la participación de más de 40 jóvenes (a pesar de que hubo sobre 50 inscritos, sólo 40 cumplían los requisitos).
Espero que el próximo año muchos más jóvenes se interesen en participar, y que el evento tenga más cobertura de los medios y apoyo de todos los que estamos interesados en desarrollar las TI en Chile.
La nota lamentable fue la no presentación de los 3 representates del Instituto Nacional, quienes se marginaron de la competencia, y que al parecer están buscando clasificar a la IOI por "otros medios".
Es cierto que existe situación que necesita una aclaración, y que está aprovechando cierto personaje (cuyas motivaciones no conocemos). Pero recordemos que la única representación oficial chilena invitada formalmente por la IOI es la seleccionada por la ONI, además de ser la única organización que cuenta con el apoyo oficial del nuestro gobierno.
Ustedes saben que no basta poner un sitio web y decir que tenemos la olución al Transantiago (la que genra un error 404, por cierto) como proclama este "representante de la IOI" para obtener automáticamente credibilidad. Este señor ha estado aprovechándose de la falta de organización de nuestro país en este tema para establecerse dentro de la organización de la IOI, pero eso se acabó, ahora hay un mecanismo oficial, avalado por la principal autoridad educacional de nuestro país.
Todos los que hemos apoyado este evento, vamos a asegurarnos de que se respete este resultado, transparente, oficial y participativo, como el único válido para definir quien representa a nuestro país.
Yo espero que los jóvenes del Insituto Nacional dejen de lado la natural ambición, y las seducciones de este señor, y sepan que lo que importa es ganar honestamente la representación del país, y no entrar por secretaría, como les prometió este personaje. Si, lamentablemente, ellos insisten en esa participación en la IOI, avalados por este señor, entonces nuestro país solicitará que se elimine nuestra bandera del evento y que no se considere como representación oficial de nuestro país.
Mañana 19 de julio es la fase final y presencial de la primera Olimpiada Nacional de Informática, a realizarse en Buin.
Los finalistas son:
Nicolas Lehmann - San Felipe, Valparaíso (Ganador 2da fase online)
Manuel Pérez - Santiago (Ganador 1era fase online)
Vicente Iglesias - Las Condes, Santiago
Francisco Hernández - Santiago
Matías Durán - Peñaflor, Santiago
Cristian Silva - Santiago
Juan Manuel Parraguez - Curicó
De entre ellos saldrán los 4 seleccionados chilenos a la Olimpiada Internacional de Informática a realizarse en Egipto en agosto.
Felicitaciones a todos ellos, a sus padres, y profesores que deben sentirse orgullosos también.
Más informaciones en el sitio oficial de la oni: www.oni.cl
A través de la iniciativa lanzada el 14 de diciembre del año 2006 por Presidencia de la República, denominada Proyecto de Conectividad Educativa de Informática Básica para el Aprendizaje en Línea (CEIBAL), el gobierno uruguayo en una decisión histórica, asume el desafío de distribuir gratuitamente
computadoras portátiles entre todos lo niños y niñas de Educación Común (1ºa 6º grado) y sus respectivos docentes de las escuelas públicas de todo país. -- CEIBAL en la Sociedad del Siglo XXI
El tema de qué hacer con la educación en Chile es complejo, y por supuesto está en una profunda crisis. Por supuesto no soy experto en educación, pero, soy de los que cree que es un imperativo incorporar las Tecnologías de la Información en el proceso educativo, por eso que he estado interesado y promovido en este blog todo lo relacionado con el proyecto OLPC (One Laptop Per Children, Un Laptop Por Niño).
CEIBAL , en Uruguay, es el más ambicioso de los proyectos que está siendo desplegado usando esta tecnología. Pero no se trata de entregar computadores a los chicos uruguayos. Es un proyecto más ambicioso, y que se propone transformar la sociedad uruguaya e integrarla verdaderamente en la sociedad de la información.
La fotografía muestra uno de los tantos encuentros de formación de docentes realizados por el proyecto CEIBAL. Ya antes publiqué una presentación con la experiencia piloto, que llevó a una de las conclusiones más importantes, es vital preparar al docente.
Uruguay está dando un ejemplo de cómo se deben implementar este tipo de programas. Sin improvisaciones que sólo generan bochornos, y en una maravillosa publicación, preparada para orientar a padres y educadores nos enteramos cómo se está implantando este proyecto.
Se trata del libro CEIBAL En la Sociedad del Siglo XXI, disponible para ser descargado desde el sitio oficial del proyecto.
A través de esta publicación no sólo nos enteramos del plan de implantación del proyecto, sus lineas de acción, objetivos, sino que también vemos una visión que pretende aprovechar esta oportunidad para llevar a toda la sociedad uruguaya hacia la sociedad de la información y presenta a los padres y educadores todas las posibilidades que se abren con el uso apropiado de las TI.
Porque no se trata de regalarle notebooks a los niños más aplicados y estudiosos. Para muchas familas este programa significa integrarse realmente a los servicios de e-government. Tal como está pasando en Perú, muchos niños uruguayos guiarán a sus padres y los introducirán en las ventajas de usar la red para mejorar su calidad de vida, accediendo a información, realizando trámites, y participando de las posibilidades que está brindando la web cada día.
Porque los computadores no sólo sirven para que los niños jueguen, o hagan sus tareas. Además son dispositivos que estarán transformando a esas familias, convirtiéndolos en usuarios activos, cultos, dominando los mínimos necesarios, dejando de ser analfabetos tecnológicos. Se convierten en personas más preparadas para aprovechar las ventajas de las nuevas tecnologías, que no pierden su identidad, y no tienen por qué, pero que amplían su mundo, y tienen mayores posibilidades, gracias a estas.
El gobierno uruguayo es valiente y decidido. Por que entregarle estas herramientas de coordinación, comunicación masiva a la gente puede ser "peligroso", los políticos le tienen miedo a este tipo de cosas, darle a la gente la oportunidad de comunicarse y expresar sus ideas, manifestar su descontento, a través de las redes sociales, y otros medios, requiere coraje.
A mi me gustaría que nuestras autoridades leyeran esta referencia uruguaya, que aprendieran y se dieran cuenta de lo ridículas que resultan las promesas presidenciales del 21 de mayo.
Yo los invito a leerlo, y a apreciar la experiencia uruguaya, a ver cómo este documento orienta y educa a los padres, para que entiendan las ventajas de internet, los problemas que podrán encontrar, y la forma en que el proyecto protege los contenidos que sus hijos accederán.
Es una publicación muy cuidada, entretenida amena, con ilustraciones muy entretenidas de Ricardo Pisano Copani, recursos a los que pueden acceder por internet, glosarios y guias.
¿Saben una cosa? Los chilenos nos estamos convirtiendo en unos pedantes, que sólo discuten sobre lo que hay que hacer, pero incapaces de hacer nada. Llenos de certezas entramos en discusiones que no valen la pena, cuando en realidad deberíamos dedicarnos a habalr menos y a hacer más. Aprendamos de nuestros hermanos uruguayos.
Si este blog fuera como alguna vez pretendí que fuera, me gustaría que se pareciera a Word Aligned, y para que tengan una idea de que les estoy hablando, he traducido un artículo de ese extraordinario blog, espero que lo disfruten (incluso los que son menos técnicos).
Detén el reloj, aplasta el bicho [1]
Por Thomas Guest (Word Aligned)
¿Cuál de estos relojes es el mejor?
Podríamos fácilmente argumentar que el que está detenido.
¿Podemos? En "Los Dos Relojes"[2] Lewis Carroll argumenta de otra manera.
¿Qué es mejor, un reloj que da la hora exacta una vez por año, o un reloj que es puntual dos veces por día? "Este último", contestarás, "incuestionablemente". Muy bien, ahora atiende.
Supongamos que tengo dos relojes: uno no funciona en lo absoluto, y el otro se retrasa un minuto al día: ¿cuál preferirías? "El que se retrasa", replicarías sin ninguna duda. Ahora observa: el que se retrasa un minuto al día tiene que emplear doce horas, o setecientos veinte minutos, hasta que de nuevo señale la hora correcta; por consiguiente es puntual una vez cada dos años, mientras que el otro es puntual evidentemente siempre que sea la hora por él indicada, lo que ocurre dos veces al día.[3]
Esta es una distracción divertida, pero no realmente problemática: por supuesto que el reloj que pierde tiempo es de uso más práctico, aún así es paradojal, mientras menos tiempo pierda menos a menudo dice la hora correcta. Un reloj que pierde sólo un segundo al día sólo indica la hora correcta cada 118 años aproximadamente.
Software Bugs
Mencione estos relojes defectuosos porque estoy pensando sobre los fallos en el software (bugs) y como los buscamos y corregimos.
El código que es obviamente correcto es más fácil de detectar que aquel que es casi correcto, y detectar fallos es previo a corregirlos. Esto implica - construyendo sobre la terminología de Carroll - que es improbable que despachemos muchos relojes detenidos, pero si no somos cuidadosos podemos terminar despachando unos pocos que pierden tiempo. Y, en general, el código que es obviamente erróneo es más fácil de corregir que el código que es casi correcto. Una función terriblemente rota claramente necesita un replanteo; mientras que una que casi funciona puede simplemente ser ajustada hasta que parezca funcionar, a menudo resultando en un error más sutil.
Fugas y Carreras
C y C++ proveen buenos ejemplos de lo que estoy hablando. Consideren un programa que usa mal la memoria. Un intento de alojar un espacio de trabajo de 4294967295 bytes falla instantáneamente [4]; una lenta fuga de memora, como el reloj lento, puede causar un daño no perceptible por un periodo extendido.
Herramientas decentes detectarán fugas de memoria. Condiciones de carrera (race conditions) en un código multi hebras son dificiles de seguir y pueden mostrarse elusivas durante las pruebas del sistema. Más de una vez he dejado un programa corriendo en un depurador (debugger), siendo alimentado con entradas al azar, con la esperanza de de que una rara y aparentemente aleatoria condición gatille una interrupción en la ejecución.
Decent tools detect memory leaks. Race conditions in multi-threaded code are harder to track and may prove elusive during system testing. More than once I've left a program running under a debugger, being fed random inputs, in the hope some rare and apparently random condition will trigger a break in execution. ¡Denme código realmente roto cualquier día!
75% correcto vs 50% correcto
Acá hay dos implementaciones de una función en C para encontrar el punto medio entre un par de valores enteros positivos y ordenados, aproximando hacia abajo. Antes de seguir leyendo, pregúntese cuál es mejor.
int midpoint1(int low, int high)
{
return low/2 + high/2;
}
int midpoint2(int low, int high)
{
return (low + high)/2;
}
Midpoint1 es un reloj detenido, retornando 3 en vez de 4 como el punto medio entre 3 y 5, por ejemplo. Entrega la respuesta incorrecta el 25% del tiempo -- fatalmente erróneo si fuera usado en el corazón de, digamos, una búsqueda binaria. Creo que podríamos detectar fácilmente el problema.
Una corrección obvía sería la mostrada en midpoint2, la que retorna 4 como el punto medio entre 3 y 5.
Midpoint2 es un reloj que se retrasas, sin embargo. Si la suma low + high produce un desbordamiento (overflow) el resultado es indefinido. En mi implementación obtengo un valor negativo -- una cosa peligrosas si lo usamos como índice de un arreglo. Este es un defecto notorio y muy real, y nuy bien documentada en una nota de Joshua Bloch subtitulada ""Casi todas las búsquedas binarias y merge sorts están rotos":http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html".
Bloch ofrece más de un arreglo así que voy a notar acá que:
- este defecto simplemente no existe en lenguajes de alto nivel como Python o Haskell, donde los enteros sólo están limintados por los recursos de la máquina.
- Pienso que Bloch no es justo al sugerir que el análisis de Jon Bentley del capítulo 4 de Programming Pearls es incorrecto. El seudo código de ese capítulo está escrito en un lenguaje tipo C algo entre C y, y de hecho uno de los ejercicios propuestos de Bentley es examinar el efecto del tamaño de las palabras (words) tiene en este análisis.
- En cierto sentido midpoint2 está más roto que midpoint1: sobre el rango de las entradas bajas y altas, la suma desborda y gatilla el defecto el 50% de las veces.
Algoritmos Probabilisticos
Los computadores se suponen que son predecibles y típicamente buscamos programas correctos. No hay razones por las que consideremos programas que sean suficientemente correctos, sin embargi, y de hecho muchos programas que son suficientemente buenos para ser útiles también tienen fallas. Los avisos de Google, por ejemplo, analizan el contenido de las páginas webs y despliegan enlaces relacionados. El algoritmo usado es secreto, ingenioso y rápido, pero a menudo resulta en errores semánticos y, en ocasiones, errores ofensivs. Pocos podrían negar cuan útil ha sido para Google este programa, sin embargo.
Acá hay un ejemplo más interesante de un algoritmo, el cual, como un reloj que se atrasa, es casi correcto:
def is_fprime(n):
"""Usa el teorema pequeño de Frmat para adivinar si n es primo.
"""
from random import randrange
tries = 3
xs = (randrange(1, n) for _ in range(tries))
return all((x ** n) % n == x for x in xs)
No entraremos en las matemáticas aquí. Una rápida ejecución con esta función parece prometedora.
>>> all(is_fprime(n) for n in [2, 3, 5, 7, 11, 13, 17, 19]) True >>> any(is_fprime(n) for n in [4, 6, 8, 9, 10, 12, 14, 15]) False
De hecho, si le damos un trabaj real con algunos números grandes, lo hace bien. Lo he usado para adivinar cual de los números entre 100000 and 102000 son primos, comparando la respuesta con el resultado corercto. Tiene una tasa de éxito mejor que un 99% (en términos de relojes, pierde 8 minutos al día) y al aumentar tries mejora su desempeño.
Mejorando is_fprime
Mientras mejor is_fprime se desempeña, menos probable es detectar lo que tiene de malo. Lo que es peor, no puede ser mejorado con ajustes simples. Sin embargo mientras más alto ponemos el valor de la variable tries no tenemos una función correcta. Podríamos aún tomar una prueba al azar de la función y probar todo valor de x en el rango 1 a n dentro del predicado:
def exhaustive_is_fprime(n):
return all((x ** n) % n == x for x in range(1, n))
exhaustive_is_fprime es muy caro para ejecutar y ocasionalmente retornará True para algún número compuesto. Si quieres saber más busca por los números de Carmichael.
El punto que quiero establecer es que código que es casi correcto puede ser peligroso. Estamos tentados a corregirlo haciendo ajustes a una implementación existente, aunque, este caso, se requiere de una revisión completa. En contraste, todos sabemos lo que se necesita hacer con el código que es claramente erróneo.
Programación defensiva
Todos hemos visto esas funciones nerviosas que van más allá de su interfaz declarada en un intento de protegerse de los usuarios descuidados.
/** * Retorna el valor máximo encontrado en el arreglo de entrada.
* Pre condición: el arreglo no debe ser vacío.
*/
int nervy_maximum_value(int const * items, size_t count)
{
int M = -INT_MAX;
if (items == NULL || count == 0)
{
return M;
}
for ( ; count-- != 0; ++items)
{
if (*items > M)
{
M = *items;
}
}
return M;
}
Lo que realmente queremos es un más simple y fácil para los clientes que usen este código:
int maximum_value(int const * items, size_t count)
{
int const * const end = items + count;
int M = *items++;
for ( ; items != end; ++items)
{
if (*items > M)
{
M = *items;
}
}
return M;
}
¿Se dieron cuenta del error sutil en nervy_maximum_value? Usa -INT_MAX en vez de INT_MIN lo que causará problemas si los clientes codifican sobre este comportamiente no documentado; si nervy_maximum_value es arreglado posteriormente, el código del cliente puede explotar. Noten que no estoy en contra del uso de asertos (assertions) para revisar las pre condiciones, y una revisión simple como assert(items != NULL && count != 0) funciona bien en maximum_value; es la escritura de código que contiene estas condiciones fallidas el que considero erróneo.
Tiempo de vida medio de los defectos.
La ocurrencia de defectos en un sistema de software complejo puede ser modelado de la misma manera que el decaimiento radiactivo. No he estudiado esta teoría y mi física está algo oxidada, pero la idea básica es que la población de errores en un software es como la población de partículas radiactivas.
Un fallo dado aparece (cualquier partícula decae) al azar, así que no podemos predecir cuando este evento sucederá, pero es igualmente probable que surja en cualquier momento particular. Esto le da a cada defecto un tiempo de vida promedio: una expectativa de vida pequeña para los defectos más ruidosos, tales como acceder a un puntero NULL, y tiempos más largos para defectos más sutiles, tales como los errores de redondeo acumulado. Asumiendo que corregimos un bug cuando ocrrue, la población de defectos decae exponencialmente, y obtenemos la clásica curva en forma de cola.
Cualquiera que ha tratado de liberar un producto de software sabe lo que se siente deslizarse por la pendiente de esta curva. Probamos el sistema, encontramos defectos, los corregimos, repetimos. Al principio puede ser estimulante en la medida que los "bichos" con corta vida son aplastados, pero hacia el final del juego es desmoralizante ver cómo los defectos son reportados y no pueden ser reproducidos, y nos encontramos sin progresar. Cuando finalmente dibujamos una linea y despachamos el producto lo hacemos sospechando que los peores problemas aún están por ser encontrandos. Para ponerlo en forma sucinta:
Ship happens!
Una combinación de técnicas nos ayuda a escapar de esta imagen depresiva. La más obvia sería evitarla: más que intentar una liberación tipo "big-bang" cada pocos años, podemos movernos hacia una liberación más continua e incremental. Una arquitectura desacoplada ayuda. De ahí la insistencia en pruebas unitarias. En vez de agitar el sistema y ver cómo caen los bichos, deberíamos desarrollar un conjunto de errores automatizados que activamente buscan los varios caminos a través del código y ejercitan los casos de borde. Dentro de la base de código, la programación defensiva puede causar que los defectos se atrincheren. En vez de eso, deberíamos adoptar un estilo más confiado, donde el código falla en forma dura y rápidamente.
¿Cómo llego a funciona ese código alguna vez?
Han arreglado un defecto y luego se han preguntado ¿cómo pudo ese código haber funcionado antes de que lo corrigieran? Es una pregunta importante y una que requiere investigación. Quizás el defecto que arreglaste está compensado por programación defensiva en otro lado. O quizás hay vastas rutas a través del código que aún deben ser probadas.
Conclusiones
Ninguno de estos relojes es muy bueno. El primero está detenido, el segundo pierde un segundo cada minuto, el tercero gana un segundo cada minuto. Al menos es fácil ver el problema con el primero: no nos tentaremos en tratar de parcharlo.
Nunca debermos esperar que nuestro código funcione la primera vez y deberíamos sospechar si así parece. La programación defensiva parece significar cosas distintas a diferentes personas. Si hemos usado mal el térmno aquí, lo siento. Nuestra mejor defensa es asumir que el código está roto hasta que los hayamos probado, asumir que se romperá en el futuro si nuestros test no son automatizados, y fallar rápidamane cuando detectemos errores.
Notas del traductor
[1] Bicho por bug, un defecto en programación.
[2] En Word Aligned hacen referencia a The Rectory Umbrella, pero el texto de Carroll, que yo copio de "Matemática Demente", aparece con el nombre de "Los Dos Relojes".
[3] Texto copiado del libro: "Matemática Demente". Lewis Carroll - Traducción de Leopoldo María Panero, Tusquets Editores, Barcelona 1999
[4] Tal como acota el autor, no es correcto que al tratar de solicitar 4294967295 bytes se provoque un error, malloc retorna NULL en el evento de una falla y el operador estandard new de C++ define como comportamiento disparar la excepción bad_alloc.
Imágenes tomadas de Word Aligned, del artículo original.
En el que se supone es el sitio tecnológico más importante de nuestro país, de lo único que hablan es del nuevo iPhone 3G, y todos los fanboys de Steve Jobs están histéricos con la novedad. Pero una noticia de impacto tecnológico enorme, no ha sido ni siquiera mencionada levemente.
Porque en Europa se aprueban medidas para intentar controlar y acabar con la neutralidad de la red. Sabemos que hay parlamentarios chilenos que han prometido torpedear el actual proyectosde neutralidad en la red.
Además nuestros parlamentarios les encanta seguir estos ejemplos de sus pares europeos, así que no me extrañaría que terminemos con una ley igual de mala y que va en contra de nuestra libertad.
Pero a los "sitios tecnológicos", de acá y de allá, lo único que les importa es el nuevo iPhone, no se dan cuenta que a Apple le interesa mantener el control de todo el stack tecnológico, tal como apunta Ricardo Galli, y que son parte interesada en todas estas medidas.
Las noticias importantes, y que nos afectan (o afectarán) pasan piola, para muchos la tecnología es el nuevo Soma. No me interesa seguir leyendo sitios que la reparten.

