JavaRush /Blog Java /Random-ES /Análisis de preguntas y respuestas de entrevistas para de...

Análisis de preguntas y respuestas de entrevistas para desarrollador Java. Parte 2

Publicado en el grupo Random-ES
¡Hola de nuevo a todos! Seguimos buscando respuestas a más de 250 preguntas para desarrolladores Junior, Middle y Senior. Las preguntas son bastante interesantes y a mí mismo me gusta analizarlas: en esos momentos se pueden descubrir lagunas en el conocimiento teórico y en los lugares más inesperados. Análisis de preguntas y respuestas de entrevistas.  Parte 2 - 1La parte anterior se puede encontrar en este artículo . Pero antes de empezar quiero recordaros que:
  1. Saltaré las preguntas que se cruzan con esta serie de artículos para no duplicar información una vez más. Recomiendo leer estos materiales, ya que contienen las preguntas de entrevistas de Java Core más comunes (populares).
  2. Las preguntas sobre DOU se presentan en ucraniano, pero aquí tendré todo en ruso.
  3. Las respuestas podrían describirse con más detalle, pero no lo haré, ya que entonces la respuesta a cada pregunta podría ocupar un artículo completo. Y no te preguntarán con tanto detalle en ninguna entrevista.
Si es necesario dejaré enlaces para un estudio más profundo. ¡Volemos!

11. Nombra todos los métodos de la clase Objeto.

La clase Object tiene 11 métodos:
  • Class<?> getClass() — obtiene la clase del objeto actual;
  • int hashCode() : obtiene el código hash del objeto actual;
  • booleano es igual​(Objeto obj) - comparación del objeto actual con otro;
  • Clon de objeto() : crea y devuelve una copia del objeto actual;
  • String toString() : obtener una representación en cadena de un objeto;
  • void notify() : despierta un hilo esperando en el monitor de este objeto (la selección del hilo es aleatoria);
  • void notifyAll() - despierta todos los hilos que esperan en el monitor de este objeto;
  • void wait() : cambia el hilo actual al modo de espera (lo congela) en el monitor actual, funciona solo en un bloque sincronizado hasta que alguna notificación o notificación a todos despierta el hilo;
  • espera vacía (tiempo de espera prolongado) : también congela el hilo actual en el monitor actual (en el monitor actual sincronizado), pero con un temporizador para salir de este estado (o nuevamente: hasta que notifique o notifique a todos se despierte);
  • espera vacía(tiempo de espera prolongado, int nanos) : un método similar al descrito anteriormente, pero con temporizadores más precisos para salir de la congelación;
  • void finalize() : antes de eliminar este objeto, el recolector de basura llama a este método (finalmente). Se utiliza para limpiar los recursos ocupados.
Para utilizar correctamente los métodos hashCode , equals ​, clone , toString y finalize, se deben redefinir, teniendo en cuenta la tarea y las circunstancias actuales.

12. ¿Cuál es la diferencia entre intentar con recursos y intentar capturar finalmente cuando se trata de recursos?

Normalmente, cuando se utiliza try-catch-finally, el bloque final se utiliza para cerrar recursos. Java 7 introdujo un nuevo tipo de operador try-with-resources , un análogo de try-catch-finally para liberar recursos, pero más compacto y legible. Recordemos cómo se ve try-catch-finally :

String text = "some text......";
BufferedWriter bufferedWriter = null;
try {
   bufferedWriter = new BufferedWriter(new FileWriter("someFileName"));
   bufferedWriter.write(text); 
} catch (IOException e) {
   e.printStackTrace();
} finally {
   try {
       bufferedWriter.close();
   } catch (IOException e) {
       e.printStackTrace();
   }
}
Ahora reescribamos este código, pero usando try-with-resources :

String text = "some text......";
try(BufferedWriter bufferedWriter =new BufferedWriter(new FileWriter("someFileName"))) {
   bufferedWriter.write(text);
} catch (IOException e) {
   e.printStackTrace();
}
De alguna manera se ha vuelto más fácil, ¿no crees? Además de la simplificación, hay un par de puntos:
  1. En try-with-resources , los recursos declarados entre paréntesis (que se cerrarán) deben implementar la interfaz AutoCloseable y su único método, close() .

    El método close se ejecuta en un bloque finalmente implícito ; de lo contrario, ¿cómo entenderá el programa exactamente cómo cerrar un recurso determinado?

    Pero lo más probable es que rara vez escriba sus propias implementaciones de recursos y su método de cierre.

  2. Secuencia de ejecución del bloque:

    1. prueba bloquear .
    2. Implícito finalmente .
    3. Un bloque catch que detecta excepciones en pasos anteriores.
    4. Explícito finalmente .

    Como regla general, las excepciones que aparecen más abajo en la lista interrumpen a las que aparecen más arriba.

Imagine una situación en la que, al utilizar try-catch-finally, se produce una excepción en su intento . En consecuencia, inmediatamente comienza a ejecutarse un bloque catch específico , en el que escribe otra excepción (por ejemplo, con un mensaje que describe el error con más detalle) y desea que el método lance más esta excepción. Luego viene la ejecución del bloque finalmente , y también se lanza una excepción. Pero esto es diferente. ¿Cuál de estas dos excepciones arrojará finalmente este método? ¡Excepción lanzada por el bloque finalmente ! Pero también hay un punto con try-with-resources . Ahora veamos el comportamiento de probar con recursos en la misma situación. Obtenemos una excepción en el bloque try cuando intentamos cerrar recursos en el método close() , es decir, en el implícito finalmente . ¿ Cuál de estas excepciones se aplicará ? ¡ El que fue arrojado por el bloque try ! Se ignorará una excepción implícita finalmente (del método close() ). Esta ignorancia también se denomina supresión de excepciones.

13. ¿Qué son las operaciones bit a bit?

Las operaciones bit a bit son operaciones en cadenas de bits que incluyen operaciones lógicas y cambios bit a bit. Operaciones lógicas:
  • bit a bit AND : compara valores de bits y, en el proceso, cualquier bit establecido en 0 (falso) establece el bit correspondiente en el resultado como 0. Es decir, si en ambos valores que se comparan el bit era 1 (verdadero), el El resultado también será 1.

    Denotado como - Y , &

    Ejemplo: 10111101 y 01100111 = 00100101

  • bit a bit OR es la operación inversa de la anterior. Cualquier bit establecido en 1 establece un bit similar en el resultado como 1. Y, en consecuencia, si el bit era 0 en ambos valores comparados, el bit resultante también será 0.

    Denotado como -O , |

    Ejemplo: 10100101 | 01100011 = 11100111

  • bit a bit NO : aplicado a un valor, voltea (invierte) los bits. Es decir, aquellos bits que eran 1 pasarán a ser 0; y los que eran 0 pasarán a ser 1.

    Denotado como - NO , ~

    Ejemplo: ~10100101 = 01011010

  • OR exclusivo bit a bit : compara valores de bits, y si en ambos valores el bit es igual a 1, entonces el resultado será 0, y si en ambos valores el bit es 0, el resultado será 0. Es decir, Para que el resultado sea igual a 1, sólo uno de los bits debe ser igual a 1 y el segundo debe ser igual a 0.

    Denotado como - XOR , ^

    Ejemplo: 10100101 ^ 01100011 = 11000110

Desplazamientos bit a bit : >> o << desplazan los bits de un valor en la dirección especificada, en el número especificado. Las posiciones libres se llenan con ceros. Por ejemplo:
  1. 01100011 >> 4 = 00000110
  2. 01100011 << 3 = 00011000
También hay una excepción cuando se desplaza a la derecha un número negativo. Como recuerdas, el primer bit es responsable del signo, y si este bit es igual a 1, entonces el número es negativo. Si mueves un número negativo, las posiciones vacantes ya no se llenarán con ceros, sino con unos, ya que es necesario mantener el bit de signo. Por ejemplo: 10100010 >> 2 = 11101000 Al mismo tiempo, en Java hay un operador adicional de desplazamiento a la derecha sin firmar >>> Este operador es un análogo de >>, al cambiar, las posiciones vacantes se llenan con 0, independientemente de si el número es negativo o positivo. Por ejemplo: 10100010 >>> 2 = 00101000 Lea más sobre operaciones bit a bit aquí . Análisis de preguntas y respuestas de entrevistas.  Parte 2 - 2Como ejemplos del uso de desplazamientos bit a bit en Java, puede citar el método hash() de un HashMap, que se utiliza para determinar un código hash interno especial para una clave: Análisis de preguntas y respuestas de entrevistas.  Parte 2 - 3este método le permite distribuir uniformemente los datos en un HashMap para minimizar el número de colisiones.

14. ¿Qué clases inmutables estándar son objetos en Java?

Inmutable es un objeto que no permite cambiar sus parámetros originales. Puede tener métodos que devuelvan nuevos objetos de un tipo determinado, con parámetros que desea cambiar. Algunos objetos inmutables estándar:
  • Con diferencia, el objeto inmutable más famoso de Java es String;
  • instancias de clases contenedoras que envuelven tipos estándar: booleano, carácter, byte, corto, entero, largo, doble, flotante;
  • objetos que normalmente se utilizan para números especialmente GRANDES: BigInteger y BigDecimal;
  • un objeto que es una unidad en stacktraces (por ejemplo, en un stacktrace de excepción) StackTraceElement;
  • un objeto de la clase Archivo: puede cambiar archivos, pero al mismo tiempo es inmutable;
  • UUID: que a menudo se utiliza como identificación única para elementos;
  • todos los objetos de clase del paquete java.time;
  • Localidad: se utiliza para definir una región geográfica, política o cultural.

15. ¿Cuáles son las ventajas de un objeto inmutable sobre los objetos normales?

  1. Estos objetos son seguros cuando se utilizan en un entorno de subprocesos múltiples . Al usarlos, no tiene que preocuparse por perder datos debido a las condiciones de carrera del subproceso. A diferencia de trabajar con objetos comunes: en este caso, tendrás que pensar con mucho cuidado y desarrollar los mecanismos para usar el objeto en un entorno paralelo.
  2. Los objetos inmutables son buenas claves en un mapa, porque si usa un objeto mutable y luego el objeto cambia su estado, puede resultar confuso al usar un HashMap: el objeto seguirá presente, y si usa contieneKey() puede que no ser encontrado.
  3. Los objetos inmutables son excelentes para almacenar datos inmutables (constantes) que nunca deben cambiarse mientras se ejecuta el programa.
  4. "Atomicidad hasta el fallo": si un objeto inmutable genera una excepción, no permanecerá en un estado no deseado (roto).
  5. Estas clases son fáciles de probar.
  6. No se necesitan mecanismos adicionales como un constructor de copias y una implementación de clonación.

Preguntas sobre POO

Análisis de preguntas y respuestas de entrevistas.  Parte 2 - 4

16. ¿Cuáles son las ventajas de la programación orientada a objetos en general y en comparación con la programación procesal?

Entonces, las ventajas de la programación orientada a objetos:
  1. Las aplicaciones complejas son más fáciles de escribir que la programación procedimental, ya que todo se divide en pequeños módulos (objetos que interactúan entre sí) y, como resultado, la programación se reduce a las relaciones entre objetos.
  2. Las aplicaciones escritas con programación orientada a objetos son mucho más fáciles de modificar (siempre que se sigan los conceptos de diseño).
  3. Dado que los datos y las operaciones en él forman una sola entidad, no se difunden por toda la aplicación (lo que suele suceder con la programación de procedimientos).
  4. La encapsulación de información protege los datos más críticos del usuario.
  5. Es posible reutilizar el mismo código con datos diferentes, porque las clases le permiten crear muchos objetos, cada uno de los cuales tiene sus propios valores de atributos.
  6. La herencia y el polimorfismo también le permiten reutilizar y ampliar el código existente (en lugar de duplicar funciones similares).
  7. Ampliabilidad de la aplicación más sencilla que con un enfoque procesal.
  8. El enfoque OOP permite abstraerse de los detalles de implementación.

17. Cuéntanos qué deficiencias hay en la programación orientada a objetos

Desafortunadamente, también están presentes:
  1. La programación orientada a objetos requiere una gran cantidad de conocimientos teóricos que es necesario dominar antes de poder escribir algo.Análisis de preguntas y respuestas de entrevistas.  Parte 2 - 5
  2. Las ideas de la programación orientada a objetos no son tan fáciles de entender y aplicar en la práctica (hay que ser un poco filósofo de corazón).
  3. Cuando se utiliza programación orientada a objetos, el rendimiento del software se reduce ligeramente debido a la organización más compleja del sistema.
  4. El enfoque OOP requiere más memoria, ya que todo consta de clases, interfaces y métodos, que ocupan mucha más memoria que las variables normales.
  5. El tiempo requerido para el análisis inicial es mayor que el procesal.

18. ¿Qué es el polimorfismo estático y dinámico?

El polimorfismo permite que los objetos se comporten de manera diferente para la misma clase o interfaz. Hay dos tipos de polimorfismo, también conocidos como de unión temprana y tardía . Polimorfismo estático o unión anterior:
  • ocurre en el momento de la compilación (al principio del ciclo de vida del programa);
  • decide qué método ejecutar en tiempo de compilación;
  • La sobrecarga de métodos es un ejemplo de polimorfismo estático;
  • la vinculación anticipada incluye métodos privados, estáticos y terminales;
  • la herencia no está involucrada en la vinculación anticipada;
  • El polimorfismo estático no involucra objetos específicos, sino información sobre la clase, cuyo tipo se representa a la izquierda del nombre de la variable.
Polimorfismo dinámico o unión tardía:
  • ocurre en tiempo de ejecución (mientras el programa se está ejecutando);
  • el polimorfismo dinámico decide qué implementación específica tendrá un método en tiempo de ejecución;
  • la anulación de métodos es un ejemplo de polimorfismo dinámico;
  • el enlace tardío es la asignación de un objeto específico, una referencia de su tipo o su superclase;
  • la herencia está asociada con el polimorfismo dinámico.
Puede leer más sobre las diferencias entre vinculación anticipada y tardía en este artículo .

19. Definir el principio de abstracción en POO.

La abstracción en programación orientada a objetos es una forma de resaltar un conjunto de características significativas de un objeto, excluyendo detalles sin importancia. Es decir, al diseñar un programa con enfoque POO, te centras en los modelos en general, sin profundizar en los detalles de su implementación. En Java, las interfaces son responsables de la abstracción . Por ejemplo, tienes una máquina y esta será la interfaz. Y varias interacciones con él, por ejemplo, arrancar el motor, usar la caja de cambios, son funciones que usamos sin entrar en detalles de implementación. Después de todo, en el momento en que conduce un automóvil, no piensa en cómo exactamente la caja de cambios cumple su propósito, ni en cómo la llave arranca el motor, ni exactamente en cómo el volante hace girar las ruedas. E incluso si se reemplaza la implementación de una de estas funciones (por ejemplo, el motor), es posible que no lo note. Esto no te importa: no entras en detalles de la implementación. Es importante para usted que la acción se lleve a cabo. En realidad, esto es una abstracción de los detalles de implementación. Aquí es donde nos detendremos hoy: ¡continuará!Análisis de preguntas y respuestas de entrevistas.  Parte 2 - 6
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION