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 6

Publicado en el grupo Random-ES
¡Hola Mundo! Continuar desarrollándose es muy importante para cualquier desarrollador. Después de todo, si se detiene, existe el riesgo de no ser reclamado y quedar completamente fuera del mercado: el mundo de las tecnologías de la información se desarrolla y avanza constantemente, y usted debe avanzar con él. Pero incluso al mismo tiempo, no es posible centrarse únicamente en las tecnologías nuevas y novedosas, para no olvidarse, por así decirlo, de los clásicos (temas clásicos). Hoy quiero continuar mi análisis de preguntas sobre temas “clásicos” para un desarrollador de Java. Análisis de preguntas y respuestas de entrevistas para desarrollador Java.  Parte 6 - 1Observo que mis respuestas no son la autoridad final; así es como veo las respuestas correctas a estas preguntas y es posible que usted no esté de acuerdo con algunas de ellas. Esto será bastante normal, así que no dudes en compartir tu opinión en los comentarios. Los enlaces a partes del análisis se encuentran al final del artículo.Análisis de preguntas y respuestas de entrevistas para desarrollador Java.  Parte 6 - 2

Bibliotecas y estándares

52. ¿Qué es Hibernar? ¿Cuál es la diferencia entre JPA e Hibernate?

Creo que para responder a esta pregunta, primero debemos entender qué es JPA . JPA es una especificación que describe el mapeo objeto-relacional de objetos Java simples y proporciona una API para almacenar, recuperar y manipular dichos objetos. Es decir, como recordamos, las bases de datos relacionales (DB) se presentan en forma de muchas tablas interconectadas. Y JPA es un estándar ampliamente aceptado que describe cómo los objetos pueden interactuar con bases de datos relacionales. Como puedes ver, JPA es algo abstracto e intangible. Es como la idea misma, el enfoque. Análisis de preguntas y respuestas de entrevistas para desarrollador Java.  Parte 6 - 3Al mismo tiempo, Hibernate es una biblioteca específica que implementa los paradigmas JPA . Es decir, con ayuda de esta biblioteca se puede trabajar con una base de datos relacional a través de objetos que representan datos de la base de datos (Entidad). Como dicen, esta biblioteca está muy cerca de los ideales de JPA y quizás por eso se ha vuelto popular. Y como comprenderá, la popularidad de su uso es un buen argumento para seguir desarrollando y mejorando. Además, detrás de su uso frecuente hay una enorme comunidad que ya ha resuelto todas las dudas posibles e imposibles relacionadas con esta herramienta. A continuación se muestra un ejemplo de un libro que examina en detalle todos los rincones oscuros de esta tecnología. Es decir, Hibernate se ha estudiado lo más posible y resulta que es confiable. En realidad, no es en vano que incluso la implementación ideal de JPA en el lado de Spring suele utilizar Hibernate bajo el capó.

53. ¿Qué es la cascada? ¿Cómo se usa en Hibernate?

Como dije anteriormente, en Hibernate la comunicación se realiza a través de objetos de datos llamados entidades . Estas entidades representan algunas tablas específicas en la base de datos y, como recordará, en Java las clases pueden contener referencias a otras clases. Estas relaciones se reflejan en la base de datos. En una base de datos, por regla general, se trata de claves externas (para OneToOne, OneToMany, ManyToOne) o tablas intermedias (para ManyToMany). Puede leer más sobre la relación entre entidades en este artículo . Cuando su entidad tiene enlaces a otras entidades relacionadas, se colocan anotaciones encima de estos enlaces para indicar el tipo de conexión: @OneToOne, @OneToMany, @ManyToOne, @ManyToMane, en cuyos parámetros puede especificar el valor de la propiedad - cascada - el tipo de cascada para esta conexión. JPA tiene métodos específicos para interactuar con entidades (persistir, guardar, fusionar...) . Los tipos en cascada se utilizan precisamente para mostrar cómo deben comportarse los datos asociados cuando se utilizan estos métodos en la entidad de destino. Entonces, ¿cuáles son las estrategias en cascada (tipos de cascada)? El estándar JPA implica el uso de seis tipos de cascada:
  • PERSIST : las operaciones de guardado se producirán en cascada (para los métodos save() y persist() ). Es decir, si guardamos una entidad asociada a otras entidades, también se guardan en la base de datos (si no están ya ahí)

  • FUSIONAR : las operaciones de actualización se producirán en cascada (para el método merge() )

  • REMOVE : las operaciones de eliminación se producen en cascada ( método remove() )

  • TODOS : contiene tres operaciones en cascada a la vez: PERSISTIR , FUSIONAR , ELIMINAR

JPA tiene el concepto de entidad persistente : una entidad asociada con sus datos en la base de datos, que está controlada por la sesión (conexión) actual . Si lo cambia, pero no guarda los cambios en la base de datos, sus datos en la base de datos aún se cambiarán.
  • DETACH : las entidades relacionadas no serán administradas por la sesión ( método detach() ). Es decir, cuando cambian, no habrá ningún cambio automático en sus datos en la base de datos: se transfieren del estado de persistencia al estado separado (una entidad no administrada por JPA).

  • ACTUALIZAR : cada vez que una entidad se actualiza con datos de la base de datos ( actualizar() : actualiza los objetos separados), las entidades relacionadas se actualizan de la misma manera. Por ejemplo, de alguna manera cambió los datos tomados de la base de datos y desea devolver sus valores originales. En este caso, esta operación te será de utilidad.

Análisis de preguntas y respuestas de entrevistas para desarrollador Java.  Parte 6 - 4Hibernate admite todas estas operaciones en cascada estándar, pero también presenta tres propias:
  • REPLICAR - Se utiliza cuando tenemos más de una fuente de datos y queremos que los datos se sincronicen (método Hibernate - replicar). Todas las entidades deben tener identificadores (id) para que no haya problemas con su generación (para que una misma entidad no tenga diferentes id para diferentes bases de datos)

  • SAVE_UPDATE : guardar/eliminar en cascada (para el método Hibernate: saveOrUpdate )

  • LOCK es la operación inversa a DETACHED : transfiere la entidad separada de nuevo al estado de persistencia , es decir. La entidad será rastreada nuevamente por la sesión actual.

Si no se selecciona el tipo de cascada, ninguna operación en una entidad tendrá efecto en otras entidades asociadas a ella.

54. ¿Puede una clase de Entidad ser abstracta?

En la especificación JPA en el párrafo 2.1 La clase de entidad hay una línea: " Tanto las clases abstractas como las concretas pueden ser entidades ". Entonces la respuesta es sí, una clase abstracta puede ser una entidad y puede anotarse con @Entity.

55. ¿Qué es un administrador de entidad? ¿De qué es responsable?

En primer lugar, me gustaría señalar que EntityManager es uno de los componentes clave de JPA , que se utiliza para interactuar entidades con la base de datos. En general, llama a los métodos de interacción entre la entidad y la base de datos (persistir, fusionar, eliminar, separar)... Pero también me gustaría señalar que este componente, por regla general, no es el único para toda la aplicación: la mayoría de las veces es liviano y a menudo se elimina y se crea uno nuevo usando EntityManagerFactory . Si trazamos un paralelo con JDBC , donde EntityManagerFactory será un análogo de DataSource , entonces EntityManager, a su vez, será un análogo de Connection . Anteriormente mencioné una entidad de persistencia , como una entidad controlada por la conexión actual. Entonces: esta entidad es administrada precisamente por el EntityManager , que está estrechamente relacionado con la conexión actual y el TransactionManager , que es responsable de abrir/cerrar transacciones. Más adelante en la figura siguiente puede ver el ciclo de vida de una entidad: Análisis de preguntas y respuestas de entrevistas para desarrollador Java.  Parte 6 - 5EntityManager administra la entidad cuando está en la etapa Administrada (en este momento es persistente, porque tiene una conexión con EntityManager). Es decir, ya no es nuevo y aún no ha sido eliminado. Podemos decir que cuando una entidad es nueva o eliminada, también está desasociada, porque no es administrado por EntityManager. Existen diferentes estrategias para EntityManager. Es decir, puede haber un EntityManager único para toda la aplicación, o se puede crear uno nuevo cada vez, para cada conexión. Si usa Spring, entonces la creación/eliminación de EntityManager se controla automáticamente (pero esto no significa que no pueda personalizarlo ^^). Vale la pena decir que uno o más EntityManagers forman el contexto de persistencia . El contexto de persistencia es un entorno en el que las instancias de entidades se sincronizan con entidades similares en la base de datos (como dije, esto solo funciona para entidades persistentes). Si profundiza en JPA (lo cual recomiendo encarecidamente), se encontrará con estos conceptos muy, muy a menudo.

56. ¿Qué es la clase Assert? ¿Por qué usarlo?

No he oído hablar de una clase de este tipo en JPA , por lo que asumiré que se refiere a la clase JUnit de la biblioteca, que se utiliza para pruebas unitarias de código. La clase de esta biblioteca, Assert , se utiliza para comprobar los resultados de la ejecución del código ( asertar es una declaración de que tienes un determinado estado/datos en un determinado lugar). Por ejemplo, estás probando un método que debería crear un gato. Ejecutas un método y obtienes algún resultado:
Cat resultOfTest = createCat();
Pero debes asegurarte de que se haya creado correctamente, ¿verdad? Por lo tanto, previamente creó un determinado gato ( esperadoCat ) manualmente con exactamente los parámetros que espera del gato obtenido del método createCat() . A continuación, utiliza la clase Assert para verificar los resultados:
Assert.assertEquals(resultOfTest, expectedCat);
Si los gatos son diferentes, se lanzará una excepción AssertionError , que nos indica que los resultados esperados no convergen. La clase Assert tiene muchos métodos diferentes que cubren muchas de las tareas de comprobar los resultados esperados. Éstos son algunos de ellos:
  • afirmarTrue(<boolean>) - el valor esperado recibido como argumento debe ser verdadero

  • afirmarFalse(<boolean>) - el valor esperado recibido como argumento debe ser falso

  • afirmarNotEquals(<objeto1>, <objeto2>) - los objetos recibidos como argumentos deben ser diferentes cuando se comparan usando iguales ( falso )

  • afirmarThrows(<ClassNameOfException>.class, <exceptionObject>) : se espera que el segundo argumento sea una excepción de la clase especificada por el primer argumento (es decir, como regla general, en lugar del segundo argumento, se llama a un método que debería lanzar una excepción del tipo requerido)

Cadena

57. Caracterizar cadenas en Java

String es una clase estándar en Java, responsable de almacenar y manipular valores de cadena (secuencias de caracteres), es una clase inmutable ( escribí sobre inmutable anteriormente ), es decir. Los datos de los objetos de esta clase no se pueden cambiar después de la creación. Me gustaría señalar de inmediato que las clases StringBuilder y StringBuffer son dos clases prácticamente idénticas con la única diferencia de que una de ellas está diseñada para usarse en un entorno multiproceso (StringBuffer). Estas clases son análogas a String , pero a diferencia de él, son mutables . Es decir, los objetos, una vez creados, permiten modificar la cadena que representan sin crear un nuevo objeto. En realidad, los métodos difieren de los métodos String estándar y están destinados a satisfacer las necesidades de cambiar la cadena (no en vano se les llama constructores). Lea más sobre String , StringBuffer y StringBuilder en este artículo .

58. ¿Cuáles son las diferentes formas de crear un objeto String? ¿Dónde se crea?

La forma más común de crear una cadena es simplemente especificar el valor que necesitamos entre corchetes dobles:
String str = "Hello World!";
También puedes hacer esto directamente a través de new :
String str = new String("Hello World!");
Puede crear una cadena a partir de una serie de caracteres:
char[] charArr = {'H','e','l','l','o',' ', 'W','o','r','l','d','!'};
String str = new String(charArr);
Como resultado de la ejecución del método toString en algún objeto:
String str = someObject.toString();
Como el resultado de cualquier otro método, devuelve una representación de cadena. Por ejemplo:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str =  reader.readLine();
Como comprenderá, puede haber muchísimos métodos para crear una cadena. Cuando se crea un objeto String , se almacena en el grupo de cadenas , del que hablaremos con más detalle en una de las preguntas siguientes.

59. ¿Cómo comparar dos cadenas en Java y cómo ordenarlas?

Para comparar valores en Java se utiliza el doble signo igual == . Si necesitáramos comparar algunos valores simples como int , lo usaríamos. Pero este método no es aplicable para comparar objetos completos. En este caso, será sólo una comparación de referencias, ya sea que apunten al mismo objeto o no. Es decir, al comparar dos objetos con exactamente los mismos valores de campos internos, la comparación mediante == dará un resultado falso : a pesar de los campos idénticos de los objetos, los objetos mismos ocupan diferentes celdas de memoria. Y los objetos de la clase String , a pesar de su engañosa simplicidad, siguen siendo objetos. Y la comparación mediante == tampoco es aplicable para ellos (incluso a pesar de la presencia de un grupo de cadenas). Aquí entra en juego el método estándar de la clase Objeto : igual , que debe anularse en la clase para que funcione correctamente (de lo contrario, de forma predeterminada compara usando == ). Está anulado en la clase String , así que simplemente lo tomamos y lo usamos:
String firstStr = "Hello World!";
String secondStr = "Hello World!";
boolean isEquals = firstStr.equals(secondStr);
Análisis de preguntas y respuestas de entrevistas para desarrollador Java.  Parte 6 - 6Hablamos de comparaciones coincidentes, ahora veamos las comparaciones de clasificación. Después de todo, para ordenar algo necesitamos saber según qué principio ordenar. Para hacer esto, puede utilizar un conjunto ordenado estándar: TreeSet . Puede leer más sobre varias colecciones en Java en este artículo . Esta lista funciona según el algoritmo del árbol rojo-negro y ordena el conjunto de acuerdo con el principio de clasificación especificado. Como dije antes, es necesario comprender cómo ordenar objetos de un determinado tipo. Los comparadores se utilizan para establecer el método de comparación para la clasificación . Normalmente, es necesario implementarlos para las clases que desea ordenar, pero en el caso de String ya están implementados. Por lo tanto, simplemente agregamos las filas que necesitamos al TreeSet y este las ordenará:
TreeSet<String> sortedSet = new TreeSet<>();
sortedSet.add("B");
sortedSet.add("C");
sortedSet.add("A");
sortedSet.forEach(System.out::println);
Salida de consola:
A B C

60. Proporcione un algoritmo para convertir una cadena en un carácter. Escribe el código apropiado

Como dije antes, los objetos de la clase String tienen muchos métodos útiles diferentes. Uno de ellos es toCharArray . Este método convierte una cadena en una matriz de caracteres:
String str = "Hello world";
char[] charArr = str.toCharArray();
A continuación tenemos una serie de caracteres que podemos llamar por índice:
char firstChar = charArr[0]; // H

61. ¿Cómo convertir una cadena en una matriz de bytes y viceversa? Escribe el código apropiado

Similar al método toCharArray , la clase String tiene un método getBytes que devuelve una matriz de bytes de la cadena:
String str = "Hello world";
byte[] byteArr = str.getBytes();
byte firstChar = byteArr[6]; // 119
La parte del análisis de hoy ha llegado a su final lógico. ¡Gracias por su atención!Análisis de preguntas y respuestas de entrevistas para desarrollador Java.  Parte 6 - 7
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION