CodeGym /Blog Java /Random-ES /Explorando preguntas y respuestas de una entrevista de tr...
John Squirrels
Nivel 41
San Francisco

Explorando preguntas y respuestas de una entrevista de trabajo para un puesto de desarrollador de Java. parte 3

Publicado en el grupo Random-ES
¡Hola! Así como es imposible aprender a pilotar un avión sin una formación especial, no puedes convertirte en desarrollador de Java sin pasar largas horas estudiando los fundamentos teóricos necesarios. Y eso es precisamente en lo que trabajaremos hoy: continuaremos explorando las preguntas que surjan durante las entrevistas de trabajo para desarrolladores de Java y, por supuesto, veremos las respuestas. Aquí están la primera y segunda parte de esta descripción general. No hay duda de que puedes convertirte en un buen desarrollador de Java sin todas estas preguntas. Dicho esto, si comprende bien todas las complejidades de Java, definitivamente tendrá una ventaja y resultará más atractivo a los ojos de su futuro empleador. Explorando preguntas y respuestas de una entrevista de trabajo para un puesto de desarrollador de Java.  Parte 3 - 1

20. ¿Qué elementos del lenguaje permiten la encapsulación?

Recordemos que la encapsulación consiste en ocultar los detalles de implementación de una clase. En otras palabras, cuando se utiliza nuestra clase, sus entrañas y su lógica interna no son obvias para los de afuera. ¿Y qué elementos del lenguaje son responsables de esto? Modificadores de acceso , ¡por supuesto! Todo lo que necesitemos ocultar lo marcamos con el modificador privado . Por ejemplo, los campos privados de una clase o algunos métodos internos que ayudan a implementar alguna funcionalidad interna. Y para cualquier cosa a la que queramos brindar acceso externo, agregamos el modificador de acceso público . Por ejemplo, un método que implementa alguna funcionalidad (que puede usar internamente muchos métodos privados) o, por supuesto, captadores y definidores para acceder a los campos privados de una clase. Aún no hemos mencionado los modificadores predeterminados y protegidos , que se pueden usar de manera más flexible y personalizar específicamente el acceso a ciertas partes de la clase.

21. ¿Qué elementos del lenguaje permiten la herencia?

La herencia es un mecanismo que le permite crear clases basadas en otra clase. Java tiene la palabra clave extends para esto. Por ejemplo, supongamos que tenemos una clase Cat y queremos crear una clase secundaria Lion . En código, se verá así:
public class Lion extends Cat
Y esto significa que la clase Lion hereda todos los métodos y variables de la clase Cat , excepto las variables estáticas. Otro elemento del lenguaje responsable de la herencia es super . Es una referencia similar a esta . La palabra clave this se refiere al objeto al que se hace referencia. La super palabra clave se refiere al padre del objeto actual. Normalmente se utiliza super :
  1. Llamar al constructor de una superclase. Por ejemplo, la clase Cat tiene una variable de nombre interna que debe inicializarse en el constructor. En el constructor de la clase Lion , se verá así:

    public Lion(final String name) {
       super(name);
    }

  2. Para hacer referencia a los campos y métodos del padre. Por ejemplo, en la clase Cat , tenemos un campo de edad inicializado:

    public class Cat {
       int age = 10;

Pero tenemos el mismo campo inicializado en Lion :
public class Lion extends Cat {
   int age = 15;
Y si en un objeto Lion queremos hacer referencia a la variable edad del objeto padre, entonces tenemos que hacerlo a través de super :
super.name

22. ¿Qué elementos del lenguaje son responsables del polimorfismo?

El polimorfismo es la capacidad de un objeto con una firma de adoptar muchas formas (muchas implementaciones). Explorando preguntas y respuestas de una entrevista de trabajo para un puesto de desarrollador de Java.  Parte 3 - 2Podemos afirmar con confianza que las palabras clave implementa y extiende de Java son responsables del polimorfismo. Cuando tenemos una interfaz, los implementos nos permiten proporcionar una posible implementación, pero esa no tiene por qué ser la única implementación, ¿verdad? Repasemos cómo se usa el implemento :
public class Cat implements Animal
Luego, en la clase Cat , tenemos que implementar todos los métodos abstractos en la interfaz Animal . Herencia también: en la clase secundaria, podemos anular la implementación existente de un método. Esto significa que con varias clases secundarias, podemos tener varias anulaciones diferentes del mismo método. O una superclase puede ser abstracta y tener un método determinado que debe implementarse de manera especial en cada una de sus clases hijas. En otras palabras, este método tendrá muchas implementaciones diferentes. La anotación @Override también puede ayudarnos con esto. Se coloca encima de los métodos implementados e indica que queremos implementar o anular (si ya existe una implementación en la superclase) un método particular de una superclase o interfaz. Es opcional y ayuda a detectar errores más fácilmente. Utilice esta anotación para indicarle al compilador que desea anular/implementar el método de superclase/interfaz. Luego, el compilador se asegurará de que no cometa errores en la firma del método.

23. ¿Qué es SÓLIDO? Proporcionar ejemplos

SOLID es un acrónimo de los cinco principios básicos de diseño de programación orientada a objetos de Robert Martin. S (principio de responsabilidad única) : establece que una clase debe tener un solo propósito/responsabilidad. En otras palabras, no deberías crear clases que hagan de todo. Si lo hace, puede reproducir el antipatrón "Objeto Dios". Si tiene un objeto Cat , debería tener métodos solo para interactuar con su funcionalidad interna, pero no debería contener ninguna lógica empresarial no relacionada con esa instancia. Por ejemplo, algún mecanismo para almacenar objetos de este tipo. Esta funcionalidad (externa a la entidad de un Cat ) debe trasladarse a otras clases o servicios, cuya tarea es proporcionar la lógica de negocios para los objetos correspondientes. O (principio abierto-cerrado) : este principio se describe a continuación: las entidades de software (clases, módulos, funciones, etc.) deben estar abiertas a la extensión pero cerradas a la modificación. Por ejemplo, supongamos que necesitamos una funcionalidad similar pero ligeramente diferente a la funcionalidad de nuestra clase Cat existente . En lugar de cambiar la funcionalidad de la clase Cat y, por lo tanto, romper el código en todos los lugares donde ya se usa, podemos usar herencia o composición . Así logramos nuestro objetivo de modificar la funcionalidad de la clase Cat , y lo hacemos sin cambiar la clase en sí y sin romper nada. L (Principio de sustitución de Liskov) : este es el principio de sustitución de Barbara Liskov. El principio dice que una función que toma un tipo base debería poder usar subtipos de ese tipo base sin saber qué está sucediendo. Por ejemplo, nuestra clase Cat debería ser reemplazable por cualquiera de sus descendientes, digamos Lion , sin cambiar fundamentalmente su comportamiento. La lógica general (comportamiento) sigue siendo la misma, pero los detalles de implementación de funcionalidades específicas cambian. I (principio de segregación de interfaces) : este principio establece que es mejor tener muchas interfaces especializadas (con un enfoque limitado) que una universal. Por ejemplo, supongamos que un desarrollador implementa alguna interfaz. Sólo necesitan uno de sus métodos, pero la interfaz tiene nueve métodos más que no se relacionan con la lógica del método requerido. En este caso, el desarrollador deberá implementar diez métodos de interfaz, ¡nueve de los cuales le resultarán superfluos! En cambio, es mejor crear diez interfaces diferentes que pueda implementar según sea necesario. Bueno, si no diez, entonces varios, cada uno con métodos estrechamente relacionados con el único propósito de la interfaz. D (principio de inversión de dependencia): El principio dice que los módulos de nivel superior no deben depender de módulos de nivel inferior. Este principio también establece: "La abstracción no debe depender de los detalles. Los detalles deben depender de las abstracciones". Debemos construir nuestra lógica haciendo referencia a interfaces y pasando objetos concretos de clases que implementen la interfaz requerida. Por ejemplo, supongamos que tenemos una interfaz Cat y algunas implementaciones, digamos Lion y HouseCat . Construimos nuestra lógica específicamente para interactuar con la interfaz Cat . Sólo entonces sustituimos la interfaz con una implementación específica ( Lion o HouseCat ), pero no al revés.

24. ¿Qué es una clase, un objeto y una interfaz?

Recordaremos que Java es un lenguaje OOP. Es decir, los programas Java se construyen en base a las interacciones entre objetos. Un programa es como un hormiguero, donde cada hormiga es un objeto. Explorando preguntas y respuestas de una entrevista de trabajo para un puesto de desarrollador de Java.  Parte 3 - 3Los objetos son colecciones de datos que incluyen varios métodos (funciones) para interactuar con estos datos internos. Las clases son instrucciones o plantillas para crear objetos. Esto significa que podemos tener muchos objetos construidos según las mismas instrucciones pero llenos de datos diferentes (o los mismos). Tomando un ejemplo de la vida real, podemos decir que una clase es un plano de un edificio y un objeto es un edificio construido específicamente de acuerdo con el plano. Las interfaces son similares a las clases, pero no podemos usarlas para crear objetos. Su propósito es agregar abstracción a Java. Más precisamente, añaden flexibilidad a la relación entre clases y objetos. Por flexibilidad nos referimos al polimorfismo y la abstracción descritos anteriormente, que crean muchas oportunidades para construir la arquitectura interna de una aplicación.

25. ¿Qué es una clase POJO? Dé un ejemplo de tal clase.

Explorando preguntas y respuestas de una entrevista de trabajo para un puesto de desarrollador de Java.  Parte 3 - 4Un POJO (Plain Old Java Object) es un objeto de clase simple que no hereda de ninguna clase específica y no implementa ninguna interfaz de servicio más allá de las necesarias para el modelo de negocio. En otras palabras, una clase POJO es sólo una clase sin requisitos especiales. El único requisito es la ausencia de diversos detalles vinculados a un marco específico. Como regla general, estas clases no heredan otras clases (excepto las clases POJO en el mismo paquete), no implementan interfaces (a veces se hace una excepción para las interfaces de marcadores de la biblioteca estándar como Serializable o Cloneable ), no usan anotaciones y no dependen de bibliotecas de terceros. Notemos que un POJO puede tener métodos que contengan lógica de negocios y constructores de cualquier tipo. Si permitimos anotaciones que no cambian la semántica de la clase (es decir, anotaciones cuya ausencia no cambia el propósito o la lógica del objeto), entonces los POJO también pueden incluir entidades JPA y objetos DTO deserializados de XML o JSON , cuyas reglas son especificado en las anotaciones. Otra cosa a tener en cuenta con respecto a las clases POJO es que es bueno anular sus métodos iguales y hashCode porque esto puede ayudarles a cumplir mejor su función. Ejemplo de una clase POJO :
public class User {
   private Long id;
   private String firstName;
   private String lastName;
   private Long age;

   public User(final Long id, final String firstName, final String lastName, final long age) {
       this.id = id;
       this.firstName = firstName;
       this.lastName = lastName;
       this.age = age;
   }

   public Long getId() {
       return this.id;
   }

   public String getFirstName() {
       return this.firstName;
   }

   public String getLastName() {
       return this.lastName;
   }

   public Long getAge() {
       return this.age;
   }

   @Override
   public boolean equals(final Object o) {
       if (this == o) return true;
       if (o == null || this.getClass() != o.getClass()) return false;
       final User user = (User) o;
       return Objects.equals(this.id, user.id) &&
               Objects.equals(this.firstName, user.firstName) &&
               Objects.equals(this.lastName, user.lastName) &&
               Objects.equals(this.age, user.age);
   }

   @Override
   public int hashCode() {
       return Objects.hash(this.id, this.firstName, this.lastName, this.age);
   }
}

26. ¿Qué elementos puede contener una clase?

Una clase puede contener los siguientes elementos:
  • campos de instancia;
  • campos estáticos;
  • un bloque de inicialización;
  • un bloque de inicialización estático;
  • constructores (por defecto siempre se declara un constructor vacío);
  • métodos;
  • métodos estáticos;
  • varias anotaciones (que pueden aplicarse a la clase misma o a sus partes constituyentes);
  • genéricos ;
  • herencia de otras clases ( extends ) o implementaciones de interfaces ( implements ).

27. Cuéntanos sobre la herencia en Java. ¿Cuáles son los detalles de la súper palabra clave?

Arriba, hablé anteriormente sobre la herencia y la super palabra clave en Java. Mencionaré algunos puntos más importantes:
  1. Solo podemos heredar una única clase: Java no tiene herencia múltiple en Java. Con la llegada de los métodos predeterminados en Java 8, esta afirmación se volverá muy controvertida.
  2. Los métodos y campos privados también se heredan. Simplemente no se puede acceder a ellos desde la clase secundaria (pero si, por ejemplo, tenemos un campo privado y tenemos captadores y definidores públicos o protegidos , entonces podemos usarlos para acceder al campo).
  3. las clases finales no se pueden heredar.
  4. Los métodos finales no se pueden anular (pero se pueden heredar y sobrecargar).
  5. Los métodos estáticos y las variables no se heredan (porque están adjuntos a clases, no a objetos).
  6. Al heredar clases abstractas, se deben implementar sus métodos abstractos o la clase secundaria también debe declararse abstracta.
  7. Si hay constructores no predeterminados en la clase principal, se deben anular en la clase secundaria (pero @Override no está escrito encima de ellos).
  8. Puede extender el modificador de acceso a métodos anulados en la clase secundaria: privado -> predeterminado -> protegido -> público .
  9. Los métodos que se anulan en la clase secundaria pueden generar excepciones más limitadas, por ejemplo: Excepción -> IOException -> FileNotFoundException.
Explorando preguntas y respuestas de una entrevista de trabajo para un puesto de desarrollador de Java.  Parte 3 - 5

28. ¿Qué son las firmas de métodos? Proporcionar ejemplos de firmas correctas e incorrectas.

La firma de un método es el nombre del método más los tipos de parámetros de entrada (el orden de los parámetros importa). La firma del método no incluye el valor de retorno ni las excepciones que arroja el método. Ejemplo de firma correcta:
doSomething(int, double, double)
Ejemplo de firma incorrecta:
void doSomething(int firstArg, int secondArg) throws Exception
La firma del método, combinada con el tipo de retorno y la lista de excepciones generadas, se denomina contrato de método . ¡Eso es todo por hoy! ¡Hasta luego!
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION