JavaRush /Blog Java /Random-ES /Núcleo de Java. Preguntas para una entrevista, parte 3
Vadim625
Nivel 27

Núcleo de Java. Preguntas para una entrevista, parte 3

Publicado en el grupo Random-ES
En los dos artículos anteriores, analizamos algunas preguntas importantes que se formulan con mayor frecuencia en las entrevistas. Es hora de seguir adelante y mirar el resto de las preguntas.
Núcleo de Java.  Preguntas de la entrevista, parte 3 - 1

Copia profunda y copia superficial

Una copia exacta del original es su clon. En Java, esto significa poder crear un objeto con una estructura similar al objeto original. El método clone()proporciona esta funcionalidad. La copia superficial copia la menor cantidad de información posible. De forma predeterminada, la clonación en Java es superficial, es decir. Object classNo conoce la estructura de la clase que está copiando. Al clonar, la JVM hace lo siguiente:
  1. Si una clase sólo tiene miembros de tipos primitivos, se creará una copia completamente nueva del objeto y se devolverá una referencia a ese objeto.
  2. Si una clase contiene no sólo miembros de tipos primitivos, sino también miembros de cualquier otro tipo de clase, entonces se copian las referencias a objetos de estas clases. Por tanto, ambos objetos tendrán las mismas referencias.
La copia profunda lo duplica todo. La copia profunda son dos colecciones, una de las cuales duplica todos los elementos de la colección original. Queremos hacer una copia de modo que realizar cambios en cualquier elemento de la copia no afecte la colección original. La clonación profunda requiere las siguientes reglas:
  1. No es necesario copiar datos primitivos por separado;
  2. Todas las clases miembro de la clase original deben admitir la clonación. Para cada miembro de la clase, se debe llamar super.clone()cuando se anula el método clone();
  3. Si algún miembro de una clase no admite la clonación, entonces, en el método de clonación, debe crear una nueva instancia de esa clase y copiar cada uno de sus miembros con todos los atributos a un nuevo objeto de clase, uno a la vez.
Obtenga más información sobre la clonación aquí

¿Qué es la sincronización? ¿Bloqueo a nivel de objeto y bloqueo a nivel de clase?

La sincronización se refiere a subprocesos múltiples. Un bloque de código sincronizado solo puede ser ejecutado por un hilo a la vez. Java le permite procesar múltiples subprocesos simultáneamente. Esto puede resultar en que dos o más hilos quieran acceder al mismo campo. La sincronización ayuda a evitar errores de memoria que ocurren cuando los recursos de memoria se usan incorrectamente. Cuando un método se declara sincronizado, el hilo mantiene su monitor. Si otro hilo intenta acceder a un método sincronizado en este momento, el hilo se bloquea y espera a que el monitor se libere. La sincronización en Java se logra con la palabra clave sincronizada especial . Puedes marcar bloques o métodos individuales en tu clase de esta manera. La palabra clave sincronizada no se puede utilizar junto con variables o atributos de clase. El bloqueo a nivel de objeto es un mecanismo cuando desea sincronizar un método no estático o un bloque de código no estático para que solo un subproceso pueda ejecutar el bloque de código en una instancia determinada de la clase. Esto siempre debe hacerse para que el subproceso de la instancia de clase sea seguro. El bloqueo a nivel de clase evita que varios subprocesos entren en un bloque sincronizado para todas las instancias disponibles de la clase. Por ejemplo, si hay 100 instancias de la clase DemoClass, entonces solo 1 hilo podrá ejecutar demoMethod() usando una de las variables en un momento dado. Esto siempre debe hacerse para garantizar la seguridad de los hilos estáticos. Obtenga más información sobre la sincronización aquí.

¿Cuál es la diferencia entre dormir() y esperar()?

Sleep()Es un método que se utiliza para retrasar el proceso unos segundos. En el caso de wait(), el hilo está en estado de espera hasta que llamemos al método notify()o notifyAll(). La principal diferencia es que wait()libera el bloqueo del monitor mientras que sleep()no lo libera. Wait()utilizado para aplicaciones de subprocesos múltiples, sleep()utilizado simplemente para pausar la ejecución del subproceso. Thread.sleep()coloca el hilo actual en el estado "No ejecutable" durante un cierto período de tiempo. El hilo guarda el estado del monitor que estaba antes de que se llamara este método. Si otro hilo llama t.interrupt(), el hilo que "se quedó dormido" se despertará. Tenga en cuenta que este sleep()es un método estático, lo que significa que siempre afecta al hilo actual (el que ejecuta el método sleep()). Un error común es llamar t.sleep()a dónde thay otro hilo; incluso cuando el hilo actual que llamó al método sleep()no es tun hilo. Object.wait()envía el hilo actual al estado "No ejecutable" por un tiempo, al igual que sleep(), pero con algunos matices. Wait()llamado a un objeto, no a un hilo; A este objeto lo llamamos "objeto de bloqueo". Antes de llamar lock.wait(), el hilo actual debe sincronizarse con el "objeto de bloqueo"; wait()después de eso, libera este bloqueo y agrega el hilo a la "lista de espera" asociada con este bloqueo. Más tarde, otro hilo puede sincronizarse con el mismo objeto de bloqueo y llamar al archivo lock.notify(). Este método "despertará" el hilo original, que todavía está esperando. En principio, wait()/ notify()se puede comparar con sleep()/ interrupt(), solo que el subproceso activo no necesita un puntero directo al subproceso inactivo, solo necesita conocer el objeto de bloqueo compartido. Lea la diferencia detallada aquí.

¿Es posible asignar nulo a this a una variable de referencia?

No, no puedes. En Java, el lado izquierdo del operador de asignación debe ser una variable. "Esto" es una palabra clave especial que siempre proporciona la instancia actual de la clase. No es una variable cualquiera. Del mismo modo, no se puede asignar nulo a una variable utilizando la palabra clave "super" o cualquier otra palabra clave similar.

¿Cuál es la diferencia entre && y &?

&- bit a bit y &&- lógicamente.
  1. &evalúa ambos lados de la operación;
  2. &&Evalúa el lado izquierdo de la operación. De ser cierto se continúa evaluando el lado derecho.
Mire aquí para una comprensión más profunda.

¿Cómo anular los métodos equals() y hachCode()?

hashCode()y equals()los métodos se definen en la clase Object, que es la clase principal de los objetos Java. Por este motivo, todos los objetos Java heredan la implementación predeterminada de los métodos. El método hashCode()se utiliza para obtener un número entero único para un objeto determinado. Este número entero se utiliza para determinar la ubicación de un objeto cuando ese objeto necesita almacenarse, por ejemplo, en HashTable. De forma predeterminada, hashCode()devuelve integeruna representación de la dirección de la ubicación de memoria donde está almacenado el objeto. El método equls(), como su nombre indica, se utiliza simplemente para probar si dos objetos son iguales. La implementación predeterminada verifica las referencias de objetos para ver si son iguales. A continuación se presentan pautas importantes para recargar estos métodos:
  1. Utilice siempre los mismos atributos de objeto al generar hashCode()y equals();
  2. Simetría. Aquellos. xsi devuelve verdadero para algunos objetos y x.equals(y), entonces y.equals(x)debería devolver verdadero;
  3. Reflexividad. Para cualquier objeto x x.equals(x)debe devolver verdadero;
  4. Consistencia. Para cualquier objeto xy y x.equals(y)devuelve lo mismo si la información utilizada en las comparaciones no cambia;
  5. Transitividad. Para cualquier objeto x, yy z, si x.equals(y)devuelve verdadero y y.equals(z)devuelve verdadero, entonces x.equals(z)debería devolver verdadero;
  6. Siempre que se llama a un método en el mismo objeto durante la ejecución de la aplicación, debe devolver el mismo número a menos que cambie la información utilizada. hashCodepuede devolver valores diferentes para objetos idénticos en diferentes instancias de aplicación;
  7. Si dos objetos son iguales, según equals, entonces hashCodedeben devolver los mismos valores;
  8. El requisito opuesto es opcional. Dos objetos desiguales pueden devolver el mismo código hash. Sin embargo, para mejorar el rendimiento, es mejor que diferentes objetos devuelvan códigos diferentes.
Lea datos interesantes sobre estos métodos aquí.

Cuéntanos sobre los modificadores de acceso

Las clases, campos, constructores y métodos de Java pueden tener uno de cuatro modificadores de acceso diferentes: privado Si un método o variable está marcado como privado , entonces sólo el código dentro de la misma clase puede acceder a la variable o llamar al método. El código dentro de las subclases no puede acceder a una variable o método, ni puede acceder a él desde ninguna otra clase. El modificador de acceso privado se utiliza con mayor frecuencia para constructores, métodos y variables. default El modificador de acceso predeterminado se declara si el modificador no se especifica en absoluto. Este modificador significa que el acceso a los campos, constructores y métodos de una clase determinada se puede obtener mediante código dentro de la clase misma, código dentro de clases en el mismo paquete. Las subclases no pueden acceder a métodos y variables miembro de una superclase si están declaradas como predeterminadas , a menos que la subclase esté en el mismo paquete que la superclase. protected El modificador protected funciona igual que default , excepto que las subclases también pueden acceder a métodos y variables protegidos de la superclase. Esta afirmación es cierta incluso si la subclase no está en el mismo paquete que la superclase. public El modificador de acceso público significa que todo el código puede acceder a la clase, sus variables, constructores o métodos, independientemente de dónde se encuentre ese código. Núcleo de Java.  Preguntas para una entrevista, parte 3 - 2

¿Qué es un recolector de basura? ¿Podemos llamarlo?

La recolección de basura es una característica de la administración automática de memoria en muchos lenguajes de programación modernos, como Java y los lenguajes de NET.Framework. Los lenguajes que utilizan la recolección de basura a menudo interpretan la recolección de basura en una máquina virtual como la JVM. La recolección de basura tiene dos propósitos: se debe liberar la memoria no utilizada y no se debe liberar la memoria si el programa todavía la usa. ¿Puedes ejecutar la recolección de basura manualmente? No, System.gc()te brinda el mayor acceso posible. La mejor opción es llamar al método System.gc(), que le indicará al recolector de basura que debe ejecutarse. No hay forma de ejecutarlo inmediatamente ya que el recolector de basura no es determinista. Además, según la documentación, OutOfMemoryErrorno se reenviará si la máquina virtual no pudo liberar memoria después de una recolección de basura completa. Obtenga más información sobre el recolector de basura aquí.

¿Qué significa la palabra clave nativa? Explicar con detalle

La palabra clave nativa se utiliza para indicar que el método se implementa en un lenguaje de programación distinto de un archivo Java. En el pasado se han utilizado métodos nativos . En las versiones actuales de Java esto se necesita con menos frecuencia. Actualmente, se necesitan métodos nativos cuando:
  1. Debe llamar a una biblioteca desde Java que esté escrita en otro idioma.
  2. Necesita acceso a recursos del sistema o de hardware a los que solo se puede acceder mediante otro idioma (normalmente C). De hecho, muchas funciones del sistema que interactúan con la computadora real (como discos o datos de red) solo pueden llamarse mediante el método nativo.
Las desventajas de utilizar bibliotecas de métodos nativas también son importantes:
  1. JNI/JNA puede desestabilizar la JVM, especialmente si intentas hacer algo complejo. Si su método nativo hace algo mal, existe la posibilidad de que la JVM falle. Además, pueden suceder cosas malas si se llama a su método nativo desde varios subprocesos. Etcétera.
  2. Es más difícil depurar un programa con código nativo .
  3. El código nativo requiere la construcción separada de marcos, lo que puede crear problemas con la migración a otras plataformas.

¿Qué es la serialización?

En informática, en el contexto del almacenamiento y transmisión de datos, la serialización es el proceso de traducir una estructura de datos o el estado de un objeto a un formato que pueda almacenarse y luego recuperarse en otro entorno informático. Después de recibir una serie de bits, se recalculan de acuerdo con el formato de serialización y se pueden usar para crear un clon semánticamente idéntico del objeto original. Java proporciona serialización automática, que requiere que el objeto implemente la interfaz java.io.Serializable. La implementación de la interfaz marca la clase como "serializable". La interfaz java.io.Serializable no tiene métodos de serialización, pero la clase serializable puede definir opcionalmente métodos que se llamarán como parte del proceso de serialización/deserialización. Al realizar cambios en las clases, debe considerar cuáles serán y cuáles no serán compatibles con la serialización. Puedes leer las instrucciones completas aquí. Daré los puntos más importantes: Cambios incompatibles:
  1. Eliminar un campo;
  2. Mover una clase hacia arriba o hacia abajo en la jerarquía;
  3. Cambiar un campo no estático a estático o no transitorio a transitorio;
  4. Cambiar el tipo de datos primitivos declarado;
  5. Cambiando el método WriteObjectya sea ReadObjectpara que ya no escriban ni lean campos por defecto;
  6. Cambiar de clase Serializablea Externalizableo viceversa;
  7. Cambiar una clase enumerada a una no enumerada o viceversa;
  8. Eliminando Serializableo Externalizable;
  9. Agregar writeReplaceun readResolvemétodo a una clase.
Cambios compatibles:
  1. Agregar campos;
  2. Agregar/eliminar clases;
  3. Agregar métodos WriteObject/ReadObject[los métodos defaultReadObjecto defaultWriteObjectdeben llamarse al principio];
  4. Métodos de eliminación WriteObject/ReadObject;
  5. Suma java.io.Serializable;
  6. Cambiar el acceso al campo;
  7. Cambiar un campo estático a no estático o transitorio a no transitorio .
Enlaces a partes anteriores: Java Core. Preguntas de la entrevista, parte 1 Java Core. Preguntas de la entrevista, parte 2 Artículo original ¡Feliz estudio!
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION