Rust no es solo el más amado por los programadores, también podría ser el lenguaje que reemplace a C/C++ en Microsoft

18/07/2019
Artículo original

Rust no es solo el más amado por los programadores, también podría ser el lenguaje que reemplace a C/C++ en Microsoft

A pesar de ser relativamente desconocido, especialmente frente a lenguajes del tope de la lista de favoritos como Java, Python o JavaScript, Rust se ha convertido en el lenguaje más amado de muchos programadores a pesar de haber surgido apenas en 2010.

Rust nació dentro de Mozilla como una solución para escribir código muy rápido al mismo nivel que con C o C++, pero sin los problemas de gestión de memoria de estos, y es justamente esa la razón por la que en Microsoft también están considerando pasarse a Rust.

Como ha explicado Gavin Thomas, director principal de ingeniería de seguridad para el Microsoft Security Response Center (MSRC), la empresa está explorando formas de crear código más seguro, enfocándose especialmente en los problemas que afectan mayoritariamente no solo a sus productos, sino a la industria en general: los bugs en la gestión de memoria.

El 70% de las vulnerabilidades que Microsoft parchea están relacionadas con problemas en la gestión de memoria

Graph 1024x398 Azul oscuro: vulnerabilidades en la gestión de memoria - Azul claro: vulnerabilidades que no son de gestión de memoria

Desde el 2004, el MSRC ha rastreado cada vulnerabilidad de seguridad de Microsoft reportada. De todo ese triaje se desprende un hecho asombroso: la mayoría de las vulnerabilidades corregidas son causadas por desarrolladores que sin darse cuenta insertan errores de corrupción de memoria en su código C y C++.

Y, ahora que Microsoft está aumentando su base y usando cada vez más software open source en su código, el problema está empeorando. La solución: optar por lenguajes de programación con gestión de memoria segura.

Tanto Windows como la mayoría de los productos de Microsoft están escritos principalmente en C y C++, estos tienen la ventaja de ser sumamente rápidos, son lenguajes maduros y extremadamente eficientes.

Sin embargo, son dos lenguajes de programación considerados como inseguros en cuanto a la gestión de memoria, esto quiere decir que errores en el código pueden causar una cascada de bugs que los atacantes pueden explotar con consecuencias graves, como en vulnerabilidades de ejecución remota de código o de privilegios elevados.

Por qué Rust

Rust

Rust es uno de los lenguajes más prometedores a la hora de subsanar los problemas de C/C++ sin perder esa eficacia y rapidez característica. Aunque en Microsoft desarrollaron C#, un lenguaje que mejora la gestión de memoria en comparación con estos, sigue siendo menos avanzado que Rust.

Rust fue desarrollado desde cero con protecciones pensadas especialmente para una excelente gestión de memoria segura garantizada en tiempo de compilación. Rust incluso logra tener valores muy cercanos o hasta mejores que C/C++ en los tiempos de ejecución.

Microsoft continuará explorando más lenguajes de programación seguros, de momento van a comenzar con Rust, que además de tener el amor de muchos programadores ya es usado en amplia variedad de proyectos importantes, no solo es parte esencial de Firefox Quantum, sino que también es usado por empresas como Dropbox, Yelp, Amazon, RedHat, LINE, System76, Coursera, CloudFlare, Reddit, Twitter, y muchas más.

¿Qué diferencia existe entre const y readonly en el lenguaje C#? - Más de la que crees...

17/07/2019
Artículo original

Una pregunta muy típica que se suele hacer la gente que empieza con .NET es la que da título a este artículo. Y es que, si una variable solamente se puede leer y por lo tanto no se puede cambiar... en realidad eso es la definición de una constante ¿no?

Sí y no. En realidad hay algunas sutiles diferencias que voy a explicar y que son básicas, pero también existe una diferencia enorme, mucho menos evidente, que mostraré al final y que ni siquiera muchos programadores experimentados conocen.

Vale, vamos a empezar por lo básico.

Constantes vs variables de solo lectura

Una constante se define en C# de la siguiente manera:

public const double PI = 3.14;

El modificador const le indica al compilador que esta variable va a ser constante, y solo la podemos inicializar al mismo tiempo que la declaramos. Si en cualquier otra parte del código la intentamos modificar, el compilador se quejará diciendo que el lado izquierdo de una asignación debe ser una variable, una propiedad o un indexador:

Error al intentar asignar una constanrte

Una variable de solo lectura, se parece mucho a una constante y se declara de manera parecida:

public readonly double PI = 3.14;

y si luego la intentamos modificarla en casi cualquier otra parte del código, veremos el siguiente error:

Error al intentar asignar una variable de solo lectura

Y es que, siendo de solo lectura, no se puede asignar tampoco. Sin embargo, hay algo en el error del compilador que nos da una pista de una de las diferencias con una constante, y la he destacado en el mensaje de error: excepto en un constructor.

Y es que los miembros de una clase que sean readonly pueden ser modificados mientras no termine de ser ejecutado el constructor de la clase. Es decir, dentro del constructor podemos modificarlos a voluntad, por ejemplo, obteniendo su valor a partir de los parámetros que se le pasen al constructor, algo que no es posible en el caso de una constante.

Esto nos da una importante ventaja a la hora de crear estructuras de datos inmutables, que son aquellas que una vez establecidas podemos tener la seguridad de que no van a cambiar. Estas estructuras tienen muchas aplicaciones en programación y son especialmente útiles al ser inherentemente seguras para uso multi-hilo, ya que al no poder cambiar sus datos no hay peligros de interbloqueos.

En el caso de que nuestra variable de solo lectura apunte a un tipo por valor, sabemos que el valor no va cambiar, y si apunta a un tipo por referencia (otra clase), aunque la clase y sus datos cambien podemos tener la seguridad de que nuestra variable apuntará siempre a dicha clase.

Miembros estáticos

Otra importante diferencia entre una constante y una variable de solo lectura es que las constantes son siempre miembros estáticos de la clase en la que se declaran.

Es decir, si escribimos:

public class Clase01
{
public const double PI = 3.14;
}

luego podemos acceder a ese valor PI sin necesidad de crear un objeto de la clase con new, así:

Console.Write("El valor de Pi en nuestro programa es " + Clase01.PI);

ya que es un miembro estático, común a todos los objetos de la clase y existente en la propia definición de ésta, por eso no necesitamos instanciar nada.

Para conseguir lo mismo con una variable de solo lectura tendríamos que añadir explícitamente el modificador static, así:

public class Clase01
{
public static readonly double PI = 3.14;
}

y ya podríamos usarla de la misma manera.

La diferencia menos evidente es a la hora de compilar

Vale, hasta aquí lo básico todo claro: las constantes son estáticas y solo se pueden asignar al declararlas, y las de solo lectura no son estáticas por defecto y se pueden asignar también en el constructor de las clases. Perfecto, ya sabemos lo mínimo que hay que saber.

Ahora vamos a hilar un poco más fino.

Supón que tienes una clase súper-básica definida de esta manera en una biblioteca de código (que genera una DLL al final):

public class Clase01 {     public static readonly double roPI = 3.14;     public const double cPI = 3.14; }

Tan solo define una clase con dos miembros estáticos: una variable de solo lectura y una constante para el número Pi.

Evidentemente en la realidad sería algo mucho más complejo con funcionalidad que quieres exponer para que luego tú o tus compañeros la utilicen como apoyo en sus desarrollos. Puede que incluso la distribuyas como un paquete NuGet y que llegue a mucha gente. Lo importante es ver el funcionamiento de las constantes y las variables de solo lectura, así que lo hacemos así de sencillo para eso.

Ahora generas un archivo .dll que distribuyes para que pueda ser utilizado para dotar de funcionalidad a otras aplicaciones.

A continuación creas un nuevo proyecto y le añades una referencia a esta DLL. Agregas el espacio de nombres y empiezas a utilizarla. Para seguir con código muy sencillo que nos permita ver entender a dónde quiero llegar, haces esto en un programa de consola:

Console.WriteLine("La constante PI vale:" + Clase01.cPI + " mientras que la readonly vale: " + Clase01.roPI);

O sea, simplemente usas la constante y la variable de solo lectura para mostrar por pantalla sus valores. En una aplicación real operarías con ellos, pero para lo que persigo me vale así.

Al ejecutarla se verá esto:

Ambos valores muestran 3.14

Bien, con tu nueva aplicación de consola lista, la compilas y la distribuyes junto con la DLL a tus "clientes" para que la usen. Al cabo de unos días decides que deberías darle más decimales a Pi, así que cambias sus definiciones y le asignas el valor 3.14156, con más decimales. Cambias el código de la DLL, la recompilas y la distribuyes.

En condiciones normales, con tan solo copiar la DLL por encima de la vieja, te funcionará todo perfectamente, ya que el código que nos interesa está en dicha DLL y el ejecutable tan solo hace uso de ella para esa funcionalidad. Sin embargo, si la ejecutas de nuevo, verás esto por pantalla:

Se ve 3.14 y 3.14156, dos valores diferentes

WTF? ¿Cómo es posible?: sólo ha cambiado el segundo valor, el de la variable de solo lectura, pero no la constante.

El motivo lo encontramos si examinamos con un decompilador el código generado para el ejecutable es:

Código generado por el compilador en el que se ve que las constantes se sustituyen por sus literales

Este es el código inverso obtenido a partir del código intermedio del ensamblado final que se distribuye. Lo pongo en C# para que sea más fácil de ver y que se observe lo que hace el compilador, pero podrías verlo directamente como código IL y comprobar allí el mismo efecto.

Lo que vemos es que, aunque son un miembro en una clase que pertenece a una DLL externa, ¡las constantes se compilan como literales!.

Es decir, el compilador, cuando analiza el código ve que se está utilizando una constante, y como esta no puede cambiar, directamente lo que hace es sustituirla en todas partes por su valor literal. Así que, las constantes, ¡incluso cuando residen en una DLL externa se compilan con su valor en todos los sitios en los que se utilicen! 

Sin embargo, en el caso de la variable de solo lectura, como puede depender de cuándo se instancie la clase, no puede hacerlo, y se sigue utilizando desde la DLL.

Por eso, cuando copiamos una nueva versión de la DLL por encima de la anterior, aunque cambiemos alguna constante no nos valdrá solo con eso. Si queremos que "pillen" los nuevos valores de las constantes debemos recompilar de nuevo las aplicaciones que hagan uso de la biblioteca.

Y este es quizá el efecto más importante entre usar una constante y una variable de solo lectura. Y también el menos evidente y más complicado de ver, que nos puede traer por la calle de la amargura si no lo tenemos claro.

¡Espero que te resulte interesante! (y útil)!

4 reglas para programar bien bajo presión

12/07/2019
Artículo original

Imagen ornamental - ver créditos a pie de artículo

He decidido escribir este artículo tras escuchar una conversación sobre los problemas más comunes en los departamentos de programación. Tras varios años trabajando con programadores, en mi empresa hemos colgado por todas las paredes de la oficina unos letreros con el siguiente mensaje: "Underpromise and overdeliver" que viene a ser algo así como comprométete lo justo y luego haz más de lo que esperan de ti.

Según la definición de McGraw-Hill, "under promise and overdeliver" es una estrategia de prestación de servicios en la que los proveedores de los mismos se esfuerzan por ofrecer un excelente servicio y una gran satisfacción al cliente, haciendo más de lo que dicen que van a hacer por el cliente o superando las expectativas del mismo. Si trabajas en una empresa de programación, tu cliente es el jefe de desarrollo y tus demás superiores.

Por otro lado, en muchos sentidos, programar es casi como desactivar una bomba en un avión cuyo temporizador está en cuenta atrás llegando al segundo cero. Imagínate que hay un artillero que está intentando desactivar la bomba para salvar vidas, trabajando bajo muchísima tensión, pero con un plazo límite llega a su fin inexorablemente. La situación es de una presión muy intensa.

Si estás como pasajero en el avión ¿cómo te gustaría que se comportase el artillero? ¿Querrías que se mostrase tranquilo? ¿Preferirías que diera órdenes claras y precisas a las personas que lo apoyan? ¿Te gustaría que mostrase destreza y maña manipulando los cables?

O por el contrario, ¿prefieres que empiece a sudar y a gesticular histriónicamente? ¿Te gustaría que se desmoronara ante la presión y se dedicase a hacer cosas sin sentido? ¿Te inspiraría confianza un artillero así?

Un buen programador no se vuelve muy bueno simplemente por escribir un código impresionante, hay muchas más cosas. Un buen desarrollador se convierte en uno buenísimo porque se muestra tranquilo y resolutivo en situaciones de presión. A medida que aumenta la presión, se aísla del entorno, se ciñe a su formación y a sus competencias, sabiendo que son la mejor manera de cumplir con los plazos y los objetivos que se le exigen.

En resumen, hace y continúa haciendo lo que debe hacerse, independientemente de los plazos que se ciernen sobre él.

Pero esto es muy fácil de decir y no es tan fácil de hacer. En el día a día en la oficina surgen imprevistos, cambios de requerimientos, improvisaciones, etc. El reto consiste en mantenerse lo suficientemente tranquilo como para gestionar la presión del momento, de modo que se pueda tener éxito de cara a un plazo que asoma las zarpas peligrosamente.

A continuación se detallan algunas de las formas en que los buenos programadores manejan las situaciones de presión.

1.- No siempre cumplas con los compromisos que TÚ no hayas asumido

"Como programadores muchas veces pensamos que podemos con todo. Hacemos un análisis racional de lo que se nos pide, estimamos el tiempo que nos puede llevar y nos comprometemos en tenerlo listo para una fecha determinada" me comenta un veterano programador siempre que sale este tema.

"Lo que nunca tenemos en cuenta son otros factores, ajenos a nuestro trabajo y que tienen más que ver con tus compañeros programadores, si se trabaja en cascada, otros departamentos, tus superiores... Y ahí empiezan los problemas y los retrasos que en última instancia repercuten siempre en nosotros ya que somos el último eslabón en la cadena (o el primero según se mire)" explica.

Como programador, muchas veces solo puedes prometer cumplir las tareas que tú hayas asumido, pero no es bueno desvivirse por los compromisos asumidos por terceros y sobre los que no has sido jamás consultado. Eso es responsabilidad de la empresa y una lección que tienes que estar dispuesto a dar siempre y cuando cumplas con tu parte.

Es muy importante que la empresa entienda la diferencia entre los compromisos adquiridos por ti y aquellos que han adquirido en tu nombre.

Un profesional siempre ayudará a la empresa a encontrar la manera de alcanzar sus objetivos. Sin embargo, un buen profesional no tiene por qué aceptar todos los compromisos asumidos por la empresa. Al final, si no podemos encontrar la manera de cumplir las expectativas que la empresa generaba, entonces las personas que las generaron deben asumir la responsabilidad.

Evidentemente, no es fácil. La presión se propaga a todo el mundo cuando no se cumplen los compromisos. Pero al menos si te has comportado profesionalmente puedes mantener la cabeza bien alta y mantenerte firme. A la larga es lo mejor para ti, para tu empresa y para los clientes.

Finalmente decir que si tu empresa no entiende tu forma de proceder, lo mejor quizás es que busques trabajo en otro sitio puesto que esa política aboca a la quiebra empresarial tarde o temprano, y no merece la pena estar a disgusto en proyectos que no son sostenibles si eres un trabajador por cuenta ajena.

Foto por Christian Erfurt en Unsplash, CC0

2.- Nunca tomes atajos

Para ser un buen programador en momentos de mucha presión lo mejor que puedes hacer es programar como si no pasara nada. Es decir, no hacer nada distinto a cuando se programa en tiempos de tranquilidad.

A los buenos programadores se les identifica en los momentos de crisis. Si cambias notablemente tu forma de trabajar cuando hay mucha presión puede ser una mala señal. Por ejemplo, si en momentos normales haces desarrollo guiado por pruebas y lo abandonas cuando el tiempo apremia, entonces es que tampoco confías mucho en esa práctica.

Si mantienes tu código limpio y ordenado en épocas de normalidad, y cuando vienen mal dadas lo empiezas a descuidar y dejas todo hecho un desaguisado será porque no te ayuda en nada ni te ralentiza lo más mínimo mantenerlo limpio y ordenado ¿no?

Lo importante aquí es no descuidar los detalles. Nunca escatimes en hacer ese esfuerzo extra, esos pocos minutos adicionales, esa dedicación al máximo que puedes hacer. No importa lo que piensen los demás, pero sí es de suma importancia lo que pienses de ti y de tu trabajo. Hay que tener en cuenta que los atajos te van a perseguir, y tarde o temprano se vuelven en tu contra.

Los programadores experimentados nunca siguen el camino más fácil ni producen un código engorroso con el fin avanzar rápidamente. Hacen el trabajo lo mejor que pueden y entregan un código lo más limpio posible, aislándose del entorno y de los agobios.

3.- Comparte información constantemente

Se trata de compartir información clara y precisa, y con honestidad. Las personas que trabajan contigo en la empresa son merecedoras de conocer los hechos, de conocer la realidad de las cosas. No intentes contarles la mitad de la historia. No intentes tapar la realidad.

Comunicación. Se trata de honestidad. Se trata de tratar a la gente de la organización como merecedora de conocer los hechos. No intentes darles la mitad de la historia. No intentes ocultar la historia.

Si tienes alguna información importante para compartir con tu jefe, tus compañeros, tus proveedores, incluso si no son buenas noticias, no te demores. Si aplazas el momento de dar información útil hasta que ya sea demasiado tarde para actuar, entonces tus mensajes nunca serán bien recibidos, tanto si son cosas buenas o cosas malas porque te habrás creado una reputación que luego es muy difícil de limpiar.

En casi todos los escenarios imaginables, es conveniente una comunicación lo más rápida posible, permitiendo que todos los involucrados entiendan y digieran la información, y que formulen una reacción apropiada y respondan en consecuencia. Si se trata de malas noticias, una alerta temprana puede permitir elaborar un plan para intentar minimizar el daño.

Por encima de todo, mantén la profesionalidad, la educación, la franqueza y la claridad, características que harán que tu comunicación vaya en la dirección adecuada a lo largo del tiempo que estés en tu lugar de trabajo y con una reputación respetable.

4.- Aprende a pedir ayuda cuando las cosas se ponen feas

Foto por Jon Tyson en Unsplash, CC0

Búscate un socio, un cómplice dentro del equipo, que esté dispuesto a echarte una mano en momentos de dificultad, y haz lo mismo tú con él. Aplica el principio de "hoy por ti, mañana por mí".

La programación a pares os ayudará a hacer las cosas en menos tiempo y con menos errores, y es una motivación añadida, ya que el simple hecho de comprometerte a colaborar te ayudará a centrarte en las tareas y a no perder el tiempo.

La programación a pares implica tener a otra persona viendo lo que haces todo el tiempo. Programando así las personas son menos propensas a distraerse por las interrupciones (por ejemplo, revisar el correo electrónico, divagar y procrastinar en tareas no relacionadas, o a mirar fijamente a la pantalla sin hacer nada). Incluso se pueden eliminar las tareas secundarias relacionadas. La persona en el teclado puede concentrarse en simplemente golpear el código, mientras que el compañero puede preocuparse por la legibilidad, la estabilidad, la robustez y otras cuestiones de globales relacionadas con el código. El hecho de trabajar con una pareja proporciona una presión positiva para mantenerse en la tarea y no perder foco.

Lo normal es que el proceso de adaptación de programar solo a programar en parejas no sea un camino de rosas. Es como cuando bebes cerveza o café por primera vez, no te gusta porque no estás acostumbrado a esos sabores tan característicos, pero a medida que bebes más, te termina gustando.

El desarrollo en equipo además crea una cultura de colaboración y reconocimiento. La próxima vez que veas a alguien que se encuentre bajo presión, ofrécete a formar pareja, y muéstrales el camino para salir adelante.

Nota: imagen de cabecera "Pressure meter" por alex.ch con licencia CC BY-SA 2.0.

Cómo personalizar los estilos CSS de las barras de scroll

08/07/2019
Artículo original

 

A veces en el contenido de nuestras páginas web o aplicaciones, tenemos un elemento pequeño que, por lo que sea, no podemos evitar que le aparezcan las temidas barras de scroll. Y por si esto fuera poco, tenemos otro problema, y es que en móviles normalmente el hecho de que un elemento tenga scroll no se ve a primera vista hasta que interactúas con él.

Un ejemplo de esto pueden ser los bloques de código en un blog técnico como este. Pongamos que tienes un ejemplo de código que es importante que esté, pero no es tan importante como para obligar al lector a hacer scroll sobre todo su contenido. Quizá te interese limitarle el alto y ponerle un overflow:auto a su contenedor.

De esta manera, el que quiera curiosear en el código puede hacerlo, y el que no, no tiene por qué hacer scroll por toda la parte que no le interesa.

Pero claro, en un móvil es fácil que el usuario pase por alto que hay más código que el visible a simple vista, al menos en Chrome. Me refiero a que, cuando no estás haciendo scroll, la barra desaparece:

Editando con CSS las barras de scroll

¿Qué podemos hacer? Editar barras de scroll con CSS, en general más bien poco, pero lo suficiente para solucionar esto y adecentar la apariencia. Básicamente, usaremos etiquetas propietarias, porque, aunque hay un borrador de un estándar en camino, la verdad es que está en pañales y apenas Firefox implementa un par de propiedades experimentales desde la versión 64.

Por cierto, el primer navegador que permitía personalizar las barras de scroll fue Internet Explorer en la época de la Guerra de los navegadores, allá por finales de los noventa, pero dado que es un navegador que está en desuso, en este post lo vamos a obviar.

Actualmente los navegadores que ofrecen más alternativas son los basados en Webkit y Blink (principalmente Chrome, Opera, Safari y, muy pronto, Edge). El actual navegador Edge no tiene posibilidad de personalización, así que nos limitaremos a Chrome (Blink y Webkit) y a las pocas reglas que soporte Firefox.

Para Chrome (ya me entiendes, no solo me refiero a él) disponemos de los siguientes pseudoelementos personalizables:

Pseudoelementos para Webkit/Blink

  • -webkit-scrollbar el elemento que envuelve al conjunto
  • -webkit-scrollbar-button la barra y los botones
  • -webkit-scrollbar-track el carril de la barra
  • -webkit-scrollbar-track-piece la parte interna del carril de la barra
  • -webkit-scrollbar-thumb la almohadilla de la barra, o la barra en sí misma, como prefieras llamarle
  • -webkit-scrollbar-corner la esquina inferior derecha
  • -webkit-resize la esquina inferior derecha cuando el elemento es redimensionable

Pseudoclases propietarias para Webkit/Blink

Para terminar de precisar la apariencia, podemos usar las siguientes pseudoclases

  • :horizontal - Esta pseudoclase se aplica a cualquier barra de scroll horizontal

  • :vertical - Esta, obviamente a barras de scroll verticales

  • :decrement – Se aplica a los botones y al carril de la barra cuando se hace scroll en dirección decreciente (o sea, hacia abajo en vertical, hacia la izquierda en horizontal)

  • :increment – Se aplica a los botones y al carril de la barra cuando se hace scroll en dirección creciente (o sea, hacia arriba en vertical, hacia la derecha en horizontal)

  • :start – Precisa si un objeto está antes de la almohadilla de la barra

  • :end – Sirve para precisar si un objeto está después de la almohadilla de la barra

  • :double-button – Aplica a botones y a partes del carril (o pista) Sirve para seleccionar botones que forman parte de un par de botones o la barra de scroll se apoya en un botón doble.

  • :single-button – Lo mismo que el anterior, pero refiriéndose a un botón simple.

  • :no-button – Se aplica a botones y scrollbars que no tienen botón.

  • :corner-present – Se aplica a elementos de barras de scroll donde no está presente la típica esquina del scroll.

  • :window-inactive – Se aplica a scrollbars cuya ventana no está activa.

Otras pesudoclases que también podemos usar con elementos de las barras de scroll son :enabled, :disabled, :hover y :active , así como aplicarles un simple display:none

Retocando nuestras barras

Volviendo a nuestro ejemplo, tenemos este HTML: un div con texto al que le he puesto la clase "contenedor":

<div class="contenedor">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras eget nisi erat. Morbi vel lacus rutrum, imperdiet ligula a, faucibus justo.</p>
    <p>Sed <a href="https://www.campusmvp.es">eu risus ultricies</a>, mattis lacus vitae, tristique mauris. Pellentesque rutrum est at est tempor accumsan.</p>
    <p>Mauris vulputate ultrices volutpat. Fusce tincidunt arcu vel orci laoreet, a convallis urna tristique.</p>
    <p>Mauris sit amet nisi a augue malesuada semper. Vivamus nec volutpat turpis. Suspendisse est velit, blandit et dui nec, posuere dapibus mauris.</p>
    <p>Pellentesque suscipit arcu in lorem ullamcorper hendrerit. Ut vel diam ornare, consectetur libero vitae, hendrerit elit. Cras eu orci porta odio facilisis bibendum a vel felis.</p>
</div>

Vamos a ponerle una barra de scroll fina, similar a la de dispositivos móviles, pero un poco más grande y que esté siempre visible en éstos. Así que en el CSS le vamos a hacer esto para Chrome:

.contenedor {
    margin: 2rem auto;
    border: 1px solid #aaa;
    height: 300px;
    width:90%;
    max-width: 400px;
    background: #f1f2f3;
    overflow:auto;
    box-sizing: border-box;
    padding:0 1rem;
}

/* Estilos para motores Webkit y blink (Chrome, Safari, Opera... )*/

.contenedor::-webkit-scrollbar {
    -webkit-appearance: none;
}

.contenedor::-webkit-scrollbar:vertical {
    width:10px;
}

.contenedor::-webkit-scrollbar-button:increment,.contenedor::-webkit-scrollbar-button {
    display: none;
} 

.contenedor::-webkit-scrollbar:horizontal {
    height: 10px;
}

.contenedor::-webkit-scrollbar-thumb {
    background-color: #797979;
    border-radius: 20px;
    border: 2px solid #f1f2f3;
}

.contenedor::-webkit-scrollbar-track {
    border-radius: 10px;  
}

¿Qué hacemos con esto? Lo primero de todo, quitarle la apariencia propia del sistema operativo. Después, le redondeamos los bordes y hacemos más finas las barras, con un ancho suficiente para que se vean, pero sin comernos demasiado espacio.

Y para Firefox le añadiremos (dentro de la regla de .contenedor) un par de líneas de reglas estándar, aunque experimentales:

.contenedor {
    /*Estilos estándar experimentales (Principalmente Firefox)*/
    scrollbar-color: rgba(0, 0, 0, .5) rgba(0, 0, 0, 0);
    scrollbar-width: thin;
}

No quedará igual, pero sí muy parecido y se vería así:

Puedes descargar el ejemplo completo (ZIP, 5.8Kb) para examinar el código y probarlo.

Recuerda que la gran mayoría de estas técnicas o bien son propietarias o bien son experimentales. Mantén las expectativas bajas en cuanto a consistencia de la apariencia entre navegadores y ten en cuenta que en cualquier momento pueden cambiar.

Espero haberte arrojado un poco de luz sobre este tema y que te haya sido de utilidad.

Integración continua: qué es y por qué deberías aprender a utilizarla cuanto antes

03/07/2019
Artículo original

Imagen ornamental CC0 por Waldemar Brandt en Unsplash

En el mundo del software, palabras como integración continua o despliegue continuo (CI/CD) están a la orden del día. Se da por supuesto que todos los que estamos metidos en este gremio conocemos su significado y sus ventajas, pero la triste realidad es que no es así. Mucha gente no lo conoce y otra lo conoce y no lo aplica.

Por esa razón, en el artículo de hoy voy a intentar aclarar las ventajas que nos ofrece el concepto, para aseverar que, sin lugar a dudas, para hacer software de calidad, la integración continua es un requisito necesario y no negociable.

¿Qué es la integración continua (CI)?

Para poder hablar de sus ventajas, lo primero es conocer en qué consiste. La integración continua es el nombre que se le da a la automatización de las labores de compilación, test y análisis estático del código. Esto se puede conseguir de muchas maneras, y podemos llamar integración continua a todo lo que hay entre un script que periódicamente ejecuta el trabajo y un servicio online que lo haga.

La integración continua (continuous integration en inglés) es un modelo informático propuesto inicialmente por Martin Fowler que consiste en hacer integraciones automáticas de un proyecto lo más a menudo posible para así poder detectar fallos cuanto antes. Entendemos por integración la compilación y ejecución de pruebas de todo un proyecto. (Wikipedia)

¿Cómo funciona?

Independientemente del sistema que utilicemos para iniciarlo (tarea programada, un Webhook, etc), el proceso como mínimo seguirá el siguiente camino:

La imagen muestra el flujo de trabajo de la integración continua

  1. Descargará el código fuente desde el repositorio de control de versiones (git, SVN, Mercurial...).
  2. Compilará el código según sea necesario.
  3. Realizará las pruebas unitarias y/o de integración.
  4. Publicará los resultados de modo que sea accesibles.

Dependiendo de lo integrado que esté el servicio con el repositorio de código, podemos verlo directamente en el historial de commits. Por ejemplo en el caso de GitHub:

La imagen muestra un ejemplo de la integración de los resultados en github

¿Cuándo debería ejecutarla?

Lo ideal, es ejecutarla siempre que se añadan cambios al repositorio principal. Pero esto tiene un coste. Compilar cada cambio que hacemos nos da cierta seguridad, pero puede hacer que nuestro sistema de CI trabaje más de la cuenta y suponga un coste adicional. En cambio, aplicarla a todos los pull request nos garantiza que todos los cambios sobre la línea principal de trabajo van a funcionar bien. Aquí se trata de encontrar un equilibrio entre coste y beneficio.

Si nuestro proyecto es Open Source, existen varios servicios de integración continua online gratuitos como Travis CI, AppVeyor, Azure Pipelines, Circle CI.

¿Y qué me aporta?

Las principales ventajas que tiene son:

  • Detectar rápidamente los posibles errores de compilación de nuestro código. (en mi máquina funcionaba...)
  • Detectar funcionamientos anómalos en nuestro software. (es un bug, no una nueva característica)
  • Mejorar la calidad de nuestros productos
  • Nos permite compilar/testear nuestro código en diferentes plataformas.

En conclusión

Con el gran abanico de posibilidades que existen hoy en día para poder añadir integración continua a nuestro código, no hacerlo no es una opción. Da igual si es un proyecto grande o pequeño, da igual si eres un único desarrollador o un equipo. Existen incluso algunas opciones gratuitas que nos permiten hacerlo.

¿Quién no ha oído nunca el "en mi máquina funcionaba"? En mi experiencia personal, es una respuesta que he oído varias veces (y yo mismo he dicho). La integración continua es una solución muy eficaz para evitar ese tipo de problemas y poder aportar valor con nuestro software sin tener que perder horas y horas (que muchas veces no se tienen) en compilar nuestro proyecto para varias plataformas, ejecutar pruebas, analizadores de código...

Solución a la conexión sin identificar y pública en Windows Server

02/07/2019
Artículo original

Un día te levantas de buena mañana y, antes de que el café del desayuno se haya asentado en tu estómago, descubres que todas las conexiones a tu servidor de datos en tu red privada han dejado de funcionar. Obviamente no has tocado nada. Tu único pecado ha sido irte a dormir. Pero de repente nada parece funcionar. ¿A qué es debido?

Bueno, ahora te digo la causa concreta, pero el motivo último: una maldita actualización del sistema y un reinicio indeseado del servidor.

Windows Server (al menos en sus versiones 2012 y 2016 basadas en Windows 10) tiene algunas cosas molestas y problemillas. Y este es uno de ellos.

En ocasiones, cuando se reinicia el sistema se fuerza un reconocimiento de las redes a las que está conectado el servidor. Cuando una de ellas no tiene acceso a Internet, ¡zasca! , Windows la clasifica como una red sin identificar. Generalmente esto ocurre con la que se conecta a la red local. ¿Y cuál es el problema de esto? Pues que a este tipo de redes, por defecto, Windows las clasifica como redes públicas. Y si tienes un servidor, lo más común es que tengas el cortafuegos configurado de manera que las redes públicas tengan muchas restricciones, y las redes privadas o de dominio muchas menos.

Por ejemplo, estas son las 2 tarjetas de red de un servidor de datos que gestiono, tal y como me las encontré una mañana:

El centro de redes y compartición, con mis dos tarjetas

Como puedes observar hay dos redes correspondientes a otras tantas tarjetas de red. Una de ellas (que ha llamado Network 2 y yo denomino WAN) es a que está conectada a Internet. La otra es una tarjeta dedicada en exclusiva a tráfico en la red local, de la que forman parte unos cuantos servidores más. Al reiniciar Windows no reconoce esta red porque no está conectada a Internet y como resultado la nombra como "Unidentified network" (o sea, "Red no identificada") y la marca como pública.

Al considerarse una red pública y no privada que es lo que es en realidad, de repente, las reglas del firewall que actuaban sobre ella y permitían, por ejemplo, la conexión a esta máquina desde otras de la red local, dejan de funcionar, actuando las reglas para redes públicas (o sea, conectadas a Internet) y que son muchísimo más restrictivas (incluso bloqueo total del acceso en este caso). Resultado: webs caídas, soporte sin funcionar, etc...

Por suerte tiene fácil solución, aunque nada evidente. La voy a dejar reflejada aquí par ami futura referencia y por si le sirve a alguien más.

Para solucionarlo, primero vamos a proceder manualmente. Debes abrir una línea de comandos de Powershell como administrador y escribir esta instrucción para ver la información de tus conexiones:

Get-NetConnectionProfile

que devuelve algo como esto con información de las conexiones de red:

resultado de comando

En este caso he resaltado la que no está identificada. Lo más importante es tomar nota del alias de la conexión o de su identificador (yo prefiero este último por concisión, pero vale cualquiera).

Una vez identificada la que queremos modificar, vamos a cambiar de pública a privada escribiendo lo siguiente:

Set-NetConnectionProfile -InterfaceIndex 5 -NetworkCategory Private

que también puede hacerse indicando el alias en vez del índice:

resultado del comando y nueva consulta de conexiones

El comando no devuelve ni un lacónico mensaje por pantalla, pero si volvemos a pedir la información sobre las conexiones, como se observa en la figura, nuestra conexión problemática vuelve a ser considerada privada. aunque Windows sigue diciendo que está sin identificar.

¡Bien! Problema resuelto al menos por el momento. Lo mal es que quizá dure poco. No podemos saberlo. Quizá en una próxima actualización o reinicio del servidor, la cosa se vaya de madre y se vuelva a clasificar como pública. Así que, más allá de una solución puntual, no nos va a servir de mucho.

Para hacer que perdure tenemos que ir un pasito más allá. Debemos abrir las políticas de seguridad local del sistema (basta buscarlas en el menú de inicio) y abrir el nodo "Políticas del gestor de listas de red" (o algo así, ya sabes que yo uso todos los sistemas en inglés siempre, precisamente para evitar traducciones traicioneras). Es el cuarto nodo que encontrarás en la raíz.

Si haces doble-clic sobre el subnodo dedicado a las redes sin identificar verás que te deja establecer cómo quieres considerarlas por defecto: públicas o privadas (si está sin establecer, serán públicas):

Políticas para redes

Establece la opción "Privada" para el tipo de ubicación y listo. A partir de ahora, cuando se produzca de nuevo el problema, las redes sin identificar se considerarán privadas y el firewall no interferirá en su tráfico sin motivo.

¡Espero que te sea útil!

Ocurrió lo inevitable: el uso de Linux ha superado al de Windows en Azure, la nube de Microsoft

01/07/2019
Artículo original

Ocurrió lo inevitable: el uso de Linux ha superado al de Windows en Azure, la nube de Microsoft

El idilio de Microsoft con Linux ya no sorprende a nadie. Al principio hubo mucho escepticismo entre la comunidad, imaginando que la compañía de Redmond podía tener intereses que jugaran en contra de los suyos. Pero con la enorme cantidad de patentes, la llegada del kernel real de Linux a Windows 10 con el WSL 2, o la gestión que están haciendo de GitHub tras su compra, la mayoría de dudas se han disipado.

Ahora, según nos llega por Sasha Levin, un desarrollador de kernel de Linux de Microsoft, "el uso de Linux en nuestra nube (haciendo referencia a Azure) ha sobrepasado al de Windows". La tendencia estaba clara, como la de que en algún momento, aunque costara, la cuota de Windows 10 superaría a la de Windows 7, pero igualmente es histórico.

Hace más de tres años, Linux representaba una de cada cuatro instancias en Azure. En 2017, el 40% de máquinas virtuales de Azure ya funcionaban con Linux, mientras que a finales de 2018, las máquinas virtuales de Linux en Azure ya suponían prácticamente la mitad.

Una situación que refleja mejor el estado de la industria

Ms Linux

El dominio de Linux en servidores desde hace años y años es incuestionable, como lo ha sido su crecimiento en Azure. Lo que ha ocurrido con la nube de Microsoft no es ni más ni menos un reflejo de lo que ocurre en el resto de la industria. La naturaleza de código abierto de Linux hace que las empresas opten por soluciones basadas en él para adaptar sus herramientas al sistema y viceversa. En Linux puedes activar y desactivar todas las funciones que necesites o no, algo que resulta crucial para optimizar el rendimiento

Esa modularidad y versatilidad permite que Linux pueda reinar en supercomputadores, pero también en dispositivos de capacidad muy limitada, como los del Internet de las Cosas. Además, se suma a ello, entre otras cosas, la escalabilidad que Linux permite cuando las necesidades de carga crecen o decrecen, algo fundamental en servidores y que hace mejor que sus rivales.

No solo es que en Azure ya se use más Linux que Windows, sino que como recogen en ZDNet, hay servicios nativos de Microsoft en Azure que ya se ejecutan bajo Linux, como por ejemplo Software Defined Network. El papel de Windows Server también ha sido muy importante durante años, pero actualmente su uso está en franco declive, y noticias como la compra de Red Hat por IBM son un claro reflejo del interés por todo lo relacionado con Linux y la nube.

Vía | ZDNet

Ocurrió lo inevitable: el uso Linux de ha superado al de Windows en Azure, la nube de Microsoft

01/07/2019
Artículo original

Ocurrió lo inevitable: el uso Linux de ha superado al de Windows en Azure, la nube de Microsoft

El idilio de Microsoft con Linux ya no sorprende a nadie. Al principio hubo mucho escepticismo entre la comunidad, imaginando que la compañía de Redmond podía tener intereses que jugaran en contra de los suyos. Pero con la enorme cantidad de patentes, la llegada del kernel real de Linux a Windows 10 con el WSL 2, o la gestión que están haciendo de GitHub tras su compra, la mayoría de dudas se han disipado.

Ahora, según nos llega por Sasha Levin, un desarrollador de kernel de Linux de Microsoft, "el uso de Linux en nuestra nube (haciendo referencia a Azure) ha sobrepasado al de Windows". La tendencia estaba clara, como la de que en algún momento, aunque costara, la cuota de Windows 10 superaría a la de Windows 7, pero igualmente es histórico.

Hace más de tres años, Linux representaba una de cada cuatro instancias en Azure. En 2017, el 40% de máquinas virtuales de Azure ya funcionaban con Linux, mientras que a finales de 2018, las máquinas virtuales de Linux en Azure ya suponían prácticamente la mitad.

Una situación que refleja mejor el estado de la industria

Ms Linux

El dominio de Linux en servidores desde hace años y años es incuestionable, como lo ha sido su crecimiento en Azure. Lo que ha ocurrido con la nube de Microsoft no es ni más ni menos un reflejo de lo que ocurre en el resto de la industria. La naturaleza de código abierto de Linux hace que las empresas opten por soluciones basadas en él para adaptar sus herramientas al sistema y viceversa. En Linux puedes activar y desactivar todas las funciones que necesites o no, algo que resulta crucial para optimizar el rendimiento

Esa modularidad y versatilidad permite que Linux pueda reinar en supercomputadores, pero también en dispositivos de capacidad muy limitada, como los del Internet de las Cosas. Además, se suma a ello, entre otras cosas, la escalabilidad que Linux permite cuando las necesidades de carga crecen o decrecen, algo fundamental en servidores y que hace mejor que sus rivales.

No solo es que en Azure ya se use más Linux que Windows, sino que como recogen en ZDNet, hay servicios nativos de Microsoft en Azure que ya se ejecutan bajo Linux, como por ejemplo Software Defined Network. El papel de Windows Server también ha sido muy importante durante años, pero actualmente su uso está en franco declive, y noticias como la compra de Red Hat por IBM son un claro reflejo del interés por todo lo relacionado con Linux y la nube.

Vía | ZDNet

Visual Studio Code: Las 15 extensiones indispensables para programar con C# y .NET Core

24/06/2019
Artículo original

Imagen ornamental

Hace unas semanas Jorge Turrado nos contaba en un artículo y un vídeo cómo podíamos montar un entorno de desarrollo para C# y .NET Core con Visual Studio Code.

La extensión fundamental e indispensable que nos comentaba en aquella ocasión es la que se llama simplemente C# y que nos proporciona soporte para este lenguaje desde el editor, con Intellisense, depuración y soporte para archivos de proyecto de Visual Studio.

Pero además de esta y de la configuración básica del entorno, existen otras muchas extensiones especiales para trabajar con C# y .NET que nos facilitan mucho la vida y que voy a repasar a continuación.

Quitando las primeras, el orden de la lista que verás a continuación no tiene importancia, así que no te lo tomes como un ranking ni nada similar, y cualquiera puede serte útil aunque esté a final.

¡Allá vamos!

  • .NET Core Tools: añade opciones al menú contextual cuando pulsas sobre un archivo .csproj o .sln de .NET Core para poder compilarlo, ejecutarlo o lanzar las pruebas unitarias.
  • Dotnet Core commands: para poder lanzar los comandos de .NET Core sin tener que ir a la línea de comandos y sin tener que escribirlos.
  • Extensiones para C#: con multitud de atajos para tareas comunes con este lenguaje como añadir una clase o una interfaz, etc...
  • Auto-Using for C#: esta sensacional extensión te añade de manera automática los using que necesites en la cabecera de tu archivo de código a medida que empiezas a utilizar nuevas clases que no estaban referenciadas.

Auto-using en acción

  • NuGet Package Manager: una extensión que te permite gestionar fácilmente las referencias a paquetes NuGet desde tu proyecto de VSCode.
  • NuGet Reverse Package Search: complementa a la anterior, y te permite añadir los paquetes NuGet que falten en el proyecto cuando se detecta un error por este motivo, de manera parecida a como lo hacemos en Visual Studio para Windows cuando falta alguno.
  • ASP.NET Helper: si programas aplicaciones Web con ASP.NET Core MVC, esta extensión te proporciona IntelliSense para páginas Razor. Muy interesante.
  • C# Snippets, del MVP español Jorge Serrano, con muchos fragmentos de código que podemos insertar mientras trabajamos para ahorrarnos tener que escribir código.
  • Essential ASP.NET Core Snippets: con múltiples fragmentos de código listos para ser insertados y ahorrar trabajo si programas para la Web con .NET Core.
  • ASP.NET Core Scaffolding: te permite crear la estructura de las vistas y controladores de ASP.NET MVC de la misma manera que en Visual Studio "tradicional" para Windows. Un "must-have" si programas en esta plataforma web de servidor.
  • ASP.NET Core Switcher: te permite cambiar rápidamente entre el modelo, la vista y el controlador relacionados entre sí, en un proyecto ASP.NET Core MVC. Puedes usar teclas rápidas, lo cual hace que ahorres mucho tiempo en este tipo de desarrollos.

ASP.NET Core  Switcher en acción

  • Soporte para comentarios XML de documentación: para documentar mientras programamos, como en Visual Studio tradicional para Windows. Escribe /// y te genera el esqueleto de documentación de cualquier método o clase.
  • .NET Core Test Explorer, para facilitarte la vida a la hora de ejecutar pruebas unitarias.
  • SQL Server: añade soporte para SQL Server en VSCode, con posibilidad de crear y gestionar conexiones, escribir código T-SQL con ayuda contextual, ejecutar código y ver los resultados en el entorno incluso guardándolos como CSV o JSON, etc... Indispensable si trabajas con el SGBDR de Microsoft (que también funciona en Linux, no lo olvides).
  • Better Comments: que permite crear varios tipos de comentarios con significado, para ayudarte a anotar cosas importantes en el código, como por ejemplo alertas, tareas pendientes, cuestiones destacadas... Soporta muchos lenguajes, no solo C#, así que te vale para muchos otros.

¡Espero que te sean útiles!

7.000 programadores responden: Java, Python y JavaScript son los lenguajes favoritos, y Go se perfila como el más prometedor

17/06/2019
Artículo original

7.000 programadores responden: Java, Python y JavaScript son los lenguajes favoritos, y Go se perfila como el más prometedor

JetBrains acaba de publicar su encuesta anual sobre el estado actual del ecosistema de desarrollo, para ello entrevistaron a casi 7.000 programadores a principios de 2019 para identificar los lenguajes de programación más populares y las tendencias del momento.

Los puntos claves más importantes vienen a coincidir con algo que se ha hecho norma en los últimos años: Java, JavaScript y Python siguen siendo los lenguajes favoritos de los desarrolladores, pero cada vez despertando más interés, Go se viene perfilando como uno de los lenguajes más prometedores y que muchos se están planteando adoptar o incluso hasta migrar a él.

Go Go Developers

Go es un lenguaje joven, y esta subida en el interés por él concuerda con otros indicadores, como por ejemplo en índice PYPL que mide la popularidad de los lenguajes según la cantidad de tutoriales que se buscan sobre ellos, en donde Go viene subiendo paulatinamente.

Así mismo, el 2019 Developer Skills Report de HackerRank, ponía a Go como el principal lenguaje de programación que los desarrolladores quieren aprender este año, y a eso le podemos sumar el último informe de Hired que muestra a Go a la cabeza en los lenguajes de programación más demandados actualmente por las empresas a la hora de entrevistar candidatos.

Los números de la encuesta de JetBrains tienen a un 13% de los desarrolladores deseando adoptar o migrar a Go, un lenguaje que pasó de ser usado por solo un 8% de los entrevistados en 2017, a un 18% dos años después, más del doble.

Lenguajes De Programacion ¿Qué lenguajes de programación has usado en los últimos 12 meses? Naranja: usado en los últimos 12 meses Gris: planea adoptar o migrar a Fuente: JetBrains - The State of Developer Ecosystem 2019

El más popular, el más usado, el más estudiado

Pero mientras Go continúa su ascenso entre los desarrolladores, los favoritos de siempre permanecen casi inamovibles: Java, JavaScript, Python y C# siguen siendo los más apreciados, y también los más usados como lenguaje primario.

Python también es el más estudiado, un 27% de los encuestados ha empezado a aprender Python o a continuado su educación en este lenguaje en los últimos 12 meses.

De entre estos 7.000 programadores entrevistados, el 40% utiliza JavaScript, el 34% usa Java, el 27% usa Python, y el 15% usa C#. De entre todos esos, hay un 44% de usuarios que utiliza Java y solo Java como único lenguaje, mientras que en el caso de JavaScript, solo un 17% vive solo con él como primario.

La mayoría de los programadores usan Windows, aunque las diferencias entre macOS y Linux son mínimas

Otros datos interesantes de la encuesta tienen que ver con las herramientas que usan los programadores, y en el caso del sistema operativo Windows salió ganando con 57% de los encuestados, pero macOS y Linux también son usados por el 49 y 48% de los programadores respectivamente.

El 89% de los desarrolladores personaliza sus IDEs de alguna forma, el 80% utiliza alguna herramienta de colaboración para su código fuente, el 75% usa un IDE en solitario, el 71% utiliza un editor de escritorio ligero, y al 83% les encanta el tema oscuro y lo prefieren a la hora de escribir código.

Ah, y el 52% de los programadores respondieron que escriben código en sus sueños...

Página Siguiente