martes, abril 28, 2015

La industria de la Ingeniería de Software para físicos y matemáticos



Las computadoras han venido a facilitar la resolución de problemas. Desde tomar notas, enviar documentos a destinos a miles de kilómetros, hacer tus pagos, hasta un sistema de recomendaciones, métodos de identificación de personas por comportamiento, ¡Autos que se manejan sólos!.

Las computadoras no resuelven ningún problema por sí solas. Es necesario que alguien les enseñe a resolverlos y para esto, primero hay que saber resolver el problema. Es ahí donde los físicos y matemáticos tienen una buena oportunidad, porque lo que hacen es resolver problemas. Durante su formación estarán resolviendo problemas por 4 ó 5 años (sin cotas estrictas) prácticamente todos los días.

El trabajo de un programador es enseñarle a una computadora como resolver un problema por medio de algoritmos. Y un algoritmo no es nada desconocido para los físicos y matemáticos. ¿Qué es una demostración sino un algoritmo? tienen un número finito de afirmaciones que te llevan de una hipótesis (input) a un resultado (output).

Obviamente, hay mejores maneras de resolver un problema que otras. Si les pido buscar "ONOMATOPEYA" en un diccionario no van a empezar a buscar palabra por palabra empezando por "A", "ABA", "ABAD", "ABAN". De la misma manera ocurre con los programas, hay mejores maneras de implementar un programa que de otras.

Un ejemplo clásico es búsqueda binaria. Imaginen que les doy un diccionario con un millón de palabras y la habilidad de llegar a la n-ésima palabra de manera instantanea. Si les pregunto por una palabra ¿Cuantas palabras tienen que consultar para llegar a la palabra que les pregunté? (podría ser que les pregunte por una palabra que no está en el diccionario).

Una solución es ir buscando palabra por palabra hasta llegar al lugar donde debería estar la palabra que están buscando. En el peor de los casos tendrían que revisar un millón de palabras sólo para darse cuenta de que no está la palabra que les pedí.

Una mejor solución, es preguntar por la palabra de en medio (la 500,000), ver si esa palabra está antes o después de la que estoy buscando y repetir esto con la primera mitad (si la palabra está antes) o la segunda mitad (si la palabra está después). De esta manera en el peor de los casos, sólo se necesitan 20 (función techo de logaritmo base dos de un millón) consultas para encontrar o dar por no existente la palabra por la que les di a buscar. (Esta solución es conocida como búsqueda binaria).

Los problemas de programación requieren diseñar estrategias eficientes, fuerza bruta siempre es una solución, pero pocas veces es una buena solución. Imaginen que cada lectura a disco duro les toma 0.1 segundos. En el caso anterior ¡Fuerza bruta utilizaría 100,000 segundos para encontrar una palabra en el peor caso (eso es más de un día)! Búsqueda binaria utlizaría 2 segundos. (Una lectura a disco duro en realidad toma mucho menos que 0.1 segundos, la intención de la exageración es que puedan comparar la eficiencia de dos distintas soluciones).

La ingeniería de software está repleta de este tipo de retos. Lamentablemente muchas escuelas
en México no le dan importancia a que los futuros desarrolladores de software aprendan a
resolver los problemas por su propia cuenta y generalmente están atenidos a que alguien
más los resuelva, empaque la solución en una librería y lo publique, lo cual consume tiempo, el recurso más valioso en una industria que evoluciona a pasos agigantados. También cabe mencionar que aquellos programadores que saben manejar un gran número de herramientas son muy valiosos (tal vez conocer la herramienta correcta te ahorre un par de días de desarrollo), pero esto requiere invertir bastante tiempo. Jugar en ambos lados, crear soluciones y conocer soluciones, es lo más conveniente.

Esta es la parte que diferencía a un programador de una persona que sabe utlizar lo que un programador hizo.

Sobre la industria del software:

  • Al igual que en cualquier otra industria siempre tendrá mejores oportunidades quien pueda resolver los problemas de la mejor manera posible en el menor tiempo posible.
  • Es una industria que evoluciona a pasos muy agigantados, siempre es bueno experimentar con nuevas tecnologías y mantenerse al día.
  • En México generalmente las buenas oportunidades siempre implican moverse de ciudad. (Morelia tiene una industria de software en crecimiento, sin embargo aún es pequeña. Las empresas más importantes están en Guadalajara, Monterrey y el Distrito Federal). 
  • El desarrollo de software mexicano es principalmente consumido por Estados Unidos y México mismo. México ha ganado un buen lugar en el mercado estadounidense frente a la India por dos razones: la zona geográfica favorece la comunicación con Estados Unidos, y México ha demostrado tener mejores desarolladores que la India (en promedio). 
  • Existen muchos trabajos de freelancer, los cuales son bien pagados y uno tiene libertad de trabajar desde casa, pero sólo garantizan trabajo por temporadas cortas y requieren de mucha experiencia. Estos trabajos no son fáciles de encontrar para un principiante, hay que armar un buen portafolio para facilitar estas ofertas.
  • Debido a que la mayor parte del trabajo implica estar sentado, existen varios riesgos de salud en esta industria. No es nada que no pueda contrarrestarse con un poco de ejercicio, pero hay que estar conscientes de ello.
  • Una vez que uno consigue demostrar su valía es fácil encontrar buenas oportunidades o mejorar las actuales.

Sus proyectos escolares sirven como código que puede presentarse en una entrevista de trabajo, no se deshagan de él, y si es posible, súbanlo a un lugar visible (github o bitbucket por ejemplo).

Materias que les recomiendo tomar:

  • Computaciones 1 y 2. (Pongan mucha atención en estructuras de datos).
  • Todos los cursos de Matemáticas Discretas que puedan, en particular aquellas que incluyan Teoría de Gráficas.
  • Si pueden conseguir un curso en optimización combinatoria sería muy bueno.
  • Lenguajes de Programación. 
  • Lenguajes Formales.
  • Teoría de la Complejidad Computacional.
  • Inteligencia artificial.
  • Diseño y análisis de algoritmos.
  • Bases de datos.
  • Probabilidad.
  • Teoría de números.
Sé que es una lista larga, no esperaría que los tomaran todos, pero considero que todos estos cursos contribuyen con aportaciones importantes.

Programen mucho, programar se aprende programando, es muy complicado enseñar a programar.
Se pueden dar consejos, pero la única manera en que en realidad aprenderán es cuando intenten
resolver sus propios problemas.

El inglés es fundamental y les dará ventaja en el mercado mexicano. No se diga en el extranjero.

Cosas que podrían ir aprendiendo desde ahora:

  • Programación Orientada a Objetos. (bien aprendido)
  1. Herencia.
  2. Diferenciar miembros de instancia y estáticos. 
  3. Diferenciar public, protected, private, en caso de C#, internal también. (access modfiers).
  4. Diferenciar una clase de una interfaz.
  • Manejar Linux propiamente, en Linux es más fácil resolver algunas tareas que en Windows, una vez que lo aprenden a hacer en Linux, encontrar la analogía en Windows será más sencillo. Siempre es mejor ser hábiles en ambos. (Recomendación personal, Ubuntu para principiantes, y Arch Linux para cuando ya no sean principiantes).
  • Busquen muchos problemas y resuélvanlos.
  • Aprendan a utilizar al menos unos 5 lenguajes distintos (HTML no es un lenguaje de programación, CSS tampoco).   Mi recomendación personal es: Java, C#, Javascript, Python, Ruby.
  • Aprendan cosas básicas de HTML y CSS. Después de que hayan estudiado, un buen ejercicio es tomar una página no demasiado sencilla e intentar recrearla.
  • Aprendan a sacar ventaja de la programación funcional, eso es algo que a los físicos y matemáticos se nos da de manera natural.


Recursos:

  1. Guía de Linux para novatos, brutos y extremadamente torpes. http://www.sistemasverschae.cl/acceso/sitio/manual%20openoffice/paratorpes.pdf No se ofendan, yo no elegí el título. Es un excelente curso, lamentablemente la versión web desapareció.
  2. http://www.coderbyte.com/ aquí hay muchos problemas sencillos.
  3. http://www.topcoder.com aquí encontrarán muchos problemas no tan sencillos.
  4. https://projecteuler.net/ aquí hay un montón de muy buenos problemas de programación para matemáticos.
  5. Libro: Programming Challenges de Steven S Skiena y Miguel A. Revilla.
  6. Libro: Cracking the Coding Interview de Gayle Laakmann McDowell. Este libro tiene muchos problemas de todos los niveles.

Existen muchos otros recursos interesantes, pero por el momento creo que no serviría de mucho apabullarles  con una lista aún más grande.

A la audiencia de fismat: Malú y Karina podrían darles algunos de los cursos enlistados o al menos recomendarles quien podría dárselos.