¿Qué es lo más importante que aprendió como ingeniero de software a través de la experiencia que nadie le enseñó?

Hace unos meses completé mi primer año en Enthought Scientific Computing Solutions. Antes de eso, he trabajado dos veces en Google Summer of Code para Drupal – Open Source CMS. Hay muchas cosas que aprendí mientras trabajaba en varios proyectos:

  • Las pruebas son tan importantes como escribir código.
    Las pruebas, que a menudo se tratan como un ciudadano de segunda clase del proyecto, son en realidad una parte importante del proyecto. Son de gran ayuda para verificar si el código funciona como se esperaba y que cualquier cambio particular en el código rompió una parte del código base que funcionaba previamente. También son útiles para verificar si el sistema está construido según las especificaciones de requisitos. Después de tener pocas experiencias malas y perder mucho tiempo reparando piezas que no tenían pruebas, ahora uso el desarrollo basado en pruebas para la mayoría de mis nuevos proyectos / módulos.
  • La optimización prematura es la fuente de todos los males.
    Lo más importante en la ingeniería de software es la entrega de código. Sin embargo, un código completo de trabajo es mejor que un código incompleto optimizado, asumiendo que la implementación de trabajo es utilizable hasta cierto punto. “Implementar primero, refactorizar y optimizar luego” . Esto es útil porque si ya tiene un código de trabajo, puede escribir pruebas en su contra y luego, cuando refactorice, puede ejecutar el mismo conjunto de pruebas en el código de refactorizado y verificar si está funcionando como es debido o no. También puede hacer un perfil de su código y verificar si el refactor fue útil o no.
  • El refactor es inevitable
    El encabezado lo dice todo. No importa cuánto haya pensado en el diseño o la arquitectura del nuevo proyecto / módulo, su código necesitará un refactor, simplemente son inevitables.
    Lectura adicional: Case 105 Navigation
  • Documente su código y proyecto
    Cuando trabaje en un equipo, recuerde que su código será leído, utilizado y modificado por otros miembros del equipo. Trate de mantener su código lo más legible, claro y documentado posible para que otros puedan usarlo fácilmente.

    Al desarrollar bibliotecas / APIs, construya documentación! eso facilita que otros vean su proyecto y las diversas API que expone sin pasar por el código fuente y descubrir cómo se conectan e interactúan entre sí los diferentes módulos. Agregue código de ejemplo y casos de uso común a la documentación. El uso de su biblioteca / proyecto también puede depender de qué tan bien esté documentado.

  • La depuración es una buena manera de aprender cosas nuevas.
    Aprendí muchas cosas de la depuración. Comúnmente, los errores son causados ​​porque no pensamos en ciertos casos de borde o la plataforma se comporta de una manera ligeramente diferente o el entorno tiene una configuración diferente. La depuración y el descubrimiento de dichos errores te hacen pensar en tales casos cuando escribes un tipo de código similar en el futuro y consideras esos escenarios mientras desarrollas. A veces, la depuración también puede ayudarte a darte cuenta de lo estúpido que puedes ser (a veces)

    También descubres las peculiaridades de diferentes proyectos / bibliotecas y cómo se diferencian entre sí.
    Por ejemplo, en PostgreSQL, por defecto, los valores de la columna UTF8 VARCHAR distinguen entre mayúsculas y minúsculas, pero en MySQL, los valores de la columna UTF8 VARCHAR son, por defecto, no distinguen entre mayúsculas y minúsculas, para usar valores que distingan entre mayúsculas y minúsculas, la intercalación debe ser UTF8_CS.

  • Estimación del tiempo
    Regla de ochenta y veinte: “80% del código toma 20% de tu tiempo, y el otro 20% tomará 80% de tu tiempo”.
    Lo creas o no, los desarrolladores son muy malos en la estimación del tiempo. El tiempo estimado para completar y el tiempo real tomado generalmente son muy diferentes. Personalmente cuadruplico el tiempo estimado para estimaciones pequeñas y aproximadamente el doble para estimaciones grandes. Por ejemplo, si calculo el tiempo requerido en 15 minutos, entonces citaré una hora, o si estimo en 3 días, citaré de 4 a 5 días.
  • No hay una buena arquitectura ni una mala arquitectura, todos son compensaciones
    “Diseñar para el presente con futuro en mente”.
    Resuelva los problemas inmediatos a la mano, pero tenga en cuenta los casos de uso futuros mientras los resuelve. La arquitectura de su sistema dependerá principalmente de los requisitos, pero los requisitos cambian con el tiempo, así que asegúrese de que su diseño sea flexible hasta cierto punto. Las soluciones completamente genéricas a menudo agregan complejidad al código. Así que limite la cantidad de flexibilidad y modularidad dependiendo de su experiencia y requisitos, hay muchos otros factores para esto.
  • ¡El método de resolución de problemas del oso de peluche funciona!
    Si te quedas atascado en un problema y sabes que puedes resolverlo, la solución parece esquiva. Utilice el método de resolución de problemas del oso de peluche.
    “Levante un osito de peluche y explíquele el problema al osito de peluche. 9 veces de cada 10 podrá resolver el problema”.
  • La entrega de software no es suficiente, el soporte también es importante
    Si la gente va a usar su software, tendrán problemas y tendrán preguntas. Es muy importante establecer un canal de comunicación que los usuarios puedan usar para contactarlo y hacer esas preguntas o proporcionar comentarios / sugerencias, explicar el caso de uso específico en el que podrían estar interesados. Tener una buena documentación es muy útil para reducir la sobrecarga de soporte.
  • Tomar la licencia en serio
    Al escribir un código comercial, siempre considere la licencia de las bibliotecas que está utilizando. Esto es muy importante desde el punto de vista legal. También cuando esté liberando su código, use las licencias apropiadas.
  • Todo lo que hagas se sumará a tu experiencia.
    Cada decisión incorrecta que tome, el error que cometa se agregará a su experiencia (solo trate de no repetirlos :-)) y también lo harán todas las decisiones correctas que tome. “Hagas lo que hagas, vas a aprender algo de eso :)”

Creo que he cubierto la mayoría de los puntos y seguiré actualizando esta publicación a medida que tenga tiempo.

Respuesta corta : lea los documentos / manuales y confíe en ellos más que en publicaciones de blog o tutoriales en línea.

En mis primeros días como programador autodidacta, solía encontrar más fácil aprender algo leyendo tutoriales y publicaciones de blog en lugar de los documentos oficiales. Creo que funcionó porque en esos días ..

* mi principal preocupación era hacer las cosas en lugar de hacerlo correctamente

* Lo que quería hacer era un caso muy común y muchas personas habían escrito un blog al respecto.

* en muchos casos, estas publicaciones fueron escritas por compañeros programadores novatos para que fueran más fáciles de entender como yo mismo como novato

* cuando comencé a programar (a finales de 2008), los sitios como stackoverflow ya estaban recuperándose

Sin embargo, este enfoque le fallará bastante rápido una vez que comience a realizar cualquier desarrollo de software serio. De hecho, diría que es una trampa que los novatos deberían tratar de evitar desde el principio.

Por un lado, fomenta el enfoque XY [1] y terminas perdiendo mucho tiempo en Internet buscando respuestas que de otra manera estarían mirando tu cara si hubieses leído los documentos en su lugar. Además, esta forma a menudo conduce a una solución que es innecesariamente una solución alternativa, por ejemplo. construyendo un dict de valores a partir de vars locales en python solo para pasarlo a una función cuando también habría aceptado argumentos con nombre. En este caso es bastante inofensivo pero podría ser peor.

Los documentos oficiales son el mejor lugar para visitar si desea conocer las intenciones y motivaciones de los autores detrás de la redacción del software. También proporciona información útil sobre conceptos de fondo sobre el tema. A menudo incluyen secciones de inicio rápido, casos de uso comunes y advertencias también. A veces, después de leer unas cuantas páginas, es posible que sienta que la biblioteca / el marco puede no ser el más adecuado para el problema en cuestión. Esta es la razón por la que muchos desarrolladores (incluido yo) no escriben una sola línea de código antes de que hayan leído una parte sustancial de los documentos y se sientan seguros al elegir. Una documentación deficiente podría ser un factor de ruptura razonable a menos que no haya mejores alternativas.

Por supuesto, esto no quiere decir que las publicaciones de los blogs no sean útiles en absoluto. Muchas veces llenan los vacíos y es práctico referirse a ellos de vez en cuando como material complementario, pero no son un sustituto de la documentación bien escrita. Los documentos proporcionan una imagen más grande y completa que ninguna publicación de blog puede hacer (sin dejar de ser una publicación de blog, es decir, incluso si crees que encontraste la que lo hace, es poco probable que se mantenga actualizada con el tiempo)

[1]: Página en wooledge.org

  1. Necesitas un fuerte Google-fu. La mayor parte de la programación principal consiste en googlear y cortar y pegar.
  2. Simplemente hazlo. Es mejor escribir código después de una planificación mínima y reescribir iterativamente en comparación con pasar meses planificando y escribiendo meticulosamente una vez. Siempre encontrará problemas que no se explicaron a pesar de la planificación meticulosa y tendrá que volver a escribir de todos modos.
  3. Prueba a medida que avanzas. No hay nada peor que escribir todo el programa antes de probar y descubrir que necesita volver a escribir partes importantes de su código. Además, las pruebas de caja negra a nivel de sistema casi nunca harán hincapié en ciertos problemas que se muestran fácilmente a través de pruebas de unidad.

Que los programas tienen al menos dos cosas en común con los niños:

  1. Crearlos es fácil y divertido.
  2. Es muy difícil orientar su desarrollo en una buena dirección desde el momento en que enfrentan los problemas de un mundo exterior.

Sin duda, varias personas intentaron enseñarme esto, pero no estoy seguro de si su gravedad puede comunicarse correctamente hasta que te mira a la cara. Al menos no entendí solo por haberme dicho.

Alguien más, algún día, tendrá que leer su código y trabajar en ello.

En la universidad, se nos enseña cómo optimizar algoritmos, cómo nombrar tipos de datos y patrones de diseño, y todo tipo de cosas similares y abstractas que no son tan relevantes para el mundo real. Lo que no le dicen que un solo método con un nombre engañoso puede llevar a horas y horas de tiempo perdido por un desarrollador que no sea usted . El código legible es el mayor contribuyente a la productividad del equipo técnico, ya que le permite redistribuir sus recursos de acuerdo con quién está disponible, no quién ya entiende los secretos de ese fragmento de código en particular.

Si tuviera que elegir una segunda cosa, sería cómo comunicarme con personas que no son ingenieros de software . Prometo que su carrera será mucho mejor si se le conoce como alguien que puede comunicarse con el “lado comercial” y que puede hablar sobre cómo su código se relaciona con los objetivos más amplios de la empresa / organización. Estas son las personas que se promocionan, ya sea para ser un administrador o un arquitecto, porque no se atascan en el mundo cerrado de los algoritmos, sino que unen el mundo del software y el mundo “real”, que es de donde proviene el dinero. .

  • Problemas como la corrupción de la memoria, el doble libre, las condiciones de carrera, etc. son pesadillas, especialmente en grandes bases de código. Siempre es mejor asignar más tiempo para probar esto por separado.
  • Todos quieren desarrollar una característica, pero muy pocos de ellos están dispuestos a depurar un problema relacionado con eso. No hace falta decir que es una de las habilidades importantes para desarrollar.
  • Implementar (codificar) soluciones complejas en un código simple es un arte que lo hace diferente.
  • Lea los artículos de investigación si realmente aspira a producir buenas ideas y sea capaz de evaluar sus propias ideas.
  • Si una tarea demora más de 40 segundos de su tiempo, automatícela. Tu tiempo importa, tu productividad también.
  • Mientras se trabaja en grandes bases de código, no romper las cosas existentes es mucho más importante que agregar una cosa nueva.
  • Entregar calidad es mucho más importante que entregar cantidad (características). Todos lo saben pero no todos lo siguen.
  • Diga sí para un proyecto desafiante, incluso si no está completamente preparado para ello. Pero una vez que te hayas comprometido, aprende lo más posible y complétalo con éxito. Así es como aseguras tu crecimiento acelerado.
  • Antes de cometer ciegamente los cambios de código sugeridos por otra persona, haga su propia diligencia debida al sopesar todos los escenarios relacionados con los cambios sugeridos. No importa si el código fue sugerido por un ingeniero principal o un ingeniero distinguido. Los seres humanos pueden cometer errores y usted puede asegurarse de que no suceda.
  • Un código incorrecto no se puede corregir simplemente agregando comentarios. Además, un buen código sin comentarios y documentación es tan bueno como el código malo con comentarios.
  • Los comentarios de un programador mediocre hablan más que su código. Debería ser al revés.
  • Un prototipo funcional tiene más peso que la excelente idea en papel / PPT.
  • La segunda cosa más importante para implementar sistemas escalables, centrados en el rendimiento y críticos en el tiempo es la elección de las estructuras de datos y los algoritmos después de la elección de la arquitectura / diseño del sistema y antes de la elección de la tecnología.
  • Nunca dude en optimizar, modificar o refactorizar el código antiguo / legado / torpe existente. Además, nunca elimine o cambie una sola línea de código sin comprender completamente el propósito de su existencia.
  • Una función que implique cambios mínimos en el código puede ser muy útil para un cliente / usuario, y una función que involucre una cantidad significativa de cambios en el código puede ser trivial para un cliente / usuario. Trabaja más en aquellos en los que estás aprendiendo significativamente.
  • Nadie puede hacer la estimación del tiempo de codificación mejor que tú. Entonces, cuando se le pida que proporcione un presupuesto, haga su propia diligencia debida antes de comprometerse con cualquier fecha límite. Siempre ten un poco de amortiguador.
  • Cuando elija o se le solicite trabajar en un nuevo producto / proyecto, evalúe si las tecnologías involucradas son útiles fuera de su organización. No te limites a las tecnologías específicas de tu organización.

– La mayoría de los programas se usarán por mucho más tiempo (¡a menudo años!) Y para muchas más cosas de las que se anticiparon (a menudo en entornos de producción “críticos”), incluso “hacks rápidos” que estaban destinados a usarse una vez y para resolver un problema muy específico. tarea. Personalmente creo que esto es bastante fascinante y realmente no creo que necesites nada “al respecto” aparte de intentar escribir código legible

– Independientemente de la minuciosidad que tenga cuando escriba su código e independientemente de cuánta validación de entrada agregue a un programa, método, etc., siempre habrá al menos una cosa en la que no haya pensado. La mejor manera de encontrar esas cosas en mi experiencia es permitir que tantas personas como sea posible utilicen el programa para tantas cosas diferentes como sea posible.

– La mayoría de los errores, problemas, o lo que sea que los llames 🙂 son mucho más simples de lo que crees y aún después de muchos años de desarrollo de software, empiezo a buscar en el extremo equivocado, pensando que el problema es mucho más complicado de lo que es.

Anécdota: una vez iba a mostrar una aplicación a un cliente junto con un colega, en la oficina del cliente. Tuvimos todo tipo de problemas extraños al configurar la demo y pronto, mi colega y yo investigamos los informes de estado, etc. ¡Incluso uno de los desarrolladores del cliente se unió a nosotros para tratar de ayudarnos!

Pronto nos dimos por vencidos y pedimos ayuda al administrador de sistemas del cliente. Lo primero (!) Que comprobó fue la conexión de la red y, por supuesto, el enlace en el conector de Ethernet estaba oscuro, ¡no hay conexión de red! 🙂 Arregló algo con el interruptor, y pronto todo funcionó a la perfección.

Hay sabiduría en la muy frustrante pregunta de soporte de TI: “¿Ha conectado el cable de alimentación a su computadora?”

Solución: aprenda, o debería decir, esforzarse, para comenzar siempre a mirar las cosas más simples cuando algo que solía funcionar bien de repente deja de funcionar.

Siempre, siempre implemente desde la prueba a un entorno de control de calidad.
Tenga los métodos adecuados para adaptar su entorno de producción a control de calidad, datos y software.
Aprenda todos los métodos que existen para depurar el entorno con el que está trabajando (nunca “olvide” incluir el registro).
Asegúrese de que puede depurar correctamente en su entorno de control de calidad (donde tendrá los datos reales ), no solo en su sistema de desarrollo.
Asegúrese de que puede “cambiar” su entorno de producción para iniciar un registro más intensivo cuando encuentre un problema que solo ocurre en la producción.

Una media hora de prueba puede descubrir más errores que un día dedicado a revisar el código.

Esta es mi opinión personal puramente por experiencia. Esto es especialmente cierto para las correcciones de errores. La parte del código puede interactuar con algún otro fragmento de código que la mayoría de las personas ni siquiera conocen. Todos están contentos con tu cambio, hasta que descubres más tarde que tu cambio rompe el código en el 90% de los escenarios.

Algunos se enseñan, pero la experiencia me enseñó más que eso.

  • Construye y libera tu código diariamente.
  • Divida los requisitos de funciones en las tareas de implementación más pequeñas.
  • La tarea más grande no debería tomar más de un día. Si lo hace, debería romperse más.
  • La característica más importante no debe tomar más de una semana. Si lo hace se rompe en más trozos de características.
  • Como dijo Ankur Jain KISS (hazlo estúpidamente simple). Debe ser a prueba de idiotas en el sentido de que un idiota también puede usar su software sin ningún esfuerzo.

Haz muchas preguntas. Todos piensan que entienden lo que se necesita, pero a menudo las preguntas más superficiales muestran que nadie entiende o que muchas personas tienen diferentes entendimientos.

Cuando todo el mundo parece estar de acuerdo y no está seguro de algo, pregunte al respecto. Un montón de otras personas agradecerán que hayas hecho la pregunta que fueron demasiado tímidos para preguntar.

Al final de una reunión, pídale a alguien que resuma las decisiones o hágalo usted mismo. Prepárese para que las personas tengan diferentes ideas sobre lo que se decidió. Repetir.

Mucha gente piensa que una parte necesaria del desarrollo de software es trabajar horas tontas para cumplir con los compromisos que los que trabajan horas probablemente no tienen nada que ver con hacer. No hagas eso Este proyecto pasará. La compañía será un recuerdo lejano. Pero tu salud y tu familia y otras cosas que haces son tuyas para que las guardes (o no). No hay nada especial en el software que no tenga este mito.

Si no lo has probado, no funciona.

En comparación con la informática, las epifanías en la ingeniería de software son raras. La mayoría de los problemas de ingeniería de software no requieren un poco de lógica intrincada y diabólicamente inteligente, sino que requieren una aplicación directa de capas de abstracción.

De hecho, en retrospectiva, la mayoría de las soluciones a los problemas de ingeniería de software del día a día que aparecen son banales y cegadores, como si ningún otro método fuera concebible.

Hay muchas más herramientas por ahí. Cada herramienta le facilita adaptarse a un dominio de problema particular. Esto es probable porque la educación formal y los campos de entrenamiento corporativos se centran en solo un puñado de herramientas específicas seleccionadas por esas entidades.

Cómo depurar.
Cómo escribir código que sea robusto para una amplia gama de escenarios y que esté desacoplado para que el cambio en una función no necesite cambios en todas partes.
Control de versiones.
Cómo leer el código de otros.
Importancia de la optimización de código para datos a gran escala.

1. Siempre hay una solución a tu problema.
2. Su aplicación siempre tiene margen de mejora. Necesitas decidir cuándo parar

La cosa más importante de la que aprendí (que mi jefe todavía dice):

Todo lo que se necesita para crear un software maravilloso es una mente curiosa y un compilador.

Lo más importante que he aprendido y que siempre me recuerdo es el principio KISS (Keep.It.Simple.Stupid).

Siempre una vez “Limpio”, vuelva a compilar su proyecto antes de comenzar a depurar errores inútiles -_-

Escribir código y escribir buen código son dos cosas diferentes.

Por “bueno”, me refiero a escribir código que sea legible, mantenible y extensible sin comprometer el rendimiento / eficiencia.