
71. ¿Qué sucede si no anulamos el método toString() de Enum?
Supongamos que tenemos la siguiente enumeración :public enum Role {
STUDENT,
TEACHER,
DIRECTOR,
SECURITY_GUARD;
}
Mostremos el campo ESTUDIANTE en la consola llamando a su método toString() :
System.out.println(Role.STUDENT.toString());
Como resultado, obtenemos la siguiente salida de consola:
72. ¿Puedes declarar un constructor dentro de un Enum?
Sí, claro. El constructor es lo que establece los valores de los campos internos de la enumeración . Como ejemplo, agreguemos dos campos a la enumeración anterior ( ageFrom y ageTo ) para indicar el rango de edad para cada rol:public enum Role {
STUDENT(5,18),
TEACHER(20,60),
DIRECTOR(40,70),
SECURITY_GUARD(18,50);
int ageFrom;
int ageTo;
Role(int ageFrom, int ageTo) {
this.ageFrom = ageFrom;
this.ageTo = ageTo;
}
}
73. ¿Cuál es la diferencia entre == y es igual()?
Esta es una de las preguntas de entrevista más comunes que se hacen a los aspirantes a desarrolladores de Java. Para empezar, al comparar valores simples ( int , char , double ...), usamos == , ya que estas variables contienen valores concretos que se pueden comparar directamente. Es más, las variables primitivas no son objetos completos: no heredan la clase Object y no tienen un método equals() . Si estamos hablando de comparar variables que hacen referencia a objetos, entonces necesitamos saber que == solo compara el valor de las referencias, es decir, si se refieren al mismo objeto o no. Incluso si todos los datos de un objeto son idénticos a todos los datos de otro, usar == para una comparación producirá un resultado negativo ( falso ), porque son objetos separados. Como habrás adivinado, utilizamos el método equals() para comparar variables de referencia. Este es uno de los métodos estándar de la clase Objeto y es necesario para una comparación completa de objetos. Pero debo decir de inmediato que para que este método funcione correctamente, debe anularse para indicar exactamente cómo se deben comparar los objetos. Si no anula el método, obtendrá la implementación predeterminada, que compara los objetos usando == . En IntelliJ IDEA, puede anularlo automáticamente usando un atajo de IDEA: Alt+Insert . En la ventana que aparece, seleccione igual a() y hashCode() . Luego seleccione los campos que deberían estar involucrados. ¡Voilá! Los métodos se implementan automáticamente. A continuación se muestra un ejemplo de cómo un método de igualdad generado automáticamente busca la clase Cat más simple posible con dos campos: int age y String name :@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || this.getClass() != o.getClass()) return false;
final Cat cat = (Cat) o;
return this.age == cat.age &&
Objects.equals(this.name, cat.name);
}
Cuando se trata de enum , no existe una diferencia práctica entre == y equals() . 


74. ¿Qué hace el método ordinal() de Enum?
Cuando llamamos al método int ordinal() en un campo de enumeración , obtenemos el índice de base cero del campo en la lista de valores de enumeración. Llamemos a este método en un campo de la enumeración Rol , que consideramos anteriormente:System.out.println(Role.DIRECTOR.ordinal());
En consecuencia, la consola muestra:
75. ¿Se puede utilizar Enum con TreeSet o TreeMap en Java?
Podemos usar tipos de enumeración en TreeSet y TreeMap . Y podemos escribir esto:TreeSet<Role> treeSet = new TreeSet<>();
treeSet.add(Role.SECURITY_GUARD);
treeSet.add(Role.DIRECTOR);
treeSet.add(Role.TEACHER);
treeSet.add(Role.STUDENT);
treeSet.forEach(System.out::println);
Y la consola mostrará:
76. ¿Cómo se relacionan los métodos ordinal() y compareTo() de Enum?
Como se mencionó anteriormente, ordinal() devuelve el índice de un campo en la lista de campos de enumeración. Además, al considerar la pregunta anterior, vio que cuando los campos de enumeración se colocan en un TreeSet (que es un conjunto ordenado), adoptan el orden en que se declaran en la enumeración . Y como sabemos, TreeSet y TreeMap clasifican elementos llamando al método compareTo() de su interfaz Comparable . Esto nos dice que la clase Enum implementa la interfaz Comparable , lo que significa que implementa el método compareTo() , que utiliza internamente el método ordinal() para determinar el orden de clasificación. Al ingresar a la clase Enum , podemos confirmar nuestra suposición:


77. Escribe un ejemplo de enumeración.
En las preguntas discutidas anteriormente, ya he dado ejemplos de enumeraciones . No veo ninguna razón para duplicar el código aquí. Por ejemplo, consulte la Pregunta 72 sobre un constructor en una enumeración.78. ¿Se puede utilizar un Enum en una caja de interruptor?
¡Puede ser y debe ser! Al observar mi experiencia, señalaré que uno de los usos más comunes de enum es en construcciones lógicas como declaraciones de cambio . En este caso, puede proporcionar todos los casos posibles : una vez que escriba la lógica para cada campo de enumeración , ¡ni siquiera necesitará una cláusula predeterminada ! Después de todo, si usa String o un valor numérico, como int , puede recibir un valor inesperado, pero eso es imposible con un enum . Así es como se vería una declaración de cambio para el ejemplo anterior:public void doSomething(Role role) {
switch (role) {
case STUDENT:
// some logic for STUDENT
break;
case TEACHER:
// some logic for TEACHER
break;
case DIRECTOR:
// some logic for DIRECTOR
break;
case SECURITY_GUARD:
// some logic for SECURITY_GUARD
break;
}
}
79. ¿Cómo obtengo todos los valores posibles de un Enum?
Si necesita obtener todos los valores de enumeración posibles, existe un método de valores () , que devuelve una matriz de todos los valores posibles para la enumeración en su orden natural (es decir, en el orden en que se especifican en la enumeración ). Ejemplo:Role[] roles = Role.values();
for (Role role : roles) {
System.out.println(role);
}
Tendremos lo siguiente en la consola:
API de transmisión
80. ¿Qué es una secuencia en Java?
La API Java Stream es una forma relativamente nueva de interactuar con un flujo de datos, lo que nos permite procesar big data de manera más conveniente y compacta, así como procesar datos en paralelo entre una cierta cantidad de flujos, lo que potencialmente aumenta el rendimiento.81. Nombra las principales propiedades de las transacciones.
El tema aquí es la API Stream, pero la pregunta es sobre las transacciones. Hmm... Primero, comprendamos qué es una transacción. Una transacción es un grupo de operaciones secuenciales en una base de datos. Representa una unidad lógica de trabajo. Una transacción se puede ejecutar independientemente de otras transacciones concurrentes de forma completa y exitosa, manteniendo así la integridad de los datos, o no ejecutarse en absoluto, en cuyo caso no tiene ningún efecto. Las transacciones tienen cuatro propiedades principales, que podemos recordar fácilmente gracias al acrónimo ACID . Veamos qué significa cada letra de este acrónimo: A significa Atomicidad . Esta propiedad garantiza que ninguna transacción se confirma parcialmente en el sistema. O se ejecutarán todas sus suboperaciones o ninguna de ellas ( todo o nada ). С significa Consistencia . Esta propiedad garantiza que cada transacción exitosa solo enviará resultados válidos. En otras palabras, esto es una garantía de que si la transacción tiene éxito, se obedecerán todas las reglas del sistema para datos específicos. Si la transacción no tiene éxito, no se ejecutará y los datos del sistema volverán a su estado anterior. I significa aislamiento . Esta propiedad significa que cuando se ejecuta una transacción, las transacciones simultáneas no deben afectar su resultado. Esta propiedad consume muchos recursos, por lo que, como regla general, se implementa parcialmente, lo que permite ciertos niveles de aislamiento que resuelven problemas de aislamiento específicos. Discutiremos esto con más detalle en la siguiente pregunta. D significa Durabilidad . Esta propiedad garantiza que si el usuario recibe la confirmación de que la transacción se completó, entonces puede estar seguro de que los cambios no serán cancelados por alguna falla. Es decir, puedes estar seguro de que alguna falla del sistema operativo no afectará tus datos si ya recibiste la confirmación de que tu transacción finalizó exitosamente.82. ¿Cuáles son los niveles de aislamiento de transacciones?
Como dije antes, cuando se trata de propiedades ACID, garantizar el aislamiento es un proceso que requiere muchos recursos. En consecuencia, esta propiedad se implementa parcialmente. Existen diferentes niveles de aislamiento: cuanto mayor sea el nivel, más grave será el impacto en el rendimiento. Antes de pasar a los niveles de aislamiento de transacciones, debemos considerar varios problemas que ocurren debido a un aislamiento de transacciones insuficiente :-
lecturas fantasma : cuando la misma solicitud, llamada más de una vez dentro de una sola transacción, produce resultados diferentes debido a inserciones de otra transacción;
-
lecturas no repetibles : cuando la misma solicitud, llamada más de una vez dentro de una sola transacción, produce datos diferentes debido a cambios (actualizaciones) y eliminaciones por parte de otra transacción;
-
lecturas sucias : lectura de datos aún no confirmados que han sido agregados o modificados por una transacción y posteriormente se revierten;
-
Actualizaciones perdidas : cuando un bloque de datos es cambiado simultáneamente por diferentes transacciones y todos los cambios excepto el último se pierden (similar a una condición de carrera en subprocesos múltiples).
Nivel de aislamiento | lecturas fantasma | Lecturas no repetibles | lecturas sucias | Actualización perdida |
---|---|---|---|---|
SERIALIZABLE | + | + | + | + |
LECTURA REPETIBLE | - | + | + | + |
LEER COMPROMETIDO | - | - | + | + |
LEER SIN COMPROMISO | - | - | - | + |
NINGUNO | - | - | - | - |
83. ¿Cuál es la diferencia entre una Declaración y una Declaración Preparada?
Aquí hemos cambiado abruptamente la transición a las características de JDBC . En cualquier caso, primero averigüemos de qué se trata una Declaración . Es un objeto utilizado para formar consultas SQL. JDBC utiliza tres tipos: Declaración , PreparedStatement y CallableStatement . No consideraremos CallableStatement hoy. En cambio, estamos hablando de la diferencia entre Statement y PreparedStatement .-
La declaración se utiliza para ejecutar consultas SQL simples sin parámetros de entrada en tiempo de ejecución. PrepareStatement puede aceptar parámetros de entrada en tiempo de ejecución.
-
Para establecer parámetros para PreparedStatement , los parámetros de entrada se escriben como signos de interrogación en la solicitud, por lo que pueden reemplazarse por algún valor usando varios configuradores, como setDouble() , setFloat() , setInt() , setTime() ... Esto significa que no insertará el tipo incorrecto de datos en la solicitud.
-
PreparedStatement está precompilado y utiliza almacenamiento en caché, por lo que se puede ejecutar un poco más rápido que una solicitud realizada a partir de objetos Statement . Como resultado, las sentencias SQL que se ejecutan con frecuencia se crean como objetos PreparedStatement para mejorar el rendimiento.
-
La declaración es vulnerable a la inyección de SQL, pero PreparedStatement las previene.
GO TO FULL VERSION