¿Cuáles son algunas técnicas “rápidas y sucias” que los principales programadores usan con frecuencia sabiendo que no deberían?

Por definición, los mejores programadores no hacen nada que no deberían. Pero justo debajo del rango superior …

Iría con campos de base de datos de tamaño fijo para cualquier dato proporcionado por el usuario y luego usaría esos datos para indexar al usuario. Eso es un problema esperando a suceder. Cada vez que le pide al usuario su nombre, su dirección o incluso su fecha de nacimiento, la respuesta puede ser más complicada de lo que ha proporcionado. Conozco a un chico con dos cumpleaños, uno oficial y uno real. Hubo un tipo cuyo nombre oficial fue “Tarquin Fin-tim-lin-bin-whin-bim-lim-bus-stop-F’tang-F’tang-Olé-Biscuitbarrel” y existen nombres extraños, como aquellos con nombres en escritura latina y apellidos en chino. Cuanto más lo investigas, más te das cuenta de que no hay reglas: todo es posible, especialmente las cosas en las que no has pensado.

No solo es posible que los datos que solicitó no encajen en el campo de base de datos que tiene disponible, sino que la respuesta puede cambiar según lo que solicite.

Nombres por ejemplo. ¿Quieres mi nombre para escribirlo por correo, para referirme a mí por mi nombre o para fines legales? ¿Quieres el nombre que uso, mi nombre legal, mi nombre en línea o mi nombre profesional (piense en autores y actores)? Incluso si la mayoría de ellos son iguales, cuando solicita el nombre completo, necesito saber si necesita mi segundo nombre, que normalmente nunca usaría, excepto para fines legales. Mi respuesta puede cambiar dependiendo de lo que percibo que estás pidiendo.

Incluso la identificación de una persona por su dirección de correo electrónico falla si un esposo y una esposa comparten la misma cuenta.

Con los datos proporcionados por el usuario no puede asumir nada. Solo almacénelo como un blob de longitud variable y verifíquelo solo citando al usuario y obteniendo confirmación. Para identificar al usuario, proporcione un índice único que usted controle: un nombre de usuario único para esa persona.

En mi humilde opinión, “piratear” o “parchar” es la peor técnica que utilizan muchos programadores. Los gerentes generalmente los presionan para que entreguen lo antes posible y, a menudo, no les importa cómo solucionaron exactamente el error o agregaron una nueva función. Para satisfacer los deseos de la gerencia, los desarrolladores tienen que trabajar rápidamente. Como resultado, a la larga, la base de código se vuelve imposible de mantener.

Es como cuando tiene un conjunto de cables bien empaquetados en una casa y desea reemplazar uno con un cable más potente o agregar un enchufe, tiene que hacer un nuevo canal de cable, perforar algunos agujeros, etc. Pero solo puede agregar Un extensor de potencia. Eso funciona a corto plazo, pero a la larga seguirás golpeando cables en el piso, sin saber a dónde va cada cable, perdiendo energía, etc. Y piensas que la aplicación de computadora es mucho más complicada que el sistema eléctrico doméstico. Sin embargo, pocas personas pueden ver lo que hay dentro de una aplicación y, si funciona, no les importa lo que hay dentro.

Cuando los ingenieros crean una nueva aplicación, generalmente diseñan una arquitectura, una especie de carcasa que mantiene diferentes módulos juntos, define interfaces para ayudar a los programadores a trabajar en diferentes partes de la aplicación de forma independiente. Además, eso garantiza la reutilización del código para que cada parte de la aplicación realice su propia tarea única. La reutilización del código es importante no solo porque ahorra tiempo, sino también porque si hay un error, se puede solucionar en un solo lugar. Cuando los requisitos cambian, a menudo necesita actualizar la arquitectura, que, como en un ejemplo anterior, requiere trabajo adicional, pero cuando los desarrolladores trabajan rápidamente comienzan a hackear: copiar y pegar código, crear parches (por ejemplo, usar RTTI en lugar de virtualización). Esto ralentiza el tiempo de compilación, hace que el código sea difícil de entender. Como resultado en aplicaciones grandes, a menudo no sabes qué parte está haciendo qué. Arreglar el error en un lugar puede introducir otro error en un lugar completamente diferente.

Lo peor es cuando la gerencia piensa: “Ahora creamos una aplicación y no necesitamos tantos desarrolladores de software. Vamos a cortarlos y concentrarnos en las ventas ”. Después de un tiempo, la aplicación queda desactualizada, necesitan agregar nuevos desarrolladores. Los nuevos tipos tienen poca comprensión de lo que los anteriores tenían en mente y comienzan a hacerlo más complicado. Luego, los gerentes entienden que hay un desastre y llaman a los que han despedido hace unos años para arreglar lo que hicieron los otros muchachos. Ese es un ejemplo de la vida real.

Cortocircuito una prueba fallida.

Omita las pruebas de escritura debido a los plazos

Siga acumulando código en una función compleja con la esperanza de que encuentren tiempo para refactorizar más tarde debido a los plazos.

Básicamente, ceder a la presión del tiempo y ejecutar cualquier codificación no higiénica. Rara vez puedes mejorarlo.

Codificación estocástica

De vez en cuando me encuentro con un problema que sé que podría resolver laboriosamente desde los primeros principios. Un ejemplo sería evitar “out-by-one” al contar a través de una matriz basada en 0 hacia atrás desde el penúltimo elemento en pasos de 2.

Como tu lo haces.

Pero solo hay un par de opciones, por lo que es más rápido adivinarlo y ejecutarlo para ver si funciona. Yo llamo a esto Codificación estocástica: arroje ideas a la pared hasta que se pegue.

Debe probarlo de todos modos (comienza y se detiene en los elementos correctos), por lo que tal vez sea más rápido “adivinar y revisar” que obtener lápiz y papel y ejecutar el algoritmo en su cabeza para hacerlo bien la primera vez.

(Este es un gran ejemplo de los beneficios de las pruebas unitarias).

Otro ejemplo es rastrear un error en un sistema complejo. ¿Debería comenzar desde el principio y avanzar, o debería saltar directamente al punto donde mi instinto me dice que mire primero?

La parte de “no debería” es ser flojo y apuñalar en la oscuridad durante demasiado tiempo y luego tener que regresar y resolverlo adecuadamente.

De hecho, esto está relacionado con algo que me sucedió tanto como una década en mi carrera de codificación. Me di cuenta de que si hago algo que actúa correctamente y parece seguro, no siempre necesito saber cómo o por qué funciona; Puedo pasar a la siguiente tarea. Por supuesto, “seguro” es un juicio de valor mejor realizado por un codificador experimentado.

Haciendo pruebas funcionales directamente.

  • Estás escribiendo una API
  • Su entrada para registrar un usuario es un controlador que simplemente llama a un servicio
  • En lugar de probar el servicio en la unidad, prueba el controlador directamente

Me permite ir más rápido y garantizar un conjunto de pruebas confiable. Cuando trabajas en una startup, no tienes tiempo para probar todo en la batalla (intercambias tiempo por ese 1% de confiabilidad faltante que no cuesta mucho).

Además, omitir las pruebas para partes de la aplicación que no son críticas (ya sea porque aún no se usan o porque realmente no son una parte importante de la experiencia del usuario).

Un buen programador sabe cuándo es seguro cortar esquinas y cuándo no.

Don Knuth dijo una vez que “la optimización prematura es la raíz de todo mal”. No pierda el tiempo tratando de eliminar microsegundos de una función que solo se llamará unos pocos millones de veces. Si algo solo se va a hacer una vez , por lo general es mejor hacerlo de una sola vez.

Poner una cadena de ayuda en un script de shell en lugar de escribir una página de manual es otro acceso directo común. (Aunque se está convirtiendo rápidamente en una práctica común).

No validando entrada. Cualquiera puede caer en esta trampa.

No verificando los códigos de retorno. La mayoría de las veces esto es un error de novato, pero a veces estás creando un código que debe usarse de manera casual. No verificar los códigos de retorno puede hacer que el trabajo vaya muy rápido.

Realmente no trabajando contingencias en una estimación. Este es un asesino.

Proporcionar estimaciones caminando hacia atrás desde una fecha de vencimiento conocida.

No proporcionar completamente una “evaluación de riesgos” adecuada al proporcionar estimaciones o trabajar con la Gestión de Proyectos.

Yo diría que es muy peligroso en c y c ++ no asignar o desasignar la memoria correctamente. Estas son áreas que pueden ser explotadas.

No lidiar con las excepciones correctamente. Es muy fácil ingresar a una zona en el camino principal (feliz) y nunca volver a las condiciones excepcionales.

Hay varias buenas respuestas aquí. Pero aquí hay uno más, insinuado en otras respuestas.

Escribir lógica de ramificación compleja y eliminar el código donde no cree que pueda ocurrir una condición. Este tipo de problema tiende a suceder a los mejores programadores con los que he trabajado porque están tan convencidos de que saben que una condición nunca puede ocurrir. Esto crea algunos de los errores más difíciles de depurar.

Cerca de esto no está el rango de verificación de referencias de matriz en idiomas que permiten que las referencias de matriz escriban fuera de la memoria para las matrices. Esta es la fuente de muchos errores oscuros y fallas de seguridad.

Pegar cuerdas juntas para hacer … bueno, casi cualquier cosa. SQL es el culpable más obvio (invitando así a los ataques de inyección SQL), pero también hay un millón de otros casos: pegar cadenas para crear XML o JSON. o para hacer “código fuente” que se ejecuta a través de un compilador / intérprete, o para hacer HTML, o expresiones regulares, o casi cualquier otra cosa.

El problema con pegar cadenas juntas es que necesitas “escapar” de caracteres especiales, y las reglas para hacerlo difieren con cada contexto, y a menudo son endiabladamente complejas, especialmente cuando diferentes contextos interactúan entre sí. Si hay una manera de hacerlo que no implique pegar cadenas juntas (parámetros SQL, un generador XML adecuado, etc.), haga eso. Se ahorrará una serie interminable de pequeños fallos cuando omita algún caso, y cada vez más feo código a medida que expande sus casos especiales para corregir cada vez más esos problemas técnicos.

“La depuración es dos veces más difícil que escribir el código en primer lugar. Por lo tanto, si escribe su código de la manera más inteligente posible, por definición no es lo suficientemente inteligente como para depurarlo ”. – Brian Kernighan

Ah, y por cierto, los mejores programadores no lo hacen rápido y sucio. Si lo hacen, no son los mejores programadores.

¡Hola!

En realidad, nunca es “seguro” hacer cosas rápidas y sucias a largo plazo. Puede estar bien para el corto / medio, pero a la larga cada “hack” te morderá eventualmente.

Vale la pena señalar que esto realmente no es una cuestión de opinión: siempre sucede al final.

En este momento, en la nueva versión del sistema en el que estoy trabajando, tenemos un par de … ejem … áreas problemáticas 😛 lo sabemos, pero esto va a sitios piloto, por lo que está bien, porque piloto.

Ya tenemos un plan para hacerlos menos frágiles. También vale la pena señalar que no son particularmente poco confiables, simplemente … eh … no están muy bien diseñados 😛

Sabemos que está bien, para un piloto, tenerlos, pero también sabemos que a largo plazo deberíamos solucionarlos. Los mejores equipos identifican esas áreas, toman una decisión y luego también se aseguran de asignar tiempo para reelaborarlas adecuadamente.

Cortar y pegar el mismo código en unas pocas docenas de lugares en lugar de convertir ese código en una clase o una función y cambiar esas pocas docenas de lugares para llamar a esa clase o función.

Hacer exactamente lo que dicen las especificaciones a pesar de que se dan cuenta de que las especificaciones causarán un problema en el futuro en lugar de plantear el problema temprano.

Sin comentar su código.

¿Por qué los mejores programadores hacen estas cosas? Porque con frecuencia se les somete a plazos arbitrarios totalmente poco realistas y son humanos.

No prueban soluciones “simples y obvias”.

Apestan a la documentación.

More Interesting

¿Qué software usan los equipos de cricket para analizar el desempeño de los otros equipos? ¿De dónde sacan los datos? ¿Cómo lo visualizan? ¿Quién desarrolla este software?

¿Por qué contratas a un desarrollador de software independiente? ¿Es solo el precio?

¿Cómo es difícil conseguir un trabajo en Finlandia en la industria del desarrollo de software si eres de un país asiático? Si tengo suficiente experiencia laboral y un título.

Al contratar, ¿cuáles son algunas técnicas creativas para evaluar a los desarrolladores de software?

¿Cómo es el mercado de ingeniería de software en Canadá?

Como desarrollador de software, ¿por qué siempre siento que, aparte del conocimiento técnico, no logro nada en mi vida?

Preguntas generales para el desarrollo de software Descubrimiento del cliente: ¿qué necesito investigar?

¿El éxito como desarrollador de software depende de un título de ingeniería?

¿Cuál es la diferencia entre un desarrollador de software que se graduó en CS y un desarrollador que aprendió la codificación a través de un campo de entrenamiento?

Como ingeniero de software o desarrollador de software, ¿es necesario / importante saber cómo realizar pruebas de software?

¿Dónde puedo calificar a los desarrolladores?

¿Cuáles son los diferentes dominios en el desarrollo de software?

Cómo adquirir experiencia de un desarrollador de software guru rápidamente

¿Cuáles son las cosas que todo desarrollador de software de fondo debe saber?

¿Cuál es un buen teclado mecánico que recomiendas para desarrolladores?