Articulos

Manejando el cambio desde el punto de vista de management.

Si tienes o eres parte de cualquier empresa moderna estos días sabrás que, para mantenerse en el negocio, uno debe adaptarse al mercado, a las nuevas tecnologías y lenguajes que van apareciendo. A veces, incluso cuando no hay ninguna ventaja significativa desde el punto de vista técnico, el cliente es significativamente más receptivo a comprar las cosas que están desarolladas usando la última tecnología, o las últimas técnicas. A veces el client quiere saber si usas SCRUM o desarrollo ágil, incluso cuando no sabe lo que significan.

Eso significa que, de una forma u otra, te ves obligado a evolucionar con la tecnología para adaptarte a los cambios en el mercado, a las nuevas tecnologías que van surgiendo, a nuevas formas de hacer las cosas. Puede que te veas forzado a migrar del escritorio a la "web 2.0" o pasar de un sistema con una base de datos central a un sistema más escalable, con una base de datos distribuida (esté justificado o no, a veces el mercado es muy caprichoso).

Cuando esto pasa, ¿cómo debes manejar ese cambio en tu equipo? ¿Cómo van a tomarselo?

Por supuesto habrá gente que aceptará el cambio gustosa, sin ningún tipo de problemas o que incluso estén deseando cambiar a ese nuevo lenguaje o esa nueva forma de hacer las cosas, pero en la mayor parte de las situaciones vas a encontrar gente que se resiste a dicho cambio y es importante entender las razones que llevan a ese tipo de comportamiento si quieres manejarlo bien.

En primer lugar la gente tiene aversión al cambio (con la excepción de unos pocos). Es decir, la gente tiende a evitar los riesgos, y todo cambio es un riesgo, una modificación del status quo anterior.

En segundo lugar la gente suele tener miedo de DONDE les situarán esos cambios. Miralo de esta forma: un desarrollador de tu equipo siempre se planteará: "si cambiamos al lenguaje xxx, ¿cómo afectará eso a mi trabajo? ¿cómo afectara a mis posibilidades de tener un ascenso? ¿puede poner en riesto mi puesto de trabajo? ¿me van a echar si no me adapto lo suficientmente rápido?. En otras palabras, muy probablemente no conocen el nuevo lenguaje o la nueva tecnología, o al menos no son tan expertos como en la vieja, es normal (en cualquiera) sentir miedo de quedarse anticuados o perder su antigua posición como "expertos" en su area.

Usando referencias débiles (weak references)

Introducción

Una referencia débil (weak reference) es un concepto estrechamente unido al de recolector de basura, lo cual significa que solo esta presente en aquellos lenguajes que tienen un recolector de basura.

Para clarificar lo que es una referencia débil primero tenemos que explorar (en términos simples) que es el recolector de basura y los fundamentos en los que se basa para trabajar.

Fundamentos del recolector de basura

Los lenguajes imperativos tradicionales siempre han tenido que manejar manualmente la memoria de los tipos por referencia. De esta forma, cada vez que deseabamos obtener una nueva instancia de una clase o una estructura en memoria necesitabamos crearla reservando la memoria necesaria, memoria que quedaba reservada en el heap.

En ese momento la memoria quedaba marcada como usada, de forma que cuando pidieramos otro "trozo" de memoria no obtuvieramos la misma dirección.

Evidentemente, en algún momento, dejabamos de necesitar ese primer fragmento de memoria, de forma que necesitamos decirle al sistema que esa parte del heap ya no nos es necesaria y por lo tante esta disponible. Esta operación se conoce como "liberar la memoria". Y ese es más o menos el problema que ha estado introduciendo bugs en las aplicaciones durante más de tres decadas. Si se nos olvida liberar esa memoria, entonces nunca se queda libre y por tanto nunca la recuperamos ni podemos usarla de nuevo. Con el tiempo (o con un bucle muy rápido) terminamos consumiendo toda la memoria disponible, lo que nos lleva primero a un impacto en el rendimiento de la aplicación y finalmente a que la aplicación se cierre por falta de memoria.

Patrones de diseño. Introducción

¿Qué es un patrón de software?

En software un patrón de diseño se refiere a una determinada forma de crear software, una forma de fabricarlo, por decirlo de alguna forma para crearlo de forma correcta.

En determinados marcos de trabajo, cuando nos enfrentamos a determinados problemas en el diseño de software hay formas determinadas de enfocalos que permiten adaptar mejor los posibles cambios de dichos problemas y las distintas evoluciones que pueda sufrir el software en un futuro.

Un buen dominio de los patrones más comunes nos puede servir para no tener que reinventar la rueda a cada paso que damos sino que podemos hacer uso de lo que otros pensaron por nosotros (y que descubriremos en multiples situaciones).

Patrones de diseño. Strategy

Introducción

El patrón strategy (estrategia) esta orientado a resolver situaciones en las que nos encontramos con un problema base pero existen diversas estrategias para abordar el problema. En este sentido nuestro problema define un interface que será (o podrá ser) implementado de diversas formas.

Problema

El patrón Strategy aborda problemas que pueden (o se prevee que puedan) ser implementados o afrontados de distintas formas y cuyo interfaz esta bien definido y es común para dichas formas, pudiendo ser cualquiera de ellas valida o más desable en determinadas situaciones y permitiendo el cambio entre las distintas estrategias en tiempo de ejecución.

Estructura

main.php?g2_view=core.DownloadItem&g2_itemId=825&g2_serialNumber=1

SQL Injection explicado

Introducción

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.

Anatomía del ataque

Un ataque basado en inyección de sql responde a una estructura de código en la que vamos a realizar una consulta o comando sobre una base de datos que contiene algunos parametros que nos suministra el usuario.

El problema se plantea cuando no se comprueba que dichos parametros sean válidos sino que el programador se ha limitado a concatenarlos en las partes correspondientes de la consulta, por ejemplo:

string consulta = "SELECT Count(*) FROM Users WHERE Name='" +
                   txtNombre.Text + "' AND Password = '" + txtPassword.Text + "'";

dicha consulta en principio devuelve el número de usuarios cuyo nombre y password coincide con los suministrados en los campos de texto indicados. El problema asociado a un atáque SQL Injection viene dado, no porque el código sea incorrecto sino porque se asume que los parametros de entrada son correctos, es decir, no se tienen en cuenta todas las posibilidades. Así si suponemos los siguientes valores para los campos

C# 3.0. Nuevas características III

Introducción

matrix_ico.jpg

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.

Expresiones Lambda

En C# 2.0 se introdujo el concepto de métodos anónimos. Estos métodos mejoraban la forma de escribir código de forma que nos ahorrabamos la necesidad de escribir un método para un delegado, simplificando conseguían una mejora de este estilo:

C# 3.0. Nuevas características II

Introducción

matrix_ico.jpg En la entrada anterior comenzamos a ver las características de c# 3.0, concretamente la inclusión de los inicializadores de objeto y las propiedaes automáticas, que, como vimos, nos permitían mostrar nuestro código de una forma mucho más limpia.

En esta nueva entrega vamos a ver los metodos de extensión que al igual que lo anterior nos facilitarán la vida en ciertas tareas e incluso nos permitiran cambiar, en cierto sentido, nuestra forma de programar.

En términos generales los métodos de extensión se limitan a proporcionarnos la capacidad de extender una clase o interfaz ya existente añadiendole nuevos métodos, es decir, complementar esa clase con nueva funcionalidad (cosas que, por ejemplo, hemos tenido que tener en cuenta más tarde), aunque donde realmente consiguen su máxima potencia los métodos de extensión es en los interfaces y clases genéricos, y su mejor ejemplo (que ya veremos más adelante) es LinQ

C# 3.0. Nuevas características I

Introducción

matrix_ico.jpg Vale, se que esto viene un poco tarde puesto que lleva mucho tiempo en el mercado ya, y no digamos como beta, de hecho Monet, la librería de plugins que creé hace un tiempo, ya utiliza algunas de dichas características.

Visto por encima podemos decir que C# 3.0 proporciona los siguientes "avances" o "facilidades" nuevas:

  • Propiedades automáticas.
  • Inicializadores de objeto y de colecciones (Object & Collections Initializers)
  • Extensiones (Extension Methods)
  • Expresiones Lambda
  • LinQ

En este primer post solo voy a cubrir las dos primeras partes, en un segundo hablaré de las extensiones y ya en el tercero os hablaré de las maravillas de las lambda expressions y el LinQ.

El misterio del bloque try vacio

El misterio

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:

try
{
}
finally
{
  HazCosas1();
  HazCosas2();
}

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 ;)

Introducción a Parallel Extensions. Parte I

Introducción

Parallel Extensions es un framework de Microsoft, aún en desarrollo para facilitar el desarrollo de aplicaciones concurrentes. Recientemente acaban de sacar la primera CTP (comunity tecnology preview) que está disponible para descarga y han solicitado feedback y comentarios en sus foros.

El funcionamiento es el común de una biblioteca, pero la implementación incorpora optimizaciones para mejorar el rendimiento de las aplicaciones multihilo liberando al programador de la tarea. Internamente se encarga de "decidir" si un trabajo debe ser ejecutado en un hilo separado o si se debe ejecutar en el propio hilo que invoca la llamada. Internamente está organizado en una serie de hilos, parecido al thread pool de .NET pero con ciertas optimizaciones, ya que existen una serie de colas internas en las que se insertan los trabajos (es algo más complicado que eso pero baste la simplificación), permitiendo que determinados hilos se "roben" las tareas entre ellos para mejorar la ocupación general de la CPU y por tanto el rendimiento del programa.

La base

Parallel.For

La base de funcionamiento de la librería está centrada en la existencia de una clase estática llamada Parallel que aglutina toda la funcionalidad de la librería, mediante funciones como Parallel.For, Parallel.ForEach o Parallel.Do. Básicamente trata de abordar el cálculo en paralelo de las estructuras For o ForEach. En cuanto a la orden Do, en un momento veremos lo que hace.