Como dicen, si no te avergüenzas de tu antiguo código, entonces no estás creciendo como programador, y estoy de acuerdo con esta opinión. Empecé a programar por diversión hace más de 40 años y profesionalmente hace 30 años, así que cometo muchos errores. mucho. Como profesor de informática, enseño a mis alumnos a aprender de los errores: los suyos, los míos y los de otros. Creo que es hora de hablar de mis errores para no perder el pudor. Espero que le sean útiles a alguien.
Tercer lugar: compilador de Microsoft C
Mi maestra de escuela creía que Romeo y Julieta no podían considerarse una tragedia porque los personajes no tenían culpa trágica: simplemente se comportaban estúpidamente, como deberían hacerlo los adolescentes. Entonces no estaba de acuerdo con él, pero ahora veo una pizca de racionalidad en su opinión, especialmente en relación con la programación.
Cuando terminé mi segundo año en el MIT, era joven e inexperto, tanto en la vida como en programación. En el verano, hice una pasantía en Microsoft, en el equipo del compilador de C. Al principio hice cosas rutinarias como soporte de creación de perfiles, y luego me confiaron trabajar en la parte más divertida del compilador (como pensaba): la optimización del backend. En particular, tuve que mejorar el código x86 para declaraciones de rama.
Decidido a escribir el código de máquina óptimo para cada caso posible, me lancé de cabeza a la piscina. Si la densidad de distribución de los valores era alta, los ingresaba en
Fue una pesadilla. Muchos años después me dijeron que el programador que heredó mi código me odiaba.
Lección aprendida
Como escriben David Patterson y John Hennessy en Computer Architecture and Computer Systems Design, uno de los principios fundamentales de la arquitectura y el diseño es, en general, hacer que las cosas funcionen lo más rápido posible.
Acelerar los casos comunes mejorará el rendimiento de manera más efectiva que optimizar los casos raros. Irónicamente, los casos comunes suelen ser más simples que los raros. Este consejo lógico supone que usted sabe qué caso se considera común, y esto sólo es posible mediante un proceso de pruebas y mediciones cuidadosas.
En mi defensa, traté de averiguar cómo se veían las declaraciones de rama en la práctica (como cuántas ramas había y cómo se distribuían las constantes), pero en 1988 esta información no estaba disponible. Sin embargo, no debería haber agregado casos especiales cuando el compilador actual no podía generar código óptimo para el ejemplo artificial que se me ocurrió.
Necesitaba llamar a un desarrollador experimentado y, junto con él, pensar en cuáles eran los casos más comunes y tratarlos específicamente. Escribiría menos código, pero eso es algo bueno. Como escribió el fundador de Stack Overflow, Jeff Atwood, el peor enemigo de un programador es el propio programador:
Sé que tienes las mejores intenciones, como todos nosotros. Creamos programas y nos encanta escribir código. Así estamos hechos. Creemos que cualquier problema se puede solucionar con cinta adhesiva, una muleta casera y una pizca de código. Por mucho que a los programadores les cueste admitirlo, el mejor código es el código que no existe. Cada nueva línea necesita depuración y soporte, es necesario comprenderla. Cuando agrega código nuevo, debe hacerlo con desgana y disgusto porque todas las demás opciones se han agotado. Muchos programadores escriben demasiado código, lo que lo convierte en nuestro enemigo.
Si hubiera escrito un código más simple que cubriera casos comunes, habría sido mucho más fácil actualizarlo si fuera necesario. Dejé atrás un desastre con el que nadie quería lidiar.
Segundo lugar: publicidad en redes sociales
Cuando trabajaba en Google en publicidad en redes sociales (¿recuerdas Myspace?), escribí algo como esto en C++:
for (int i = 0; i < user->interests->length(); i++) {
for (int j = 0; j < user->interests(i)->keywords.length(); j++) {
keywords->add(user->interests(i)->keywords(i)) {
}
}
Los programadores pueden ver inmediatamente el error: el último argumento debería ser j, no i. Las pruebas unitarias no revelaron el error, ni tampoco mi revisor. El lanzamiento se llevó a cabo y una noche mi código fue al servidor y bloqueó todas las computadoras en el centro de datos.
No pasó nada malo. A nadie le salió nada mal, porque antes del lanzamiento global el código se probó en un centro de datos. A menos que los ingenieros de SRE dejaran de jugar al billar por un tiempo y retrocedieran un poco. A la mañana siguiente recibí un correo electrónico con un volcado de memoria, corregí el código y agregué pruebas unitarias que detectarían el error. Como seguí el protocolo (de lo contrario, mi código simplemente no se ejecutaría) no hubo otros problemas.
Lección aprendida
Muchos están seguros de que un error tan grave definitivamente le costará el despido al culpable, pero no es así: en primer lugar, todos los programadores cometen errores y, en segundo lugar, rara vez cometen el mismo error dos veces.
De hecho, tengo un amigo programador que era un ingeniero brillante y fue despedido por cometer un solo error. Después de eso, fue contratado en Google (y pronto ascendido); habló honestamente sobre el error que cometió en una entrevista y no se consideró fatal.
Esto es lo que
Se anunció un pedido gubernamental por valor de aproximadamente un millón de dólares. IBM Corporation, o mejor dicho, personalmente Thomas Watson Sr., tenía muchas ganas de conseguirlo. Desafortunadamente, el representante de ventas no pudo hacerlo e IBM perdió la oferta. Al día siguiente, este empleado entró en la oficina del Sr. Watson y colocó un sobre en su escritorio. El Sr. Watson ni siquiera se molestó en mirarla: estaba esperando a un empleado y sabía que era una carta de renuncia.
Watson preguntó qué salió mal.
El representante de ventas habló en detalle sobre el avance de la licitación. Mencionó errores cometidos que podrían haberse evitado. Finalmente dijo: “Señor Watson, gracias por permitirme explicarle. Sé cuánto necesitábamos este pedido. Sé lo importante que era”, y se dispuso a partir.
Watson se acercó a él en la puerta, lo miró a los ojos y le devolvió el sobre con las palabras: “¿Cómo puedo dejarte ir? Acabo de invertir un millón de dólares en tu educación.
Tengo una camiseta que dice: “Si realmente se aprende de los errores, entonces ya soy un maestro”. De hecho, cuando se trata de errores, soy doctor en ciencias.
Primer lugar: API de App Inventor
Errores verdaderamente terribles afectan a un gran número de usuarios, se vuelven de conocimiento público, tardan mucho en corregirse y son cometidos por quienes no podrían haberlos cometido. Mi mayor error se ajusta a todos estos criterios.
Cuanto peor, mejor
Yo leo
Cómo debería ser: el diseño debe ser simple en implementación e interfaz. La simplicidad de la interfaz es más importante que la simplicidad de la implementación.
Cuanto peor, mejor: el diseño debe ser simple en implementación e interfaz. La simplicidad de la implementación es más importante que la simplicidad de la interfaz.
Olvidémonos de eso por un minuto. Desafortunadamente, lo olvidé durante muchos años.
Inventor de aplicaciones
Mientras trabajaba en Google, fui parte del equipo.
Implementamos App Inventor orientado a objetos en Java, por lo que solo hay un montón de objetos allí. Dado que las bolas y los sprites se comportan de manera muy similar, creé una clase de sprite abstracta con propiedades (campos) X, Y, Speed (velocidad) y Heading (dirección). Tenían los mismos métodos para detectar colisiones, rebotar en el borde de la pantalla, etc.
La principal diferencia entre una bola y un sprite es qué se dibuja exactamente: un círculo relleno o una trama. Dado que implementé sprites primero, era lógico especificar las coordenadas xey de la esquina superior izquierda de donde se encontraba la imagen.
Una vez que los sprites estuvieron funcionando, decidí que podía implementar objetos bola con muy poco código. El único problema fue que tomé la ruta más simple (desde el punto de vista del implementador), indicando las coordenadas xey de la esquina superior izquierda del contorno que enmarca la pelota.
De hecho, era necesario indicar las coordenadas xey del centro del círculo, como se enseña en cualquier libro de texto de matemáticas y en cualquier otra fuente que mencione círculos.
A diferencia de mis errores pasados, este afectó no sólo a mis colegas, sino también a millones de usuarios de App Inventor. Muchos de ellos eran niños o completamente nuevos en la programación. Tuvieron que realizar muchos pasos innecesarios al trabajar en cada aplicación en la que estaba presente la pelota. Si recuerdo mis otros errores con risas, este me hace sudar incluso hoy.
Finalmente solucioné este error recientemente, diez años después. “Parcheadas”, no “reparadas”, porque como dice Joshua Bloch, las API son eternas. Al no poder realizar cambios que afectarían los programas existentes, agregamos la propiedad OriginAtCenter con el valor falso en los programas antiguos y verdadero en todos los futuros. Los usuarios pueden hacer una pregunta lógica: ¿a quién se le ocurrió colocar el punto de partida en otro lugar que no fuera el centro? ¿A quien? Para un programador que era demasiado vago para crear una API normal hace diez años.
Lecciones aprendidas
Cuando trabaje en API (lo que casi todos los programadores tienen que hacer a veces), debe seguir los mejores consejos descritos en el video de Joshua Bloch "
- Una API puede traerle grandes beneficios y grandes daños.. Una buena API genera clientes habituales. El malo se convierte en tu eterna pesadilla.
- Las API públicas, como los diamantes, duran para siempre. Dalo todo: nunca habrá otra oportunidad de hacer todo bien.
- Los esquemas de API deben ser breves - una página con firmas y descripciones de clases y métodos, que no ocupa más de una línea. Esto le permitirá reestructurar fácilmente la API si no resulta perfecta la primera vez.
- Describir casos de usoantes de implementar la API o incluso trabajar en su especificación. De esta forma evitará implementar y especificar una API completamente no funcional.
Si hubiera escrito aunque fuera una breve sinopsis con un guión artificial, lo más probable es que hubiera identificado el error y lo hubiera corregido. Si no, uno de mis colegas definitivamente lo haría. Cualquier decisión que tenga consecuencias de gran alcance debe reflexionarse al menos durante un día (esto se aplica no sólo a la programación).
El título del ensayo de Richard Gabriel, "Lo peor es mejor", se refiere a la ventaja que supone ser el primero en llegar al mercado (incluso con un producto imperfecto) mientras otro pasa una eternidad persiguiendo el producto perfecto. Al reflexionar sobre el código del sprite, me doy cuenta de que ni siquiera tuve que escribir más código para hacerlo bien. Digan lo que digan, estaba tremendamente equivocado.
Conclusión
Los programadores cometen errores todos los días, ya sea escribiendo código con errores o no queriendo probar algo que mejore sus habilidades y productividad. Por supuesto, puedes ser programador sin cometer errores tan graves como yo. Pero es imposible convertirse en un buen programador sin reconocer tus errores y aprender de ellos.
Constantemente me encuentro con estudiantes que sienten que cometen demasiados errores y, por lo tanto, no están hechos para programar. Sé lo común que es el síndrome del impostor en TI. Espero que aprenda las lecciones que he enumerado, pero recuerde la principal: cada uno de nosotros comete errores: vergonzosos, divertidos y terribles. Me sorprenderé y enojaré si en el futuro no tengo suficiente material para continuar con el artículo.
Fuente: habr.com