¿Qué diferencia a un programador y a un programador realmente bueno? ¿Qué hace que el código sea bueno o malo?

Cuando codifico, codifico estúpido de la A a la Z.

Cuando alguien más lee el código, piensa: “Guau. ¡Eso es muy organizado! ”.

El truco es simple.

Imagine que tengo que crear un programa para importar algunos datos en nuestra Base de datos SQL.

Yo escribo esto:

  clase DataImporter () {
   DataImporter (receptor de DataSink) {...}
   void importData (fuente DataSource, convertidor DataConverter) arroja ImportException () {
      para (Datos de datos: fuente) {
          this.db.insert (converter.convert (data));
      }
   }
 }

Y ahora, puedo continuar y crear mi SQLDataSink, CSVDataSource e IPConverter para importar IP de un archivo CSV a una Base de Datos SQL y mi DataImporter en realidad no se preocupa por estos específicos.

  Importador de DataImporter = nuevo DataImporter (nuevo SQLDataSink (...));
 Fuente de DataSource = nuevo CSVDataSource ();
 DataSource source2 = new WSDataSource ();
 DataConverter csvConv = nuevo IPProviderCSVConverter ();
 DataConverter xmlConv = new XMLDataConverter ();
 importador.importData (fuente, csvConv);
 importador.importData (fuente, xmlConv);

Pero, de hecho, estas 7 líneas no aparecerían en mi código. Al impulsar las dependencias (inyección de dependencia / IOC), puedo crear un archivo de configuración como:

  importar:
   objetivo:
	 MySQLDataSink:
       anfitrión: ...
   fuente:
     csv: "ip.csv"
   convertidor:
     - maxMindCSV

Si me pide que lo modifique para importar IP de una imagen a través de OCR, agregaré una pequeña clase (o algunas de ellas para manejar el propio OCR, etc.) sin cambiar una línea en la base de código existente. ¿Quieres tener alguna alternativa? ¿Los han importado de una lista de archivos? No hay grandes, solo algunas clases para agregar. ¿El campo no está en el mismo lugar y no tiene el mismo formato? Agregaré un convertidor. Luego, actualizaré el archivo de configuración. Si evoluciona, crearé una interfaz para tener una vista visual del archivo de configuración.

Otra ventaja: ¡no es necesario volver a compilar si está ajustando la configuración! (De hecho, el archivo YAML simplemente describe el gráfico del objeto ^^)

Y este método tiene estas ventajas:

  • Más fácil de entender
    • Código corto
    • Problemas pospuestos para enfocarse en el asunto real (de manera recursiva)
    • Divide y vencerás de forma natural
    • Autocontenido
  • Altamente reutilizable
    • Las dependencias pueden cambiarse e intercambiarse sin buscarlas
  • Una brisa para probar
    • Las clases más pesadas son alrededor de 30 líneas. (clases en negrita ya que la gente pensará “método”)
    • Fácil de aislar una clase y proporcionarle dependencias “simuladas”. (¡EasyMock, Mockito, etc. son menos necesarios!)
  • Se presta a
    • composición
    • decoración

Y en serio, la gente se pregunta cómo sé que necesitaré X e Y. ¡No lo hago! Solo asumo que tengo todo lo que necesito donde estoy ocupado en este momento. Y hago eso por cada parte.

¡Las piezas son tan pequeñas que las pruebas unitarias son en sí mismas bastante ridículas!

Por otro lado, el desarrollador basura creará un método como:

  / ** Actualice el artículo del carrito si el usuario tiene más de 21 años, de lo contrario, redirija al aviso parental a menos que se haya establecido un indicador en "foo.properties".  Si alguno de estos falla, reenvíe a su método hermano.  * /
 void setUserProperties (forceMinorCheck, capitalizeName, validateGender, shoulderdupdateDb, extra []) {
  // Realiza llamadas a muchas partes del sistema
  // Puntos de bonificación por cada "nuevo"
  // Llamadas a métodos estáticos
  // Y el estado de conservación que obliga a la persona que llama a saber en qué orden llamar al método de la clase de propietario.
 }

Y ese método analiza (Sí, el análisis es la palabra correcta). Parámetros para saber qué hacer, mantener algún caso interno para hacer otro procesamiento cuando se llama de nuevo. Por lo general, son alrededor de 200 líneas de estructura de control altamente anidadas. Y tiene un nombre muy descriptivo.

El comentario describe ampliamente lo que el método está tratando de lograr, pero incluso no lo logra. También se refiere a cosas que no se envían, como un método hermano, ya que la clase tenía solo dos métodos y ahora es el afortunado titular de 40 de ellos (cada uno grabando en varias partes no relacionadas del sistema Y duplicando cargas de código).


FYI: Soy un ingeniero de calidad a quien se le paga para que revise el código. También hago refactores para disminuir las deudas técnicas. Describo el código tal como lo veo. ¡Ni siquiera exagerando!


Parece que malinterpreto algunos comentarios aquí. ¡Disculpas si hago lo mismo con tu!

Los expertos en acrobacia de punteros y los piratas informáticos de pueden reclamar todo lo que quieran sobre reducción de línea y compacidad, pero afirmo lo siguiente:

El “código” compilado está en binario, nadie más que un procesador necesita usar binario.

Lo bueno y lo malo no tienen impedimentos sobre cómo un procesador podría pensar sobre el “código”, funciona, funciona bien o no funciona.

El “Código” está destinado a ser leído por humanos.

Si la mayoría de la gente no puede leer y entender fácilmente su código, entonces es un código malo.

Un buen código es un código legible.

¿Qué legibilidad de ligas? El uso adecuado de lo siguiente:

  • Diseño
  • Sangría
  • Nombres de variables
  • Abstracción
  • Alcance funcional
  • Arquitectura de software / sistemas
  • Escalabilidad (por sí mismo / otros humanos)
  • Mantenibilidad (cuando las cosas se rompen, más allá de lo que pretendía)

Estos son los acentos y las anunciaciones de una comunicación adecuada.

Sinónimo de hablar en voz alta, clara, concisa y con la capacidad de transmitir ideas entre las personas.

“Código” es comunicación escrita entre humanos.

Un buen programador construye un Ferarri,

Fuente: https://media.giphy.com/media/11

Un programador realmente bueno construye un Tesla Roadster.

Fuente: https://media.giphy.com/media/xU

Ambos pueden ir muy rápido, un Tesla puede ir 0-60 en 1.9 segundos mientras que un LaFerrari puede hacerlo 2.4 segundos. Ambos se ven increíblemente geniales y se manejan bien, pero un automóvil eléctrico como el Tesla es menos complejo que el Ferrari en un orden de magnitud.

Donde el Ferrari tiene miles de pequeñas piezas pequeñas, trabajando dentro de tolerancias muy ajustadas en un ambiente altamente estresante para sacar la última onza de potencia de cada giro del motor.

El Tesla, por otro lado, es básicamente un motor eléctrico acoplado a algunas ruedas. Entonces, ¿qué tiene esto que ver con la programación?

Un buen programador puede escribir un programa que haga el trabajo como un Ferrari. Un programador realmente bueno puede escribir código que hace el trabajo en la mitad del tiempo con una complejidad considerablemente menor como un Tesla.

Verá, un código malo y desordenado aún puede producir buenos resultados. Simplemente es increíblemente complejo y difícil de entender para otros programadores. Está hinchado y puede llevar más tiempo procesar una máquina. Esto se convierte en un problema cuando alguien más viene a trabajar en ello. Tendrían que comenzar desde cero para obtener los mismos resultados.

Espero que esto ayude.

Bueno, hay algunas categorías que diferenciarán a un programador de un programador realmente bueno. Algunos de los que elegí son:

• eficiencia

Un buen programador es realmente eficiente. Siempre escribe un buen código y lo hace lo mejor posible. La eficiencia de un buen programador también se mide cuando las cosas van mal. Su capacidad para arreglar el código y hacerlo funcionar nuevamente es realmente importante en la programación. Si creas programas buenos y muy eficientes, entonces estás haciendo tu trabajo realmente bien.

• restricciones

Cada proyecto o trabajo tiene varias limitaciones. Un buen programador hace un código muy bueno en términos de complejidad de tiempo y espacio. Dado que el presupuesto es realmente importante en muchos proyectos, un buen programador creará un software con menos recursos. Un buen programador sabe cómo administrar los requisitos del proyecto y es muy flexible.

• Comprensión del código

Por lo general, los programadores trabajan en un entorno mutuo. La mayoría de ellos solo diseña una parte del código y, combinada con otras partes, crea el programa. Por lo tanto, es muy importante que el programador haga que su código sea muy comprensible, fácil y simple de leer. Debería facilitar el cambio, adaptando el código a las demandas del proyecto.

• actitud

Un buen programador tiene una muy buena actitud. Escribe cosas desde cero, contribuye al trabajo de otros, le gusta resolver un problema y les da un gran placer. Entonces, en busca del conocimiento, él mejora cada vez más en la programación. Escuela Holberton de Ingeniería de Software en San Francisco.

Es muy sencillo.

Es el estándar de trabajo que pueden crear.

No juzgamos a un constructor por lo bien que balancea un martillo, o su conocimiento de las sierras eléctricas, lo juzgan por la calidad de la producción.

¿Puede su constructor construir una buena casa? Entonces es un buen constructor.

Si puedes escribir un buen software, entonces eres un buen programador.

Tomando las respuestas aquí un poco más allá, un desarrollador generalmente no se desarrolla solo. Trabajan en un entorno colaborativo, así como en un entorno empresarial que cambia constantemente y siempre con un horario apretado.

Por lo tanto, un buen desarrollador es consciente de que cualquier código que esté escribiendo en este momento, no solo necesitará ser leído y entendido por otra persona, sino que también será modificado o refactorizado.

Buen código con el que me encuentro, lo entiendo fácilmente, la lógica es simple y clara, la implementación no es demasiado abstracta o innecesariamente compleja técnicamente.

Más importante aún, un buen código permite adiciones y mejoras sin romper todo lo demás. No es un castillo de naipes donde todos tienen miedo de tocarlo en caso de que rompa algo que no sea obvio hasta que se lance.

Los buenos desarrolladores tampoco necesariamente escriben un buen código la primera vez. Los buenos desarrolladores colaboran y piensan mucho. Escriben y eliminan y vuelven a escribir. Saben cuándo revisarlo y cuándo se requieren pruebas. También saben cuándo NO perder el tiempo de la compañía escribiendo pruebas o revisando.

Los buenos desarrolladores tampoco son buenos desarrolladores todo el tiempo. Todos se enfrentan a plazos y frustraciones y todos resbalan y cometen errores. La diferencia es que un buen desarrollador sabe cuándo ha escrito un código incorrecto. Lo anotan y vuelven más tarde. No esperan hasta que aparezca el error, saben que eventualmente aparecerá y lo cuidan, con suerte antes de que el error sea evidente.

Desafortunadamente, es por eso que un buen desarrollador es difícil de notar. Si se trata de un buen desarrollador, es como tratar con una buena silla. Solo notará la silla cuando se rompa después de sentarse en ella.

Un buen desarrollo es bueno porque funciona, obtienes lo que esperas obtener, y cuanto más fácil y rápido lo obtengas, menos notarás todo el buen trabajo que se está haciendo.

Un buen código es bueno porque puede agregarlo y cambiarlo, sin tener que notar todas las otras partes. Puede confiar en el código para hacer lo que se supone que debe hacer, y ESPECIALMENTE no hacer nada más que eso.

Para mí, hay dos tipos de programadores:

  • trabajadores del teclado, y
  • Programadores “reales” (buenos).

La primera categoría habla por sí misma, cualquiera puede aprender if () y for () y algunas funciones útiles. Saber eso puede hacer un programa, pero para mí eso no es algo especial. Esto no es “programación”, es solo conocimientos básicos de informática.

Un programador real conceptualiza el código antes de escribirlo. Y dado que un buen software necesita una estructura de datos adecuada, el programador real puede construir un modelo mental abstracto de los datos antes de escribir el código.

Y una cosa más: hay miles de “programadores” que simplemente toman una biblioteca preparada de Internet y la adaptan un poco para hacer el trabajo. Esos NO son programadores, sino trabajadores de teclados. El verdadero programador es el que desarrolla la biblioteca, que puede escribir rápidamente código personalizado para problemas personalizados.

Adaptar bibliotecas es similar a usar un cañón para matar una mosca: el trabajo está hecho, pero con un gran consumo de recursos. Por el contrario, el verdadero programador puede escribir código personalizado que hace el trabajo con un consumo mínimo de recursos.

Veo muchas respuestas complicadas o personas que defienden cómo, porque usan COI a su manera, es lo mejor.

Sus preguntas tienen una respuesta relativamente simple.

Un programador crea un sistema funcional que funciona según lo previsto. Esa es la carrera del molino.

La mayoría de las personas con las que me encuentro en tecnología no son programadores, sino personas que rellenan asientos y que alguien consiguió un trabajo pero no tienen idea de lo que están haciendo.

Ahora pasemos al siguiente paso de lo que hace que un programador sea bueno o excelente. Estos son los chicos que se dan cuenta de que hay una serie de herramientas diferentes que tienes y cada situación requiere la correcta. ¿Estás escribiendo un simple lanzamiento a la utilidad, el COI sería ridículo? ¿Su equipo está tercerizado y tiene poca habilidad? Deje de usar patrones de diseño complicados y use patrones simples y estúpidos.

Un gran desarrollador comprende si es un software que se utilizará internamente en una empresa o por los clientes. Sabe cuándo retrasar las funciones que no tienen sentido. Sabe cuándo ha terminado la ingeniería y retrocede. Deja de usar el patrón del día o la tecnología de punta y se da cuenta de que usar el probado y verdadero es más seguro para el desarrollo empresarial.

Podría continuar, pero la respuesta simple es que sabes que estás viendo un buen trabajo si son capaces de explicar el sistema, entiendes su explicación y puedes trabajar en ello. Significa que diseñaron al nivel de las habilidades de sus equipos.

He simplificado los sistemas o mejorado sus estándares de ingeniería basados ​​en los equipos que trabajarían con mi código.

Intente explicar un diseño de configuración basado en archivos altamente configurable basado en IOC en un centenar de proyectos a su equipo indio subcontratado más reciente de graduados universitarios y podría tener la idea de que es más inteligente escribir el sistema de manera un poco diferente.

¡Feliz codificación!

El código no vive aislado. Está ahí para hacer algo, para alguien, y siempre hay compromisos que hacer. Existen los compromisos técnicos: ¿necesita ser realmente rápido o realmente eficiente en memoria? Existen otros compromisos, a menudo forzados por limitaciones presupuestarias o de tiempo. Tal vez no podamos ofrecer toda la funcionalidad en esta versión: ¿qué podemos hacer ahora en un tiempo limitado, sin dejar una base para construir la próxima entrega?

Un programador realmente bueno comprende cómo hacer estos compromisos sin hacer sacrificios inaceptables por la claridad y la comprensión del código.

Un programador solo se enfoca en desarrollar la funcionalidad donde, como buen programador, ofrece funcionalidad sí, pero también pasa tiempo para asegurarse de que lo que construye sea limpio y fácil de leer, ampliable, probado en la unidad y siga los patrones de diseño del software cuando sea apropiado y use principios SOLID.

Un programador realmente bueno se asegura de no sobre diseñar y seguir principios como YAGNI, así como trabajar con otros programadores y, si es necesario, ayudarlos a escribir un buen código porque un equipo de buenos programadores, que trabajan juntos, siempre es mejor que un programador realmente bueno y un grupo de programadores promedio que no trabajan bien juntos.

Como han dicho otros, hay muchas buenas respuestas aquí. Agregaré uno general.

Un buen programador escribe código que funciona sin mucho esfuerzo, como buscar cosas en Internet.

Un programador realmente bueno optimiza el código de una manera apropiada a la necesidad y no optimiza donde no se necesita. Esto puede incluir la optimización para:

Velocidad

Requisitos de memoria

Mantenibilidad (por ejemplo, legibilidad, estándares de nombres, etc.)

Fiabilidad (por ejemplo, captura de errores)

Intento recordar que el código incorrecto no es evidencia de un mal programador. No terminas con un código bueno y limpio a menos que se alineen muchos factores, y aunque la habilidad del desarrollador es el factor más importante, definitivamente no es el único.

Dicho esto, saber cuándo ves un buen código es como saber cuándo ves una buena escritura en inglés (o en cualquier otro idioma natural). Si puedes leerlo, comprenderlo y pensar para ti mismo “eso tiene mucho sentido”, entonces es bueno. Si puede leerlo, vuelva a leerlo y aún así cree que debería tener a alguien que se lo explique, esa es una señal de que el código probablemente no esté escrito tan bien como podría estarlo.

Como se ha señalado, un buen programador es aquel que escribe un buen código. Sin embargo, lo llevaría un poco más lejos y diría que él / ella / shkli / lo que sea escribe de manera consistente y repetible un buen código. Es decir, es probable que cualquier muestra aleatoria de su código sea buena (en lugar de haber escrito algún código bueno alguna vez y todo lo demás era una mierda), y pueden hacer una predicción razonablemente precisa (por ejemplo, entre el doble y la mitad ) sobre cuánto tiempo llevará escribir código para hacer una cosa determinada (suponiendo niveles razonables de conocimiento de dominio).

Pero eso todavía deja la pregunta de qué hace que el código sea bueno o malo. Últimamente he estado reflexionando sobre eso, con la intención de agregar algunos cursos de capacitación a mis ofertas de consultoría, sobre cómo escribir software de alta calidad. Identifiqué siete aspectos clave y estoy tratando de encontrar un buen acrónimo para expresarlos. Necesito reformular algunos para que hagan algo memorable en orden de prioridad (que no es el siguiente), pero hasta ahora lo mejor que he hecho es USCREAM:

  • Usable
  • Seguro
  • Correcto
  • Robusto
  • Eficiente
  • A propósito
  • Mantenible

ACTUALIZADO PARA AGREGAR: He descubierto un acrónimo mejor, que convierte Secure en Robust, y luego los pone en orden de prioridad, apareciendo ACRUMEN. ¿Qué significan las N? No, no esa palabra n! Echa un vistazo a Lightning Talk que hice en RubyConf 2017 para obtener la respuesta. 🙂

Algunas excelentes respuestas generales ya están aquí, así que seré un poco más específico.

Capacidad para escribir código escalable, fácil de administrar y usar las herramientas adecuadas para el trabajo.

De hecho, me encontré con un gran ejemplo de esto en el trabajo hace una semana más o menos. He estado refactorizando muchas de nuestras piezas clave de software y me encontré con un fragmento de código particularmente desagradable.

Básicamente, era un controlador de vista de lo necesario para mostrar varios tipos diferentes de datos; cada uno con un formato diferente según el tipo de datos. Especificándose para el desarrollador de iOS, el ViewController original solo contenía un UIScrollView y usaba UIViews individuales rellenas allí; posicionamiento establecido por un valor Y incrementado.

¿Funcionó? Seguro. Pero agregar nuevas secciones o cambiar la funcionalidad de una sección o reordenarlas fue un gran dolor de cabeza. El código funcionó, era legible por lo que era, pero no era fácilmente escalable y no estaba usando la herramienta adecuada para el trabajo.

La herramienta correcta es una UICollectionView. Con esto, ahora puedo barajar el orden cambiando solo un par de constantes, puedo agregar fácilmente nuevas secciones para tipos de datos completamente nuevos sin acumular lo que hay actualmente, puedo construir divertidos bits de interfaz de usuario que antes habrían sido imposibles . No tengo que hacer un cálculo de posicionamiento en Y extraño porque la UICollectionView lo hace por mí.

Este UIViewController refactorizado tiene muchas más líneas de código debido a los delegados necesarios para un UICollectionView, pero lo que están haciendo todos tiene sentido. Está utilizando la herramienta adecuada para el trabajo y cualquiera que sepa cómo trabajar con un UICollectionView puede modificarlo fácilmente con un mínimo esfuerzo de mirar mi código diciendo “¿Qué estaba pensando este tipo?”

Considere el futuro y use las herramientas adecuadas, ¡eso es lo que digo!

Lo que dijo otro escritor pero todo lo contrario.

Un programador realmente bueno construye un Ferrari, alguien que se emborrachó demasiado construye un Tesla.

Un Ferrari es mantenible.

Se garantiza que un Tesla se desgastará y no se puede cambiar cuánto tiempo se necesita para mantenerlo. La grasa en los motores no se puede cambiar. Como un marco que no puedes cambiar. Si sucede algo “la grasa finalmente se secó porque está sujeta al calor”, no puede hacer nada al respecto, pero reemplace todo el motor sabiendo que lo volverá a hacer.

Usted sabe que la batería se desgastará dependiendo de cómo la use, pero todo lo que puede hacer es reemplazar la batería.

No puedes entrar y cambiar algunas partes que se desgastan aquí y allá y eso es lo que quieres.

Desea un Ferrari con un millón de piezas pequeñas que se puedan reemplazar individualmente.

Un Tesla está garantizado para volverse obsoleto.

Lo siento pero se equivocó.

No me importa tu política, es solo un ejemplo. Un automóvil eléctrico NO ES MANTENIBLE, lo venden como “SIN MANTENIMIENTO”.

QUIERES QUE TU CÓDIGO SEA MANTENIBLE.

Al igual que un Ferrari que necesita un cambio de aceite ocasional, es mejor que simplemente desgastarse un día por completo. Desea poder cambiar la transmisión para que funcione mejor para alta velocidad o aceleración.

No desea una solución única que no pueda cambiar más adelante ni mantener.

Si hay un problema de seguridad que desea poder reemplazar en un alternador individual o una bomba de combustible sin tener que cambiar su batería completa o motor con mucho más esfuerzo. Desea piezas pequeñas que pueda cambiar para actualizar y mantener su código.

No me refiero a ser un troll anónimo, pero la política de “EV vs ICE y AI vs HI” es ridícula. No me importa tu política sobre los automóviles que usamos. El punto es que desea un software que pueda cambiar con más piezas pequeñas que puede reemplazar en lugar de algunas piezas grandes que requieren mucho más esfuerzo para reemplazar un problema menor.

Una cosa que he notado que nadie menciona …

Para mí, una de las cosas principales que separa a los programadores buenos y malos es lo que hacen cuando las cosas salen mal. ¿Qué tan rápido y eficientemente una persona descubre lo que está mal y la mejor manera de solucionarlo?

Si alguien descubre constantemente los problemas y produce soluciones rápidamente que me dicen que entienden tanto el espacio del problema como el entorno en el que están trabajando.

Otro atributo que me gusta ver en los desarrolladores es cuando entienden que el problema no es suyo para solucionarlo. Por ejemplo, si tiene algún software de procesamiento de datos relacionales que se está ejecutando ridículamente lento, puede intentar aislar inmediatamente el código del problema y encontrar formas de optimizarlo, O bien, puede hablar con su DBA y ver si faltan algunos índices o consultas ineficientes de la base de datos que podrían limpiarse.

Un programador realmente bueno tendrá años de experiencia. Le gusta lo que hace, y simplemente “hace cosas” sin un objetivo claro. Él le dirá en qué está metido en este momento y entrará en gran detalle al respecto si está dispuesto a escuchar (no recomendado).

Piense en personas que no necesitan medallas para lograr cosas. Son impulsados ​​solo por la alegría de la exploración.

Diría que solo hay 2 métricas reales en las que juzgaría el código:

  1. Funciona
  2. puede documentarlo y su documento no parece estúpido o ridículo.

El resto es optimización según su caso de uso.

He seguido esta pregunta durante muchos años, pero es triste descubrir que los programadores realmente buenos como el gerente o la compañía lo ven, serán los que se besan con la administración, o los que se hacen amigos de los administradores, o los que forman un grupo de poder para que la compañía no pueda despedir fácilmente a los 8 o 12 de ellos.

La calidad del código es inversamente proporcional a la dificultad de modificarlo cuando decides que quieres cambiar ligeramente lo que hace (posiblemente años después).