in

Java más eficaz con Joshua Bloch de Google

Joshua Bloch, arquitecto jefe de Java de Google, es un ex ingeniero distinguido en Sun Microsystems, donde dirigió el diseño y la implementación de numerosas funciones de la plataforma Java, incluidas las mejoras del lenguaje JDK 5.0 y el galardonado Java Collections Framework. Tiene un doctorado. en ciencias de la computación de la Universidad Carnegie-Mellon.

Bloch ganó el prestigioso premio Jolt Award de Revista de desarrollo de software para la primera edición de su libro de 2001, Guía eficaz del lenguaje de programación Java , conocido por muchos desarrolladores como Java eficaz , y también es coautor (con Neal Gafter) del libro de gran prestigio Rompecabezas de Java.

Si hay un libro al que los desarrolladores de Java se refieren repetidamente como su favorito, es Java eficaz.

Q: En el prefacio de la nueva edición de Java eficaz , describió que se mudó a Google en 2004 y escribió: «También tuve el placer de usar la plataforma Java para desarrollar bibliotecas para su uso dentro de Google. Ahora sé lo que se siente al ser un usuario». ¿Cómo influyó su experiencia como usuario en la nueva edición del libro?

A: Bueno, por un lado, reforzó mi sensación de que es fundamental que los diseños de API sean correctos. Por ejemplo, me encontré queriendo ofrecer una alternativa FileChannel implementación para el sistema de archivos de Google, pero no pude, porque FileChannel es una clase concreta en lugar de una interfaz. Del mismo modo, quería implementar un crecimiento ByteBuffer. Este es el tipo de frustraciones que los desarrolladores normales sienten todos los días.

Q: Ha dicho que un error común entre los desarrolladores de Java es la tendencia natural a optimizar el código, lo que resulta en un código más lento que es innecesariamente complicado. ¿Por qué los desarrolladores optimizan el código por error?

«Es fácil sentir que las advertencias generales sobre la optimización prematura no se aplican a usted, porque solo sabe qué código es crítico en el tiempo y cómo hacerlo rápido. Pero nadie puede determinar esto sin medir antes y después de cada intento de optimización. . »

Joshua Bloch Autor, Java efectivo, segunda edición

A: Para ser un desarrollador de software, debe ser optimista; de lo contrario, se sentiría como una batalla perdida. Generalmente, esto es algo bueno, pero tiene una desventaja: el optimismo puede llevar a un exceso de confianza. Es fácil sentir que las advertencias generales sobre la optimización prematura no se aplican a usted, porque solo sabe qué código es crítico en el tiempo y cómo hacerlo rápido. Pero nadie puede determinar esto sin medir antes y después de cada intento de optimización.

Q: Otro error al que hace referencia es que los desarrolladores escriben su propio código cuando existen bibliotecas perfectamente buenas. ¿Por qué los desarrolladores hacen esto?

A: Dos razones: La razón más común con diferencia es que el desarrollador no sabe que existe la biblioteca. Lo siento por ese desarrollador, porque hay tantas bibliotecas por ahí que es imposible hacer un seguimiento de todas. Dicho esto, es tan difícil hacer bien algunas de estas instalaciones que vale la pena hacer el esfuerzo de averiguar si existe una biblioteca.

Esto es particularmente cierto cuando se trata de simultaneidad. No es raro que los expertos pasen literalmente meses escribiendo utilidades de concurrencia aparentemente modestas. Cuando se enfrente a la necesidad de este tipo de funcionalidad, el desarrollador inteligente hará lo que sea necesario para encontrar una biblioteca adecuada. Es muy fácil equivocarse en el código concurrente no trivial, y los errores resultantes pueden ser casi imposibles de detectar.

La segunda razón por la que los desarrolladores tienden a reinventar la rueda es la misma razón por la que tienden a optimizar prematuramente: para mantenerse cuerdos, la mayoría de los desarrolladores tienen una actitud positiva y algunos lo llevan demasiado lejos. Se dicen a sí mismos: «Sí, hay una biblioteca, pero puedo hacerlo mejor». Quizás puedas, pero eso no significa que debas hacerlo. Utilice la biblioteca estándar a menos que sea profundamente inadecuada para sus necesidades.

Ignorando bibliotecas

“Para mantenerse cuerdos, la mayoría de los desarrolladores tienen una actitud positiva y algunos lo llevan demasiado lejos. Se dicen a sí mismos: ‘Sí, hay una biblioteca, pero puedo hacerlo mejor’. Quizás puedas, pero eso no significa que debas «.

Joshua Bloch Autor, Java efectivo, segunda edición

Q: George Orwell presentó cinco reglas de buena escritura y luego agregó una sexta: «Rompe cualquiera de estas reglas antes que decir algo absolutamente bárbaro». Java eficaz ahora consta de 78 elementos con títulos que consisten en reglas cortas como «Favorecer métodos genéricos» o «Considere usar un formulario serializado personalizado», para elegir dos al azar. ¿Tienes algunas reglas favoritas? ¿Y cuándo deberían los desarrolladores romper las reglas?

Firma de Joshua Bloch Java eficaz en Jazoon

A: Primero, debo señalar que robé descaradamente la amonestación de Orwell. En la introducción a Java eficaz, dice, «No debe seguir estas reglas servilmente, sino violarlas sólo ocasionalmente y con una buena razón».

Puedo ser un poco voluble, por lo que mis reglas favoritas pueden cambiar si me preguntas otro día, pero hoy iré con el elemento 13, «Minimizar la accesibilidad de clases y miembros», y el elemento 15, «Minimizar la mutabilidad». Ambas reglas trascienden cualquier lenguaje de programación en particular.

El primero le dice que oculte la información en la mayor medida posible. Este principio, debido originalmente a David Parnas, es uno de los principios más fundamentales de una buena programación. Si oculta información, puede cambiarla sin riesgo de dañar el sistema. La ocultación de información desacopla los componentes del sistema, lo que permite que se desarrollen, prueben, optimicen, utilicen, comprendan y modifiquen de forma aislada.

El ítem 15 le dice que mantenga el espacio de estado de cada objeto lo más simple posible. Si un objeto es inmutable, puede estar en un solo estado y usted gana a lo grande. Nunca tendrá que preocuparse por el estado en el que se encuentra el objeto y puede compartirlo libremente, sin necesidad de sincronización. Si no puede hacer que un objeto sea inmutable, al menos minimice la cantidad de mutación que es posible. Esto facilita el uso correcto del objeto.

Como ejemplo extremo de lo que no se debe hacer, considérese el caso de java.util.Calendar . Muy pocas personas entienden su espacio de estado, ciertamente yo no, y ha sido una fuente constante de errores durante años.

Entonces, ¿cuándo debes romper las reglas? Parafraseando a Orwell, debería romperlos cuando resulten en un código que sea «completamente bárbaro». Como ejemplo simple, el artículo 25 dice: «Prefiero las listas a las matrices». Entonces, ¿por qué values método presente en cada tipo de enumeración devuelve una matriz? Porque el uso más común de este método es iterar sobre los elementos de su valor de retorno, y es mucho más barato iterar sobre una matriz que cualquier otra. List implementación. Con el for-each construir, el código para iterar es el mismo de cualquier manera:

for (Planet p : Planet.values())

Podría pensar que esto fue una optimización prematura por parte de los diseñadores de enumeraciones, pero no lo fue. Esto no es solo un código de bucle interno, es el (inner) loop. Por supuesto, nosotros (el JSR 201 grupo de expertos) realizó amplias mediciones de desempeño antes de tomar esta decisión, y estoy satisfecho de haber tomado la decisión correcta.

Otro momento en el que debe romper las reglas es cuando dos de las reglas lo llevarían a tomar decisiones opuestas. En tales casos, se ve obligado a violar al menos una de las reglas y debe elegir cuál es más importante, lo que puede ser muy difícil.

Cuando me enfrento a tales decisiones, normalmente lo hablo con alguien más para una revisión de cordura. No hay vergüenza en hacer esto, y podría decirse que es una mejor práctica. Contrariamente a la creencia popular, el diseño de software no es, o no debería ser, una ocupación solitaria.

Genéricos, enumeraciones y anotaciones

Q: Danos una idea de lo que crees que los desarrolladores deben saber sobre genéricos, enumeraciones y anotaciones.

A: Debido a las limitaciones de espacio, tiene que ser una pequeña muestra, pero aquí va.

En el caso de los genéricos, la frase clave es «No utilice tipos crudos» (artículo 23). Si un diseñador de bibliotecas se tomó el tiempo de escribir una biblioteca genérica, debería aprovecharla. En otras palabras, no hagas esto:

// Raw type-leads to unsafe code!
List dogs = new ArrayList();

List<Dog> dogs = new ArrayList<Dog>();

«Para los genéricos, el fragmento de sonido es ‘No use tipos crudos’. … Si un diseñador de bibliotecas se tomó el tiempo de escribir una biblioteca genérica, debería aprovecharla «.

Joshua Bloch Autor, Java efectivo, segunda edición

Al principio, esto puede parecer una palabrería innecesaria, pero no lo es. Al decirle al compilador qué tipo de elementos contiene la lista, lo habilita para encontrar muchos errores en el tiempo de compilación que de otra manera causarían una ClassCastException en tiempo de ejecución. También eliminas los moldes feos de tu programa.

Para las enumeraciones, el fragmento de sonido es «Utilice siempre enumeraciones en lugar de int constantes «(ítem 30). Las enumeraciones brindan muchas ventajas: seguridad de tipos en tiempo de compilación, la capacidad de agregar o eliminar valores sin romper clientes, valores impresos significativos, la capacidad de asociar métodos y campos con los valores, etc. tenemos EnumSet, este consejo se aplica igualmente a los campos de bits, que deben considerarse obsoletos.

Para las anotaciones, la frase clave es «No defina las suyas propias a menos que tenga una muy buena razón, pero utilice las estándar para su entorno». Para muchos programadores, los únicos que importan serán @Override (Ítem 36) y @SuppressWarnings (Ítem 24). Utilizando el @Override La anotación es una forma fácil de evitar errores que, de otro modo, serían muy difíciles de detectar. En particular, no es infrecuente sobrecargar accidentalmente el equals método cuando tiene la intención de anularlo, causando errores sutiles y perniciosos:

// Broken! Unintentional overloading
public boolean equals(MyClass other) { // MyClass should be Object.
    ...
}

Si le dice al compilador que cree que está anulando un superclass método, le informará de su error:

// @Override annotation prevents broken code from compiling.
@Override public boolean equals(MyClass mc) {
    ...
}

Prácticas recomendadas para la inicialización diferida

Q: ¿Qué es más importante comprender sobre las mejores prácticas para la inicialización diferida?

A: El consejo más importante es «No lo hagas a menos que sea necesario». El gran…

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

0zbrJo8PFqyoRgGMB

Una descripción general de la explicabilidad del modelo en el aprendizaje automático moderno

Entrada de usuario de Python