En los últimos tiempos parece que los movimientos de las grandes compañías, especialmente Microsoft y Google tienden a intentar acercarse cada vez más a la tecnología web de una forma o de otra.
No es para menos, el mercado potencial de internet es muy superior a cualquier otro mercado que se haya dado hasta ahora, basta con mirar a Google, cuyo negocio es únicamente internet para darse cuenta de eso. Cada vez nos encontramos con más acercamientos por parte de montones de empresas para ofrecer diversos servicios alrededor de la web, muchas de ellas con un enorme éxito. Ahí tenemos Twitter, Facebook, Blogspot...
Sin embargo, últimamente parece que se empieza a hablar de un "universo web", Google Docs, Microsoft Office Live, Piccasa, etc ... y empieza a implantarse por aquí y por allá la idea de "sistemas operativos web", a saber donde llegaremos. La absurdez del asunto asusta, que uno pueda hacer algo no quiere decir que lo que haga este bien hecho y tenga sentido, no porque el correo electrónico online sea algo extremadamente útil va a pasar lo mismo con una suite ofimática en linea.
I've been reading an entry from the Sasha Goldshtein blog named "Design for Performance Up-Front" in which he gives some interesting thoughts. I've specially liked this one
If a user clicks a button and the application crashes, it's a problem. If a user clicks a button and the application takes 5 seconds to respond when it should be unnoticeable, it's a problem. It's the same problem.
Hace bien poco he leido un interesante artículo (en inglés) llamado "The empty try block mystery" que describe algunas secciones de código presentes en el código fuente del .NET Framework y que son similares a lo siguiente:
y que responde a la pregunta ¿porque diablos iba alguien a declarar un bloque try finally estando el try vacío? Pues vamos a explicarlo, en español ;)
La técnica de ataque de SQL Injectión (Inyección de SQL) explota una vulnerabilidad de la capa de acceso a datos de la aplicación. Es genérica a cualquier aplicación, no solo, como mucha gente cree, a aplicaciones web aunque debido al mayor acceso a través de internet así como al "descuido" de los desarrolladores web en muchas ocasiones a la hora de tratar los parametros GET ha hecho que este tipo de ataque se popularice en la web.

Seguimos con un repaso a las características nuevas de C# 3.0, en la primera parte vimos el uso de de propiedades automáticas e inicializadores de objetos y colecciones. En la segunda parte vimos una introducción al uso de extensiones, que nos proporionan una forma no intrusiva de ampliar la funcionalidad de una clase.
En esta última parte vamos a ver la expresiones lambda y su integración con Linq así como algunas de las funciones que nos proporciona este último.
Acabo de leer un artículo bastante interesante sobre el rendimiento del uso de excepciones en .NET (aunque en general el concepto es aplicable a prácticamente cualquier lenguaje que las soporte).
El manejado de una excepción, especialmente la parte correspondiente a su resolución implica un gran consumo de recursos y tiempo. Para los que no vayan muy bien con el inglés (o sean demasiado vagos para leer el artículo :P) lo que viene a demostrar es la diferencia entre estos dos segmentos de código
|
for (int i = 0; i < 1000000; i++)
{ string s = null; try{ string ss = s.Substring(0, 2); } catch (System.NullReferenceException) { } } |
for (int i = 0; i < 1000000; i++)
{ string s = null; if (s != null) { string ss = s.Substring(0, 2); } } |
observando que el código de la derecha tarda medio segundo frente a los nada más y nada menos que 50 segundos del código de la izquierada.
No obstante, aunque la comparación así hecha parezca nefasta, no debemos olvidar que la prueba lanza un total de un millon de excepciones consecutivas, algo que no es muy probable que pasé en la vida real, no obstante, si podemos comprobar que una llamada sea correcta antes de realizar, siempre será mucho mejor que capturar la excepción. En ese sentido es importante recalcar que lo importante es evitar la excepción en la medida de lo posible, no suprimir el bloque try catch, que en si mismo no genera ningún overhead, solo perdemos rendimiento cuando la excepción sucede, si no salta ninguna excepción la presencia o no de dicho bloque no afecta prácticamente al rendimiento.

Apple a publicado una nueva versión del SDK del iPhone (SDK beta 2) que fundamentalmente, aparte de algunas mejoras leves en XCode 3.1, incluye la inclusión del interface builder para XCode lo que nos permite realizar nuestras interfaces de una forma mucho más intuitiva lo cual, la verdad, se agradece.
Además, con el paquete de descarga (otros 2.1 GB, no se si se podrá uno actualizar o no) se incluye una beta del firmware 2.0 para instalar en los iPhones registrados.
Via: Applesfera
El arte de refactorizar (refactor en inglés) viene a ser el arte de coger código viejo, existen y probablemente en producción y mejorarlo.
Refactorizar es un proceso largo, difífil y probablemente de las tareas más ingratas para un programador, entre otras cosas porque, probablemente nadie lo verá nunca (y menos de todos ellos el usuario final) ya que, en resumidas cuentas, estamos cambiando las tripas, la base, lo que hace funcionar al programa sin cambiar el interface ni las apariencias. Se trata básicamente de mejorar el producto, hacer que vaya más rápido y que esté más organizado.
Sobre ese asunto hay un artículo de Joel on Software acerca de como los programadores tendemos siempre a querer diseñar las cosas de nuevo en lugar de refactorizar y actualizar el código existente, el artículo se llama Cosas que nunca deberías hacer y es bastante interesante.
Aunque en general estoy de acuerdo con Joel en casi todo el artículo (en general suelo estar de acuerdo con él en la mayoría de las cosas porque soy un gran admirador) hay una parte en la que discrepo. Es cierto que un producto hecho contiene un montón de información y experiencia, no obstante, cuando un producto se descuida el suficiente tiempo acaba siendo un verdadero amasijo de código y remiendos, parches, retoques y, a falta de una palabra mejor, ñapas, que lo convierten en algo inusable y que llega a requerir más tiempo arreglarlo, refactorizarlo que hacerlo de nuevo. En mi opinión, siempre es relativamente bueno reinventar la rueda, eso si, sin tirar nunca el código viejo. A veces merece la pena empezar de nuevo con un desarrollo paralelo (para utilizar nuevas tecnologías o ventajas por ejemplo) mientras sigues con el desarrollo antiguo, hay una máxima, como dice Joel, !! ten siempre algo que vender ¡¡

.NET (y Java y otros cuantos lenguajes de programación) incorporan el concepto de recolector de basura. Básicamente su función consiste en liberarnos del problema o la preocupación de tener que gestionar la memoria manualmente. Esto, para aquellos que venimos de Delphi o C++ es, llanamente, una gozada. Se acabaron los malloc y los frees, se acabó controlar si nadie utiliza un objeto o no, nada de usar conteo referencial o técnicas similares, el recolector de basura se encarga por nosotros.
Sin embargo la propia implementación del recolector de basura es algo en lo que nunca tendemos a pensar. No es precisamente sencilla aunque es sin duda uno de los campos de programación más interesantes en cuanto a que implica la resolución de un montón de problemas asociados. Algunos de dichos problemas estan explicados junto con una explicación del funcionamiento del nuevo recolector de basura de mono en un excelente artículo en inglés.
Otros enlaces sobre el tema:
Aunque la ingeniería del software nunca ha sido precisamente una de mis pasiones, con el paso del tiempo y al ganar experiencia terminas reconociendo su importancia en proyectos grandes para llevar acabao un control de los mismos.
Una de las cosas a las que hace referencia es a la definición de lo que es el ciclo de vida de un proyecto, es decir, el proceso que debe seguir un proyecto desde que se inicia hasta que muere. Hay un interesante artículo sobre el mismo en La Tecla de Escape que resume las actividades fundamentales de dicho ciclo como un recordatorio a lo que se enseña en la carrera o como una introducción para aquellos que no lo hayan estudiado nunca.